Search in sources :

Example 1 with GeneratedApks

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

the class BuildApksManager method execute.

public void execute() throws IOException {
    ImmutableSet<BundleModuleName> permanentlyFusedModules = ImmutableSet.of();
    ImmutableSet<BundleModule> requestedModules = command.getModules().isEmpty() ? ImmutableSet.of() : ModuleDependenciesUtils.getModulesIncludingDependencies(appBundle, getBundleModules(appBundle, command.getModules()));
    GeneratedApks.Builder generatedApksBuilder = GeneratedApks.builder();
    GeneratedAssetSlices.Builder generatedAssetSlices = GeneratedAssetSlices.builder();
    boolean enableUniversalAsFallbackForSplits = false;
    boolean enableInstallTimeNonRemovableModules = false;
    ApksToGenerate apksToGenerate = new ApksToGenerate(appBundle, command.getApkBuildMode(), enableUniversalAsFallbackForSplits, deviceSpec);
    // Split APKs
    if (apksToGenerate.generateSplitApks()) {
        AppBundle mergedAppBundle = BundleModuleMerger.mergeNonRemovableInstallTimeModules(appBundle, enableInstallTimeNonRemovableModules);
        AppBundleValidator bundleValidator = AppBundleValidator.create(command.getExtraValidators());
        bundleValidator.validate(mergedAppBundle);
        generatedApksBuilder.setSplitApks(generateSplitApks(mergedAppBundle));
        permanentlyFusedModules = Sets.difference(appBundle.getModules().keySet(), mergedAppBundle.getModules().keySet()).immutableCopy();
    }
    // Instant APKs
    if (apksToGenerate.generateInstantApks()) {
        generatedApksBuilder.setInstantApks(generateInstantApks(appBundle));
    }
    // Standalone APKs
    if (apksToGenerate.generateStandaloneApks()) {
        generatedApksBuilder.setStandaloneApks(generateStandaloneApks(appBundle));
    }
    // Universal APK
    if (apksToGenerate.generateUniversalApk()) {
        // Note: Universal APK is a special type of standalone, with no optimization dimensions.
        ImmutableList<BundleModule> modulesToFuse = requestedModules.isEmpty() ? modulesToFuse(getModulesForStandaloneApks(appBundle)) : requestedModules.asList();
        generatedApksBuilder.setStandaloneApks(shardedApksFacade.generateSplits(modulesToFuse, ApkOptimizations.getOptimizationsForUniversalApk()));
    }
    // System APKs
    if (apksToGenerate.generateSystemApks()) {
        generatedApksBuilder.setSystemApks(generateSystemApks(appBundle, requestedModules));
    }
    // Archived APKs
    if (apksToGenerate.generateArchivedApks()) {
        generatedApksBuilder.setArchivedApks(generateArchivedApks(appBundle));
    }
    // Asset Slices
    if (apksToGenerate.generateAssetSlices()) {
        generatedAssetSlices.setAssetSlices(generateAssetSlices(appBundle));
    }
    // Populate alternative targeting based on variant targeting of all APKs.
    GeneratedApks generatedApks = AlternativeVariantTargetingPopulator.populateAlternativeVariantTargeting(generatedApksBuilder.build(), appBundle.isAssetOnly() ? Optional.empty() : appBundle.getBaseModule().getAndroidManifest().getMaxSdkVersion());
    // A variant is a set of APKs. One device is guaranteed to receive only APKs from the same. This
    // is why we are processing new entries like split.xml for each variant separately.
    generatedApks = GeneratedApks.fromModuleSplits(generatedApks.getAllApksGroupedByOrderedVariants().asMap().entrySet().stream().map(keySplit -> {
        SplitsXmlInjector splitsXmlInjector = new SplitsXmlInjector();
        ImmutableList<ModuleSplit> moduleSplits = splitsXmlInjector.process(keySplit.getKey(), keySplit.getValue());
        LocaleConfigXmlInjector localeConfigXmlInjector = new LocaleConfigXmlInjector();
        moduleSplits = localeConfigXmlInjector.process(keySplit.getKey(), moduleSplits);
        return moduleSplits;
    }).flatMap(Collection::stream).collect(toImmutableList()));
    if (deviceSpec.isPresent()) {
        // It is easier to fully check device compatibility once the splits have been generated (in
        // memory). Note that no costly I/O happened up until this point, so it's not too late for
        // this check.
        checkDeviceCompatibilityWithBundle(generatedApks, deviceSpec.get());
    }
    if (command.getOverwriteOutput() && Files.exists(command.getOutputFile())) {
        MoreFiles.deleteRecursively(command.getOutputFile(), RecursiveDeleteOption.ALLOW_INSECURE);
    }
    // Create variants and serialize APKs.
    apkSerializerManager.serializeApkSet(createApkSetWriter(tempDir.getPath()), generatedApks, generatedAssetSlices.build(), deviceSpec, getLocalTestingInfo(appBundle), permanentlyFusedModules);
}
Also used : BundleModuleName(com.android.tools.build.bundletool.model.BundleModuleName) AppBundle(com.android.tools.build.bundletool.model.AppBundle) AppBundleValidator(com.android.tools.build.bundletool.validation.AppBundleValidator) GeneratedApks(com.android.tools.build.bundletool.model.GeneratedApks) ModuleSplit(com.android.tools.build.bundletool.model.ModuleSplit) BundleModule(com.android.tools.build.bundletool.model.BundleModule) SplitsXmlInjector(com.android.tools.build.bundletool.model.utils.SplitsXmlInjector) GeneratedAssetSlices(com.android.tools.build.bundletool.model.GeneratedAssetSlices) LocaleConfigXmlInjector(com.android.tools.build.bundletool.model.utils.LocaleConfigXmlInjector)

