diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java index d2dbd64ccd7a42d5b8e2fa99b3051730ed3b4c59..31c02b8866868c7fbaa85d162fc6162c9f640b67 100644 --- a/core/java/android/content/ContentProvider.java +++ b/core/java/android/content/ContentProvider.java @@ -302,10 +302,11 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall @Override public String getType(AttributionSource attributionSource, Uri uri) { - // getCallingPackage() isn't available in getType(), as the javadoc states. uri = validateIncomingUri(uri); uri = maybeGetUriWithoutUserId(uri); traceBegin(TRACE_TAG_DATABASE, "getType: ", uri.getAuthority()); + final AttributionSource original = setCallingAttributionSource( + attributionSource); try { if (checkGetTypePermission(attributionSource, uri) == PermissionChecker.PERMISSION_GRANTED) { @@ -346,6 +347,7 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall } catch (RemoteException e) { throw e.rethrowAsRuntimeException(); } finally { + setCallingAttributionSource(original); Trace.traceEnd(TRACE_TAG_DATABASE); } } @@ -405,16 +407,20 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall @Override public void getTypeAnonymousAsync(Uri uri, RemoteCallback callback) { + // getCallingPackage() isn't available in getTypeAnonymous(), as the javadoc states. uri = validateIncomingUri(uri); uri = maybeGetUriWithoutUserId(uri); + traceBegin(TRACE_TAG_DATABASE, "getTypeAnonymous: ", uri.getAuthority()); final Bundle result = new Bundle(); try { result.putString(ContentResolver.REMOTE_CALLBACK_RESULT, getTypeAnonymous(uri)); } catch (Exception e) { result.putParcelable(ContentResolver.REMOTE_CALLBACK_ERROR, new ParcelableException(e)); + } finally { + callback.sendResult(result); + Trace.traceEnd(TRACE_TAG_DATABASE); } - callback.sendResult(result); } @Override @@ -629,16 +635,19 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall } @Override - public String[] getStreamTypes(Uri uri, String mimeTypeFilter) { - // getCallingPackage() isn't available in getType(), as the javadoc states. + public String[] getStreamTypes(AttributionSource attributionSource, + Uri uri, String mimeTypeFilter) { uri = validateIncomingUri(uri); uri = maybeGetUriWithoutUserId(uri); traceBegin(TRACE_TAG_DATABASE, "getStreamTypes: ", uri.getAuthority()); + final AttributionSource original = setCallingAttributionSource( + attributionSource); try { return mInterface.getStreamTypes(uri, mimeTypeFilter); } catch (RemoteException e) { throw e.rethrowAsRuntimeException(); } finally { + setCallingAttributionSource(original); Trace.traceEnd(TRACE_TAG_DATABASE); } } @@ -1114,7 +1123,10 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall * currently processing a request. *
* This will always return {@code null} when processing - * {@link #getType(Uri)} or {@link #getStreamTypes(Uri, String)} requests. + * {@link #getTypeAnonymous(Uri)} requests + * + * For {@link #getType(Uri)} requests, this will be only available for cases, where + * the caller can be identified. See {@link #getTypeAnonymous(Uri)} * * @see Binder#getCallingUid() * @see Context#grantUriPermission(String, Uri, int) @@ -1154,7 +1166,10 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall * a request of the request is for the default attribution. *
* This will always return {@code null} when processing - * {@link #getType(Uri)} or {@link #getStreamTypes(Uri, String)} requests. + * {@link #getTypeAnonymous(Uri)} requests + * + * For {@link #getType(Uri)} requests, this will be only available for cases, where + * the caller can be identified. See {@link #getTypeAnonymous(Uri)} * * @see #getCallingPackage */ @@ -1181,7 +1196,10 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall * {@code null} if not currently processing a request. *
* This will always return {@code null} when processing - * {@link #getType(Uri)} or {@link #getStreamTypes(Uri, String)} requests. + * {@link #getTypeAnonymous(Uri)} requests + * + * For {@link #getType(Uri)} requests, this will be only available for cases, where + * the caller can be identified. See {@link #getTypeAnonymous(Uri)} * * @see Binder#getCallingUid() * @see Context#grantUriPermission(String, Uri, int) diff --git a/core/java/android/content/ContentProviderClient.java b/core/java/android/content/ContentProviderClient.java index cc3c01241c661a7a95a39b87a230361c37ecccb8..6b6ac03db46fc2cf5ae4b65fd090feea1b4d6280 100644 --- a/core/java/android/content/ContentProviderClient.java +++ b/core/java/android/content/ContentProviderClient.java @@ -217,7 +217,7 @@ public class ContentProviderClient implements ContentInterface, AutoCloseable { beforeRemote(); try { - return mContentProvider.getType(url); + return mContentProvider.getType(mAttributionSource, url); } catch (DeadObjectException e) { if (!mStable) { mContentResolver.unstableProviderDied(mContentProvider); @@ -237,7 +237,7 @@ public class ContentProviderClient implements ContentInterface, AutoCloseable { beforeRemote(); try { - return mContentProvider.getStreamTypes(url, mimeTypeFilter); + return mContentProvider.getStreamTypes(mAttributionSource, url, mimeTypeFilter); } catch (DeadObjectException e) { if (!mStable) { mContentResolver.unstableProviderDied(mContentProvider); diff --git a/core/java/android/content/ContentProviderNative.java b/core/java/android/content/ContentProviderNative.java index 4ba3ff4fe3d3e13e6f255022f507fdc22f97215b..fda3e3782d88064b13c70edb5b7b77bef9d6d7c8 100644 --- a/core/java/android/content/ContentProviderNative.java +++ b/core/java/android/content/ContentProviderNative.java @@ -315,9 +315,11 @@ abstract public class ContentProviderNative extends Binder implements IContentPr case GET_STREAM_TYPES_TRANSACTION: { data.enforceInterface(IContentProvider.descriptor); + AttributionSource attributionSource = AttributionSource.CREATOR + .createFromParcel(data); Uri url = Uri.CREATOR.createFromParcel(data); String mimeTypeFilter = data.readString(); - String[] types = getStreamTypes(url, mimeTypeFilter); + String[] types = getStreamTypes(attributionSource, url, mimeTypeFilter); reply.writeNoException(); reply.writeStringArray(types); @@ -769,12 +771,14 @@ final class ContentProviderProxy implements IContentProvider } @Override - public String[] getStreamTypes(Uri url, String mimeTypeFilter) throws RemoteException + public String[] getStreamTypes(AttributionSource attributionSource, + Uri url, String mimeTypeFilter) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); try { data.writeInterfaceToken(IContentProvider.descriptor); + attributionSource.writeToParcel(data, 0); url.writeToParcel(data, 0); data.writeString(mimeTypeFilter); diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java index 456d2189771133720ecf0b8dfa0dd9e21d424717..feca7a0229340efe777eb3e11bd4393125c3c376 100644 --- a/core/java/android/content/ContentResolver.java +++ b/core/java/android/content/ContentResolver.java @@ -1069,7 +1069,7 @@ public abstract class ContentResolver implements ContentInterface { } try { - return provider.getStreamTypes(url, mimeTypeFilter); + return provider.getStreamTypes(mContext.getAttributionSource(), url, mimeTypeFilter); } catch (RemoteException e) { // Arbitrary and not worth documenting, as Activity // Manager will kill this process shortly anyway. diff --git a/core/java/android/content/IContentProvider.java b/core/java/android/content/IContentProvider.java index eb80148250b945a0a3abfc6fe8d9465153deabf4..ef8d0f9e18c81ebdd5b533c6b2dc35d5c4e01a55 100644 --- a/core/java/android/content/IContentProvider.java +++ b/core/java/android/content/IContentProvider.java @@ -182,8 +182,19 @@ public interface IContentProvider extends IInterface { public boolean refresh(@NonNull AttributionSource attributionSource, Uri url, @Nullable Bundle extras, ICancellationSignal cancellationSignal) throws RemoteException; + /** + * @deprecated -- use getStreamTypes with AttributionSource + */ + @Deprecated + default String[] getStreamTypes(Uri url, String mimeTypeFilter) throws RemoteException { + return getStreamTypes(new AttributionSource(Binder.getCallingUid(), + AppGlobals.getPackageManager().getPackagesForUid(Binder.getCallingUid())[0], + null), url, mimeTypeFilter); + } + // Data interchange. - public String[] getStreamTypes(Uri url, String mimeTypeFilter) throws RemoteException; + String[] getStreamTypes(AttributionSource attributionSource, + Uri url, String mimeTypeFilter) throws RemoteException; public AssetFileDescriptor openTypedAssetFile(@NonNull AttributionSource attributionSource, Uri url, String mimeType, Bundle opts, ICancellationSignal signal) diff --git a/test-mock/src/android/test/mock/MockContentProvider.java b/test-mock/src/android/test/mock/MockContentProvider.java index 7f084f896e3ff3053e54d0e41a856ef76ba12a66..548dded9c47e5cd26ca3843dd8ddcdfbdb1b8dc9 100644 --- a/test-mock/src/android/test/mock/MockContentProvider.java +++ b/test-mock/src/android/test/mock/MockContentProvider.java @@ -140,7 +140,8 @@ public class MockContentProvider extends ContentProvider { } @Override - public String[] getStreamTypes(Uri url, String mimeTypeFilter) throws RemoteException { + public String[] getStreamTypes(AttributionSource attributionSource, + Uri url, String mimeTypeFilter) throws RemoteException { return MockContentProvider.this.getStreamTypes(url, mimeTypeFilter); } diff --git a/test-mock/src/android/test/mock/MockIContentProvider.java b/test-mock/src/android/test/mock/MockIContentProvider.java index bb2996a2cb40282d5a75569149f32860c4f6400a..23f8b98a704a1cad188d1863fbc17825aebbd226 100644 --- a/test-mock/src/android/test/mock/MockIContentProvider.java +++ b/test-mock/src/android/test/mock/MockIContentProvider.java @@ -144,7 +144,8 @@ public class MockIContentProvider implements IContentProvider { } @Override - public String[] getStreamTypes(Uri url, String mimeTypeFilter) throws RemoteException { + public String[] getStreamTypes(@NonNull AttributionSource attributionSource, + Uri url, String mimeTypeFilter) throws RemoteException { throw new UnsupportedOperationException("unimplemented mock method"); }