Loading services/core/java/com/android/server/pm/PackageManagerService.java +12 −0 Original line number Diff line number Diff line Loading @@ -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 Loading services/core/java/com/android/server/pm/dex/DexManager.java +18 −9 Original line number Diff line number Diff line Loading @@ -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); } Loading @@ -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 Loading @@ -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. Loading services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java +40 −0 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading
services/core/java/com/android/server/pm/PackageManagerService.java +12 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
services/core/java/com/android/server/pm/dex/DexManager.java +18 −9 Original line number Diff line number Diff line Loading @@ -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); } Loading @@ -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 Loading @@ -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. Loading
services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java +40 −0 Original line number Diff line number Diff line Loading @@ -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) { Loading