Search in sources :

Example 1 with ZipBuilder

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);
}
Also used : ZipBuilder(com.android.tools.build.bundletool.io.ZipBuilder)

Example 2 with ZipBuilder

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();
}
Also used : Path(java.nio.file.Path) ZipPath(com.android.tools.build.bundletool.model.ZipPath) BuildApksResult(com.android.bundle.Commands.BuildApksResult) ZipBuilder(com.android.tools.build.bundletool.io.ZipBuilder) AtomicReference(java.util.concurrent.atomic.AtomicReference) Test(org.junit.Test)

Example 3 with ZipBuilder

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();
}
Also used : Path(java.nio.file.Path) ZipPath(com.android.tools.build.bundletool.model.ZipPath) BuildApksResult(com.android.bundle.Commands.BuildApksResult) ZipBuilder(com.android.tools.build.bundletool.io.ZipBuilder) Test(org.junit.Test)

Example 4 with ZipBuilder

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.");
}
Also used : Path(java.nio.file.Path) ZipPath(com.android.tools.build.bundletool.model.ZipPath) PrintStream(java.io.PrintStream) ModuleSplit(com.android.tools.build.bundletool.model.ModuleSplit) ZipBuilder(com.android.tools.build.bundletool.io.ZipBuilder) ByteString(com.google.protobuf.ByteString) ByteArrayOutputStream(java.io.ByteArrayOutputStream) Test(org.junit.Test)

Example 5 with ZipBuilder

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.");
}
Also used : Path(java.nio.file.Path) ZipPath(com.android.tools.build.bundletool.model.ZipPath) PrintStream(java.io.PrintStream) ModuleSplit(com.android.tools.build.bundletool.model.ModuleSplit) ZipBuilder(com.android.tools.build.bundletool.io.ZipBuilder) ByteString(com.google.protobuf.ByteString) ByteArrayOutputStream(java.io.ByteArrayOutputStream) Test(org.junit.Test)

Aggregations

ZipBuilder (com.android.tools.build.bundletool.io.ZipBuilder)44 Test (org.junit.Test)39 ZipPath (com.android.tools.build.bundletool.model.ZipPath)37 Path (java.nio.file.Path)37 ZipFile (java.util.zip.ZipFile)19 InvalidBundleException (com.android.tools.build.bundletool.model.exceptions.InvalidBundleException)11 BuildApksResult (com.android.bundle.Commands.BuildApksResult)5 ModuleSplit (com.android.tools.build.bundletool.model.ModuleSplit)5 ByteString (com.google.protobuf.ByteString)5 ByteArrayOutputStream (java.io.ByteArrayOutputStream)5 PrintStream (java.io.PrintStream)5 ZipEntry (java.util.zip.ZipEntry)5 XmlNode (com.android.aapt.Resources.XmlNode)4 Variant (com.android.bundle.Commands.Variant)4 ApksArchiveHelpers.createVariant (com.android.tools.build.bundletool.testing.ApksArchiveHelpers.createVariant)4 FlagParseException (com.android.tools.build.bundletool.flags.FlagParser.FlagParseException)3 ConfigurationSizes (com.android.tools.build.bundletool.model.ConfigurationSizes)3 InvalidCommandException (com.android.tools.build.bundletool.model.exceptions.InvalidCommandException)3 ApksArchiveHelpers.standaloneVariant (com.android.tools.build.bundletool.testing.ApksArchiveHelpers.standaloneVariant)3 ResourceTableBuilder (com.android.tools.build.bundletool.testing.ResourceTableBuilder)3