Skip to content

Commit f17ce94

Browse files
committed
Prepare for release 1.15.1.
1 parent 65ca3b5 commit f17ce94

File tree

17 files changed

+555
-56
lines changed

17 files changed

+555
-56
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,4 @@ https://developer.android.com/studio/command-line/bundletool
4646

4747
## Releases
4848

49-
Latest release: [1.15.0](https://github.com/google/bundletool/releases)
49+
Latest release: [1.15.1](https://github.com/google/bundletool/releases)

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
release_version = 1.15.0
1+
release_version = 1.15.1

src/main/java/com/android/tools/build/bundletool/commands/BuildApksCommand.java

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1008,13 +1008,7 @@ private ImmutableMap<String, BundleModule> getValidatedSdkModules(
10081008
getValidatedSdkBundlesByPackageName(closer, tempDir);
10091009
validateSdkBundlesMatchAppBundleDependencies(appBundle, sdkBundles);
10101010
return sdkBundles.entrySet().stream()
1011-
.collect(
1012-
toImmutableMap(
1013-
Entry::getKey,
1014-
entry ->
1015-
entry.getValue().getModule().toBuilder()
1016-
.setSdkModulesConfig(entry.getValue().getSdkModulesConfig())
1017-
.build()));
1011+
.collect(toImmutableMap(Entry::getKey, entry -> entry.getValue().getModule()));
10181012
}
10191013

10201014
private ImmutableMap<String, SdkAsar> getValidatedSdkAsarsByPackageName(

src/main/java/com/android/tools/build/bundletool/commands/BuildSdkApksForAppCommand.java

Lines changed: 78 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import static com.android.tools.build.bundletool.model.utils.files.FilePreconditions.checkFileExistsAndReadable;
2222
import static com.android.tools.build.bundletool.model.utils.files.FilePreconditions.checkFileHasExtension;
2323
import static com.google.common.base.Preconditions.checkArgument;
24+
import static com.google.common.base.Preconditions.checkState;
2425

2526
import com.android.bundle.RuntimeEnabledSdkConfigProto.SdkSplitPropertiesInheritedFromApp;
2627
import com.android.tools.build.bundletool.androidtools.Aapt2Command;
@@ -32,6 +33,7 @@
3233
import com.android.tools.build.bundletool.model.BundleModule;
3334
import com.android.tools.build.bundletool.model.Password;
3435
import com.android.tools.build.bundletool.model.SdkAsar;
36+
import com.android.tools.build.bundletool.model.SdkBundle;
3537
import com.android.tools.build.bundletool.model.SignerConfig;
3638
import com.android.tools.build.bundletool.model.SigningConfiguration;
3739
import com.android.tools.build.bundletool.model.exceptions.CommandExecutionException;
@@ -41,6 +43,7 @@
4143
import com.android.tools.build.bundletool.model.utils.files.BufferedIo;
4244
import com.android.tools.build.bundletool.sdkmodule.SdkModuleToAppBundleModuleConverter;
4345
import com.android.tools.build.bundletool.validation.SdkAsarValidator;
46+
import com.android.tools.build.bundletool.validation.SdkBundleValidator;
4447
import com.google.auto.value.AutoValue;
4548
import com.google.common.util.concurrent.ListeningExecutorService;
4649
import com.google.common.util.concurrent.MoreExecutors;
@@ -64,7 +67,10 @@ public abstract class BuildSdkApksForAppCommand {
6467

6568
public static final String COMMAND_NAME = "build-sdk-apks-for-app";
6669

70+
private static final Flag<Path> SDK_BUNDLE_LOCATION_FLAG = Flag.path("sdk-bundle");
71+
6772
private static final Flag<Path> SDK_ARCHIVE_LOCATION_FLAG = Flag.path("sdk-archive");
73+
6874
private static final Flag<Path> INHERITED_APP_PROPERTIES_LOCATION_FLAG =
6975
Flag.path("app-properties");
7076

@@ -81,7 +87,9 @@ public abstract class BuildSdkApksForAppCommand {
8187
private static final SystemEnvironmentProvider DEFAULT_PROVIDER =
8288
new DefaultSystemEnvironmentProvider();
8389

84-
public abstract Path getSdkArchivePath();
90+
public abstract Optional<Path> getSdkBundlePath();
91+
92+
public abstract Optional<Path> getSdkArchivePath();
8593

8694
public abstract SdkSplitPropertiesInheritedFromApp getInheritedAppProperties();
8795

@@ -107,6 +115,9 @@ public static BuildSdkApksForAppCommand.Builder builder() {
107115
@AutoValue.Builder
108116
public abstract static class Builder {
109117

118+
/** Sets the path to the SDK bundle file. Must have the extension ".asb". */
119+
public abstract Builder setSdkBundlePath(Path sdkBundlePath);
120+
110121
/** Sets the path to the SDK archive file. Must have the extension ".asar". */
111122
public abstract Builder setSdkArchivePath(Path sdkArchivePath);
112123

@@ -160,19 +171,33 @@ public BuildSdkApksForAppCommand build() {
160171
setExecutorServiceInternal(createInternalExecutorService(DEFAULT_THREAD_POOL_SIZE));
161172
setExecutorServiceCreatedByBundleTool(true);
162173
}
163-
return autoBuild();
174+
BuildSdkApksForAppCommand command = autoBuild();
175+
checkState(
176+
command.getSdkBundlePath().isPresent() ^ command.getSdkArchivePath().isPresent(),
177+
"One and only one of SdkBundlePath and SdkArchivePath should be set.");
178+
return command;
164179
}
165180
}
166181

167182
public static CommandHelp help() {
168183
return CommandHelp.builder()
169184
.setCommandName(COMMAND_NAME)
170185
.setCommandDescription(CommandDescription.builder().setShortDescription("").build())
186+
.addFlag(
187+
FlagDescription.builder()
188+
.setFlagName(SDK_BUNDLE_LOCATION_FLAG.getName())
189+
.setExampleValue("sdk.asb")
190+
.setDescription(
191+
"Path to SDK bundle to generate app-specific split APKs from. Can"
192+
+ " not be used together with the `sdk-archive` flag.")
193+
.build())
171194
.addFlag(
172195
FlagDescription.builder()
173196
.setFlagName(SDK_ARCHIVE_LOCATION_FLAG.getName())
174197
.setExampleValue("sdk.asar")
175-
.setDescription("Path to SDK archive to generate app-specific split APKs from.")
198+
.setDescription(
199+
"Path to SDK archive to generate app-specific split APKs from. Can"
200+
+ " not be used together with the `sdk-bundle` flag.")
176201
.build())
177202
.addFlag(
178203
FlagDescription.builder()
@@ -250,11 +275,11 @@ static BuildSdkApksForAppCommand fromFlags(
250275
ParsedFlags flags, PrintStream out, SystemEnvironmentProvider systemEnvironmentProvider) {
251276
BuildSdkApksForAppCommand.Builder command =
252277
BuildSdkApksForAppCommand.builder()
253-
.setSdkArchivePath(SDK_ARCHIVE_LOCATION_FLAG.getRequiredValue(flags))
254278
.setInheritedAppProperties(
255279
INHERITED_APP_PROPERTIES_LOCATION_FLAG.getRequiredValue(flags))
256280
.setOutputFile(OUTPUT_FILE_FLAG.getRequiredValue(flags));
257-
281+
SDK_BUNDLE_LOCATION_FLAG.getValue(flags).ifPresent(command::setSdkBundlePath);
282+
SDK_ARCHIVE_LOCATION_FLAG.getValue(flags).ifPresent(command::setSdkArchivePath);
258283
AAPT2_PATH_FLAG
259284
.getValue(flags)
260285
.ifPresent(
@@ -267,14 +292,58 @@ static BuildSdkApksForAppCommand fromFlags(
267292

268293
public void execute() {
269294
validateInput();
295+
if (getSdkBundlePath().isPresent()) {
296+
executeForSdkBundle();
297+
} else if (getSdkArchivePath().isPresent()) {
298+
executeForSdkArchive();
299+
} else {
300+
throw new IllegalStateException("whaaat");
301+
}
302+
}
303+
304+
private void validateInput() {
305+
if (getSdkBundlePath().isPresent()) {
306+
checkFileExistsAndReadable(getSdkBundlePath().get());
307+
checkFileHasExtension("ASB file", getSdkBundlePath().get(), ".asb");
308+
}
309+
if (getSdkArchivePath().isPresent()) {
310+
checkFileExistsAndReadable(getSdkArchivePath().get());
311+
checkFileHasExtension("ASAR file", getSdkArchivePath().get(), ".asar");
312+
}
313+
}
314+
315+
private void executeForSdkBundle() {
316+
try (TempDirectory tempDir = new TempDirectory(getClass().getSimpleName());
317+
ZipFile sdkBundleZip = new ZipFile(getSdkBundlePath().get().toFile())) {
318+
Path modulesPath = tempDir.getPath().resolve(EXTRACTED_SDK_MODULES_FILE_NAME);
319+
try (ZipFile modulesZip = getModulesZip(sdkBundleZip, modulesPath)) {
320+
SdkBundleValidator sdkBundleValidator = SdkBundleValidator.create();
321+
sdkBundleValidator.validateModulesFile(modulesZip);
322+
// SdkBundle#getVersionCode is not used in `build-apks`. It does not matter what
323+
// value we set here, so we are just setting 0.
324+
SdkBundle sdkBundle =
325+
SdkBundle.buildFromZip(sdkBundleZip, modulesZip, /* versionCode= */ 0);
326+
sdkBundleValidator.validate(sdkBundle);
327+
generateAppApks(sdkBundle.getModule(), tempDir);
328+
}
329+
} catch (ZipException e) {
330+
throw CommandExecutionException.builder()
331+
.withInternalMessage("ASB is not a valid zip file.")
332+
.withCause(e)
333+
.build();
334+
} catch (IOException e) {
335+
throw new UncheckedIOException("An error occurred when processing the SDK bundle.", e);
336+
}
337+
}
270338

339+
private void executeForSdkArchive() {
271340
try (TempDirectory tempDir = new TempDirectory(getClass().getSimpleName());
272-
ZipFile asarZip = new ZipFile(getSdkArchivePath().toFile())) {
341+
ZipFile asarZip = new ZipFile(getSdkArchivePath().get().toFile())) {
273342
Path modulesPath = tempDir.getPath().resolve(EXTRACTED_SDK_MODULES_FILE_NAME);
274343
try (ZipFile modulesZip = getModulesZip(asarZip, modulesPath)) {
275344
SdkAsarValidator.validateModulesFile(modulesZip);
276345
SdkAsar sdkAsar = SdkAsar.buildFromZip(asarZip, modulesZip, modulesPath);
277-
generateAppApks(sdkAsar, tempDir);
346+
generateAppApks(sdkAsar.getModule(), tempDir);
278347
}
279348
} catch (ZipException e) {
280349
throw CommandExecutionException.builder()
@@ -286,15 +355,9 @@ public void execute() {
286355
}
287356
}
288357

289-
private void validateInput() {
290-
checkFileExistsAndReadable(getSdkArchivePath());
291-
checkFileHasExtension("ASAR file", getSdkArchivePath(), ".asar");
292-
}
293-
294-
private void generateAppApks(SdkAsar sdkAsar, TempDirectory tempDirectory) {
358+
private void generateAppApks(BundleModule sdkModule, TempDirectory tempDirectory) {
295359
BundleModule convertedAppModule =
296-
new SdkModuleToAppBundleModuleConverter(sdkAsar.getModule(), getInheritedAppProperties())
297-
.convert();
360+
new SdkModuleToAppBundleModuleConverter(sdkModule, getInheritedAppProperties()).convert();
298361
DaggerBuildSdkApksForAppManagerComponent.builder()
299362
.setBuildSdkApksForAppCommand(this)
300363
.setModule(convertedAppModule)

src/main/java/com/android/tools/build/bundletool/commands/BuildSdkBundleCommand.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,10 @@
3434
import com.android.tools.build.bundletool.flags.Flag;
3535
import com.android.tools.build.bundletool.flags.ParsedFlags;
3636
import com.android.tools.build.bundletool.io.ZipFlingerBundleSerializer;
37+
import com.android.tools.build.bundletool.model.AndroidManifest;
3738
import com.android.tools.build.bundletool.model.BundleMetadata;
3839
import com.android.tools.build.bundletool.model.BundleModule;
40+
import com.android.tools.build.bundletool.model.ManifestEditor;
3941
import com.android.tools.build.bundletool.model.SdkBundle;
4042
import com.android.tools.build.bundletool.model.ZipPath;
4143
import com.android.tools.build.bundletool.model.exceptions.CommandExecutionException;
@@ -224,6 +226,7 @@ public void execute() {
224226
.map(
225227
moduleZipPath ->
226228
BundleModuleParser.parseSdkBundleModule(moduleZipPath, sdkModulesConfig))
229+
.map(BuildSdkBundleCommand::sanitizeManifest)
227230
.collect(toImmutableList());
228231

229232
new SdkBundleModulesValidator().validateSdkBundleModules(modules);
@@ -324,6 +327,17 @@ private static <T extends Message.Builder> void populateConfigFromJson(
324327
}
325328
}
326329

330+
private static BundleModule sanitizeManifest(BundleModule bundleModule) {
331+
return bundleModule.toBuilder()
332+
.setAndroidManifest(sanitizeManifest(bundleModule.getAndroidManifest()))
333+
.build();
334+
}
335+
336+
private static AndroidManifest sanitizeManifest(AndroidManifest androidManifest) {
337+
return androidManifest.applyMutators(
338+
ImmutableList.of(ManifestEditor::removePermissions, ManifestEditor::removeComponents));
339+
}
340+
327341
public static CommandHelp help() {
328342
return CommandHelp.builder()
329343
.setCommandName(COMMAND_NAME)

src/main/java/com/android/tools/build/bundletool/model/AppBundle.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ public static AppBundle buildFromZip(ZipFile bundleFile) {
8989
bundleConfig.getType(),
9090
Version.of(bundleConfig.getBundletool().getVersion()),
9191
apexConfig,
92+
/* sdkModulesConfig= */ Optional.empty(),
9293
NON_MODULE_DIRECTORIES)),
9394
bundleConfig,
9495
readBundleMetadata(bundleFile));

src/main/java/com/android/tools/build/bundletool/model/BundleModule.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,10 @@ public AndroidManifest getAndroidManifest() {
153153

154154
public abstract Optional<RuntimeEnabledSdkConfig> getRuntimeEnabledSdkConfig();
155155

156-
/** Only present for modules of type SDK_DEPENDENCY_MODULE. */
156+
/**
157+
* Only present for modules of type SDK_DEPENDENCY_MODULE in app bundles, as well as in SDK
158+
* bundles and ASARs.
159+
*/
157160
public abstract Optional<SdkModulesConfig> getSdkModulesConfig();
158161

159162
/**

src/main/java/com/android/tools/build/bundletool/model/ManifestEditor.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,10 @@
5050
import static com.android.tools.build.bundletool.model.AndroidManifest.NAME_ATTRIBUTE_NAME;
5151
import static com.android.tools.build.bundletool.model.AndroidManifest.NAME_RESOURCE_ID;
5252
import static com.android.tools.build.bundletool.model.AndroidManifest.NO_NAMESPACE_URI;
53+
import static com.android.tools.build.bundletool.model.AndroidManifest.PERMISSION_ELEMENT_NAME;
5354
import static com.android.tools.build.bundletool.model.AndroidManifest.PROPERTY_ELEMENT_NAME;
5455
import static com.android.tools.build.bundletool.model.AndroidManifest.PROVIDER_ELEMENT_NAME;
56+
import static com.android.tools.build.bundletool.model.AndroidManifest.RECEIVER_ELEMENT_NAME;
5557
import static com.android.tools.build.bundletool.model.AndroidManifest.REMOVABLE_ELEMENT_NAME;
5658
import static com.android.tools.build.bundletool.model.AndroidManifest.REQUIRED_ATTRIBUTE_NAME;
5759
import static com.android.tools.build.bundletool.model.AndroidManifest.REQUIRED_BY_PRIVACY_SANDBOX_SDK_ATTRIBUTE_NAME;
@@ -741,6 +743,38 @@ private boolean hasRequiredByPrivacySandboxSdkAttr(XmlProtoElementBuilder elemen
741743
.isPresent();
742744
}
743745

746+
/** Removes custom permissions from the manifest. */
747+
@CanIgnoreReturnValue
748+
public ManifestEditor removePermissions() {
749+
manifestElement.removeChildrenElementsIf(
750+
childElement ->
751+
childElement.isElement()
752+
&& childElement.getElement().getName().equals(PERMISSION_ELEMENT_NAME));
753+
return this;
754+
}
755+
756+
/** Removes any components from the application element. */
757+
@CanIgnoreReturnValue
758+
public ManifestEditor removeComponents() {
759+
manifestElement
760+
.getOptionalChildElement(APPLICATION_ELEMENT_NAME)
761+
.ifPresent(this::removeComponents);
762+
return this;
763+
}
764+
765+
private void removeComponents(XmlProtoElementBuilder element) {
766+
ImmutableSet<String> componentNames =
767+
ImmutableSet.of(
768+
ACTIVITY_ELEMENT_NAME,
769+
SERVICE_ELEMENT_NAME,
770+
PROVIDER_ELEMENT_NAME,
771+
RECEIVER_ELEMENT_NAME);
772+
element.removeChildrenElementsIf(
773+
childElement ->
774+
childElement.isElement()
775+
&& componentNames.contains(childElement.getElement().getName()));
776+
}
777+
744778
/** Generates the modified manifest. */
745779
@CheckReturnValue
746780
public AndroidManifest save() {

src/main/java/com/android/tools/build/bundletool/model/SdkAsar.java

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,16 +52,14 @@ public static SdkAsar buildFromZip(ZipFile asar, ZipFile modulesFile, Path modul
5252
SdkModulesConfig sdkModulesConfig = readSdkModulesConfig(modulesFile);
5353
BundleModule sdkModule =
5454
Iterables.getOnlyElement(
55-
sanitize(
56-
extractModules(
57-
modulesFile,
58-
BundleType.REGULAR,
59-
Version.of(sdkModulesConfig.getBundletool().getVersion()),
60-
/* apexConfig= */ Optional.empty(),
61-
/* nonModuleDirectories= */ ImmutableSet.of())))
62-
.toBuilder()
63-
.setSdkModulesConfig(sdkModulesConfig)
64-
.build();
55+
sanitize(
56+
extractModules(
57+
modulesFile,
58+
BundleType.REGULAR,
59+
Version.of(sdkModulesConfig.getBundletool().getVersion()),
60+
/* apexConfig= */ Optional.empty(),
61+
Optional.of(sdkModulesConfig),
62+
/* nonModuleDirectories= */ ImmutableSet.of())));
6563
SdkAsar.Builder sdkAsarBuilder =
6664
builder()
6765
.setModule(sdkModule)

src/main/java/com/android/tools/build/bundletool/model/SdkBundle.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ public static SdkBundle buildFromZip(
5959
BundleType.REGULAR,
6060
Version.of(sdkModulesConfig.getBundletool().getVersion()),
6161
/* apexConfig= */ Optional.empty(),
62+
Optional.of(sdkModulesConfig),
6263
/* nonModuleDirectories= */ ImmutableSet.of()))
6364
.get(0))
6465
.setSdkModulesConfig(sdkModulesConfig)

0 commit comments

Comments
 (0)