Request more documents when EXTRA_HAS_MORE.
Implement EXTRA_HAS_MORE and EXTRA_REQUEST_MORE contract with
document providers. Providers can include EXTRA_HAS_MORE when
additional data is available with additional cost, such as a network
request.
Listen to content changes based on returned cursor instead of
original Uri. Include a test backend to exercise. UX still under
development.
Bug: 10350207
Change-Id: Iaa8954df55a1a1c0aa96eb8a4fd288e12c2fbb01
diff --git a/src/com/android/documentsui/DirectoryLoader.java b/src/com/android/documentsui/DirectoryLoader.java
index c99d6af..14d6fd5 100644
--- a/src/com/android/documentsui/DirectoryLoader.java
+++ b/src/com/android/documentsui/DirectoryLoader.java
@@ -36,29 +36,27 @@
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 @@
}
@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");
- }
+ result.cursor = cursor;
+ result.cursor.registerContentObserver(mObserver);
- if (doc != null && (mFilter == null || mFilter.apply(doc))) {
- result.add(doc);
- }
+ 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");
}
- } finally {
- IoUtils.closeQuietly(cursor);
+
+ if (doc != null && (mFilter == null || mFilter.apply(doc))) {
+ result.contents.add(doc);
+ }
}
if (mSortOrder != null) {
- Collections.sort(result, mSortOrder);
+ Collections.sort(result.contents, mSortOrder);
}
-
- return result;
}
private String getQuerySortOrder() {