diff options
3 files changed, 70 insertions, 9 deletions
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 461d121e6bc4..86a29c6813c2 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -1787,6 +1787,18 @@ public class PackageManagerService extends IPackageManager.Stub { res.removedInfo.args.doPostDeleteLI(true); } } + + if (!isEphemeral(res.pkg)) { + // Notify DexManager that the package was installed for new users. + // The updated users should already be indexed and the package code paths + // should not change. + // Don't notify the manager for ephemeral apps as they are not expected to + // survive long enough to benefit of background optimizations. + for (int userId : firstUsers) { + PackageInfo info = getPackageInfo(packageName, /*flags*/ 0, userId); + mDexManager.notifyPackageInstalled(info, userId); + } + } } // If someone is watching installs - notify them diff --git a/services/core/java/com/android/server/pm/dex/DexManager.java b/services/core/java/com/android/server/pm/dex/DexManager.java index 6d06838cd24f..e8092131a74f 100644 --- a/services/core/java/com/android/server/pm/dex/DexManager.java +++ b/services/core/java/com/android/server/pm/dex/DexManager.java @@ -132,8 +132,8 @@ public class DexManager { // - new installed splits // If we can't find the owner of the dex we simply do not track it. The impact is // that the dex file will not be considered for offline optimizations. - // TODO(calin): add hooks for install/uninstall notifications to - // capture new or obsolete packages. + // TODO(calin): add hooks for move/uninstall notifications to + // capture package moves or obsolete packages. if (DEBUG) { Slog.i(TAG, "Could not find owning package for dex file: " + dexPath); } @@ -157,6 +157,20 @@ public class DexManager { } } + public void notifyPackageInstalled(PackageInfo info, int userId) { + cachePackageCodeLocation(info, userId); + } + + private void cachePackageCodeLocation(PackageInfo info, int userId) { + PackageCodeLocations pcl = mPackageCodeLocationsCache.get(info.packageName); + if (pcl != null) { + pcl.mergeAppDataDirs(info.applicationInfo, userId); + } else { + mPackageCodeLocationsCache.put(info.packageName, + new PackageCodeLocations(info.applicationInfo, userId)); + } + } + private void loadInternal(Map<Integer, List<PackageInfo>> existingPackages) { Map<String, Set<Integer>> packageToUsersMap = new HashMap<>(); // Cache the code locations for the installed packages. This allows for @@ -166,13 +180,8 @@ public class DexManager { int userId = entry.getKey(); for (PackageInfo pi : packageInfoList) { // Cache the code locations. - PackageCodeLocations pcl = mPackageCodeLocationsCache.get(pi.packageName); - if (pcl != null) { - pcl.mergeAppDataDirs(pi.applicationInfo, userId); - } else { - mPackageCodeLocationsCache.put(pi.packageName, - new PackageCodeLocations(pi.applicationInfo, userId)); - } + cachePackageCodeLocation(pi, userId); + // Cache a map from package name to the set of user ids who installed the package. // We will use it to sync the data and remove obsolete entries from // mPackageDexUsage. diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java b/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java index b655f3af3a24..2d07e651fdd1 100644 --- a/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java +++ b/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java @@ -204,6 +204,46 @@ public class DexManagerTests { assertNull(getPackageUseInfo(mBarUser1)); } + @Test + public void testNotifyPackageInstallUsedByOther() { + TestData newPackage = new TestData("newPackage", + VMRuntime.getInstructionSet(Build.SUPPORTED_ABIS[0]), mUser0); + + List<String> newSecondaries = newPackage.getSecondaryDexPaths(); + // Before we notify about the installation of the newPackage if mFoo + // is trying to load something from it we should not find it. + notifyDexLoad(mFooUser0, newSecondaries, mUser0); + assertNull(getPackageUseInfo(newPackage)); + + // Notify about newPackage install and let mFoo load its dexes. + mDexManager.notifyPackageInstalled(newPackage.mPackageInfo, mUser0); + notifyDexLoad(mFooUser0, newSecondaries, mUser0); + + // We should get back the right info. + PackageUseInfo pui = getPackageUseInfo(newPackage); + assertNotNull(pui); + assertFalse(pui.isUsedByOtherApps()); + assertEquals(newSecondaries.size(), pui.getDexUseInfoMap().size()); + assertSecondaryUse(newPackage, pui, newSecondaries, /*isUsedByOtherApps*/true, mUser0); + } + + @Test + public void testNotifyPackageInstallSelfUse() { + TestData newPackage = new TestData("newPackage", + VMRuntime.getInstructionSet(Build.SUPPORTED_ABIS[0]), mUser0); + + List<String> newSecondaries = newPackage.getSecondaryDexPaths(); + // Packages should be able to find their own dex files even if the notification about + // their installation is delayed. + notifyDexLoad(newPackage, newSecondaries, mUser0); + + PackageUseInfo pui = getPackageUseInfo(newPackage); + assertNotNull(pui); + assertFalse(pui.isUsedByOtherApps()); + assertEquals(newSecondaries.size(), pui.getDexUseInfoMap().size()); + assertSecondaryUse(newPackage, pui, newSecondaries, /*isUsedByOtherApps*/false, mUser0); + } + private void assertSecondaryUse(TestData testData, PackageUseInfo pui, List<String> secondaries, boolean isUsedByOtherApps, int ownerUserId) { for (String dex : secondaries) { |