Prevent loop in PermissionPolicyService
The AppOpsModeChangeWatchers call back even if the mode was set to
already set mode. PermissionPolicyService listens to the same app-ops it
changes. I.e. it used to change the mode to default, which then causes a
call-back which made set it to default again, etc...
This exhausts a thread until the app-op is finally set to non-default.
The fix is to prevent the loop by checking if the app-op is already the
correct mode before setting it.
Fixes: 135674928
Test: atest IncidentReportListenerTest CollectorHostsideLibTest on
cuttlefish and crosshatch
Change-Id: Ic65945e814957ac59495b3da221fabb0f3d42b66
diff --git a/services/core/java/com/android/server/policy/PermissionPolicyService.java b/services/core/java/com/android/server/policy/PermissionPolicyService.java
index 68feb4a..3a78aa2 100644
--- a/services/core/java/com/android/server/policy/PermissionPolicyService.java
+++ b/services/core/java/com/android/server/policy/PermissionPolicyService.java
@@ -365,7 +365,7 @@
*
* @see #syncPackages
*/
- private final @NonNull ArrayList<OpToRestrict> mOpsToDefault = new ArrayList<>();
+ private final @NonNull ArrayList<OpToChange> mOpsToDefault = new ArrayList<>();
/**
* All ops that need to be flipped to allow if default.
@@ -374,14 +374,14 @@
*
* @see #syncPackages
*/
- private final @NonNull ArrayList<OpToUnrestrict> mOpsToAllowIfDefault = new ArrayList<>();
+ private final @NonNull ArrayList<OpToChange> mOpsToAllowIfDefault = new ArrayList<>();
/**
* All ops that need to be flipped to allow.
*
* @see #syncPackages
*/
- private final @NonNull ArrayList<OpToUnrestrict> mOpsToAllow = new ArrayList<>();
+ private final @NonNull ArrayList<OpToChange> mOpsToAllow = new ArrayList<>();
/**
* All ops that need to be flipped to ignore if default.
@@ -390,14 +390,14 @@
*
* @see #syncPackages
*/
- private final @NonNull ArrayList<OpToUnrestrict> mOpsToIgnoreIfDefault = new ArrayList<>();
+ private final @NonNull ArrayList<OpToChange> mOpsToIgnoreIfDefault = new ArrayList<>();
/**
* All ops that need to be flipped to ignore.
*
* @see #syncPackages
*/
- private final @NonNull ArrayList<OpToUnrestrict> mOpsToIgnore = new ArrayList<>();
+ private final @NonNull ArrayList<OpToChange> mOpsToIgnore = new ArrayList<>();
/**
* All ops that need to be flipped to foreground.
@@ -406,7 +406,7 @@
*
* @see #syncPackages
*/
- private final @NonNull ArrayList<OpToUnrestrict> mOpsToForeground = new ArrayList<>();
+ private final @NonNull ArrayList<OpToChange> mOpsToForeground = new ArrayList<>();
/**
* All ops that need to be flipped to foreground if allow.
@@ -415,7 +415,7 @@
*
* @see #syncPackages
*/
- private final @NonNull ArrayList<OpToUnrestrict> mOpsToForegroundIfAllow =
+ private final @NonNull ArrayList<OpToChange> mOpsToForegroundIfAllow =
new ArrayList<>();
PermissionToOpSynchroniser(@NonNull Context context) {
@@ -432,38 +432,38 @@
private void syncPackages() {
final int allowCount = mOpsToAllow.size();
for (int i = 0; i < allowCount; i++) {
- final OpToUnrestrict op = mOpsToAllow.get(i);
+ final OpToChange op = mOpsToAllow.get(i);
setUidModeAllowed(op.code, op.uid, op.packageName);
}
final int allowIfDefaultCount = mOpsToAllowIfDefault.size();
for (int i = 0; i < allowIfDefaultCount; i++) {
- final OpToUnrestrict op = mOpsToAllowIfDefault.get(i);
+ final OpToChange op = mOpsToAllowIfDefault.get(i);
setUidModeAllowedIfDefault(op.code, op.uid, op.packageName);
}
final int foregroundCount = mOpsToForegroundIfAllow.size();
for (int i = 0; i < foregroundCount; i++) {
- final OpToUnrestrict op = mOpsToForegroundIfAllow.get(i);
+ final OpToChange op = mOpsToForegroundIfAllow.get(i);
setUidModeForegroundIfAllow(op.code, op.uid, op.packageName);
}
final int foregroundIfAllowCount = mOpsToForeground.size();
for (int i = 0; i < foregroundIfAllowCount; i++) {
- final OpToUnrestrict op = mOpsToForeground.get(i);
+ final OpToChange op = mOpsToForeground.get(i);
setUidModeForeground(op.code, op.uid, op.packageName);
}
final int ignoreCount = mOpsToIgnore.size();
for (int i = 0; i < ignoreCount; i++) {
- final OpToUnrestrict op = mOpsToIgnore.get(i);
+ final OpToChange op = mOpsToIgnore.get(i);
setUidModeIgnored(op.code, op.uid, op.packageName);
}
final int ignoreIfDefaultCount = mOpsToIgnoreIfDefault.size();
for (int i = 0; i < ignoreIfDefaultCount; i++) {
- final OpToUnrestrict op = mOpsToIgnoreIfDefault.get(i);
+ final OpToChange op = mOpsToIgnoreIfDefault.get(i);
setUidModeIgnoredIfDefault(op.code, op.uid, op.packageName);
}
final int defaultCount = mOpsToDefault.size();
for (int i = 0; i < defaultCount; i++) {
- final OpToRestrict op = mOpsToDefault.get(i);
- setUidModeDefault(op.code, op.uid);
+ final OpToChange op = mOpsToDefault.get(i);
+ setUidModeDefault(op.code, op.uid, op.packageName);
}
}
@@ -493,9 +493,9 @@
if (permissionInfo.isHardRestricted()) {
if (opCode != OP_NONE) {
if (applyRestriction) {
- mOpsToDefault.add(new OpToRestrict(uid, opCode));
+ mOpsToDefault.add(new OpToChange(uid, pkg.packageName, opCode));
} else {
- mOpsToAllowIfDefault.add(new OpToUnrestrict(uid, pkg.packageName, opCode));
+ mOpsToAllowIfDefault.add(new OpToChange(uid, pkg.packageName, opCode));
}
}
} else if (permissionInfo.isSoftRestricted()) {
@@ -505,9 +505,9 @@
if (opCode != OP_NONE) {
if (policy.canBeGranted()) {
- mOpsToAllowIfDefault.add(new OpToUnrestrict(uid, pkg.packageName, opCode));
+ mOpsToAllowIfDefault.add(new OpToChange(uid, pkg.packageName, opCode));
} else {
- mOpsToDefault.add(new OpToRestrict(uid, opCode));
+ mOpsToDefault.add(new OpToChange(uid, pkg.packageName, opCode));
}
}
@@ -515,15 +515,14 @@
if (op != OP_NONE) {
switch (policy.getDesiredOpMode()) {
case MODE_DEFAULT:
- mOpsToDefault.add(new OpToRestrict(uid, op));
+ mOpsToDefault.add(new OpToChange(uid, pkg.packageName, op));
break;
case MODE_ALLOWED:
if (policy.shouldSetAppOpIfNotDefault()) {
- mOpsToAllow.add(new OpToUnrestrict(uid, pkg.packageName, op));
+ mOpsToAllow.add(new OpToChange(uid, pkg.packageName, op));
} else {
mOpsToAllowIfDefault.add(
- new OpToUnrestrict(uid, pkg.packageName,
- op));
+ new OpToChange(uid, pkg.packageName, op));
}
break;
case MODE_FOREGROUND:
@@ -532,10 +531,10 @@
break;
case MODE_IGNORED:
if (policy.shouldSetAppOpIfNotDefault()) {
- mOpsToIgnore.add(new OpToUnrestrict(uid, pkg.packageName, op));
+ mOpsToIgnore.add(new OpToChange(uid, pkg.packageName, op));
} else {
mOpsToIgnoreIfDefault.add(
- new OpToUnrestrict(uid, pkg.packageName,
+ new OpToChange(uid, pkg.packageName,
op));
}
break;
@@ -597,7 +596,7 @@
if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0
&& isBgPermRestricted(pkgName, bgPermissionName, uid)) {
- mOpsToForegroundIfAllow.add(new OpToUnrestrict(uid, pkgName, opCode));
+ mOpsToForegroundIfAllow.add(new OpToChange(uid, pkgName, opCode));
}
return;
@@ -611,12 +610,12 @@
pkgName) == PackageManager.PERMISSION_GRANTED;
if (!isBgHardRestricted && isBgPermGranted) {
- mOpsToAllow.add(new OpToUnrestrict(uid, pkgName, opCode));
+ mOpsToAllow.add(new OpToChange(uid, pkgName, opCode));
} else {
- mOpsToForeground.add(new OpToUnrestrict(uid, pkgName, opCode));
+ mOpsToForeground.add(new OpToChange(uid, pkgName, opCode));
}
} else {
- mOpsToIgnore.add(new OpToUnrestrict(uid, pkgName, opCode));
+ mOpsToIgnore.add(new OpToChange(uid, pkgName, opCode));
}
}
@@ -703,26 +702,16 @@
}
}
- private void setUidModeDefault(int opCode, int uid) {
- mAppOpsManager.setUidMode(opCode, uid, MODE_DEFAULT);
+ private void setUidModeDefault(int opCode, int uid, String packageName) {
+ setUidMode(opCode, uid, MODE_DEFAULT, packageName);
}
- private class OpToRestrict {
- final int uid;
- final int code;
-
- OpToRestrict(int uid, int code) {
- this.uid = uid;
- this.code = code;
- }
- }
-
- private class OpToUnrestrict {
+ private class OpToChange {
final int uid;
final @NonNull String packageName;
final int code;
- OpToUnrestrict(int uid, @NonNull String packageName, int code) {
+ OpToChange(int uid, @NonNull String packageName, int code) {
this.uid = uid;
this.packageName = packageName;
this.code = code;