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

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

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

parents 50ab7b07 3b8c14c1
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"
        }
      ]
    }