diff options
| -rw-r--r-- | api/current.txt | 2 | ||||
| -rw-r--r-- | api/system-current.txt | 2 | ||||
| -rw-r--r-- | core/java/android/provider/DocumentsContract.java | 10 | ||||
| -rw-r--r-- | core/java/android/provider/DocumentsProvider.java | 60 |
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); } } |