summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.txt2
-rw-r--r--api/system-current.txt2
-rw-r--r--core/java/android/provider/DocumentsContract.java10
-rw-r--r--core/java/android/provider/DocumentsProvider.java60
4 files changed, 64 insertions, 10 deletions
diff --git a/api/current.txt b/api/current.txt
index 0cf1de32270a..3e63cd7237e1 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -26218,6 +26218,7 @@ package android.provider {
field public static final int FLAG_SUPPORTS_MOVE = 256; // 0x100
field public static final int FLAG_SUPPORTS_RENAME = 64; // 0x40
field public static final int FLAG_SUPPORTS_THUMBNAIL = 1; // 0x1
+ field public static final int FLAG_SUPPORTS_TYPED_DOCUMENT = 512; // 0x200
field public static final int FLAG_SUPPORTS_WRITE = 2; // 0x2
field public static final java.lang.String MIME_TYPE_DIR = "vnd.android.document/directory";
}
@@ -26255,6 +26256,7 @@ package android.provider {
method public final android.os.ParcelFileDescriptor openFile(android.net.Uri, java.lang.String, android.os.CancellationSignal) throws java.io.FileNotFoundException;
method public final android.content.res.AssetFileDescriptor openTypedAssetFile(android.net.Uri, java.lang.String, android.os.Bundle) throws java.io.FileNotFoundException;
method public final android.content.res.AssetFileDescriptor openTypedAssetFile(android.net.Uri, java.lang.String, android.os.Bundle, android.os.CancellationSignal) throws java.io.FileNotFoundException;
+ method public android.content.res.AssetFileDescriptor openTypedDocument(java.lang.String, java.lang.String, android.os.Bundle, android.os.CancellationSignal) throws java.io.FileNotFoundException;
method public final android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
method public abstract android.database.Cursor queryChildDocuments(java.lang.String, java.lang.String[], java.lang.String) throws java.io.FileNotFoundException;
method public abstract android.database.Cursor queryDocument(java.lang.String, java.lang.String[]) throws java.io.FileNotFoundException;
diff --git a/api/system-current.txt b/api/system-current.txt
index 1ce9ec39f40b..42753ee96d92 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -28207,6 +28207,7 @@ package android.provider {
field public static final int FLAG_SUPPORTS_MOVE = 256; // 0x100
field public static final int FLAG_SUPPORTS_RENAME = 64; // 0x40
field public static final int FLAG_SUPPORTS_THUMBNAIL = 1; // 0x1
+ field public static final int FLAG_SUPPORTS_TYPED_DOCUMENT = 512; // 0x200
field public static final int FLAG_SUPPORTS_WRITE = 2; // 0x2
field public static final java.lang.String MIME_TYPE_DIR = "vnd.android.document/directory";
}
@@ -28244,6 +28245,7 @@ package android.provider {
method public final android.os.ParcelFileDescriptor openFile(android.net.Uri, java.lang.String, android.os.CancellationSignal) throws java.io.FileNotFoundException;
method public final android.content.res.AssetFileDescriptor openTypedAssetFile(android.net.Uri, java.lang.String, android.os.Bundle) throws java.io.FileNotFoundException;
method public final android.content.res.AssetFileDescriptor openTypedAssetFile(android.net.Uri, java.lang.String, android.os.Bundle, android.os.CancellationSignal) throws java.io.FileNotFoundException;
+ method public android.content.res.AssetFileDescriptor openTypedDocument(java.lang.String, java.lang.String, android.os.Bundle, android.os.CancellationSignal) throws java.io.FileNotFoundException;
method public final android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
method public abstract android.database.Cursor queryChildDocuments(java.lang.String, java.lang.String[], java.lang.String) throws java.io.FileNotFoundException;
method public abstract android.database.Cursor queryDocument(java.lang.String, java.lang.String[]) throws java.io.FileNotFoundException;
diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java
index 241e6db91756..159ca01d3f85 100644
--- a/core/java/android/provider/DocumentsContract.java
+++ b/core/java/android/provider/DocumentsContract.java
@@ -231,6 +231,7 @@ public final class DocumentsContract {
* @see #FLAG_SUPPORTS_WRITE
* @see #FLAG_SUPPORTS_DELETE
* @see #FLAG_SUPPORTS_THUMBNAIL
+ * @see #FLAG_SUPPORTS_TYPED_DOCUMENT
* @see #FLAG_DIR_PREFERS_GRID
* @see #FLAG_DIR_PREFERS_LAST_MODIFIED
*/
@@ -347,6 +348,15 @@ public final class DocumentsContract {
public static final int FLAG_SUPPORTS_MOVE = 1 << 8;
/**
+ * Flag indicating that a document can be converted to alternative types.
+ *
+ * @see #COLUMN_FLAGS
+ * @see DocumentsProvider#openTypedDocument(String, String, Bundle,
+ * android.os.CancellationSignal)
+ */
+ public static final int FLAG_SUPPORTS_TYPED_DOCUMENT = 1 << 9;
+
+ /**
* Flag indicating that document titles should be hidden when viewing
* this directory in a larger format grid. For example, a directory
* containing only images may want the image thumbnails to speak for
diff --git a/core/java/android/provider/DocumentsProvider.java b/core/java/android/provider/DocumentsProvider.java
index 28ac165b1003..f01073bbd43d 100644
--- a/core/java/android/provider/DocumentsProvider.java
+++ b/core/java/android/provider/DocumentsProvider.java
@@ -31,6 +31,7 @@ import static android.provider.DocumentsContract.getTreeDocumentId;
import static android.provider.DocumentsContract.isTreeUri;
import android.annotation.CallSuper;
+import android.content.ClipDescription;
import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.ContentValues;
@@ -502,6 +503,29 @@ public abstract class DocumentsProvider extends ContentProvider {
}
/**
+ * Open and return the document in a format matching the specified MIME
+ * type filter.
+ * <p>
+ * A provider may perform a conversion if the documents's MIME type is not
+ * matching the specified MIME type filter.
+ *
+ * @param documentId the document to return.
+ * @param mimeTypeFilter the MIME type filter for the requested format. May
+ * be *\/*, which matches any MIME type.
+ * @param opts extra options from the client. Specific to the content
+ * provider.
+ * @param signal used by the caller to signal if the request should be
+ * cancelled. May be null.
+ * @see Document#FLAG_SUPPORTS_TYPED_DOCUMENT
+ */
+ @SuppressWarnings("unused")
+ public AssetFileDescriptor openTypedDocument(
+ String documentId, String mimeTypeFilter, Bundle opts, CancellationSignal signal)
+ throws FileNotFoundException {
+ throw new UnsupportedOperationException("Typed documents not supported");
+ }
+
+ /**
* Implementation is provided by the parent class. Cannot be overriden.
*
* @see #queryRoots(String[])
@@ -846,34 +870,50 @@ public abstract class DocumentsProvider extends ContentProvider {
* Implementation is provided by the parent class. Cannot be overriden.
*
* @see #openDocumentThumbnail(String, Point, CancellationSignal)
+ * @see #openTypedDocument(String, String, Bundle, CancellationSignal)
*/
@Override
public final AssetFileDescriptor openTypedAssetFile(Uri uri, String mimeTypeFilter, Bundle opts)
throws FileNotFoundException {
- enforceTree(uri);
- if (opts != null && opts.containsKey(ContentResolver.EXTRA_SIZE)) {
- final Point sizeHint = opts.getParcelable(ContentResolver.EXTRA_SIZE);
- return openDocumentThumbnail(getDocumentId(uri), sizeHint, null);
- } else {
- return super.openTypedAssetFile(uri, mimeTypeFilter, opts);
- }
+ return openTypedAssetFileImpl(uri, mimeTypeFilter, opts, null);
}
/**
* Implementation is provided by the parent class. Cannot be overriden.
*
* @see #openDocumentThumbnail(String, Point, CancellationSignal)
+ * @see #openTypedDocument(String, String, Bundle, CancellationSignal)
*/
@Override
public final AssetFileDescriptor openTypedAssetFile(
Uri uri, String mimeTypeFilter, Bundle opts, CancellationSignal signal)
throws FileNotFoundException {
+ return openTypedAssetFileImpl(uri, mimeTypeFilter, opts, signal);
+ }
+
+ /**
+ * @hide
+ */
+ private final AssetFileDescriptor openTypedAssetFileImpl(
+ Uri uri, String mimeTypeFilter, Bundle opts, CancellationSignal signal)
+ throws FileNotFoundException {
enforceTree(uri);
+ final String documentId = getDocumentId(uri);
if (opts != null && opts.containsKey(ContentResolver.EXTRA_SIZE)) {
final Point sizeHint = opts.getParcelable(ContentResolver.EXTRA_SIZE);
- return openDocumentThumbnail(getDocumentId(uri), sizeHint, signal);
- } else {
- return super.openTypedAssetFile(uri, mimeTypeFilter, opts, signal);
+ return openDocumentThumbnail(documentId, sizeHint, signal);
+ }
+ if ("*/*".equals(mimeTypeFilter)) {
+ // If they can take anything, the untyped open call is good enough.
+ return openAssetFile(uri, "r");
+ }
+ final String baseType = getType(uri);
+ if (baseType != null && ClipDescription.compareMimeTypes(baseType, mimeTypeFilter)) {
+ // Use old untyped open call if this provider has a type for this
+ // URI and it matches the request.
+ return openAssetFile(uri, "r");
}
+ // For any other yet unhandled case, let the provider subclass handle it.
+ return openTypedDocument(documentId, mimeTypeFilter, opts, signal);
}
}