summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Patrick Baumann <patb@google.com> 2018-12-14 15:13:16 -0800
committer Patrick Baumann <patb@google.com> 2018-12-14 15:34:10 -0800
commit1b8ee6d3437f055f4545136303f76635d5604c68 (patch)
treeeadb54430b0a121924064c368b1e3c30b3fc90b0
parent66f04be168a9329622e1f40e33e2ba180d69b5ab (diff)
Fixes app removed broadcast
When an app is deleted for all users, it would send package removed broadcasts to no users. After this fix, it expands all users and correctly targets the users that the app was installed for. Change-Id: I664aee6f4a607ad8bba87b095dc78a387824887a Fixes: 121003130 Fixes: 121047681 Test: atest InputMethodServiceLifecycleTest#testUninstallCurrentImeFull
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java111
1 files changed, 56 insertions, 55 deletions
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 6cfb846e3ade..282457623a9c 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -15269,7 +15269,7 @@ public class PackageManagerService extends IPackageManager.Stub
| (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
deletePackageAction = mayDeletePackageLocked(res.removedInfo,
prepareResult.originalPs, prepareResult.disabledPs,
- prepareResult.childPackageSettings, deleteFlags, installArgs.user);
+ prepareResult.childPackageSettings, deleteFlags, null /* all users */);
if (deletePackageAction == null) {
throw new ReconcileFailure(
PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE,
@@ -17356,28 +17356,22 @@ public class PackageManagerService extends IPackageManager.Stub
* make sure this flag is set for partially installed apps. If not its meaningless to
* delete a partially installed application.
*/
- private void removePackageDataLIF(PackageSetting ps, int[] allUserHandles,
+ private void removePackageDataLIF(final PackageSetting deletedPs, int[] allUserHandles,
PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
- String packageName = ps.name;
- if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
+ String packageName = deletedPs.name;
+ if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + deletedPs);
// Retrieve object to delete permissions for shared user later on
- final PackageParser.Package deletedPkg;
- final PackageSetting deletedPs;
- // reader
- synchronized (mPackages) {
- deletedPkg = mPackages.get(packageName);
- deletedPs = mSettings.mPackages.get(packageName);
- if (outInfo != null) {
- outInfo.removedPackage = packageName;
- outInfo.installerPackageName = ps.installerPackageName;
- outInfo.isStaticSharedLib = deletedPkg != null
- && deletedPkg.staticSharedLibName != null;
- outInfo.populateUsers(deletedPs == null ? null
- : deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true), deletedPs);
- }
+ final PackageParser.Package deletedPkg = deletedPs.pkg;
+ if (outInfo != null) {
+ outInfo.removedPackage = packageName;
+ outInfo.installerPackageName = deletedPs.installerPackageName;
+ outInfo.isStaticSharedLib = deletedPkg != null
+ && deletedPkg.staticSharedLibName != null;
+ outInfo.populateUsers(deletedPs == null ? null
+ : deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true), deletedPs);
}
- removePackageLI(ps.name, (flags & PackageManager.DELETE_CHATTY) != 0);
+ removePackageLI(deletedPs.name, (flags & PackageManager.DELETE_CHATTY) != 0);
if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
final PackageParser.Package resolvedPkg;
@@ -17386,8 +17380,8 @@ public class PackageManagerService extends IPackageManager.Stub
} 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);
+ resolvedPkg = new PackageParser.Package(deletedPs.name);
+ resolvedPkg.setVolumeUuid(deletedPs.volumeUuid);
}
destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL,
StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
@@ -17447,10 +17441,10 @@ public class PackageManagerService extends IPackageManager.Stub
if (DEBUG_REMOVE) {
Slog.d(TAG, " user " + userId + " => " + installed);
}
- if (installed != ps.getInstalled(userId)) {
+ if (installed != deletedPs.getInstalled(userId)) {
installedStateChanged = true;
}
- ps.setInstalled(installed, userId);
+ deletedPs.setInstalled(installed, userId);
}
}
}
@@ -17460,7 +17454,7 @@ public class PackageManagerService extends IPackageManager.Stub
mSettings.writeLPr();
}
if (installedStateChanged) {
- mSettings.writeKernelMappingLPr(ps);
+ mSettings.writeKernelMappingLPr(deletedPs);
}
}
if (removedAppId != -1) {
@@ -17530,12 +17524,12 @@ public class PackageManagerService extends IPackageManager.Stub
/*
* Tries to delete system package.
*/
- private void deleteSystemPackageLIF(DeletePackageAction action,
- PackageParser.Package deletedPkg, PackageSetting deletedPs, int[] allUserHandles,
- int flags, PackageRemovedInfo outInfo, boolean writeSettings)
+ private void deleteSystemPackageLIF(DeletePackageAction action, PackageSetting deletedPs,
+ int[] allUserHandles, int flags, PackageRemovedInfo outInfo, boolean writeSettings)
throws SystemDeleteException {
final boolean applyUserRestrictions
= (allUserHandles != null) && (outInfo.origUsers != null);
+ final PackageParser.Package deletedPkg = deletedPs.pkg;
// Confirm if the system package has been updated
// An updated system app can be deleted. This will also have to restore
// the system pkg from system partition
@@ -17895,16 +17889,18 @@ public class PackageManagerService extends IPackageManager.Stub
PackageSetting[] children = mSettings.getChildSettingsLPr(ps);
action = mayDeletePackageLocked(outInfo, ps, disabledPs, children, flags, user);
}
+ if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
if (null == action) {
+ if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: action was null");
return false;
}
- if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
try {
executeDeletePackageLIF(action, packageName, deleteCodeAndResources,
allUserHandles, writeSettings, replacingPackage);
} catch (SystemDeleteException e) {
+ if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: system deletion failure", e);
return false;
}
return true;
@@ -17951,42 +17947,48 @@ public class PackageManagerService extends IPackageManager.Stub
unsuspendForSuspendingPackage(packageName, userId);
}
-
if (!systemApp || action.mayDeleteUnupdatedSystemApp) {
// The caller is asking that the package only be deleted for a single
// user. To do this, we just mark its uninstalled state and delete
// its data. If this is a system app, we only allow this to happen if
// they have set the special DELETE_SYSTEM_APP which requests different
// semantics than normal for uninstalling system apps.
- markPackageUninstalledForUserLPw(ps, user);
-
- if (!systemApp) {
- // Do not uninstall the APK if an app should be cached
- boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
- if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) {
- // Other user still have this package installed, so all
+ synchronized (mPackages) {
+ markPackageUninstalledForUserLPw(ps, user);
+ if (!systemApp) {
+ // Do not uninstall the APK if an app should be cached
+ boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
+ if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) {
+ // Other users still have this package installed, so all
+ // we need to do is clear this user's data and save that
+ // it is uninstalled.
+ if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
+ clearPackageStateForUserLIF(ps, userId, outInfo, flags);
+ scheduleWritePackageRestrictionsLocked(user);
+ return;
+ } else {
+ // We need to set it back to 'installed' so the uninstall
+ // broadcasts will be sent correctly.
+ if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
+ if (userId != UserHandle.USER_ALL) {
+ ps.setInstalled(true, userId);
+ } else {
+ for (int origUserId : outInfo.origUsers) {
+ ps.setInstalled(true, origUserId);
+ }
+ }
+ mSettings.writeKernelMappingLPr(ps);
+ }
+ } else {
+ // This is a system app, so we assume that the
+ // other users still have this package installed, so all
// we need to do is clear this user's data and save that
// it is uninstalled.
- if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
- clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo, flags);
+ if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
+ clearPackageStateForUserLIF(ps, userId, outInfo, flags);
scheduleWritePackageRestrictionsLocked(user);
return;
- } else {
- // We need to set it back to 'installed' so the uninstall
- // broadcasts will be sent correctly.
- if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
- ps.setInstalled(true, user.getIdentifier());
- mSettings.writeKernelMappingLPr(ps);
}
- } else {
- // This is a system app, so we assume that the
- // other users still have this package installed, so all
- // we need to do is clear this user's data and save that
- // it is uninstalled.
- if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
- clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo, flags);
- scheduleWritePackageRestrictionsLocked(user);
- return;
}
}
@@ -18015,8 +18017,7 @@ public class PackageManagerService extends IPackageManager.Stub
if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
// When an updated system application is deleted we delete the existing resources
// as well and fall back to existing code in system partition
- deleteSystemPackageLIF(
- action, ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings);
+ deleteSystemPackageLIF(action, ps, allUserHandles, flags, outInfo, writeSettings);
} else {
if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles,