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

Commit ec0d07e8 authored by Pyuli Naithani's avatar Pyuli Naithani
Browse files

Associate a user id with package app-op modes.

This fixes the bug that cause the package app-op mode to be consistent
across all users.

FIXES:245355124

Test: Manual
Change-Id: I3dd8f5a5c7618f87f29cfd44d09ad3163c7647cb
parent 69d41ad5
Loading
Loading
Loading
Loading
+16 −10
Original line number Diff line number Diff line
@@ -574,7 +574,7 @@ public class AppOpsService extends IAppOpsService.Stub implements PersistenceSch
            mAppOpsServiceInterface.removeUid(uid);
            if (pkgOps != null) {
                for (String packageName : pkgOps.keySet()) {
                    mAppOpsServiceInterface.removePackage(packageName);
                    mAppOpsServiceInterface.removePackage(packageName, UserHandle.getUserId(uid));
                }
            }
            pkgOps = null;
@@ -584,7 +584,8 @@ public class AppOpsService extends IAppOpsService.Stub implements PersistenceSch
            boolean areAllPackageModesDefault = true;
            if (pkgOps != null) {
                for (String packageName : pkgOps.keySet()) {
                    if (!mAppOpsServiceInterface.arePackageModesDefault(packageName)) {
                    if (!mAppOpsServiceInterface.arePackageModesDefault(packageName,
                            UserHandle.getUserId(uid))) {
                        areAllPackageModesDefault = false;
                        break;
                    }
@@ -664,7 +665,8 @@ public class AppOpsService extends IAppOpsService.Stub implements PersistenceSch
            if (pkgOps != null) {
                for (int i = pkgOps.size() - 1; i >= 0; i--) {
                    foregroundOps = mAppOpsServiceInterface
                            .evalForegroundPackageOps(pkgOps.valueAt(i).packageName, foregroundOps);
                            .evalForegroundPackageOps(pkgOps.valueAt(i).packageName, foregroundOps,
                                    UserHandle.getUserId(uid));
                }
            }
            hasForegroundWatchers = false;
@@ -1467,10 +1469,12 @@ public class AppOpsService extends IAppOpsService.Stub implements PersistenceSch
        }

        @Mode int getMode() {
            return mAppOpsServiceInterface.getPackageMode(packageName, this.op);
            return mAppOpsServiceInterface.getPackageMode(packageName, this.op,
                    UserHandle.getUserId(this.uid));
        }
        void setMode(@Mode int mode) {
            mAppOpsServiceInterface.setPackageMode(packageName, this.op, mode);
            mAppOpsServiceInterface.setPackageMode(packageName, this.op, mode,
                    UserHandle.getUserId(this.uid));
        }

        int evalMode() {
@@ -1814,7 +1818,7 @@ public class AppOpsService extends IAppOpsService.Stub implements PersistenceSch
                    if (uidState == null || uidState.pkgOps == null) {
                        return;
                    }
                    mAppOpsServiceInterface.removePackage(pkgName);
                    mAppOpsServiceInterface.removePackage(pkgName, UserHandle.getUserId(uid));
                    Ops removedOps = uidState.pkgOps.remove(pkgName);
                    if (removedOps != null) {
                        scheduleFastWriteLocked();
@@ -2041,7 +2045,7 @@ public class AppOpsService extends IAppOpsService.Stub implements PersistenceSch
            // Remove any package state if such.
            if (uidState.pkgOps != null) {
                removedOps = uidState.pkgOps.remove(packageName);
                mAppOpsServiceInterface.removePackage(packageName);
                mAppOpsServiceInterface.removePackage(packageName, UserHandle.getUserId(uid));
            }

            // If we just nuked the last package state check if the UID is valid.
@@ -2491,7 +2495,8 @@ public class AppOpsService extends IAppOpsService.Stub implements PersistenceSch
                    ArrayMap<String, Ops> pkgOps = uidState.pkgOps;
                    if (pkgOps != null) {
                        pkgOps.remove(ops.packageName);
                        mAppOpsServiceInterface.removePackage(ops.packageName);
                        mAppOpsServiceInterface.removePackage(ops.packageName,
                                UserHandle.getUserId(uidState.uid));
                        if (pkgOps.isEmpty()) {
                            uidState.pkgOps = null;
                        }
@@ -2944,7 +2949,8 @@ public class AppOpsService extends IAppOpsService.Stub implements PersistenceSch
                    }
                    if (pkgOps.size() == 0) {
                        it.remove();
                        mAppOpsServiceInterface.removePackage(packageName);
                        mAppOpsServiceInterface.removePackage(packageName,
                                UserHandle.getUserId(uidState.uid));
                    }
                }
                if (uidState.isDefault()) {
@@ -6646,7 +6652,7 @@ public class AppOpsService extends IAppOpsService.Stub implements PersistenceSch
                return;
            }
            Ops removedOps = uidState.pkgOps.remove(packageName);
            mAppOpsServiceInterface.removePackage(packageName);
            mAppOpsServiceInterface.removePackage(packageName, UserHandle.getUserId(uid));
            if (removedOps != null) {
                scheduleFastWriteLocked();
            }
+12 −5
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ package com.android.server.appop;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.AppOpsManager.Mode;
import android.util.ArraySet;
import android.util.SparseBooleanArray;
@@ -61,23 +62,27 @@ public interface AppOpsServiceInterface {
     * Returns default op mode if the op mode for the particular package is not set.
     * @param packageName package name for which we need the op mode.
     * @param op app-op for which we need the mode.
     * @param userId user id associated with the package.
     * @return the mode of the app-op.
     */
    int getPackageMode(@NonNull String packageName, int op);
    int getPackageMode(@NonNull String packageName, int op, @UserIdInt int userId);

    /**
     * Sets the app-op mode for a particular package.
     * @param packageName package name for which we need to set the op mode.
     * @param op app-op for which we need to set the mode.
     * @param mode the mode of the app-op.
     * @param userId user id associated with the package.
     *
     */
    void setPackageMode(@NonNull String packageName, int op, @Mode int mode);
    void setPackageMode(@NonNull String packageName, int op, @Mode int mode, @UserIdInt int userId);

    /**
     * Stop tracking any app-op modes for a package.
     * @param packageName Name of the package for which we want to remove all mode tracking.
     * @param userId user id associated with the package.
     */
    boolean removePackage(@NonNull String packageName);
    boolean removePackage(@NonNull String packageName,  @UserIdInt int userId);

    /**
     * Stop tracking any app-op modes for this uid.
@@ -96,8 +101,9 @@ public interface AppOpsServiceInterface {
     * Returns true if all package modes for this package name are
     * in default state.
     * @param packageName package name.
     * @param userId user id associated with the package.
     */
    boolean arePackageModesDefault(String packageName);
    boolean arePackageModesDefault(String packageName, @UserIdInt int userId);

    /**
     * Stop tracking app-op modes for all uid and packages.
@@ -177,10 +183,11 @@ public interface AppOpsServiceInterface {
     * foregroundOps.
     * @param packageName for which the app-op's mode needs to be marked.
     * @param foregroundOps boolean array where app-ops that have MODE_FOREGROUND are marked true.
     * @param userId user id associated with the package.
     * @return foregroundOps.
     */
    SparseBooleanArray evalForegroundPackageOps(String packageName,
            SparseBooleanArray foregroundOps);
            SparseBooleanArray foregroundOps, @UserIdInt int userId);

    /**
     * Dump op mode and package mode listeners and their details.
+34 −14
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import static com.android.server.appop.AppOpsService.ModeCallback.ALL_OPS;
import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.AppGlobals;
import android.app.AppOpsManager;
import android.app.AppOpsManager.Mode;
@@ -70,7 +71,7 @@ public class LegacyAppOpsServiceInterfaceImpl implements AppOpsServiceInterface
    final SparseArray<SparseIntArray> mUidModes = new SparseArray<>();

    @GuardedBy("mLock")
    final ArrayMap<String, SparseIntArray> mPackageModes = new ArrayMap<>();
    final SparseArray<ArrayMap<String, SparseIntArray>> mUserPackageModes = new SparseArray<>();

    final SparseArray<ArraySet<OnOpModeChangedListener>> mOpModeWatchers = new SparseArray<>();
    final ArrayMap<String, ArraySet<OnOpModeChangedListener>> mPackageModeWatchers =
@@ -147,9 +148,13 @@ public class LegacyAppOpsServiceInterfaceImpl implements AppOpsServiceInterface
    }

    @Override
    public int getPackageMode(String packageName, int op) {
    public int getPackageMode(String packageName, int op, @UserIdInt int userId) {
        synchronized (mLock) {
            SparseIntArray opModes = mPackageModes.getOrDefault(packageName, null);
            ArrayMap<String, SparseIntArray> packageModes = mUserPackageModes.get(userId, null);
            if (packageModes == null) {
                return AppOpsManager.opToDefaultMode(op);
            }
            SparseIntArray opModes = packageModes.getOrDefault(packageName, null);
            if (opModes == null) {
                return AppOpsManager.opToDefaultMode(op);
            }
@@ -158,14 +163,19 @@ public class LegacyAppOpsServiceInterfaceImpl implements AppOpsServiceInterface
    }

    @Override
    public void setPackageMode(String packageName, int op, @Mode int mode) {
    public void setPackageMode(String packageName, int op, @Mode int mode, @UserIdInt int userId) {
        final int defaultMode = AppOpsManager.opToDefaultMode(op);
        synchronized (mLock) {
            SparseIntArray opModes = mPackageModes.get(packageName);
            ArrayMap<String, SparseIntArray> packageModes = mUserPackageModes.get(userId, null);
            if (packageModes == null) {
                packageModes = new ArrayMap<>();
                mUserPackageModes.put(userId, packageModes);
            }
            SparseIntArray opModes = packageModes.get(packageName);
            if (opModes == null) {
                if (mode != defaultMode) {
                    opModes = new SparseIntArray();
                    mPackageModes.put(packageName, opModes);
                    packageModes.put(packageName, opModes);
                    opModes.put(op, mode);
                    mPersistenceScheduler.scheduleWriteLocked();
                }
@@ -177,7 +187,7 @@ public class LegacyAppOpsServiceInterfaceImpl implements AppOpsServiceInterface
                    opModes.delete(op);
                    if (opModes.size() <= 0) {
                        opModes = null;
                        mPackageModes.remove(packageName);
                        packageModes.remove(packageName);
                    }
                } else {
                    opModes.put(op, mode);
@@ -208,17 +218,25 @@ public class LegacyAppOpsServiceInterfaceImpl implements AppOpsServiceInterface
    }

    @Override
    public boolean arePackageModesDefault(String packageMode) {
    public boolean arePackageModesDefault(String packageMode, @UserIdInt int userId) {
        synchronized (mLock) {
            SparseIntArray opModes = mPackageModes.get(packageMode);
            ArrayMap<String, SparseIntArray> packageModes = mUserPackageModes.get(userId, null);
            if (packageModes == null) {
                return true;
            }
            SparseIntArray opModes = packageModes.get(packageMode);
            return (opModes == null || opModes.size() <= 0);
        }
    }

    @Override
    public boolean removePackage(String packageName) {
    public boolean removePackage(String packageName, @UserIdInt int userId) {
        synchronized (mLock) {
            SparseIntArray ops = mPackageModes.remove(packageName);
            ArrayMap<String, SparseIntArray> packageModes = mUserPackageModes.get(userId, null);
            if (packageModes == null) {
                return false;
            }
            SparseIntArray ops = packageModes.remove(packageName);
            if (ops != null) {
                mPersistenceScheduler.scheduleFastWriteLocked();
                return true;
@@ -231,7 +249,7 @@ public class LegacyAppOpsServiceInterfaceImpl implements AppOpsServiceInterface
    public void clearAllModes() {
        synchronized (mLock) {
            mUidModes.clear();
            mPackageModes.clear();
            mUserPackageModes.clear();
        }
    }

@@ -468,9 +486,11 @@ public class LegacyAppOpsServiceInterfaceImpl implements AppOpsServiceInterface

    @Override
    public SparseBooleanArray evalForegroundPackageOps(String packageName,
            SparseBooleanArray foregroundOps) {
            SparseBooleanArray foregroundOps, @UserIdInt int userId) {
        synchronized (mLock) {
            return evalForegroundOps(mPackageModes.get(packageName), foregroundOps);
            ArrayMap<String, SparseIntArray> packageModes = mUserPackageModes.get(userId, null);
            return evalForegroundOps(packageModes == null ? null : packageModes.get(packageName),
                    foregroundOps);
        }
    }