Loading core/api/current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -9848,6 +9848,7 @@ package android.content { method @Nullable public final String getReadPermission(); method @Nullable public String[] getStreamTypes(@NonNull android.net.Uri, @NonNull String); method @Nullable public abstract String getType(@NonNull android.net.Uri); method @Nullable public String getTypeAnonymous(@NonNull android.net.Uri); method @Nullable public final String getWritePermission(); method @Nullable public abstract android.net.Uri insert(@NonNull android.net.Uri, @Nullable android.content.ContentValues); method @Nullable public android.net.Uri insert(@NonNull android.net.Uri, @Nullable android.content.ContentValues, @Nullable android.os.Bundle); core/java/android/app/IActivityManager.aidl +1 −1 Original line number Diff line number Diff line Loading @@ -347,7 +347,7 @@ interface IActivityManager { String getProviderMimeType(in Uri uri, int userId); oneway void getProviderMimeTypeAsync(in Uri uri, int userId, in RemoteCallback resultCallback); oneway void getMimeTypeFilterAsync(in Uri uri, int userId, in RemoteCallback resultCallback); // Cause the specified process to dump the specified heap. boolean dumpHeap(in String process, int userId, boolean managed, boolean mallocInfo, boolean runGc, in String path, in ParcelFileDescriptor fd, Loading core/java/android/content/ContentProvider.java +103 −45 Original line number Diff line number Diff line Loading @@ -18,14 +18,15 @@ package android.content; import static android.Manifest.permission.INTERACT_ACROSS_USERS; import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; import static android.os.Process.SYSTEM_UID; import static android.os.Process.myUserHandle; import static android.os.Trace.TRACE_TAG_DATABASE; import static com.android.internal.util.FrameworkStatsLog.GET_TYPE_ACCESSED_WITHOUT_PERMISSION; import static com.android.internal.util.FrameworkStatsLog.GET_TYPE_ACCESSED_WITHOUT_PERMISSION__LOCATION__PROVIDER_CHECK_URI_PERMISSION; import static com.android.internal.util.FrameworkStatsLog.GET_TYPE_ACCESSED_WITHOUT_PERMISSION__LOCATION__PROVIDER_ERROR; import static com.android.internal.util.FrameworkStatsLog.GET_TYPE_ACCESSED_WITHOUT_PERMISSION__LOCATION__PROVIDER_FRAMEWORK_PERMISSION; import android.Manifest; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; Loading Loading @@ -300,17 +301,32 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall } @Override public String getType(Uri uri) { 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()); try { if (checkGetTypePermission(attributionSource, uri) == PermissionChecker.PERMISSION_GRANTED) { final String type = mInterface.getType(uri); if (type != null) { logGetTypeData(Binder.getCallingUid(), uri, type); logGetTypeData(Binder.getCallingUid(), uri, type, true); } return type; } else { final int callingUid = Binder.getCallingUid(); final long origId = Binder.clearCallingIdentity(); try { final String type = getTypeAnonymous(uri); if (type != null) { logGetTypeData(callingUid, uri, type, false); } return type; } finally { Binder.restoreCallingIdentity(origId); } } } catch (RemoteException e) { throw e.rethrowAsRuntimeException(); } finally { Loading @@ -319,23 +335,14 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall } // Utility function to log the getTypeData calls private void logGetTypeData(int callingUid, Uri uri, String type) { private void logGetTypeData(int callingUid, Uri uri, String type, boolean permissionCheckPassed) { final int enumFrameworkPermission = GET_TYPE_ACCESSED_WITHOUT_PERMISSION__LOCATION__PROVIDER_FRAMEWORK_PERMISSION; final int enumCheckUriPermission = GET_TYPE_ACCESSED_WITHOUT_PERMISSION__LOCATION__PROVIDER_CHECK_URI_PERMISSION; final int enumError = GET_TYPE_ACCESSED_WITHOUT_PERMISSION__LOCATION__PROVIDER_ERROR; try { final AttributionSource attributionSource = new AttributionSource.Builder( callingUid).build(); try { if (enforceReadPermission(attributionSource, uri) != PermissionChecker.PERMISSION_GRANTED) { FrameworkStatsLog.write(GET_TYPE_ACCESSED_WITHOUT_PERMISSION, enumFrameworkPermission, callingUid, uri.getAuthority(), type); } else { if (permissionCheckPassed) { // Just for logging for mediaProvider cases final ProviderInfo cpi = mContext.getPackageManager() .resolveContentProvider(uri.getAuthority(), PackageManager.ComponentInfoFlags.of(PackageManager.GET_META_DATA)); Loading @@ -343,6 +350,7 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall final Uri userUri = (mSingleUser && !UserHandle.isSameUser(mMyUid, callingUid)) ? maybeAddUserId(uri, callingUserId) : uri; try { if (cpi.forceUriPermissions && mInterface.checkUriPermission(uri, callingUid, Intent.FLAG_GRANT_READ_URI_PERMISSION) Loading @@ -354,24 +362,35 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall enumCheckUriPermission, callingUid, uri.getAuthority(), type); } } catch (RemoteException e) { //does nothing } } catch (SecurityException e) { } else { FrameworkStatsLog.write(GET_TYPE_ACCESSED_WITHOUT_PERMISSION, enumFrameworkPermission, callingUid, uri.getAuthority(), type); } } @Override public void getTypeAsync(AttributionSource attributionSource, Uri uri, RemoteCallback callback) { final Bundle result = new Bundle(); try { result.putString(ContentResolver.REMOTE_CALLBACK_RESULT, getType(attributionSource, uri)); } catch (Exception e) { FrameworkStatsLog.write(GET_TYPE_ACCESSED_WITHOUT_PERMISSION, enumError, callingUid, uri.getAuthority(), type); result.putParcelable(ContentResolver.REMOTE_CALLBACK_ERROR, new ParcelableException(e)); } callback.sendResult(result); } @Override public void getTypeAsync(Uri uri, RemoteCallback callback) { public void getTypeAnonymousAsync(Uri uri, RemoteCallback callback) { final Bundle result = new Bundle(); try { result.putString(ContentResolver.REMOTE_CALLBACK_RESULT, getType(uri)); result.putString(ContentResolver.REMOTE_CALLBACK_RESULT, getTypeAnonymous(uri)); } catch (Exception e) { result.putParcelable(ContentResolver.REMOTE_CALLBACK_ERROR, new ParcelableException(e)); Loading Loading @@ -795,6 +814,23 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall } return PermissionChecker.PERMISSION_GRANTED; } @PermissionCheckerManager.PermissionResult private int checkGetTypePermission(@NonNull AttributionSource attributionSource, Uri uri) { final int callingUid = Binder.getCallingUid(); if (UserHandle.getAppId(callingUid) == SYSTEM_UID || checkPermission(Manifest.permission.GET_ANY_PROVIDER_TYPE, attributionSource) == PermissionChecker.PERMISSION_GRANTED) { // Allowing System Uid and apps with permission to get any type, to access all types return PermissionChecker.PERMISSION_GRANTED; } try { return enforceReadPermission(attributionSource, uri); } catch (SecurityException e) { return PermissionChecker.PERMISSION_HARD_DENIED; } } } boolean checkUser(int pid, int uid, Context context) { Loading Loading @@ -1625,11 +1661,15 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes * and Threads</a>. * * <p>Note that there are no permissions needed for an application to * <p>Note that by default there are no permissions needed for an application to * access this information; if your content provider requires read and/or * write permissions, or is not exported, all applications can still call * this method regardless of their access permissions. This allows them * to retrieve the MIME type for a URI when dispatching intents. * this method regardless of their access permissions. </p> * * <p>If your mime type reveals details that should be protected, * then you should protect this method by implementing {@link #getTypeAnonymous}. * Implementing {@link #getTypeAnonymous} ensures your {@link #getType} can be * only accessed by caller's having associated readPermission for the URI. </p> * * @param uri the URI to query. * @return a MIME type string, or {@code null} if there is no type. Loading @@ -1637,6 +1677,24 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall @Override public abstract @Nullable String getType(@NonNull Uri uri); /** * Implement this to handle requests for MIME type of URIs, that does not need to * reveal any internal information which should be protected by any permission. * * <p>If your mime type reveals details that should be protected, then you should protect those * by implementing those in {@link #getType}, and in this function, only return types of * URIs which can be obtained by anyone without any access. * * Implementing ths function will make sure {@link #getType} is protected by readPermission. * This function by default works as the {@link #getType}</p> * * @param uri the URI to query. * @return a MIME type string, or {@code null} if type needs to be protected. */ public @Nullable String getTypeAnonymous(@NonNull Uri uri) { return getType(uri); } /** * Implement this to support canonicalization of URIs that refer to your * content provider. A canonical URI is one that can be transported across Loading core/java/android/content/ContentProviderNative.java +36 −6 Original line number Diff line number Diff line Loading @@ -140,8 +140,10 @@ abstract public class ContentProviderNative extends Binder implements IContentPr case GET_TYPE_TRANSACTION: { data.enforceInterface(IContentProvider.descriptor); AttributionSource attributionSource = AttributionSource.CREATOR .createFromParcel(data); Uri url = Uri.CREATOR.createFromParcel(data); String type = getType(url); String type = getType(attributionSource, url); reply.writeNoException(); reply.writeString(type); Loading @@ -150,9 +152,19 @@ abstract public class ContentProviderNative extends Binder implements IContentPr case GET_TYPE_ASYNC_TRANSACTION: { data.enforceInterface(IContentProvider.descriptor); AttributionSource attributionSource = AttributionSource.CREATOR .createFromParcel(data); Uri url = Uri.CREATOR.createFromParcel(data); RemoteCallback callback = RemoteCallback.CREATOR.createFromParcel(data); getTypeAsync(url, callback); getTypeAsync(attributionSource, url, callback); return true; } case GET_TYPE_ANONYMOUS_ASYNC_TRANSACTION: { data.enforceInterface(IContentProvider.descriptor); Uri url = Uri.CREATOR.createFromParcel(data); RemoteCallback callback = RemoteCallback.CREATOR.createFromParcel(data); getTypeAnonymousAsync(url, callback); return true; } Loading Loading @@ -502,13 +514,13 @@ final class ContentProviderProxy implements IContentProvider } @Override public String getType(Uri url) throws RemoteException public String getType(AttributionSource attributionSource, Uri url) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); try { data.writeInterfaceToken(IContentProvider.descriptor); attributionSource.writeToParcel(data, 0); url.writeToParcel(data, 0); mRemote.transact(IContentProvider.GET_TYPE_TRANSACTION, data, reply, 0); Loading @@ -523,11 +535,12 @@ final class ContentProviderProxy implements IContentProvider } @Override /* oneway */ public void getTypeAsync(Uri uri, RemoteCallback callback) throws RemoteException { /* oneway */ public void getTypeAsync(AttributionSource attributionSource, Uri uri, RemoteCallback callback) throws RemoteException { Parcel data = Parcel.obtain(); try { data.writeInterfaceToken(IContentProvider.descriptor); attributionSource.writeToParcel(data, 0); uri.writeToParcel(data, 0); callback.writeToParcel(data, 0); Loading @@ -538,6 +551,23 @@ final class ContentProviderProxy implements IContentProvider } } @Override /* oneway */ public void getTypeAnonymousAsync(Uri uri, RemoteCallback callback) throws RemoteException { Parcel data = Parcel.obtain(); try { data.writeInterfaceToken(IContentProvider.descriptor); uri.writeToParcel(data, 0); callback.writeToParcel(data, 0); mRemote.transact(IContentProvider.GET_TYPE_ANONYMOUS_ASYNC_TRANSACTION, data, null, IBinder.FLAG_ONEWAY); } finally { data.recycle(); } } @Override public Uri insert(@NonNull AttributionSource attributionSource, Uri url, ContentValues values, Bundle extras) throws RemoteException Loading core/java/android/content/ContentResolver.java +8 −3 Original line number Diff line number Diff line Loading @@ -920,8 +920,13 @@ public abstract class ContentResolver implements ContentInterface { return null; } // XXX would like to have an acquireExistingUnstableProvider for this. IContentProvider provider = acquireExistingProvider(url); IContentProvider provider = null; try { provider = acquireProvider(url); } catch (Exception e) { // if unable to acquire the provider, then it should try to get the type // using getTypeAnonymous via ActivityManagerService } if (provider != null) { try { final StringResultListener resultListener = new StringResultListener(); Loading Loading @@ -949,7 +954,7 @@ public abstract class ContentResolver implements ContentInterface { try { final StringResultListener resultListener = new StringResultListener(); ActivityManager.getService().getProviderMimeTypeAsync( ActivityManager.getService().getMimeTypeFilterAsync( ContentProvider.getUriWithoutUserId(url), resolveUserId(url), new RemoteCallback(resultListener)); Loading Loading
core/api/current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -9848,6 +9848,7 @@ package android.content { method @Nullable public final String getReadPermission(); method @Nullable public String[] getStreamTypes(@NonNull android.net.Uri, @NonNull String); method @Nullable public abstract String getType(@NonNull android.net.Uri); method @Nullable public String getTypeAnonymous(@NonNull android.net.Uri); method @Nullable public final String getWritePermission(); method @Nullable public abstract android.net.Uri insert(@NonNull android.net.Uri, @Nullable android.content.ContentValues); method @Nullable public android.net.Uri insert(@NonNull android.net.Uri, @Nullable android.content.ContentValues, @Nullable android.os.Bundle);
core/java/android/app/IActivityManager.aidl +1 −1 Original line number Diff line number Diff line Loading @@ -347,7 +347,7 @@ interface IActivityManager { String getProviderMimeType(in Uri uri, int userId); oneway void getProviderMimeTypeAsync(in Uri uri, int userId, in RemoteCallback resultCallback); oneway void getMimeTypeFilterAsync(in Uri uri, int userId, in RemoteCallback resultCallback); // Cause the specified process to dump the specified heap. boolean dumpHeap(in String process, int userId, boolean managed, boolean mallocInfo, boolean runGc, in String path, in ParcelFileDescriptor fd, Loading
core/java/android/content/ContentProvider.java +103 −45 Original line number Diff line number Diff line Loading @@ -18,14 +18,15 @@ package android.content; import static android.Manifest.permission.INTERACT_ACROSS_USERS; import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; import static android.os.Process.SYSTEM_UID; import static android.os.Process.myUserHandle; import static android.os.Trace.TRACE_TAG_DATABASE; import static com.android.internal.util.FrameworkStatsLog.GET_TYPE_ACCESSED_WITHOUT_PERMISSION; import static com.android.internal.util.FrameworkStatsLog.GET_TYPE_ACCESSED_WITHOUT_PERMISSION__LOCATION__PROVIDER_CHECK_URI_PERMISSION; import static com.android.internal.util.FrameworkStatsLog.GET_TYPE_ACCESSED_WITHOUT_PERMISSION__LOCATION__PROVIDER_ERROR; import static com.android.internal.util.FrameworkStatsLog.GET_TYPE_ACCESSED_WITHOUT_PERMISSION__LOCATION__PROVIDER_FRAMEWORK_PERMISSION; import android.Manifest; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; Loading Loading @@ -300,17 +301,32 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall } @Override public String getType(Uri uri) { 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()); try { if (checkGetTypePermission(attributionSource, uri) == PermissionChecker.PERMISSION_GRANTED) { final String type = mInterface.getType(uri); if (type != null) { logGetTypeData(Binder.getCallingUid(), uri, type); logGetTypeData(Binder.getCallingUid(), uri, type, true); } return type; } else { final int callingUid = Binder.getCallingUid(); final long origId = Binder.clearCallingIdentity(); try { final String type = getTypeAnonymous(uri); if (type != null) { logGetTypeData(callingUid, uri, type, false); } return type; } finally { Binder.restoreCallingIdentity(origId); } } } catch (RemoteException e) { throw e.rethrowAsRuntimeException(); } finally { Loading @@ -319,23 +335,14 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall } // Utility function to log the getTypeData calls private void logGetTypeData(int callingUid, Uri uri, String type) { private void logGetTypeData(int callingUid, Uri uri, String type, boolean permissionCheckPassed) { final int enumFrameworkPermission = GET_TYPE_ACCESSED_WITHOUT_PERMISSION__LOCATION__PROVIDER_FRAMEWORK_PERMISSION; final int enumCheckUriPermission = GET_TYPE_ACCESSED_WITHOUT_PERMISSION__LOCATION__PROVIDER_CHECK_URI_PERMISSION; final int enumError = GET_TYPE_ACCESSED_WITHOUT_PERMISSION__LOCATION__PROVIDER_ERROR; try { final AttributionSource attributionSource = new AttributionSource.Builder( callingUid).build(); try { if (enforceReadPermission(attributionSource, uri) != PermissionChecker.PERMISSION_GRANTED) { FrameworkStatsLog.write(GET_TYPE_ACCESSED_WITHOUT_PERMISSION, enumFrameworkPermission, callingUid, uri.getAuthority(), type); } else { if (permissionCheckPassed) { // Just for logging for mediaProvider cases final ProviderInfo cpi = mContext.getPackageManager() .resolveContentProvider(uri.getAuthority(), PackageManager.ComponentInfoFlags.of(PackageManager.GET_META_DATA)); Loading @@ -343,6 +350,7 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall final Uri userUri = (mSingleUser && !UserHandle.isSameUser(mMyUid, callingUid)) ? maybeAddUserId(uri, callingUserId) : uri; try { if (cpi.forceUriPermissions && mInterface.checkUriPermission(uri, callingUid, Intent.FLAG_GRANT_READ_URI_PERMISSION) Loading @@ -354,24 +362,35 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall enumCheckUriPermission, callingUid, uri.getAuthority(), type); } } catch (RemoteException e) { //does nothing } } catch (SecurityException e) { } else { FrameworkStatsLog.write(GET_TYPE_ACCESSED_WITHOUT_PERMISSION, enumFrameworkPermission, callingUid, uri.getAuthority(), type); } } @Override public void getTypeAsync(AttributionSource attributionSource, Uri uri, RemoteCallback callback) { final Bundle result = new Bundle(); try { result.putString(ContentResolver.REMOTE_CALLBACK_RESULT, getType(attributionSource, uri)); } catch (Exception e) { FrameworkStatsLog.write(GET_TYPE_ACCESSED_WITHOUT_PERMISSION, enumError, callingUid, uri.getAuthority(), type); result.putParcelable(ContentResolver.REMOTE_CALLBACK_ERROR, new ParcelableException(e)); } callback.sendResult(result); } @Override public void getTypeAsync(Uri uri, RemoteCallback callback) { public void getTypeAnonymousAsync(Uri uri, RemoteCallback callback) { final Bundle result = new Bundle(); try { result.putString(ContentResolver.REMOTE_CALLBACK_RESULT, getType(uri)); result.putString(ContentResolver.REMOTE_CALLBACK_RESULT, getTypeAnonymous(uri)); } catch (Exception e) { result.putParcelable(ContentResolver.REMOTE_CALLBACK_ERROR, new ParcelableException(e)); Loading Loading @@ -795,6 +814,23 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall } return PermissionChecker.PERMISSION_GRANTED; } @PermissionCheckerManager.PermissionResult private int checkGetTypePermission(@NonNull AttributionSource attributionSource, Uri uri) { final int callingUid = Binder.getCallingUid(); if (UserHandle.getAppId(callingUid) == SYSTEM_UID || checkPermission(Manifest.permission.GET_ANY_PROVIDER_TYPE, attributionSource) == PermissionChecker.PERMISSION_GRANTED) { // Allowing System Uid and apps with permission to get any type, to access all types return PermissionChecker.PERMISSION_GRANTED; } try { return enforceReadPermission(attributionSource, uri); } catch (SecurityException e) { return PermissionChecker.PERMISSION_HARD_DENIED; } } } boolean checkUser(int pid, int uid, Context context) { Loading Loading @@ -1625,11 +1661,15 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes * and Threads</a>. * * <p>Note that there are no permissions needed for an application to * <p>Note that by default there are no permissions needed for an application to * access this information; if your content provider requires read and/or * write permissions, or is not exported, all applications can still call * this method regardless of their access permissions. This allows them * to retrieve the MIME type for a URI when dispatching intents. * this method regardless of their access permissions. </p> * * <p>If your mime type reveals details that should be protected, * then you should protect this method by implementing {@link #getTypeAnonymous}. * Implementing {@link #getTypeAnonymous} ensures your {@link #getType} can be * only accessed by caller's having associated readPermission for the URI. </p> * * @param uri the URI to query. * @return a MIME type string, or {@code null} if there is no type. Loading @@ -1637,6 +1677,24 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall @Override public abstract @Nullable String getType(@NonNull Uri uri); /** * Implement this to handle requests for MIME type of URIs, that does not need to * reveal any internal information which should be protected by any permission. * * <p>If your mime type reveals details that should be protected, then you should protect those * by implementing those in {@link #getType}, and in this function, only return types of * URIs which can be obtained by anyone without any access. * * Implementing ths function will make sure {@link #getType} is protected by readPermission. * This function by default works as the {@link #getType}</p> * * @param uri the URI to query. * @return a MIME type string, or {@code null} if type needs to be protected. */ public @Nullable String getTypeAnonymous(@NonNull Uri uri) { return getType(uri); } /** * Implement this to support canonicalization of URIs that refer to your * content provider. A canonical URI is one that can be transported across Loading
core/java/android/content/ContentProviderNative.java +36 −6 Original line number Diff line number Diff line Loading @@ -140,8 +140,10 @@ abstract public class ContentProviderNative extends Binder implements IContentPr case GET_TYPE_TRANSACTION: { data.enforceInterface(IContentProvider.descriptor); AttributionSource attributionSource = AttributionSource.CREATOR .createFromParcel(data); Uri url = Uri.CREATOR.createFromParcel(data); String type = getType(url); String type = getType(attributionSource, url); reply.writeNoException(); reply.writeString(type); Loading @@ -150,9 +152,19 @@ abstract public class ContentProviderNative extends Binder implements IContentPr case GET_TYPE_ASYNC_TRANSACTION: { data.enforceInterface(IContentProvider.descriptor); AttributionSource attributionSource = AttributionSource.CREATOR .createFromParcel(data); Uri url = Uri.CREATOR.createFromParcel(data); RemoteCallback callback = RemoteCallback.CREATOR.createFromParcel(data); getTypeAsync(url, callback); getTypeAsync(attributionSource, url, callback); return true; } case GET_TYPE_ANONYMOUS_ASYNC_TRANSACTION: { data.enforceInterface(IContentProvider.descriptor); Uri url = Uri.CREATOR.createFromParcel(data); RemoteCallback callback = RemoteCallback.CREATOR.createFromParcel(data); getTypeAnonymousAsync(url, callback); return true; } Loading Loading @@ -502,13 +514,13 @@ final class ContentProviderProxy implements IContentProvider } @Override public String getType(Uri url) throws RemoteException public String getType(AttributionSource attributionSource, Uri url) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); try { data.writeInterfaceToken(IContentProvider.descriptor); attributionSource.writeToParcel(data, 0); url.writeToParcel(data, 0); mRemote.transact(IContentProvider.GET_TYPE_TRANSACTION, data, reply, 0); Loading @@ -523,11 +535,12 @@ final class ContentProviderProxy implements IContentProvider } @Override /* oneway */ public void getTypeAsync(Uri uri, RemoteCallback callback) throws RemoteException { /* oneway */ public void getTypeAsync(AttributionSource attributionSource, Uri uri, RemoteCallback callback) throws RemoteException { Parcel data = Parcel.obtain(); try { data.writeInterfaceToken(IContentProvider.descriptor); attributionSource.writeToParcel(data, 0); uri.writeToParcel(data, 0); callback.writeToParcel(data, 0); Loading @@ -538,6 +551,23 @@ final class ContentProviderProxy implements IContentProvider } } @Override /* oneway */ public void getTypeAnonymousAsync(Uri uri, RemoteCallback callback) throws RemoteException { Parcel data = Parcel.obtain(); try { data.writeInterfaceToken(IContentProvider.descriptor); uri.writeToParcel(data, 0); callback.writeToParcel(data, 0); mRemote.transact(IContentProvider.GET_TYPE_ANONYMOUS_ASYNC_TRANSACTION, data, null, IBinder.FLAG_ONEWAY); } finally { data.recycle(); } } @Override public Uri insert(@NonNull AttributionSource attributionSource, Uri url, ContentValues values, Bundle extras) throws RemoteException Loading
core/java/android/content/ContentResolver.java +8 −3 Original line number Diff line number Diff line Loading @@ -920,8 +920,13 @@ public abstract class ContentResolver implements ContentInterface { return null; } // XXX would like to have an acquireExistingUnstableProvider for this. IContentProvider provider = acquireExistingProvider(url); IContentProvider provider = null; try { provider = acquireProvider(url); } catch (Exception e) { // if unable to acquire the provider, then it should try to get the type // using getTypeAnonymous via ActivityManagerService } if (provider != null) { try { final StringResultListener resultListener = new StringResultListener(); Loading Loading @@ -949,7 +954,7 @@ public abstract class ContentResolver implements ContentInterface { try { final StringResultListener resultListener = new StringResultListener(); ActivityManager.getService().getProviderMimeTypeAsync( ActivityManager.getService().getMimeTypeFilterAsync( ContentProvider.getUriWithoutUserId(url), resolveUserId(url), new RemoteCallback(resultListener)); Loading