diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java index 0cfa009163269..ee050d5d4f4f7 100644 --- a/core/java/android/app/LoadedApk.java +++ b/core/java/android/app/LoadedApk.java @@ -356,14 +356,18 @@ public final class LoadedApk { 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 47f2c708c1a0d..a7a3cb59f90db 100644 --- a/core/java/com/android/internal/os/InstallerConnection.java +++ b/core/java/com/android/internal/os/InstallerConnection.java @@ -135,14 +135,15 @@ public class InstallerConnection { } 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 @@ public class InstallerConnection { 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 78b5d61d3f1a3..9c09782e7dcde 100644 --- a/core/java/com/android/internal/os/ZygoteInit.java +++ b/core/java/com/android/internal/os/ZygoteInit.java @@ -499,6 +499,7 @@ public class ZygoteInit { 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 @@ public class ZygoteInit { 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 66c1a53f587a0..913c82428ec6d 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 final class Installer extends SystemService { } 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 c3a9226d5a367..50b86708c14a8 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.InstructionSets.getDexCodeInstructionSets; 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 @@ public class OtaDexoptService extends IOtaDexopt.Stub { 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 b3ac05c2e91db..22f630d3276c1 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 @@ class PackageDexOptimizer { *
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 @@ class PackageDexOptimizer {
mDexoptWakeLock.acquire();
}
try {
- return performDexOptLI(pkg, instructionSets, checkProfiles,
+ return performDexOptLI(pkg, sharedLibraries, instructionSets, checkProfiles,
targetCompilationFilter);
} finally {
if (useLock) {
@@ -122,8 +122,8 @@ class PackageDexOptimizer {
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);
@@ -207,10 +207,22 @@ class PackageDexOptimizer {
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;
@@ -223,7 +235,8 @@ class PackageDexOptimizer {
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 2a4d2b2237cf6..c0d4aa9206ed6 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 class PackageManagerService extends IPackageManager.Stub {
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;
@@ -2337,7 +2340,8 @@ public class PackageManagerService extends IPackageManager.Stub {
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);
@@ -7301,12 +7305,14 @@ public class PackageManagerService extends IPackageManager.Stub {
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