diff options
Diffstat (limited to 'services/core/java')
5 files changed, 69 insertions, 12 deletions
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 5d3b0f1..4dfb161 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -6967,6 +6967,10 @@ public class PackageManagerService extends IPackageManager.Stub { PermissionsState permissionsState = ps.getPermissionsState(); PermissionsState origPermissions = permissionsState; + final int[] currentUserIds = UserManagerService.getInstance().getUserIds(); + + int[] upgradeUserIds = PermissionsState.USERS_NONE; + boolean changedPermission = false; if (replace) { @@ -7022,16 +7026,32 @@ public class PackageManagerService extends IPackageManager.Stub { // For legacy apps dangerous permissions are install time ones. grant = GRANT_INSTALL; } else if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { - // For modern system apps dangerous permissions are runtime ones. - grant = GRANT_UPGRADE; - } else { + final int[] updatedUserIds = ps.getPermissionsUpdatedForUserIds(); if (origPermissions.hasInstallPermission(bp.name)) { - // For legacy apps that became modern, install becomes runtime. + // If a system app had an install permission, then the app was + // upgraded and we grant the permissions as runtime to all users. + grant = GRANT_UPGRADE; + upgradeUserIds = currentUserIds; + } else if (!Arrays.equals(updatedUserIds, currentUserIds)) { + // If users changed since the last permissions update for a + // system app, we grant the permission as runtime to the new users. grant = GRANT_UPGRADE; - } else if (replace) { - // For upgraded modern apps keep runtime permissions unchanged. + upgradeUserIds = currentUserIds; + for (int userId : updatedUserIds) { + upgradeUserIds = ArrayUtils.removeInt(upgradeUserIds, userId); + } + } else { + // Otherwise, we grant the permission as runtime if the app + // already had it, i.e. we preserve runtime permissions. grant = GRANT_RUNTIME; } + } else if (origPermissions.hasInstallPermission(bp.name)) { + // For legacy apps that became modern, install becomes runtime. + grant = GRANT_UPGRADE; + upgradeUserIds = currentUserIds; + } else if (replace) { + // For upgraded modern apps keep runtime permissions unchanged. + grant = GRANT_RUNTIME; } } break; @@ -7086,7 +7106,7 @@ public class PackageManagerService extends IPackageManager.Stub { case GRANT_UPGRADE: { // Grant runtime permissions for a previously held install permission. permissionsState.revokeInstallPermission(bp); - for (int userId : UserManagerService.getInstance().getUserIds()) { + for (int userId : upgradeUserIds) { if (permissionsState.grantRuntimePermission(bp, userId) != PermissionsState.PERMISSION_OPERATION_FAILURE) { changedPermission = true; @@ -7133,6 +7153,8 @@ public class PackageManagerService extends IPackageManager.Stub { // changed. ps.permissionsFixed = true; } + + ps.setPermissionsUpdatedForUserIds(currentUserIds); } private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) { diff --git a/services/core/java/com/android/server/pm/PackageSettingBase.java b/services/core/java/com/android/server/pm/PackageSettingBase.java index 9e8b3df..c40784b 100644 --- a/services/core/java/com/android/server/pm/PackageSettingBase.java +++ b/services/core/java/com/android/server/pm/PackageSettingBase.java @@ -198,6 +198,7 @@ abstract class PackageSettingBase extends SettingBase { * Make a shallow copy of this package settings. */ public void copyFrom(PackageSettingBase base) { + setPermissionsUpdatedForUserIds(base.getPermissionsUpdatedForUserIds()); getPermissionsState().copyFrom(base.getPermissionsState()); primaryCpuAbiString = base.primaryCpuAbiString; secondaryCpuAbiString = base.secondaryCpuAbiString; diff --git a/services/core/java/com/android/server/pm/PermissionsState.java b/services/core/java/com/android/server/pm/PermissionsState.java index 3e0e342..705abf8 100644 --- a/services/core/java/com/android/server/pm/PermissionsState.java +++ b/services/core/java/com/android/server/pm/PermissionsState.java @@ -55,9 +55,9 @@ public final class PermissionsState { /** The permission operation failed. */ public static final int PERMISSION_OPERATION_FAILURE = 3; - private static final int[] USERS_ALL = {UserHandle.USER_ALL}; + public static final int[] USERS_ALL = {UserHandle.USER_ALL}; - private static final int[] USERS_NONE = {}; + public static final int[] USERS_NONE = {}; private static final int[] NO_GIDS = {}; @@ -149,6 +149,9 @@ public final class PermissionsState { * #PERMISSION_OPERATION_FAILURE}. */ public int grantRuntimePermission(BasePermission permission, int userId) { + if (userId == UserHandle.USER_ALL) { + return PERMISSION_OPERATION_FAILURE; + } return grantPermission(permission, userId); } @@ -162,6 +165,9 @@ public final class PermissionsState { * #PERMISSION_OPERATION_FAILURE}. */ public int revokeRuntimePermission(BasePermission permission, int userId) { + if (userId == UserHandle.USER_ALL) { + return PERMISSION_OPERATION_FAILURE; + } return revokePermission(permission, userId); } diff --git a/services/core/java/com/android/server/pm/SettingBase.java b/services/core/java/com/android/server/pm/SettingBase.java index d350c09..3a7b6ee 100644 --- a/services/core/java/com/android/server/pm/SettingBase.java +++ b/services/core/java/com/android/server/pm/SettingBase.java @@ -17,13 +17,15 @@ package com.android.server.pm; import android.content.pm.ApplicationInfo; -import android.util.ArraySet; + +import java.util.Arrays; abstract class SettingBase { int pkgFlags; int pkgPrivateFlags; private final PermissionsState mPermissionsState; + private int[] mPermissionsUpdatedForUserIds = PermissionsState.USERS_NONE; SettingBase(int pkgFlags, int pkgPrivateFlags) { setFlags(pkgFlags); @@ -35,12 +37,29 @@ abstract class SettingBase { pkgFlags = base.pkgFlags; pkgPrivateFlags = base.pkgPrivateFlags; mPermissionsState = new PermissionsState(base.mPermissionsState); + setPermissionsUpdatedForUserIds(base.mPermissionsUpdatedForUserIds); } public PermissionsState getPermissionsState() { return mPermissionsState; } + public int[] getPermissionsUpdatedForUserIds() { + return mPermissionsUpdatedForUserIds; + } + + public void setPermissionsUpdatedForUserIds(int[] userIds) { + if (Arrays.equals(mPermissionsUpdatedForUserIds, userIds)) { + return; + } + + if (userIds == PermissionsState.USERS_NONE || userIds == PermissionsState.USERS_ALL) { + mPermissionsUpdatedForUserIds = userIds; + } else { + mPermissionsUpdatedForUserIds = Arrays.copyOf(userIds, userIds.length); + } + } + void setFlags(int pkgFlags) { this.pkgFlags = pkgFlags & (ApplicationInfo.FLAG_SYSTEM diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index 82aa74a..95ee990 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -2253,6 +2253,17 @@ final class Settings { mReadMessages.append("Read completed successfully: " + mPackages.size() + " packages, " + mSharedUsers.size() + " shared uids\n"); + // The persisted state we just read was generated after a permissions + // update for all users, update each package and shared user setting + // with the device users ids to start from were we left off. + final int[] userIds = UserManagerService.getInstance().getUserIds(); + for (PackageSetting ps : mPackages.values()) { + ps.setPermissionsUpdatedForUserIds(userIds); + } + for (SharedUserSetting sus : mSharedUsers.values()) { + sus.setPermissionsUpdatedForUserIds(userIds); + } + return true; } @@ -3010,8 +3021,6 @@ final class Settings { XmlUtils.skipCurrentTag(parser); } } - - } else { XmlUtils.skipCurrentTag(parser); } |