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");
}
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;
}
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);
}
}
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);
}
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()));
}
}
}
}
Aggregations