Example 2 with GeneratedApks

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

the class AlternativeVariantTargetingPopulatorTest method instantPassThrough.

@Test
public void instantPassThrough() throws Exception {
    SdkVersion lPlusVersion = sdkVersionFrom(Versions.ANDROID_L_API_VERSION);
    VariantTargeting lPlusTargeting = variantSdkTargeting(lPlusVersion);
    VariantTargeting emptySdkTargeting = variantSdkTargeting(SdkVersion.getDefaultInstance());
    // Post-L splits with 1 module.
    ImmutableList<ModuleSplit> postLSplits = ImmutableList.of(createModuleSplit(lPlusTargeting));
    // Post-L instant splits with 2 modules
    ImmutableList<ModuleSplit> instantSplits = ImmutableList.of(createModuleSplit(lPlusTargeting, SplitType.INSTANT), createModuleSplit(lPlusTargeting, SplitType.INSTANT));
    // 1 density shard.
    ImmutableList<ModuleSplit> standaloneShards = ImmutableList.of(createStandaloneModuleSplit(mergeVariantTargeting(emptySdkTargeting, variantDensityTargeting(DensityAlias.XHDPI))));
    GeneratedApks generatedApks = GeneratedApks.builder().setStandaloneApks(standaloneShards).setInstantApks(instantSplits).setSplitApks(postLSplits).build();
    GeneratedApks processedApks = AlternativeVariantTargetingPopulator.populateAlternativeVariantTargeting(generatedApks);
    assertThat(processedApks.size()).isEqualTo(4);
    ImmutableCollection<ModuleSplit> processedSplits = processedApks.getSplitApks();
    assertThat(processedSplits).hasSize(1);
    ImmutableCollection<ModuleSplit> processedShards = processedApks.getStandaloneApks();
    assertThat(processedShards).hasSize(1);
    ImmutableCollection<ModuleSplit> processedInstantSplits = processedApks.getInstantApks();
    assertThat(processedInstantSplits).containsExactlyElementsIn(instantSplits);
}
Also used : GeneratedApks(com.android.tools.build.bundletool.model.GeneratedApks) SdkVersion(com.android.bundle.Targeting.SdkVersion) ModuleSplit(com.android.tools.build.bundletool.model.ModuleSplit) TargetingUtils.mergeVariantTargeting(com.android.tools.build.bundletool.testing.TargetingUtils.mergeVariantTargeting) VariantTargeting(com.android.bundle.Targeting.VariantTargeting) Test(org.junit.Test)

Example 3 with GeneratedApks

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

the class AlternativeVariantTargetingPopulatorTest method archivedApksPassThrough.

