diff --git a/api/current.txt b/api/current.txt index ac3948fe83770..d4e23f33bbb52 100644 --- a/api/current.txt +++ b/api/current.txt @@ -17974,6 +17974,7 @@ package android.os { method public static boolean isExternalStorageRemovable(); field public static java.lang.String DIRECTORY_ALARMS; field public static java.lang.String DIRECTORY_DCIM; + field public static java.lang.String DIRECTORY_DOCUMENTS; field public static java.lang.String DIRECTORY_DOWNLOADS; field public static java.lang.String DIRECTORY_MOVIES; field public static java.lang.String DIRECTORY_MUSIC; @@ -20811,10 +20812,9 @@ package android.provider { field public static final java.lang.String COLUMN_MIME_TYPE = "mime_type"; field public static final java.lang.String COLUMN_SIZE = "_size"; field public static final java.lang.String COLUMN_SUMMARY = "summary"; - field public static final int FLAG_DIR_PREFERS_GRID = 32; // 0x20 - field public static final int FLAG_DIR_PREFERS_LAST_MODIFIED = 64; // 0x40 + field public static final int FLAG_DIR_PREFERS_GRID = 16; // 0x10 + field public static final int FLAG_DIR_PREFERS_LAST_MODIFIED = 32; // 0x20 field public static final int FLAG_DIR_SUPPORTS_CREATE = 8; // 0x8 - field public static final int FLAG_DIR_SUPPORTS_SEARCH = 16; // 0x10 field public static final int FLAG_SUPPORTS_DELETE = 4; // 0x4 field public static final int FLAG_SUPPORTS_THUMBNAIL = 1; // 0x1 field public static final int FLAG_SUPPORTS_WRITE = 2; // 0x2 @@ -20832,9 +20832,11 @@ package android.provider { field public static final java.lang.String COLUMN_SUMMARY = "summary"; field public static final java.lang.String COLUMN_TITLE = "title"; field public static final int FLAG_ADVANCED = 4; // 0x4 + field public static final int FLAG_EMPTY = 32; // 0x20 field public static final int FLAG_LOCAL_ONLY = 2; // 0x2 field public static final int FLAG_SUPPORTS_CREATE = 1; // 0x1 field public static final int FLAG_SUPPORTS_RECENTS = 8; // 0x8 + field public static final int FLAG_SUPPORTS_SEARCH = 16; // 0x10 field public static final int ROOT_TYPE_DEVICE = 3; // 0x3 field public static final int ROOT_TYPE_SERVICE = 1; // 0x1 field public static final int ROOT_TYPE_SHORTCUT = 2; // 0x2 diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java index c6e8c3e5b7be7..5b36bca33b8f5 100644 --- a/core/java/android/os/Environment.java +++ b/core/java/android/os/Environment.java @@ -460,7 +460,13 @@ public class Environment { * top-level public directory, as this convention makes no sense elsewhere. */ public static String DIRECTORY_DCIM = "DCIM"; - + + /** + * Standard directory in which to place documents that have been created by + * the user. + */ + public static String DIRECTORY_DOCUMENTS = "Documents"; + /** * Get a top-level public external storage directory for placing files of * a particular type. This is where the user will typically place and diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java index 37ce065a5cd86..231e6a6f5842b 100644 --- a/core/java/android/provider/DocumentsContract.java +++ b/core/java/android/provider/DocumentsContract.java @@ -64,9 +64,9 @@ public final class DocumentsContract { // content://com.example/root/ // content://com.example/root/sdcard/ // content://com.example/root/sdcard/recent/ + // content://com.example/root/sdcard/search/?query=pony // content://com.example/document/12/ // content://com.example/document/12/children/ - // content://com.example/document/12/search/?query=pony private DocumentsContract() { } @@ -174,7 +174,6 @@ public final class DocumentsContract { * @see #FLAG_SUPPORTS_THUMBNAIL * @see #FLAG_DIR_PREFERS_GRID * @see #FLAG_DIR_SUPPORTS_CREATE - * @see #FLAG_DIR_SUPPORTS_SEARCH */ public static final String COLUMN_FLAGS = "flags"; @@ -240,16 +239,6 @@ public final class DocumentsContract { */ public static final int FLAG_DIR_SUPPORTS_CREATE = 1 << 3; - /** - * Flag indicating that a directory supports search. Only valid when - * {@link #COLUMN_MIME_TYPE} is {@link #MIME_TYPE_DIR}. - * - * @see #COLUMN_FLAGS - * @see DocumentsProvider#querySearchDocuments(String, String, - * String[]) - */ - public static final int FLAG_DIR_SUPPORTS_SEARCH = 1 << 4; - /** * Flag indicating that a directory prefers its contents be shown in a * larger format grid. Usually suitable when a directory contains mostly @@ -258,7 +247,7 @@ public final class DocumentsContract { * * @see #COLUMN_FLAGS */ - public static final int FLAG_DIR_PREFERS_GRID = 1 << 5; + public static final int FLAG_DIR_PREFERS_GRID = 1 << 4; /** * Flag indicating that a directory prefers its contents be sorted by @@ -267,7 +256,7 @@ public final class DocumentsContract { * * @see #COLUMN_FLAGS */ - public static final int FLAG_DIR_PREFERS_LAST_MODIFIED = 1 << 6; + public static final int FLAG_DIR_PREFERS_LAST_MODIFIED = 1 << 5; } /** @@ -306,9 +295,12 @@ public final class DocumentsContract { *
* Type: INTEGER (int)
*
+ * @see #FLAG_ADVANCED
+ * @see #FLAG_EMPTY
* @see #FLAG_LOCAL_ONLY
* @see #FLAG_SUPPORTS_CREATE
- * @see #FLAG_ADVANCED
+ * @see #FLAG_SUPPORTS_RECENTS
+ * @see #FLAG_SUPPORTS_SEARCH
*/
public static final String COLUMN_FLAGS = "flags";
@@ -422,6 +414,27 @@ public final class DocumentsContract {
* @see DocumentsContract#buildRecentDocumentsUri(String, String)
*/
public static final int FLAG_SUPPORTS_RECENTS = 1 << 3;
+
+ /**
+ * Flag indicating that this root supports search.
+ *
+ * @see #COLUMN_FLAGS
+ * @see DocumentsProvider#querySearchDocuments(String, String,
+ * String[])
+ */
+ public static final int FLAG_SUPPORTS_SEARCH = 1 << 4;
+
+ /**
+ * Flag indicating that this root is currently empty. This may be used
+ * to hide the root when opening documents, but the root will still be
+ * shown when creating documents and {@link #FLAG_SUPPORTS_CREATE} is
+ * also set.
+ *
+ * @see #COLUMN_FLAGS
+ * @see DocumentsProvider#querySearchDocuments(String, String,
+ * String[])
+ */
+ public static final int FLAG_EMPTY = 1 << 5;
}
/**
@@ -493,9 +506,9 @@ public final class DocumentsContract {
}
/**
- * Build Uri representing the recently modified documents of a specific
- * root. When queried, a provider will return zero or more rows with columns
- * defined by {@link Document}.
+ * Build Uri representing the recently modified documents of a specific root
+ * in a document provider. When queried, a provider will return zero or more
+ * rows with columns defined by {@link Document}.
*
* @see DocumentsProvider#queryRecentDocuments(String, String[])
* @see #getRootId(Uri)
@@ -538,21 +551,17 @@ public final class DocumentsContract {
/**
* Build Uri representing a search for matching documents under a specific
- * directory in a document provider. When queried, a provider will return
- * zero or more rows with columns defined by {@link Document}.
+ * root in a document provider. When queried, a provider will return zero or
+ * more rows with columns defined by {@link Document}.
*
- * @param parentDocumentId the document to return children for, which must
- * be both a directory with MIME type of
- * {@link Document#MIME_TYPE_DIR} and have
- * {@link Document#FLAG_DIR_SUPPORTS_SEARCH} set.
* @see DocumentsProvider#querySearchDocuments(String, String, String[])
- * @see #getDocumentId(Uri)
+ * @see #getRootId(Uri)
* @see #getSearchDocumentsQuery(Uri)
*/
public static Uri buildSearchDocumentsUri(
- String authority, String parentDocumentId, String query) {
+ String authority, String rootId, String query) {
return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT).authority(authority)
- .appendPath(PATH_DOCUMENT).appendPath(parentDocumentId).appendPath(PATH_SEARCH)
+ .appendPath(PATH_ROOT).appendPath(rootId).appendPath(PATH_SEARCH)
.appendQueryParameter(PARAM_QUERY, query).build();
}
diff --git a/core/java/android/provider/DocumentsProvider.java b/core/java/android/provider/DocumentsProvider.java
index d80182703bdf1..bc4e28bdf481c 100644
--- a/core/java/android/provider/DocumentsProvider.java
+++ b/core/java/android/provider/DocumentsProvider.java
@@ -75,9 +75,9 @@ public abstract class DocumentsProvider extends ContentProvider {
private static final int MATCH_ROOTS = 1;
private static final int MATCH_ROOT = 2;
private static final int MATCH_RECENT = 3;
- private static final int MATCH_DOCUMENT = 4;
- private static final int MATCH_CHILDREN = 5;
- private static final int MATCH_SEARCH = 6;
+ private static final int MATCH_SEARCH = 4;
+ private static final int MATCH_DOCUMENT = 5;
+ private static final int MATCH_CHILDREN = 6;
private String mAuthority;
@@ -94,9 +94,9 @@ public abstract class DocumentsProvider extends ContentProvider {
mMatcher.addURI(mAuthority, "root", MATCH_ROOTS);
mMatcher.addURI(mAuthority, "root/*", MATCH_ROOT);
mMatcher.addURI(mAuthority, "root/*/recent", MATCH_RECENT);
+ mMatcher.addURI(mAuthority, "root/*/search", MATCH_SEARCH);
mMatcher.addURI(mAuthority, "document/*", MATCH_DOCUMENT);
mMatcher.addURI(mAuthority, "document/*/children", MATCH_CHILDREN);
- mMatcher.addURI(mAuthority, "document/*/search", MATCH_SEARCH);
// Sanity check our setup
if (!info.exported) {
@@ -176,13 +176,12 @@ public abstract class DocumentsProvider extends ContentProvider {
}
/**
- * Return documents that that match the given query, starting the search at
- * the given directory.
+ * Return documents that that match the given query.
*
- * @param parentDocumentId the directory to start search at.
+ * @param rootId the root to search under.
*/
@SuppressWarnings("unused")
- public Cursor querySearchDocuments(String parentDocumentId, String query, String[] projection)
+ public Cursor querySearchDocuments(String rootId, String query, String[] projection)
throws FileNotFoundException {
throw new UnsupportedOperationException("Search not supported");
}
@@ -267,6 +266,9 @@ public abstract class DocumentsProvider extends ContentProvider {
return queryRoots(projection);
case MATCH_RECENT:
return queryRecentDocuments(getRootId(uri), projection);
+ case MATCH_SEARCH:
+ return querySearchDocuments(
+ getRootId(uri), getSearchDocumentsQuery(uri), projection);
case MATCH_DOCUMENT:
return queryDocument(getDocumentId(uri), projection);
case MATCH_CHILDREN:
@@ -276,9 +278,6 @@ public abstract class DocumentsProvider extends ContentProvider {
} else {
return queryChildDocuments(getDocumentId(uri), projection, sortOrder);
}
- case MATCH_SEARCH:
- return querySearchDocuments(
- getDocumentId(uri), getSearchDocumentsQuery(uri), projection);
default:
throw new UnsupportedOperationException("Unsupported Uri " + uri);
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
index b2981dbe301b4..aee865b352715 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
@@ -125,9 +125,8 @@ public class DirectoryFragment extends Fragment {
show(fm, TYPE_NORMAL, root, doc, null);
}
- public static void showSearch(
- FragmentManager fm, RootInfo root, DocumentInfo doc, String query) {
- show(fm, TYPE_SEARCH, root, doc, query);
+ public static void showSearch(FragmentManager fm, RootInfo root, String query) {
+ show(fm, TYPE_SEARCH, root, null, query);
}
public static void showRecentsOpen(FragmentManager fm) {
@@ -205,7 +204,7 @@ public class DirectoryFragment extends Fragment {
context, mType, root, doc, contentsUri, state.userSortOrder);
case TYPE_SEARCH:
contentsUri = DocumentsContract.buildSearchDocumentsUri(
- doc.authority, doc.documentId, query);
+ root.authority, root.rootId, query);
if (state.action == ACTION_MANAGE) {
contentsUri = DocumentsContract.setManageMode(contentsUri);
}
@@ -274,7 +273,7 @@ public class DirectoryFragment extends Fragment {
final RootInfo root = getArguments().getParcelable(EXTRA_ROOT);
final DocumentInfo doc = getArguments().getParcelable(EXTRA_DOC);
- if (root != null) {
+ if (root != null && doc != null) {
final Uri stateUri = RecentsProvider.buildState(
root.authority, root.rootId, doc.documentId);
final ContentValues values = new ContentValues();
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DirectoryLoader.java b/packages/DocumentsUI/src/com/android/documentsui/DirectoryLoader.java
index 334e26285f6ae..8627ecfaa2f7e 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DirectoryLoader.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DirectoryLoader.java
@@ -32,6 +32,7 @@ import android.database.Cursor;
import android.net.Uri;
import android.os.CancellationSignal;
import android.os.OperationCanceledException;
+import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Document;
import android.util.Log;
@@ -42,6 +43,8 @@ import com.android.documentsui.model.RootInfo;
import libcore.io.IoUtils;
+import java.io.FileNotFoundException;
+
class DirectoryResult implements AutoCloseable {
ContentProviderClient client;
Cursor cursor;
@@ -64,7 +67,7 @@ public class DirectoryLoader extends AsyncTaskLoader