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

Commit 93e92b1d authored by Philip P. Moltmann's avatar Philip P. Moltmann Committed by android-build-merger
Browse files

Merge "Set most leniant mode if two perms affect one appop" into qt-dev am: d84102bf

am: 1554254b

Change-Id: I87e87b533132c8867590fad5d6ac351333a30666
parents d44358f1 1554254b
Loading
Loading
Loading
Loading
+95 −21
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ import android.permission.PermissionControllerManager;
import android.provider.Telephony;
import android.telecom.TelecomManager;
import android.util.ArraySet;
import android.util.LongSparseLongArray;
import android.util.Pair;
import android.util.Slog;
import android.util.SparseBooleanArray;
@@ -58,6 +59,7 @@ import android.util.SparseIntArray;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.app.IAppOpsCallback;
import com.android.internal.app.IAppOpsService;
import com.android.internal.util.IntPair;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.FgThread;
import com.android.server.LocalServices;
@@ -147,11 +149,9 @@ public final class PermissionPolicyService extends SystemService {
                PermissionInfo perm = dangerousPerms.get(i);

                if (perm.isHardRestricted() || perm.backgroundPermission != null) {
                    appOpsService.startWatchingMode(AppOpsManager.permissionToOpCode(perm.name),
                            null, appOpsListener);
                    appOpsService.startWatchingMode(getSwitchOp(perm.name), null, appOpsListener);
                } else if (perm.isSoftRestricted()) {
                    appOpsService.startWatchingMode(AppOpsManager.permissionToOpCode(perm.name),
                            null, appOpsListener);
                    appOpsService.startWatchingMode(getSwitchOp(perm.name), null, appOpsListener);

                    SoftRestrictedPermissionPolicy policy =
                            SoftRestrictedPermissionPolicy.forPermission(null, null, null,
@@ -167,6 +167,25 @@ public final class PermissionPolicyService extends SystemService {
        }
    }

    /**
     * Get op that controls the access related to the permission.
     *
     * <p>Usually the permission-op relationship is 1:1 but some permissions (e.g. fine location)
     * {@link AppOpsManager#sOpToSwitch share an op} to control the access.
     *
     * @param permission The permission
     *
     * @return The op that controls the access of the permission
     */
    private static int getSwitchOp(@NonNull String permission) {
        int op = AppOpsManager.permissionToOpCode(permission);
        if (op == OP_NONE) {
            return OP_NONE;
        }

        return AppOpsManager.opToSwitch(op);
    }

    private void synchronizePackagePermissionsAndAppOpsAsyncForUser(@NonNull String packageName,
            @UserIdInt int changedUserId) {
        if (isStarted(changedUserId)) {
@@ -430,40 +449,89 @@ public final class PermissionPolicyService extends SystemService {
         * <p>This processes ops previously added by {@link #addOpIfRestricted}
         */
        private void syncPackages() {
            // Remember which ops were already set. This makes sure that we always set the most
            // permissive mode if two OpChanges are scheduled. This can e.g. happen if two
            // permissions change the same op. See {@link #getSwitchOp}.
            LongSparseLongArray alreadySetAppOps = new LongSparseLongArray();

            final int allowCount = mOpsToAllow.size();
            for (int i = 0; i < allowCount; i++) {
                final OpToChange op = mOpsToAllow.get(i);

                setUidModeAllowed(op.code, op.uid, op.packageName);
                alreadySetAppOps.put(IntPair.of(op.uid, op.code), 1);
            }

            final int allowIfDefaultCount = mOpsToAllowIfDefault.size();
            for (int i = 0; i < allowIfDefaultCount; i++) {
                final OpToChange op = mOpsToAllowIfDefault.get(i);
                setUidModeAllowedIfDefault(op.code, op.uid, op.packageName);
                if (alreadySetAppOps.indexOfKey(IntPair.of(op.uid, op.code)) >= 0) {
                    continue;
                }
            final int foregroundCount = mOpsToForegroundIfAllow.size();
            for (int i = 0; i < foregroundCount; i++) {

                boolean wasSet = setUidModeAllowedIfDefault(op.code, op.uid, op.packageName);
                if (wasSet) {
                    alreadySetAppOps.put(IntPair.of(op.uid, op.code), 1);
                }
            }

            final int foregroundIfAllowedCount = mOpsToForegroundIfAllow.size();
            for (int i = 0; i < foregroundIfAllowedCount; i++) {
                final OpToChange op = mOpsToForegroundIfAllow.get(i);
                setUidModeForegroundIfAllow(op.code, op.uid, op.packageName);
                if (alreadySetAppOps.indexOfKey(IntPair.of(op.uid, op.code)) >= 0) {
                    continue;
                }

                boolean wasSet = setUidModeForegroundIfAllow(op.code, op.uid, op.packageName);
                if (wasSet) {
                    alreadySetAppOps.put(IntPair.of(op.uid, op.code), 1);
                }
            final int foregroundIfAllowCount = mOpsToForeground.size();
            for (int i = 0; i < foregroundIfAllowCount; i++) {
            }

            final int foregroundCount = mOpsToForeground.size();
            for (int i = 0; i < foregroundCount; i++) {
                final OpToChange op = mOpsToForeground.get(i);
                if (alreadySetAppOps.indexOfKey(IntPair.of(op.uid, op.code)) >= 0) {
                    continue;
                }

                setUidModeForeground(op.code, op.uid, op.packageName);
                alreadySetAppOps.put(IntPair.of(op.uid, op.code), 1);
            }

            final int ignoreCount = mOpsToIgnore.size();
            for (int i = 0; i < ignoreCount; i++) {
                final OpToChange op = mOpsToIgnore.get(i);
                if (alreadySetAppOps.indexOfKey(IntPair.of(op.uid, op.code)) >= 0) {
                    continue;
                }

                setUidModeIgnored(op.code, op.uid, op.packageName);
                alreadySetAppOps.put(IntPair.of(op.uid, op.code), 1);
            }

            final int ignoreIfDefaultCount = mOpsToIgnoreIfDefault.size();
            for (int i = 0; i < ignoreIfDefaultCount; i++) {
                final OpToChange op = mOpsToIgnoreIfDefault.get(i);
                setUidModeIgnoredIfDefault(op.code, op.uid, op.packageName);
                if (alreadySetAppOps.indexOfKey(IntPair.of(op.uid, op.code)) >= 0) {
                    continue;
                }

                boolean wasSet = setUidModeIgnoredIfDefault(op.code, op.uid, op.packageName);
                if (wasSet) {
                    alreadySetAppOps.put(IntPair.of(op.uid, op.code), 1);
                }
            }

            final int defaultCount = mOpsToDefault.size();
            for (int i = 0; i < defaultCount; i++) {
                final OpToChange op = mOpsToDefault.get(i);
                if (alreadySetAppOps.indexOfKey(IntPair.of(op.uid, op.code)) >= 0) {
                    continue;
                }

                setUidModeDefault(op.code, op.uid, op.packageName);
                alreadySetAppOps.put(IntPair.of(op.uid, op.code), 1);
            }
        }

@@ -479,7 +547,7 @@ public final class PermissionPolicyService extends SystemService {
        private void addOpIfRestricted(@NonNull PermissionInfo permissionInfo,
                @NonNull PackageInfo pkg) {
            final String permission = permissionInfo.name;
            final int opCode = AppOpsManager.permissionToOpCode(permission);
            final int opCode = getSwitchOp(permission);
            final int uid = pkg.applicationInfo.uid;

            if (!permissionInfo.isRestricted()) {
@@ -581,7 +649,7 @@ public final class PermissionPolicyService extends SystemService {
            }

            final String permission = permissionInfo.name;
            final int opCode = AppOpsManager.permissionToOpCode(permission);
            final int opCode = getSwitchOp(permission);
            final String pkgName = pkg.packageName;
            final int uid = pkg.applicationInfo.uid;

@@ -641,7 +709,7 @@ public final class PermissionPolicyService extends SystemService {
            }

            for (String permission : pkg.requestedPermissions) {
                final int opCode = AppOpsManager.permissionToOpCode(permission);
                final int opCode = getSwitchOp(permission);
                if (opCode == OP_NONE) {
                    continue;
                }
@@ -658,24 +726,27 @@ public final class PermissionPolicyService extends SystemService {
            }
        }

        private void setUidModeAllowedIfDefault(int opCode, int uid, @NonNull String packageName) {
            setUidModeIfMode(opCode, uid, MODE_DEFAULT, MODE_ALLOWED, packageName);
        private boolean setUidModeAllowedIfDefault(int opCode, int uid,
                @NonNull String packageName) {
            return setUidModeIfMode(opCode, uid, MODE_DEFAULT, MODE_ALLOWED, packageName);
        }

        private void setUidModeAllowed(int opCode, int uid, @NonNull String packageName) {
            setUidMode(opCode, uid, MODE_ALLOWED, packageName);
        }

        private void setUidModeForegroundIfAllow(int opCode, int uid, @NonNull String packageName) {
            setUidModeIfMode(opCode, uid, MODE_ALLOWED, MODE_FOREGROUND, packageName);
        private boolean setUidModeForegroundIfAllow(int opCode, int uid,
                @NonNull String packageName) {
            return setUidModeIfMode(opCode, uid, MODE_ALLOWED, MODE_FOREGROUND, packageName);
        }

        private void setUidModeForeground(int opCode, int uid, @NonNull String packageName) {
            setUidMode(opCode, uid, MODE_FOREGROUND, packageName);
        }

        private void setUidModeIgnoredIfDefault(int opCode, int uid, @NonNull String packageName) {
            setUidModeIfMode(opCode, uid, MODE_DEFAULT, MODE_IGNORED, packageName);
        private boolean setUidModeIgnoredIfDefault(int opCode, int uid,
                @NonNull String packageName) {
            return setUidModeIfMode(opCode, uid, MODE_DEFAULT, MODE_IGNORED, packageName);
        }

        private void setUidModeIgnored(int opCode, int uid, @NonNull String packageName) {
@@ -692,14 +763,17 @@ public final class PermissionPolicyService extends SystemService {
            }
        }

        private void setUidModeIfMode(int opCode, int uid, int requiredModeBefore, int newMode,
        private boolean setUidModeIfMode(int opCode, int uid, int requiredModeBefore, int newMode,
                @NonNull String packageName) {
            final int currentMode = mAppOpsManager.unsafeCheckOpRaw(AppOpsManager
                    .opToPublicName(opCode), uid, packageName);

            if (currentMode == requiredModeBefore) {
                mAppOpsManager.setUidMode(opCode, uid, newMode);
                return true;
            }

            return false;
        }

        private void setUidModeDefault(int opCode, int uid, String packageName) {
+3 −0
Original line number Diff line number Diff line
@@ -41,6 +41,9 @@
      "options": [
        {
          "include-filter": "android.permission.cts.SplitPermissionTest"
        },
        {
          "include-filter": "android.permission.cts.BackgroundPermissionsTest"
        }
      ]
    }