Search in sources :

Example 11 with ModuleEntry

use of com.android.tools.build.bundletool.model.ModuleEntry in project bundletool by google.

the class SplitsXmlInjectorTest method process_fileExists.

@Test
public void process_fileExists() {
    ModuleEntry existingModuleEntry = createModuleEntryForFile("res/xml/splits0.xml", "123".getBytes(UTF_8));
    ModuleSplit baseMasterSplit = createModuleSplit(BASE_MODULE_NAME.getName(), /* splitId= */
    "", /* masterSplit= */
    true, SPLIT, /* languageTargeting= */
    null).toBuilder().setEntries(ImmutableList.of(existingModuleEntry)).build();
    ModuleSplit processedBaseMasterSplit = xmlInjectorProcess(GeneratedApks.fromModuleSplits(ImmutableList.of(baseMasterSplit))).stream().collect(onlyElement());
    assertThat(processedBaseMasterSplit.getEntries()).hasSize(2);
    assertThat(processedBaseMasterSplit.getEntries()).contains(existingModuleEntry);
    assertThat(processedBaseMasterSplit.getEntries().get(1).getPath().toString()).isEqualTo("res/xml/splits1.xml");
    assertThat(processedBaseMasterSplit.getResourceTable().get()).containsResource("com.example.app:xml/splits1").withFileReference("res/xml/splits1.xml");
}
Also used : ModuleEntry(com.android.tools.build.bundletool.model.ModuleEntry) ModuleSplit(com.android.tools.build.bundletool.model.ModuleSplit) Test(org.junit.Test)

Example 12 with ModuleEntry

use of com.android.tools.build.bundletool.model.ModuleEntry in project bundletool by google.

the class ModuleSplitSerializer method shouldUncompressBecauseOfLowRatio.

/**
 * Whether module entry should be put in uncompressed form because savings for the entry is low.
 */
private boolean shouldUncompressBecauseOfLowRatio(ModuleEntry moduleEntry, ModuleEntriesPack compressedPack) {
    Entry entry = compressedPack.getZipEntry(moduleEntry);
    long compressedSize = entry.getCompressedSize();
    long uncompressedSize = entry.getUncompressedSize();
    // Copying logic from aapt2: require at least 10% gains in savings.
    if (moduleEntry.getPath().startsWith("res")) {
        return compressedSize + compressedSize / 10 > uncompressedSize;
    }
    return compressedSize >= uncompressedSize;
}
Also used : Entry(com.android.zipflinger.Entry) SpecialModuleEntry(com.android.tools.build.bundletool.model.BundleModule.SpecialModuleEntry) ModuleEntry(com.android.tools.build.bundletool.model.ModuleEntry)

Example 13 with ModuleEntry

use of com.android.tools.build.bundletool.model.ModuleEntry in project bundletool by google.

the class ModuleSplitSerializer method serializeSplit.

