diff options
6 files changed, 68 insertions, 9 deletions
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index 3fc95c669622..64d687e9d3de 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -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 diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java index 406466507606..b00b374fa1b1 100644 --- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java +++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java @@ -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]; diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 0b126a4d87d9..6b8a41536487 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -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)); } /** diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java index 20d7b28c55e1..10ceba418f22 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 @@ 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"); 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 f6f261c36d5f..f57cf5e2b999 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 @@ 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; + } } diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/DexoptOptionsTests.java b/services/tests/servicestests/src/com/android/server/pm/dex/DexoptOptionsTests.java index 2c684b96cc2a..1eb5552d533f 100644 --- a/services/tests/servicestests/src/com/android/server/pm/dex/DexoptOptionsTests.java +++ b/services/tests/servicestests/src/com/android/server/pm/dex/DexoptOptionsTests.java @@ -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()); @@ -102,6 +106,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; try { |