Notify DexManager about new package installs
This will update the internal cache so that the secondary dex files of
the new package can be found when loaded.
Test: runtest -x .../DexManagerTests.java
Bug: 32871170
(cherry picked from commit 0d4b8f8b0c)
Change-Id: I34008f6d262f19e88a346a36b83e4093b4129105
Merged-In: I0cb7158af249feeb01cf578a7544dda978eede9d
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user