private void serializeSplit(Path outputPath, ModuleSplit split, ModuleEntriesPack allEntriesPack, ModuleEntriesPack uncompressedEntriesPack) {
    FileUtils.createDirectories(outputPath.getParent());
    try (ZipArchive archive = new ZipArchive(outputPath)) {
        ImmutableMap<ZipPath, ModuleEntry> moduleEntriesByName = split.getEntries().stream().collect(toImmutableMap(entry -> toApkEntryPath(entry.getPath()), entry -> entry, // e.g. base/assets/foo and base/root/assets/foo.
        (a, b) -> b));
        // Sorting entries by name for determinism.
        ImmutableList<ModuleEntry> sortedEntries = ImmutableList.sortedCopyOf(Comparator.comparing(e -> toApkEntryPath(e.getPath())), moduleEntriesByName.values());
        ZipSource zipSource = allEntriesPack.select(sortedEntries, entry -> toApkEntryPath(entry.getPath(), /* binaryApk= */
        true).toString(), entry -> alignmentForEntry(entry, uncompressedEntriesPack));
        archive.add(zipSource);
    } catch (IOException e) {
        throw new UncheckedIOException(e);
    }
}
Also used : PathMatcher(com.android.tools.build.bundletool.model.utils.PathMatcher) ListenableFuture(com.google.common.util.concurrent.ListenableFuture) ZipPath(com.android.tools.build.bundletool.model.ZipPath) ApkListener(com.android.tools.build.bundletool.model.ApkListener) Inject(javax.inject.Inject) ApkSerializerHelper.toApkEntryPath(com.android.tools.build.bundletool.io.ApkSerializerHelper.toApkEntryPath) ImmutableList(com.google.common.collect.ImmutableList) ApkDescription(com.android.bundle.Commands.ApkDescription) ZipArchive(com.android.zipflinger.ZipArchive) Version(com.android.tools.build.bundletool.model.version.Version) ByteSource(com.google.common.io.ByteSource) Path(java.nio.file.Path) ImmutableMap(com.google.common.collect.ImmutableMap) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) Collection(java.util.Collection) ApkSerializerHelper.requiresAapt2Conversion(com.android.tools.build.bundletool.io.ApkSerializerHelper.requiresAapt2Conversion) IOException(java.io.IOException) Deflater(java.util.zip.Deflater) VerboseLogs(com.android.tools.build.bundletool.commands.BuildApksModule.VerboseLogs) Streams(com.google.common.collect.Streams) Entry(com.android.zipflinger.Entry) ZipSource(com.android.zipflinger.ZipSource) SpecialModuleEntry(com.android.tools.build.bundletool.model.BundleModule.SpecialModuleEntry) UncheckedIOException(java.io.UncheckedIOException) ImmutableMap.toImmutableMap(com.google.common.collect.ImmutableMap.toImmutableMap) ModuleSplit(com.android.tools.build.bundletool.model.ModuleSplit) BundleConfig(com.android.bundle.Config.BundleConfig) ModuleEntry(com.android.tools.build.bundletool.model.ModuleEntry) NO_DEFAULT_UNCOMPRESS_EXTENSIONS(com.android.tools.build.bundletool.model.version.VersionGuardedFeature.NO_DEFAULT_UNCOMPRESS_EXTENSIONS) Function.identity(java.util.function.Function.identity) Optional(java.util.Optional) Pattern(java.util.regex.Pattern) Comparator(java.util.Comparator) FileUtils(com.android.tools.build.bundletool.model.utils.files.FileUtils) ListeningExecutorService(com.google.common.util.concurrent.ListeningExecutorService) ZipSource(com.android.zipflinger.ZipSource) SpecialModuleEntry(com.android.tools.build.bundletool.model.BundleModule.SpecialModuleEntry) ModuleEntry(com.android.tools.build.bundletool.model.ModuleEntry) ZipArchive(com.android.zipflinger.ZipArchive) UncheckedIOException(java.io.UncheckedIOException) ZipPath(com.android.tools.build.bundletool.model.ZipPath) IOException(java.io.IOException) UncheckedIOException(java.io.UncheckedIOException)

Example 14 with ModuleEntry

use of com.android.tools.build.bundletool.model.ModuleEntry in project bundletool by google.

the class SdkBundleSerializer method writeToDisk.

/**
 * Writes the SDK Bundle on disk at the given location.
 */
public void writeToDisk(SdkBundle bundle, Path pathOnDisk) throws IOException {
    ZipBuilder zipBuilder = new ZipBuilder();
    zipBuilder.addFileWithProtoContent(ZipPath.create(BUNDLE_CONFIG_FILE_NAME), bundle.getBundleConfig());
    // BUNDLE-METADATA
    for (Entry<ZipPath, ByteSource> metadataEntry : bundle.getBundleMetadata().getFileContentMap().entrySet()) {
        zipBuilder.addFile(METADATA_DIRECTORY.resolve(metadataEntry.getKey()), metadataEntry.getValue());
    }
    // Base module (the only module in an ASB)
    BundleModule module = bundle.getModule();
    ZipPath moduleDir = ZipPath.create(module.getName().toString());
    for (ModuleEntry entry : module.getEntries()) {
        ZipPath entryPath = moduleDir.resolve(entry.getPath());
        zipBuilder.addFile(entryPath, entry.getContent());
    }
    // Special module files are not represented as module entries (above).
    zipBuilder.addFileWithProtoContent(moduleDir.resolve(SpecialModuleEntry.ANDROID_MANIFEST.getPath()), module.getAndroidManifest().getManifestRoot().getProto());
    module.getAssetsConfig().ifPresent(assetsConfig -> zipBuilder.addFileWithProtoContent(moduleDir.resolve(SpecialModuleEntry.ASSETS_TABLE.getPath()), assetsConfig));
    module.getNativeConfig().ifPresent(nativeConfig -> zipBuilder.addFileWithProtoContent(moduleDir.resolve(SpecialModuleEntry.NATIVE_LIBS_TABLE.getPath()), nativeConfig));
    module.getResourceTable().ifPresent(resourceTable -> zipBuilder.addFileWithProtoContent(moduleDir.resolve(SpecialModuleEntry.RESOURCE_TABLE.getPath()), resourceTable));
    zipBuilder.writeTo(pathOnDisk);
}
Also used : SpecialModuleEntry(com.android.tools.build.bundletool.model.BundleModule.SpecialModuleEntry) ModuleEntry(com.android.tools.build.bundletool.model.ModuleEntry) ByteSource(com.google.common.io.ByteSource) ZipPath(com.android.tools.build.bundletool.model.ZipPath) BundleModule(com.android.tools.build.bundletool.model.BundleModule)

