From 6b086884c232f68ce425798a5056ad1b0251a9d4 Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Tue, 24 Nov 2020 22:47:10 +0000 Subject: [PATCH] Revert "Revert "Replace permissions API with onPackageInstalled()."" This reverts commit 84ee067aca0ef89d310b05bff0b8e4d53277b3cd. Reason for revert: Fixed the issue where allowlisted restricted permissions were removed upon package update due to the original CL. This was caused by the fact that previously the allowlisted permissions passed in by installer are used to replace the set of existing allowlisted permissions, and this is inconsistent with the granted permissions passed in by installer where we simply grant the specified permissions instead of revoking permissions that weren't in the list passed in. So I believe making the allowlisted permissions an addition instead of replacement makes more sense and also solves the issue. The other change is that onPackageInstalled() is now called on a per-user basis, because permission allowlist addition has to be done per-user unlike the previous replacement. This also gives us a cleaner API. Bug: 158736025 Test: RestrictedStoragePermissionTest Change-Id: I7a47afebf88406dc16f64942db6dcaff4e18ab75 --- .../server/pm/PackageManagerService.java | 57 +-- .../permission/PermissionManagerService.java | 423 +++++++++--------- .../PermissionManagerServiceInternal.java | 52 +-- 3 files changed, 252 insertions(+), 280 deletions(-) diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 55f9feec10d3f..479a26b0f10d7 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -21,7 +21,6 @@ import static android.Manifest.permission.MANAGE_DEVICE_ADMINS; import static android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS; import static android.Manifest.permission.REQUEST_DELETE_PACKAGES; import static android.Manifest.permission.SET_HARMFUL_APP_WARNINGS; -import static android.app.AppOpsManager.MODE_ALLOWED; import static android.app.AppOpsManager.MODE_DEFAULT; import static android.app.AppOpsManager.MODE_IGNORED; import static android.content.Intent.ACTION_MAIN; @@ -44,7 +43,6 @@ import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKED_COMPAT; import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED; import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET; -import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER; import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS; import static android.content.pm.PackageManager.INSTALL_FAILED_BAD_PERMISSION_GROUP; import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE; @@ -2172,7 +2170,7 @@ public class PackageManagerService extends IPackageManager.Stub private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions, boolean killApp, boolean virtualPreload, - String[] grantedPermissions, List whitelistedRestrictedPermissions, + String[] grantedPermissions, List allowlistedRestrictedPermissions, int autoRevokePermissionsMode, boolean launchedForRestore, String installerPackage, IPackageInstallObserver2 installObserver, int dataLoaderType) { @@ -2205,31 +2203,22 @@ public class PackageManagerService extends IPackageManager.Stub res.removedInfo.sendPackageRemovedBroadcasts(killApp, false /*removedBySystem*/); } - // Allowlist any restricted permissions first as some may be runtime - // that the installer requested to be granted at install time. - if (whitelistedRestrictedPermissions != null - && !whitelistedRestrictedPermissions.isEmpty()) { - mPermissionManager.setAllowlistedRestrictedPermissions(res.pkg, - whitelistedRestrictedPermissions, FLAG_PERMISSION_WHITELIST_INSTALLER, - res.newUsers); - } - - if (autoRevokePermissionsMode == MODE_ALLOWED - || autoRevokePermissionsMode == MODE_IGNORED) { - mPermissionManager.setAutoRevokeExempted(res.pkg, - autoRevokePermissionsMode == MODE_IGNORED, res.newUsers); - } - - // Now that we successfully installed the package, grant runtime - // permissions if requested before broadcasting the install. Also - // for legacy apps in permission review mode we clear the permission - // review flag which is used to emulate runtime permissions for - // legacy apps. + final List grantedPermissionsList; if (grantPermissions) { - final int callingUid = Binder.getCallingUid(); - mPermissionManager.grantRequestedRuntimePermissions(res.pkg, - grantedPermissions != null ? Arrays.asList(grantedPermissions) : null, - res.newUsers); + if (grantedPermissions != null) { + grantedPermissionsList = Arrays.asList(grantedPermissions); + } else { + grantedPermissionsList = res.pkg.getRequestedPermissions(); + } + } else { + grantedPermissionsList = Collections.emptyList(); + } + if (allowlistedRestrictedPermissions == null) { + allowlistedRestrictedPermissions = Collections.emptyList(); + } + for (final int userId : res.newUsers) { + mPermissionManager.onPackageInstalled(res.pkg, grantedPermissionsList, + allowlistedRestrictedPermissions, autoRevokePermissionsMode, userId); } final String installerPackageName = @@ -13609,11 +13598,12 @@ public class PackageManagerService extends IPackageManager.Stub int installExistingPackageAsUser(@Nullable String packageName, @UserIdInt int userId, @PackageManager.InstallFlags int installFlags, @PackageManager.InstallReason int installReason, - @Nullable List whiteListedPermissions, @Nullable IntentSender intentSender) { + @Nullable List allowlistedRestrictedPermissions, + @Nullable IntentSender intentSender) { if (DEBUG_INSTALL) { Log.v(TAG, "installExistingPackageAsUser package=" + packageName + " userId=" + userId + " installFlags=" + installFlags + " installReason=" + installReason - + " whiteListedPermissions=" + whiteListedPermissions); + + " allowlistedRestrictedPermissions=" + allowlistedRestrictedPermissions); } final int callingUid = Binder.getCallingUid(); @@ -13679,11 +13669,12 @@ public class PackageManagerService extends IPackageManager.Stub if (pkgSetting.pkg != null) { if ((installFlags & PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS) != 0) { - whiteListedPermissions = pkgSetting.pkg.getRequestedPermissions(); + allowlistedRestrictedPermissions = pkgSetting.pkg.getRequestedPermissions(); + } else if (allowlistedRestrictedPermissions == null) { + allowlistedRestrictedPermissions = Collections.emptyList(); } - mPermissionManager.setAllowlistedRestrictedPermissions(pkgSetting.pkg, - whiteListedPermissions, FLAG_PERMISSION_WHITELIST_INSTALLER, - new int[] { userId }); + mPermissionManager.onPackageInstalled(pkgSetting.pkg, Collections.emptyList(), + allowlistedRestrictedPermissions, MODE_DEFAULT, userId); } if (pkgSetting.pkg != null) { 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 fb1ed2f6b58bd..d2c9bf0733d3d 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -1243,50 +1243,56 @@ public class PermissionManagerService extends IPermissionManager.Stub { final long identity = Binder.clearCallingIdentity(); try { - synchronized (mLock) { - final UidPermissionState uidState = getUidStateLocked(pkg, userId); - if (uidState == null) { - Slog.e(TAG, "Missing permissions state for " + packageName + " and user " - + userId); - return null; - } - - int queryFlags = 0; - if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM) != 0) { - queryFlags |= FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT; - } - if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE) != 0) { - queryFlags |= FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT; - } - if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER) != 0) { - queryFlags |= FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT; - } - if ((flags & PackageManager.FLAG_PERMISSION_ALLOWLIST_ROLE) != 0) { - queryFlags |= FLAG_PERMISSION_RESTRICTION_ROLE_EXEMPT; - } - - ArrayList whitelistedPermissions = null; - - final int permissionCount = ArrayUtils.size(pkg.getRequestedPermissions()); - for (int i = 0; i < permissionCount; i++) { - final String permissionName = pkg.getRequestedPermissions().get(i); - final int currentFlags = - uidState.getPermissionFlags(permissionName); - if ((currentFlags & queryFlags) != 0) { - if (whitelistedPermissions == null) { - whitelistedPermissions = new ArrayList<>(); - } - whitelistedPermissions.add(permissionName); - } - } - - return whitelistedPermissions; - } + return getAllowlistedRestrictedPermissionsInternal(pkg, flags, userId); } finally { Binder.restoreCallingIdentity(identity); } } + @Nullable + private List getAllowlistedRestrictedPermissionsInternal(@NonNull AndroidPackage pkg, + @PermissionWhitelistFlags int flags, @UserIdInt int userId) { + synchronized (mLock) { + final UidPermissionState uidState = getUidStateLocked(pkg, userId); + if (uidState == null) { + Slog.e(TAG, "Missing permissions state for " + pkg.getPackageName() + " and user " + + userId); + return null; + } + + int queryFlags = 0; + if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM) != 0) { + queryFlags |= FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT; + } + if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE) != 0) { + queryFlags |= FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT; + } + if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER) != 0) { + queryFlags |= FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT; + } + if ((flags & PackageManager.FLAG_PERMISSION_ALLOWLIST_ROLE) != 0) { + queryFlags |= FLAG_PERMISSION_RESTRICTION_ROLE_EXEMPT; + } + + ArrayList allowlistedPermissions = null; + + final int permissionCount = ArrayUtils.size(pkg.getRequestedPermissions()); + for (int i = 0; i < permissionCount; i++) { + final String permissionName = pkg.getRequestedPermissions().get(i); + final int currentFlags = + uidState.getPermissionFlags(permissionName); + if ((currentFlags & queryFlags) != 0) { + if (allowlistedPermissions == null) { + allowlistedPermissions = new ArrayList<>(); + } + allowlistedPermissions.add(permissionName); + } + } + + return allowlistedPermissions; + } + } + @Override public boolean addWhitelistedRestrictedPermission(@NonNull String packageName, @NonNull String permName, @PermissionWhitelistFlags int flags, @@ -1429,8 +1435,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { final long identity = Binder.clearCallingIdentity(); try { - setAllowlistedRestrictedPermissionsInternal(pkg, permissions, flags, - new int[] { userId }); + setAllowlistedRestrictedPermissionsInternal(pkg, permissions, flags, userId); } finally { Binder.restoreCallingIdentity(identity); } @@ -1453,13 +1458,6 @@ public class PermissionManagerService extends IPermissionManager.Stub { return setAutoRevokeExemptedInternal(pkg, whitelisted, userId); } - private void setAutoRevokeExemptedInternal(@NonNull AndroidPackage pkg, boolean exempted, - @NonNull int[] userIds) { - for (final int userId : userIds) { - setAutoRevokeExemptedInternal(pkg, exempted, userId); - } - } - private boolean setAutoRevokeExemptedInternal(@NonNull AndroidPackage pkg, boolean exempted, @UserIdInt int userId) { final int packageUid = UserHandle.getUid(userId, pkg.getUid()); @@ -3775,13 +3773,6 @@ public class PermissionManagerService extends IPermissionManager.Stub { } private void grantRequestedRuntimePermissionsInternal(@NonNull AndroidPackage pkg, - @Nullable List permissions, @NonNull int[] userIds) { - for (int userId : userIds) { - grantRequestedRuntimePermissionsForUser(pkg, permissions, userId); - } - } - - private void grantRequestedRuntimePermissionsForUser(@NonNull AndroidPackage pkg, @Nullable List permissions, int userId) { final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED | PackageManager.FLAG_PERMISSION_POLICY_FIXED; @@ -3828,25 +3819,136 @@ public class PermissionManagerService extends IPermissionManager.Stub { private void setAllowlistedRestrictedPermissionsInternal(@NonNull AndroidPackage pkg, @Nullable List permissions, @PermissionWhitelistFlags int allowlistFlags, - @UserIdInt int[] userIds) { - SparseArray> oldGrantedRestrictedPermissions = new SparseArray<>(); + @UserIdInt int userId) { + ArraySet oldGrantedRestrictedPermissions = null; boolean updatePermissions = false; final int permissionCount = pkg.getRequestedPermissions().size(); final int myUid = Process.myUid(); - for (int i = 0; i < userIds.length; i++) { - int userId = userIds[i]; + for (int j = 0; j < permissionCount; j++) { + final String permissionName = pkg.getRequestedPermissions().get(j); - for (int j = 0; j < permissionCount; j++) { - final String permissionName = pkg.getRequestedPermissions().get(j); + final boolean isGranted; + synchronized (mLock) { + final Permission bp = mRegistry.getPermission(permissionName); + if (bp == null || !bp.isHardOrSoftRestricted()) { + continue; + } + final UidPermissionState uidState = getUidStateLocked(pkg, userId); + if (uidState == null) { + Slog.e(TAG, "Missing permissions state for " + pkg.getPackageName() + + " and user " + userId); + continue; + } + isGranted = uidState.isPermissionGranted(permissionName); + } + + if (isGranted) { + if (oldGrantedRestrictedPermissions == null) { + oldGrantedRestrictedPermissions = new ArraySet<>(); + } + oldGrantedRestrictedPermissions.add(permissionName); + } + + final int oldFlags = getPermissionFlagsInternal(permissionName, + pkg.getPackageName(), myUid, userId); + + int newFlags = oldFlags; + int mask = 0; + int whitelistFlagsCopy = allowlistFlags; + while (whitelistFlagsCopy != 0) { + final int flag = 1 << Integer.numberOfTrailingZeros(whitelistFlagsCopy); + whitelistFlagsCopy &= ~flag; + switch (flag) { + case FLAG_PERMISSION_WHITELIST_SYSTEM: { + mask |= FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT; + if (permissions != null && permissions.contains(permissionName)) { + newFlags |= FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT; + } else { + newFlags &= ~FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT; + } + } + break; + case FLAG_PERMISSION_WHITELIST_UPGRADE: { + mask |= FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT; + if (permissions != null && permissions.contains(permissionName)) { + newFlags |= FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT; + } else { + newFlags &= ~FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT; + } + } + break; + case FLAG_PERMISSION_WHITELIST_INSTALLER: { + mask |= FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT; + if (permissions != null && permissions.contains(permissionName)) { + newFlags |= FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT; + } else { + newFlags &= ~FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT; + } + } + break; + case FLAG_PERMISSION_ALLOWLIST_ROLE: { + mask |= FLAG_PERMISSION_RESTRICTION_ROLE_EXEMPT; + if (permissions != null && permissions.contains(permissionName)) { + newFlags |= FLAG_PERMISSION_RESTRICTION_ROLE_EXEMPT; + } else { + newFlags &= ~FLAG_PERMISSION_RESTRICTION_ROLE_EXEMPT; + } + } + break; + } + } + + if (oldFlags == newFlags) { + continue; + } + + updatePermissions = true; + + final boolean wasWhitelisted = (oldFlags + & (PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT)) != 0; + final boolean isWhitelisted = (newFlags + & (PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT)) != 0; + + // If the permission is policy fixed as granted but it is no longer + // on any of the whitelists we need to clear the policy fixed flag + // as whitelisting trumps policy i.e. policy cannot grant a non + // grantable permission. + if ((oldFlags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) { + if (!isWhitelisted && isGranted) { + mask |= PackageManager.FLAG_PERMISSION_POLICY_FIXED; + newFlags &= ~PackageManager.FLAG_PERMISSION_POLICY_FIXED; + } + } + + // If we are whitelisting an app that does not support runtime permissions + // we need to make sure it goes through the permission review UI at launch. + if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M + && !wasWhitelisted && isWhitelisted) { + mask |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; + newFlags |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; + } + + updatePermissionFlagsInternal(permissionName, pkg.getPackageName(), mask, newFlags, + myUid, userId, false, null /*callback*/); + } + + if (updatePermissions) { + // Update permission of this app to take into account the new whitelist state. + restorePermissionState(pkg, false, pkg.getPackageName(), mDefaultPermissionCallback); + + // If this resulted in losing a permission we need to kill the app. + if (oldGrantedRestrictedPermissions == null) { + return; + } + + final int oldGrantedCount = oldGrantedRestrictedPermissions.size(); + for (int j = 0; j < oldGrantedCount; j++) { + final String permissionName = oldGrantedRestrictedPermissions.valueAt(j); + // Sometimes we create a new permission state instance during update. final boolean isGranted; synchronized (mLock) { - final Permission bp = mRegistry.getPermission(permissionName); - if (bp == null || !bp.isHardOrSoftRestricted()) { - continue; - } - final UidPermissionState uidState = getUidStateLocked(pkg, userId); if (uidState == null) { Slog.e(TAG, "Missing permissions state for " + pkg.getPackageName() @@ -3855,128 +3957,9 @@ public class PermissionManagerService extends IPermissionManager.Stub { } isGranted = uidState.isPermissionGranted(permissionName); } - - if (isGranted) { - if (oldGrantedRestrictedPermissions.get(userId) == null) { - oldGrantedRestrictedPermissions.put(userId, new ArraySet<>()); - } - oldGrantedRestrictedPermissions.get(userId).add(permissionName); - } - - final int oldFlags = getPermissionFlagsInternal(permissionName, - pkg.getPackageName(), myUid, userId); - - int newFlags = oldFlags; - int mask = 0; - int whitelistFlagsCopy = allowlistFlags; - while (whitelistFlagsCopy != 0) { - final int flag = 1 << Integer.numberOfTrailingZeros(whitelistFlagsCopy); - whitelistFlagsCopy &= ~flag; - switch (flag) { - case FLAG_PERMISSION_WHITELIST_SYSTEM: { - mask |= FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT; - if (permissions != null && permissions.contains(permissionName)) { - newFlags |= FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT; - } else { - newFlags &= ~FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT; - } - } - break; - case FLAG_PERMISSION_WHITELIST_UPGRADE: { - mask |= FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT; - if (permissions != null && permissions.contains(permissionName)) { - newFlags |= FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT; - } else { - newFlags &= ~FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT; - } - } - break; - case FLAG_PERMISSION_WHITELIST_INSTALLER: { - mask |= FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT; - if (permissions != null && permissions.contains(permissionName)) { - newFlags |= FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT; - } else { - newFlags &= ~FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT; - } - } - break; - case FLAG_PERMISSION_ALLOWLIST_ROLE: { - mask |= FLAG_PERMISSION_RESTRICTION_ROLE_EXEMPT; - if (permissions != null && permissions.contains(permissionName)) { - newFlags |= FLAG_PERMISSION_RESTRICTION_ROLE_EXEMPT; - } else { - newFlags &= ~FLAG_PERMISSION_RESTRICTION_ROLE_EXEMPT; - } - } - break; - } - } - - if (oldFlags == newFlags) { - continue; - } - - updatePermissions = true; - - final boolean wasWhitelisted = (oldFlags - & (PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT)) != 0; - final boolean isWhitelisted = (newFlags - & (PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT)) != 0; - - // If the permission is policy fixed as granted but it is no longer - // on any of the whitelists we need to clear the policy fixed flag - // as whitelisting trumps policy i.e. policy cannot grant a non - // grantable permission. - if ((oldFlags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) { - if (!isWhitelisted && isGranted) { - mask |= PackageManager.FLAG_PERMISSION_POLICY_FIXED; - newFlags &= ~PackageManager.FLAG_PERMISSION_POLICY_FIXED; - } - } - - // If we are whitelisting an app that does not support runtime permissions - // we need to make sure it goes through the permission review UI at launch. - if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M - && !wasWhitelisted && isWhitelisted) { - mask |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; - newFlags |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; - } - - updatePermissionFlagsInternal(permissionName, pkg.getPackageName(), mask, newFlags, - myUid, userId, false, null /*callback*/); - } - } - - if (updatePermissions) { - // Update permission of this app to take into account the new whitelist state. - restorePermissionState(pkg, false, pkg.getPackageName(), mDefaultPermissionCallback); - - // If this resulted in losing a permission we need to kill the app. - for (int i = 0; i < userIds.length; i++) { - int userId = userIds[i]; - ArraySet oldPermsForUser = oldGrantedRestrictedPermissions.get(userId); - if (oldPermsForUser == null) { - continue; - } - - final int oldGrantedCount = oldPermsForUser.size(); - for (int j = 0; j < oldGrantedCount; j++) { - final String permissionName = oldPermsForUser.valueAt(j); - // Sometimes we create a new permission state instance during update. - final boolean isGranted; - synchronized (mLock) { - final UidPermissionState uidState = getUidStateLocked(pkg, userId); - if (uidState == null) { - Slog.e(TAG, "Missing permissions state for " + pkg.getPackageName() - + " and user " + userId); - continue; - } - isGranted = uidState.isPermissionGranted(permissionName); - } - if (!isGranted) { - mDefaultPermissionCallback.onPermissionRevoked(pkg.getUid(), userId, null); - break; - } + if (!isGranted) { + mDefaultPermissionCallback.onPermissionRevoked(pkg.getUid(), userId, null); + break; } } } @@ -4914,6 +4897,34 @@ public class PermissionManagerService extends IPermissionManager.Stub { return true; } + private void onPackageInstalledInternal(@NonNull AndroidPackage pkg, + @NonNull List grantedPermissions, + @NonNull List allowlistedRestrictedPermissions, int autoRevokePermissionsMode, + @UserIdInt int userId) { + addAllowlistedRestrictedPermissionsInternal(pkg, allowlistedRestrictedPermissions, + FLAG_PERMISSION_WHITELIST_INSTALLER, userId); + if (autoRevokePermissionsMode == AppOpsManager.MODE_ALLOWED + || autoRevokePermissionsMode == AppOpsManager.MODE_IGNORED) { + setAutoRevokeExemptedInternal(pkg, + autoRevokePermissionsMode == AppOpsManager.MODE_IGNORED, userId); + } + grantRequestedRuntimePermissionsInternal(pkg, grantedPermissions, userId); + } + + private void addAllowlistedRestrictedPermissionsInternal(@NonNull AndroidPackage pkg, + @NonNull List allowlistedRestrictedPermissions, + @PermissionWhitelistFlags int flags, @UserIdInt int userId) { + List permissions = getAllowlistedRestrictedPermissionsInternal(pkg, flags, userId); + if (permissions != null) { + ArraySet permissionSet = new ArraySet<>(permissions); + permissionSet.addAll(allowlistedRestrictedPermissions); + permissions = new ArrayList<>(permissionSet); + } else { + permissions = allowlistedRestrictedPermissions; + } + setAllowlistedRestrictedPermissionsInternal(pkg, permissions, flags, userId); + } + private void onPackageRemovedInternal(@NonNull AndroidPackage pkg) { removeAllPermissionsInternal(pkg); } @@ -5080,28 +5091,6 @@ public class PermissionManagerService extends IPermissionManager.Stub { return PermissionManagerService.this.getAppOpPermissionPackagesInternal(permissionName); } @Override - public void grantRequestedRuntimePermissions(@NonNull AndroidPackage pkg, - @Nullable List permissions, @NonNull int[] userIds) { - Objects.requireNonNull(pkg, "pkg"); - Objects.requireNonNull(userIds, "userIds"); - grantRequestedRuntimePermissionsInternal(pkg, permissions, userIds); - } - @Override - public void setAllowlistedRestrictedPermissions(@NonNull AndroidPackage pkg, - @Nullable List permissions, @PermissionWhitelistFlags int allowlistFlags, - @NonNull int[] userIds) { - Objects.requireNonNull(pkg, "pkg"); - Objects.requireNonNull(userIds, "userIds"); - setAllowlistedRestrictedPermissionsInternal(pkg, permissions, allowlistFlags, userIds); - } - @Override - public void setAutoRevokeExempted(@NonNull AndroidPackage pkg, boolean exempted, - @NonNull int[] userIds) { - Objects.requireNonNull(pkg, "pkg"); - Objects.requireNonNull(userIds, "userIds"); - setAutoRevokeExemptedInternal(pkg, exempted, userIds); - } - @Override public void updatePermissions(@NonNull String packageName, @Nullable AndroidPackage pkg) { PermissionManagerService.this .updatePermissions(packageName, pkg, mDefaultPermissionCallback); @@ -5371,6 +5360,20 @@ public class PermissionManagerService extends IPermissionManager.Stub { onPackageAddedInternal(pkg, isInstantApp, oldPkg); } + @Override + public void onPackageInstalled(@NonNull AndroidPackage pkg, + @NonNull List grantedPermissions, + @NonNull List allowlistedRestrictedPermissions, + int autoRevokePermissionsMode, @UserIdInt int userId) { + Objects.requireNonNull(pkg, "pkg"); + Objects.requireNonNull(grantedPermissions, "grantedPermissions"); + Objects.requireNonNull(allowlistedRestrictedPermissions, + "allowlistedRestrictedPermissions"); + Preconditions.checkArgumentNonNegative(userId, "userId"); + onPackageInstalledInternal(pkg, grantedPermissions, allowlistedRestrictedPermissions, + autoRevokePermissionsMode, userId); + } + @Override public void onPackageRemoved(@NonNull AndroidPackage pkg) { Objects.requireNonNull(pkg); 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 1becbedc29fbb..457fe36ca2b88 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java @@ -20,7 +20,6 @@ import android.annotation.AppIdInt; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; -import android.content.pm.PackageManager; import android.content.pm.PermissionInfo; import android.permission.PermissionManagerInternal; @@ -189,42 +188,6 @@ public abstract class PermissionManagerServiceInternal extends PermissionManager public abstract boolean isPermissionsReviewRequired(@NonNull String packageName, @UserIdInt int userId); - /** - * Grant the requested runtime permissions for a package, or an explicit subset of them. - * - * @param pkg the package - * @param permissions the names of the subset of permissions to be granted, or {@code null} for - * granting all the requested permissions - * @param userIds the user IDs - */ - //@SystemApi(client = SystemApi.Client.SYSTEM_SERVER) - public abstract void grantRequestedRuntimePermissions(@NonNull AndroidPackage pkg, - @Nullable List permissions, @NonNull int[] userIds); - - /** - * Set the allowlisted restricted permissions for a package, or an explicit subset of them. - * - * @param pkg the package - * @param permissions the names of the subset of permissions to be allowlisted, or {@code null} - * for allowlisting all the requested restricted permissions - * @param userIds the user IDs - */ - //@SystemApi(client = SystemApi.Client.SYSTEM_SERVER) - public abstract void setAllowlistedRestrictedPermissions( - @NonNull AndroidPackage pkg, @Nullable List permissions, - @PackageManager.PermissionWhitelistFlags int allowlistFlags, @NonNull int[] userIds); - - /** - * Set whether a package is exempted from auto revoke. - * - * @param pkg the package - * @param exempted whether the package is exempted from auto revoke - * @param userIds the user IDs - */ - //@SystemApi(client = SystemApi.Client.SYSTEM_SERVER) - public abstract void setAutoRevokeExempted(@NonNull AndroidPackage pkg, boolean exempted, - @NonNull int[] userIds); - /** * Update permissions when a package changed. * @@ -525,6 +488,21 @@ public abstract class PermissionManagerServiceInternal extends PermissionManager public abstract void onPackageAdded(@NonNull AndroidPackage pkg, boolean isInstantApp, @Nullable AndroidPackage oldPkg); + /** + * Callback when a package has been installed for certain users. + * + * @param pkg the installed package + * @param grantedPermissions the permissions to be granted + * @param allowlistedRestrictedPermissions the restricted permissions to be allowlisted + * @param autoRevokePermissionsMode the auto revoke permissions mode for this package + * @param userId the user ID this package is installed for + */ + //@SystemApi(client = SystemApi.Client.SYSTEM_SERVER) + public abstract void onPackageInstalled(@NonNull AndroidPackage pkg, + @NonNull List grantedPermissions, + @NonNull List allowlistedRestrictedPermissions, + int autoRevokePermissionsMode, @UserIdInt int userId); + /** * Callback when a package has been removed. *