summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Calin Juravle <calin@google.com> 2017-04-06 15:54:58 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2017-04-06 15:55:04 +0000
commit539128f6d652d0a38cede9cb4dbb9888f89ffbcf (patch)
treee4a155472073f8c6a72d1125f7db4dcc645a0582
parent3c0f1f1aa2dc4d6a3b73e535ef13ad851b7bbbfb (diff)
parentadbadd5577d2b1291d10146b6ffb5577cf236528 (diff)
Merge "Keep track of protected data dirs in DexManager" into oc-dev
-rw-r--r--services/core/java/com/android/server/pm/PackageDexOptimizer.java7
-rw-r--r--services/core/java/com/android/server/pm/dex/DexManager.java52
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java22
3 files changed, 63 insertions, 18 deletions
diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
index acbd446a967f..781be34828ad 100644
--- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java
+++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
@@ -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);
diff --git a/services/core/java/com/android/server/pm/dex/DexManager.java b/services/core/java/com/android/server/pm/dex/DexManager.java
index c693a475ed59..3d7cedce522a 100644
--- a/services/core/java/com/android/server/pm/dex/DexManager.java
+++ b/services/core/java/com/android/server/pm/dex/DexManager.java
@@ -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;
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java b/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java
index 72fb78e89ea2..afc0f67fe993 100644
--- a/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java
@@ -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);