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

Commit 93540ca6 authored by Hai Zhang's avatar Hai Zhang
Browse files

Revert "Access app op modes in UID state indirectly."

This reverts commit 8f876988.

Reason for revert: We no longer compute app op mode.

Change-Id: I2af8be50950739213afc93cf5545e9ed1eec3cd6
parent 8f876988
Loading
Loading
Loading
Loading
+121 −145
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ import android.content.pm.PermissionInfo;
import android.content.pm.UserInfo;
import android.database.ContentObserver;
import android.hardware.camera2.CameraDevice.CAMERA_AUDIO_RESTRICTION;
import android.media.AudioAttributes;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Binder;
@@ -360,7 +361,7 @@ public class AppOpsService extends IAppOpsService.Stub {

        public int startNesting;
        public ArrayMap<String, Ops> pkgOps;
        private SparseIntArray opModes;
        public SparseIntArray opModes;

        // true indicates there is an interested observer, false there isn't but it has such an op
        public SparseBooleanArray foregroundOps;
@@ -382,64 +383,6 @@ public class AppOpsService extends IAppOpsService.Stub {
                    && (pendingState == UID_STATE_CACHED));
        }

        public int getOpModeCount() {
            return opModes != null ? opModes.size() : 0;
        }

        public int getOpCodeAt(int index) {
            return opModes.keyAt(index);
        }

        public boolean hasOpMode(int code) {
            return opModes != null && opModes.indexOfKey(code) >= 0;
        }

        public int getOpMode(int code) {
            return opModes.get(code);
        }

        public boolean putOpMode(int code, int mode) {
            if (mode == AppOpsManager.opToDefaultMode(code)) {
                return removeOpMode(code);
            }
            if (opModes == null) {
                opModes = new SparseIntArray();
            }
            int index = opModes.indexOfKey(code);
            if (index < 0) {
                opModes.put(code, mode);
                return true;
            }
            if (opModes.valueAt(index) == mode) {
                return false;
            }
            opModes.setValueAt(index, mode);
            return true;
        }

        public boolean removeOpMode(int code) {
            if (opModes == null) {
                return false;
            }
            int index = opModes.indexOfKey(code);
            if (index < 0) {
                return false;
            }
            opModes.removeAt(index);
            if (opModes.size() == 0) {
                opModes = null;
            }
            return true;
        }

        @Nullable
        public SparseIntArray cloneOpModes() {
            if (opModes == null) {
                return null;
            }
            return opModes.clone();
        }

        int evalMode(int op, int mode) {
            if (mode == AppOpsManager.MODE_FOREGROUND) {
                return state <= AppOpsManager.resolveFirstUnrestrictedUidState(op)
@@ -467,13 +410,14 @@ public class AppOpsService extends IAppOpsService.Stub {
        public void evalForegroundOps(SparseArray<ArraySet<ModeCallback>> watchers) {
            SparseBooleanArray which = null;
            hasForegroundWatchers = false;
            for (int i = getOpModeCount() - 1; i >= 0; i--) {
                int code = getOpCodeAt(i);
                if (getOpMode(code) == AppOpsManager.MODE_FOREGROUND) {
            if (opModes != null) {
                for (int i = opModes.size() - 1; i >= 0; i--) {
                    if (opModes.valueAt(i) == AppOpsManager.MODE_FOREGROUND) {
                        if (which == null) {
                            which = new SparseBooleanArray();
                        }
                    evalForegroundWatchers(code, watchers, which);
                        evalForegroundWatchers(opModes.keyAt(i), watchers, which);
                    }
                }
            }
            if (pkgOps != null) {
@@ -1112,28 +1056,24 @@ public class AppOpsService extends IAppOpsService.Stub {
        return resOps;
    }

    @Nullable
    private ArrayList<AppOpsManager.OpEntry> collectOps(@NonNull UidState uidState,
            @Nullable int[] ops) {
        int opModeCount = uidState.getOpModeCount();
        if (opModeCount == 0) {
    private ArrayList<AppOpsManager.OpEntry> collectOps(SparseIntArray uidOps, int[] ops) {
        if (uidOps == null) {
            return null;
        }
        ArrayList<AppOpsManager.OpEntry> resOps = null;
        if (ops == null) {
            resOps = new ArrayList<>();
            for (int i = 0; i < opModeCount; i++) {
                int code = uidState.getOpCodeAt(i);
                resOps.add(new OpEntry(code, uidState.getOpMode(code)));
            for (int j=0; j<uidOps.size(); j++) {
                resOps.add(new OpEntry(uidOps.keyAt(j), uidOps.valueAt(j)));
            }
        } else {
            for (int i = 0; i < ops.length; i++) {
                int code = ops[i];
                if (uidState.hasOpMode(code)) {
            for (int j=0; j<ops.length; j++) {
                int index = uidOps.indexOfKey(ops[j]);
                if (index >= 0) {
                    if (resOps == null) {
                        resOps = new ArrayList<>();
                    }
                    resOps.add(new OpEntry(code, uidState.getOpMode(code)));
                    resOps.add(new OpEntry(uidOps.keyAt(j), uidOps.valueAt(j)));
                }
            }
        }
@@ -1279,11 +1219,11 @@ public class AppOpsService extends IAppOpsService.Stub {
            if (uidState == null) {
                return null;
            }
            ArrayList<AppOpsManager.OpEntry> resOps = collectOps(uidState, ops);
            ArrayList<AppOpsManager.OpEntry> resOps = collectOps(uidState.opModes, ops);
            if (resOps == null) {
                return null;
            }
            ArrayList<AppOpsManager.PackageOps> res = new ArrayList<>();
            ArrayList<AppOpsManager.PackageOps> res = new ArrayList<AppOpsManager.PackageOps>();
            AppOpsManager.PackageOps resPackage = new AppOpsManager.PackageOps(
                    null, uidState.uid, resOps);
            res.add(resPackage);
@@ -1351,14 +1291,29 @@ public class AppOpsService extends IAppOpsService.Stub {
                    return;
                }
                uidState = new UidState(uid);
                uidState.putOpMode(code, mode);
                uidState.opModes = new SparseIntArray();
                uidState.opModes.put(code, mode);
                mUidStates.put(uid, uidState);
                scheduleWriteLocked();
            } else {
                boolean changed = uidState.putOpMode(code, mode);
                if (changed) {
            } else if (uidState.opModes == null) {
                if (mode != defaultMode) {
                    uidState.opModes = new SparseIntArray();
                    uidState.opModes.put(code, mode);
                    scheduleWriteLocked();
                }
            } else {
                if (uidState.opModes.indexOfKey(code) >= 0 && uidState.opModes.get(code) == mode) {
                    return;
                }
                if (mode == defaultMode) {
                    uidState.opModes.delete(code);
                    if (uidState.opModes.size() <= 0) {
                        uidState.opModes = null;
                    }
                } else {
                    uidState.opModes.put(code, mode);
                }
                scheduleWriteLocked();
            }
            uidState.evalForegroundOps(mOpModeWatchers);
        }
@@ -1597,13 +1552,16 @@ public class AppOpsService extends IAppOpsService.Stub {
            for (int i = mUidStates.size() - 1; i >= 0; i--) {
                UidState uidState = mUidStates.valueAt(i);

                if (uidState.uid == reqUid || reqUid == -1) {
                    for (int opModeIndex = uidState.getOpModeCount() - 1; opModeIndex >= 0;
                            opModeIndex--) {
                        final int code = uidState.getOpCodeAt(opModeIndex);

                SparseIntArray opModes = uidState.opModes;
                if (opModes != null && (uidState.uid == reqUid || reqUid == -1)) {
                    final int uidOpCount = opModes.size();
                    for (int j = uidOpCount - 1; j >= 0; j--) {
                        final int code = opModes.keyAt(j);
                        if (AppOpsManager.opAllowsReset(code)) {
                            uidState.removeOpMode(code);
                            opModes.removeAt(j);
                            if (opModes.size() <= 0) {
                                uidState.opModes = null;
                            }
                            for (String packageName : getPackagesForUid(uidState.uid)) {
                                callbacks = addCallbacks(callbacks, code, uidState.uid, packageName,
                                        mOpModeWatchers.get(code));
@@ -1853,8 +1811,9 @@ public class AppOpsService extends IAppOpsService.Stub {
            }
            code = AppOpsManager.opToSwitch(code);
            UidState uidState = getUidStateLocked(uid, false);
            if (uidState != null && uidState.hasOpMode(code)) {
                final int rawMode = uidState.getOpMode(code);
            if (uidState != null && uidState.opModes != null
                    && uidState.opModes.indexOfKey(code) >= 0) {
                final int rawMode = uidState.opModes.get(code);
                return raw ? rawMode : uidState.evalMode(code, rawMode);
            }
            Op op = getOpLocked(code, uid, packageName, false, false);
@@ -2023,8 +1982,8 @@ public class AppOpsService extends IAppOpsService.Stub {
            final int switchCode = AppOpsManager.opToSwitch(code);
            // If there is a non-default per UID policy (we set UID op mode only if
            // non-default) it takes over, otherwise use the per package policy.
            if (uidState.hasOpMode(switchCode)) {
                final int uidMode = uidState.evalMode(code, uidState.getOpMode(switchCode));
            if (uidState.opModes != null && uidState.opModes.indexOfKey(switchCode) >= 0) {
                final int uidMode = uidState.evalMode(code, uidState.opModes.get(switchCode));
                if (uidMode != AppOpsManager.MODE_ALLOWED) {
                    if (DEBUG) Slog.d(TAG, "noteOperation: uid reject #" + uidMode + " for code "
                            + switchCode + " (" + code + ") uid " + uid + " package "
@@ -2325,8 +2284,8 @@ public class AppOpsService extends IAppOpsService.Stub {
            // If there is a non-default per UID policy (we set UID op mode only if
            // non-default) it takes over, otherwise use the per package policy.
            final int opCode = op.op;
            if (uidState.hasOpMode(switchCode)) {
                final int uidMode = uidState.evalMode(code, uidState.getOpMode(switchCode));
            if (uidState.opModes != null && uidState.opModes.indexOfKey(switchCode) >= 0) {
                final int uidMode = uidState.evalMode(code, uidState.opModes.get(switchCode));
                if (uidMode != AppOpsManager.MODE_ALLOWED
                        && (!startIfModeDefault || uidMode != AppOpsManager.MODE_DEFAULT)) {
                    if (DEBUG) Slog.d(TAG, "noteOperation: uid reject #" + uidMode + " for code "
@@ -2645,8 +2604,9 @@ public class AppOpsService extends IAppOpsService.Stub {
                                || !callback.isWatchingUid(uidState.uid)) {
                            continue;
                        }
                        boolean doAllPackages = uidState.hasOpMode(code)
                                && uidState.getOpMode(code) == AppOpsManager.MODE_FOREGROUND;
                        boolean doAllPackages = uidState.opModes != null
                                && uidState.opModes.indexOfKey(code) >= 0
                                && uidState.opModes.get(code) == AppOpsManager.MODE_FOREGROUND;
                        if (uidState.pkgOps != null) {
                            for (int pkgi = uidState.pkgOps.size() - 1; pkgi >= 0; pkgi--) {
                                final Op op = uidState.pkgOps.valueAt(pkgi).get(code);
@@ -2967,9 +2927,12 @@ public class AppOpsService extends IAppOpsService.Stub {
            if (uidState == null) {
                continue;
            }
            if (uidState.hasOpMode(AppOpsManager.OP_RUN_IN_BACKGROUND)) {
                uidState.putOpMode(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, uidState.getOpMode(
                        AppOpsManager.OP_RUN_IN_BACKGROUND));
            if (uidState.opModes != null) {
                final int idx = uidState.opModes.indexOfKey(AppOpsManager.OP_RUN_IN_BACKGROUND);
                if (idx >= 0) {
                    uidState.opModes.put(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND,
                        uidState.opModes.valueAt(idx));
                }
            }
            if (uidState.pkgOps == null) {
                continue;
@@ -3025,7 +2988,10 @@ public class AppOpsService extends IAppOpsService.Stub {
                final int code = Integer.parseInt(parser.getAttributeValue(null, "n"));
                final int mode = Integer.parseInt(parser.getAttributeValue(null, "m"));
                UidState uidState = getUidStateLocked(uid, true);
                uidState.putOpMode(code, mode);
                if (uidState.opModes == null) {
                    uidState.opModes = new SparseIntArray();
                }
                uidState.opModes.put(code, mode);
            } else {
                Slog.w(TAG, "Unknown element under <uid-ops>: "
                        + parser.getName());
@@ -3177,39 +3143,48 @@ public class AppOpsService extends IAppOpsService.Stub {
                out.startTag(null, "app-ops");
                out.attribute(null, "v", String.valueOf(CURRENT_VERSION));

                final SparseArray<SparseIntArray> uidOpModes = new SparseArray<>();
                SparseArray<SparseIntArray> uidStatesClone;
                synchronized (this) {
                    final int uidStatesSize = mUidStates.size();
                    for (int i = 0; i < uidStatesSize; i++) {
                        final SparseIntArray opModes = mUidStates.valueAt(i).cloneOpModes();
                        if (opModes != null) {
                            final int uid = mUidStates.keyAt(i);
                            uidOpModes.put(uid, opModes);
                    uidStatesClone = new SparseArray<>(mUidStates.size());

                    final int uidStateCount = mUidStates.size();
                    for (int uidStateNum = 0; uidStateNum < uidStateCount; uidStateNum++) {
                        UidState uidState = mUidStates.valueAt(uidStateNum);
                        int uid = mUidStates.keyAt(uidStateNum);

                        SparseIntArray opModes = uidState.opModes;
                        if (opModes != null && opModes.size() > 0) {
                            uidStatesClone.put(uid, new SparseIntArray(opModes.size()));

                            final int opCount = opModes.size();
                            for (int opCountNum = 0; opCountNum < opCount; opCountNum++) {
                                uidStatesClone.get(uid).put(
                                        opModes.keyAt(opCountNum),
                                        opModes.valueAt(opCountNum));
                            }
                        }
                    }
                }

                final int uidOpModesSize = uidOpModes.size();
                for (int uidOpModesIndex = 0; uidOpModesIndex < uidOpModesSize; uidOpModesIndex++) {
                    final int uid = uidOpModes.keyAt(uidOpModesIndex);
                    final SparseIntArray opModes = uidOpModes.valueAt(uidOpModesIndex);

                final int uidStateCount = uidStatesClone.size();
                for (int uidStateNum = 0; uidStateNum < uidStateCount; uidStateNum++) {
                    SparseIntArray opModes = uidStatesClone.valueAt(uidStateNum);
                    if (opModes != null && opModes.size() > 0) {
                        out.startTag(null, "uid");
                    out.attribute(null, "n", Integer.toString(uid));

                    final int opModesSize = opModes.size();
                    for (int opModesIndex = 0; opModesIndex < opModesSize; opModesIndex++) {
                        final int code = opModes.keyAt(opModesIndex);
                        final int mode = opModes.valueAt(opModesIndex);

                        out.attribute(null, "n",
                                Integer.toString(uidStatesClone.keyAt(uidStateNum)));
                        final int opCount = opModes.size();
                        for (int opCountNum = 0; opCountNum < opCount; opCountNum++) {
                            final int op = opModes.keyAt(opCountNum);
                            final int mode = opModes.valueAt(opCountNum);
                            out.startTag(null, "op");
                        out.attribute(null, "n", Integer.toString(code));
                            out.attribute(null, "n", Integer.toString(op));
                            out.attribute(null, "m", Integer.toString(mode));
                            out.endTag(null, "op");
                        }

                        out.endTag(null, "uid");
                    }
                }

                if (allOps != null) {
                    String lastPkg = null;
@@ -4153,22 +4128,21 @@ public class AppOpsService extends IAppOpsService.Stub {
            }
            for (int i=0; i<mUidStates.size(); i++) {
                UidState uidState = mUidStates.valueAt(i);
                final SparseIntArray opModes = uidState.opModes;
                final ArrayMap<String, Ops> pkgOps = uidState.pkgOps;

                if (dumpWatchers || dumpHistory) {
                    continue;
                }
                if (dumpOp >= 0 || dumpPackage != null || dumpMode >= 0) {
                    boolean hasOp = dumpOp < 0 || uidState.hasOpMode(dumpOp);
                    boolean hasOp = dumpOp < 0 || (uidState.opModes != null
                            && uidState.opModes.indexOfKey(dumpOp) >= 0);
                    boolean hasPackage = dumpPackage == null;
                    boolean hasMode = dumpMode < 0;
                    if (!hasMode) {
                        int opModeCount = uidState.getOpModeCount();
                        for (int opModeIndex = 0; opModeIndex < opModeCount; opModeIndex++) {
                            int code = uidState.getOpCodeAt(opModeIndex);
                            if (uidState.getOpMode(code) == dumpMode) {
                    if (!hasMode && opModes != null) {
                        for (int opi = 0; !hasMode && opi < opModes.size(); opi++) {
                            if (opModes.valueAt(opi) == dumpMode) {
                                hasMode = true;
                                break;
                            }
                        }
                    }
@@ -4235,10 +4209,11 @@ public class AppOpsService extends IAppOpsService.Stub {
                }
                needSep = true;

                final int opModeCount = uidState.getOpModeCount();
                for (int opModeIndex = 0; opModeIndex < opModeCount; opModeIndex++) {
                    final int code = uidState.getOpCodeAt(opModeIndex);
                    final int mode = uidState.getOpMode(code);
                if (opModes != null) {
                    final int opModeCount = opModes.size();
                    for (int j = 0; j < opModeCount; j++) {
                        final int code = opModes.keyAt(j);
                        final int mode = opModes.valueAt(j);
                        if (dumpOp >= 0 && dumpOp != code) {
                            continue;
                        }
@@ -4248,6 +4223,7 @@ public class AppOpsService extends IAppOpsService.Stub {
                        pw.print("      "); pw.print(AppOpsManager.opToName(code));
                        pw.print(": mode="); pw.println(AppOpsManager.modeToName(mode));
                    }
                }

                if (pkgOps == null) {
                    continue;
+7 −5
Original line number Diff line number Diff line
@@ -89,12 +89,14 @@ public class AppOpsUpgradeTest {
        final int defaultModeOp2 = AppOpsManager.opToDefaultMode(op2);
        for(int i = 0; i < uidStates.size(); i++) {
            final AppOpsService.UidState uidState = uidStates.valueAt(i);
            final int uidMode1 = uidState.hasOpMode(op1) ? uidState.getOpMode(op1) : defaultModeOp1;
            final int uidMode2 = uidState.hasOpMode(op2) ? uidState.getOpMode(op2) : defaultModeOp2;
            if (uidState.opModes != null) {
                final int uidMode1 = uidState.opModes.get(op1, defaultModeOp1);
                final int uidMode2 = uidState.opModes.get(op2, defaultModeOp2);
                assertEquals(uidMode1, uidMode2);
                if (uidMode1 != defaultModeOp1) {
                    numberOfNonDefaultOps++;
                }
            }
            if (uidState.pkgOps == null) {
                continue;
            }