Skip to content

Commit

Permalink
Prepare for release 0.11.0.
Browse files Browse the repository at this point in the history
  • Loading branch information
plecesne committed Nov 7, 2019
1 parent 131c1fb commit 1c41e70
Show file tree
Hide file tree
Showing 107 changed files with 4,378 additions and 712 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ https://developer.android.com/studio/command-line/bundletool

## Releases

Latest release: [0.10.3](https://github.com/google/bundletool/releases)
Latest release: [0.11.0](https://github.com/google/bundletool/releases)
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
release_version = 0.10.3
release_version = 0.11.0
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,11 @@
import com.android.tools.build.bundletool.model.utils.SystemEnvironmentProvider;
import com.android.tools.build.bundletool.splitters.DexCompressionSplitter;
import com.android.tools.build.bundletool.splitters.NativeLibrariesCompressionSplitter;
import com.android.tools.build.bundletool.validation.SubValidator;
import com.google.auto.value.AutoValue;
import com.google.common.base.Ascii;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.io.MoreFiles;
import com.google.common.util.concurrent.ListeningExecutorService;
Expand Down Expand Up @@ -167,6 +169,8 @@ ListeningExecutorService getExecutorService() {

public abstract Optional<ApkModifier> getApkModifier();

public abstract ImmutableList<SubValidator> getExtraValidators();

public abstract Optional<Integer> getFirstVariantNumber();

public abstract Optional<PrintStream> getOutputPrintStream();
Expand All @@ -178,7 +182,8 @@ public static Builder builder() {
.setGenerateOnlyForConnectedDevice(false)
.setCreateApkSetArchive(true)
.setOptimizationDimensions(ImmutableSet.of())
.setModules(ImmutableSet.of());
.setModules(ImmutableSet.of())
.setExtraValidators(ImmutableList.of());
}

/** Builder for the {@link BuildApksCommand}. */
Expand Down Expand Up @@ -297,6 +302,9 @@ public Builder setExecutorService(ListeningExecutorService executorService) {
*/
public abstract Builder setApkModifier(ApkModifier apkModifier);

/** Provides additional {@link SubValidator}s that will be invoked during validation. */
public abstract Builder setExtraValidators(ImmutableList<SubValidator> extraValidators);

/**
* Provides the lowest variant number to use.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

import com.android.bundle.Config.BundleConfig;
import com.android.bundle.Config.Compression;
import com.android.bundle.Config.SuffixStripping;
import com.android.bundle.Devices.DeviceSpec;
import com.android.tools.build.bundletool.commands.BuildApksCommand.ApkBuildMode;
import com.android.tools.build.bundletool.device.AdbServer;
Expand All @@ -43,10 +44,12 @@
import com.android.tools.build.bundletool.model.ApkModifier;
import com.android.tools.build.bundletool.model.AppBundle;
import com.android.tools.build.bundletool.model.BundleModule;
import com.android.tools.build.bundletool.model.BundleModule.ModuleDeliveryType;
import com.android.tools.build.bundletool.model.BundleModuleName;
import com.android.tools.build.bundletool.model.GeneratedApks;
import com.android.tools.build.bundletool.model.GeneratedAssetSlices;
import com.android.tools.build.bundletool.model.ModuleSplit;
import com.android.tools.build.bundletool.model.OptimizationDimension;
import com.android.tools.build.bundletool.model.SigningConfiguration;
import com.android.tools.build.bundletool.model.exceptions.CommandExecutionException;
import com.android.tools.build.bundletool.model.targeting.AlternativeVariantTargetingPopulator;
Expand All @@ -57,20 +60,23 @@
import com.android.tools.build.bundletool.model.version.Version;
import com.android.tools.build.bundletool.optimizations.ApkOptimizations;
import com.android.tools.build.bundletool.optimizations.OptimizationsMerger;
import com.android.tools.build.bundletool.preprocessors.AppBundle64BitNativeLibrariesPreprocessor;
import com.android.tools.build.bundletool.splitters.ApkGenerationConfiguration;
import com.android.tools.build.bundletool.splitters.AssetSlicesGenerator;
import com.android.tools.build.bundletool.splitters.ResourceAnalyzer;
import com.android.tools.build.bundletool.splitters.ShardedApksGenerator;
import com.android.tools.build.bundletool.splitters.SplitApksGenerator;
import com.android.tools.build.bundletool.validation.AppBundleValidator;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Optional;
import java.util.logging.Logger;
import java.util.stream.Stream;
import java.util.zip.ZipFile;

/** Executes the "build-apks" command. */
Expand Down Expand Up @@ -124,18 +130,15 @@ public Path execute() {

private void executeWithZip(ZipFile bundleZip, Optional<DeviceSpec> deviceSpec)
throws IOException {
AppBundleValidator bundleValidator = new AppBundleValidator();
AppBundleValidator bundleValidator = AppBundleValidator.create(command.getExtraValidators());

bundleValidator.validateFile(bundleZip);
AppBundle appBundle = AppBundle.buildFromZip(bundleZip);
bundleValidator.validate(appBundle);

if (appBundle.has32BitRenderscriptCode()) {
printWarning(
"App Bundle contains 32-bit RenderScript bitcode file (.bc) which disables 64-bit "
+ "support in Android. 64-bit native libraries won't be included in generated "
+ "APKs.");
}
appBundle =
new AppBundle64BitNativeLibrariesPreprocessor(command.getOutputPrintStream())
.preprocess(appBundle);

ImmutableSet<BundleModule> requestedModules =
command.getModules().isEmpty()
Expand Down Expand Up @@ -175,7 +178,10 @@ private void executeWithZip(ZipFile bundleZip, Optional<DeviceSpec> deviceSpec)
? modulesToFuse(appBundle.getFeatureModules().values().asList())
: requestedModules.asList();
generatedApksBuilder.setStandaloneApks(
new ShardedApksGenerator(tempDir, bundleVersion)
new ShardedApksGenerator(
tempDir,
bundleVersion,
getSuffixStrippings(bundleConfig))
.generateSplits(
modulesToFuse,
appBundle.getBundleMetadata(),
Expand Down Expand Up @@ -236,24 +242,25 @@ private void executeWithZip(ZipFile bundleZip, Optional<DeviceSpec> deviceSpec)
}

private ImmutableList<ModuleSplit> generateStandaloneApks(Path tempDir, AppBundle appBundle) {
ImmutableList<BundleModule> allFeatureModules = appBundle.getFeatureModules().values().asList();
ImmutableList<BundleModule> allModules = getModulesForStandaloneApks(appBundle);
Version bundleVersion = Version.of(appBundle.getBundleConfig().getBundletool().getVersion());
ShardedApksGenerator shardedApksGenerator =
new ShardedApksGenerator(
tempDir,
bundleVersion,
/* generate64BitShards= */ !appBundle.has32BitRenderscriptCode());
shouldStrip64BitLibrariesFromShards(appBundle),
getSuffixStrippings(appBundle.getBundleConfig()));
return appBundle.isApex()
? shardedApksGenerator.generateApexSplits(modulesToFuse(allFeatureModules))
? shardedApksGenerator.generateApexSplits(modulesToFuse(allModules))
: shardedApksGenerator.generateSplits(
modulesToFuse(allFeatureModules),
modulesToFuse(allModules),
appBundle.getBundleMetadata(),
getApkOptimizations(appBundle.getBundleConfig()));
}

private ImmutableList<ModuleSplit> generateAssetSlices(AppBundle appBundle) {
ApkGenerationConfiguration assetSlicesGenerationConfiguration =
getAssetSliceGenerationConfiguration();
getAssetSliceGenerationConfiguration(appBundle.getBundleConfig());
AssetSlicesGenerator assetSlicesGenerator =
new AssetSlicesGenerator(appBundle, assetSlicesGenerationConfiguration);
return assetSlicesGenerator.generateAssetSlices();
Expand Down Expand Up @@ -304,7 +311,8 @@ private ImmutableList<ModuleSplit> generateSystemApks(
return new ShardedApksGenerator(
tempDir,
bundleVersion,
/* generate64BitShards= */ !appBundle.has32BitRenderscriptCode())
shouldStrip64BitLibrariesFromShards(appBundle),
getSuffixStrippings(appBundle.getBundleConfig()))
.generateSystemSplits(
/* modules= */ featureModules,
/* modulesToFuse= */ modulesToFuse.stream()
Expand All @@ -321,10 +329,6 @@ private static void checkDeviceCompatibilityWithBundle(
generatedApks.getAllApksStream().forEach(apkMatcher::checkCompatibleWithApkTargeting);
}

private void printWarning(String message) {
command.getOutputPrintStream().ifPresent(out -> out.println("WARNING: " + message));
}

private DeviceSpec getDeviceSpecFromConnectedDevice() {
AdbServer adbServer = command.getAdbServer().get();
adbServer.init(command.getAdbPath().get());
Expand Down Expand Up @@ -380,27 +384,33 @@ private ApkGenerationConfiguration.Builder getCommonSplitApkGenerationConfigurat
installLocation.equals("auto") || installLocation.equals("preferExternal"))
.orElse(false));

if (appBundle.has32BitRenderscriptCode()) {
apkGenerationConfiguration.setInclude64BitLibs(false);
}

apkGenerationConfiguration.setMasterPinnedResources(appBundle.getMasterPinnedResources());

apkGenerationConfiguration.setSuffixStrippings(getSuffixStrippings(bundleConfig));

return apkGenerationConfiguration;
}

private ApkGenerationConfiguration getAssetSliceGenerationConfiguration() {
private static ApkGenerationConfiguration getAssetSliceGenerationConfiguration(
BundleConfig bundleConfig) {
ApkOptimizations apkOptimizations = ApkOptimizations.getOptimizationsForAssetSlices();

return ApkGenerationConfiguration.builder()
.setOptimizationDimensions(apkOptimizations.getSplitDimensions())
.setSuffixStrippings(getSuffixStrippings(bundleConfig))
.build();
}

private static ImmutableList<BundleModule> modulesToFuse(ImmutableList<BundleModule> modules) {
return modules.stream().filter(BundleModule::isIncludedInFusing).collect(toImmutableList());
}

private static ImmutableMap<OptimizationDimension, SuffixStripping> getSuffixStrippings(
BundleConfig bundleConfig) {
return OptimizationsMerger.getSuffixStrippings(
bundleConfig.getOptimizations().getSplitsConfig().getSplitDimensionList());
}

private ApkOptimizations getApkOptimizations(BundleConfig bundleConfig) {
return new OptimizationsMerger()
.mergeWithDefaults(bundleConfig, command.getOptimizationDimensions());
Expand Down Expand Up @@ -445,6 +455,24 @@ private static ImmutableList<BundleModule> getBundleModules(
.collect(toImmutableList());
}

private static ImmutableList<BundleModule> getModulesForStandaloneApks(AppBundle appBundle) {
return Stream.concat(
appBundle.getFeatureModules().values().stream(),
appBundle.getAssetModules().values().stream()
.filter(
module ->
module.getDeliveryType().equals(ModuleDeliveryType.ALWAYS_INITIAL_INSTALL)))
.collect(toImmutableList());
}

private static boolean shouldStrip64BitLibrariesFromShards(AppBundle appBundle) {
return appBundle
.getBundleConfig()
.getOptimizations()
.getStandaloneConfig()
.getStrip64BitLibraries();
}

private static class ApksToGenerate {
private final AppBundle appBundle;
private final ApkBuildMode apkBuildMode;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public void execute() throws CommandExecutionException {
validateInput();

try (ZipFile bundleZip = new ZipFile(getBundlePath().toFile())) {
AppBundleValidator bundleValidator = new AppBundleValidator();
AppBundleValidator bundleValidator = AppBundleValidator.create();

bundleValidator.validateFile(bundleZip);
AppBundle appBundle = AppBundle.buildFromZip(bundleZip);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,28 +66,28 @@ public void processNewLines(String[] strings) {
} catch (IOException e) {
throw CommandExecutionException.builder()
.withMessage(
"I/O error while executing adb shell '%s' on device '%s'.",
"I/O error while executing 'adb shell %s' on device '%s'.",
command, device.getSerialNumber())
.withCause(e)
.build();
} catch (TimeoutException e) {
throw CommandExecutionException.builder()
.withMessage(
"Timeout while executing adb shell '%s' on device '%s'.",
"Timeout while executing 'adb shell %s' on device '%s'.",
command, device.getSerialNumber())
.withCause(e)
.build();
} catch (ShellCommandUnresponsiveException e) {
throw CommandExecutionException.builder()
.withMessage(
"Unresponsive shell command while executing adb shell '%s' on device '%s'.",
"Unresponsive shell command while executing 'adb shell %s' on device '%s'.",
command, device.getSerialNumber())
.withCause(e)
.build();
} catch (AdbCommandRejectedException e) {
throw CommandExecutionException.builder()
.withMessage(
"Rejected adb shell command '%s' on device '%s'.", command, device.getSerialNumber())
"Rejected 'adb shell %s' command on device '%s'.", command, device.getSerialNumber())
.withCause(e)
.build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,16 +77,28 @@ public ApkMatcher(
ScreenDensityMatcher screenDensityMatcher = new ScreenDensityMatcher(deviceSpec);
LanguageMatcher languageMatcher = new LanguageMatcher(deviceSpec);
DeviceFeatureMatcher deviceFeatureMatcher = new DeviceFeatureMatcher(deviceSpec);
TextureCompressionFormatMatcher textureCompressionFormatMatcher =
new TextureCompressionFormatMatcher(deviceSpec);

this.apkMatchers =
ImmutableList.of(
sdkVersionMatcher, abiMatcher, multiAbiMatcher, screenDensityMatcher, languageMatcher);
sdkVersionMatcher,
abiMatcher,
multiAbiMatcher,
screenDensityMatcher,
languageMatcher,
textureCompressionFormatMatcher);
this.requestedModuleNames = requestedModuleNames;
this.matchInstant = matchInstant;
this.moduleMatcher = new ModuleMatcher(sdkVersionMatcher, deviceFeatureMatcher);
this.variantMatcher =
new VariantMatcher(
sdkVersionMatcher, abiMatcher, multiAbiMatcher, screenDensityMatcher, matchInstant);
sdkVersionMatcher,
abiMatcher,
multiAbiMatcher,
screenDensityMatcher,
textureCompressionFormatMatcher,
matchInstant);
}

/**
Expand Down Expand Up @@ -276,8 +288,6 @@ private ImmutableList<ZipPath> getMatchingApksFromAssetModules(BuildApksResult b
for (ApkDescription apkDescription : sliceSet.getApkDescriptionList()) {
ApkTargeting apkTargeting = apkDescription.getTargeting();

checkCompatibleWithApkTargeting(apkTargeting);

if (matchesApk(apkTargeting, /*isSplit=*/ true, moduleName, assetModuleNameMatcher)) {
matchedApksBuilder.add(ZipPath.create(apkDescription.getPath()));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,10 @@ public class DdmlibDevice extends Device {
private final IDevice device;
private static final int ADB_TIMEOUT_MS = 60000;
private static final String DEVICE_FEATURES_COMMAND = "pm list features";
private static final String GL_EXTENSIONS_COMMAND = "dumpsys SurfaceFlinger";

private final DeviceFeaturesParser deviceFeaturesParser = new DeviceFeaturesParser();
private final GlExtensionsParser glExtensionsParser = new GlExtensionsParser();

public DdmlibDevice(IDevice device) {
this.device = device;
Expand Down Expand Up @@ -85,6 +87,13 @@ public ImmutableList<String> getDeviceFeatures() {
.execute(ADB_TIMEOUT_MS, TimeUnit.MILLISECONDS));
}

@Override
public ImmutableList<String> getGlExtensions() {
return glExtensionsParser.parse(
new AdbShellCommandTask(this, GL_EXTENSIONS_COMMAND)
.execute(ADB_TIMEOUT_MS, TimeUnit.MILLISECONDS));
}

@Override
public void executeShellCommand(
String command,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ public abstract class Device {

public abstract ImmutableList<String> getDeviceFeatures();

public abstract ImmutableList<String> getGlExtensions();

public abstract void executeShellCommand(
String command,
IShellOutputReceiver receiver,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ public DeviceSpec getDeviceSpec(Optional<String> deviceId) {
int deviceDensity = device.getDensity();
checkState(deviceDensity > 0, "Error retrieving device density. Please try again.");
ImmutableList<String> deviceFeatures = device.getDeviceFeatures();
ImmutableList<String> glExtensions = device.getGlExtensions();

ActivityManagerRunner activityManagerRunner = new ActivityManagerRunner(device);
ImmutableList<String> deviceLocales = activityManagerRunner.getDeviceLocales();
Expand All @@ -78,6 +79,7 @@ public DeviceSpec getDeviceSpec(Optional<String> deviceId) {
.addAllSupportedLocales(deviceLocales)
.setScreenDensity(deviceDensity)
.addAllDeviceFeatures(deviceFeatures)
.addAllGlExtensions(glExtensions)
.build();
} catch (TimeoutException e) {
throw CommandExecutionException.builder()
Expand Down
Loading

0 comments on commit 1c41e70

Please sign in to comment.