use of com.android.tools.build.bundletool.model.BundleModule in project bundletool by google.
the class AndroidManifestValidator method validateMinMaxSdk.
private static void validateMinMaxSdk(BundleModule module) {
AndroidManifest manifest = module.getAndroidManifest();
Optional<Integer> maxSdk = manifest.getMaxSdkVersion();
Optional<Integer> minSdk = manifest.getMinSdkVersion();
maxSdk.filter(sdk -> sdk < 0).ifPresent(sdk -> {
throw InvalidBundleException.builder().withUserMessage("maxSdkVersion must be nonnegative, found: (%d).", sdk).build();
});
minSdk.filter(sdk -> sdk < 0).ifPresent(sdk -> {
throw InvalidBundleException.builder().withUserMessage("minSdkVersion must be nonnegative, found: (%d).", sdk).build();
});
if (maxSdk.isPresent() && minSdk.isPresent() && maxSdk.get() < minSdk.get()) {
throw InvalidBundleException.builder().withUserMessage("minSdkVersion (%d) is greater than maxSdkVersion (%d).", minSdk.get(), maxSdk.get()).build();
}
}
use of com.android.tools.build.bundletool.model.BundleModule in project bundletool by google.
the class ApexBundleValidator method validateModule.
@Override
public void validateModule(BundleModule module) {
if (module.findEntriesUnderPath(APEX_DIRECTORY).count() == 0) {
return;
}
Optional<ModuleEntry> apexManifest = module.getEntry(APEX_MANIFEST_PATH);
if (apexManifest.isPresent()) {
validateApexManifest(apexManifest.get());
} else {
apexManifest = module.getEntry(APEX_MANIFEST_JSON_PATH);
if (!apexManifest.isPresent()) {
throw InvalidBundleException.builder().withUserMessage("Missing expected file in APEX bundle: '%s' or '%s'.", APEX_MANIFEST_PATH, APEX_MANIFEST_JSON_PATH).build();
}
validateApexManifestJson(apexManifest.get());
}
ImmutableSet.Builder<String> apexImagesBuilder = ImmutableSet.builder();
ImmutableSet.Builder<String> apexBuildInfosBuilder = ImmutableSet.builder();
ImmutableSet.Builder<String> apexFileNamesBuilder = ImmutableSet.builder();
for (ModuleEntry entry : module.getEntries()) {
ZipPath path = entry.getPath();
if (path.startsWith(APEX_DIRECTORY)) {
if (path.getFileName().toString().endsWith(BundleModule.APEX_IMAGE_SUFFIX)) {
apexImagesBuilder.add(path.toString());
apexFileNamesBuilder.add(path.getFileName().toString());
} else if (path.getFileName().toString().endsWith(BundleModule.BUILD_INFO_SUFFIX)) {
apexBuildInfosBuilder.add(path.toString());
} else {
throw InvalidBundleException.builder().withUserMessage("Unexpected file in apex directory of bundle: '%s'.", entry.getPath()).build();
}
} else if (!ALLOWED_APEX_FILES_OUTSIDE_APEX_DIRECTORY.contains(path)) {
throw InvalidBundleException.builder().withUserMessage("Unexpected file in APEX bundle: '%s'.", entry.getPath()).build();
}
}
ImmutableSet<String> apexBuildInfos = apexBuildInfosBuilder.build();
ImmutableSet<String> apexImages = apexImagesBuilder.build();
ImmutableSet<ImmutableSet<AbiName>> allAbiNameSets = apexFileNamesBuilder.build().stream().map(ApexBundleValidator::abiNamesFromFile).collect(toImmutableSet());
if (allAbiNameSets.size() != apexImages.size()) {
throw InvalidBundleException.builder().withUserMessage("Every APEX image file must target a unique set of architectures, " + "but found multiple files that target the same set of architectures.").build();
}
ImmutableSet<String> expectedImages = apexBuildInfos.stream().map(f -> f.replace(BundleModule.BUILD_INFO_SUFFIX, BundleModule.APEX_IMAGE_SUFFIX)).collect(toImmutableSet());
if (!apexBuildInfos.isEmpty() && !expectedImages.equals(apexImages)) {
throw InvalidBundleException.builder().withUserMessage("If APEX build info is provided then one must be provided for each APEX image file:\n" + " Expected %s\n" + " Found %s.", expectedImages, apexImages).build();
}
if (REQUIRED_ONE_OF_ABI_SETS.stream().anyMatch(one_of -> one_of.stream().noneMatch(allAbiNameSets::contains))) {
throw InvalidBundleException.builder().withUserMessage("APEX bundle must contain one of %s.", Joiner.on(" and one of ").join(REQUIRED_ONE_OF_ABI_SETS)).build();
}
module.getApexConfig().ifPresent(targeting -> validateTargeting(apexImages, targeting));
}
use of com.android.tools.build.bundletool.model.BundleModule in project bundletool by google.
the class AssetsTargetingValidator method validateTargeting.
private void validateTargeting(BundleModule module, Assets assets) {
ImmutableSet<ZipPath> assetDirsWithFiles = getDirectoriesWithFiles(module);
for (TargetedAssetsDirectory targetedDirectory : assets.getDirectoryList()) {
ZipPath path = ZipPath.create(targetedDirectory.getPath());
if (!path.startsWith(ASSETS_DIRECTORY)) {
throw InvalidBundleException.builder().withUserMessage("Path of targeted assets directory must start with 'assets/' but found '%s'.", path).build();
}
if (!assetDirsWithFiles.contains(path)) {
throw InvalidBundleException.builder().withUserMessage("Targeted directory '%s' is empty.", path).build();
}
checkNoDimensionWithoutValuesAndAlternatives(targetedDirectory);
}
if (module.getModuleType().equals(ModuleType.ASSET_MODULE) && assets.getDirectoryList().stream().anyMatch(dir -> dir.getTargeting().hasLanguage())) {
throw InvalidBundleException.builder().withUserMessage("Language targeting for asset packs is not supported, but found in module %s.", module.getName().getName()).build();
}
}
use of com.android.tools.build.bundletool.model.BundleModule in project bundletool by google.
the class BundleModulesValidator method validate.
public ImmutableList<BundleModule> validate(ImmutableList<ZipFile> moduleZips, BundleConfig bundleConfig) {
for (ZipFile moduleZip : moduleZips) {
new ValidatorRunner(MODULE_FILE_SUB_VALIDATORS).validateModuleZipFile(moduleZip);
}
ImmutableList<BundleModule> modules = moduleZips.stream().map(module -> toBundleModule(module, bundleConfig)).collect(toImmutableList());
new ValidatorRunner(MODULES_SUB_VALIDATORS).validateBundleModules(modules);
return modules;
}
use of com.android.tools.build.bundletool.model.BundleModule in project bundletool by google.
the class BundleModulesValidator method toBundleModule.
private BundleModule toBundleModule(ZipFile moduleZipFile, BundleConfig bundleConfig) {
BundleModule bundleModule = BundleModule.builder().setName(BundleModuleName.create("TEMPORARY_MODULE_NAME")).setBundleConfig(bundleConfig).addEntries(moduleZipFile.stream().filter(not(ZipEntry::isDirectory)).map(zipEntry -> ModuleEntry.builder().setPath(ZipPath.create(zipEntry.getName())).setContent(ZipUtils.asByteSource(moduleZipFile, zipEntry)).build()).collect(toImmutableList())).build();
BundleModuleName actualModuleName = bundleModule.getAndroidManifest().getSplitId().map(BundleModuleName::create).orElse(BundleModuleName.BASE_MODULE_NAME);
return bundleModule.toBuilder().setName(actualModuleName).build();
}
Aggregations