Report non-primary dex files loads to PM

Scaffold for the reporting of non-primary dex files loads to the package
manager.

This will enable:
1) monitoring and compilation of secondary dex file
2) better way to track foreign dex file usage (used to determined the
compilation filter of apks).

Test: device boots
Bug: 32871170

(cherry picked from commit 8d2a51f1b8)

Change-Id: I61e65aee471798fbc7a18938647051274c3a058a
This commit is contained in:
Calin Juravle
2016-11-23 19:50:58 +00:00
parent 9ab94e15c7
commit 9abb501075
3 changed files with 49 additions and 0 deletions

View File

@@ -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);
}
}
}
/**

View File

@@ -457,6 +457,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.

View File

@@ -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) {