diff options
3 files changed, 76 insertions, 41 deletions
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 85659edd1321..956c6e22f636 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -19501,13 +19501,20 @@ public class PackageManagerService extends IPackageManager.Stub if (outInfo != null) { outInfo.removedAppId = removedAppId; } - final SharedUserSetting sus = deletedPs.getSharedUser(); - List<AndroidPackage> sharedUserPkgs = sus != null ? sus.getPackages() : null; - if (sharedUserPkgs == null) { - sharedUserPkgs = Collections.emptyList(); + if (!mSettings.isDisabledSystemPackageLPr(packageName)) { + // If we don't have a disabled system package to reinstall, the package is + // really gone and its permission state should be removed. + final SharedUserSetting sus = deletedPs.getSharedUser(); + List<AndroidPackage> sharedUserPkgs = sus != null ? sus.getPackages() + : null; + if (sharedUserPkgs == null) { + sharedUserPkgs = Collections.emptyList(); + } + for (final int userId : allUserHandles) { + mPermissionManager.onPackageUninstalled(packageName, deletedPs.appId, + deletedPs.pkg, sharedUserPkgs, userId); + } } - mPermissionManager.onPackageStateRemoved(packageName, deletedPs.appId, - deletedPs.pkg, sharedUserPkgs); clearPackagePreferredActivitiesLPw( deletedPs.name, changedUsers, UserHandle.USER_ALL); } @@ -19696,10 +19703,6 @@ public class PackageManagerService extends IPackageManager.Stub synchronized (mLock) { PackageSetting ps = mSettings.mPackages.get(pkg.getPackageName()); - // The update permissions method below will take care of removing obsolete permissions - // and granting install permissions. - mPermissionManager.updatePermissions(pkg.getPackageName(), pkg); - final boolean applyUserRestrictions = origUserHandles != null; if (applyUserRestrictions) { boolean installedStateChanged = false; @@ -19718,8 +19721,6 @@ public class PackageManagerService extends IPackageManager.Stub if (installed) { ps.setUninstallReason(UNINSTALL_REASON_UNKNOWN, userId); } - - mSettings.writeRuntimePermissionsForUserLPr(userId, false); } // Regardless of writeSettings we need to ensure that this restriction // state propagation is persisted @@ -19728,6 +19729,16 @@ public class PackageManagerService extends IPackageManager.Stub mSettings.writeKernelMappingLPr(ps); } } + + // The update permissions method below will take care of removing obsolete permissions + // and granting install permissions. + mPermissionManager.updatePermissions(pkg.getPackageName(), pkg); + if (applyUserRestrictions) { + for (int userId : allUserHandles) { + mSettings.writeRuntimePermissionsForUserLPr(userId, false); + } + } + // can downgrade to reader here if (writeSettings) { writeSettingsLPrTEMP(); @@ -20026,6 +20037,11 @@ public class PackageManagerService extends IPackageManager.Stub destroyAppProfilesLIF(pkg); + final SharedUserSetting sus = ps.getSharedUser(); + List<AndroidPackage> sharedUserPkgs = sus != null ? sus.getPackages() : null; + if (sharedUserPkgs == null) { + sharedUserPkgs = Collections.emptyList(); + } final int[] userIds = (userId == UserHandle.USER_ALL) ? mUserManager.getUserIds() : new int[] {userId}; for (int nextUserId : userIds) { @@ -20040,7 +20056,8 @@ public class PackageManagerService extends IPackageManager.Stub clearDefaultBrowserIfNeededForUser(ps.name, nextUserId); removeKeystoreDataIfNeeded(mInjector.getUserManagerInternal(), nextUserId, ps.appId); clearPackagePreferredActivities(ps.name, nextUserId); - mPermissionManager.resetRuntimePermissions(pkg, nextUserId); + mPermissionManager.onPackageUninstalled(ps.name, ps.appId, pkg, sharedUserPkgs, + nextUserId); } if (outInfo != 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 52bb3d772387..e58d8c44ae8f 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -4712,13 +4712,13 @@ public class PermissionManagerService extends IPermissionManager.Stub { return userState.getUidState(appId); } - private void removeAppIdState(@AppIdInt int appId) { + private void removeUidState(@AppIdInt int appId, @UserIdInt int userId) { synchronized (mLock) { - final int[] userIds = mState.getUserIds(); - for (final int userId : userIds) { - final UserPermissionState userState = mState.getUserState(userId); - userState.removeUidState(appId); + final UserPermissionState userState = mState.getUserState(userId); + if (userState == null) { + return; } + userState.removeUidState(appId); } } @@ -4978,25 +4978,34 @@ public class PermissionManagerService extends IPermissionManager.Stub { removeAllPermissionsInternal(pkg); } - private void onPackageStateRemovedInternal(@NonNull String packageName, int appId, - @Nullable AndroidPackage pkg, @NonNull List<AndroidPackage> sharedUserPkgs) { - if (sharedUserPkgs.isEmpty() - && mPackageManagerInt.getDisabledSystemPackage(packageName) == null) { - removeAppIdState(appId); + private void onPackageUninstalledInternal(@NonNull String packageName, int appId, + @Nullable AndroidPackage pkg, @NonNull List<AndroidPackage> sharedUserPkgs, + @UserIdInt int userId) { + // TODO: Move these checks to check PackageState to be more reliable. + // System packages should always have an available APK. + if (pkg != null && pkg.isSystem() + // We may be fully removing invalid system packages during boot, and in that case we + // do want to remove their permission state. So make sure that the package is only + // being marked as uninstalled instead of fully removed. + && mPackageManagerInt.getPackage(packageName) != null) { + // If we are only marking a system package as uninstalled, we need to keep its + // pregranted permission state so that it still works once it gets reinstalled, thus + // only reset the user modifications to its permission state. + resetRuntimePermissionsInternal(pkg, userId); + return; } updatePermissions(packageName, null, mDefaultPermissionCallback); - if (!sharedUserPkgs.isEmpty()) { + if (sharedUserPkgs.isEmpty()) { + removeUidState(appId, userId); + } else { // Remove permissions associated with package. Since runtime // permissions are per user we have to kill the removed package // or packages running under the shared user of the removed // package if revoking the permissions requested only by the removed // package is successful and this causes a change in gids. - boolean shouldKill = false; - for (int userId : UserManagerService.getInstance().getUserIds()) { - final int userIdToKill = revokeSharedUserPermissionsForDeletedPackageInternal(pkg, - sharedUserPkgs, userId); - shouldKill |= userIdToKill != UserHandle.USER_NULL; - } + final int userIdToKill = revokeSharedUserPermissionsForDeletedPackageInternal(pkg, + sharedUserPkgs, userId); + final boolean shouldKill = userIdToKill != UserHandle.USER_NULL; // If gids changed, kill all affected packages. if (shouldKill) { mHandler.post(() -> { @@ -5430,11 +5439,13 @@ public class PermissionManagerService extends IPermissionManager.Stub { } @Override - public void onPackageStateRemoved(@NonNull String packageName, int appId, - @Nullable AndroidPackage pkg, @NonNull List<AndroidPackage> sharedUserPkgs) { - Objects.requireNonNull(packageName); - Objects.requireNonNull(sharedUserPkgs); - onPackageStateRemovedInternal(packageName, appId, pkg, sharedUserPkgs); + public void onPackageUninstalled(@NonNull String packageName, int appId, + @Nullable AndroidPackage pkg, @NonNull List<AndroidPackage> sharedUserPkgs, + @UserIdInt int userId) { + Objects.requireNonNull(packageName, "packageName"); + Objects.requireNonNull(sharedUserPkgs, "sharedUserPkgs"); + Preconditions.checkArgumentNonNegative(userId, "userId"); + onPackageUninstalledInternal(packageName, appId, pkg, sharedUserPkgs, userId); } @Override 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 457fe36ca2b8..8ed7fb43fb81 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java @@ -512,16 +512,23 @@ public abstract class PermissionManagerServiceInternal extends PermissionManager public abstract void onPackageRemoved(@NonNull AndroidPackage pkg); /** - * Callback when the state for a package has been removed. + * Callback when a package has been uninstalled. + * <p> + * The package may have been fully removed from the system, or only marked as uninstalled for + * this user but still instlaled for other users. + * + * TODO: Pass PackageState instead. * - * @param packageName the name of the removed package - * @param appId the app ID of the removed package - * @param pkg the removed package, or {@code null} if unavailable + * @param packageName the name of the uninstalled package + * @param appId the app ID of the uninstalled package + * @param pkg the uninstalled package, or {@code null} if unavailable * @param sharedUserPkgs the packages that are in the same shared user + * @param userId the user ID the package is uninstalled for */ //@SystemApi(client = SystemApi.Client.SYSTEM_SERVER) - public abstract void onPackageStateRemoved(@NonNull String packageName, int appId, - @Nullable AndroidPackage pkg, @NonNull List<AndroidPackage> sharedUserPkgs); + public abstract void onPackageUninstalled(@NonNull String packageName, int appId, + @Nullable AndroidPackage pkg, @NonNull List<AndroidPackage> sharedUserPkgs, + @UserIdInt int userId); /** * Check whether a permission can be propagated to instant app. |