diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java index 87494a62b6251..351c5be5e7910 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java @@ -2536,33 +2536,38 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt } } + Collection uidRequestedPermissions; + Collection uidImplicitPermissions; + int uidTargetSdkVersion; + if (!ps.hasSharedUser()) { + uidRequestedPermissions = pkg.getRequestedPermissions(); + uidImplicitPermissions = pkg.getImplicitPermissions(); + uidTargetSdkVersion = pkg.getTargetSdkVersion(); + } else { + uidRequestedPermissions = new ArraySet<>(); + uidImplicitPermissions = new ArraySet<>(); + uidTargetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT; + final ArraySet packages = + mPackageManagerInt.getSharedUserPackages(ps.getSharedUserAppId()); + int packagesSize = packages.size(); + for (int i = 0; i < packagesSize; i++) { + AndroidPackageApi sharedUserPackage = + packages.valueAt(i).getAndroidPackage(); + uidRequestedPermissions.addAll( + sharedUserPackage.getRequestedPermissions()); + uidImplicitPermissions.addAll( + sharedUserPackage.getImplicitPermissions()); + uidTargetSdkVersion = Math.min(uidTargetSdkVersion, + sharedUserPackage.getTargetSdkVersion()); + } + } + synchronized (mLock) { for (final int userId : userIds) { final UserPermissionState userState = mState.getOrCreateUserState(userId); final UidPermissionState uidState = userState.getOrCreateUidState(ps.getAppId()); if (uidState.isMissing()) { - Collection uidRequestedPermissions; - int targetSdkVersion; - if (!ps.hasSharedUser()) { - uidRequestedPermissions = pkg.getRequestedPermissions(); - targetSdkVersion = pkg.getTargetSdkVersion(); - } else { - uidRequestedPermissions = new ArraySet<>(); - targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT; - final ArraySet packages = - mPackageManagerInt.getSharedUserPackages(ps.getSharedUserAppId()); - int packagesSize = packages.size(); - for (int i = 0; i < packagesSize; i++) { - AndroidPackageApi sharedUserPackage = - packages.valueAt(i).getAndroidPackage(); - uidRequestedPermissions.addAll( - sharedUserPackage.getRequestedPermissions()); - targetSdkVersion = Math.min(targetSdkVersion, - sharedUserPackage.getTargetSdkVersion()); - } - } - for (String permissionName : uidRequestedPermissions) { Permission permission = mRegistry.getPermission(permissionName); if (permission == null) { @@ -2576,7 +2581,7 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT, FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT); } - if (targetSdkVersion < Build.VERSION_CODES.M) { + if (uidTargetSdkVersion < Build.VERSION_CODES.M) { uidState.updatePermissionFlags(permission, PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED | PackageManager.FLAG_PERMISSION_REVOKED_COMPAT, @@ -2606,8 +2611,7 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt // the runtime ones are written only if changed. The only cases of // changed runtime permissions here are promotion of an install to // runtime and revocation of a runtime from a shared user. - if (revokeUnusedSharedUserPermissionsLocked( - mPackageManagerInt.getSharedUserPackages(ps.getSharedUserAppId()), + if (revokeUnusedSharedUserPermissionsLocked(uidRequestedPermissions, uidState)) { updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId); runtimePermissionsRevoked = true; @@ -2909,8 +2913,9 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt userState.setInstallPermissionsFixed(ps.getPackageName(), true); } - updatedUserIds = revokePermissionsNoLongerImplicitLocked(uidState, pkg, - userId, updatedUserIds); + updatedUserIds = revokePermissionsNoLongerImplicitLocked(uidState, + pkg.getPackageName(), uidImplicitPermissions, uidTargetSdkVersion, userId, + updatedUserIds); updatedUserIds = setInitialGrantForNewImplicitPermissionsLocked(origState, uidState, pkg, newImplicitPermissions, userId, updatedUserIds); } @@ -2947,7 +2952,9 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt * {@link PackageManager#FLAG_PERMISSION_REVOKE_WHEN_REQUESTED} set. * * @param ps The state of the permissions of the package - * @param pkg The package that is currently looked at + * @param packageName The name of the package + * @param uidImplicitPermissions The implicit permissions of all packages in the UID + * @param uidTargetSdkVersion The lowest target SDK version of all packages in the UID * @param userIds All user IDs in the system, must be passed in because this method is locked * @param updatedUserIds a list of user ids that needs to be amended if the permission state * for a user is changed. @@ -2957,14 +2964,12 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt @NonNull @GuardedBy("mLock") private int[] revokePermissionsNoLongerImplicitLocked(@NonNull UidPermissionState ps, - @NonNull AndroidPackage pkg, int userId, @NonNull int[] updatedUserIds) { - String pkgName = pkg.getPackageName(); - boolean supportsRuntimePermissions = pkg.getTargetSdkVersion() - >= Build.VERSION_CODES.M; + @NonNull String packageName, @NonNull Collection uidImplicitPermissions, + int uidTargetSdkVersion, int userId, @NonNull int[] updatedUserIds) { + boolean supportsRuntimePermissions = uidTargetSdkVersion >= Build.VERSION_CODES.M; for (String permission : ps.getGrantedPermissions()) { - if (pkg.getRequestedPermissions().contains(permission) - && !pkg.getImplicitPermissions().contains(permission)) { + if (!uidImplicitPermissions.contains(permission)) { Permission bp = mRegistry.getPermission(permission); if (bp != null && bp.isRuntime()) { int flags = ps.getPermissionFlags(permission); @@ -2991,7 +2996,7 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt if (ps.revokePermission(bp)) { if (DEBUG_PERMISSIONS) { Slog.i(TAG, "Revoking runtime permission " - + permission + " for " + pkgName + + permission + " for " + packageName + " as it is now requested"); } } @@ -3822,27 +3827,8 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt @GuardedBy("mLock") private boolean revokeUnusedSharedUserPermissionsLocked( - ArraySet pkgList, UidPermissionState uidState) { - // Collect all used permissions in the UID - final ArraySet usedPermissions = new ArraySet<>(); - if (pkgList == null || pkgList.size() == 0) { - return false; - } - for (PackageStateInternal pkgState : pkgList) { - final AndroidPackageApi pkg = pkgState.getAndroidPackage(); - if (pkg.getRequestedPermissions().isEmpty()) { - continue; - } - final int requestedPermCount = pkg.getRequestedPermissions().size(); - for (int j = 0; j < requestedPermCount; j++) { - String permission = pkg.getRequestedPermissions().get(j); - Permission bp = mRegistry.getPermission(permission); - if (bp != null) { - usedPermissions.add(permission); - } - } - } - + @NonNull Collection uidRequestedPermissions, + @NonNull UidPermissionState uidState) { boolean runtimePermissionChanged = false; // Prune permissions @@ -3850,7 +3836,7 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt final int permissionStatesSize = permissionStates.size(); for (int i = permissionStatesSize - 1; i >= 0; i--) { PermissionState permissionState = permissionStates.get(i); - if (!usedPermissions.contains(permissionState.getName())) { + if (!uidRequestedPermissions.contains(permissionState.getName())) { Permission bp = mRegistry.getPermission(permissionState.getName()); if (bp != null) { if (uidState.removePermissionState(bp.getName()) && bp.isRuntime()) {