Support to pass <uses-library> option through to dex2oat.
This change takes an app's shared libraries specified by <uses-library>
and passes it through to dex2oat to be used during compilation.
Part of a multi-project change.
Bug: 26880306
(cherry-picked from 7b331b6a8ae8d9f10482b292439457de98abd32a)
Change-Id: I523b1b74775e7ed27072498509e743f1f10b1164
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index 3050ac8..bb2cc95 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -356,14 +356,18 @@
if (instrumentationSplitAppDirs != null) {
Collections.addAll(outZipPaths, instrumentationSplitAppDirs);
}
- outZipPaths.add(instrumentedAppDir);
- if (instrumentedSplitAppDirs != null) {
- Collections.addAll(outZipPaths, instrumentedSplitAppDirs);
+ if (!instrumentationAppDir.equals(instrumentedAppDir)) {
+ outZipPaths.add(instrumentedAppDir);
+ if (instrumentedSplitAppDirs != null) {
+ Collections.addAll(outZipPaths, instrumentedSplitAppDirs);
+ }
}
if (outLibPaths != null) {
outLibPaths.add(instrumentationLibDir);
- outLibPaths.add(instrumentedLibDir);
+ if (!instrumentationLibDir.equals(instrumentedLibDir)) {
+ outLibPaths.add(instrumentedLibDir);
+ }
}
if (!instrumentedAppDir.equals(instrumentationAppDir)) {
diff --git a/core/java/com/android/internal/os/InstallerConnection.java b/core/java/com/android/internal/os/InstallerConnection.java
index 47f2c70..a7a3cb5 100644
--- a/core/java/com/android/internal/os/InstallerConnection.java
+++ b/core/java/com/android/internal/os/InstallerConnection.java
@@ -135,14 +135,15 @@
}
public void dexopt(String apkPath, int uid, String instructionSet, int dexoptNeeded,
- int dexFlags, String compilerFilter, String volumeUuid) throws InstallerException {
- dexopt(apkPath, uid, "*", instructionSet, dexoptNeeded,
- null /*outputPath*/, dexFlags, compilerFilter, volumeUuid);
+ int dexFlags, String compilerFilter, String volumeUuid, String sharedLibraries)
+ throws InstallerException {
+ dexopt(apkPath, uid, "*", instructionSet, dexoptNeeded, null /*outputPath*/, dexFlags,
+ compilerFilter, volumeUuid, sharedLibraries);
}
public void dexopt(String apkPath, int uid, String pkgName, String instructionSet,
int dexoptNeeded, String outputPath, int dexFlags, String compilerFilter,
- String volumeUuid) throws InstallerException {
+ String volumeUuid, String sharedLibraries) throws InstallerException {
execute("dexopt",
apkPath,
uid,
@@ -152,7 +153,8 @@
outputPath,
dexFlags,
compilerFilter,
- volumeUuid);
+ volumeUuid,
+ sharedLibraries);
}
public boolean mergeProfiles(int uid, String pkgName) throws InstallerException {
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 78b5d61..9c09782 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -499,6 +499,7 @@
final String instructionSet = VMRuntime.getRuntime().vmInstructionSet();
try {
+ String sharedLibraries = "";
for (String classPathElement : classPathElements) {
// System server is fully AOTed and never profiled
// for profile guided compilation.
@@ -508,9 +509,13 @@
false /* newProfile */);
if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
installer.dexopt(classPathElement, Process.SYSTEM_UID, instructionSet,
- dexoptNeeded, 0 /*dexFlags*/, "speed",
- null /*volumeUuid*/);
+ dexoptNeeded, 0 /*dexFlags*/, "speed", null /*volumeUuid*/,
+ sharedLibraries);
}
+ if (!sharedLibraries.isEmpty()) {
+ sharedLibraries += ":";
+ }
+ sharedLibraries += classPathElement;
}
} catch (IOException | InstallerException e) {
throw new RuntimeException("Error starting system_server", e);
diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java
index 66c1a53..913c824 100644
--- a/services/core/java/com/android/server/pm/Installer.java
+++ b/services/core/java/com/android/server/pm/Installer.java
@@ -133,19 +133,20 @@
}
public void dexopt(String apkPath, int uid, String instructionSet, int dexoptNeeded,
- int dexFlags, String compilerFilter, String volumeUuid) throws InstallerException {
+ int dexFlags, String compilerFilter, String volumeUuid, String sharedLibraries)
+ throws InstallerException {
assertValidInstructionSet(instructionSet);
mInstaller.dexopt(apkPath, uid, instructionSet, dexoptNeeded, dexFlags,
- compilerFilter, volumeUuid);
+ compilerFilter, volumeUuid, sharedLibraries);
}
public void dexopt(String apkPath, int uid, String pkgName, String instructionSet,
int dexoptNeeded, @Nullable String outputPath, int dexFlags,
- String compilerFilter, String volumeUuid)
- throws InstallerException {
+ String compilerFilter, String volumeUuid, String sharedLibraries)
+ throws InstallerException {
assertValidInstructionSet(instructionSet);
mInstaller.dexopt(apkPath, uid, pkgName, instructionSet, dexoptNeeded,
- outputPath, dexFlags, compilerFilter, volumeUuid);
+ outputPath, dexFlags, compilerFilter, volumeUuid, sharedLibraries);
}
public boolean mergeProfiles(int uid, String pkgName) throws InstallerException {
diff --git a/services/core/java/com/android/server/pm/OtaDexoptService.java b/services/core/java/com/android/server/pm/OtaDexoptService.java
index c3a9226..50b8670 100644
--- a/services/core/java/com/android/server/pm/OtaDexoptService.java
+++ b/services/core/java/com/android/server/pm/OtaDexoptService.java
@@ -22,7 +22,9 @@
import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason;
import android.content.Context;
+import android.content.pm.ApplicationInfo;
import android.content.pm.IOtaDexopt;
+import android.content.pm.PackageManager;
import android.content.pm.PackageParser;
import android.os.Environment;
import android.os.RemoteException;
@@ -142,7 +144,8 @@
return;
}
- mPackageDexOptimizer.performDexOpt(nextPackage, null /* ISAs */, false /* useProfiles */,
+ mPackageDexOptimizer.performDexOpt(nextPackage, nextPackage.usesLibraryFiles,
+ null /* ISAs */, false /* checkProfiles */,
getCompilerFilterForReason(PackageManagerService.REASON_AB_OTA));
}
diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
index f620274..f134e40 100644
--- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java
+++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
@@ -88,8 +88,8 @@
* <p>Calls to {@link com.android.server.pm.Installer#dexopt} on {@link #mInstaller} are
* synchronized on {@link #mInstallLock}.
*/
- int performDexOpt(PackageParser.Package pkg, String[] instructionSets, boolean checkProfiles,
- String targetCompilationFilter) {
+ int performDexOpt(PackageParser.Package pkg, String[] sharedLibraries,
+ String[] instructionSets, boolean checkProfiles, String targetCompilationFilter) {
synchronized (mInstallLock) {
final boolean useLock = mSystemReady;
if (useLock) {
@@ -97,7 +97,7 @@
mDexoptWakeLock.acquire();
}
try {
- return performDexOptLI(pkg, instructionSets, checkProfiles,
+ return performDexOptLI(pkg, sharedLibraries, instructionSets, checkProfiles,
targetCompilationFilter);
} finally {
if (useLock) {
@@ -122,8 +122,8 @@
return dexoptFlags;
}
- private int performDexOptLI(PackageParser.Package pkg, String[] targetInstructionSets,
- boolean checkProfiles, String targetCompilerFilter) {
+ private int performDexOptLI(PackageParser.Package pkg, String[] sharedLibraries,
+ String[] targetInstructionSets, boolean checkProfiles, String targetCompilerFilter) {
final String[] instructionSets = targetInstructionSets != null ?
targetInstructionSets : getAppDexInstructionSets(pkg.applicationInfo);
@@ -200,10 +200,22 @@
throw new IllegalStateException("Invalid dexopt:" + dexoptNeeded);
}
+ String sharedLibrariesPath = null;
+ if (sharedLibraries != null && sharedLibraries.length != 0) {
+ StringBuilder sb = new StringBuilder();
+ for (String lib : sharedLibraries) {
+ if (sb.length() != 0) {
+ sb.append(":");
+ }
+ sb.append(lib);
+ }
+ sharedLibrariesPath = sb.toString();
+ }
Log.i(TAG, "Running dexopt (" + dexoptType + ") on: " + path + " pkg="
+ pkg.applicationInfo.packageName + " isa=" + dexCodeInstructionSet
+ " vmSafeMode=" + vmSafeMode + " debuggable=" + debuggable
- + " target-filter=" + targetCompilerFilter + " oatDir = " + oatDir);
+ + " target-filter=" + targetCompilerFilter + " oatDir = " + oatDir
+ + " sharedLibraries=" + sharedLibrariesPath);
// Profile guide compiled oat files should not be public.
final boolean isPublic = !pkg.isForwardLocked() && !isProfileGuidedFilter;
final int profileFlag = isProfileGuidedFilter ? DEXOPT_PROFILE_GUIDED : 0;
@@ -216,7 +228,8 @@
try {
mInstaller.dexopt(path, sharedGid, pkg.packageName, dexCodeInstructionSet,
- dexoptNeeded, oatDir, dexFlags, targetCompilerFilter, pkg.volumeUuid);
+ dexoptNeeded, oatDir, dexFlags, targetCompilerFilter, pkg.volumeUuid,
+ sharedLibrariesPath);
performedDexOpt = true;
} catch (InstallerException e) {
Slog.w(TAG, "Failed to dexopt", e);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index a128877..4b0eeed 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -498,6 +498,9 @@
public static final int REASON_LAST = REASON_FORCED_DEXOPT;
+ // Special String to skip shared libraries check during compilation.
+ private static final String SPECIAL_SHARED_LIBRARY = "&";
+
final ServiceThread mHandlerThread;
final PackageHandler mHandler;
@@ -2332,7 +2335,8 @@
mInstaller.dexopt(lib, Process.SYSTEM_UID, dexCodeInstructionSet,
dexoptNeeded, DEXOPT_PUBLIC /*dexFlags*/,
getCompilerFilterForReason(REASON_SHARED_APK),
- StorageManager.UUID_PRIVATE_INTERNAL);
+ StorageManager.UUID_PRIVATE_INTERNAL,
+ SPECIAL_SHARED_LIBRARY);
}
} catch (FileNotFoundException e) {
Slog.w(TAG, "Library not found: " + lib);
@@ -7298,12 +7302,14 @@
for (PackageParser.Package depPackage : deps) {
// TODO: Analyze and investigate if we (should) profile libraries.
// Currently this will do a full compilation of the library by default.
- pdo.performDexOpt(depPackage, instructionSets, false /* checkProfiles */,
+ pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets,
+ false /* checkProfiles */,
getCompilerFilterForReason(REASON_NON_SYSTEM_LIBRARY));
}
}
- return pdo.performDexOpt(p, instructionSets, checkProfiles, targetCompilerFilter);
+ return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets, checkProfiles,
+ targetCompilerFilter);
}
Collection<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) {
@@ -14709,11 +14715,20 @@
return;
}
+ // Shared libraries for the package need to be updated.
+ synchronized (mPackages) {
+ try {
+ updateSharedLibrariesLPw(pkg, null);
+ } catch (PackageManagerException e) {
+ Slog.e(TAG, "updateSharedLibrariesLPw failed: " + e.getMessage());
+ }
+ }
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
// Do not run PackageDexOptimizer through the local performDexOpt
// method because `pkg` is not in `mPackages` yet.
- int result = mPackageDexOptimizer.performDexOpt(pkg, null /* instructionSets */,
- false /* checkProfiles */, getCompilerFilterForReason(REASON_INSTALL));
+ int result = mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles,
+ null /* instructionSets */, false /* checkProfiles */,
+ getCompilerFilterForReason(REASON_INSTALL));
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
if (result == PackageDexOptimizer.DEX_OPT_FAILED) {
String msg = "Extracting package failed for " + pkgName;