Skip to content

Commit

Permalink
Prepare for release 1.14.1.
Browse files Browse the repository at this point in the history
  • Loading branch information
sopo-c committed Apr 14, 2023

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent da6938b commit 6a54377
Showing 73 changed files with 4,802 additions and 312 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -46,4 +46,4 @@ https://developer.android.com/studio/command-line/bundletool

## Releases

Latest release: [1.14.0](https://github.com/google/bundletool/releases)
Latest release: [1.14.1](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.14.0
release_version = 1.14.1
Original file line number Diff line number Diff line change
@@ -90,7 +90,8 @@ public final class ArchivedAndroidManifestUtils {
AndroidManifest.PERMISSION_GROUP_ELEMENT_NAME,
AndroidManifest.PERMISSION_TREE_ELEMENT_NAME);

public static AndroidManifest createArchivedManifest(AndroidManifest manifest) {
public static AndroidManifest createArchivedManifest(
AndroidManifest manifest, boolean createDifferentThemesForTvAndPhone) {
checkNotNull(manifest);

ManifestEditor editor =
@@ -130,7 +131,27 @@ public static AndroidManifest createArchivedManifest(AndroidManifest manifest) {
CHILDREN_ELEMENTS_TO_KEEP.forEach(
elementName -> editor.copyChildrenElements(manifest, elementName));

editor.addActivity(createReactivateActivity(manifest));
if (createDifferentThemesForTvAndPhone) {
if (manifest.hasMainActivity()) {
editor.addActivity(
createReactivateActivity(
IntentFilter.builder()
.addActionName(MAIN_ACTION_NAME)
.addCategoryName(LAUNCHER_CATEGORY_NAME)
.build()));
}
if (manifest.hasMainTvActivity()) {
editor.addActivity(
createReactivateActivity(
IntentFilter.builder()
.addActionName(MAIN_ACTION_NAME)
.addCategoryName(LEANBACK_LAUNCHER_CATEGORY_NAME)
.build()));
}
} else {
editor.addActivity(createReactivateActivity(manifest));
}

editor.addReceiver(createUpdateBroadcastReceiver());
addTvSupportIfRequired(editor, manifest);

@@ -145,7 +166,9 @@ private static XmlProtoNode createMinimalManifestTag() {
}

public static AndroidManifest updateArchivedIconsAndTheme(
AndroidManifest manifest, ImmutableMap<String, Integer> resourceNameToIdMap) {
AndroidManifest manifest,
ImmutableMap<String, Integer> resourceNameToIdMap,
boolean createDifferentThemesForTvAndPhone) {
ManifestEditor archivedManifestEditor = manifest.toEditor();

if (manifest.getIconAttribute().isPresent()
@@ -159,13 +182,40 @@ public static AndroidManifest updateArchivedIconsAndTheme(
resourceNameToIdMap.get(ARCHIVED_ROUND_ICON_DRAWABLE_NAME));
}

archivedManifestEditor.setActivityTheme(
REACTIVATE_ACTIVITY_NAME,
resourceNameToIdMap.getOrDefault(ArchivedResourcesHelper.ARCHIVED_TV_THEME_NAME, 0));
if (createDifferentThemesForTvAndPhone) {
if (manifest.hasMainActivity()) {
archivedManifestEditor.setActivityTheme(
REACTIVATE_ACTIVITY_NAME,
LAUNCHER_CATEGORY_NAME,
HOLO_LIGHT_NO_ACTION_BAR_FULSCREEN_THEME_RESOURCE_ID);
}
if (manifest.hasMainTvActivity()) {
archivedManifestEditor.setActivityTheme(
REACTIVATE_ACTIVITY_NAME,
LEANBACK_LAUNCHER_CATEGORY_NAME,
checkNotNull(resourceNameToIdMap.get(ArchivedResourcesHelper.ARCHIVED_TV_THEME_NAME))
.intValue());
}
} else {
archivedManifestEditor.setActivityTheme(
REACTIVATE_ACTIVITY_NAME,
resourceNameToIdMap.getOrDefault(ArchivedResourcesHelper.ARCHIVED_TV_THEME_NAME, 0));
}

return archivedManifestEditor.save();
}

private static Activity createReactivateActivity(IntentFilter intentFilter) {
return Activity.builder()
.setName(REACTIVATE_ACTIVITY_NAME)
.setExported(true)
.setExcludeFromRecents(true)
.setStateNotNeeded(true)
.setNoHistory(true)
.setIntentFilter(intentFilter)
.build();
}

private static Activity createReactivateActivity(AndroidManifest manifest) {
IntentFilter.Builder intentFilterBuilder =
IntentFilter.builder().addActionName(MAIN_ACTION_NAME);
Original file line number Diff line number Diff line change
@@ -19,6 +19,7 @@
import static com.google.common.base.Preconditions.checkNotNull;

import com.android.aapt.Resources.ResourceTable;
import com.android.tools.build.bundletool.commands.BuildApksModule.DifferentThemesForTvAndPhone;
import com.android.tools.build.bundletool.io.ResourceReader;
import com.android.tools.build.bundletool.model.AndroidManifest;
import com.android.tools.build.bundletool.model.AppBundle;
@@ -48,11 +49,13 @@
public final class ArchivedApksGenerator {
private final ResourceReader resourceReader;
private final ArchivedResourcesHelper archivedResourcesHelper;
private final boolean createDifferentThemesForTvAndPhone;

@Inject
ArchivedApksGenerator() {
ArchivedApksGenerator(@DifferentThemesForTvAndPhone boolean createDifferentThemesForTvAndPhone) {
resourceReader = new ResourceReader();
archivedResourcesHelper = new ArchivedResourcesHelper(resourceReader);
this.createDifferentThemesForTvAndPhone = createDifferentThemesForTvAndPhone;
}

public ModuleSplit generateArchivedApk(
@@ -62,7 +65,8 @@ public ModuleSplit generateArchivedApk(
BundleModule baseModule = appBundle.getBaseModule();

AndroidManifest archivedManifest =
ArchivedAndroidManifestUtils.createArchivedManifest(baseModule.getAndroidManifest());
ArchivedAndroidManifestUtils.createArchivedManifest(
baseModule.getAndroidManifest(), createDifferentThemesForTvAndPhone);
ResourceTable archivedResourceTable =
getArchivedResourceTable(appBundle, baseModule, archivedManifest);

@@ -87,7 +91,7 @@ public ModuleSplit generateArchivedApk(

archivedManifest =
ArchivedAndroidManifestUtils.updateArchivedIconsAndTheme(
archivedManifest, extraResourceNameToIdMap);
archivedManifest, extraResourceNameToIdMap, createDifferentThemesForTvAndPhone);

ModuleSplit moduleSplit =
ModuleSplit.forArchive(
Original file line number Diff line number Diff line change
@@ -25,6 +25,7 @@
import com.android.bundle.Commands.LocalTestingInfo;
import com.android.bundle.Config.BundleConfig;
import com.android.bundle.Config.ResourceOptimizations.SparseEncoding;
import com.android.bundle.Config.StandaloneConfig.FeatureModulesMode;
import com.android.bundle.Devices.DeviceSpec;
import com.android.tools.build.bundletool.archive.ArchivedApksGenerator;
import com.android.tools.build.bundletool.commands.BuildApksCommand.ApkBuildMode;
@@ -371,6 +372,14 @@ private ApkGenerationConfiguration getAssetSliceGenerationConfiguration() {
}

private ImmutableList<BundleModule> modulesToFuse(ImmutableList<BundleModule> modules) {
if (appBundle
.getBundleConfig()
.getOptimizations()
.getStandaloneConfig()
.getFeatureModulesMode()
.equals(FeatureModulesMode.SEPARATE_FEATURE_MODULES)) {
return modules;
}
return modules.stream()
.filter(BundleModule::isIncludedInFusing)
.filter(
Original file line number Diff line number Diff line change
@@ -172,6 +172,15 @@ static Optional<LocalDeploymentRuntimeEnabledSdkConfig> provideLocalRuntimeEnabl
return command.getLocalDeploymentRuntimeEnabledSdkConfig();
}

@CommandScoped
@Provides
@DifferentThemesForTvAndPhone
static boolean provideDifferentThemesForTvAndPhone(BuildApksCommand command) {
@SuppressWarnings("unused")
boolean differentThemesForTvAndPhone = false;
return differentThemesForTvAndPhone;
}

/**
* Qualifying annotation of an {@code Optional<Integer>} for the first variant number to use when
* numbering the generated variants.
@@ -198,5 +207,13 @@ static Optional<LocalDeploymentRuntimeEnabledSdkConfig> provideLocalRuntimeEnabl
@Retention(RUNTIME)
public @interface ApkSigningConfigProvider {}

/**
* Qualifying annotation of a {@code boolean} to enable usage of different themes for tv and
* phone.
*/
@Qualifier
@Retention(RUNTIME)
public @interface DifferentThemesForTvAndPhone {}

private BuildApksModule() {}
}
Original file line number Diff line number Diff line change
@@ -16,7 +16,6 @@

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

import com.android.tools.build.bundletool.model.exceptions.AdbOutputParseException;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableList;

@@ -66,10 +65,9 @@ public ImmutableList<String> parse(ImmutableList<String> dumpSysOutput) {
}

if (!parsingState.equals(ParsingState.FOUND_GL_EXTENSIONS)) {
throw AdbOutputParseException.builder()
.withInternalMessage(
"Unexpected output of 'dumpsys SurfaceFlinger' command: no GL extensions found.")
.build();
System.out.println(
"WARNING: Unexpected output of 'dumpsys SurfaceFlinger' command: no GL extensions"
+ " found.");
}

return glExtensions.build();
Original file line number Diff line number Diff line change
@@ -54,6 +54,7 @@ static ApkDescription createApkDescription(
}
break;
case STANDALONE:
case STANDALONE_FEATURE_MODULE:
if (split.isApex()) {
resultBuilder.setApexApkMetadata(createApexApkMetadata(split));
} else {
Original file line number Diff line number Diff line change
@@ -91,6 +91,11 @@ public ZipPath getApkPath(ModuleSplit moduleSplit) {
directory = ZipPath.create("standalones");
apkFileName = buildName("standalone", targetingSuffix);
break;
case STANDALONE_FEATURE_MODULE:
directory = ZipPath.create("standalones");
apkFileName =
buildName(moduleSplit.isBaseModuleSplit() ? "standalone" : moduleName, targetingSuffix);
break;
case SYSTEM:
if (moduleSplit.isBaseModuleSplit() && moduleSplit.isMasterSplit()) {
directory = ZipPath.create("system");
Original file line number Diff line number Diff line change
@@ -51,6 +51,7 @@
import com.android.bundle.Devices.DeviceSpec;
import com.android.bundle.Targeting.VariantTargeting;
import com.android.tools.build.bundletool.commands.BuildApksCommand.ApkBuildMode;
import com.android.tools.build.bundletool.commands.BuildApksModule.ApkSigningConfigProvider;
import com.android.tools.build.bundletool.commands.BuildApksModule.FirstVariantNumber;
import com.android.tools.build.bundletool.device.ApkMatcher;
import com.android.tools.build.bundletool.model.AndroidManifest;
@@ -68,6 +69,7 @@
import com.android.tools.build.bundletool.model.ModuleSplit.SplitType;
import com.android.tools.build.bundletool.model.OptimizationDimension;
import com.android.tools.build.bundletool.model.SdkBundle;
import com.android.tools.build.bundletool.model.SigningConfigurationProvider;
import com.android.tools.build.bundletool.model.VariantKey;
import com.android.tools.build.bundletool.model.ZipPath;
import com.android.tools.build.bundletool.model.version.BundleToolVersion;
@@ -101,6 +103,7 @@ public class ApkSerializerManager {
private final ApkPathManager apkPathManager;
private final ApkOptimizations apkOptimizations;
private final ApkSerializer apkSerializer;
private final Optional<SigningConfigurationProvider> signingConfigProvider;

@Inject
public ApkSerializerManager(
@@ -110,14 +113,16 @@ public ApkSerializerManager(
ApkBuildMode apkBuildMode,
ApkPathManager apkPathManager,
ApkOptimizations apkOptimizations,
ApkSerializer apkSerializer) {
ApkSerializer apkSerializer,
@ApkSigningConfigProvider Optional<SigningConfigurationProvider> signingConfigProvider) {
this.bundle = bundle;
this.apkModifier = apkModifier.orElse(ApkModifier.NO_OP);
this.firstVariantNumber = firstVariantNumber.orElse(0);
this.apkBuildMode = apkBuildMode;
this.apkPathManager = apkPathManager;
this.apkOptimizations = apkOptimizations;
this.apkSerializer = apkSerializer;
this.signingConfigProvider = signingConfigProvider;
}

/** Serialize App Bundle APKs. */
@@ -483,10 +488,21 @@ private ModuleSplit modifyApk(ModuleSplit moduleSplit, int variantNumber) {
.build();
}

private static ModuleSplit clearVariantTargeting(ModuleSplit moduleSplit) {
return moduleSplit.toBuilder()
.setVariantTargeting(VariantTargeting.getDefaultInstance())
.build();
private ModuleSplit clearVariantTargeting(ModuleSplit moduleSplit) {
VariantTargeting.Builder variantTargeting = VariantTargeting.newBuilder();
boolean hasRestrictedV3SigningConfig =
signingConfigProvider
.map(SigningConfigurationProvider::hasRestrictedV3SigningConfig)
.orElse(false);
// If the signing config includes signing with rotated keys using V3 signature scheme, and it is
// restricted to specific Android SDK versions, then the de-duplication of generated splits must
// account for variant SDK version targeting when comparing splits.
if (hasRestrictedV3SigningConfig
&& moduleSplit.getVariantTargeting().hasSdkVersionTargeting()) {
variantTargeting.setSdkVersionTargeting(
moduleSplit.getVariantTargeting().getSdkVersionTargeting());
}
return moduleSplit.toBuilder().setVariantTargeting(variantTargeting.build()).build();
}

private static AssetModulesInfo getAssetModulesInfo(AssetModulesConfig assetModulesConfig) {
Original file line number Diff line number Diff line change
@@ -95,6 +95,7 @@ public abstract class AndroidManifest {
public static final String REMOVABLE_ELEMENT_NAME = "removable";
public static final String FUSING_ELEMENT_NAME = "fusing";
public static final String STYLE_ELEMENT_NAME = "style";
public static final String MAIN_ACTION_ELEMENT_NAME = "action";

public static final String DEBUGGABLE_ATTRIBUTE_NAME = "debuggable";
public static final String EXTRACT_NATIVE_LIBS_ATTRIBUTE_NAME = "extractNativeLibs";
@@ -135,12 +136,14 @@ public abstract class AndroidManifest {
public static final String LOCALE_CONFIG_ATTRIBUTE_NAME = "localeConfig";
public static final String SDK_LIBRARY_ELEMENT_NAME = "sdk-library";
public static final String SDK_VERSION_MAJOR_ATTRIBUTE_NAME = "versionMajor";
public static final String ISOLATED_SPLITS_ATTRIBUTE_NAME = "isolatedSplits";
public static final String SDK_PATCH_VERSION_ATTRIBUTE_NAME =
"com.android.vending.sdk.version.patch";
public static final String SDK_PROVIDER_CLASS_NAME_ATTRIBUTE_NAME =
"android.sdksandbox.PROPERTY_SDK_PROVIDER_CLASS_NAME";
public static final String COMPAT_SDK_PROVIDER_CLASS_NAME_ATTRIBUTE_NAME =
"android.sdksandbox.PROPERTY_COMPAT_SDK_PROVIDER_CLASS_NAME";

public static final String REQUIRED_ATTRIBUTE_NAME = "required";
public static final int SDK_SANDBOX_MIN_VERSION = ANDROID_T_API_VERSION;
public static final String USES_SDK_LIBRARY_ELEMENT_NAME = "uses-sdk-library";
@@ -913,12 +916,11 @@ public ImmutableList<XmlProtoElement> getSdkLibraryElements() {

/**
* Gets the SDK patch version if it is set in the AndroidManifest. If there are multiple
* <property> elements with android:name={@value SDK_PATCH_VERSION_ATTRIBUTE_NAME}, return the
* <meta-data> elements with android:name={@value SDK_PATCH_VERSION_ATTRIBUTE_NAME}, return the
* first one.
*/
public Optional<Integer> getSdkPatchVersionProperty() {
return getPropertyValue(SDK_PATCH_VERSION_ATTRIBUTE_NAME)
.map(XmlProtoAttribute::getValueAsInteger);
public Optional<Integer> getSdkPatchVersionMetadata() {
return getMetadataValueAsInteger(SDK_PATCH_VERSION_ATTRIBUTE_NAME);
}

/**
Original file line number Diff line number Diff line change
@@ -52,6 +52,12 @@ public ApksigSigningConfiguration getSigningConfiguration(ApkDescription apkDesc
return apksigSigningConfig.build();
}

@Override
public boolean hasRestrictedV3SigningConfig() {
return signingConfiguration.getSigningCertificateLineage().isPresent()
&& signingConfiguration.getEffectiveMinimumV3RotationApiVersion() > 1;
}

private ImmutableList<SignerConfig> getSignerConfigs(ApkDescription apkDescription) {
ImmutableList.Builder<SignerConfig> signerConfigs = ImmutableList.builder();
Optional<SignerConfig> oldestSigner = signingConfiguration.getOldestSigner();
Loading

0 comments on commit 6a54377

Please sign in to comment.