Merge "Keep track of protected data dirs in DexManager" into oc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
539128f6d6
@@ -22,6 +22,7 @@ import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageParser;
|
||||
import android.os.Environment;
|
||||
import android.os.FileUtils;
|
||||
import android.os.PowerManager;
|
||||
import android.os.UserHandle;
|
||||
import android.os.WorkSource;
|
||||
@@ -259,9 +260,11 @@ public class PackageDexOptimizer {
|
||||
// Get the dexopt flags after getRealCompilerFilter to make sure we get the correct flags.
|
||||
int dexoptFlags = getDexFlags(info, compilerFilter) | DEXOPT_SECONDARY_DEX;
|
||||
// Check the app storage and add the appropriate flags.
|
||||
if (info.dataDir.equals(info.deviceProtectedDataDir)) {
|
||||
if (info.deviceProtectedDataDir != null &&
|
||||
FileUtils.contains(info.deviceProtectedDataDir, path)) {
|
||||
dexoptFlags |= DEXOPT_STORAGE_DE;
|
||||
} else if (info.dataDir.equals(info.credentialProtectedDataDir)) {
|
||||
} else if (info.credentialProtectedDataDir != null &&
|
||||
FileUtils.contains(info.credentialProtectedDataDir, path)) {
|
||||
dexoptFlags |= DEXOPT_STORAGE_CE;
|
||||
} else {
|
||||
Slog.e(TAG, "Could not infer CE/DE storage for package " + info.packageName);
|
||||
|
||||
@@ -19,7 +19,7 @@ package com.android.server.pm.dex;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.IPackageManager;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageParser;
|
||||
import android.os.FileUtils;
|
||||
import android.os.RemoteException;
|
||||
import android.os.storage.StorageManager;
|
||||
import android.os.UserHandle;
|
||||
@@ -93,7 +93,7 @@ public class DexManager {
|
||||
* Note that this method is invoked when apps load dex files and it should
|
||||
* return as fast as possible.
|
||||
*
|
||||
* @param loadingPackage the package performing the load
|
||||
* @param loadingAppInfo the package performing the load
|
||||
* @param dexPaths the list of dex files being loaded
|
||||
* @param loaderIsa the ISA of the app loading the dex files
|
||||
* @param loaderUserId the user id which runs the code loading the dex files
|
||||
@@ -191,8 +191,7 @@ public class DexManager {
|
||||
throw new IllegalArgumentException(
|
||||
"notifyPackageInstalled called with USER_ALL");
|
||||
}
|
||||
cachePackageCodeLocation(pi.packageName, pi.applicationInfo.sourceDir,
|
||||
pi.applicationInfo.splitSourceDirs, pi.applicationInfo.dataDir, userId);
|
||||
cachePackageInfo(pi, userId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -231,13 +230,32 @@ public class DexManager {
|
||||
}
|
||||
}
|
||||
|
||||
public void cachePackageCodeLocation(String packageName, String baseCodePath,
|
||||
String[] splitCodePaths, String dataDir, int userId) {
|
||||
/**
|
||||
* Caches the code location from the given package info.
|
||||
*/
|
||||
private void cachePackageInfo(PackageInfo pi, int userId) {
|
||||
ApplicationInfo ai = pi.applicationInfo;
|
||||
String[] dataDirs = new String[] {ai.dataDir, ai.deviceProtectedDataDir,
|
||||
ai.credentialProtectedDataDir};
|
||||
cachePackageCodeLocation(pi.packageName, ai.sourceDir, ai.splitSourceDirs,
|
||||
dataDirs, userId);
|
||||
}
|
||||
|
||||
private void cachePackageCodeLocation(String packageName, String baseCodePath,
|
||||
String[] splitCodePaths, String[] dataDirs, int userId) {
|
||||
PackageCodeLocations pcl = putIfAbsent(mPackageCodeLocationsCache, packageName,
|
||||
new PackageCodeLocations(packageName, baseCodePath, splitCodePaths));
|
||||
pcl.updateCodeLocation(baseCodePath, splitCodePaths);
|
||||
if (dataDir != null) {
|
||||
pcl.mergeAppDataDirs(dataDir, userId);
|
||||
if (dataDirs != null) {
|
||||
for (String dataDir : dataDirs) {
|
||||
// The set of data dirs includes deviceProtectedDataDir and
|
||||
// credentialProtectedDataDir which might be null for shared
|
||||
// libraries. Currently we don't track these but be lenient
|
||||
// and check in case we ever decide to store their usage data.
|
||||
if (dataDir != null) {
|
||||
pcl.mergeAppDataDirs(dataDir, userId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -250,8 +268,7 @@ public class DexManager {
|
||||
int userId = entry.getKey();
|
||||
for (PackageInfo pi : packageInfoList) {
|
||||
// Cache the code locations.
|
||||
cachePackageCodeLocation(pi.packageName, pi.applicationInfo.sourceDir,
|
||||
pi.applicationInfo.splitSourceDirs, pi.applicationInfo.dataDir, userId);
|
||||
cachePackageInfo(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
|
||||
@@ -329,6 +346,7 @@ public class DexManager {
|
||||
mPackageDexUsage.removeUserPackage(packageName, dexUseInfo.getOwnerUserId());
|
||||
continue;
|
||||
}
|
||||
|
||||
int result = pdo.dexOptSecondaryDexPath(pkg.applicationInfo, dexPath,
|
||||
dexUseInfo.getLoaderIsas(), compilerFilter, dexUseInfo.isUsedByOtherApps());
|
||||
success = success && (result != PackageDexOptimizer.DEX_OPT_FAILED);
|
||||
@@ -350,7 +368,7 @@ public class DexManager {
|
||||
// Nothing to reconcile.
|
||||
return;
|
||||
}
|
||||
Set<String> dexFilesToRemove = new HashSet<>();
|
||||
|
||||
boolean updated = false;
|
||||
for (Map.Entry<String, DexUseInfo> entry : useInfo.getDexUseInfoMap().entrySet()) {
|
||||
String dexPath = entry.getKey();
|
||||
@@ -378,14 +396,16 @@ public class DexManager {
|
||||
}
|
||||
ApplicationInfo info = pkg.applicationInfo;
|
||||
int flags = 0;
|
||||
if (info.dataDir.equals(info.deviceProtectedDataDir)) {
|
||||
if (info.deviceProtectedDataDir != null &&
|
||||
FileUtils.contains(info.deviceProtectedDataDir, dexPath)) {
|
||||
flags |= StorageManager.FLAG_STORAGE_DE;
|
||||
} else if (info.dataDir.equals(info.credentialProtectedDataDir)) {
|
||||
} else if (info.credentialProtectedDataDir!= null &&
|
||||
FileUtils.contains(info.credentialProtectedDataDir, dexPath)) {
|
||||
flags |= StorageManager.FLAG_STORAGE_CE;
|
||||
} else {
|
||||
Slog.e(TAG, "Could not infer CE/DE storage for package " + info.packageName);
|
||||
updated = mPackageDexUsage.removeUserPackage(
|
||||
packageName, dexUseInfo.getOwnerUserId()) || updated;
|
||||
Slog.e(TAG, "Could not infer CE/DE storage for path " + dexPath);
|
||||
updated = mPackageDexUsage.removeDexFile(
|
||||
packageName, dexPath, dexUseInfo.getOwnerUserId()) || updated;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -360,6 +360,19 @@ public class DexManagerTests {
|
||||
assertNull(mDexManager.getPackageUseInfo(frameworkDex));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotifySecondaryFromProtected() {
|
||||
// Foo loads its own secondary files.
|
||||
List<String> fooSecondaries = mFooUser0.getSecondaryDexPathsFromProtectedDirs();
|
||||
notifyDexLoad(mFooUser0, fooSecondaries, mUser0);
|
||||
|
||||
PackageUseInfo pui = getPackageUseInfo(mFooUser0);
|
||||
assertNotNull(pui);
|
||||
assertFalse(pui.isUsedByOtherApps());
|
||||
assertEquals(fooSecondaries.size(), pui.getDexUseInfoMap().size());
|
||||
assertSecondaryUse(mFooUser0, pui, fooSecondaries, /*isUsedByOtherApps*/false, mUser0);
|
||||
}
|
||||
|
||||
private void assertSecondaryUse(TestData testData, PackageUseInfo pui,
|
||||
List<String> secondaries, boolean isUsedByOtherApps, int ownerUserId) {
|
||||
for (String dex : secondaries) {
|
||||
@@ -394,6 +407,8 @@ public class DexManagerTests {
|
||||
ai.setBaseCodePath(codeDir + "/base.dex");
|
||||
ai.setSplitCodePaths(new String[] {codeDir + "/split-1.dex", codeDir + "/split-2.dex"});
|
||||
ai.dataDir = "/data/user/" + userId + "/" + packageName;
|
||||
ai.deviceProtectedDataDir = "/data/user_de/" + userId + "/" + packageName;
|
||||
ai.credentialProtectedDataDir = "/data/user_ce/" + userId + "/" + packageName;
|
||||
ai.packageName = packageName;
|
||||
return ai;
|
||||
}
|
||||
@@ -426,6 +441,13 @@ public class DexManagerTests {
|
||||
return paths;
|
||||
}
|
||||
|
||||
List<String> getSecondaryDexPathsFromProtectedDirs() {
|
||||
List<String> paths = new ArrayList<>();
|
||||
paths.add(mPackageInfo.applicationInfo.dataDir + "/secondary6.dex");
|
||||
paths.add(mPackageInfo.applicationInfo.dataDir + "/secondary7.dex");
|
||||
return paths;
|
||||
}
|
||||
|
||||
List<String> getBaseAndSplitDexPaths() {
|
||||
List<String> paths = new ArrayList<>();
|
||||
paths.add(mPackageInfo.applicationInfo.sourceDir);
|
||||
|
||||
Reference in New Issue
Block a user