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
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user