Skip to content

Commit

Permalink
Prepare for release 1.17.0.
Browse files Browse the repository at this point in the history
  • Loading branch information
sopo-c committed Jun 27, 2024
1 parent 9a4a1c9 commit 3f4ef99
Show file tree
Hide file tree
Showing 23 changed files with 489 additions and 37 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,4 @@ https://developer.android.com/studio/command-line/bundletool

## Releases

Latest release: [1.16.0](https://github.com/google/bundletool/releases)
Latest release: [1.17.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 = 1.16.0
release_version = 1.17.0
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ private void setEnableUncompressedDexOptimization(
uncompressedDexFiles.getUncompressedDexTargetSdk());
return;
}
// Otherwise we rely on default for bundletool version used to build this AAB:
// Depending on bundletool version used to build this AAB:
// * no uncompressed dex for bundletool < 1.12.0;
// * uncompressed dex for Android S+ for bundletool [1.12.0, 1.16.0);
// * uncompressed dex for Android Q+ for bundletool >= 1.16.0.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,10 @@ private static boolean devicePropertiesMatchDeviceTier(
private static boolean devicePropertiesMatchDeviceSelector(
DeviceProperties deviceProperties, DeviceSelector deviceSelector) {
return devicePropertiesMatchRamRule(deviceProperties, deviceSelector.getDeviceRam())
&& deviceIdInList(deviceProperties.getDeviceId(), deviceSelector.getIncludedDeviceIdsList())
&& !deviceSelector.getExcludedDeviceIdsList().contains(deviceProperties.getDeviceId())
&& deviceIdIncluded(
deviceProperties.getDeviceId(), deviceSelector.getIncludedDeviceIdsList())
&& !deviceIdExcluded(
deviceProperties.getDeviceId(), deviceSelector.getExcludedDeviceIdsList())
&& deviceProperties
.getSystemFeaturesList()
.containsAll(deviceSelector.getRequiredSystemFeaturesList())
Expand All @@ -135,13 +137,21 @@ private static boolean devicePropertiesMatchRamRule(
return minBytes <= deviceProperties.getRam() && deviceProperties.getRam() < maxBytes;
}

private static boolean deviceIdInList(DeviceId deviceId, List<DeviceId> deviceIdList) {
private static boolean deviceIdExcluded(DeviceId deviceId, List<DeviceId> deviceIdList) {
DeviceId deviceOnlyBrand =
DeviceId.newBuilder().setBuildBrand(deviceId.getBuildBrand()).build();
return deviceIdList.contains(deviceId) || deviceIdList.contains(deviceOnlyBrand);
}

private static boolean deviceIdIncluded(DeviceId deviceId, List<DeviceId> deviceIdList) {
// If the deviceIdList is empty, it means that the targeting configuration is not specifying any
// DeviceId in particular. This means that any DeviceId provided satisfies the
// included_device_ids rule in the DeviceSelector. Hence, we return true in this case.
if (deviceIdList.isEmpty()) {
return true;
}
return deviceIdList.contains(deviceId);
DeviceId deviceOnlyBrand =
DeviceId.newBuilder().setBuildBrand(deviceId.getBuildBrand()).build();
return deviceIdList.contains(deviceId) || deviceIdList.contains(deviceOnlyBrand);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
package com.android.tools.build.bundletool.io;

import static com.android.tools.build.bundletool.commands.BuildApksCommand.ApkBuildMode.SYSTEM;
import static com.android.tools.build.bundletool.model.AndroidManifest.MODULE_TYPE_AI_VALUE;
import static com.android.tools.build.bundletool.model.AndroidManifest.MODULE_TYPE_ASSET_VALUE;
import static com.android.tools.build.bundletool.model.BundleModule.DEX_DIRECTORY;
import static com.android.tools.build.bundletool.model.utils.CollectorUtils.groupingByDeterministic;
import static com.android.tools.build.bundletool.model.utils.CollectorUtils.groupingBySortedKeys;
Expand All @@ -31,6 +33,7 @@
import com.android.bundle.Commands.ApkDescription;
import com.android.bundle.Commands.ApkSet;
import com.android.bundle.Commands.AssetModuleMetadata;
import com.android.bundle.Commands.AssetModuleType;
import com.android.bundle.Commands.AssetModulesInfo;
import com.android.bundle.Commands.AssetSliceSet;
import com.android.bundle.Commands.BuildApksResult;
Expand Down Expand Up @@ -393,6 +396,11 @@ private AssetModuleMetadata getAssetModuleMetadata(BundleModule module) {
AndroidManifest manifest = module.getAndroidManifest();
AssetModuleMetadata.Builder metadataBuilder =
AssetModuleMetadata.newBuilder().setName(module.getName().getName());
metadataBuilder.setAssetModuleType(
manifest
.getOptionalModuleTypeAttributeValue()
.map(ApkSerializerManager::getAssetModuleType)
.orElse(AssetModuleType.UNKNOWN_ASSET_TYPE));
Optional<ManifestDeliveryElement> persistentDelivery = manifest.getManifestDeliveryElement();
metadataBuilder.setDeliveryType(
persistentDelivery
Expand All @@ -419,6 +427,17 @@ private AssetModuleMetadata getAssetModuleMetadata(BundleModule module) {
return metadataBuilder.build();
}

private static AssetModuleType getAssetModuleType(String value) {
switch (value) {
case MODULE_TYPE_ASSET_VALUE:
return AssetModuleType.DEFAULT_ASSET_TYPE;
case MODULE_TYPE_AI_VALUE:
return AssetModuleType.AI_PACK_TYPE;
default:
return AssetModuleType.UNKNOWN_ASSET_TYPE;
}
}

private static void validateInput(GeneratedApks generatedApks, ApkBuildMode apkBuildMode) {
switch (apkBuildMode) {
case DEFAULT:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

import static java.lang.annotation.RetentionPolicy.RUNTIME;

import com.android.bundle.Config.BundleConfig;
import com.android.tools.build.bundletool.optimizations.ApkOptimizations;
import dagger.Binds;
import dagger.Module;
import dagger.Provides;
Expand All @@ -33,8 +33,8 @@ public abstract class ApkSerializerModule {

@Provides
@NativeLibrariesAlignmentInBytes
static int provideNativeLibrariesAlignmentInBytes(BundleConfig bundleConfig) {
switch (bundleConfig.getOptimizations().getUncompressNativeLibraries().getAlignment()) {
static int provideNativeLibrariesAlignmentInBytes(ApkOptimizations apkOptimizations) {
switch (apkOptimizations.getPageAlignment()) {
case PAGE_ALIGNMENT_16K:
return 16384;
case PAGE_ALIGNMENT_64K:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,10 @@ public abstract class AndroidManifest {

public static final String MODULE_TYPE_FEATURE_VALUE = "feature";
public static final String MODULE_TYPE_ASSET_VALUE = "asset-pack";
// A feature module that contains ML models. This is the legacy way to package ML models.
public static final String MODULE_TYPE_ML_VALUE = "ml-pack";
// An asset pack that contains ML models. This is the preferred way to package ML models.
public static final String MODULE_TYPE_AI_VALUE = "ai-pack";
public static final String MODULE_TYPE_SDK_VALUE = "sdk";

/** <meta-data> name that specifies native library for native activity */
Expand Down Expand Up @@ -503,6 +506,7 @@ private static ModuleType getModuleTypeFromAttributeValue(String value) {
case MODULE_TYPE_FEATURE_VALUE:
return ModuleType.FEATURE_MODULE;
case MODULE_TYPE_ASSET_VALUE:
case MODULE_TYPE_AI_VALUE:
return ModuleType.ASSET_MODULE;
case MODULE_TYPE_ML_VALUE:
return ModuleType.ML_MODULE;
Expand All @@ -516,14 +520,17 @@ private static ModuleType getModuleTypeFromAttributeValue(String value) {
}

public Optional<ModuleType> getOptionalModuleType() {
Optional<String> typeAttributeValue =
getManifestElement()
.getOptionalChildElement(DISTRIBUTION_NAMESPACE_URI, "module")
.flatMap(module -> module.getAttribute(DISTRIBUTION_NAMESPACE_URI, "type"))
.map(XmlProtoAttribute::getValueAsString);
Optional<String> typeAttributeValue = getOptionalModuleTypeAttributeValue();
return typeAttributeValue.map(AndroidManifest::getModuleTypeFromAttributeValue);
}

public Optional<String> getOptionalModuleTypeAttributeValue() {
return getManifestElement()
.getOptionalChildElement(DISTRIBUTION_NAMESPACE_URI, "module")
.flatMap(module -> module.getAttribute(DISTRIBUTION_NAMESPACE_URI, "type"))
.map(XmlProtoAttribute::getValueAsString);
}

public ModuleType getModuleType() {
// If the module type is not defined in the manifest, default to feature module for backwards
// compatibility.
Expand Down Expand Up @@ -1111,12 +1118,14 @@ public ImmutableList<XmlProtoElement> getUsesSdkLibraryElements() {
return getApplicationElementChildElements(USES_SDK_LIBRARY_ELEMENT_NAME);
}

public ImmutableList<XmlProtoElement> getAllContentProviders() {
return getApplicationElementChildElements(PROVIDER_ELEMENT_NAME);
}

private ImmutableList<XmlProtoElement> getApplicationElementChildElements(
String childElementName) {
return getManifestRoot()
.getElement()
.getChildElement(APPLICATION_ELEMENT_NAME)
.getChildrenElements()
return stream(getManifestRoot().getElement().getOptionalChildElement(APPLICATION_ELEMENT_NAME))
.flatMap(app -> app.getChildrenElements())
.filter(element -> element.getName().equals(childElementName))
.collect(toImmutableList());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
*/
public final class BundleToolVersion {

private static final String CURRENT_VERSION = "1.16.0";
private static final String CURRENT_VERSION = "1.17.0";


/** Returns the version of BundleTool being run. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

import com.android.bundle.Config.SuffixStripping;
import com.android.bundle.Config.UncompressDexFiles.UncompressedDexTargetSdk;
import com.android.bundle.Config.UncompressNativeLibraries.PageAlignment;
import com.android.tools.build.bundletool.model.OptimizationDimension;
import com.android.tools.build.bundletool.model.version.Version;
import com.google.auto.value.AutoValue;
Expand Down Expand Up @@ -131,6 +132,24 @@ public abstract class ApkOptimizations {
// UNSPECIFIED here means SDK 29+ (Android Q+)
.setUncompressedDexTargetSdk(UncompressedDexTargetSdk.UNSPECIFIED)
.build())
.put(
Version.of("1.17.0"),
ApkOptimizations.builder()
.setSplitDimensions(
ImmutableSet.of(
ABI,
SCREEN_DENSITY,
TEXTURE_COMPRESSION_FORMAT,
LANGUAGE,
DEVICE_TIER,
COUNTRY_SET))
.setUncompressNativeLibraries(true)
.setPageAlignment(PageAlignment.PAGE_ALIGNMENT_16K)
.setStandaloneDimensions(ImmutableSet.of(ABI, SCREEN_DENSITY))
.setUncompressDexFiles(true)
// UNSPECIFIED here means SDK 29+ (Android Q+)
.setUncompressedDexTargetSdk(UncompressedDexTargetSdk.UNSPECIFIED)
.build())
.buildOrThrow();

/** List of dimensions supported by asset modules. */
Expand All @@ -146,6 +165,8 @@ public ImmutableSet<OptimizationDimension> getSplitDimensionsForAssetModules() {

public abstract boolean getUncompressNativeLibraries();

public abstract PageAlignment getPageAlignment();

public abstract boolean getUncompressDexFiles();

public abstract UncompressedDexTargetSdk getUncompressedDexTargetSdk();
Expand All @@ -161,6 +182,7 @@ public static Builder builder() {
.setUncompressNativeLibraries(false)
.setUncompressDexFiles(false)
.setUncompressedDexTargetSdk(UncompressedDexTargetSdk.UNSPECIFIED)
.setPageAlignment(PageAlignment.PAGE_ALIGNMENT_UNSPECIFIED)
.setSuffixStrippings(ImmutableMap.of());
}

Expand All @@ -171,6 +193,8 @@ public abstract static class Builder {

public abstract Builder setUncompressNativeLibraries(boolean enable);

public abstract Builder setPageAlignment(PageAlignment pageAlignment);

public abstract Builder setUncompressDexFiles(boolean enable);

public abstract Builder setUncompressedDexTargetSdk(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.android.bundle.Config.SplitDimension.Value;
import com.android.bundle.Config.SuffixStripping;
import com.android.bundle.Config.UncompressDexFiles.UncompressedDexTargetSdk;
import com.android.bundle.Config.UncompressNativeLibraries.PageAlignment;
import com.android.tools.build.bundletool.model.OptimizationDimension;
import com.android.tools.build.bundletool.model.utils.EnumMapper;
import com.android.tools.build.bundletool.model.version.BundleToolVersion;
Expand Down Expand Up @@ -104,6 +105,12 @@ public ApkOptimizations mergeWithDefaults(
? requestedOptimizations.getUncompressNativeLibraries().getEnabled()
: defaultOptimizations.getUncompressNativeLibraries();

PageAlignment pageAlignment =
requestedOptimizations.getUncompressNativeLibraries().getAlignment()
!= PageAlignment.PAGE_ALIGNMENT_UNSPECIFIED
? requestedOptimizations.getUncompressNativeLibraries().getAlignment()
: defaultOptimizations.getPageAlignment();

boolean uncompressDexFiles;
UncompressedDexTargetSdk uncompressedDexTargetSdk;

Expand All @@ -123,6 +130,7 @@ public ApkOptimizations mergeWithDefaults(
return ApkOptimizations.builder()
.setSplitDimensions(splitDimensions)
.setUncompressNativeLibraries(uncompressNativeLibraries)
.setPageAlignment(pageAlignment)
.setUncompressDexFiles(uncompressDexFiles)
.setUncompressedDexTargetSdk(uncompressedDexTargetSdk)
.setStandaloneDimensions(standaloneDimensions)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,15 @@ public boolean shouldApplyMutation(BundleModule module) {
}

private ModuleEntry updateJavaResourceEntryPath(ModuleEntry javaResourceEntry) {
String javaResourceFileName = javaResourceEntry.getPath().getFileName().toString();
ZipPath javaResourceEntryPath = javaResourceEntry.getPath();
if (javaResourceEntryPath.getNameCount() < 2) {
throw new IllegalStateException(
"Unexpected path to a Java resource entry: " + javaResourceEntryPath);
}
String javaResourceFilePath =
javaResourceEntryPath.subpath(1, javaResourceEntryPath.getNameCount()).toString();
return javaResourceEntry.toBuilder()
.setPath(ZipPath.create(getNewJavaResourceDirectoryPath() + "/" + javaResourceFileName))
.setPath(ZipPath.create(getNewJavaResourceDirectoryPath() + "/" + javaResourceFilePath))
.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@

package com.android.tools.build.bundletool.splitters;

import static com.android.tools.build.bundletool.model.utils.Versions.ANDROID_Q_API_VERSION;
import static com.android.tools.build.bundletool.model.utils.Versions.ANDROID_S_API_VERSION;

import com.android.bundle.Config.SuffixStripping;
import com.android.bundle.Config.UncompressDexFiles.UncompressedDexTargetSdk;
import com.android.bundle.Targeting.Abi;
Expand Down Expand Up @@ -72,6 +75,17 @@ public boolean shouldStripTargetingSuffix(OptimizationDimension dimension) {
&& getSuffixStrippings().get(dimension).getEnabled();
}

public int getMinimalSdkTargetingForUncompressedDex() {
switch (getDexCompressionSplitterForTargetSdk()) {
case SDK_31:
return ANDROID_S_API_VERSION;
default:
// Uncompressed dex are supported starting from Android P, but only starting from Android Q
// the performance impact is negligible compared to a compressed dex.
return ANDROID_Q_API_VERSION;
}
}

/**
* Minimum SDK version for which signing with v3 key rotation is intended to be performed.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@
import static com.android.tools.build.bundletool.model.utils.TargetingProtoUtils.sdkVersionFrom;
import static com.android.tools.build.bundletool.model.utils.TargetingProtoUtils.sdkVersionTargeting;
import static com.android.tools.build.bundletool.model.utils.TargetingProtoUtils.variantTargeting;
import static com.android.tools.build.bundletool.model.utils.Versions.ANDROID_Q_API_VERSION;
import static com.android.tools.build.bundletool.model.utils.Versions.ANDROID_S_API_VERSION;
import static com.google.common.collect.ImmutableSet.toImmutableSet;

import com.android.bundle.Targeting.VariantTargeting;
Expand Down Expand Up @@ -54,17 +52,11 @@ public Stream<VariantTargeting> generate(BundleModule module) {
return Stream.of();
}
Stream.Builder<VariantTargeting> variantTargetings = Stream.builder();
switch (apkGenerationConfiguration.getDexCompressionSplitterForTargetSdk()) {
case SDK_31:
variantTargetings.add(
variantTargeting(sdkVersionTargeting(sdkVersionFrom(ANDROID_S_API_VERSION))));
break;
default:
// Uncompressed dex are supported starting from Android P, but only starting from Android Q
// the performance impact is negligible compared to a compressed dex.
variantTargetings.add(
variantTargeting(sdkVersionTargeting(sdkVersionFrom(ANDROID_Q_API_VERSION))));
}
variantTargetings.add(
variantTargeting(
sdkVersionTargeting(
sdkVersionFrom(
apkGenerationConfiguration.getMinimalSdkTargetingForUncompressedDex()))));
return variantTargetings.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,9 @@ private SplittingPipeline createAssetsSplittingPipeline() {

private SplittingPipeline createDexSplittingPipeline() {
ImmutableList.Builder<ModuleSplitSplitter> dexSplitters = ImmutableList.builder();
if (apkGenerationConfiguration.getEnableDexCompressionSplitter()) {
if (apkGenerationConfiguration.getEnableDexCompressionSplitter()
&& getMinSdk(variantTargeting.getSdkVersionTargeting())
>= apkGenerationConfiguration.getMinimalSdkTargetingForUncompressedDex()) {
dexSplitters.add(new DexCompressionSplitter());
}

Expand Down
9 changes: 9 additions & 0 deletions src/main/proto/commands.proto
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,9 @@ message AssetModuleMetadata {

// Deprecated. Use delivery_type.
bool on_demand_deprecated = 2 [deprecated = true];

// Type of asset module.
AssetModuleType asset_module_type = 5;
}

message InstantMetadata {
Expand Down Expand Up @@ -218,6 +221,12 @@ enum FeatureModuleType {
SDK_MODULE = 3;
}

enum AssetModuleType {
UNKNOWN_ASSET_TYPE = 0;
DEFAULT_ASSET_TYPE = 1;
AI_PACK_TYPE = 2;
}

message ApkDescription {
ApkTargeting targeting = 1;

Expand Down
Loading

0 comments on commit 3f4ef99

Please sign in to comment.