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
(cherry picked from commit b6f844d28c)
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
Merged-In: I579bb12fa6699f99cd3824f185bd9352fb8007c5
Change-Id: I579bb12fa6699f99cd3824f185bd9352fb8007c5
This commit is contained in:
committed by
Andreas Gampe
parent
dea3fd8cf1
commit
caed6000be
@@ -514,7 +514,7 @@ interface IPackageManager {
|
||||
* definite state.
|
||||
*/
|
||||
boolean performDexOptMode(String packageName, boolean checkProfiles,
|
||||
String targetCompilerFilter, boolean force, boolean bootComplete);
|
||||
String targetCompilerFilter, boolean force, boolean bootComplete, String splitName);
|
||||
|
||||
/**
|
||||
* Ask the package manager to perform a dex-opt with the given compiler filter on the
|
||||
|
||||
@@ -173,6 +173,14 @@ public class PackageDexOptimizer {
|
||||
}
|
||||
// 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];
|
||||
|
||||
@@ -9506,11 +9506,12 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
@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));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -365,6 +365,7 @@ class PackageManagerShellCommand extends ShellCommand {
|
||||
String compilationReason = null;
|
||||
String checkProfilesRaw = null;
|
||||
boolean secondaryDex = false;
|
||||
String split = null;
|
||||
|
||||
String opt;
|
||||
while ((opt = getNextOption()) != null) {
|
||||
@@ -395,6 +396,9 @@ class PackageManagerShellCommand extends ShellCommand {
|
||||
case "--secondary-dex":
|
||||
secondaryDex = true;
|
||||
break;
|
||||
case "--split":
|
||||
split = getNextArgRequired();
|
||||
break;
|
||||
default:
|
||||
pw.println("Error: Unknown option: " + opt);
|
||||
return 1;
|
||||
@@ -423,6 +427,16 @@ class PackageManagerShellCommand extends ShellCommand {
|
||||
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 @@ class PackageManagerShellCommand extends ShellCommand {
|
||||
targetCompilerFilter, forceCompilation)
|
||||
: mInterface.performDexOptMode(packageName,
|
||||
checkProfiles, targetCompilerFilter, forceCompilation,
|
||||
true /* bootComplete */);
|
||||
true /* bootComplete */, split);
|
||||
if (!result) {
|
||||
failedPackages.add(packageName);
|
||||
}
|
||||
@@ -1609,7 +1623,7 @@ class PackageManagerShellCommand extends ShellCommand {
|
||||
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 @@ class PackageManagerShellCommand extends ShellCommand {
|
||||
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");
|
||||
|
||||
@@ -18,6 +18,8 @@ package com.android.server.pm.dex;
|
||||
|
||||
import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Options used for dexopt invocations.
|
||||
*/
|
||||
@@ -58,7 +60,19 @@ public final class DexoptOptions {
|
||||
// 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 @@ public final class DexoptOptions {
|
||||
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 final class DexoptOptions {
|
||||
public boolean isDowngrade() {
|
||||
return (mFlags & DEXOPT_DOWNGRADE) != 0;
|
||||
}
|
||||
|
||||
public String getSplitName() {
|
||||
return mSplitName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,12 +38,14 @@ public class DexoptOptionsTests {
|
||||
private final static String mPackageName = "test.android.com";
|
||||
private final static String mCompilerFilter =
|
||||
PackageManagerServiceCompilerMapping.getDefaultCompilerFilter();
|
||||
private final static String mSplitName = "split-A.apk";
|
||||
|
||||
@Test
|
||||
public void testCreateDexoptOptionsEmpty() {
|
||||
DexoptOptions opt = new DexoptOptions(mPackageName, mCompilerFilter, /*flags*/ 0);
|
||||
assertEquals(mPackageName, opt.getPackageName());
|
||||
assertEquals(mCompilerFilter, opt.getCompilerFilter());
|
||||
assertEquals(null, opt.getSplitName());
|
||||
assertFalse(opt.isBootComplete());
|
||||
assertFalse(opt.isCheckForProfileUpdates());
|
||||
assertFalse(opt.isDexoptOnlySecondaryDex());
|
||||
@@ -65,6 +67,7 @@ public class DexoptOptionsTests {
|
||||
DexoptOptions opt = new DexoptOptions(mPackageName, mCompilerFilter, flags);
|
||||
assertEquals(mPackageName, opt.getPackageName());
|
||||
assertEquals(mCompilerFilter, opt.getCompilerFilter());
|
||||
assertEquals(null, opt.getSplitName());
|
||||
assertTrue(opt.isBootComplete());
|
||||
assertTrue(opt.isCheckForProfileUpdates());
|
||||
assertTrue(opt.isDexoptOnlySecondaryDex());
|
||||
@@ -92,6 +95,7 @@ public class DexoptOptionsTests {
|
||||
DexoptOptions opt = new DexoptOptions(mPackageName, reason, flags);
|
||||
assertEquals(mPackageName, opt.getPackageName());
|
||||
assertEquals(getCompilerFilterForReason(reason), opt.getCompilerFilter());
|
||||
assertEquals(null, opt.getSplitName());
|
||||
assertTrue(opt.isBootComplete());
|
||||
assertTrue(opt.isCheckForProfileUpdates());
|
||||
assertFalse(opt.isDexoptOnlySecondaryDex());
|
||||
@@ -101,6 +105,22 @@ public class DexoptOptionsTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateDexoptOptionsSplit() {
|
||||
int flags = DexoptOptions.DEXOPT_FORCE | DexoptOptions.DEXOPT_BOOT_COMPLETE;
|
||||
|
||||
DexoptOptions opt = new DexoptOptions(mPackageName, mCompilerFilter, mSplitName, flags);
|
||||
assertEquals(mPackageName, opt.getPackageName());
|
||||
assertEquals(mCompilerFilter, opt.getCompilerFilter());
|
||||
assertEquals(mSplitName, opt.getSplitName());
|
||||
assertTrue(opt.isBootComplete());
|
||||
assertFalse(opt.isCheckForProfileUpdates());
|
||||
assertFalse(opt.isDexoptOnlySecondaryDex());
|
||||
assertFalse(opt.isDexoptOnlySharedDex());
|
||||
assertFalse(opt.isDowngrade());
|
||||
assertTrue(opt.isForce());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateDexoptInvalid() {
|
||||
boolean gotException = false;
|
||||
|
||||
Reference in New Issue
Block a user