Also trigger PermPolicySvc on app-ops changes
PermissionPolicyService is supposed to keep permissions and app-ops in sync. Hence listen for app-ops changes too. Test: Reset app-ops and saw PermissionPolicyService triggered Fixes: 132704705 Change-Id: Ic208d9aebaab52c84893716777964c5b5cb254d2
This commit is contained in:
@@ -3126,6 +3126,27 @@ public class PermissionManagerService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NonNull ArrayList<PermissionInfo> getAllPermissionWithProtectionLevel(
|
||||||
|
@PermissionInfo.Protection int protectionLevel) {
|
||||||
|
ArrayList<PermissionInfo> matchingPermissions = new ArrayList<>();
|
||||||
|
|
||||||
|
synchronized (PermissionManagerService.this.mLock) {
|
||||||
|
int numTotalPermissions = mSettings.mPermissions.size();
|
||||||
|
|
||||||
|
for (int i = 0; i < numTotalPermissions; i++) {
|
||||||
|
BasePermission bp = mSettings.mPermissions.valueAt(i);
|
||||||
|
|
||||||
|
if (bp.perm != null && bp.perm.info != null
|
||||||
|
&& bp.protectionLevel == protectionLevel) {
|
||||||
|
matchingPermissions.add(bp.perm.info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return matchingPermissions;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable byte[] backupRuntimePermissions(@NonNull UserHandle user) {
|
public @Nullable byte[] backupRuntimePermissions(@NonNull UserHandle user) {
|
||||||
return PermissionManagerService.this.backupRuntimePermissions(user);
|
return PermissionManagerService.this.backupRuntimePermissions(user);
|
||||||
|
|||||||
@@ -195,4 +195,8 @@ public abstract class PermissionManagerServiceInternal extends PermissionManager
|
|||||||
|
|
||||||
/** HACK HACK methods to allow for partial migration of data to the PermissionManager class */
|
/** HACK HACK methods to allow for partial migration of data to the PermissionManager class */
|
||||||
public abstract @Nullable BasePermission getPermissionTEMP(@NonNull String permName);
|
public abstract @Nullable BasePermission getPermissionTEMP(@NonNull String permName);
|
||||||
|
|
||||||
|
/** Get all permission that have a certain protection level */
|
||||||
|
public abstract @NonNull ArrayList<PermissionInfo> getAllPermissionWithProtectionLevel(
|
||||||
|
@PermissionInfo.Protection int protectionLevel);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,10 +41,11 @@ import android.content.pm.PackageParser;
|
|||||||
import android.content.pm.PermissionInfo;
|
import android.content.pm.PermissionInfo;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
|
import android.os.RemoteException;
|
||||||
|
import android.os.ServiceManager;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.os.UserManagerInternal;
|
import android.os.UserManagerInternal;
|
||||||
import android.permission.PermissionControllerManager;
|
import android.permission.PermissionControllerManager;
|
||||||
import android.permission.PermissionManagerInternal;
|
|
||||||
import android.provider.Telephony;
|
import android.provider.Telephony;
|
||||||
import android.telecom.TelecomManager;
|
import android.telecom.TelecomManager;
|
||||||
import android.util.ArraySet;
|
import android.util.ArraySet;
|
||||||
@@ -54,10 +55,13 @@ import android.util.SparseBooleanArray;
|
|||||||
import android.util.SparseIntArray;
|
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.IAppOpsService;
|
||||||
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;
|
||||||
import com.android.server.SystemService;
|
import com.android.server.SystemService;
|
||||||
|
import com.android.server.pm.permission.PermissionManagerServiceInternal;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
@@ -96,8 +100,10 @@ public final class PermissionPolicyService extends SystemService {
|
|||||||
public void onStart() {
|
public void onStart() {
|
||||||
final PackageManagerInternal packageManagerInternal = LocalServices.getService(
|
final PackageManagerInternal packageManagerInternal = LocalServices.getService(
|
||||||
PackageManagerInternal.class);
|
PackageManagerInternal.class);
|
||||||
final PermissionManagerInternal permManagerInternal = LocalServices.getService(
|
final PermissionManagerServiceInternal permManagerInternal = LocalServices.getService(
|
||||||
PermissionManagerInternal.class);
|
PermissionManagerServiceInternal.class);
|
||||||
|
final IAppOpsService appOpsService = IAppOpsService.Stub.asInterface(
|
||||||
|
ServiceManager.getService(Context.APP_OPS_SERVICE));
|
||||||
|
|
||||||
packageManagerInternal.getPackageList(new PackageListObserver() {
|
packageManagerInternal.getPackageList(new PackageListObserver() {
|
||||||
@Override
|
@Override
|
||||||
@@ -122,6 +128,42 @@ public final class PermissionPolicyService extends SystemService {
|
|||||||
|
|
||||||
permManagerInternal.addOnRuntimePermissionStateChangedListener(
|
permManagerInternal.addOnRuntimePermissionStateChangedListener(
|
||||||
this::synchronizePackagePermissionsAndAppOpsAsyncForUser);
|
this::synchronizePackagePermissionsAndAppOpsAsyncForUser);
|
||||||
|
|
||||||
|
IAppOpsCallback appOpsListener = new IAppOpsCallback.Stub() {
|
||||||
|
public void opChanged(int op, int uid, String packageName) {
|
||||||
|
synchronizePackagePermissionsAndAppOpsAsyncForUser(packageName,
|
||||||
|
UserHandle.getUserId(uid));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
final ArrayList<PermissionInfo> dangerousPerms =
|
||||||
|
permManagerInternal.getAllPermissionWithProtectionLevel(
|
||||||
|
PermissionInfo.PROTECTION_DANGEROUS);
|
||||||
|
|
||||||
|
try {
|
||||||
|
int numDangerousPerms = dangerousPerms.size();
|
||||||
|
for (int i = 0; i < numDangerousPerms; i++) {
|
||||||
|
PermissionInfo perm = dangerousPerms.get(i);
|
||||||
|
|
||||||
|
if (perm.isHardRestricted() || perm.backgroundPermission != null) {
|
||||||
|
appOpsService.startWatchingMode(AppOpsManager.permissionToOpCode(perm.name),
|
||||||
|
null, appOpsListener);
|
||||||
|
} else if (perm.isSoftRestricted()) {
|
||||||
|
appOpsService.startWatchingMode(AppOpsManager.permissionToOpCode(perm.name),
|
||||||
|
null, appOpsListener);
|
||||||
|
|
||||||
|
SoftRestrictedPermissionPolicy policy =
|
||||||
|
SoftRestrictedPermissionPolicy.forPermission(null, null, null,
|
||||||
|
perm.name);
|
||||||
|
if (policy.resolveAppOp() != OP_NONE) {
|
||||||
|
appOpsService.startWatchingMode(policy.resolveAppOp(), null,
|
||||||
|
appOpsListener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (RemoteException doesNotHappen) {
|
||||||
|
Slog.wtf(LOG_TAG, "Cannot set up app-ops listener");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void synchronizePackagePermissionsAndAppOpsAsyncForUser(@NonNull String packageName,
|
private void synchronizePackagePermissionsAndAppOpsAsyncForUser(@NonNull String packageName,
|
||||||
@@ -380,7 +422,7 @@ public final class PermissionPolicyService extends SystemService {
|
|||||||
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 OpToUnrestrict op = mOpsToAllow.get(i);
|
final OpToUnrestrict op = mOpsToAllow.get(i);
|
||||||
setUidModeAllowed(op.code, op.uid);
|
setUidModeAllowed(op.code, op.uid, op.packageName);
|
||||||
}
|
}
|
||||||
final int allowIfDefaultCount = mOpsToAllowIfDefault.size();
|
final int allowIfDefaultCount = mOpsToAllowIfDefault.size();
|
||||||
for (int i = 0; i < allowIfDefaultCount; i++) {
|
for (int i = 0; i < allowIfDefaultCount; i++) {
|
||||||
@@ -390,12 +432,12 @@ public final class PermissionPolicyService extends SystemService {
|
|||||||
final int foregroundCount = mOpsToForeground.size();
|
final int foregroundCount = mOpsToForeground.size();
|
||||||
for (int i = 0; i < foregroundCount; i++) {
|
for (int i = 0; i < foregroundCount; i++) {
|
||||||
final OpToUnrestrict op = mOpsToForeground.get(i);
|
final OpToUnrestrict op = mOpsToForeground.get(i);
|
||||||
setUidModeForeground(op.code, op.uid);
|
setUidModeForeground(op.code, op.uid, op.packageName);
|
||||||
}
|
}
|
||||||
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 OpToUnrestrict op = mOpsToIgnore.get(i);
|
final OpToUnrestrict op = mOpsToIgnore.get(i);
|
||||||
setUidModeIgnored(op.code, op.uid);
|
setUidModeIgnored(op.code, op.uid, op.packageName);
|
||||||
}
|
}
|
||||||
final int ignoreIfDefaultCount = mOpsToIgnoreIfDefault.size();
|
final int ignoreIfDefaultCount = mOpsToIgnoreIfDefault.size();
|
||||||
for (int i = 0; i < ignoreIfDefaultCount; i++) {
|
for (int i = 0; i < ignoreIfDefaultCount; i++) {
|
||||||
@@ -586,20 +628,30 @@ public final class PermissionPolicyService extends SystemService {
|
|||||||
setUidModeIfDefault(opCode, uid, AppOpsManager.MODE_ALLOWED, packageName);
|
setUidModeIfDefault(opCode, uid, AppOpsManager.MODE_ALLOWED, packageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUidModeAllowed(int opCode, int uid) {
|
private void setUidModeAllowed(int opCode, int uid, @NonNull String packageName) {
|
||||||
mAppOpsManager.setUidMode(opCode, uid, AppOpsManager.MODE_ALLOWED);
|
setUidMode(opCode, uid, MODE_ALLOWED, packageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUidModeForeground(int opCode, int uid) {
|
private void setUidModeForeground(int opCode, int uid, @NonNull String packageName) {
|
||||||
mAppOpsManager.setUidMode(opCode, uid, AppOpsManager.MODE_FOREGROUND);
|
setUidMode(opCode, uid, MODE_FOREGROUND, packageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUidModeIgnoredIfDefault(int opCode, int uid, @NonNull String packageName) {
|
private void setUidModeIgnoredIfDefault(int opCode, int uid, @NonNull String packageName) {
|
||||||
setUidModeIfDefault(opCode, uid, AppOpsManager.MODE_IGNORED, packageName);
|
setUidModeIfDefault(opCode, uid, AppOpsManager.MODE_IGNORED, packageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUidModeIgnored(int opCode, int uid) {
|
private void setUidModeIgnored(int opCode, int uid, @NonNull String packageName) {
|
||||||
mAppOpsManager.setUidMode(opCode, uid, MODE_IGNORED);
|
setUidMode(opCode, uid, MODE_IGNORED, packageName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setUidMode(int opCode, int uid, int mode,
|
||||||
|
@NonNull String packageName) {
|
||||||
|
final int currentMode = mAppOpsManager.unsafeCheckOpRaw(AppOpsManager
|
||||||
|
.opToPublicName(opCode), uid, packageName);
|
||||||
|
|
||||||
|
if (currentMode != mode) {
|
||||||
|
mAppOpsManager.setUidMode(opCode, uid, mode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUidModeIfDefault(int opCode, int uid, int mode,
|
private void setUidModeIfDefault(int opCode, int uid, int mode,
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_SYST
|
|||||||
import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
|
import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
|
import android.annotation.Nullable;
|
||||||
import android.app.AppOpsManager;
|
import android.app.AppOpsManager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
@@ -75,14 +76,16 @@ public abstract class SoftRestrictedPermissionPolicy {
|
|||||||
* Get the policy for a soft restricted permission.
|
* Get the policy for a soft restricted permission.
|
||||||
*
|
*
|
||||||
* @param context A context to use
|
* @param context A context to use
|
||||||
* @param appInfo The application the permission belongs to
|
* @param appInfo The application the permission belongs to. Can be {@code null}, but then
|
||||||
* @param user The user the app belongs to
|
* only {@link #resolveAppOp} will work.
|
||||||
|
* @param user The user the app belongs to. Can be {@code null}, but then only
|
||||||
|
* {@link #resolveAppOp} will work.
|
||||||
* @param permission The name of the permission
|
* @param permission The name of the permission
|
||||||
*
|
*
|
||||||
* @return The policy for this permission
|
* @return The policy for this permission
|
||||||
*/
|
*/
|
||||||
public static @NonNull SoftRestrictedPermissionPolicy forPermission(@NonNull Context context,
|
public static @NonNull SoftRestrictedPermissionPolicy forPermission(@NonNull Context context,
|
||||||
@NonNull ApplicationInfo appInfo, @NonNull UserHandle user,
|
@Nullable ApplicationInfo appInfo, @Nullable UserHandle user,
|
||||||
@NonNull String permission) {
|
@NonNull String permission) {
|
||||||
switch (permission) {
|
switch (permission) {
|
||||||
// Storage uses a special app op to decide the mount state and supports soft restriction
|
// Storage uses a special app op to decide the mount state and supports soft restriction
|
||||||
@@ -90,13 +93,26 @@ public abstract class SoftRestrictedPermissionPolicy {
|
|||||||
// collections.
|
// collections.
|
||||||
case READ_EXTERNAL_STORAGE:
|
case READ_EXTERNAL_STORAGE:
|
||||||
case WRITE_EXTERNAL_STORAGE: {
|
case WRITE_EXTERNAL_STORAGE: {
|
||||||
int flags = context.getPackageManager().getPermissionFlags(
|
final int flags;
|
||||||
permission, appInfo.packageName, user);
|
final boolean applyRestriction;
|
||||||
boolean applyRestriction = (flags & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
|
final boolean isWhiteListed;
|
||||||
boolean isWhiteListed = (flags & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) != 0;
|
final boolean hasRequestedLegacyExternalStorage;
|
||||||
boolean hasRequestedLegacyExternalStorage =
|
final int targetSDK;
|
||||||
appInfo.hasRequestedLegacyExternalStorage();
|
|
||||||
int targetSDK = appInfo.targetSdkVersion;
|
if (appInfo != null) {
|
||||||
|
flags = context.getPackageManager().getPermissionFlags(permission,
|
||||||
|
appInfo.packageName, user);
|
||||||
|
applyRestriction = (flags & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
|
||||||
|
isWhiteListed = (flags & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) != 0;
|
||||||
|
hasRequestedLegacyExternalStorage = appInfo.hasRequestedLegacyExternalStorage();
|
||||||
|
targetSDK = appInfo.targetSdkVersion;
|
||||||
|
} else {
|
||||||
|
flags = 0;
|
||||||
|
applyRestriction = false;
|
||||||
|
isWhiteListed = false;
|
||||||
|
hasRequestedLegacyExternalStorage = false;
|
||||||
|
targetSDK = 0;
|
||||||
|
}
|
||||||
|
|
||||||
return new SoftRestrictedPermissionPolicy() {
|
return new SoftRestrictedPermissionPolicy() {
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Reference in New Issue
Block a user