use of com.android.zipflinger.BytesSource 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()));
}
}
}
}
use of com.android.zipflinger.BytesSource in project bundletool by google.
the class ApkSetWriter method zip.
/**
* Creates ApkSet writer which stores all splits as ZIP archive.
*/
static ApkSetWriter zip(Path tempDirectory, Path outputFile) {
return new ApkSetWriter() {
@Override
public Path getSplitsDirectory() {
return tempDirectory;
}
@Override
public void writeApkSet(BuildApksResult toc) throws IOException {
Stream<ApkDescription> apks = toc.getVariantList().stream().flatMap(variant -> variant.getApkSetList().stream()).flatMap(apkSet -> apkSet.getApkDescriptionList().stream());
Stream<ApkDescription> assets = toc.getAssetSliceSetList().stream().flatMap(assetSliceSet -> assetSliceSet.getApkDescriptionList().stream());
ImmutableSet<String> apkRelativePaths = Stream.concat(apks, assets).map(ApkDescription::getPath).sorted().collect(toImmutableSet());
zipApkSet(apkRelativePaths, toc.toByteArray());
}
@Override
public void writeApkSet(BuildSdkApksResult toc) throws IOException {
Stream<ApkDescription> apks = toc.getVariantList().stream().flatMap(variant -> variant.getApkSetList().stream()).flatMap(apkSet -> apkSet.getApkDescriptionList().stream());
ImmutableSet<String> apkRelativePaths = apks.map(ApkDescription::getPath).sorted().collect(toImmutableSet());
zipApkSet(apkRelativePaths, toc.toByteArray());
}
private void zipApkSet(ImmutableSet<String> apkRelativePaths, byte[] tocBytes) throws IOException {
try (ZipArchive zipArchive = new ZipArchive(outputFile)) {
zipArchive.add(new BytesSource(tocBytes, TABLE_OF_CONTENTS_FILE, Deflater.NO_COMPRESSION));
for (String relativePath : apkRelativePaths) {
zipArchive.add(new LargeFileSource(getSplitsDirectory().resolve(relativePath), /* tmpStorage= */
null, relativePath, Deflater.NO_COMPRESSION));
}
}
}
};
}
use of com.android.zipflinger.BytesSource in project bundletool by google.
the class ZipFlingerAppBundleSerializer method addNewEntries.
/**
* Adds new and modified entries to an archive, compressing them.
*/
private static void addNewEntries(ZipArchive archive, ImmutableListMultimap<BundleModule, ModuleEntry> entries) throws IOException {
for (Map.Entry<BundleModule, ModuleEntry> moduleAndEntry : entries.entries()) {
BundleModule module = moduleAndEntry.getKey();
ModuleEntry moduleEntry = moduleAndEntry.getValue();
checkState(!moduleEntry.getBundleLocation().isPresent());
ZipPath moduleDir = ZipPath.create(module.getName().toString());
ZipPath destPath = moduleDir.resolve(moduleEntry.getPath());
archive.add(new BytesSource(moduleEntry.getContent().read(), destPath.toString(), DEFAULT_COMPRESSION_LEVEL));
}
}
use of com.android.zipflinger.BytesSource in project bundletool by google.
the class ZipFlingerAppBundleSerializer method writeToDisk.
/**
* Writes the App Bundle on disk at the given location.
*/
public void writeToDisk(AppBundle bundle, Path destBundlePath) throws IOException {
try (ZipArchive zipArchive = new ZipArchive(destBundlePath)) {
zipArchive.add(protoToSource(ZipPath.create(BUNDLE_CONFIG_FILE_NAME), bundle.getBundleConfig(), DEFAULT_COMPRESSION_LEVEL));
// APEX bundles do not have metadata files.
if (bundle.getFeatureModules().isEmpty() || !bundle.isApex()) {
for (Map.Entry<ZipPath, ByteSource> metadataEntry : bundle.getBundleMetadata().getFileContentMap().entrySet()) {
zipArchive.add(new BytesSource(metadataEntry.getValue().read(), METADATA_DIRECTORY.resolve(metadataEntry.getKey()).toString(), DEFAULT_COMPRESSION_LEVEL));
}
}
addEntriesFromSourceBundles(zipArchive, getUnmodifiedModuleEntries(bundle));
addNewEntries(zipArchive, getNewOrModifiedModuleEntries(bundle));
// Special module files are not represented as module entries (above).
for (BundleModule module : bundle.getModules().values()) {
ZipPath moduleDir = ZipPath.create(module.getName().toString());
zipArchive.add(protoToSource(moduleDir.resolve(SpecialModuleEntry.ANDROID_MANIFEST.getPath()), module.getAndroidManifest().getManifestRoot().getProto(), DEFAULT_COMPRESSION_LEVEL));
if (module.getAssetsConfig().isPresent()) {
zipArchive.add(protoToSource(moduleDir.resolve(SpecialModuleEntry.ASSETS_TABLE.getPath()), module.getAssetsConfig().get(), DEFAULT_COMPRESSION_LEVEL));
}
if (module.getNativeConfig().isPresent()) {
zipArchive.add(protoToSource(moduleDir.resolve(SpecialModuleEntry.NATIVE_LIBS_TABLE.getPath()), module.getNativeConfig().get(), DEFAULT_COMPRESSION_LEVEL));
}
if (module.getResourceTable().isPresent()) {
zipArchive.add(protoToSource(moduleDir.resolve(SpecialModuleEntry.RESOURCE_TABLE.getPath()), module.getResourceTable().get(), DEFAULT_COMPRESSION_LEVEL));
}
if (module.getApexConfig().isPresent()) {
zipArchive.add(protoToSource(moduleDir.resolve(SpecialModuleEntry.APEX_TABLE.getPath()), module.getApexConfig().get(), DEFAULT_COMPRESSION_LEVEL));
}
}
}
}
Aggregations