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

Commit a24e2445 authored by Thomas Vannet's avatar Thomas Vannet
Browse files

Self-revocation: Call PermissionControllerManager directly from Context

This fixes a bug where self-revocation didn't work in multi-user
settings. Now the correct context is used throughout the call stack and
the permission for the calling user will be revoked.

Also added a checked IllegalArgumentException (previously unchecked
SecurityException) when trying to revoke a permission that is not
currently granted.

Test: manual using two users and
atest android.permission.cts.RevokeOwnPermissionTest
Bug: 218788609

Change-Id: I3dce34b8b956b4d1eb0ac1e34b6fdbf1795aa269
parent c7d1f62f
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -77,6 +77,7 @@ import android.os.Trace;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.storage.StorageManager;
import android.permission.PermissionControllerManager;
import android.permission.PermissionManager;
import android.system.ErrnoException;
import android.system.Os;
@@ -2181,7 +2182,8 @@ class ContextImpl extends Context {

    @Override
    public void revokeOwnPermissionsOnKill(@NonNull Collection<String> permissions) {
        getSystemService(PermissionManager.class).revokeOwnPermissionsOnKill(permissions);
        getSystemService(PermissionControllerManager.class).revokeOwnPermissionsOnKill(
                getPackageName(), new ArrayList<String>(permissions));
    }

    @Override
+7 −6
Original line number Diff line number Diff line
@@ -6508,10 +6508,12 @@ public abstract class Context {


    /**
     * Triggers the asynchronous revocation of a permission.
     * Triggers the asynchronous revocation of a runtime permission. If the permission is not
     * currently granted, nothing happens (even if later granted by the user).
     *
     * @param permName The name of the permission to be revoked.
     * @see #revokeOwnPermissionsOnKill(Collection)
     * @throws IllegalArgumentException if the permission is not a runtime permission
     */
    public void revokeOwnPermissionOnKill(@NonNull String permName) {
        revokeOwnPermissionsOnKill(Collections.singletonList(permName));
@@ -6519,11 +6521,9 @@ public abstract class Context {

    /**
     * Triggers the revocation of one or more permissions for the calling package. A package is only
     * able to revoke a permission under the following conditions:
     * <ul>
     * <li>Each permission in {@code permissions} must be granted to the calling package.
     * <li>Each permission in {@code permissions} must be a runtime permission.
     * </ul>
     * able to revoke runtime permissions. If a permission is not currently granted, it is ignored
     * and will not get revoked (even if later granted by the user). Ultimately, you should never
     * make assumptions about a permission status as users may grant or revoke them at any time.
     * <p>
     * Background permissions which have no corresponding foreground permission still granted once
     * the revocation is effective will also be revoked.
@@ -6549,6 +6549,7 @@ public abstract class Context {
     * @param permissions Collection of permissions to be revoked.
     * @see PackageManager#getGroupOfPlatformPermission(String, Executor, Consumer)
     * @see PackageManager#getPlatformPermissionsForGroup(String, Executor, Consumer)
     * @throws IllegalArgumentException if any of the permissions is not a runtime permission
     */
    public void revokeOwnPermissionsOnKill(@NonNull Collection<String> permissions) {
        throw new AbstractMethodError("Must be overridden in implementing class");
+0 −2
Original line number Diff line number Diff line
@@ -76,8 +76,6 @@ interface IPermissionManager {

    List<SplitPermissionInfoParcelable> getSplitPermissions();

    void revokeOwnPermissionsOnKill(String packageName, in List<String> permissions);

    void startOneTimePermissionSession(String packageName, int userId, long timeout,
            long revokeAfterKilledDelay, int importanceToResetTimer,
            int importanceToKeepSessionAlive);
+10 −3
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ import android.compat.annotation.Disabled;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
@@ -339,7 +340,7 @@ public abstract class PermissionControllerService extends Service {
     * @param permissions List of permissions to be revoked.
     * @param callback Callback waiting for operation to be complete.
     *
     * @see PermissionManager#revokeOwnPermissionsOnKill(java.util.Collection)
     * @see android.content.Context#revokeOwnPermissionsOnKill(java.util.Collection)
     */
    @BinderThread
    public void onRevokeOwnPermissionsOnKill(@NonNull String packageName,
@@ -706,9 +707,15 @@ public abstract class PermissionControllerService extends Service {
            public void revokeOwnPermissionsOnKill(@NonNull String packageName,
                    @NonNull List<String> permissions, @NonNull AndroidFuture callback) {
                try {
                    Objects.requireNonNull(callback);

                    final int callingUid = Binder.getCallingUid();
                    int targetPackageUid = getPackageManager().getPackageUid(packageName,
                            PackageManager.PackageInfoFlags.of(0));
                    if (targetPackageUid != callingUid) {
                        enforceSomePermissionsGrantedToCaller(
                                Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
                    Objects.requireNonNull(callback);
                    }
                    onRevokeOwnPermissionsOnKill(packageName, permissions,
                            () -> callback.complete(null));
                } catch (Throwable t) {
+0 −14
Original line number Diff line number Diff line
@@ -76,7 +76,6 @@ import com.android.internal.annotations.Immutable;
import com.android.internal.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
@@ -625,19 +624,6 @@ public final class PermissionManager {
        }
    }

    /**
     * @see Context#revokeOwnPermissionsOnKill(Collection)
     * @hide
     */
    public void revokeOwnPermissionsOnKill(@NonNull Collection<String> permissions) {
        try {
            mPermissionManager.revokeOwnPermissionsOnKill(mContext.getPackageName(),
                    new ArrayList<String>(permissions));
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Gets the state flags associated with a permission.
     *
Loading