Merge "Expose @SystemApi and @Public for unbundling DocumentsUI"
diff --git a/api/current.txt b/api/current.txt
index 7a53327..2ef4a39 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -37370,11 +37370,15 @@
method public static void ejectRoot(android.content.ContentResolver, android.net.Uri);
method public static android.provider.DocumentsContract.Path findDocumentPath(android.content.ContentResolver, android.net.Uri) throws java.io.FileNotFoundException;
method public static java.lang.String getDocumentId(android.net.Uri);
+ method public static android.os.Bundle getDocumentMetadata(android.content.ContentResolver, android.net.Uri) throws java.io.FileNotFoundException;
method public static android.graphics.Bitmap getDocumentThumbnail(android.content.ContentResolver, android.net.Uri, android.graphics.Point, android.os.CancellationSignal) throws java.io.FileNotFoundException;
method public static java.lang.String getRootId(android.net.Uri);
method public static java.lang.String getSearchDocumentsQuery(android.net.Uri);
method public static java.lang.String getTreeDocumentId(android.net.Uri);
+ method public static boolean isChildDocument(android.content.ContentResolver, android.net.Uri, android.net.Uri) throws java.io.FileNotFoundException;
method public static boolean isDocumentUri(android.content.Context, android.net.Uri);
+ method public static boolean isRootUri(android.content.Context, android.net.Uri);
+ method public static boolean isRootsUri(android.content.Context, android.net.Uri);
method public static boolean isTreeUri(android.net.Uri);
method public static android.net.Uri moveDocument(android.content.ContentResolver, android.net.Uri, android.net.Uri, android.net.Uri) throws java.io.FileNotFoundException;
method public static boolean removeDocument(android.content.ContentResolver, android.net.Uri, android.net.Uri) throws java.io.FileNotFoundException;
@@ -37387,7 +37391,14 @@
field public static final java.lang.String EXTRA_LOADING = "loading";
field public static final java.lang.String EXTRA_ORIENTATION = "android.provider.extra.ORIENTATION";
field public static final java.lang.String EXTRA_PROMPT = "android.provider.extra.PROMPT";
+ field public static final java.lang.String METADATA_EXIF = "android:documentExif";
+ field public static final java.lang.String METADATA_TYPES = "android:documentMetadataTypes";
field public static final java.lang.String PROVIDER_INTERFACE = "android.content.action.DOCUMENTS_PROVIDER";
+ field public static final java.lang.String QUERY_ARG_DISPLAY_NAME = "android:query-arg-display-name";
+ field public static final java.lang.String QUERY_ARG_EXCLUDE_MEDIA = "android:query-arg-exclude-media";
+ field public static final java.lang.String QUERY_ARG_FILE_SIZE_OVER = "android:query-arg-file-size-over";
+ field public static final java.lang.String QUERY_ARG_LAST_MODIFIED_AFTER = "android:query-arg-last-modified-after";
+ field public static final java.lang.String QUERY_ARG_MIME_TYPES = "android:query-arg-mime-types";
}
public static final class DocumentsContract.Document {
@@ -37402,8 +37413,10 @@
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_PARTIAL = 8192; // 0x2000
field public static final int FLAG_SUPPORTS_COPY = 128; // 0x80
field public static final int FLAG_SUPPORTS_DELETE = 4; // 0x4
+ field public static final int FLAG_SUPPORTS_METADATA = 16384; // 0x4000
field public static final int FLAG_SUPPORTS_MOVE = 256; // 0x100
field public static final int FLAG_SUPPORTS_REMOVE = 1024; // 0x400
field public static final int FLAG_SUPPORTS_RENAME = 64; // 0x40
@@ -37434,6 +37447,7 @@
field public static final java.lang.String COLUMN_ROOT_ID = "root_id";
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_EMPTY = 64; // 0x40
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_EJECT = 32; // 0x20
@@ -37452,6 +37466,7 @@
method public void deleteDocument(java.lang.String) throws java.io.FileNotFoundException;
method public void ejectRoot(java.lang.String);
method public android.provider.DocumentsContract.Path findDocumentPath(java.lang.String, java.lang.String) throws java.io.FileNotFoundException;
+ method public android.os.Bundle getDocumentMetadata(java.lang.String) throws java.io.FileNotFoundException;
method public java.lang.String[] getDocumentStreamTypes(java.lang.String, java.lang.String);
method public java.lang.String getDocumentType(java.lang.String) throws java.io.FileNotFoundException;
method public final java.lang.String getType(android.net.Uri);
@@ -37476,6 +37491,7 @@
method public android.database.Cursor queryRecentDocuments(java.lang.String, java.lang.String[], android.os.Bundle, android.os.CancellationSignal) throws java.io.FileNotFoundException;
method public abstract android.database.Cursor queryRoots(java.lang.String[]) throws java.io.FileNotFoundException;
method public android.database.Cursor querySearchDocuments(java.lang.String, java.lang.String, java.lang.String[]) throws java.io.FileNotFoundException;
+ method public android.database.Cursor querySearchDocuments(java.lang.String, java.lang.String[], android.os.Bundle) throws java.io.FileNotFoundException;
method public void removeDocument(java.lang.String, java.lang.String) throws java.io.FileNotFoundException;
method public java.lang.String renameDocument(java.lang.String, java.lang.String) throws java.io.FileNotFoundException;
method public final void revokeDocumentPermission(java.lang.String);
diff --git a/api/system-current.txt b/api/system-current.txt
index 542fdff..a37da64 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -4507,6 +4507,21 @@
field public static final java.lang.String STATE = "state";
}
+ public final class DocumentsContract {
+ method public static boolean isManageMode(android.net.Uri);
+ method public static android.net.Uri setManageMode(android.net.Uri);
+ field public static final java.lang.String ACTION_DOCUMENT_ROOT_SETTINGS = "android.provider.action.DOCUMENT_ROOT_SETTINGS";
+ field public static final java.lang.String ACTION_MANAGE_DOCUMENT = "android.provider.action.MANAGE_DOCUMENT";
+ field public static final java.lang.String EXTRA_SHOW_ADVANCED = "android.provider.extra.SHOW_ADVANCED";
+ }
+
+ public static final class DocumentsContract.Root {
+ field public static final int FLAG_ADVANCED = 65536; // 0x10000
+ field public static final int FLAG_HAS_SETTINGS = 131072; // 0x20000
+ field public static final int FLAG_REMOVABLE_SD = 262144; // 0x40000
+ field public static final int FLAG_REMOVABLE_USB = 524288; // 0x80000
+ }
+
public abstract class SearchIndexableData {
ctor public SearchIndexableData();
ctor public SearchIndexableData(android.content.Context);
diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java
index 37c84bd..4737577 100644
--- a/core/java/android/provider/DocumentsContract.java
+++ b/core/java/android/provider/DocumentsContract.java
@@ -22,6 +22,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.SystemApi;
import android.annotation.UnsupportedAppUsage;
import android.content.ContentProviderClient;
import android.content.ContentResolver;
@@ -97,8 +98,15 @@
@Deprecated
public static final String EXTRA_PACKAGE_NAME = Intent.EXTRA_PACKAGE_NAME;
- /** {@hide} */
- public static final String EXTRA_SHOW_ADVANCED = "android.content.extra.SHOW_ADVANCED";
+ /**
+ * The value is decide whether to show advance mode or not.
+ * If the value is true, the local/device storage root must be
+ * visible in DocumentsUI.
+ *
+ * {@hide}
+ */
+ @SystemApi
+ public static final String EXTRA_SHOW_ADVANCED = "android.provider.extra.SHOW_ADVANCED";
/** {@hide} */
public static final String EXTRA_TARGET_URI = "android.content.extra.TARGET_URI";
@@ -111,7 +119,6 @@
*
* @see DocumentsProvider#querySearchDocuments(String, String[],
* Bundle)
- * {@hide}
*/
public static final String QUERY_ARG_DISPLAY_NAME = "android:query-arg-display-name";
@@ -124,7 +131,6 @@
*
* @see DocumentsProvider#querySearchDocuments(String, String[],
* Bundle)
- * {@hide}
*/
public static final String QUERY_ARG_MIME_TYPES = "android:query-arg-mime-types";
@@ -134,7 +140,6 @@
*
* @see DocumentsProvider#querySearchDocuments(String, String[],
* Bundle)
- * {@hide}
*/
public static final String QUERY_ARG_FILE_SIZE_OVER = "android:query-arg-file-size-over";
@@ -146,7 +151,6 @@
* @see DocumentsProvider#querySearchDocuments(String, String[],
* Bundle)
* @see Document#COLUMN_LAST_MODIFIED
- * {@hide}
*/
public static final String QUERY_ARG_LAST_MODIFIED_AFTER =
"android:query-arg-last-modified-after";
@@ -158,7 +162,6 @@
*
* @see DocumentsProvider#querySearchDocuments(String, String[],
* Bundle)
- * {@hide}
*/
public static final String QUERY_ARG_EXCLUDE_MEDIA = "android:query-arg-exclude-media";
@@ -216,10 +219,18 @@
public static final String
ACTION_DOCUMENT_SETTINGS = "android.provider.action.DOCUMENT_SETTINGS";
- /** {@hide} */
+ /**
+ * The action to manage document in Downloads root in DocumentsUI.
+ * {@hide}
+ */
+ @SystemApi
public static final String ACTION_MANAGE_DOCUMENT = "android.provider.action.MANAGE_DOCUMENT";
- /** {@hide} */
+ /**
+ * The action to launch the settings of this root.
+ * {@hide}
+ */
+ @SystemApi
public static final String
ACTION_DOCUMENT_ROOT_SETTINGS = "android.provider.action.DOCUMENT_ROOT_SETTINGS";
@@ -235,10 +246,19 @@
/** {@hide} */
public static final String PACKAGE_DOCUMENTS_UI = "com.android.documentsui";
- /** {@hide} */
- public static final String METADATA_TYPES = "android:documentMetadataType";
+ /**
+ * Get string array identifies the type or types of metadata returned
+ * using DocumentsContract#getDocumentMetadata.
+ *
+ * @see #getDocumentMetadata(ContentResolver, Uri)
+ */
+ public static final String METADATA_TYPES = "android:documentMetadataTypes";
- /** {@hide} */
+ /**
+ * Get Exif information using DocumentsContract#getDocumentMetadata.
+ *
+ * @see #getDocumentMetadata(ContentResolver, Uri)
+ */
public static final String METADATA_EXIF = "android:documentExif";
/**
@@ -498,16 +518,17 @@
* if they represent a failed download.
*
* @see #COLUMN_FLAGS
- * @hide
*/
- public static final int FLAG_PARTIAL = 1 << 16;
+ public static final int FLAG_PARTIAL = 1 << 13;
/**
* Flag indicating that a document has available metadata that can be read
* using DocumentsContract#getDocumentMetadata
- * @hide
+ *
+ * @see #COLUMN_FLAGS
+ * @see DocumentsContract#getDocumentMetadata(ContentResolver, Uri)
*/
- public static final int FLAG_SUPPORTS_METADATA = 1 << 17;
+ public static final int FLAG_SUPPORTS_METADATA = 1 << 14;
}
/**
@@ -679,44 +700,46 @@
* @see #COLUMN_FLAGS
* @see ContentResolver#notifyChange(Uri,
* android.database.ContentObserver, boolean)
- * @hide
*/
- public static final int FLAG_EMPTY = 1 << 16;
+ public static final int FLAG_EMPTY = 1 << 6;
/**
* Flag indicating that this root should only be visible to advanced
* users.
*
* @see #COLUMN_FLAGS
- * @hide
+ * {@hide}
*/
- @UnsupportedAppUsage
- public static final int FLAG_ADVANCED = 1 << 17;
+ @SystemApi
+ public static final int FLAG_ADVANCED = 1 << 16;
/**
* Flag indicating that this root has settings.
*
* @see #COLUMN_FLAGS
* @see DocumentsContract#ACTION_DOCUMENT_ROOT_SETTINGS
- * @hide
+ * {@hide}
*/
- public static final int FLAG_HAS_SETTINGS = 1 << 18;
+ @SystemApi
+ public static final int FLAG_HAS_SETTINGS = 1 << 17;
/**
* Flag indicating that this root is on removable SD card storage.
*
* @see #COLUMN_FLAGS
- * @hide
+ * {@hide}
*/
- public static final int FLAG_REMOVABLE_SD = 1 << 19;
+ @SystemApi
+ public static final int FLAG_REMOVABLE_SD = 1 << 18;
/**
* Flag indicating that this root is on removable USB storage.
*
* @see #COLUMN_FLAGS
- * @hide
+ * {@hide}
*/
- public static final int FLAG_REMOVABLE_USB = 1 << 20;
+ @SystemApi
+ public static final int FLAG_REMOVABLE_USB = 1 << 19;
}
/**
@@ -1090,8 +1113,6 @@
* Test if the given URI represents roots backed by {@link DocumentsProvider}.
*
* @see #buildRootsUri(String)
- *
- * {@hide}
*/
public static boolean isRootsUri(Context context, @Nullable Uri uri) {
return isRootUri(context, uri, 1 /* pathSize */);
@@ -1101,8 +1122,6 @@
* Test if the given URI represents specific root backed by {@link DocumentsProvider}.
*
* @see #buildRootUri(String, String)
- *
- * {@hide}
*/
public static boolean isRootUri(Context context, @Nullable Uri uri) {
return isRootUri(context, uri, 2 /* pathSize */);
@@ -1200,13 +1219,23 @@
return bundle.getString(QUERY_ARG_DISPLAY_NAME, "" /* defaultValue */);
}
- /** {@hide} */
- @UnsupportedAppUsage
+ /**
+ * Build URI that append the query parameter {@link PARAM_MANAGE} to
+ * enable the manage mode.
+ * @see DocumentsProvider#queryChildDocumentsForManage(String parentDocId, String[], String)
+ * {@hide}
+ */
+ @SystemApi
public static Uri setManageMode(Uri uri) {
return uri.buildUpon().appendQueryParameter(PARAM_MANAGE, "true").build();
}
- /** {@hide} */
+ /**
+ * Extract the manage mode from a URI built by
+ * {@link #setManageMode(Uri)}.
+ * {@hide}
+ */
+ @SystemApi
public static boolean isManageMode(Uri uri) {
return uri.getBooleanQueryParameter(PARAM_MANAGE, false);
}
@@ -1287,6 +1316,31 @@
return out.getParcelable(DocumentsContract.EXTRA_URI);
}
+
+ /**
+ * Test if a document is descendant (child, grandchild, etc) from the given
+ * parent.
+ *
+ * @param parentDocumentUri parent to verify against.
+ * @param childDocumentUri child to verify.
+ * @return if given document is a descendant of the given parent.
+ * @see Root#FLAG_SUPPORTS_IS_CHILD
+ */
+ public static boolean isChildDocument(ContentResolver resolver, Uri parentDocumentUri,
+ Uri childDocumentUri) throws FileNotFoundException {
+ final ContentProviderClient client = resolver.acquireUnstableContentProviderClient(
+ parentDocumentUri.getAuthority());
+ try {
+ return isChildDocument(client, parentDocumentUri, childDocumentUri);
+ } catch (Exception e) {
+ Log.w(TAG, "Failed to query isChildDocument", e);
+ rethrowIfNecessary(resolver, e);
+ return false;
+ } finally {
+ ContentProviderClient.releaseQuietly(client);
+ }
+ }
+
/** {@hide} */
public static boolean isChildDocument(ContentProviderClient client, Uri parentDocumentUri,
Uri childDocumentUri) throws RemoteException {
@@ -1297,7 +1351,7 @@
final Bundle out = client.call(METHOD_IS_CHILD_DOCUMENT, null, in);
if (out == null) {
- throw new RemoteException("Failed to get a reponse from isChildDocument query.");
+ throw new RemoteException("Failed to get a response from isChildDocument query.");
}
if (!out.containsKey(DocumentsContract.EXTRA_RESULT)) {
throw new RemoteException("Response did not include result field..");
@@ -1513,13 +1567,13 @@
/**
* Returns metadata associated with the document. The type of metadata returned
* is specific to the document type. For example the data returned for an image
- * file will likely consist primarily or soley of EXIF metadata.
+ * file will likely consist primarily or solely of EXIF metadata.
*
* <p>The returned {@link Bundle} will contain zero or more entries depending
* on the type of data supported by the document provider.
*
* <ol>
- * <li>A {@link DocumentsContract.METADATA_TYPES} containing a {@code String[]} value.
+ * <li>A {@link DocumentsContract#METADATA_TYPES} containing a {@code String[]} value.
* The string array identifies the type or types of metadata returned. Each
* value in the can be used to access a {@link Bundle} of data
* containing that type of data.
@@ -1539,7 +1593,6 @@
*
* @param documentUri a Document URI
* @return a Bundle of Bundles.
- * {@hide}
*/
public static Bundle getDocumentMetadata(ContentResolver resolver, Uri documentUri)
throws FileNotFoundException {
diff --git a/core/java/android/provider/DocumentsProvider.java b/core/java/android/provider/DocumentsProvider.java
index 6ab72c7..70c84f8 100644
--- a/core/java/android/provider/DocumentsProvider.java
+++ b/core/java/android/provider/DocumentsProvider.java
@@ -691,7 +691,6 @@
* @see DocumentsContract#EXTRA_LOADING
* @see DocumentsContract#EXTRA_INFO
* @see DocumentsContract#EXTRA_ERROR
- * {@hide}
*/
@SuppressWarnings("unused")
public Cursor querySearchDocuments(String rootId, String[] projection, Bundle queryArgs)
@@ -711,7 +710,28 @@
throw new UnsupportedOperationException("Eject not supported");
}
- /** {@hide} */
+ /**
+ * Returns metadata associated with the document. The type of metadata returned
+ * is specific to the document type. For example the data returned for an image
+ * file will likely consist primarily or solely of EXIF metadata.
+ *
+ * <p>The returned {@link Bundle} will contain zero or more entries depending
+ * on the type of data supported by the document provider.
+ *
+ * <ol>
+ * <li>A {@link DocumentsContract#METADATA_TYPES} containing a {@code String[]} value.
+ * The string array identifies the type or types of metadata returned. Each
+ * value in the can be used to access a {@link Bundle} of data
+ * containing that type of data.
+ * <li>An entry each for each type of returned metadata. Each set of metadata is
+ * itself represented as a bundle and accessible via a string key naming
+ * the type of data.
+ * </ol>
+ *
+ * @param documentId get the metadata of the document
+ * @return a Bundle of Bundles.
+ * @see DocumentsContract#getDocumentMetadata(ContentResolver, Uri)
+ */
public @Nullable Bundle getDocumentMetadata(String documentId)
throws FileNotFoundException {
throw new UnsupportedOperationException("Metadata not supported");