OSDN Git Service

When scanning unbundled apps, only install the expected APK tree
authorChristopher Tate <ctate@google.com>
Thu, 26 Mar 2015 22:38:29 +0000 (15:38 -0700)
committerThe Android Automerger <android-build@google.com>
Fri, 27 Mar 2015 22:02:04 +0000 (15:02 -0700)
We now make sure, when scanning post-factory app installs, that we do not
accidentally activate a "leaked" or otherwise superfluous APK tree that the
scan algorithm happens to encounter before the one that we expect a priori
based on the persisted package-installation state.  When we find such an
extraneous installation we ignore it in favor of the expected one, similarly
to the policy used when collecting system-bundled packages that have been
updated.

Even if we find an unexpected APK for the package, if the expected one
turns out to be absent we fall back to the existing "we thought this app
was present and now it isn't" logic.

Bug 19602471

Change-Id: I141a93661946176c05d8cf52a123bdf75c8eef74

services/core/java/com/android/server/pm/PackageManagerService.java

index cc0a30a..6498dcc 100644 (file)
@@ -271,6 +271,7 @@ public class PackageManagerService extends IPackageManager.Stub {
     static final int SCAN_TRUSTED_OVERLAY = 1<<9;
     static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<10;
     static final int SCAN_REPLACING = 1<<11;
+    static final int SCAN_REQUIRE_KNOWN = 1<<12;
 
     static final int REMOVE_CHATTY = 1<<16;
 
@@ -1646,10 +1647,10 @@ public class PackageManagerService extends IPackageManager.Stub {
             if (!mOnlyCore) {
                 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
                         SystemClock.uptimeMillis());
-                scanDirLI(mAppInstallDir, 0, scanFlags, 0);
+                scanDirLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
 
                 scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK,
-                        scanFlags, 0);
+                        scanFlags | SCAN_REQUIRE_KNOWN, 0);
 
                 /**
                  * Remove disable package settings for any updated system
@@ -5349,6 +5350,28 @@ public class PackageManagerService extends IPackageManager.Stub {
                     + " already installed.  Skipping duplicate.");
         }
 
+        // If we're only installing presumed-existing packages, require that the
+        // scanned APK is both already known and at the path previously established
+        // for it.  Previously unknown packages we pick up normally, but if we have an
+        // a priori expectation about this package's install presence, enforce it.
+        if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
+            PackageSetting known = mSettings.peekPackageLPr(pkg.packageName);
+            if (known != null) {
+                if (DEBUG_PACKAGE_SCANNING) {
+                    Log.d(TAG, "Examining " + pkg.codePath
+                            + " and requiring known paths " + known.codePathString
+                            + " & " + known.resourcePathString);
+                }
+                if (!pkg.applicationInfo.getCodePath().equals(known.codePathString)
+                        || !pkg.applicationInfo.getResourcePath().equals(known.resourcePathString)) {
+                    throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
+                            "Application package " + pkg.packageName
+                            + " found at " + pkg.applicationInfo.getCodePath()
+                            + " but expected at " + known.codePathString + "; ignoring.");
+                }
+            }
+        }
+
         // Initialize package source and resource directories
         File destCodeFile = new File(pkg.applicationInfo.getCodePath());
         File destResourceFile = new File(pkg.applicationInfo.getResourcePath());