use of com.android.tools.build.bundletool.io.ZipBuilder in project bundletool by google.
the class ApksArchiveHelpers method createApksArchiveFile.
public static Path createApksArchiveFile(BuildApksResult result, Path location) throws Exception {
ZipBuilder archiveBuilder = new ZipBuilder();
apkDescriptionStream(result).forEach(apkDesc -> archiveBuilder.addFileWithContent(ZipPath.create(apkDesc.getPath()), DUMMY_BYTES));
archiveBuilder.addFileWithProtoContent(ZipPath.create("toc.pb"), result);
return archiveBuilder.writeTo(location);
}
use of com.android.tools.build.bundletool.io.ZipBuilder in project bundletool by google.
the class InstallMultiApksCommandTest method execute_extractZipWithSdkDirectories.
@Test
public void execute_extractZipWithSdkDirectories() throws Exception {
// GIVEN a zip file containing fake .apks files
BuildApksResult tableOfContent1 = fakeTableOfContents(PKG_NAME_1);
Path package1Apks = createApksArchiveFile(tableOfContent1, tmpDir.resolve("package1.apks"));
BuildApksResult tableOfContent2 = fakeTableOfContents(PKG_NAME_2);
Path package2Apks = createApksArchiveFile(tableOfContent2, tmpDir.resolve("package2.apks"));
BuildApksResult tableOfContent3 = BuildApksResult.newBuilder().setPackageName(PKG_NAME_1).setBundletool(Bundletool.newBuilder().setVersion(BundleToolVersion.getCurrentVersion().toString())).addVariant(createVariant(VariantTargeting.getDefaultInstance(), createSplitApkSet("base", createMasterApkDescription(ApkTargeting.getDefaultInstance(), ZipPath.create(PKG_NAME_1 + "base-master.apk"))), createSplitApkSet("feature3", createMasterApkDescription(ApkTargeting.getDefaultInstance(), ZipPath.create(PKG_NAME_1 + "feature3-master.apk"))), createSplitApkSet("feature4", createMasterApkDescription(ApkTargeting.getDefaultInstance(), ZipPath.create(PKG_NAME_1 + "feature4-master.apk"))))).build();
Path package1v2Apks = createApksArchiveFile(tableOfContent3, tmpDir.resolve("package3.apks"));
ZipBuilder bundleBuilder = new ZipBuilder();
bundleBuilder.addFileFromDisk(ZipPath.create("29/package1.apks"), package1Apks.toFile()).addFileFromDisk(ZipPath.create("30/package1.apks"), package1v2Apks.toFile()).addFileFromDisk(ZipPath.create("package2.apks"), package2Apks.toFile());
Path zipBundle = bundleBuilder.writeTo(tmpDir.resolve("bundle.zip"));
AtomicReference<Integer> counter = new AtomicReference<>(3);
InstallMultiApksCommand command = InstallMultiApksCommand.builder().setAdbServer(fakeServerOneDevice(device)).setDeviceId(DEVICE_ID).setAdbPath(adbPath).setApksArchiveZipPath(zipBundle).setAapt2Command(createFakeAapt2CommandFromSupplier(ImmutableMap.of(PKG_NAME_2, () -> ImmutableList.of(String.format("package: name='%s' versionCode='%d' ", PKG_NAME_2, 2)), PKG_NAME_1, () -> ImmutableList.of(String.format("package: name='%s' versionCode='%d' ", PKG_NAME_1, counter.getAndSet(counter.get() + 1)))))).setAdbCommand(createFakeAdbCommand(ImmutableListMultimap.<String, String>builder().putAll(PKG_NAME_1, ImmutableList.of(Paths.get(PKG_NAME_1, PKG_NAME_1 + "base-master.apk").toString(), Paths.get(PKG_NAME_1, PKG_NAME_1 + "feature3-master.apk").toString(), Paths.get(PKG_NAME_1, PKG_NAME_1 + "feature4-master.apk").toString())).putAll(PKG_NAME_2, Paths.get(PKG_NAME_2, PKG_NAME_2 + "base-master.apk").toString(), Paths.get(PKG_NAME_2, PKG_NAME_2 + "feature1-master.apk").toString(), Paths.get(PKG_NAME_2, PKG_NAME_2 + "feature2-master.apk").toString()).build(), /* expectedStaged= */
false, /* expectedEnableRollback= */
false, Optional.of(DEVICE_ID))).build();
// EXPECT
// 1) Get existing packages.
device.injectShellCommandOutput("pm list packages --show-versioncode", () -> "");
device.injectShellCommandOutput("pm list packages --apex-only --show-versioncode", () -> "");
// 2) Install command (above)
command.execute();
assertAdbCommandExecuted();
}
use of com.android.tools.build.bundletool.io.ZipBuilder in project bundletool by google.
the class InstallMultiApksCommandTest method execute_updateOnly_apex.
@Test
public void execute_updateOnly_apex() throws Exception {
// GIVEN a zip file containing fake .apks files for multiple packages, one of which is an
// apex.
BuildApksResult tableOfContent1 = fakeTableOfContents(PKG_NAME_1);
Path package1Apks = createApksArchiveFile(tableOfContent1, tmpDir.resolve("package1.apks"));
BuildApksResult apexTableOfContents = BuildApksResult.newBuilder().setPackageName(PKG_NAME_2).setBundletool(Bundletool.newBuilder().setVersion(BundleToolVersion.getCurrentVersion().toString())).addVariant(apexVariant(VariantTargeting.getDefaultInstance(), ApkTargeting.getDefaultInstance(), ZipPath.create(PKG_NAME_2 + "base.apex"))).build();
Path package2Apks = createApksArchiveFile(apexTableOfContents, tmpDir.resolve("package2.apks"));
ZipBuilder bundleBuilder = new ZipBuilder();
bundleBuilder.addFileFromDisk(ZipPath.create("package1.apks"), package1Apks.toFile()).addFileFromDisk(ZipPath.create("package2.apks"), package2Apks.toFile());
Path zipBundle = bundleBuilder.writeTo(tmpDir.resolve("bundle.zip"));
// GIVEN only one of the packages is installed on the device...
device.injectShellCommandOutput("pm list packages --show-versioncode", () -> "");
device.injectShellCommandOutput("pm list packages --apex-only --show-versioncode", () -> String.format("package:%s versionCode:1\njunk_to_ignore", PKG_NAME_2));
// GIVEN the --update-only flag is set on the command...
InstallMultiApksCommand command = InstallMultiApksCommand.builder().setAdbServer(fakeServerOneDevice(device)).setUpdateOnly(true).setDeviceId(DEVICE_ID).setAdbPath(adbPath).setApksArchiveZipPath(zipBundle).setAapt2Command(createFakeAapt2Command(ImmutableMap.of(PKG_NAME_1, 2L, PKG_NAME_2, 2L))).setAdbCommand(createFakeAdbCommand(expectedInstallApks(PKG_NAME_2, apexTableOfContents), /* expectedStaged= */
false, /* expectedEnableRollback= */
false, Optional.of(DEVICE_ID))).build();
// EXPECT only one of the packages
command.execute();
assertAdbCommandExecuted();
}
use of com.android.tools.build.bundletool.io.ZipBuilder in project bundletool by google.
the class CheckTransparencyCommandTest method apkMode_transparencyVerified_transparencyKeyCertificateNotProvidedByUser.
@Test
public void apkMode_transparencyVerified_transparencyKeyCertificateNotProvidedByUser() throws Exception {
Path apkPath = tmpDir.resolve("universal.apk");
Path zipOfApksPath = tmpDir.resolve("apks.zip");
String dexFileName = "classes.dex";
byte[] dexFileContents = new byte[] { 1, 2, 3 };
String serializedJws = createJwsToken(CodeTransparency.newBuilder().setVersion(CodeTransparencyVersion.getCurrentVersion()).addCodeRelatedFile(CodeRelatedFile.newBuilder().setType(CodeRelatedFile.Type.DEX).setPath("base/dex/" + dexFileName).setSha256(ByteSource.wrap(dexFileContents).hash(Hashing.sha256()).toString()).build()).build(), transparencyKeyCertificate, transparencyPrivateKey);
ModuleSplit baseModuleSplit = ModuleSplit.builder().setModuleName(BundleModuleName.create("base")).setAndroidManifest(AndroidManifest.create(androidManifest("com.app"))).setApkTargeting(ApkTargeting.getDefaultInstance()).setVariantTargeting(VariantTargeting.getDefaultInstance()).setMasterSplit(true).addEntry(ModuleEntry.builder().setPath(ZipPath.create("").resolve(dexFileName)).setContent(ByteSource.wrap(dexFileContents)).build()).addEntry(ModuleEntry.builder().setPath(ZipPath.create("META-INF").resolve(BundleMetadata.TRANSPARENCY_SIGNED_FILE_NAME)).setContent(CharSource.wrap(serializedJws).asByteSource(Charset.defaultCharset())).build()).build();
apkSerializer.serialize(apkPath, baseModuleSplit);
ZipBuilder zipBuilder = new ZipBuilder().addFileWithContent(ZipPath.create("universal.apk"), ByteString.readFrom(Files.newInputStream(apkPath)).toByteArray());
zipBuilder.writeTo(zipOfApksPath);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
CheckTransparencyCommand.builder().setMode(Mode.APK).setApkZipPath(zipOfApksPath).build().checkTransparency(new PrintStream(outputStream));
String output = new String(outputStream.toByteArray(), UTF_8);
assertThat(output).contains("APK signature is valid. SHA-256 fingerprint of the apk signing key certificate (must" + " be compared with the developer's public key manually): " + CodeTransparencyCryptoUtils.getCertificateFingerprint(apkSigningKeyCertificate));
assertThat(output).contains("Code transparency signature is valid. SHA-256 fingerprint of the code transparency key" + " certificate (must be compared with the developer's public key manually): " + CodeTransparencyCryptoUtils.getCertificateFingerprint((JsonWebSignature) JsonWebSignature.fromCompactSerialization(serializedJws)));
assertThat(output).contains("Code transparency verified: code related file contents match the code transparency" + " file.");
}
use of com.android.tools.build.bundletool.io.ZipBuilder in project bundletool by google.
the class CheckTransparencyCommandTest method apkMode_transparencyVerified_unsupportedCodeTransparencyVersion.
@Test
public void apkMode_transparencyVerified_unsupportedCodeTransparencyVersion() throws Exception {
Path apkPath = tmpDir.resolve("universal.apk");
Path zipOfApksPath = tmpDir.resolve("apks.zip");
String dexFileName = "classes.dex";
byte[] dexFileContents = new byte[] { 1, 2, 3 };
String serializedJws = createJwsToken(CodeTransparency.newBuilder().setVersion(CodeTransparencyVersion.getCurrentVersion() + 1).addCodeRelatedFile(CodeRelatedFile.newBuilder().setType(CodeRelatedFile.Type.DEX).setPath("base/dex/" + dexFileName).setSha256(ByteSource.wrap(dexFileContents).hash(Hashing.sha256()).toString()).build()).build(), transparencyKeyCertificate, transparencyPrivateKey);
ModuleSplit baseModuleSplit = ModuleSplit.builder().setModuleName(BundleModuleName.create("base")).setAndroidManifest(AndroidManifest.create(androidManifest("com.app"))).setApkTargeting(ApkTargeting.getDefaultInstance()).setVariantTargeting(VariantTargeting.getDefaultInstance()).setMasterSplit(true).addEntry(ModuleEntry.builder().setPath(ZipPath.create("").resolve(dexFileName)).setContent(ByteSource.wrap(dexFileContents)).build()).addEntry(ModuleEntry.builder().setPath(ZipPath.create("META-INF").resolve(BundleMetadata.TRANSPARENCY_SIGNED_FILE_NAME)).setContent(CharSource.wrap(serializedJws).asByteSource(Charset.defaultCharset())).build()).build();
apkSerializer.serialize(apkPath, baseModuleSplit);
ZipBuilder zipBuilder = new ZipBuilder().addFileWithContent(ZipPath.create("universal.apk"), ByteString.readFrom(Files.newInputStream(apkPath)).toByteArray());
zipBuilder.writeTo(zipOfApksPath);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
Throwable e = assertThrows(IllegalStateException.class, () -> CheckTransparencyCommand.builder().setMode(Mode.APK).setApkZipPath(zipOfApksPath).build().checkTransparency(new PrintStream(outputStream)));
assertThat(e).hasMessageThat().contains("Code transparency file has unsupported version.");
}
Aggregations