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);
|
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
|
// If someone is watching installs - notify them
|
||||||
|
|||||||
@@ -132,8 +132,8 @@ public class DexManager {
|
|||||||
// - new installed splits
|
// - new installed splits
|
||||||
// If we can't find the owner of the dex we simply do not track it. The impact is
|
// 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.
|
// that the dex file will not be considered for offline optimizations.
|
||||||
// TODO(calin): add hooks for install/uninstall notifications to
|
// TODO(calin): add hooks for move/uninstall notifications to
|
||||||
// capture new or obsolete packages.
|
// capture package moves or obsolete packages.
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Slog.i(TAG, "Could not find owning package for dex file: " + dexPath);
|
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) {
|
private void loadInternal(Map<Integer, List<PackageInfo>> existingPackages) {
|
||||||
Map<String, Set<Integer>> packageToUsersMap = new HashMap<>();
|
Map<String, Set<Integer>> packageToUsersMap = new HashMap<>();
|
||||||
// Cache the code locations for the installed packages. This allows for
|
// Cache the code locations for the installed packages. This allows for
|
||||||
@@ -166,13 +180,8 @@ public class DexManager {
|
|||||||
int userId = entry.getKey();
|
int userId = entry.getKey();
|
||||||
for (PackageInfo pi : packageInfoList) {
|
for (PackageInfo pi : packageInfoList) {
|
||||||
// Cache the code locations.
|
// Cache the code locations.
|
||||||
PackageCodeLocations pcl = mPackageCodeLocationsCache.get(pi.packageName);
|
cachePackageCodeLocation(pi, userId);
|
||||||
if (pcl != null) {
|
|
||||||
pcl.mergeAppDataDirs(pi.applicationInfo, userId);
|
|
||||||
} else {
|
|
||||||
mPackageCodeLocationsCache.put(pi.packageName,
|
|
||||||
new PackageCodeLocations(pi.applicationInfo, userId));
|
|
||||||
}
|
|
||||||
// Cache a map from package name to the set of user ids who installed the package.
|
// 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
|
// We will use it to sync the data and remove obsolete entries from
|
||||||
// mPackageDexUsage.
|
// mPackageDexUsage.
|
||||||
|
|||||||
@@ -204,6 +204,46 @@ public class DexManagerTests {
|
|||||||
assertNull(getPackageUseInfo(mBarUser1));
|
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,
|
private void assertSecondaryUse(TestData testData, PackageUseInfo pui,
|
||||||
List<String> secondaries, boolean isUsedByOtherApps, int ownerUserId) {
|
List<String> secondaries, boolean isUsedByOtherApps, int ownerUserId) {
|
||||||
for (String dex : secondaries) {
|
for (String dex : secondaries) {
|
||||||
|
|||||||
Reference in New Issue
Block a user