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
// - 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);
}
}
}
+ 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
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.
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) {