Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 68bb82cf authored by Ashish Kumar Gaurav's avatar Ashish Kumar Gaurav Committed by Automerger Merge Worker
Browse files

Merge "Added a new api ContentProvider#getTypeAnonymous" into udc-dev am: 3d907cca

parents f1d90275 3d907cca
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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);
+1 −1
Original line number Diff line number Diff line
@@ -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,
+103 −45
Original line number Diff line number Diff line
@@ -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;
@@ -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 {
@@ -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));
@@ -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)
@@ -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));
@@ -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) {
@@ -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.
@@ -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
+36 −6
Original line number Diff line number Diff line
@@ -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);

@@ -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;
                }

@@ -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);
@@ -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);

@@ -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
+8 −3
Original line number Diff line number Diff line
@@ -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();
@@ -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