Example 15 with ModuleEntry

use of com.android.tools.build.bundletool.model.ModuleEntry in project bundletool by google.

the class ZipFlingerApkSerializer method writeProtoApk.

/**
 * Writes an APK for aapt2 to convert to binary.
 *
 * <p>This APK contains only files that aapt2 will convert from proto to binary, and the files
 * needed for the conversion to succeed (e.g. all resources referenced in the resource table).
 *
 * <p>All files are left uncompressed to save aapt2 from re-compressing all the entries it
 * generated since we prefer having control over which compression is used. This is effectively a
 * tradeoff between local storage and CPU.
 *
 * <p>No entry is 4-byte aligned since it's only a temporary APK for aapt2 conversion which won't
 * be actually stored or served to any device.
 */
private void writeProtoApk(ModuleSplit split, Path protoApkPath, TempDirectory tempDir) throws IOException {
    try (ZipArchive apkWriter = new ZipArchive(protoApkPath)) {
        apkWriter.add(new BytesSource(split.getAndroidManifest().getManifestRoot().getProto().toByteArray(), MANIFEST_FILENAME, NO_COMPRESSION.getValue()));
        if (split.getResourceTable().isPresent()) {
            BytesSource bytesSource = new BytesSource(split.getResourceTable().get().toByteArray(), SpecialModuleEntry.RESOURCE_TABLE.getPath().toString(), NO_COMPRESSION.getValue());
            bytesSource.align(4);
            apkWriter.add(bytesSource);
        }
        Map<String, Entry> bundleEntriesByName = bundleZipReader.getEntries();
        ZipEntrySourceFactory sourceFactory = new ZipEntrySourceFactory(bundleZipReader, tempDir);
        for (ModuleEntry moduleEntry : split.getEntries()) {
            ZipPath pathInApk = ApkSerializerHelper.toApkEntryPath(moduleEntry.getPath());
            if (!requiresAapt2Conversion(pathInApk)) {
                continue;
            }
            if (moduleEntry.getBundleLocation().isPresent()) {
                ZipPath pathInBundle = moduleEntry.getBundleLocation().get().entryPathInBundle();
                Entry entry = bundleEntriesByName.get(pathInBundle.toString());
                checkNotNull(entry, "Could not find entry '%s'.", pathInBundle);
                apkWriter.add(sourceFactory.create(entry, pathInApk, NO_COMPRESSION));
            } else {
                apkWriter.add(new BytesSource(moduleEntry.getContent().read(), pathInApk.toString(), NO_COMPRESSION.getValue()));
            }
        }
    }
}
Also used : BytesSource(com.android.zipflinger.BytesSource) SpecialModuleEntry(com.android.tools.build.bundletool.model.BundleModule.SpecialModuleEntry) ModuleEntry(com.android.tools.build.bundletool.model.ModuleEntry) Entry(com.android.zipflinger.Entry) SpecialModuleEntry(com.android.tools.build.bundletool.model.BundleModule.SpecialModuleEntry) ModuleEntry(com.android.tools.build.bundletool.model.ModuleEntry) ZipArchive(com.android.zipflinger.ZipArchive) ZipPath(com.android.tools.build.bundletool.model.ZipPath)

Aggregations

ModuleEntry (com.android.tools.build.bundletool.model.ModuleEntry)41 ModuleSplit (com.android.tools.build.bundletool.model.ModuleSplit)22 ZipPath (com.android.tools.build.bundletool.model.ZipPath)18 ImmutableList (com.google.common.collect.ImmutableList)18 Test (org.junit.Test)13 BundleModule (com.android.tools.build.bundletool.model.BundleModule)12 ImmutableSet (com.google.common.collect.ImmutableSet)12 ImmutableList.toImmutableList (com.google.common.collect.ImmutableList.toImmutableList)10 SpecialModuleEntry (com.android.tools.build.bundletool.model.BundleModule.SpecialModuleEntry)8 BundleModuleBuilder (com.android.tools.build.bundletool.testing.BundleModuleBuilder)6 HashMap (java.util.HashMap)6 Optional (java.util.Optional)6 TargetedAssetsDirectory (com.android.bundle.Files.TargetedAssetsDirectory)5 ImmutableSet.toImmutableSet (com.google.common.collect.ImmutableSet.toImmutableSet)5 IOException (java.io.IOException)5 Map (java.util.Map)5 ResourceTable (com.android.aapt.Resources.ResourceTable)4 ApkTargeting (com.android.bundle.Targeting.ApkTargeting)4 BundleModuleName (com.android.tools.build.bundletool.model.BundleModuleName)4 ApkOptimizations (com.android.tools.build.bundletool.optimizations.ApkOptimizations)4