summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/LoadedApk.java35
-rw-r--r--core/java/android/content/pm/IPackageManager.aidl9
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java5
3 files changed, 49 insertions, 0 deletions
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index 9ea16a719ceb..afe9651d82f5 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -51,6 +51,7 @@ import android.util.SparseArray;
import android.view.Display;
import android.view.DisplayAdjustments;
+import dalvik.system.BaseDexClassLoader;
import dalvik.system.VMRuntime;
import java.io.File;
@@ -600,6 +601,40 @@ public final class LoadedApk {
VMRuntime.registerAppInfo(profileFile.getPath(), mApplicationInfo.dataDir,
codePaths.toArray(new String[codePaths.size()]), foreignDexProfilesFile.getPath());
+
+ // Setup the reporter to notify package manager of any relevant dex loads.
+ // At this point the primary apk is loaded and will not be reported.
+ // Anything loaded from now on will be tracked as a potential secondary
+ // or foreign dex file. The goal is to enable:
+ // 1) monitoring and compilation of secondary dex file
+ // 2) track foreign dex file usage (used to determined the
+ // compilation filter of apks).
+ if (BaseDexClassLoader.getReporter() != DexLoadReporter.INSTANCE) {
+ // Set the dex load reporter if not already set.
+ // Note that during the app's life cycle different LoadedApks may be
+ // created and loaded (e.g. if two different apps share the same runtime).
+ BaseDexClassLoader.setReporter(DexLoadReporter.INSTANCE);
+ }
+ }
+
+ private static class DexLoadReporter implements BaseDexClassLoader.Reporter {
+ private static final DexLoadReporter INSTANCE = new DexLoadReporter();
+
+ private DexLoadReporter() {}
+
+ @Override
+ public void report(List<String> dexPaths) {
+ if (dexPaths.isEmpty()) {
+ return;
+ }
+ String packageName = ActivityThread.currentPackageName();
+ try {
+ ActivityThread.getPackageManager().notifyDexLoad(
+ packageName, dexPaths, VMRuntime.getRuntime().vmInstructionSet());
+ } catch (RemoteException re) {
+ Slog.e(TAG, "Failed to notify PM about dex load for package " + packageName, re);
+ }
+ }
}
/**
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 11f0eb626964..f35b13d44474 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -458,6 +458,15 @@ interface IPackageManager {
void notifyPackageUse(String packageName, int reason);
/**
+ * Notify the package manager that a list of dex files have been loaded.
+ *
+ * @param loadingPackageName the name of the package who performs the load
+ * @param dexPats the list of the dex files paths that have been loaded
+ * @param loaderIsa the ISA of the loader process
+ */
+ void notifyDexLoad(String loadingPackageName, in List<String> dexPaths, String loaderIsa);
+
+ /**
* Ask the package manager to perform dex-opt (if needed) on the given
* package if it already hasn't done so.
*
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 1c78b1637ccd..7ce5aa8ae39d 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -7360,6 +7360,11 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
+ @Override
+ public void notifyDexLoad(String loadingPackageName, List<String> dexPaths, String loaderIsa) {
+ // TODO(calin): b/32871170
+ }
+
// TODO: this is not used nor needed. Delete it.
@Override
public boolean performDexOptIfNeeded(String packageName) {