Also trigger PermPolicySvc on app-ops changes
am: fad1a8fb2f
Change-Id: I254d2ca990e17109703a0980ff693b7dca08a812
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
|
||||
public @Nullable byte[] backupRuntimePermissions(@NonNull UserHandle 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 */
|
||||
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.os.Build;
|
||||
import android.os.Process;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManagerInternal;
|
||||
import android.permission.PermissionControllerManager;
|
||||
import android.permission.PermissionManagerInternal;
|
||||
import android.provider.Telephony;
|
||||
import android.telecom.TelecomManager;
|
||||
import android.util.ArraySet;
|
||||
@@ -54,10 +55,13 @@ import android.util.SparseBooleanArray;
|
||||
import android.util.SparseIntArray;
|
||||
|
||||
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.server.FgThread;
|
||||
import com.android.server.LocalServices;
|
||||
import com.android.server.SystemService;
|
||||
import com.android.server.pm.permission.PermissionManagerServiceInternal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
@@ -96,8 +100,10 @@ public final class PermissionPolicyService extends SystemService {
|
||||
public void onStart() {
|
||||
final PackageManagerInternal packageManagerInternal = LocalServices.getService(
|
||||
PackageManagerInternal.class);
|
||||
final PermissionManagerInternal permManagerInternal = LocalServices.getService(
|
||||
PermissionManagerInternal.class);
|
||||
final PermissionManagerServiceInternal permManagerInternal = LocalServices.getService(
|
||||
PermissionManagerServiceInternal.class);
|
||||
final IAppOpsService appOpsService = IAppOpsService.Stub.asInterface(
|
||||
ServiceManager.getService(Context.APP_OPS_SERVICE));
|
||||
|
||||
packageManagerInternal.getPackageList(new PackageListObserver() {
|
||||
@Override
|
||||
@@ -122,6 +128,42 @@ public final class PermissionPolicyService extends SystemService {
|
||||
|
||||
permManagerInternal.addOnRuntimePermissionStateChangedListener(
|
||||
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,
|
||||
@@ -380,7 +422,7 @@ public final class PermissionPolicyService extends SystemService {
|
||||
final int allowCount = mOpsToAllow.size();
|
||||
for (int i = 0; i < allowCount; i++) {
|
||||
final OpToUnrestrict op = mOpsToAllow.get(i);
|
||||
setUidModeAllowed(op.code, op.uid);
|
||||
setUidModeAllowed(op.code, op.uid, op.packageName);
|
||||
}
|
||||
final int allowIfDefaultCount = mOpsToAllowIfDefault.size();
|
||||
for (int i = 0; i < allowIfDefaultCount; i++) {
|
||||
@@ -390,12 +432,12 @@ public final class PermissionPolicyService extends SystemService {
|
||||
final int foregroundCount = mOpsToForeground.size();
|
||||
for (int i = 0; i < foregroundCount; i++) {
|
||||
final OpToUnrestrict op = mOpsToForeground.get(i);
|
||||
setUidModeForeground(op.code, op.uid);
|
||||
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);
|
||||
setUidModeIgnored(op.code, op.uid);
|
||||
setUidModeIgnored(op.code, op.uid, op.packageName);
|
||||
}
|
||||
final int ignoreIfDefaultCount = mOpsToIgnoreIfDefault.size();
|
||||
for (int i = 0; i < ignoreIfDefaultCount; i++) {
|
||||
@@ -586,20 +628,30 @@ public final class PermissionPolicyService extends SystemService {
|
||||
setUidModeIfDefault(opCode, uid, AppOpsManager.MODE_ALLOWED, packageName);
|
||||
}
|
||||
|
||||
private void setUidModeAllowed(int opCode, int uid) {
|
||||
mAppOpsManager.setUidMode(opCode, uid, AppOpsManager.MODE_ALLOWED);
|
||||
private void setUidModeAllowed(int opCode, int uid, @NonNull String packageName) {
|
||||
setUidMode(opCode, uid, MODE_ALLOWED, packageName);
|
||||
}
|
||||
|
||||
private void setUidModeForeground(int opCode, int uid) {
|
||||
mAppOpsManager.setUidMode(opCode, uid, AppOpsManager.MODE_FOREGROUND);
|
||||
private void setUidModeForeground(int opCode, int uid, @NonNull String packageName) {
|
||||
setUidMode(opCode, uid, MODE_FOREGROUND, packageName);
|
||||
}
|
||||
|
||||
private void setUidModeIgnoredIfDefault(int opCode, int uid, @NonNull String packageName) {
|
||||
setUidModeIfDefault(opCode, uid, AppOpsManager.MODE_IGNORED, packageName);
|
||||
}
|
||||
|
||||
private void setUidModeIgnored(int opCode, int uid) {
|
||||
mAppOpsManager.setUidMode(opCode, uid, MODE_IGNORED);
|
||||
private void setUidModeIgnored(int opCode, int uid, @NonNull String packageName) {
|
||||
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,
|
||||
|
||||
@@ -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 android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.app.AppOpsManager;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
@@ -75,14 +76,16 @@ public abstract class SoftRestrictedPermissionPolicy {
|
||||
* Get the policy for a soft restricted permission.
|
||||
*
|
||||
* @param context A context to use
|
||||
* @param appInfo The application the permission belongs to
|
||||
* @param user The user the app belongs to
|
||||
* @param appInfo The application the permission belongs to. Can be {@code null}, but then
|
||||
* 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
|
||||
*
|
||||
* @return The policy for this permission
|
||||
*/
|
||||
public static @NonNull SoftRestrictedPermissionPolicy forPermission(@NonNull Context context,
|
||||
@NonNull ApplicationInfo appInfo, @NonNull UserHandle user,
|
||||
@Nullable ApplicationInfo appInfo, @Nullable UserHandle user,
|
||||
@NonNull String permission) {
|
||||
switch (permission) {
|
||||
// Storage uses a special app op to decide the mount state and supports soft restriction
|
||||
@@ -90,13 +93,26 @@ public abstract class SoftRestrictedPermissionPolicy {
|
||||
// collections.
|
||||
case READ_EXTERNAL_STORAGE:
|
||||
case WRITE_EXTERNAL_STORAGE: {
|
||||
int flags = context.getPackageManager().getPermissionFlags(
|
||||
permission, appInfo.packageName, user);
|
||||
boolean applyRestriction = (flags & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
|
||||
boolean isWhiteListed = (flags & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) != 0;
|
||||
boolean hasRequestedLegacyExternalStorage =
|
||||
appInfo.hasRequestedLegacyExternalStorage();
|
||||
int targetSDK = appInfo.targetSdkVersion;
|
||||
final int flags;
|
||||
final boolean applyRestriction;
|
||||
final boolean isWhiteListed;
|
||||
final boolean hasRequestedLegacyExternalStorage;
|
||||
final int targetSDK;
|
||||
|
||||
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() {
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user