Created
November 22, 2019 19:54
-
-
Save benjaminRomano/2df1a1c2bd47ae55317066f44364a4c6 to your computer and use it in GitHub Desktop.
Getting App Size per module using Bundletool
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/main/java/com/android/tools/build/bundletool/commands/GetSizeCommand.java b/src/main/java/com/android/tools/build/bundletool/commands/GetSizeCommand.java | |
index 80ca234..438bb5b 100755 | |
--- a/src/main/java/com/android/tools/build/bundletool/commands/GetSizeCommand.java | |
+++ b/src/main/java/com/android/tools/build/bundletool/commands/GetSizeCommand.java | |
@@ -96,6 +96,7 @@ public abstract class GetSizeCommand implements GetSizeRequest { | |
private static final Flag<Path> DEVICE_SPEC_FLAG = Flag.path("device-spec"); | |
private static final Flag<ImmutableSet<String>> MODULES_FLAG = Flag.stringSet("modules"); | |
private static final Flag<Boolean> INSTANT_FLAG = Flag.booleanFlag("instant"); | |
+ private static final Flag<Boolean> EXACT_FLAG = Flag.booleanFlag("exact"); | |
private static final Flag<ImmutableSet<Dimension>> DIMENSIONS_FLAG = | |
Flag.enumSet("dimensions", Dimension.class); | |
private static final Joiner COMMA_JOINER = Joiner.on(','); | |
@@ -121,10 +122,15 @@ public abstract class GetSizeCommand implements GetSizeRequest { | |
@Override | |
public abstract boolean getInstant(); | |
+ /** Gets whether only explicit modules should used for size calculation */ | |
+ @Override | |
+ public abstract boolean getExact(); | |
+ | |
public static Builder builder() { | |
return new AutoValue_GetSizeCommand.Builder() | |
.setDeviceSpec(DeviceSpec.getDefaultInstance()) | |
.setInstant(false) | |
+ .setExact(false) | |
.setDimensions(ImmutableSet.of()); | |
} | |
@@ -151,6 +157,14 @@ public abstract class GetSizeCommand implements GetSizeRequest { | |
*/ | |
public abstract Builder setInstant(boolean instant); | |
+ /** | |
+ * Sets whether to only use modules explicitly specified in app size calculation | |
+ * | |
+ * <p>The default is {@code false}. If this is set to {@code true}, only the modules | |
+ * specified by modules flag be used in size calculation | |
+ */ | |
+ public abstract Builder setExact(boolean exact); | |
+ | |
/** Sets the sub-command of the get-size command, e.g. total. */ | |
public abstract Builder setGetSizeSubCommand(GetSizeSubcommand getSizeSubcommand); | |
@@ -162,6 +176,7 @@ public abstract class GetSizeCommand implements GetSizeRequest { | |
Optional<Path> deviceSpecPath = DEVICE_SPEC_FLAG.getValue(flags); | |
Optional<ImmutableSet<String>> modules = MODULES_FLAG.getValue(flags); | |
Optional<Boolean> instant = INSTANT_FLAG.getValue(flags); | |
+ Optional<Boolean> exact = EXACT_FLAG.getValue(flags); | |
ImmutableSet<Dimension> dimensions = DIMENSIONS_FLAG.getValue(flags).orElse(ImmutableSet.of()); | |
flags.checkNoUnknownFlags(); | |
@@ -183,6 +198,8 @@ public abstract class GetSizeCommand implements GetSizeRequest { | |
instant.ifPresent(command::setInstant); | |
+ exact.ifPresent(command::setExact); | |
+ | |
if (dimensions.contains(Dimension.ALL)) { | |
dimensions = SUPPORTED_DIMENSIONS; | |
} | |
@@ -305,6 +322,14 @@ public abstract class GetSizeCommand implements GetSizeRequest { | |
"When set, APKs of the instant modules will be considered instead of the " | |
+ "installable APKs. Defaults to false.") | |
.build()) | |
+ .addFlag( | |
+ FlagDescription.builder() | |
+ .setFlagName(EXACT_FLAG.getName()) | |
+ .setOptional(true) | |
+ .setDescription( | |
+ "When set, only APKs with modules explicitly defined will" + | |
+ "be considered for size calculation. Defaults to false.") | |
+ .build()) | |
.build(); | |
} | |
diff --git a/src/main/java/com/android/tools/build/bundletool/device/ApkMatcher.java b/src/main/java/com/android/tools/build/bundletool/device/ApkMatcher.java | |
index aa7c58a..afc83f8 100755 | |
--- a/src/main/java/com/android/tools/build/bundletool/device/ApkMatcher.java | |
+++ b/src/main/java/com/android/tools/build/bundletool/device/ApkMatcher.java | |
@@ -54,8 +54,21 @@ public class ApkMatcher { | |
private final ModuleMatcher moduleMatcher; | |
private final VariantMatcher variantMatcher; | |
+ /** | |
+ * Only include modules explicitly specified by requestedModuleNames | |
+ */ | |
+ private final boolean exact; | |
+ | |
public ApkMatcher(DeviceSpec deviceSpec) { | |
- this(deviceSpec, Optional.empty(), /* matchInstant= */ false); | |
+ this(deviceSpec, Optional.empty(), /* matchInstant= */ false, false); | |
+ } | |
+ | |
+ public ApkMatcher( | |
+ DeviceSpec deviceSpec, | |
+ Optional<ImmutableSet<String>> requestedModuleNames, | |
+ boolean matchInstant | |
+ ) { | |
+ this(deviceSpec, requestedModuleNames, matchInstant, false); | |
} | |
/** | |
@@ -65,10 +78,14 @@ public class ApkMatcher { | |
public ApkMatcher( | |
DeviceSpec deviceSpec, | |
Optional<ImmutableSet<String>> requestedModuleNames, | |
- boolean matchInstant) { | |
+ boolean matchInstant, | |
+ boolean exact) { | |
checkArgument( | |
!requestedModuleNames.isPresent() || !requestedModuleNames.get().isEmpty(), | |
"Set of requested split modules cannot be empty."); | |
+ checkArgument( | |
+ !exact || requestedModuleNames.isPresent(), | |
+ "Exact mode requires providing one or more module names"); | |
SdkVersionMatcher sdkVersionMatcher = new SdkVersionMatcher(deviceSpec); | |
AbiMatcher abiMatcher = new AbiMatcher(deviceSpec); | |
MultiAbiMatcher multiAbiMatcher = new MultiAbiMatcher(deviceSpec); | |
@@ -81,6 +98,7 @@ public class ApkMatcher { | |
sdkVersionMatcher, abiMatcher, multiAbiMatcher, screenDensityMatcher, languageMatcher); | |
this.requestedModuleNames = requestedModuleNames; | |
this.matchInstant = matchInstant; | |
+ this.exact = exact; | |
this.moduleMatcher = new ModuleMatcher(sdkVersionMatcher, deviceFeatureMatcher); | |
this.variantMatcher = | |
new VariantMatcher( | |
@@ -137,7 +155,9 @@ public class ApkMatcher { | |
addModuleDependencies(requestedModuleName, moduleDependenciesMap, dependencyModules); | |
} | |
- if (matchInstant) { | |
+ if (exact) { | |
+ return requestedModuleNames.get()::contains; | |
+ } else if (matchInstant) { | |
return dependencyModules::contains; | |
} else { | |
return Predicates.or( | |
diff --git a/src/main/java/com/android/tools/build/bundletool/device/VariantTotalSizeAggregator.java b/src/main/java/com/android/tools/build/bundletool/device/VariantTotalSizeAggregator.java | |
index a68dfb4..c6d5df6 100755 | |
--- a/src/main/java/com/android/tools/build/bundletool/device/VariantTotalSizeAggregator.java | |
+++ b/src/main/java/com/android/tools/build/bundletool/device/VariantTotalSizeAggregator.java | |
@@ -224,7 +224,8 @@ public class VariantTotalSizeAggregator { | |
screenDensityTargeting, | |
languageTargeting), | |
getSizeRequest.getModules(), | |
- getSizeRequest.getInstant()) | |
+ getSizeRequest.getInstant(), | |
+ getSizeRequest.getExact()) | |
.getMatchingApksFromVariant(variant, bundleVersion)); | |
minSizeByConfiguration.merge(configuration, compressedSize, Math::min); | |
diff --git a/src/main/java/com/android/tools/build/bundletool/model/GetSizeRequest.java b/src/main/java/com/android/tools/build/bundletool/model/GetSizeRequest.java | |
index 7567ce4..fc7a493 100755 | |
--- a/src/main/java/com/android/tools/build/bundletool/model/GetSizeRequest.java | |
+++ b/src/main/java/com/android/tools/build/bundletool/model/GetSizeRequest.java | |
@@ -40,4 +40,7 @@ public interface GetSizeRequest { | |
/** Gets whether instant APKs should be used for size calculation. */ | |
boolean getInstant(); | |
+ | |
+ /** Gets whether only explicit modules should used for size calculation */ | |
+ boolean getExact(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
With this patch, it is now possible to request app size for specific module(s) using the
--exact
flag:bundletool get-size total --apks=output.apks --modules=my_feature --exact --dimensions=ALL