DocumentsUI handles GET_CONTENT; hinting, errors.
Document browser now takes over all GET_CONTENT requests that request
openable Uris. It shows both storage backends and includes other apps
that respond to GET_CONTENT. Only grants transient read permissions.
Better guarding against throwing storage backends. Send sort order
and local-only hinting to backends.
Require that OPEN/CREATE_DOC users include openable category.
Bug: 10330112, 10329976, 10340741, 10331689, 10329971
Change-Id: Ieb8768a6d71201816046f4a4c48832061a313c28
diff --git a/src/com/android/documentsui/DirectoryLoader.java b/src/com/android/documentsui/DirectoryLoader.java
index 94c2b61..98f9a4d 100644
--- a/src/com/android/documentsui/DirectoryLoader.java
+++ b/src/com/android/documentsui/DirectoryLoader.java
@@ -26,6 +26,7 @@
import android.database.Cursor;
import android.net.Uri;
import android.os.CancellationSignal;
+import android.provider.DocumentsContract.DocumentColumns;
import android.util.Log;
import com.android.documentsui.model.Document;
@@ -38,6 +39,7 @@
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>> {
@@ -46,6 +48,17 @@
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);
@@ -56,11 +69,18 @@
@Override
public List<Document> loadInBackground(Uri uri, CancellationSignal signal) {
+ try {
+ return loadInBackgroundInternal(uri, signal);
+ } catch (Exception e) {
+ return new ExceptionResult(e);
+ }
+ }
+
+ private List<Document> loadInBackgroundInternal(Uri uri, CancellationSignal signal) {
final ArrayList<Document> result = Lists.newArrayList();
- // TODO: send selection and sorting hints to backend
final ContentResolver resolver = getContext().getContentResolver();
- final Cursor cursor = resolver.query(uri, null, null, null, null, signal);
+ final Cursor cursor = resolver.query(uri, null, null, null, getQuerySortOrder(), signal);
try {
while (cursor != null && cursor.moveToNext()) {
Document doc = null;
@@ -94,4 +114,16 @@
return result;
}
+
+ private String getQuerySortOrder() {
+ if (mSortOrder instanceof Document.DateComparator) {
+ return DocumentColumns.LAST_MODIFIED + " DESC";
+ } else if (mSortOrder instanceof Document.NameComparator) {
+ return DocumentColumns.DISPLAY_NAME + " ASC";
+ } else if (mSortOrder instanceof Document.SizeComparator) {
+ return DocumentColumns.SIZE + " DESC";
+ } else {
+ return null;
+ }
+ }
}