Grab lock when accessing mutable state
bug:30881375
Change-Id: Ied52fd9666f28b5c2038144b85cd74480ccfde43
diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java
index b5b0cd8..4caeba8 100644
--- a/services/core/java/com/android/server/AppOpsService.java
+++ b/services/core/java/com/android/server/AppOpsService.java
@@ -875,7 +875,7 @@
return AppOpsManager.MODE_IGNORED;
}
synchronized (this) {
- if (isOpRestricted(uid, code, resolvedPackageName)) {
+ if (isOpRestrictedLocked(uid, code, resolvedPackageName)) {
return AppOpsManager.MODE_IGNORED;
}
code = AppOpsManager.opToSwitch(code);
@@ -1024,7 +1024,7 @@
return AppOpsManager.MODE_ERRORED;
}
Op op = getOpLocked(ops, code, true);
- if (isOpRestricted(uid, code, packageName)) {
+ if (isOpRestrictedLocked(uid, code, packageName)) {
return AppOpsManager.MODE_IGNORED;
}
if (op.duration == -1) {
@@ -1082,7 +1082,7 @@
return AppOpsManager.MODE_ERRORED;
}
Op op = getOpLocked(ops, code, true);
- if (isOpRestricted(uid, code, resolvedPackageName)) {
+ if (isOpRestrictedLocked(uid, code, resolvedPackageName)) {
return AppOpsManager.MODE_IGNORED;
}
final int switchCode = AppOpsManager.opToSwitch(code);
@@ -1308,7 +1308,7 @@
return op;
}
- private boolean isOpRestricted(int uid, int code, String packageName) {
+ private boolean isOpRestrictedLocked(int uid, int code, String packageName) {
int userHandle = UserHandle.getUserId(uid);
final int restrictionSetCount = mOpUserRestrictions.size();
@@ -2210,25 +2210,33 @@
private void setUserRestrictionNoCheck(int code, boolean restricted, IBinder token,
int userHandle, String[] exceptionPackages) {
- ClientRestrictionState restrictionState = mOpUserRestrictions.get(token);
+ boolean notifyChange = false;
- if (restrictionState == null) {
- try {
- restrictionState = new ClientRestrictionState(token);
- } catch (RemoteException e) {
- return;
+ synchronized (AppOpsService.this) {
+ ClientRestrictionState restrictionState = mOpUserRestrictions.get(token);
+
+ if (restrictionState == null) {
+ try {
+ restrictionState = new ClientRestrictionState(token);
+ } catch (RemoteException e) {
+ return;
+ }
+ mOpUserRestrictions.put(token, restrictionState);
}
- mOpUserRestrictions.put(token, restrictionState);
+
+ if (restrictionState.setRestriction(code, restricted, exceptionPackages, userHandle)) {
+ notifyChange = true;
+ }
+
+ if (restrictionState.isDefault()) {
+ mOpUserRestrictions.remove(token);
+ restrictionState.destroy();
+ }
}
- if (restrictionState.setRestriction(code, restricted, exceptionPackages, userHandle)) {
+ if (notifyChange) {
notifyWatchersOfChange(code);
}
-
- if (restrictionState.isDefault()) {
- mOpUserRestrictions.remove(token);
- restrictionState.destroy();
- }
}
private void notifyWatchersOfChange(int code) {
@@ -2263,10 +2271,12 @@
@Override
public void removeUser(int userHandle) throws RemoteException {
checkSystemUid("removeUser");
- final int tokenCount = mOpUserRestrictions.size();
- for (int i = tokenCount - 1; i >= 0; i--) {
- ClientRestrictionState opRestrictions = mOpUserRestrictions.valueAt(i);
- opRestrictions.removeUser(userHandle);
+ synchronized (AppOpsService.this) {
+ final int tokenCount = mOpUserRestrictions.size();
+ for (int i = tokenCount - 1; i >= 0; i--) {
+ ClientRestrictionState opRestrictions = mOpUserRestrictions.valueAt(i);
+ opRestrictions.removeUser(userHandle);
+ }
}
}