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

Commit cbb05a31 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes I9ed87db1,Ic0b766f6

* changes:
  Make PermissionControllerManager user aware
  Check same uid for permission and app-op
parents 2f9b0bd2 cfd2fbc4
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -309,6 +309,7 @@ package android.app {
    method @Deprecated @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public java.util.List<android.app.AppOpsManager.PackageOps> getOpsForPackage(int, String, int[]);
    method @NonNull @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public java.util.List<android.app.AppOpsManager.PackageOps> getOpsForPackage(int, @NonNull String, @Nullable java.lang.String...);
    method @NonNull @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public java.util.List<android.app.AppOpsManager.PackageOps> getPackagesForOps(@Nullable String[]);
    method public int noteProxyOpNoThrow(@NonNull String, @Nullable String, int);
    method public static int opToDefaultMode(@NonNull String);
    method @Nullable public static String opToPermission(@NonNull String);
    method @RequiresPermission("android.permission.MANAGE_APP_OPS_MODES") public void setMode(String, int, String, int);
+38 −2
Original line number Diff line number Diff line
@@ -4291,11 +4291,34 @@ public class AppOpsManager {
    /**
     * Like {@link #noteProxyOp(String, String)} but instead
     * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
     *
     * <p>This API requires the package with the {@code proxiedPackageName} to belongs to
     * {@link Binder#getCallingUid()}.
     */
    public int noteProxyOpNoThrow(String op, String proxiedPackageName) {
        return noteProxyOpNoThrow(strOpToOp(op), proxiedPackageName);
    }

    /**
     * Like {@link #noteProxyOp(String, String)} but instead
     * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
     *
     * <p>This API requires package with the {@code proxiedPackageName} to belong to
     * {@code proxiedUid}.
     *
     * @param op The op to note
     * @param proxiedPackageName The package to note the op for or {@code null} if the op should be
     *                           noted for the "android" package
     * @param proxiedUid The uid the package belongs to
     *
     * @hide
     */
    @SystemApi
    public int noteProxyOpNoThrow(@NonNull String op, @Nullable String proxiedPackageName,
            int proxiedUid) {
        return noteProxyOpNoThrow(strOpToOp(op), proxiedPackageName, proxiedUid);
    }

    /**
     * Report that an application has started executing a long-running operation.  Note that you
     * must pass in both the uid and name of the application to be checked; this function will
@@ -4495,16 +4518,29 @@ public class AppOpsManager {
     * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
     * @hide
     */
    public int noteProxyOpNoThrow(int op, String proxiedPackageName) {
    public int noteProxyOpNoThrow(int op, String proxiedPackageName, int proxiedUid) {
        logOperationIfNeeded(op, mContext.getOpPackageName(), proxiedPackageName);
        try {
            return mService.noteProxyOperation(op, Process.myUid(), mContext.getOpPackageName(),
                    Binder.getCallingUid(), proxiedPackageName);
                    proxiedUid, proxiedPackageName);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Like {@link #noteProxyOp(int, String)} but instead
     * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
     *
     * <p>This API requires the package with {@code proxiedPackageName} to belongs to
     * {@link Binder#getCallingUid()}.
     *
     * @hide
     */
    public int noteProxyOpNoThrow(int op, String proxiedPackageName) {
        return noteProxyOpNoThrow(op, proxiedPackageName, Binder.getCallingUid());
    }

    /**
     * Like {@link #noteOp} but instead of throwing a {@link SecurityException} it
     * returns {@link #MODE_ERRORED}.
+4 −2
Original line number Diff line number Diff line
@@ -108,8 +108,7 @@ public final class PermissionChecker {
            packageName = packageNames[0];
        }

        if (appOpsManager.noteProxyOpNoThrow(op, packageName)
                != AppOpsManager.MODE_ALLOWED) {
        if (appOpsManager.noteProxyOpNoThrow(op, packageName, uid) != AppOpsManager.MODE_ALLOWED) {
            return PERMISSION_DENIED_APP_OP;
        }

@@ -120,6 +119,9 @@ public final class PermissionChecker {
     * Checks whether your app has a given permission and whether the app op
     * that corresponds to this permission is allowed.
     *
     * <p>This API assumes the the {@link Binder#getCallingUid()} is the same as
     * {@link Process#myUid()}.
     *
     * @param context Context for accessing resources.
     * @param permission The permission to check.
     * @return The permission check result which is either {@link #PERMISSION_GRANTED}
+32 −23
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ import android.os.RemoteException;
import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.Log;
import android.util.SparseArray;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.infra.AbstractMultiplePendingRequestsRemoteService;
@@ -85,9 +86,11 @@ public final class PermissionControllerManager {

    private static final Object sLock = new Object();

    /** App global remote service used by all {@link PermissionControllerManager managers} */
    /**
     * Global remote services (per user) used by all {@link PermissionControllerManager managers}
     */
    @GuardedBy("sLock")
    private static RemoteService sRemoteService;
    private static SparseArray<RemoteService> sRemoteServices = new SparseArray<>(1);

    /**
     * The key for retrieving the result from the returned bundle.
@@ -203,6 +206,7 @@ public final class PermissionControllerManager {
    }

    private final @NonNull Context mContext;
    private final @NonNull RemoteService mRemoteService;

    /**
     * Create a new {@link PermissionControllerManager}.
@@ -213,14 +217,18 @@ public final class PermissionControllerManager {
     */
    public PermissionControllerManager(@NonNull Context context) {
        synchronized (sLock) {
            if (sRemoteService == null) {
            RemoteService remoteService = sRemoteServices.get(context.getUserId(), null);
            if (remoteService == null) {
                Intent intent = new Intent(SERVICE_INTERFACE);
                intent.setPackage(context.getPackageManager().getPermissionControllerPackageName());
                ResolveInfo serviceInfo = context.getPackageManager().resolveService(intent, 0);

                sRemoteService = new RemoteService(context.getApplicationContext(),
                        serviceInfo.getComponentInfo().getComponentName());
                remoteService = new RemoteService(context.getApplicationContext(),
                        serviceInfo.getComponentInfo().getComponentName(), context.getUser());
                sRemoteServices.put(context.getUserId(), remoteService);
            }

            mRemoteService = remoteService;
        }

        mContext = context;
@@ -255,7 +263,7 @@ public final class PermissionControllerManager {
                    + " required");
        }

        sRemoteService.scheduleRequest(new PendingRevokeRuntimePermissionRequest(sRemoteService,
        mRemoteService.scheduleRequest(new PendingRevokeRuntimePermissionRequest(mRemoteService,
                request, doDryRun, reason, mContext.getPackageName(), executor, callback));
    }

@@ -276,7 +284,7 @@ public final class PermissionControllerManager {
        checkNotNull(executor);
        checkNotNull(callback);

        sRemoteService.scheduleRequest(new PendingGetRuntimePermissionBackup(sRemoteService,
        mRemoteService.scheduleRequest(new PendingGetRuntimePermissionBackup(mRemoteService,
                user, executor, callback));
    }

@@ -294,8 +302,8 @@ public final class PermissionControllerManager {
        checkNotNull(backup);
        checkNotNull(user);

        sRemoteService.scheduleAsyncRequest(
                new PendingRestoreRuntimePermissionBackup(sRemoteService, backup, user));
        mRemoteService.scheduleAsyncRequest(
                new PendingRestoreRuntimePermissionBackup(mRemoteService, backup, user));
    }

    /**
@@ -318,8 +326,8 @@ public final class PermissionControllerManager {
        checkNotNull(executor);
        checkNotNull(callback);

        sRemoteService.scheduleRequest(
                new PendingRestoreDelayedRuntimePermissionBackup(sRemoteService, packageName,
        mRemoteService.scheduleRequest(
                new PendingRestoreDelayedRuntimePermissionBackup(mRemoteService, packageName,
                        user, executor, callback));
    }

@@ -338,8 +346,8 @@ public final class PermissionControllerManager {
        checkNotNull(packageName);
        checkNotNull(callback);

        sRemoteService.scheduleRequest(new PendingGetAppPermissionRequest(sRemoteService,
                packageName, callback, handler == null ? sRemoteService.getHandler() : handler));
        mRemoteService.scheduleRequest(new PendingGetAppPermissionRequest(mRemoteService,
                packageName, callback, handler == null ? mRemoteService.getHandler() : handler));
    }

    /**
@@ -356,7 +364,7 @@ public final class PermissionControllerManager {
        checkNotNull(packageName);
        checkNotNull(permissionName);

        sRemoteService.scheduleAsyncRequest(new PendingRevokeAppPermissionRequest(packageName,
        mRemoteService.scheduleAsyncRequest(new PendingRevokeAppPermissionRequest(packageName,
                permissionName));
    }

@@ -379,9 +387,9 @@ public final class PermissionControllerManager {
        checkFlagsArgument(flags, COUNT_WHEN_SYSTEM | COUNT_ONLY_WHEN_GRANTED);
        checkNotNull(callback);

        sRemoteService.scheduleRequest(new PendingCountPermissionAppsRequest(sRemoteService,
        mRemoteService.scheduleRequest(new PendingCountPermissionAppsRequest(mRemoteService,
                permissionNames, flags, callback,
                handler == null ? sRemoteService.getHandler() : handler));
                handler == null ? mRemoteService.getHandler() : handler));
    }

    /**
@@ -402,7 +410,7 @@ public final class PermissionControllerManager {
        checkNotNull(executor);
        checkNotNull(callback);

        sRemoteService.scheduleRequest(new PendingGetPermissionUsagesRequest(sRemoteService,
        mRemoteService.scheduleRequest(new PendingGetPermissionUsagesRequest(mRemoteService,
                countSystem, numMillis, executor, callback));
    }

@@ -424,8 +432,8 @@ public final class PermissionControllerManager {
        checkNotNull(executor);
        checkNotNull(callback);

        sRemoteService.scheduleRequest(new PendingIsApplicationQualifiedForRoleRequest(
                sRemoteService, roleName, packageName, executor, callback));
        mRemoteService.scheduleRequest(new PendingIsApplicationQualifiedForRoleRequest(
                mRemoteService, roleName, packageName, executor, callback));
    }

    /**
@@ -441,11 +449,12 @@ public final class PermissionControllerManager {
         *
         * @param context A context to use
         * @param componentName The component of the service to connect to
         * @param user User the remote service should be connected as
         */
        RemoteService(@NonNull Context context, @NonNull ComponentName componentName) {
            super(context, SERVICE_INTERFACE, componentName, UserHandle.myUserId(),
                    service -> Log.e(TAG, "RuntimePermPresenterService " + service + " died"),
                    false, false, 1);
        RemoteService(@NonNull Context context, @NonNull ComponentName componentName,
                @NonNull UserHandle user) {
            super(context, SERVICE_INTERFACE, componentName, user.getIdentifier(),
                    service -> Log.e(TAG, "RemoteService " + service + " died"), false, false, 1);
        }

        /**