Add a command line option to optimize individual splits
The new option is "--split SplitName" and applies to "adb shell cmd
package compile" command.
Usage example:
adb shell cmd package compile -m speed --split split_feature_a.apk
com.android.cts.classloadersplitapp
Bug: 38138251
Test: adb install-multiple CtsClassloaderSplitApp.apk
CtsClassloaderSplitAppFeatureA.apk CtsClassloaderSplitAppFeatureB.apk
adb shell cmd package compile -m speed --split split_feature_a.apk
com.android.cts.classloadersplitapp
check the status of split_feature_a
runtest -x
services/tests/servicestests/src/com/android/server/pm/dex/DexoptOptionsTests.java
Change-Id: I579bb12fa6699f99cd3824f185bd9352fb8007c5
diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
index 60fba27..2c935f1 100644
--- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java
+++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
@@ -162,6 +162,14 @@
}
// Append shared libraries with split dependencies for this split.
String path = paths.get(i);
+ if (options.getSplitName() != null) {
+ // We are asked to compile only a specific split. Check that the current path is
+ // what we are looking for.
+ if (!options.getSplitName().equals(new File(path).getName())) {
+ continue;
+ }
+ }
+
String sharedLibrariesPathWithSplits;
if (sharedLibrariesPath != null && splitDependencies[i] != null) {
sharedLibrariesPathWithSplits = sharedLibrariesPath + ":" + splitDependencies[i];
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 5f797e8..6692690 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -9473,11 +9473,12 @@
@Override
public boolean performDexOptMode(String packageName,
boolean checkProfiles, String targetCompilerFilter, boolean force,
- boolean bootComplete) {
+ boolean bootComplete, String splitName) {
int flags = (checkProfiles ? DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES : 0) |
(force ? DexoptOptions.DEXOPT_FORCE : 0) |
(bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0);
- return performDexOpt(new DexoptOptions(packageName, targetCompilerFilter, flags));
+ return performDexOpt(new DexoptOptions(packageName, targetCompilerFilter,
+ splitName, flags));
}
/**
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 9765113..6d6611f 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -365,6 +365,7 @@
String compilationReason = null;
String checkProfilesRaw = null;
boolean secondaryDex = false;
+ String split = null;
String opt;
while ((opt = getNextOption()) != null) {
@@ -395,6 +396,9 @@
case "--secondary-dex":
secondaryDex = true;
break;
+ case "--split":
+ split = getNextArgRequired();
+ break;
default:
pw.println("Error: Unknown option: " + opt);
return 1;
@@ -423,6 +427,16 @@
return 1;
}
+ if (allPackages && split != null) {
+ pw.println("-a cannot be specified together with --split");
+ return 1;
+ }
+
+ if (secondaryDex && split != null) {
+ pw.println("--secondary-dex cannot be specified together with --split");
+ return 1;
+ }
+
String targetCompilerFilter;
if (compilerFilter != null) {
if (!DexFile.isValidCompilerFilter(compilerFilter)) {
@@ -472,7 +486,7 @@
targetCompilerFilter, forceCompilation)
: mInterface.performDexOptMode(packageName,
checkProfiles, targetCompilerFilter, forceCompilation,
- true /* bootComplete */);
+ true /* bootComplete */, split);
if (!result) {
failedPackages.add(packageName);
}
@@ -1609,7 +1623,7 @@
pw.println(" help");
pw.println(" Print this help text.");
pw.println("");
- pw.println(" compile [-m MODE | -r REASON] [-f] [-c]");
+ pw.println(" compile [-m MODE | -r REASON] [-f] [-c] [--split SPLIT_NAME]");
pw.println(" [--reset] [--check-prof (true | false)] (-a | TARGET-PACKAGE)");
pw.println(" Trigger compilation of TARGET-PACKAGE or all packages if \"-a\".");
pw.println(" Options:");
@@ -1635,6 +1649,7 @@
pw.println(" --reset: restore package to its post-install state");
pw.println(" --check-prof (true | false): look at profiles when doing dexopt?");
pw.println(" --secondary-dex: compile app secondary dex files");
+ pw.println(" --split SPLIT: compile only the given split name");
pw.println(" bg-dexopt-job");
pw.println(" Execute the background optimizations immediately.");
pw.println(" Note that the command only runs the background optimizer logic. It may");
diff --git a/services/core/java/com/android/server/pm/dex/DexoptOptions.java b/services/core/java/com/android/server/pm/dex/DexoptOptions.java
index f6f261c..f57cf5e 100644
--- a/services/core/java/com/android/server/pm/dex/DexoptOptions.java
+++ b/services/core/java/com/android/server/pm/dex/DexoptOptions.java
@@ -18,6 +18,8 @@
import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason;
+import android.annotation.Nullable;
+
/**
* Options used for dexopt invocations.
*/
@@ -58,7 +60,19 @@
// The set of flags for the dexopt options. It's a mix of the DEXOPT_* flags.
private final int mFlags;
+ // When not null, dexopt will optimize only the split identified by this name.
+ // It only applies for primary apk and it's always null if mOnlySecondaryDex is true.
+ private final String mSplitName;
+
public DexoptOptions(String packageName, String compilerFilter, int flags) {
+ this(packageName, compilerFilter, /*splitName*/ null, flags);
+ }
+
+ public DexoptOptions(String packageName, int compilerReason, int flags) {
+ this(packageName, getCompilerFilterForReason(compilerReason), flags);
+ }
+
+ public DexoptOptions(String packageName, String compilerFilter, String splitName, int flags) {
int validityMask =
DEXOPT_CHECK_FOR_PROFILES_UPDATES |
DEXOPT_FORCE |
@@ -73,10 +87,7 @@
mPackageName = packageName;
mCompilerFilter = compilerFilter;
mFlags = flags;
- }
-
- public DexoptOptions(String packageName, int compilerReason, int flags) {
- this(packageName, getCompilerFilterForReason(compilerReason), flags);
+ mSplitName = splitName;
}
public String getPackageName() {
@@ -110,4 +121,8 @@
public boolean isDowngrade() {
return (mFlags & DEXOPT_DOWNGRADE) != 0;
}
+
+ public String getSplitName() {
+ return mSplitName;
+ }
}