private SplittingPipeline createDexSplittingPipeline() { ImmutableList.Builder<ModuleSplitSplitter> dexSplitters = ImmutableList.builder(); if (apkGenerationConfiguration.getEnableDexCompressionSplitter()) { dexSplitters.add(new DexCompressionSplitter()); } return new SplittingPipeline(dexSplitters.build()); }
/** * Generates a single {@link ModuleSplit} setting the compression of dex entries. * * <p>Dex entries are only compressed for pre P devices. */ @Override public ImmutableCollection<ModuleSplit> split(ModuleSplit moduleSplit) { ImmutableSet<ModuleEntry> dexEntries = moduleSplit.getEntries().stream() .filter(entry -> entry.getPath().startsWith(DEX_DIRECTORY)) .collect(toImmutableSet()); if (dexEntries.isEmpty()) { return ImmutableList.of(moduleSplit); } // Only APKs targeting devices below Android P should be compressed. boolean shouldCompress = targetsPreP(moduleSplit); return ImmutableList.of( createModuleSplit( moduleSplit, mergeAndSetCompression(dexEntries, moduleSplit, shouldCompress))); }
@Test public void dexCompressionSplitter_preP_withDexFiles() throws Exception { DexCompressionSplitter dexCompressionSplitter = new DexCompressionSplitter(); ImmutableCollection<ModuleSplit> splits = dexCompressionSplitter.split( ModuleSplit.forDex(createModuleWithDexFile(), variantSdkTargeting(27))); assertThat(splits).hasSize(1); ModuleSplit moduleSplit = Iterables.getOnlyElement(splits); assertThat(moduleSplit.getVariantTargeting()).isEqualTo(variantSdkTargeting(27)); assertThat(extractPaths(moduleSplit.getEntries())).containsExactly("dex/classes.dex"); assertThat(isCompressed(moduleSplit, "dex/classes.dex")).isTrue(); assertThat(splits.asList().get(0)).isEqualTo(moduleSplit); }
@Test public void dexCompressionSplitter_withP_noDexFiles() throws Exception { DexCompressionSplitter dexCompressionSplitter = new DexCompressionSplitter(); ModuleSplit moduleSplit = ModuleSplit.forModule( new BundleModuleBuilder("testModule") .addFile("lib/x86_64/libsome.so") .addFile("assets/leftover.txt") .setManifest(androidManifest("com.test.app")) .build(), variantSdkTargeting(ANDROID_P_API_VERSION)); ImmutableCollection<ModuleSplit> splits = dexCompressionSplitter.split(moduleSplit); assertThat(splits).hasSize(1); assertThat(splits.asList().get(0)).isEqualTo(moduleSplit); }
@Test public void dexCompressionSplitter_withP_withDexFiles() throws Exception { DexCompressionSplitter dexCompressionSplitter = new DexCompressionSplitter(); ImmutableCollection<ModuleSplit> splits = dexCompressionSplitter.split( ModuleSplit.forDex( createModuleWithDexFile(), variantSdkTargeting(ANDROID_P_API_VERSION))); assertThat(splits).hasSize(1); ModuleSplit moduleSplit = Iterables.getOnlyElement(splits); assertThat(moduleSplit.getVariantTargeting()) .isEqualTo(variantSdkTargeting(ANDROID_P_API_VERSION)); assertThat(extractPaths(moduleSplit.getEntries())).containsExactly("dex/classes.dex"); assertThat(moduleSplit.isMasterSplit()).isTrue(); assertThat(isCompressed(moduleSplit, "dex/classes.dex")).isFalse(); assertThat(moduleSplit.getApkTargeting()).isEqualToDefaultInstance(); }
@Test public void dexCompressionSplitter_withP_otherEntriesCompressionUnchanged() throws Exception { DexCompressionSplitter dexCompressionSplitter = new DexCompressionSplitter(); BundleModule bundleModule = createModuleBuilderWithDexFile() .addFile("lib/x86_64/libsome.so") .addFile("assets/leftover.txt") .build(); ImmutableCollection<ModuleSplit> splits = dexCompressionSplitter.split( ModuleSplit.forModule(bundleModule, variantSdkTargeting(ANDROID_P_API_VERSION))); assertThat(splits).hasSize(1); ModuleSplit moduleSplit = Iterables.getOnlyElement(splits); assertThat(moduleSplit.getVariantTargeting()) .isEqualTo(variantSdkTargeting(ANDROID_P_API_VERSION)); assertThat(extractPaths(moduleSplit.getEntries())) .containsExactly("lib/x86_64/libsome.so", "assets/leftover.txt", "dex/classes.dex"); assertThat(moduleSplit.isMasterSplit()).isTrue(); assertThat(isCompressed(moduleSplit, "dex/classes.dex")).isFalse(); assertThat(isCompressed(moduleSplit, "lib/x86_64/libsome.so")).isTrue(); assertThat(isCompressed(moduleSplit, "assets/leftover.txt")).isTrue(); assertThat(moduleSplit.getApkTargeting()).isEqualToDefaultInstance(); }