@Test
public void archivedApksPassThrough() {
    VariantTargeting emptySdkTargeting = variantSdkTargeting(SdkVersion.getDefaultInstance());
    ImmutableList<ModuleSplit> archivedSplits = ImmutableList.of(createModuleSplit(emptySdkTargeting, SplitType.ARCHIVE));
    GeneratedApks generatedApks = GeneratedApks.builder().setArchivedApks(archivedSplits).build();
    GeneratedApks processedApks = AlternativeVariantTargetingPopulator.populateAlternativeVariantTargeting(generatedApks);
    assertThat(processedApks.size()).isEqualTo(1);
    assertThat(processedApks.getInstantApks()).isEmpty();
    assertThat(processedApks.getStandaloneApks()).isEmpty();
    assertThat(processedApks.getSplitApks()).isEmpty();
    assertThat(processedApks.getSystemApks()).isEmpty();
    assertThat(processedApks.getArchivedApks()).isEqualTo(archivedSplits);
}
Also used : GeneratedApks(com.android.tools.build.bundletool.model.GeneratedApks) ModuleSplit(com.android.tools.build.bundletool.model.ModuleSplit) TargetingUtils.mergeVariantTargeting(com.android.tools.build.bundletool.testing.TargetingUtils.mergeVariantTargeting) VariantTargeting(com.android.bundle.Targeting.VariantTargeting) Test(org.junit.Test)

Example 4 with GeneratedApks

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

the class SplitsXmlInjectorTest method process_standaloneSplitTypes.

@Test
public void process_standaloneSplitTypes() throws Exception {
    ModuleSplit standalone = createModuleSplit(BASE_MODULE_NAME.getName(), /* splitId= */
    "", /* masterSplit= */
    true, STANDALONE, /* languageTargeting= */
    null);
    ResourceTable standaloneResourceTable = new ResourceTableBuilder().addPackage("com.example.app").addStringResourceForMultipleLocales("title", ImmutableMap.of("ru-RU", "title ru-RU", "fr", "title fr")).build();
    standalone = standalone.toBuilder().setResourceTable(standaloneResourceTable).build();
    GeneratedApks generatedApks = GeneratedApks.fromModuleSplits(ImmutableList.of(standalone));
    ModuleSplit processedStandalone = xmlInjectorProcess(generatedApks).stream().collect(onlyElement());
    assertThat(processedStandalone.getAndroidManifest().getMetadataResourceId("com.android.vending.splits")).hasValue(0x7f020000);
    assertThat(processedStandalone.getResourceTable().get()).containsResource("com.example.app:xml/splits0").withFileReference("res/xml/splits0.xml");
    XmlNode expectedSplitsProtoXml = new SplitsProtoXmlBuilder().addLanguageMapping(BASE_MODULE_NAME, "ru", "").addLanguageMapping(BASE_MODULE_NAME, "fr", "").build();
    assertThat(XmlNode.parseFrom(processedStandalone.getEntries().get(0).getContent().read())).ignoringRepeatedFieldOrder().isEqualTo(expectedSplitsProtoXml);
}
Also used : XmlNode(com.android.aapt.Resources.XmlNode) GeneratedApks(com.android.tools.build.bundletool.model.GeneratedApks) SplitsProtoXmlBuilder(com.android.tools.build.bundletool.model.SplitsProtoXmlBuilder) ModuleSplit(com.android.tools.build.bundletool.model.ModuleSplit) ResourceTableBuilder(com.android.tools.build.bundletool.testing.ResourceTableBuilder) ResourceTable(com.android.aapt.Resources.ResourceTable) Test(org.junit.Test)

Example 5 with GeneratedApks

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

the class AlternativeVariantTargetingPopulatorTest method splitAndStandalones_addsAlternatives_withMaxSdk.

