diff options
| author | 2019-02-18 16:42:07 +0000 | |
|---|---|---|
| committer | 2019-02-18 16:42:07 +0000 | |
| commit | c2b55eb98f66bf5b5a0e4829912b2de91c3d0a57 (patch) | |
| tree | 50bc885391dab08b6c3e231ff579c97a89c028e4 | |
| parent | 71779d34f2cbd0114e2b551b4cce3e10d8d46034 (diff) | |
| parent | 497789ebd92d732cf9c8f3d2933ecc80728354a9 (diff) | |
Merge changes from topic "wrapz"
* changes:
Add tests for DocumentsContract/Provider.
Replace ContentInterface with wrapping.
| -rw-r--r-- | api/current.txt | 64 | ||||
| -rw-r--r-- | api/system-current.txt | 4 | ||||
| -rw-r--r-- | api/test-current.txt | 4 | ||||
| -rw-r--r-- | core/java/android/content/ContentInterface.java | 2 | ||||
| -rw-r--r-- | core/java/android/content/ContentProvider.java | 3 | ||||
| -rw-r--r-- | core/java/android/content/ContentResolver.java | 157 | ||||
| -rw-r--r-- | core/java/android/provider/DocumentsContract.java | 120 | ||||
| -rw-r--r-- | core/tests/coretests/src/android/provider/DocumentsProviderTest.java | 3 |
8 files changed, 210 insertions, 147 deletions
diff --git a/api/current.txt b/api/current.txt index fe52f3ae83cb..1c60efa62be3 100644 --- a/api/current.txt +++ b/api/current.txt @@ -9348,25 +9348,7 @@ package android.content { field public static final android.os.Parcelable.Creator<android.content.ComponentName> CREATOR; } - public interface ContentInterface { - method @NonNull public android.content.ContentProviderResult[] applyBatch(@NonNull String, @NonNull java.util.ArrayList<android.content.ContentProviderOperation>) throws android.content.OperationApplicationException, android.os.RemoteException; - method public int bulkInsert(@NonNull android.net.Uri, @NonNull android.content.ContentValues[]) throws android.os.RemoteException; - method @Nullable public android.os.Bundle call(@NonNull String, @NonNull String, @Nullable String, @Nullable android.os.Bundle) throws android.os.RemoteException; - method @Nullable public android.net.Uri canonicalize(@NonNull android.net.Uri) throws android.os.RemoteException; - method public int delete(@NonNull android.net.Uri, @Nullable String, @Nullable String[]) throws android.os.RemoteException; - method @Nullable public String[] getStreamTypes(@NonNull android.net.Uri, @NonNull String) throws android.os.RemoteException; - method @Nullable public String getType(@NonNull android.net.Uri) throws android.os.RemoteException; - method @Nullable public android.net.Uri insert(@NonNull android.net.Uri, @Nullable android.content.ContentValues) throws android.os.RemoteException; - method @Nullable public android.content.res.AssetFileDescriptor openAssetFile(@NonNull android.net.Uri, @NonNull String, @Nullable android.os.CancellationSignal) throws java.io.FileNotFoundException, android.os.RemoteException; - method @Nullable public android.os.ParcelFileDescriptor openFile(@NonNull android.net.Uri, @NonNull String, @Nullable android.os.CancellationSignal) throws java.io.FileNotFoundException, android.os.RemoteException; - method @Nullable public android.content.res.AssetFileDescriptor openTypedAssetFile(@NonNull android.net.Uri, @NonNull String, @Nullable android.os.Bundle, @Nullable android.os.CancellationSignal) throws java.io.FileNotFoundException, android.os.RemoteException; - method @Nullable public android.database.Cursor query(@NonNull android.net.Uri, @Nullable String[], @Nullable android.os.Bundle, @Nullable android.os.CancellationSignal) throws android.os.RemoteException; - method public boolean refresh(@NonNull android.net.Uri, @Nullable android.os.Bundle, @Nullable android.os.CancellationSignal) throws android.os.RemoteException; - method @Nullable public android.net.Uri uncanonicalize(@NonNull android.net.Uri) throws android.os.RemoteException; - method public int update(@NonNull android.net.Uri, @Nullable android.content.ContentValues, @Nullable String, @Nullable String[]) throws android.os.RemoteException; - } - - public abstract class ContentProvider implements android.content.ComponentCallbacks2 android.content.ContentInterface { + public abstract class ContentProvider implements android.content.ComponentCallbacks2 { ctor public ContentProvider(); method @NonNull public android.content.ContentProviderResult[] applyBatch(@NonNull String, @NonNull java.util.ArrayList<android.content.ContentProviderOperation>) throws android.content.OperationApplicationException; method @NonNull public android.content.ContentProviderResult[] applyBatch(@NonNull java.util.ArrayList<android.content.ContentProviderOperation>) throws android.content.OperationApplicationException; @@ -9419,7 +9401,7 @@ package android.content { method public void writeDataToPipe(@NonNull android.os.ParcelFileDescriptor, @NonNull android.net.Uri, @NonNull String, @Nullable android.os.Bundle, @Nullable T); } - public class ContentProviderClient implements java.lang.AutoCloseable android.content.ContentInterface { + public class ContentProviderClient implements java.lang.AutoCloseable { method @NonNull public android.content.ContentProviderResult[] applyBatch(@NonNull java.util.ArrayList<android.content.ContentProviderOperation>) throws android.content.OperationApplicationException, android.os.RemoteException; method @NonNull public android.content.ContentProviderResult[] applyBatch(@NonNull String, @NonNull java.util.ArrayList<android.content.ContentProviderOperation>) throws android.content.OperationApplicationException, android.os.RemoteException; method public int bulkInsert(@NonNull android.net.Uri, @NonNull android.content.ContentValues[]) throws android.os.RemoteException; @@ -9502,8 +9484,8 @@ package android.content { method public void setKeepUpdated(boolean); } - public abstract class ContentResolver implements android.content.ContentInterface { - ctor public ContentResolver(android.content.Context); + public abstract class ContentResolver { + ctor public ContentResolver(@Nullable android.content.Context); method @Nullable public final android.content.ContentProviderClient acquireContentProviderClient(@NonNull android.net.Uri); method @Nullable public final android.content.ContentProviderClient acquireContentProviderClient(@NonNull String); method @Nullable public final android.content.ContentProviderClient acquireUnstableContentProviderClient(@NonNull android.net.Uri); @@ -9568,6 +9550,8 @@ package android.content { method public final void unregisterContentObserver(@NonNull android.database.ContentObserver); method public final int update(@RequiresPermission.Write @NonNull android.net.Uri, @Nullable android.content.ContentValues, @Nullable String, @Nullable String[]); method public static void validateSyncExtrasBundle(android.os.Bundle); + method public static android.content.ContentResolver wrap(@NonNull android.content.ContentProvider); + method public static android.content.ContentResolver wrap(@NonNull android.content.ContentProviderClient); field public static final String ANY_CURSOR_ITEM_TYPE = "vnd.android.cursor.item/*"; field public static final String CURSOR_DIR_BASE_TYPE = "vnd.android.cursor.dir"; field public static final String CURSOR_ITEM_BASE_TYPE = "vnd.android.cursor.item"; @@ -38171,38 +38155,26 @@ package android.provider { method public static android.net.Uri buildRootsUri(String); method public static android.net.Uri buildSearchDocumentsUri(String, String, String); method public static android.net.Uri buildTreeDocumentUri(String, String); - method public static android.net.Uri copyDocument(android.content.ContentInterface, android.net.Uri, android.net.Uri) throws java.io.FileNotFoundException; - method @Deprecated public static android.net.Uri copyDocument(android.content.ContentResolver, android.net.Uri, android.net.Uri) throws java.io.FileNotFoundException; - method public static android.net.Uri createDocument(android.content.ContentInterface, android.net.Uri, String, String) throws java.io.FileNotFoundException; - method @Deprecated public static android.net.Uri createDocument(android.content.ContentResolver, android.net.Uri, String, String) throws java.io.FileNotFoundException; - method public static android.content.IntentSender createWebLinkIntent(android.content.ContentInterface, android.net.Uri, android.os.Bundle) throws java.io.FileNotFoundException; - method @Deprecated public static android.content.IntentSender createWebLinkIntent(android.content.ContentResolver, android.net.Uri, android.os.Bundle) throws java.io.FileNotFoundException; - method public static boolean deleteDocument(android.content.ContentInterface, android.net.Uri) throws java.io.FileNotFoundException; - method @Deprecated public static boolean deleteDocument(android.content.ContentResolver, android.net.Uri) throws java.io.FileNotFoundException; - method public static void ejectRoot(android.content.ContentInterface, android.net.Uri); - method @Deprecated public static void ejectRoot(android.content.ContentResolver, android.net.Uri); - method public static android.provider.DocumentsContract.Path findDocumentPath(android.content.ContentInterface, android.net.Uri) throws java.io.FileNotFoundException; - method @Deprecated public static android.provider.DocumentsContract.Path findDocumentPath(android.content.ContentResolver, android.net.Uri) throws java.io.FileNotFoundException; + method @Nullable public static android.net.Uri copyDocument(@NonNull android.content.ContentResolver, @NonNull android.net.Uri, @NonNull android.net.Uri) throws java.io.FileNotFoundException; + method @Nullable public static android.net.Uri createDocument(@NonNull android.content.ContentResolver, @NonNull android.net.Uri, @NonNull String, @NonNull String) throws java.io.FileNotFoundException; + method @Nullable public static android.content.IntentSender createWebLinkIntent(@NonNull android.content.ContentResolver, @NonNull android.net.Uri, @Nullable android.os.Bundle) throws java.io.FileNotFoundException; + method public static boolean deleteDocument(@NonNull android.content.ContentResolver, @NonNull android.net.Uri) throws java.io.FileNotFoundException; + method public static void ejectRoot(@NonNull android.content.ContentResolver, @NonNull android.net.Uri); + method @Nullable public static android.provider.DocumentsContract.Path findDocumentPath(@NonNull android.content.ContentResolver, @NonNull android.net.Uri) throws java.io.FileNotFoundException; method public static String getDocumentId(android.net.Uri); - method @Nullable public static android.os.Bundle getDocumentMetadata(@NonNull android.content.ContentInterface, @NonNull android.net.Uri) throws java.io.FileNotFoundException; - method @Deprecated 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.ContentInterface, android.net.Uri, android.graphics.Point, android.os.CancellationSignal) throws java.io.FileNotFoundException; - method @Deprecated public static android.graphics.Bitmap getDocumentThumbnail(android.content.ContentResolver, android.net.Uri, android.graphics.Point, android.os.CancellationSignal) throws java.io.FileNotFoundException; + method @Nullable public static android.os.Bundle getDocumentMetadata(@NonNull android.content.ContentResolver, @NonNull android.net.Uri) throws java.io.FileNotFoundException; + method @Nullable public static android.graphics.Bitmap getDocumentThumbnail(@NonNull android.content.ContentResolver, @NonNull android.net.Uri, @NonNull android.graphics.Point, @Nullable android.os.CancellationSignal) throws java.io.FileNotFoundException; method public static String getRootId(android.net.Uri); method public static String getSearchDocumentsQuery(android.net.Uri); method public static String getTreeDocumentId(android.net.Uri); - method public static boolean isChildDocument(@NonNull android.content.ContentInterface, @NonNull android.net.Uri, @NonNull android.net.Uri) throws java.io.FileNotFoundException; - method @Deprecated public static boolean isChildDocument(android.content.ContentResolver, android.net.Uri, android.net.Uri) throws java.io.FileNotFoundException; + method public static boolean isChildDocument(@NonNull android.content.ContentResolver, @NonNull android.net.Uri, @NonNull android.net.Uri) throws java.io.FileNotFoundException; method public static boolean isDocumentUri(android.content.Context, @Nullable android.net.Uri); method public static boolean isRootUri(@NonNull android.content.Context, @Nullable android.net.Uri); method public static boolean isRootsUri(@NonNull android.content.Context, @Nullable android.net.Uri); method public static boolean isTreeUri(android.net.Uri); - method public static android.net.Uri moveDocument(android.content.ContentInterface, android.net.Uri, android.net.Uri, android.net.Uri) throws java.io.FileNotFoundException; - method @Deprecated 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.ContentInterface, android.net.Uri, android.net.Uri) throws java.io.FileNotFoundException; - method @Deprecated public static boolean removeDocument(android.content.ContentResolver, android.net.Uri, android.net.Uri) throws java.io.FileNotFoundException; - method public static android.net.Uri renameDocument(android.content.ContentInterface, android.net.Uri, String) throws java.io.FileNotFoundException; - method @Deprecated public static android.net.Uri renameDocument(android.content.ContentResolver, android.net.Uri, String) throws java.io.FileNotFoundException; + method @Nullable public static android.net.Uri moveDocument(@NonNull android.content.ContentResolver, @NonNull android.net.Uri, @NonNull android.net.Uri, @NonNull android.net.Uri) throws java.io.FileNotFoundException; + method public static boolean removeDocument(@NonNull android.content.ContentResolver, @NonNull android.net.Uri, @NonNull android.net.Uri) throws java.io.FileNotFoundException; + method @Nullable public static android.net.Uri renameDocument(@NonNull android.content.ContentResolver, @NonNull android.net.Uri, @NonNull String) throws java.io.FileNotFoundException; field public static final String ACTION_DOCUMENT_SETTINGS = "android.provider.action.DOCUMENT_SETTINGS"; field public static final String EXTRA_ERROR = "error"; field public static final String EXTRA_EXCLUDE_SELF = "android.provider.extra.EXCLUDE_SELF"; diff --git a/api/system-current.txt b/api/system-current.txt index b75051f27fc9..128ee99c27ad 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -1295,11 +1295,11 @@ package android.bluetooth.le { package android.content { - public class ContentProviderClient implements java.lang.AutoCloseable android.content.ContentInterface { + public class ContentProviderClient implements java.lang.AutoCloseable { method @RequiresPermission(android.Manifest.permission.REMOVE_TASKS) public void setDetectNotResponding(long); } - public abstract class ContentResolver implements android.content.ContentInterface { + public abstract class ContentResolver { method public android.os.Bundle getCache(android.net.Uri); method public android.graphics.drawable.Drawable getTypeDrawable(String); method public void putCache(android.net.Uri, android.os.Bundle); diff --git a/api/test-current.txt b/api/test-current.txt index a371a17de4a1..01678b1c1066 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -483,11 +483,11 @@ package android.bluetooth { package android.content { - public class ContentProviderClient implements java.lang.AutoCloseable android.content.ContentInterface { + public class ContentProviderClient implements java.lang.AutoCloseable { method @RequiresPermission(android.Manifest.permission.REMOVE_TASKS) public void setDetectNotResponding(long); } - public abstract class ContentResolver implements android.content.ContentInterface { + public abstract class ContentResolver { method public static String[] getSyncAdapterPackagesForAuthorityAsUser(String, int); } diff --git a/core/java/android/content/ContentInterface.java b/core/java/android/content/ContentInterface.java index 3d732eb7678d..d41d8d9cc1e2 100644 --- a/core/java/android/content/ContentInterface.java +++ b/core/java/android/content/ContentInterface.java @@ -36,6 +36,8 @@ import java.util.ArrayList; * These methods have been extracted into a general interface so that APIs can * be flexible in accepting either a {@link ContentProvider}, a * {@link ContentResolver}, or a {@link ContentProviderClient}. + * + * @hide */ public interface ContentInterface { public @Nullable Cursor query(@NonNull Uri uri, @Nullable String[] projection, diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java index f138d39b7fb0..e06322df7a7f 100644 --- a/core/java/android/content/ContentProvider.java +++ b/core/java/android/content/ContentProvider.java @@ -134,7 +134,7 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall private boolean mNoPerms; private boolean mSingleUser; - private final ThreadLocal<String> mCallingPackage = new ThreadLocal<>(); + private ThreadLocal<String> mCallingPackage; private Transport mTransport = new Transport(); @@ -2034,6 +2034,7 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall private void attachInfo(Context context, ProviderInfo info, boolean testing) { mNoPerms = testing; + mCallingPackage = new ThreadLocal<>(); /* * Only allow it to be set once, so after the content service gives diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java index 7672ccfcd995..bbfa5cceec1d 100644 --- a/core/java/android/content/ContentResolver.java +++ b/core/java/android/content/ContentResolver.java @@ -609,10 +609,60 @@ public abstract class ContentResolver implements ContentInterface { private static final int SLOW_THRESHOLD_MILLIS = 500; private final Random mRandom = new Random(); // guarded by itself - public ContentResolver(Context context) { + public ContentResolver(@Nullable Context context) { + this(context, null); + } + + /** {@hide} */ + public ContentResolver(@Nullable Context context, @Nullable ContentInterface wrapped) { mContext = context != null ? context : ActivityThread.currentApplication(); mPackageName = mContext.getOpPackageName(); mTargetSdkVersion = mContext.getApplicationInfo().targetSdkVersion; + mWrapped = wrapped; + } + + /** {@hide} */ + public static ContentResolver wrap(@NonNull ContentInterface wrapped) { + Preconditions.checkNotNull(wrapped); + + return new ContentResolver(null, wrapped) { + @Override + public void unstableProviderDied(IContentProvider icp) { + throw new UnsupportedOperationException(); + } + @Override + public boolean releaseUnstableProvider(IContentProvider icp) { + throw new UnsupportedOperationException(); + } + @Override + public boolean releaseProvider(IContentProvider icp) { + throw new UnsupportedOperationException(); + } + @Override + protected IContentProvider acquireUnstableProvider(Context c, String name) { + throw new UnsupportedOperationException(); + } + @Override + protected IContentProvider acquireProvider(Context c, String name) { + throw new UnsupportedOperationException(); + } + }; + } + + /** + * Create a {@link ContentResolver} instance that redirects all its methods + * to the given {@link ContentProvider}. + */ + public static ContentResolver wrap(@NonNull ContentProvider wrapped) { + return wrap((ContentInterface) wrapped); + } + + /** + * Create a {@link ContentResolver} instance that redirects all its methods + * to the given {@link ContentProviderClient}. + */ + public static ContentResolver wrap(@NonNull ContentProviderClient wrapped) { + return wrap((ContentInterface) wrapped); } /** @hide */ @@ -660,6 +710,12 @@ public abstract class ContentResolver implements ContentInterface { public final @Nullable String getType(@NonNull Uri url) { Preconditions.checkNotNull(url, "url"); + try { + if (mWrapped != null) return mWrapped.getType(url); + } catch (RemoteException e) { + return null; + } + // XXX would like to have an acquireExistingUnstableProvider for this. IContentProvider provider = acquireExistingProvider(url); if (provider != null) { @@ -715,6 +771,12 @@ public abstract class ContentResolver implements ContentInterface { Preconditions.checkNotNull(url, "url"); Preconditions.checkNotNull(mimeTypeFilter, "mimeTypeFilter"); + try { + if (mWrapped != null) return mWrapped.getStreamTypes(url, mimeTypeFilter); + } catch (RemoteException e) { + return null; + } + IContentProvider provider = acquireProvider(url); if (provider == null) { return null; @@ -843,6 +905,15 @@ public abstract class ContentResolver implements ContentInterface { @Nullable String[] projection, @Nullable Bundle queryArgs, @Nullable CancellationSignal cancellationSignal) { Preconditions.checkNotNull(uri, "uri"); + + try { + if (mWrapped != null) { + return mWrapped.query(uri, projection, queryArgs, cancellationSignal); + } + } catch (RemoteException e) { + return null; + } + IContentProvider unstableProvider = acquireUnstableProvider(uri); if (unstableProvider == null) { return null; @@ -942,6 +1013,13 @@ public abstract class ContentResolver implements ContentInterface { @Override public final @Nullable Uri canonicalize(@NonNull Uri url) { Preconditions.checkNotNull(url, "url"); + + try { + if (mWrapped != null) return mWrapped.canonicalize(url); + } catch (RemoteException e) { + return null; + } + IContentProvider provider = acquireProvider(url); if (provider == null) { return null; @@ -979,6 +1057,13 @@ public abstract class ContentResolver implements ContentInterface { @Override public final @Nullable Uri uncanonicalize(@NonNull Uri url) { Preconditions.checkNotNull(url, "url"); + + try { + if (mWrapped != null) return mWrapped.uncanonicalize(url); + } catch (RemoteException e) { + return null; + } + IContentProvider provider = acquireProvider(url); if (provider == null) { return null; @@ -1015,6 +1100,13 @@ public abstract class ContentResolver implements ContentInterface { public final boolean refresh(@NonNull Uri url, @Nullable Bundle args, @Nullable CancellationSignal cancellationSignal) { Preconditions.checkNotNull(url, "url"); + + try { + if (mWrapped != null) return mWrapped.refresh(url, args, cancellationSignal); + } catch (RemoteException e) { + return false; + } + IContentProvider provider = acquireProvider(url); if (provider == null) { return false; @@ -1126,6 +1218,12 @@ public abstract class ContentResolver implements ContentInterface { @Override public final @Nullable ParcelFileDescriptor openFile(@NonNull Uri uri, @NonNull String mode, @Nullable CancellationSignal signal) throws FileNotFoundException { + try { + if (mWrapped != null) return mWrapped.openFile(uri, mode, signal); + } catch (RemoteException e) { + return null; + } + return openFileDescriptor(uri, mode, signal); } @@ -1237,6 +1335,12 @@ public abstract class ContentResolver implements ContentInterface { @Override public final @Nullable AssetFileDescriptor openAssetFile(@NonNull Uri uri, @NonNull String mode, @Nullable CancellationSignal signal) throws FileNotFoundException { + try { + if (mWrapped != null) return mWrapped.openAssetFile(uri, mode, signal); + } catch (RemoteException e) { + return null; + } + return openAssetFileDescriptor(uri, mode, signal); } @@ -1448,6 +1552,14 @@ public abstract class ContentResolver implements ContentInterface { public final @Nullable AssetFileDescriptor openTypedAssetFile(@NonNull Uri uri, @NonNull String mimeTypeFilter, @Nullable Bundle opts, @Nullable CancellationSignal signal) throws FileNotFoundException { + try { + if (mWrapped != null) { + return mWrapped.openTypedAssetFile(uri, mimeTypeFilter, opts, signal); + } + } catch (RemoteException e) { + return null; + } + return openTypedAssetFileDescriptor(uri, mimeTypeFilter, opts, signal); } @@ -1664,6 +1776,13 @@ public abstract class ContentResolver implements ContentInterface { public final @Nullable Uri insert(@RequiresPermission.Write @NonNull Uri url, @Nullable ContentValues values) { Preconditions.checkNotNull(url, "url"); + + try { + if (mWrapped != null) return mWrapped.insert(url, values); + } catch (RemoteException e) { + return null; + } + IContentProvider provider = acquireProvider(url); if (provider == null) { throw new IllegalArgumentException("Unknown URL " + url); @@ -1705,6 +1824,13 @@ public abstract class ContentResolver implements ContentInterface { throws RemoteException, OperationApplicationException { Preconditions.checkNotNull(authority, "authority"); Preconditions.checkNotNull(operations, "operations"); + + try { + if (mWrapped != null) return mWrapped.applyBatch(authority, operations); + } catch (RemoteException e) { + return null; + } + ContentProviderClient provider = acquireContentProviderClient(authority); if (provider == null) { throw new IllegalArgumentException("Unknown authority " + authority); @@ -1731,6 +1857,13 @@ public abstract class ContentResolver implements ContentInterface { @NonNull ContentValues[] values) { Preconditions.checkNotNull(url, "url"); Preconditions.checkNotNull(values, "values"); + + try { + if (mWrapped != null) return mWrapped.bulkInsert(url, values); + } catch (RemoteException e) { + return 0; + } + IContentProvider provider = acquireProvider(url); if (provider == null) { throw new IllegalArgumentException("Unknown URL " + url); @@ -1764,6 +1897,13 @@ public abstract class ContentResolver implements ContentInterface { public final int delete(@RequiresPermission.Write @NonNull Uri url, @Nullable String where, @Nullable String[] selectionArgs) { Preconditions.checkNotNull(url, "url"); + + try { + if (mWrapped != null) return mWrapped.delete(url, where, selectionArgs); + } catch (RemoteException e) { + return 0; + } + IContentProvider provider = acquireProvider(url); if (provider == null) { throw new IllegalArgumentException("Unknown URL " + url); @@ -1801,6 +1941,13 @@ public abstract class ContentResolver implements ContentInterface { @Nullable ContentValues values, @Nullable String where, @Nullable String[] selectionArgs) { Preconditions.checkNotNull(uri, "uri"); + + try { + if (mWrapped != null) return mWrapped.update(uri, values, where, selectionArgs); + } catch (RemoteException e) { + return 0; + } + IContentProvider provider = acquireProvider(uri); if (provider == null) { throw new IllegalArgumentException("Unknown URI " + uri); @@ -1844,6 +1991,13 @@ public abstract class ContentResolver implements ContentInterface { @Nullable String arg, @Nullable Bundle extras) { Preconditions.checkNotNull(authority, "authority"); Preconditions.checkNotNull(method, "method"); + + try { + if (mWrapped != null) return mWrapped.call(authority, method, arg, extras); + } catch (RemoteException e) { + return null; + } + IContentProvider provider = acquireProvider(authority); if (provider == null) { throw new IllegalArgumentException("Unknown authority " + authority); @@ -3193,6 +3347,7 @@ public abstract class ContentResolver implements ContentInterface { @UnsupportedAppUsage final String mPackageName; final int mTargetSdkVersion; + final ContentInterface mWrapped; private static final String TAG = "ContentResolver"; diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java index 570834265237..d28296786759 100644 --- a/core/java/android/provider/DocumentsContract.java +++ b/core/java/android/provider/DocumentsContract.java @@ -1281,8 +1281,9 @@ public final class DocumentsContract { * @see DocumentsProvider#openDocumentThumbnail(String, Point, * android.os.CancellationSignal) */ - public static Bitmap getDocumentThumbnail(ContentInterface content, Uri documentUri, Point size, - CancellationSignal signal) throws FileNotFoundException { + public static @Nullable Bitmap getDocumentThumbnail(@NonNull ContentResolver content, + @NonNull Uri documentUri, @NonNull Point size, @Nullable CancellationSignal signal) + throws FileNotFoundException { try { return ContentResolver.loadThumbnail(content, documentUri, Point.convert(size), signal, ImageDecoder.ALLOCATOR_SOFTWARE); @@ -1295,12 +1296,6 @@ public final class DocumentsContract { } } - @Deprecated - public static Bitmap getDocumentThumbnail(ContentResolver content, Uri documentUri, Point size, - CancellationSignal signal) throws FileNotFoundException { - return getDocumentThumbnail((ContentInterface) content, documentUri, size, signal); - } - /** * Create a new document with given MIME type and display name. * @@ -1309,8 +1304,9 @@ public final class DocumentsContract { * @param displayName name of new document * @return newly created document, or {@code null} if failed */ - public static Uri createDocument(ContentInterface content, Uri parentDocumentUri, - String mimeType, String displayName) throws FileNotFoundException { + public static @Nullable Uri createDocument(@NonNull ContentResolver content, + @NonNull Uri parentDocumentUri, @NonNull String mimeType, @NonNull String displayName) + throws FileNotFoundException { try { final Bundle in = new Bundle(); in.putParcelable(DocumentsContract.EXTRA_URI, parentDocumentUri); @@ -1327,12 +1323,6 @@ public final class DocumentsContract { } } - @Deprecated - public static Uri createDocument(ContentResolver content, Uri parentDocumentUri, - String mimeType, String displayName) throws FileNotFoundException { - return createDocument((ContentInterface) content, parentDocumentUri, mimeType, displayName); - } - /** * Test if a document is descendant (child, grandchild, etc) from the given * parent. @@ -1342,7 +1332,7 @@ public final class DocumentsContract { * @return if given document is a descendant of the given parent. * @see Root#FLAG_SUPPORTS_IS_CHILD */ - public static boolean isChildDocument(@NonNull ContentInterface content, + public static boolean isChildDocument(@NonNull ContentResolver content, @NonNull Uri parentDocumentUri, @NonNull Uri childDocumentUri) throws FileNotFoundException { Preconditions.checkNotNull(content, "content can not be null"); @@ -1369,12 +1359,6 @@ public final class DocumentsContract { } } - @Deprecated - public static boolean isChildDocument(ContentResolver content, Uri parentDocumentUri, - Uri childDocumentUri) throws FileNotFoundException { - return isChildDocument((ContentInterface) content, parentDocumentUri, childDocumentUri); - } - /** * Change the display name of an existing document. * <p> @@ -1388,8 +1372,8 @@ public final class DocumentsContract { * @return the existing or new document after the rename, or {@code null} if * failed. */ - public static Uri renameDocument(ContentInterface content, Uri documentUri, - String displayName) throws FileNotFoundException { + public static @Nullable Uri renameDocument(@NonNull ContentResolver content, + @NonNull Uri documentUri, @NonNull String displayName) throws FileNotFoundException { try { final Bundle in = new Bundle(); in.putParcelable(DocumentsContract.EXTRA_URI, documentUri); @@ -1406,19 +1390,13 @@ public final class DocumentsContract { } } - @Deprecated - public static Uri renameDocument(ContentResolver content, Uri documentUri, - String displayName) throws FileNotFoundException { - return renameDocument((ContentInterface) content, documentUri, displayName); - } - /** * Delete the given document. * * @param documentUri document with {@link Document#FLAG_SUPPORTS_DELETE} * @return if the document was deleted successfully. */ - public static boolean deleteDocument(ContentInterface content, Uri documentUri) + public static boolean deleteDocument(@NonNull ContentResolver content, @NonNull Uri documentUri) throws FileNotFoundException { try { final Bundle in = new Bundle(); @@ -1434,12 +1412,6 @@ public final class DocumentsContract { } } - @Deprecated - public static boolean deleteDocument(ContentResolver content, Uri documentUri) - throws FileNotFoundException { - return deleteDocument((ContentInterface) content, documentUri); - } - /** * Copies the given document. * @@ -1448,8 +1420,9 @@ public final class DocumentsContract { * document's copy. * @return the copied document, or {@code null} if failed. */ - public static Uri copyDocument(ContentInterface content, Uri sourceDocumentUri, - Uri targetParentDocumentUri) throws FileNotFoundException { + public static @Nullable Uri copyDocument(@NonNull ContentResolver content, + @NonNull Uri sourceDocumentUri, @NonNull Uri targetParentDocumentUri) + throws FileNotFoundException { try { final Bundle in = new Bundle(); in.putParcelable(DocumentsContract.EXTRA_URI, sourceDocumentUri); @@ -1465,12 +1438,6 @@ public final class DocumentsContract { } } - @Deprecated - public static Uri copyDocument(ContentResolver content, Uri sourceDocumentUri, - Uri targetParentDocumentUri) throws FileNotFoundException { - return copyDocument((ContentInterface) content, sourceDocumentUri, targetParentDocumentUri); - } - /** * Moves the given document under a new parent. * @@ -1480,8 +1447,9 @@ public final class DocumentsContract { * document. * @return the moved document, or {@code null} if failed. */ - public static Uri moveDocument(ContentInterface content, Uri sourceDocumentUri, - Uri sourceParentDocumentUri, Uri targetParentDocumentUri) throws FileNotFoundException { + public static @Nullable Uri moveDocument(@NonNull ContentResolver content, + @NonNull Uri sourceDocumentUri, @NonNull Uri sourceParentDocumentUri, + @NonNull Uri targetParentDocumentUri) throws FileNotFoundException { try { final Bundle in = new Bundle(); in.putParcelable(DocumentsContract.EXTRA_URI, sourceDocumentUri); @@ -1498,13 +1466,6 @@ public final class DocumentsContract { } } - @Deprecated - public static Uri moveDocument(ContentResolver content, Uri sourceDocumentUri, - Uri sourceParentDocumentUri, Uri targetParentDocumentUri) throws FileNotFoundException { - return moveDocument((ContentInterface) content, sourceDocumentUri, sourceParentDocumentUri, - targetParentDocumentUri); - } - /** * Removes the given document from a parent directory. * @@ -1515,8 +1476,8 @@ public final class DocumentsContract { * @param parentDocumentUri parent document of the document to remove. * @return true if the document was removed successfully. */ - public static boolean removeDocument(ContentInterface content, Uri documentUri, - Uri parentDocumentUri) throws FileNotFoundException { + public static boolean removeDocument(@NonNull ContentResolver content, @NonNull Uri documentUri, + @NonNull Uri parentDocumentUri) throws FileNotFoundException { try { final Bundle in = new Bundle(); in.putParcelable(DocumentsContract.EXTRA_URI, documentUri); @@ -1532,34 +1493,23 @@ public final class DocumentsContract { } } - @Deprecated - public static boolean removeDocument(ContentResolver content, Uri documentUri, - Uri parentDocumentUri) throws FileNotFoundException { - return removeDocument((ContentInterface) content, documentUri, parentDocumentUri); - } - /** * Ejects the given root. It throws {@link IllegalStateException} when ejection failed. * * @param rootUri root with {@link Root#FLAG_SUPPORTS_EJECT} to be ejected */ - public static void ejectRoot(ContentInterface content, Uri rootUri) { + public static void ejectRoot(@NonNull ContentResolver content, @NonNull Uri rootUri) { try { final Bundle in = new Bundle(); in.putParcelable(DocumentsContract.EXTRA_URI, rootUri); content.call(rootUri.getAuthority(), METHOD_EJECT_ROOT, null, in); - } catch (RemoteException e) { - e.rethrowAsRuntimeException(); + } catch (Exception e) { + Log.w(TAG, "Failed to eject", e); } } - @Deprecated - public static void ejectRoot(ContentResolver content, Uri rootUri) { - ejectRoot((ContentInterface) content, rootUri); - } - /** * 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 @@ -1590,7 +1540,7 @@ public final class DocumentsContract { * @param documentUri a Document URI * @return a Bundle of Bundles. */ - public static @Nullable Bundle getDocumentMetadata(@NonNull ContentInterface content, + public static @Nullable Bundle getDocumentMetadata(@NonNull ContentResolver content, @NonNull Uri documentUri) throws FileNotFoundException { Preconditions.checkNotNull(content, "content can not be null"); Preconditions.checkNotNull(documentUri, "documentUri can not be null"); @@ -1607,12 +1557,6 @@ public final class DocumentsContract { } } - @Deprecated - public static Bundle getDocumentMetadata(ContentResolver content, Uri documentUri) - throws FileNotFoundException { - return getDocumentMetadata((ContentInterface) content, documentUri); - } - /** * Finds the canonical path from the top of the document tree. * @@ -1626,8 +1570,8 @@ public final class DocumentsContract { * @return the path of the document, or {@code null} if failed. * @see DocumentsProvider#findDocumentPath(String, String) */ - public static Path findDocumentPath(ContentInterface content, Uri treeUri) - throws FileNotFoundException { + public static @Nullable Path findDocumentPath(@NonNull ContentResolver content, + @NonNull Uri treeUri) throws FileNotFoundException { try { final Bundle in = new Bundle(); in.putParcelable(DocumentsContract.EXTRA_URI, treeUri); @@ -1642,12 +1586,6 @@ public final class DocumentsContract { } } - @Deprecated - public static Path findDocumentPath(ContentResolver content, Uri treeUri) - throws FileNotFoundException { - return findDocumentPath((ContentInterface) content, treeUri); - } - /** * Creates an intent for obtaining a web link for the specified document. * @@ -1699,8 +1637,8 @@ public final class DocumentsContract { * @see DocumentsProvider#createWebLinkIntent(String, Bundle) * @see Intent#EXTRA_EMAIL */ - public static IntentSender createWebLinkIntent(ContentInterface content, Uri uri, - Bundle options) throws FileNotFoundException { + public static @Nullable IntentSender createWebLinkIntent(@NonNull ContentResolver content, + @NonNull Uri uri, @Nullable Bundle options) throws FileNotFoundException { try { final Bundle in = new Bundle(); in.putParcelable(DocumentsContract.EXTRA_URI, uri); @@ -1721,12 +1659,6 @@ public final class DocumentsContract { } } - @Deprecated - public static IntentSender createWebLinkIntent(ContentResolver content, Uri uri, - Bundle options) throws FileNotFoundException { - return createWebLinkIntent((ContentInterface) content, uri, options); - } - /** * Open the given image for thumbnail purposes, using any embedded EXIF * thumbnail if available, and providing orientation hints from the parent diff --git a/core/tests/coretests/src/android/provider/DocumentsProviderTest.java b/core/tests/coretests/src/android/provider/DocumentsProviderTest.java index 02a9adf4fb4d..bff6b5fb3d24 100644 --- a/core/tests/coretests/src/android/provider/DocumentsProviderTest.java +++ b/core/tests/coretests/src/android/provider/DocumentsProviderTest.java @@ -60,7 +60,8 @@ public class DocumentsProviderTest extends ProviderTestCase2<TestDocumentsProvid DocumentsContract.buildDocumentUri(TestDocumentsProvider.AUTHORITY, DOCUMENT_ID); try (ContentProviderClient client = mResolver.acquireUnstableContentProviderClient(docUri)) { - final Path actual = DocumentsContract.findDocumentPath(client, docUri); + final Path actual = DocumentsContract.findDocumentPath( + ContentResolver.wrap(client), docUri); assertEquals(expected, actual); } } |