diff options
| author | 2019-06-19 14:44:04 -0700 | |
|---|---|---|
| committer | 2019-06-19 14:44:04 -0700 | |
| commit | 1b3d97cac23313c8c18a1fbe08e5cf08c01537f9 (patch) | |
| tree | c69dfd4303fcf82079ab7beb63c3ec346d041202 | |
| parent | 9f89ee2516954fe76d17e1ea93400b1831880414 (diff) | |
| parent | fad1a8fb2f259cb9e699e9ac50c38f87d1921ba6 (diff) | |
Also trigger PermPolicySvc on app-ops changes
am: fad1a8fb2f
Change-Id: I0a1a9b04378f6ac95fc95a33cfbc4aeb6367dc08
4 files changed, 115 insertions, 22 deletions
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java index e5f914d9bf75..a7da3ec950f4 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -3127,6 +3127,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); } diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java index 313de3daffa3..e5e9598bec57 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java @@ -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); } diff --git a/services/core/java/com/android/server/policy/PermissionPolicyService.java b/services/core/java/com/android/server/policy/PermissionPolicyService.java index e01f42c642eb..48f3d0b95996 100644 --- a/services/core/java/com/android/server/policy/PermissionPolicyService.java +++ b/services/core/java/com/android/server/policy/PermissionPolicyService.java @@ -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, diff --git a/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java b/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java index 90e0dc4abd21..165883398897 100644 --- a/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java +++ b/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java @@ -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 |