From aab8cbfa234e1c53f909ac4bebeccbe2ddbeda05 Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Mon, 9 May 2016 16:51:08 -0600 Subject: [PATCH] Fix package cleanup when parsed APK missing. Recently the uninstall logic was changed to require a parsed APK to succeed, but we need uninstall to succeed when the APK lives on an ejected storage device. To fix that case, create a fake parsed package with just enough information for the delete to proceed. Fix package movement bug that sent an invalid user ID to installd; we need to explicitly ask for each user. Bug: 28658206 Change-Id: Icf417661f07688c7523f0d082528adec2ac70cc6 --- .../server/pm/PackageManagerService.java | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 4adfc3fb7d45f..d7693b0ebe617 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -15453,9 +15453,18 @@ public class PackageManagerService extends IPackageManager.Stub { removePackageLI(ps, (flags & REMOVE_CHATTY) != 0); if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) { - destroyAppDataLIF(deletedPkg, UserHandle.USER_ALL, + final PackageParser.Package 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 = new PackageParser.Package(ps.name); + resolvedPkg.setVolumeUuid(ps.volumeUuid); + } + destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); - destroyAppProfilesLIF(deletedPkg); + destroyAppProfilesLIF(resolvedPkg); if (outInfo != null) { outInfo.dataRemoved = true; } @@ -19610,6 +19619,7 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); final String label; final int targetSdkVersion; final PackageFreezer freezer; + final int[] installedUserIds; // reader synchronized (mPackages) { @@ -19664,6 +19674,7 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo)); targetSdkVersion = pkg.applicationInfo.targetSdkVersion; freezer = new PackageFreezer(packageName, "movePackageInternal"); + installedUserIds = ps.queryInstalledUsers(sUserManager.getUserIds(), true); } final Bundle extras = new Bundle(); @@ -19701,10 +19712,12 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); final PackageStats stats = new PackageStats(null, -1); synchronized (mInstaller) { - if (!getPackageSizeInfoLI(packageName, -1, stats)) { - freezer.close(); - throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, - "Failed to measure package size"); + for (int userId : installedUserIds) { + if (!getPackageSizeInfoLI(packageName, userId, stats)) { + freezer.close(); + throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, + "Failed to measure package size"); + } } }