Loading services/core/java/com/android/server/pm/RemovePackageHelper.java +94 −78 Original line number Diff line number Diff line Loading @@ -252,42 +252,105 @@ final class RemovePackageHelper { } } /** * This method clears the data and states stored in the system that are related to the * package being deleted and the target user, including the data directory. * If the DELETE_KEEP_DATA flag is set, everything is preserved except ART profiles. * Make sure this flag is set for partially installed apps. If not it's meaningless to * delete a partially installed application. */ public void clearPackageStateForUserLIF(PackageSetting ps, int userId, int flags) { final String packageName = ps.getPackageName(); // Step 1: always destroy app profiles. mAppDataHelper.destroyAppProfilesLIF(packageName); // Everything else is preserved if the DELETE_KEEP_DATA flag is on if ((flags & PackageManager.DELETE_KEEP_DATA) != 0) { return; } final AndroidPackage pkg; final SharedUserSetting sus; synchronized (mPm.mLock) { pkg = mPm.mPackages.get(ps.getPackageName()); pkg = mPm.mPackages.get(packageName); sus = mPm.mSettings.getSharedUserSettingLPr(ps); } mAppDataHelper.destroyAppProfilesLIF(ps.getPackageName()); final AndroidPackage resolvedPkg; if (pkg != null) { resolvedPkg = pkg; } else { // We don't have a parsed package when it lives on an ejected // adopted storage device, so fake something together resolvedPkg = PackageImpl.buildFakeForDeletion(packageName, ps.getVolumeUuid()); } // Step 2: destroy app data. mAppDataHelper.destroyAppDataLIF(resolvedPkg, userId, FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL); if (userId != UserHandle.USER_ALL) { ps.setCeDataInode(-1, userId); ps.setDeDataInode(-1, userId); } final List<AndroidPackage> sharedUserPkgs = sus != null ? sus.getPackages() : Collections.emptyList(); final PreferredActivityHelper preferredActivityHelper = new PreferredActivityHelper(mPm, mBroadcastHelper); final int[] userIds = (userId == UserHandle.USER_ALL) ? mUserManagerInternal.getUserIds() : new int[] {userId}; for (int nextUserId : userIds) { if (userId == UserHandle.USER_ALL) { if (DEBUG_REMOVE) { Slog.d(TAG, "Updating package:" + ps.getPackageName() + " install state for user:" + nextUserId); Slog.d(TAG, "Clear package:" + packageName + " state for all users"); } if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) { mAppDataHelper.destroyAppDataLIF(pkg, nextUserId, FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL); ps.setCeDataInode(-1, nextUserId); ps.setDeDataInode(-1, nextUserId); // Step 3: inform DomainVerificationManager. mPm.mDomainVerificationManager.clearPackage(packageName); synchronized (mPm.mLock) { // Step 3.1 (only for USER_ALL): notify KeySetManagerService. mPm.mSettings.getKeySetManagerService().removeAppKeySetDataLPw(packageName); // Step 3.2 (only for USER_ALL): update installer ownership. mPm.mInjector.getUpdateOwnershipHelper().removeUpdateOwnerDenyList(packageName); // Step 3.3 (only for USER_ALL): update AppsFilter. final Computer snapshot = mPm.snapshotComputer(); mPm.mAppsFilter.removePackage(snapshot, snapshot.getPackageStateInternal(packageName)); // Step 4: clear perferred activities. final SparseBooleanArray changedUsers = new SparseBooleanArray(); mPm.clearPackagePreferredActivitiesLPw( packageName, changedUsers, UserHandle.USER_ALL); mPm.mInjector.getBackgroundHandler().post(() -> { if (changedUsers.size() > 0) { preferredActivityHelper.updateDefaultHomeNotLocked(mPm.snapshotComputer(), changedUsers); mBroadcastHelper.sendPreferredActivityChangedBroadcast(UserHandle.USER_ALL); } mAppDataHelper.clearKeystoreData(nextUserId, ps.getAppId()); preferredActivityHelper.clearPackagePreferredActivities(ps.getPackageName(), nextUserId); mPm.mDomainVerificationManager.clearPackageForUser(ps.getPackageName(), nextUserId); }); // Step 5: inform PermissionManager. // This has to be done after the removal from mSettings in removePackageDataLIF. } mPermissionManager.onPackageUninstalled(ps.getPackageName(), ps.getAppId(), ps, pkg, } else { if (DEBUG_REMOVE) { Slog.d(TAG, "Clear package:" + packageName + " state for user:" + userId); } // Step 3: inform DomainVerificationManager. mPm.mDomainVerificationManager.clearPackageForUser(packageName, userId); // Step 4: clear perferred activities. preferredActivityHelper.clearPackagePreferredActivities(packageName, userId); // Step 5: inform PermissionManager. List<AndroidPackage> sharedUserPkgs = sus != null ? sus.getPackages() : Collections.emptyList(); mPermissionManager.onPackageUninstalled(packageName, ps.getAppId(), ps, pkg, sharedUserPkgs, userId); } // Step 6: detroy keystore data. mPm.mInjector.getBackgroundHandler().post(() -> { try { Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "clearKeystoreData:" + ps.getAppId() + " for user: " + userId); mAppDataHelper.clearKeystoreData(userId, ps.getAppId()); } finally { Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); } }); } // Called to clean up disabled system packages public void removePackageData(final PackageSetting deletedPs, @NonNull int[] allUserHandles) { synchronized (mPm.mInstallLock) { Loading @@ -297,10 +360,7 @@ final class RemovePackageHelper { } /* * This method deletes the package from internal data structures. If the DELETE_KEEP_DATA * flag is not set, the data directory is removed as well. * make sure this flag is set for partially installed apps. If not it's meaningless to * delete a partially installed application. * This method deletes the package from internal data structures such as mPackages / mSettings. */ @GuardedBy("mPm.mInstallLock") public void removePackageDataLIF(final PackageSetting deletedPs, @NonNull int[] allUserHandles, Loading @@ -310,7 +370,11 @@ final class RemovePackageHelper { // Retrieve object to delete permissions for shared user later on final AndroidPackage deletedPkg = deletedPs.getPkg(); removePackageLI(deletedPs.getPackageName(), (flags & PackageManager.DELETE_CHATTY) != 0); // Delete all the data and states related to this package. clearPackageStateForUserLIF(deletedPs, UserHandle.USER_ALL, flags); // Delete from mPackages removePackageLI(packageName, (flags & PackageManager.DELETE_CHATTY) != 0); if (!deletedPs.isSystem()) { // A non-system app's AndroidPackage object has been removed from the service. // Explicitly nullify the corresponding app's PackageSetting's pkg object to Loading @@ -320,39 +384,16 @@ final class RemovePackageHelper { } if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) { final AndroidPackage resolvedPkg; if (deletedPkg != null) { resolvedPkg = deletedPkg; } else { // We don't have a parsed package when it lives on an ejected // adopted storage device, so fake something together resolvedPkg = PackageImpl.buildFakeForDeletion(deletedPs.getPackageName(), deletedPs.getVolumeUuid()); } mAppDataHelper.destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL, FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL); mAppDataHelper.destroyAppProfilesLIF(resolvedPkg.getPackageName()); } int removedAppId = -1; // writer if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) { // Delete from mSettings final SparseBooleanArray changedUsers = new SparseBooleanArray(); synchronized (mPm.mLock) { mPm.mDomainVerificationManager.clearPackage(deletedPs.getPackageName()); mPm.mSettings.getKeySetManagerService().removeAppKeySetDataLPw(packageName); mPm.mInjector.getUpdateOwnershipHelper().removeUpdateOwnerDenyList(packageName); final Computer snapshot = mPm.snapshotComputer(); mPm.mAppsFilter.removePackage(snapshot, snapshot.getPackageStateInternal(packageName)); removedAppId = mPm.mSettings.removePackageLPw(packageName); mPm.mSettings.removePackageLPw(packageName); outInfo.mIsAppIdRemoved = true; if (!mPm.mSettings.isDisabledSystemPackageLPr(packageName)) { final SharedUserSetting sus = mPm.mSettings.getSharedUserSettingLPr(deletedPs); // If we don't have a disabled system package to reinstall, the package is // really gone and its permission state should be removed. SharedUserSetting sus = mPm.mSettings.getSharedUserSettingLPr(deletedPs); List<AndroidPackage> sharedUserPkgs = final List<AndroidPackage> sharedUserPkgs = sus != null ? sus.getPackages() : Collections.emptyList(); mPermissionManager.onPackageUninstalled(packageName, deletedPs.getAppId(), deletedPs, deletedPkg, sharedUserPkgs, UserHandle.USER_ALL); Loading @@ -361,20 +402,8 @@ final class RemovePackageHelper { mPm.mSettings.checkAndConvertSharedUserSettingsLPw(sus); } } mPm.clearPackagePreferredActivitiesLPw( deletedPs.getPackageName(), changedUsers, UserHandle.USER_ALL); mPm.mSettings.removeRenamedPackageLPw(deletedPs.getRealName()); } if (changedUsers.size() > 0) { mPm.mInjector.getBackgroundHandler().post(() -> { final PreferredActivityHelper preferredActivityHelper = new PreferredActivityHelper(mPm, mBroadcastHelper); preferredActivityHelper.updateDefaultHomeNotLocked(mPm.snapshotComputer(), changedUsers); mBroadcastHelper.sendPreferredActivityChangedBroadcast(UserHandle.USER_ALL); }); } } else if (!deletedPs.isSystem() && !outInfo.mIsUpdate && outInfo.mRemovedUsers != null && !deletedPs.isExternalStorage()) { // For non-system uninstalls with DELETE_KEEP_DATA, set the installed state to false Loading @@ -393,6 +422,7 @@ final class RemovePackageHelper { deletedPs.setInstalled(/* installed= */ false, userId); } } // make sure to preserve per-user installed state if this removal was just // a downgrade of a system app to the factory package boolean installedStateChanged = false; Loading Loading @@ -424,20 +454,6 @@ final class RemovePackageHelper { mPm.mSettings.writeKernelMappingLPr(deletedPs); } } if (removedAppId != -1) { // A user ID was deleted here. Go through all users and remove it from KeyStore. final int appIdToRemove = removedAppId; mPm.mInjector.getBackgroundHandler().post(() -> { try { Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "clearKeystoreData:" + appIdToRemove); mAppDataHelper.clearKeystoreData(UserHandle.USER_ALL, appIdToRemove); } finally { Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); } }); } } void cleanUpResources(File codeFile, String[] instructionSets) { Loading Loading
services/core/java/com/android/server/pm/RemovePackageHelper.java +94 −78 Original line number Diff line number Diff line Loading @@ -252,42 +252,105 @@ final class RemovePackageHelper { } } /** * This method clears the data and states stored in the system that are related to the * package being deleted and the target user, including the data directory. * If the DELETE_KEEP_DATA flag is set, everything is preserved except ART profiles. * Make sure this flag is set for partially installed apps. If not it's meaningless to * delete a partially installed application. */ public void clearPackageStateForUserLIF(PackageSetting ps, int userId, int flags) { final String packageName = ps.getPackageName(); // Step 1: always destroy app profiles. mAppDataHelper.destroyAppProfilesLIF(packageName); // Everything else is preserved if the DELETE_KEEP_DATA flag is on if ((flags & PackageManager.DELETE_KEEP_DATA) != 0) { return; } final AndroidPackage pkg; final SharedUserSetting sus; synchronized (mPm.mLock) { pkg = mPm.mPackages.get(ps.getPackageName()); pkg = mPm.mPackages.get(packageName); sus = mPm.mSettings.getSharedUserSettingLPr(ps); } mAppDataHelper.destroyAppProfilesLIF(ps.getPackageName()); final AndroidPackage resolvedPkg; if (pkg != null) { resolvedPkg = pkg; } else { // We don't have a parsed package when it lives on an ejected // adopted storage device, so fake something together resolvedPkg = PackageImpl.buildFakeForDeletion(packageName, ps.getVolumeUuid()); } // Step 2: destroy app data. mAppDataHelper.destroyAppDataLIF(resolvedPkg, userId, FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL); if (userId != UserHandle.USER_ALL) { ps.setCeDataInode(-1, userId); ps.setDeDataInode(-1, userId); } final List<AndroidPackage> sharedUserPkgs = sus != null ? sus.getPackages() : Collections.emptyList(); final PreferredActivityHelper preferredActivityHelper = new PreferredActivityHelper(mPm, mBroadcastHelper); final int[] userIds = (userId == UserHandle.USER_ALL) ? mUserManagerInternal.getUserIds() : new int[] {userId}; for (int nextUserId : userIds) { if (userId == UserHandle.USER_ALL) { if (DEBUG_REMOVE) { Slog.d(TAG, "Updating package:" + ps.getPackageName() + " install state for user:" + nextUserId); Slog.d(TAG, "Clear package:" + packageName + " state for all users"); } if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) { mAppDataHelper.destroyAppDataLIF(pkg, nextUserId, FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL); ps.setCeDataInode(-1, nextUserId); ps.setDeDataInode(-1, nextUserId); // Step 3: inform DomainVerificationManager. mPm.mDomainVerificationManager.clearPackage(packageName); synchronized (mPm.mLock) { // Step 3.1 (only for USER_ALL): notify KeySetManagerService. mPm.mSettings.getKeySetManagerService().removeAppKeySetDataLPw(packageName); // Step 3.2 (only for USER_ALL): update installer ownership. mPm.mInjector.getUpdateOwnershipHelper().removeUpdateOwnerDenyList(packageName); // Step 3.3 (only for USER_ALL): update AppsFilter. final Computer snapshot = mPm.snapshotComputer(); mPm.mAppsFilter.removePackage(snapshot, snapshot.getPackageStateInternal(packageName)); // Step 4: clear perferred activities. final SparseBooleanArray changedUsers = new SparseBooleanArray(); mPm.clearPackagePreferredActivitiesLPw( packageName, changedUsers, UserHandle.USER_ALL); mPm.mInjector.getBackgroundHandler().post(() -> { if (changedUsers.size() > 0) { preferredActivityHelper.updateDefaultHomeNotLocked(mPm.snapshotComputer(), changedUsers); mBroadcastHelper.sendPreferredActivityChangedBroadcast(UserHandle.USER_ALL); } mAppDataHelper.clearKeystoreData(nextUserId, ps.getAppId()); preferredActivityHelper.clearPackagePreferredActivities(ps.getPackageName(), nextUserId); mPm.mDomainVerificationManager.clearPackageForUser(ps.getPackageName(), nextUserId); }); // Step 5: inform PermissionManager. // This has to be done after the removal from mSettings in removePackageDataLIF. } mPermissionManager.onPackageUninstalled(ps.getPackageName(), ps.getAppId(), ps, pkg, } else { if (DEBUG_REMOVE) { Slog.d(TAG, "Clear package:" + packageName + " state for user:" + userId); } // Step 3: inform DomainVerificationManager. mPm.mDomainVerificationManager.clearPackageForUser(packageName, userId); // Step 4: clear perferred activities. preferredActivityHelper.clearPackagePreferredActivities(packageName, userId); // Step 5: inform PermissionManager. List<AndroidPackage> sharedUserPkgs = sus != null ? sus.getPackages() : Collections.emptyList(); mPermissionManager.onPackageUninstalled(packageName, ps.getAppId(), ps, pkg, sharedUserPkgs, userId); } // Step 6: detroy keystore data. mPm.mInjector.getBackgroundHandler().post(() -> { try { Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "clearKeystoreData:" + ps.getAppId() + " for user: " + userId); mAppDataHelper.clearKeystoreData(userId, ps.getAppId()); } finally { Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); } }); } // Called to clean up disabled system packages public void removePackageData(final PackageSetting deletedPs, @NonNull int[] allUserHandles) { synchronized (mPm.mInstallLock) { Loading @@ -297,10 +360,7 @@ final class RemovePackageHelper { } /* * This method deletes the package from internal data structures. If the DELETE_KEEP_DATA * flag is not set, the data directory is removed as well. * make sure this flag is set for partially installed apps. If not it's meaningless to * delete a partially installed application. * This method deletes the package from internal data structures such as mPackages / mSettings. */ @GuardedBy("mPm.mInstallLock") public void removePackageDataLIF(final PackageSetting deletedPs, @NonNull int[] allUserHandles, Loading @@ -310,7 +370,11 @@ final class RemovePackageHelper { // Retrieve object to delete permissions for shared user later on final AndroidPackage deletedPkg = deletedPs.getPkg(); removePackageLI(deletedPs.getPackageName(), (flags & PackageManager.DELETE_CHATTY) != 0); // Delete all the data and states related to this package. clearPackageStateForUserLIF(deletedPs, UserHandle.USER_ALL, flags); // Delete from mPackages removePackageLI(packageName, (flags & PackageManager.DELETE_CHATTY) != 0); if (!deletedPs.isSystem()) { // A non-system app's AndroidPackage object has been removed from the service. // Explicitly nullify the corresponding app's PackageSetting's pkg object to Loading @@ -320,39 +384,16 @@ final class RemovePackageHelper { } if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) { final AndroidPackage resolvedPkg; if (deletedPkg != null) { resolvedPkg = deletedPkg; } else { // We don't have a parsed package when it lives on an ejected // adopted storage device, so fake something together resolvedPkg = PackageImpl.buildFakeForDeletion(deletedPs.getPackageName(), deletedPs.getVolumeUuid()); } mAppDataHelper.destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL, FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL); mAppDataHelper.destroyAppProfilesLIF(resolvedPkg.getPackageName()); } int removedAppId = -1; // writer if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) { // Delete from mSettings final SparseBooleanArray changedUsers = new SparseBooleanArray(); synchronized (mPm.mLock) { mPm.mDomainVerificationManager.clearPackage(deletedPs.getPackageName()); mPm.mSettings.getKeySetManagerService().removeAppKeySetDataLPw(packageName); mPm.mInjector.getUpdateOwnershipHelper().removeUpdateOwnerDenyList(packageName); final Computer snapshot = mPm.snapshotComputer(); mPm.mAppsFilter.removePackage(snapshot, snapshot.getPackageStateInternal(packageName)); removedAppId = mPm.mSettings.removePackageLPw(packageName); mPm.mSettings.removePackageLPw(packageName); outInfo.mIsAppIdRemoved = true; if (!mPm.mSettings.isDisabledSystemPackageLPr(packageName)) { final SharedUserSetting sus = mPm.mSettings.getSharedUserSettingLPr(deletedPs); // If we don't have a disabled system package to reinstall, the package is // really gone and its permission state should be removed. SharedUserSetting sus = mPm.mSettings.getSharedUserSettingLPr(deletedPs); List<AndroidPackage> sharedUserPkgs = final List<AndroidPackage> sharedUserPkgs = sus != null ? sus.getPackages() : Collections.emptyList(); mPermissionManager.onPackageUninstalled(packageName, deletedPs.getAppId(), deletedPs, deletedPkg, sharedUserPkgs, UserHandle.USER_ALL); Loading @@ -361,20 +402,8 @@ final class RemovePackageHelper { mPm.mSettings.checkAndConvertSharedUserSettingsLPw(sus); } } mPm.clearPackagePreferredActivitiesLPw( deletedPs.getPackageName(), changedUsers, UserHandle.USER_ALL); mPm.mSettings.removeRenamedPackageLPw(deletedPs.getRealName()); } if (changedUsers.size() > 0) { mPm.mInjector.getBackgroundHandler().post(() -> { final PreferredActivityHelper preferredActivityHelper = new PreferredActivityHelper(mPm, mBroadcastHelper); preferredActivityHelper.updateDefaultHomeNotLocked(mPm.snapshotComputer(), changedUsers); mBroadcastHelper.sendPreferredActivityChangedBroadcast(UserHandle.USER_ALL); }); } } else if (!deletedPs.isSystem() && !outInfo.mIsUpdate && outInfo.mRemovedUsers != null && !deletedPs.isExternalStorage()) { // For non-system uninstalls with DELETE_KEEP_DATA, set the installed state to false Loading @@ -393,6 +422,7 @@ final class RemovePackageHelper { deletedPs.setInstalled(/* installed= */ false, userId); } } // make sure to preserve per-user installed state if this removal was just // a downgrade of a system app to the factory package boolean installedStateChanged = false; Loading Loading @@ -424,20 +454,6 @@ final class RemovePackageHelper { mPm.mSettings.writeKernelMappingLPr(deletedPs); } } if (removedAppId != -1) { // A user ID was deleted here. Go through all users and remove it from KeyStore. final int appIdToRemove = removedAppId; mPm.mInjector.getBackgroundHandler().post(() -> { try { Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "clearKeystoreData:" + appIdToRemove); mAppDataHelper.clearKeystoreData(UserHandle.USER_ALL, appIdToRemove); } finally { Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); } }); } } void cleanUpResources(File codeFile, String[] instructionSets) { Loading