diff options
Diffstat (limited to 'packages/DocumentsUI/src/com/android/documentsui')
4 files changed, 92 insertions, 80 deletions
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java index d3421e7..dd9aee5 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java +++ b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java @@ -32,6 +32,7 @@ import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.Loader; +import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.Point; import android.net.Uri; @@ -54,6 +55,7 @@ import android.widget.AbsListView.MultiChoiceModeListener; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.BaseAdapter; +import android.widget.Button; import android.widget.GridView; import android.widget.ImageView; import android.widget.ListView; @@ -79,6 +81,7 @@ public class DirectoryFragment extends Fragment { private View mEmptyView; private ListView mListView; private GridView mGridView; + private Button mMoreView; private AbsListView mCurrentView; @@ -93,7 +96,7 @@ public class DirectoryFragment extends Fragment { private Point mThumbSize; private DocumentsAdapter mAdapter; - private LoaderCallbacks<List<Document>> mCallbacks; + private LoaderCallbacks<DirectoryResult> mCallbacks; private static final String EXTRA_TYPE = "type"; private static final String EXTRA_URI = "uri"; @@ -150,14 +153,16 @@ public class DirectoryFragment extends Fragment { mGridView.setOnItemClickListener(mItemListener); mGridView.setMultiChoiceModeListener(mMultiListener); + mMoreView = (Button) view.findViewById(R.id.more); + mAdapter = new DocumentsAdapter(); final Uri uri = getArguments().getParcelable(EXTRA_URI); mType = getArguments().getInt(EXTRA_TYPE); - mCallbacks = new LoaderCallbacks<List<Document>>() { + mCallbacks = new LoaderCallbacks<DirectoryResult>() { @Override - public Loader<List<Document>> onCreateLoader(int id, Bundle args) { + public Loader<DirectoryResult> onCreateLoader(int id, Bundle args) { final DisplayState state = getDisplayState(DirectoryFragment.this); mFilter = new MimePredicate(state.acceptMimes); @@ -189,12 +194,34 @@ public class DirectoryFragment extends Fragment { } @Override - public void onLoadFinished(Loader<List<Document>> loader, List<Document> data) { - mAdapter.swapDocuments(data); + public void onLoadFinished(Loader<DirectoryResult> loader, DirectoryResult result) { + mAdapter.swapDocuments(result.contents); + + final Cursor cursor = result.cursor; + if (cursor != null && cursor.getExtras() + .getBoolean(DocumentsContract.EXTRA_HAS_MORE, false)) { + mMoreView.setText(R.string.more); + mMoreView.setVisibility(View.VISIBLE); + mMoreView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + mMoreView.setText(R.string.loading); + final Bundle bundle = new Bundle(); + bundle.putBoolean(DocumentsContract.EXTRA_REQUEST_MORE, true); + try { + cursor.respond(bundle); + } catch (Exception e) { + Log.w(TAG, "Failed to respond: " + e); + } + } + }); + } else { + mMoreView.setVisibility(View.GONE); + } } @Override - public void onLoaderReset(Loader<List<Document>> loader) { + public void onLoaderReset(Loader<DirectoryResult> loader) { mAdapter.swapDocuments(null); } }; @@ -407,7 +434,7 @@ public class DirectoryFragment extends Fragment { public void swapDocuments(List<Document> documents) { mDocuments = documents; - if (documents != null && documents.isEmpty()) { + if (mDocuments != null && mDocuments.isEmpty()) { mEmptyView.setVisibility(View.VISIBLE); } else { mEmptyView.setVisibility(View.GONE); diff --git a/packages/DocumentsUI/src/com/android/documentsui/DirectoryLoader.java b/packages/DocumentsUI/src/com/android/documentsui/DirectoryLoader.java index c99d6af..14d6fd5 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/DirectoryLoader.java +++ b/packages/DocumentsUI/src/com/android/documentsui/DirectoryLoader.java @@ -36,29 +36,27 @@ import com.google.android.collect.Lists; import libcore.io.IoUtils; import java.io.FileNotFoundException; -import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; -import java.util.LinkedList; import java.util.List; -public class DirectoryLoader extends UriDerivativeLoader<List<Document>> { +class DirectoryResult implements AutoCloseable { + Cursor cursor; + List<Document> contents = Lists.newArrayList(); + Exception e; + + @Override + public void close() throws Exception { + IoUtils.closeQuietly(cursor); + } +} + +public class DirectoryLoader extends UriDerivativeLoader<Uri, DirectoryResult> { private final int mType; private Predicate<Document> mFilter; private Comparator<Document> mSortOrder; - /** - * Stub result that represents an internal error. - */ - public static class ExceptionResult extends LinkedList<Document> { - public final Exception e; - - public ExceptionResult(Exception e) { - this.e = e; - } - } - public DirectoryLoader(Context context, Uri uri, int type, Predicate<Document> filter, Comparator<Document> sortOrder) { super(context, uri); @@ -68,53 +66,49 @@ public class DirectoryLoader extends UriDerivativeLoader<List<Document>> { } @Override - public List<Document> loadInBackground(Uri uri, CancellationSignal signal) { + public DirectoryResult loadInBackground(Uri uri, CancellationSignal signal) { + final DirectoryResult result = new DirectoryResult(); try { - return loadInBackgroundInternal(uri, signal); + loadInBackgroundInternal(result, uri, signal); } catch (Exception e) { - return new ExceptionResult(e); + result.e = e; } + return result; } - private List<Document> loadInBackgroundInternal(Uri uri, CancellationSignal signal) { - final ArrayList<Document> result = Lists.newArrayList(); - - // TODO: subscribe to the notify uri from query - + private void loadInBackgroundInternal( + DirectoryResult result, Uri uri, CancellationSignal signal) { final ContentResolver resolver = getContext().getContentResolver(); final Cursor cursor = resolver.query(uri, null, null, null, getQuerySortOrder(), signal); - try { - while (cursor != null && cursor.moveToNext()) { - Document doc = null; - switch (mType) { - case TYPE_NORMAL: - case TYPE_SEARCH: - doc = Document.fromDirectoryCursor(uri, cursor); - break; - case TYPE_RECENT_OPEN: - try { - doc = Document.fromRecentOpenCursor(resolver, cursor); - } catch (FileNotFoundException e) { - Log.w(TAG, "Failed to find recent: " + e); - } - break; - default: - throw new IllegalArgumentException("Unknown type"); - } - - if (doc != null && (mFilter == null || mFilter.apply(doc))) { - result.add(doc); - } + result.cursor = cursor; + result.cursor.registerContentObserver(mObserver); + + while (cursor.moveToNext()) { + Document doc = null; + switch (mType) { + case TYPE_NORMAL: + case TYPE_SEARCH: + doc = Document.fromDirectoryCursor(uri, cursor); + break; + case TYPE_RECENT_OPEN: + try { + doc = Document.fromRecentOpenCursor(resolver, cursor); + } catch (FileNotFoundException e) { + Log.w(TAG, "Failed to find recent: " + e); + } + break; + default: + throw new IllegalArgumentException("Unknown type"); + } + + if (doc != null && (mFilter == null || mFilter.apply(doc))) { + result.contents.add(doc); } - } finally { - IoUtils.closeQuietly(cursor); } if (mSortOrder != null) { - Collections.sort(result, mSortOrder); + Collections.sort(result.contents, mSortOrder); } - - return result; } private String getQuerySortOrder() { diff --git a/packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java b/packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java index cd8adac..5466dbf 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java +++ b/packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java @@ -124,7 +124,7 @@ public class RecentsCreateFragment extends Fragment { } }; - public static class RecentsCreateLoader extends UriDerivativeLoader<List<DocumentStack>> { + public static class RecentsCreateLoader extends UriDerivativeLoader<Uri, List<DocumentStack>> { public RecentsCreateLoader(Context context) { super(context, RecentsProvider.buildRecentCreate()); } diff --git a/packages/DocumentsUI/src/com/android/documentsui/UriDerivativeLoader.java b/packages/DocumentsUI/src/com/android/documentsui/UriDerivativeLoader.java index 1b88af4..1a5bb0c 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/UriDerivativeLoader.java +++ b/packages/DocumentsUI/src/com/android/documentsui/UriDerivativeLoader.java @@ -19,7 +19,6 @@ package com.android.documentsui; import android.content.AsyncTaskLoader; import android.content.Context; import android.database.ContentObserver; -import android.net.Uri; import android.os.CancellationSignal; import android.os.OperationCanceledException; @@ -28,17 +27,16 @@ import android.os.OperationCanceledException; * changes while started, manages {@link CancellationSignal}, and caches * returned results. */ -public abstract class UriDerivativeLoader<T> extends AsyncTaskLoader<T> { - private final ForceLoadContentObserver mObserver; - private boolean mObserving; +public abstract class UriDerivativeLoader<P, R> extends AsyncTaskLoader<R> { + final ForceLoadContentObserver mObserver; - private final Uri mUri; + private final P mParam; - private T mResult; + private R mResult; private CancellationSignal mCancellationSignal; @Override - public final T loadInBackground() { + public final R loadInBackground() { synchronized (this) { if (isLoadInBackgroundCanceled()) { throw new OperationCanceledException(); @@ -46,7 +44,7 @@ public abstract class UriDerivativeLoader<T> extends AsyncTaskLoader<T> { mCancellationSignal = new CancellationSignal(); } try { - return loadInBackground(mUri, mCancellationSignal); + return loadInBackground(mParam, mCancellationSignal); } finally { synchronized (this) { mCancellationSignal = null; @@ -54,7 +52,7 @@ public abstract class UriDerivativeLoader<T> extends AsyncTaskLoader<T> { } } - public abstract T loadInBackground(Uri uri, CancellationSignal signal); + public abstract R loadInBackground(P param, CancellationSignal signal); @Override public void cancelLoadInBackground() { @@ -68,12 +66,12 @@ public abstract class UriDerivativeLoader<T> extends AsyncTaskLoader<T> { } @Override - public void deliverResult(T result) { + public void deliverResult(R result) { if (isReset()) { closeQuietly(result); return; } - T oldResult = mResult; + R oldResult = mResult; mResult = result; if (isStarted()) { @@ -85,18 +83,14 @@ public abstract class UriDerivativeLoader<T> extends AsyncTaskLoader<T> { } } - public UriDerivativeLoader(Context context, Uri uri) { + public UriDerivativeLoader(Context context, P param) { super(context); mObserver = new ForceLoadContentObserver(); - mUri = uri; + mParam = param; } @Override protected void onStartLoading() { - if (!mObserving) { - getContext().getContentResolver().registerContentObserver(mUri, false, mObserver); - mObserving = true; - } if (mResult != null) { deliverResult(mResult); } @@ -111,7 +105,7 @@ public abstract class UriDerivativeLoader<T> extends AsyncTaskLoader<T> { } @Override - public void onCanceled(T result) { + public void onCanceled(R result) { closeQuietly(result); } @@ -125,13 +119,10 @@ public abstract class UriDerivativeLoader<T> extends AsyncTaskLoader<T> { closeQuietly(mResult); mResult = null; - if (mObserving) { - getContext().getContentResolver().unregisterContentObserver(mObserver); - mObserving = false; - } + getContext().getContentResolver().unregisterContentObserver(mObserver); } - private void closeQuietly(T result) { + private void closeQuietly(R result) { if (result instanceof AutoCloseable) { try { ((AutoCloseable) result).close(); |