Merge "Set most leniant mode if two perms affect one appop" into qt-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
d84102bf9e
@@ -50,6 +50,7 @@ import android.permission.PermissionControllerManager;
|
|||||||
import android.provider.Telephony;
|
import android.provider.Telephony;
|
||||||
import android.telecom.TelecomManager;
|
import android.telecom.TelecomManager;
|
||||||
import android.util.ArraySet;
|
import android.util.ArraySet;
|
||||||
|
import android.util.LongSparseLongArray;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
import android.util.SparseBooleanArray;
|
import android.util.SparseBooleanArray;
|
||||||
@@ -58,6 +59,7 @@ import android.util.SparseIntArray;
|
|||||||
import com.android.internal.annotations.GuardedBy;
|
import com.android.internal.annotations.GuardedBy;
|
||||||
import com.android.internal.app.IAppOpsCallback;
|
import com.android.internal.app.IAppOpsCallback;
|
||||||
import com.android.internal.app.IAppOpsService;
|
import com.android.internal.app.IAppOpsService;
|
||||||
|
import com.android.internal.util.IntPair;
|
||||||
import com.android.internal.util.function.pooled.PooledLambda;
|
import com.android.internal.util.function.pooled.PooledLambda;
|
||||||
import com.android.server.FgThread;
|
import com.android.server.FgThread;
|
||||||
import com.android.server.LocalServices;
|
import com.android.server.LocalServices;
|
||||||
@@ -147,11 +149,9 @@ public final class PermissionPolicyService extends SystemService {
|
|||||||
PermissionInfo perm = dangerousPerms.get(i);
|
PermissionInfo perm = dangerousPerms.get(i);
|
||||||
|
|
||||||
if (perm.isHardRestricted() || perm.backgroundPermission != null) {
|
if (perm.isHardRestricted() || perm.backgroundPermission != null) {
|
||||||
appOpsService.startWatchingMode(AppOpsManager.permissionToOpCode(perm.name),
|
appOpsService.startWatchingMode(getSwitchOp(perm.name), null, appOpsListener);
|
||||||
null, appOpsListener);
|
|
||||||
} else if (perm.isSoftRestricted()) {
|
} else if (perm.isSoftRestricted()) {
|
||||||
appOpsService.startWatchingMode(AppOpsManager.permissionToOpCode(perm.name),
|
appOpsService.startWatchingMode(getSwitchOp(perm.name), null, appOpsListener);
|
||||||
null, appOpsListener);
|
|
||||||
|
|
||||||
SoftRestrictedPermissionPolicy policy =
|
SoftRestrictedPermissionPolicy policy =
|
||||||
SoftRestrictedPermissionPolicy.forPermission(null, null, null,
|
SoftRestrictedPermissionPolicy.forPermission(null, null, null,
|
||||||
@@ -167,6 +167,25 @@ public final class PermissionPolicyService extends SystemService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get op that controls the access related to the permission.
|
||||||
|
*
|
||||||
|
* <p>Usually the permission-op relationship is 1:1 but some permissions (e.g. fine location)
|
||||||
|
* {@link AppOpsManager#sOpToSwitch share an op} to control the access.
|
||||||
|
*
|
||||||
|
* @param permission The permission
|
||||||
|
*
|
||||||
|
* @return The op that controls the access of the permission
|
||||||
|
*/
|
||||||
|
private static int getSwitchOp(@NonNull String permission) {
|
||||||
|
int op = AppOpsManager.permissionToOpCode(permission);
|
||||||
|
if (op == OP_NONE) {
|
||||||
|
return OP_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return AppOpsManager.opToSwitch(op);
|
||||||
|
}
|
||||||
|
|
||||||
private void synchronizePackagePermissionsAndAppOpsAsyncForUser(@NonNull String packageName,
|
private void synchronizePackagePermissionsAndAppOpsAsyncForUser(@NonNull String packageName,
|
||||||
@UserIdInt int changedUserId) {
|
@UserIdInt int changedUserId) {
|
||||||
if (isStarted(changedUserId)) {
|
if (isStarted(changedUserId)) {
|
||||||
@@ -430,40 +449,89 @@ public final class PermissionPolicyService extends SystemService {
|
|||||||
* <p>This processes ops previously added by {@link #addOpIfRestricted}
|
* <p>This processes ops previously added by {@link #addOpIfRestricted}
|
||||||
*/
|
*/
|
||||||
private void syncPackages() {
|
private void syncPackages() {
|
||||||
|
// Remember which ops were already set. This makes sure that we always set the most
|
||||||
|
// permissive mode if two OpChanges are scheduled. This can e.g. happen if two
|
||||||
|
// permissions change the same op. See {@link #getSwitchOp}.
|
||||||
|
LongSparseLongArray alreadySetAppOps = new LongSparseLongArray();
|
||||||
|
|
||||||
final int allowCount = mOpsToAllow.size();
|
final int allowCount = mOpsToAllow.size();
|
||||||
for (int i = 0; i < allowCount; i++) {
|
for (int i = 0; i < allowCount; i++) {
|
||||||
final OpToChange op = mOpsToAllow.get(i);
|
final OpToChange op = mOpsToAllow.get(i);
|
||||||
|
|
||||||
setUidModeAllowed(op.code, op.uid, op.packageName);
|
setUidModeAllowed(op.code, op.uid, op.packageName);
|
||||||
|
alreadySetAppOps.put(IntPair.of(op.uid, op.code), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
final int allowIfDefaultCount = mOpsToAllowIfDefault.size();
|
final int allowIfDefaultCount = mOpsToAllowIfDefault.size();
|
||||||
for (int i = 0; i < allowIfDefaultCount; i++) {
|
for (int i = 0; i < allowIfDefaultCount; i++) {
|
||||||
final OpToChange op = mOpsToAllowIfDefault.get(i);
|
final OpToChange op = mOpsToAllowIfDefault.get(i);
|
||||||
setUidModeAllowedIfDefault(op.code, op.uid, op.packageName);
|
if (alreadySetAppOps.indexOfKey(IntPair.of(op.uid, op.code)) >= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean wasSet = setUidModeAllowedIfDefault(op.code, op.uid, op.packageName);
|
||||||
|
if (wasSet) {
|
||||||
|
alreadySetAppOps.put(IntPair.of(op.uid, op.code), 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
final int foregroundCount = mOpsToForegroundIfAllow.size();
|
|
||||||
for (int i = 0; i < foregroundCount; i++) {
|
final int foregroundIfAllowedCount = mOpsToForegroundIfAllow.size();
|
||||||
|
for (int i = 0; i < foregroundIfAllowedCount; i++) {
|
||||||
final OpToChange op = mOpsToForegroundIfAllow.get(i);
|
final OpToChange op = mOpsToForegroundIfAllow.get(i);
|
||||||
setUidModeForegroundIfAllow(op.code, op.uid, op.packageName);
|
if (alreadySetAppOps.indexOfKey(IntPair.of(op.uid, op.code)) >= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean wasSet = setUidModeForegroundIfAllow(op.code, op.uid, op.packageName);
|
||||||
|
if (wasSet) {
|
||||||
|
alreadySetAppOps.put(IntPair.of(op.uid, op.code), 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
final int foregroundIfAllowCount = mOpsToForeground.size();
|
|
||||||
for (int i = 0; i < foregroundIfAllowCount; i++) {
|
final int foregroundCount = mOpsToForeground.size();
|
||||||
|
for (int i = 0; i < foregroundCount; i++) {
|
||||||
final OpToChange op = mOpsToForeground.get(i);
|
final OpToChange op = mOpsToForeground.get(i);
|
||||||
|
if (alreadySetAppOps.indexOfKey(IntPair.of(op.uid, op.code)) >= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
setUidModeForeground(op.code, op.uid, op.packageName);
|
setUidModeForeground(op.code, op.uid, op.packageName);
|
||||||
|
alreadySetAppOps.put(IntPair.of(op.uid, op.code), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
final int ignoreCount = mOpsToIgnore.size();
|
final int ignoreCount = mOpsToIgnore.size();
|
||||||
for (int i = 0; i < ignoreCount; i++) {
|
for (int i = 0; i < ignoreCount; i++) {
|
||||||
final OpToChange op = mOpsToIgnore.get(i);
|
final OpToChange op = mOpsToIgnore.get(i);
|
||||||
|
if (alreadySetAppOps.indexOfKey(IntPair.of(op.uid, op.code)) >= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
setUidModeIgnored(op.code, op.uid, op.packageName);
|
setUidModeIgnored(op.code, op.uid, op.packageName);
|
||||||
|
alreadySetAppOps.put(IntPair.of(op.uid, op.code), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
final int ignoreIfDefaultCount = mOpsToIgnoreIfDefault.size();
|
final int ignoreIfDefaultCount = mOpsToIgnoreIfDefault.size();
|
||||||
for (int i = 0; i < ignoreIfDefaultCount; i++) {
|
for (int i = 0; i < ignoreIfDefaultCount; i++) {
|
||||||
final OpToChange op = mOpsToIgnoreIfDefault.get(i);
|
final OpToChange op = mOpsToIgnoreIfDefault.get(i);
|
||||||
setUidModeIgnoredIfDefault(op.code, op.uid, op.packageName);
|
if (alreadySetAppOps.indexOfKey(IntPair.of(op.uid, op.code)) >= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean wasSet = setUidModeIgnoredIfDefault(op.code, op.uid, op.packageName);
|
||||||
|
if (wasSet) {
|
||||||
|
alreadySetAppOps.put(IntPair.of(op.uid, op.code), 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final int defaultCount = mOpsToDefault.size();
|
final int defaultCount = mOpsToDefault.size();
|
||||||
for (int i = 0; i < defaultCount; i++) {
|
for (int i = 0; i < defaultCount; i++) {
|
||||||
final OpToChange op = mOpsToDefault.get(i);
|
final OpToChange op = mOpsToDefault.get(i);
|
||||||
|
if (alreadySetAppOps.indexOfKey(IntPair.of(op.uid, op.code)) >= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
setUidModeDefault(op.code, op.uid, op.packageName);
|
setUidModeDefault(op.code, op.uid, op.packageName);
|
||||||
|
alreadySetAppOps.put(IntPair.of(op.uid, op.code), 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -479,7 +547,7 @@ public final class PermissionPolicyService extends SystemService {
|
|||||||
private void addOpIfRestricted(@NonNull PermissionInfo permissionInfo,
|
private void addOpIfRestricted(@NonNull PermissionInfo permissionInfo,
|
||||||
@NonNull PackageInfo pkg) {
|
@NonNull PackageInfo pkg) {
|
||||||
final String permission = permissionInfo.name;
|
final String permission = permissionInfo.name;
|
||||||
final int opCode = AppOpsManager.permissionToOpCode(permission);
|
final int opCode = getSwitchOp(permission);
|
||||||
final int uid = pkg.applicationInfo.uid;
|
final int uid = pkg.applicationInfo.uid;
|
||||||
|
|
||||||
if (!permissionInfo.isRestricted()) {
|
if (!permissionInfo.isRestricted()) {
|
||||||
@@ -581,7 +649,7 @@ public final class PermissionPolicyService extends SystemService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final String permission = permissionInfo.name;
|
final String permission = permissionInfo.name;
|
||||||
final int opCode = AppOpsManager.permissionToOpCode(permission);
|
final int opCode = getSwitchOp(permission);
|
||||||
final String pkgName = pkg.packageName;
|
final String pkgName = pkg.packageName;
|
||||||
final int uid = pkg.applicationInfo.uid;
|
final int uid = pkg.applicationInfo.uid;
|
||||||
|
|
||||||
@@ -641,7 +709,7 @@ public final class PermissionPolicyService extends SystemService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (String permission : pkg.requestedPermissions) {
|
for (String permission : pkg.requestedPermissions) {
|
||||||
final int opCode = AppOpsManager.permissionToOpCode(permission);
|
final int opCode = getSwitchOp(permission);
|
||||||
if (opCode == OP_NONE) {
|
if (opCode == OP_NONE) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -658,24 +726,27 @@ public final class PermissionPolicyService extends SystemService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUidModeAllowedIfDefault(int opCode, int uid, @NonNull String packageName) {
|
private boolean setUidModeAllowedIfDefault(int opCode, int uid,
|
||||||
setUidModeIfMode(opCode, uid, MODE_DEFAULT, MODE_ALLOWED, packageName);
|
@NonNull String packageName) {
|
||||||
|
return setUidModeIfMode(opCode, uid, MODE_DEFAULT, MODE_ALLOWED, packageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUidModeAllowed(int opCode, int uid, @NonNull String packageName) {
|
private void setUidModeAllowed(int opCode, int uid, @NonNull String packageName) {
|
||||||
setUidMode(opCode, uid, MODE_ALLOWED, packageName);
|
setUidMode(opCode, uid, MODE_ALLOWED, packageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUidModeForegroundIfAllow(int opCode, int uid, @NonNull String packageName) {
|
private boolean setUidModeForegroundIfAllow(int opCode, int uid,
|
||||||
setUidModeIfMode(opCode, uid, MODE_ALLOWED, MODE_FOREGROUND, packageName);
|
@NonNull String packageName) {
|
||||||
|
return setUidModeIfMode(opCode, uid, MODE_ALLOWED, MODE_FOREGROUND, packageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUidModeForeground(int opCode, int uid, @NonNull String packageName) {
|
private void setUidModeForeground(int opCode, int uid, @NonNull String packageName) {
|
||||||
setUidMode(opCode, uid, MODE_FOREGROUND, packageName);
|
setUidMode(opCode, uid, MODE_FOREGROUND, packageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUidModeIgnoredIfDefault(int opCode, int uid, @NonNull String packageName) {
|
private boolean setUidModeIgnoredIfDefault(int opCode, int uid,
|
||||||
setUidModeIfMode(opCode, uid, MODE_DEFAULT, MODE_IGNORED, packageName);
|
@NonNull String packageName) {
|
||||||
|
return setUidModeIfMode(opCode, uid, MODE_DEFAULT, MODE_IGNORED, packageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUidModeIgnored(int opCode, int uid, @NonNull String packageName) {
|
private void setUidModeIgnored(int opCode, int uid, @NonNull String packageName) {
|
||||||
@@ -692,14 +763,17 @@ public final class PermissionPolicyService extends SystemService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUidModeIfMode(int opCode, int uid, int requiredModeBefore, int newMode,
|
private boolean setUidModeIfMode(int opCode, int uid, int requiredModeBefore, int newMode,
|
||||||
@NonNull String packageName) {
|
@NonNull String packageName) {
|
||||||
final int currentMode = mAppOpsManager.unsafeCheckOpRaw(AppOpsManager
|
final int currentMode = mAppOpsManager.unsafeCheckOpRaw(AppOpsManager
|
||||||
.opToPublicName(opCode), uid, packageName);
|
.opToPublicName(opCode), uid, packageName);
|
||||||
|
|
||||||
if (currentMode == requiredModeBefore) {
|
if (currentMode == requiredModeBefore) {
|
||||||
mAppOpsManager.setUidMode(opCode, uid, newMode);
|
mAppOpsManager.setUidMode(opCode, uid, newMode);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUidModeDefault(int opCode, int uid, String packageName) {
|
private void setUidModeDefault(int opCode, int uid, String packageName) {
|
||||||
|
|||||||
@@ -41,6 +41,9 @@
|
|||||||
"options": [
|
"options": [
|
||||||
{
|
{
|
||||||
"include-filter": "android.permission.cts.SplitPermissionTest"
|
"include-filter": "android.permission.cts.SplitPermissionTest"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"include-filter": "android.permission.cts.BackgroundPermissionsTest"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user