summaryrefslogtreecommitdiffstats
path: root/packages/DocumentsUI/src
diff options
context:
space:
mode:
authorJeff Sharkey <jsharkey@android.com>2013-09-03 15:25:52 -0700
committerJeff Sharkey <jsharkey@android.com>2013-09-03 17:02:47 -0700
commit954be0232655d316bc5decbbd35579af902c75c2 (patch)
tree745d4ea34ad245f3e9d87ef19a8910d47cdd3ad4 /packages/DocumentsUI/src
parentded77187ef53341765fcab8e29cda94810fc2ca5 (diff)
downloadframeworks_base-954be0232655d316bc5decbbd35579af902c75c2.zip
frameworks_base-954be0232655d316bc5decbbd35579af902c75c2.tar.gz
frameworks_base-954be0232655d316bc5decbbd35579af902c75c2.tar.bz2
Show loading, error, and info messages as footers.
A provider can include extras in their Cursors to indicate that loading is ongoing, or include an error or informational message, which are now shown in footer views. Fix registration to always get change notifications. Test provider that verifies common provider behavior of holding a reference to "cloud" resources that are released by GC when the remote Cursor is closed. Also used to validate Recents behavior for slow providers. Bug: 10599268 Change-Id: I331c31058dbb80261e7d279b851197c65ac87e32
Diffstat (limited to 'packages/DocumentsUI/src')
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java108
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/DirectoryLoader.java3
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/RootCursorWrapper.java7
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/SortingCursorWrapper.java6
4 files changed, 119 insertions, 5 deletions
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
index 1220137..33d7d6af 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
@@ -412,11 +412,83 @@ public class DirectoryFragment extends Fragment {
return ((DocumentsActivity) fragment.getActivity()).getDisplayState();
}
+ private interface Footer {
+ public View getView(View convertView, ViewGroup parent);
+ }
+
+ private static class LoadingFooter implements Footer {
+ @Override
+ public View getView(View convertView, ViewGroup parent) {
+ final Context context = parent.getContext();
+ if (convertView == null) {
+ final LayoutInflater inflater = LayoutInflater.from(context);
+ convertView = inflater.inflate(R.layout.item_loading, parent, false);
+ }
+ return convertView;
+ }
+ }
+
+ private class MessageFooter implements Footer {
+ private final int mIcon;
+ private final String mMessage;
+
+ public MessageFooter(int icon, String message) {
+ mIcon = icon;
+ mMessage = message;
+ }
+
+ @Override
+ public View getView(View convertView, ViewGroup parent) {
+ final Context context = parent.getContext();
+ final State state = getDisplayState(DirectoryFragment.this);
+
+ if (convertView == null) {
+ final LayoutInflater inflater = LayoutInflater.from(context);
+ if (state.mode == MODE_LIST) {
+ convertView = inflater.inflate(R.layout.item_message_list, parent, false);
+ } else if (state.mode == MODE_GRID) {
+ convertView = inflater.inflate(R.layout.item_message_grid, parent, false);
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ final ImageView icon = (ImageView) convertView.findViewById(android.R.id.icon);
+ final TextView title = (TextView) convertView.findViewById(android.R.id.title);
+ icon.setImageResource(mIcon);
+ title.setText(mMessage);
+ return convertView;
+ }
+ }
+
private class DocumentsAdapter extends BaseAdapter {
private Cursor mCursor;
+ private int mCursorCount;
+
+ private List<Footer> mFooters = Lists.newArrayList();
public void swapCursor(Cursor cursor) {
mCursor = cursor;
+ mCursorCount = cursor != null ? cursor.getCount() : 0;
+
+ mFooters.clear();
+
+ final Bundle extras = cursor != null ? cursor.getExtras() : null;
+ if (extras != null) {
+ final String info = extras.getString(DocumentsContract.EXTRA_INFO);
+ if (info != null) {
+ mFooters.add(new MessageFooter(
+ com.android.internal.R.drawable.ic_menu_info_details, info));
+ }
+ final String error = extras.getString(DocumentsContract.EXTRA_ERROR);
+ if (error != null) {
+ mFooters.add(new MessageFooter(
+ com.android.internal.R.drawable.ic_dialog_alert, error));
+ }
+ if (extras.getBoolean(DocumentsContract.EXTRA_LOADING, false)) {
+ mFooters.add(new LoadingFooter());
+ }
+ }
if (isEmpty()) {
mEmptyView.setVisibility(View.VISIBLE);
@@ -429,6 +501,15 @@ public class DirectoryFragment extends Fragment {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
+ if (position < mCursorCount) {
+ return getDocumentView(position, convertView, parent);
+ } else {
+ position -= mCursorCount;
+ return mFooters.get(position).getView(convertView, parent);
+ }
+ }
+
+ private View getDocumentView(int position, View convertView, ViewGroup parent) {
final Context context = parent.getContext();
final State state = getDisplayState(DirectoryFragment.this);
@@ -535,21 +616,42 @@ public class DirectoryFragment extends Fragment {
@Override
public int getCount() {
- return mCursor != null ? mCursor.getCount() : 0;
+ return mCursorCount + mFooters.size();
}
@Override
public Cursor getItem(int position) {
- if (mCursor != null) {
+ if (position < mCursorCount) {
mCursor.moveToPosition(position);
+ return mCursor;
+ } else {
+ return null;
}
- return mCursor;
}
@Override
public long getItemId(int position) {
return position;
}
+
+ @Override
+ public int getItemViewType(int position) {
+ if (position < mCursorCount) {
+ return 0;
+ } else {
+ return IGNORE_ITEM_VIEW_TYPE;
+ }
+ }
+
+ @Override
+ public boolean areAllItemsEnabled() {
+ return false;
+ }
+
+ @Override
+ public boolean isEnabled(int position) {
+ return position < mCursorCount;
+ }
}
private static class ThumbnailAsyncTask extends AsyncTask<Uri, Void, Bitmap> {
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DirectoryLoader.java b/packages/DocumentsUI/src/com/android/documentsui/DirectoryLoader.java
index 3f016b5..6ea57d7 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DirectoryLoader.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DirectoryLoader.java
@@ -77,11 +77,12 @@ public class DirectoryLoader extends AsyncTaskLoader<DirectoryResult> {
.getContentResolver().acquireUnstableContentProviderClient(authority);
final Cursor cursor = result.client.query(
mUri, null, null, null, getQuerySortOrder(mSortOrder), mSignal);
+ cursor.registerContentObserver(mObserver);
+
final Cursor withRoot = new RootCursorWrapper(mUri.getAuthority(), mRootId, cursor, -1);
final Cursor sorted = new SortingCursorWrapper(withRoot, mSortOrder);
result.cursor = sorted;
- result.cursor.registerContentObserver(mObserver);
} catch (Exception e) {
result.exception = e;
ContentProviderClient.closeQuietly(result.client);
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RootCursorWrapper.java b/packages/DocumentsUI/src/com/android/documentsui/RootCursorWrapper.java
index d0e5ff6..0b58218 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RootCursorWrapper.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RootCursorWrapper.java
@@ -18,6 +18,7 @@ package com.android.documentsui;
import android.database.AbstractCursor;
import android.database.Cursor;
+import android.os.Bundle;
/**
* Cursor wrapper that adds columns to identify which root a document came from.
@@ -63,6 +64,11 @@ public class RootCursorWrapper extends AbstractCursor {
}
@Override
+ public Bundle getExtras() {
+ return mCursor.getExtras();
+ }
+
+ @Override
public void close() {
super.close();
mCursor.close();
@@ -128,5 +134,4 @@ public class RootCursorWrapper extends AbstractCursor {
public boolean isNull(int column) {
return mCursor.isNull(column);
}
-
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/SortingCursorWrapper.java b/packages/DocumentsUI/src/com/android/documentsui/SortingCursorWrapper.java
index b434a35..19ad2e2 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/SortingCursorWrapper.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/SortingCursorWrapper.java
@@ -22,6 +22,7 @@ import static com.android.documentsui.DocumentsActivity.State.SORT_ORDER_SIZE;
import android.database.AbstractCursor;
import android.database.Cursor;
+import android.os.Bundle;
import android.provider.DocumentsContract.Document;
/**
@@ -96,6 +97,11 @@ public class SortingCursorWrapper extends AbstractCursor {
}
@Override
+ public Bundle getExtras() {
+ return mCursor.getExtras();
+ }
+
+ @Override
public void close() {
super.close();
mCursor.close();