Don't accidentally delete renamed packages
Apps on the system image can change their package by declaring
their old one in the manifest. If a package is renamed it is
internally referred by its old name.
The reconciliation code was using the new package name for
renamed packages and was concluding the apk is orphaned thus
deleting it. This puts the package in a bad state where the app
is gone and the version on the system partition is disabled.
Also Play was showing an update for a renamed system app as
an install while it is an update because of the same reason,
it was using the new package name while the app is internally
referred by the old one.
The fix for both above is to internally normalize the package
name by using the old one if the package was renamed or the
package name as is.
Test: With the fix put the old calculator on the system image
and booted, then put the renamed calculator and booted, updated
calculator from play and rebooted - calculator keeps working.
Also did the above steps without the patch to put calculator
in a bad state and flashed the system with the patch which
fixed the broken calculator app.
bug:32321269
Change-Id: I98bfc05c399edfc9854ebcce44182fefa55ceeff
(cherry picked from commit e2c85890ac3941525288e08962b33d30618de801)
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index cc7ded0..d8f65c8 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -2229,6 +2229,18 @@
mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false));
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ // Clean up orphaned packages for which the code path doesn't exist
+ // and they are an update to a system app - caused by bug/32321269
+ final int packageSettingCount = mSettings.mPackages.size();
+ for (int i = packageSettingCount - 1; i >= 0; i--) {
+ PackageSetting ps = mSettings.mPackages.valueAt(i);
+ if (!isExternal(ps) && (ps.codePath == null || !ps.codePath.exists())
+ && mSettings.getDisabledSystemPkgLPr(ps.name) != null) {
+ mSettings.mPackages.removeAt(i);
+ mSettings.enableSystemPackageLPw(ps.name);
+ }
+ }
+
if (mFirstBoot) {
requestCopyPreoptedFiles();
}
@@ -3209,8 +3221,12 @@
flags = updateFlagsForPackage(flags, userId, packageName);
enforceCrossUserPermission(Binder.getCallingUid(), userId,
false /* requireFullPermission */, false /* checkShell */, "get package info");
+
// reader
synchronized (mPackages) {
+ // Normalize package name to hanlde renamed packages
+ packageName = normalizePackageNameLPr(packageName);
+
final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0;
PackageParser.Package p = null;
if (matchFactoryOnly) {
@@ -3413,8 +3429,12 @@
flags = updateFlagsForApplication(flags, userId, packageName);
enforceCrossUserPermission(Binder.getCallingUid(), userId,
false /* requireFullPermission */, false /* checkShell */, "get application info");
+
// writer
synchronized (mPackages) {
+ // Normalize package name to hanlde renamed packages
+ packageName = normalizePackageNameLPr(packageName);
+
PackageParser.Package p = mPackages.get(packageName);
if (DEBUG_PACKAGE_INFO) Log.v(
TAG, "getApplicationInfo " + packageName
@@ -3436,6 +3456,11 @@
return null;
}
+ private String normalizePackageNameLPr(String packageName) {
+ String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
+ return normalizedPackageName != null ? normalizedPackageName : packageName;
+ }
+
@Override
public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
final IPackageDataObserver observer) {
@@ -20104,6 +20129,9 @@
private void assertPackageKnown(String volumeUuid, String packageName)
throws PackageManagerException {
synchronized (mPackages) {
+ // Normalize package name to handle renamed packages
+ packageName = normalizePackageNameLPr(packageName);
+
final PackageSetting ps = mSettings.mPackages.get(packageName);
if (ps == null) {
throw new PackageManagerException("Package " + packageName + " is unknown");
@@ -20118,6 +20146,9 @@
private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId)
throws PackageManagerException {
synchronized (mPackages) {
+ // Normalize package name to handle renamed packages
+ packageName = normalizePackageNameLPr(packageName);
+
final PackageSetting ps = mSettings.mPackages.get(packageName);
if (ps == null) {
throw new PackageManagerException("Package " + packageName + " is unknown");