From ec0d07e879e39cfdf8b500a39abe3cc4a6d17860 Mon Sep 17 00:00:00 2001 From: Pyuli Naithani Date: Tue, 6 Sep 2022 20:03:49 +0000 Subject: [PATCH] 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 --- .../android/server/appop/AppOpsService.java | 26 ++++++---- .../server/appop/AppOpsServiceInterface.java | 17 +++++-- .../LegacyAppOpsServiceInterfaceImpl.java | 48 +++++++++++++------ 3 files changed, 62 insertions(+), 29 deletions(-) diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java index 248e35e6964d2..ef42a1be93b67 100644 --- a/services/core/java/com/android/server/appop/AppOpsService.java +++ b/services/core/java/com/android/server/appop/AppOpsService.java @@ -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 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(); } diff --git a/services/core/java/com/android/server/appop/AppOpsServiceInterface.java b/services/core/java/com/android/server/appop/AppOpsServiceInterface.java index c707086fb2fbe..c4a9a4b5d7279 100644 --- a/services/core/java/com/android/server/appop/AppOpsServiceInterface.java +++ b/services/core/java/com/android/server/appop/AppOpsServiceInterface.java @@ -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. diff --git a/services/core/java/com/android/server/appop/LegacyAppOpsServiceInterfaceImpl.java b/services/core/java/com/android/server/appop/LegacyAppOpsServiceInterfaceImpl.java index 2d498ea2117cb..802669728b241 100644 --- a/services/core/java/com/android/server/appop/LegacyAppOpsServiceInterfaceImpl.java +++ b/services/core/java/com/android/server/appop/LegacyAppOpsServiceInterfaceImpl.java @@ -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 mUidModes = new SparseArray<>(); @GuardedBy("mLock") - final ArrayMap mPackageModes = new ArrayMap<>(); + final SparseArray> mUserPackageModes = new SparseArray<>(); final SparseArray> mOpModeWatchers = new SparseArray<>(); final ArrayMap> 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 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 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 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 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 packageModes = mUserPackageModes.get(userId, null); + return evalForegroundOps(packageModes == null ? null : packageModes.get(packageName), + foregroundOps); } }