@Test
public void splitAndStandalones_addsAlternatives_withMaxSdk() throws Exception {
    SdkVersion lPlusVersion = sdkVersionFrom(Versions.ANDROID_L_API_VERSION);
    VariantTargeting lPlusTargeting = variantSdkTargeting(lPlusVersion);
    VariantTargeting emptySdkTargeting = variantSdkTargeting(SdkVersion.getDefaultInstance());
    // Post-L splits with 1 module.
    ImmutableList<ModuleSplit> postLSplits = ImmutableList.of(createModuleSplit(lPlusTargeting));
    // 2 density shards.
    ImmutableList<ModuleSplit> standaloneShards = ImmutableList.of(createStandaloneModuleSplit(mergeVariantTargeting(emptySdkTargeting, variantDensityTargeting(DensityAlias.HDPI))), createStandaloneModuleSplit(mergeVariantTargeting(emptySdkTargeting, variantDensityTargeting(DensityAlias.XHDPI))));
    GeneratedApks generatedApks = GeneratedApks.builder().setStandaloneApks(standaloneShards).setSplitApks(postLSplits).build();
    GeneratedApks processedApks = AlternativeVariantTargetingPopulator.populateAlternativeVariantTargeting(generatedApks, /* maxSdkVersion= */
    23);
    assertThat(processedApks.size()).isEqualTo(3);
    ImmutableCollection<ModuleSplit> processedShards = processedApks.getStandaloneApks();
    assertThat(processedShards).hasSize(2);
    assertThat(processedShards.stream().map(ModuleSplit::getVariantTargeting).collect(toImmutableSet())).containsExactly(mergeVariantTargeting(variantSdkTargeting(SdkVersion.getDefaultInstance(), ImmutableSet.of(lPlusVersion, sdkVersionFrom(24))), variantDensityTargeting(DensityAlias.HDPI, ImmutableSet.of(DensityAlias.XHDPI))), mergeVariantTargeting(variantSdkTargeting(SdkVersion.getDefaultInstance(), ImmutableSet.of(lPlusVersion, sdkVersionFrom(24))), variantDensityTargeting(DensityAlias.XHDPI, ImmutableSet.of(DensityAlias.HDPI))));
    assertThat(processedApks.getSplitApks()).hasSize(1);
    assertThat(processedApks.getSplitApks().get(0).getVariantTargeting()).ignoringRepeatedFieldOrder().isEqualTo(variantSdkTargeting(lPlusVersion, ImmutableSet.of(SdkVersion.getDefaultInstance(), sdkVersionFrom(24))));
}
Also used : GeneratedApks(com.android.tools.build.bundletool.model.GeneratedApks) SdkVersion(com.android.bundle.Targeting.SdkVersion) ModuleSplit(com.android.tools.build.bundletool.model.ModuleSplit) TargetingUtils.mergeVariantTargeting(com.android.tools.build.bundletool.testing.TargetingUtils.mergeVariantTargeting) VariantTargeting(com.android.bundle.Targeting.VariantTargeting) Test(org.junit.Test)

Aggregations

GeneratedApks (com.android.tools.build.bundletool.model.GeneratedApks)13 ModuleSplit (com.android.tools.build.bundletool.model.ModuleSplit)13 Test (org.junit.Test)10 VariantTargeting (com.android.bundle.Targeting.VariantTargeting)9 ResourceTable (com.android.aapt.Resources.ResourceTable)5 BundleModuleName (com.android.tools.build.bundletool.model.BundleModuleName)5 ResourceTableBuilder (com.android.tools.build.bundletool.testing.ResourceTableBuilder)5 TargetingUtils.mergeVariantTargeting (com.android.tools.build.bundletool.testing.TargetingUtils.mergeVariantTargeting)5 XmlNode (com.android.aapt.Resources.XmlNode)4 AndroidManifest (com.android.tools.build.bundletool.model.AndroidManifest)4 SplitType (com.android.tools.build.bundletool.model.ModuleSplit.SplitType)4 SplitsProtoXmlBuilder (com.android.tools.build.bundletool.model.SplitsProtoXmlBuilder)4 ImmutableList (com.google.common.collect.ImmutableList)4 ImmutableList.toImmutableList (com.google.common.collect.ImmutableList.toImmutableList)4 ImmutableMap (com.google.common.collect.ImmutableMap)4 Optional (java.util.Optional)4 ApkTargeting (com.android.bundle.Targeting.ApkTargeting)3 LanguageTargeting (com.android.bundle.Targeting.LanguageTargeting)3 BASE_MODULE_NAME (com.android.tools.build.bundletool.model.BundleModuleName.BASE_MODULE_NAME)3 ModuleEntry (com.android.tools.build.bundletool.model.ModuleEntry)3