// Copyright 2017 The Bazel Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package com.google.devtools.build.android; import static java.util.stream.Collectors.toSet; import com.android.builder.core.VariantConfiguration; import com.google.common.collect.ImmutableList; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListeningExecutorService; import com.google.devtools.build.android.ResourceShrinkerAction.Options; import com.google.devtools.build.android.aapt2.Aapt2ConfigOptions; import com.google.devtools.build.android.aapt2.CompiledResources; import com.google.devtools.build.android.aapt2.ResourceCompiler; import com.google.devtools.build.android.aapt2.ResourceLinker; import com.google.devtools.build.android.aapt2.StaticLibrary; import com.google.devtools.common.options.Option; import com.google.devtools.common.options.OptionDocumentationCategory; import com.google.devtools.common.options.OptionEffectTag; import com.google.devtools.common.options.OptionsBase; import com.google.devtools.common.options.OptionsParser; import com.google.devtools.common.options.ShellQuotedParamsFilePreProcessor; import java.io.File; import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.function.Function; /** * An action to perform resource shrinking using the Gradle resource shrinker. * *
* Example Usage: * java/com/google/build/android/ResourceShrinkerAction * --aapt2 path to sdk/aapt2 * --androidJar path to sdk/androidJar * --shrunkJar path to proguard dead code removal jar * --resources path to processed resources zip * --rTxt path to processed resources R.txt * --primaryManifest path to processed resources AndroidManifest.xml * --dependencyManifest path to dependency library manifest (repeated flag) * --shrunkResourceApk path to write shrunk ap_ * --shrunkResources path to write shrunk resources zip **/ public class Aapt2ResourceShrinkingAction { /** Aapt2 shrinking specific options */ public static final class Aapt2ShrinkOptions extends OptionsBase { @Option( name = "useProtoApk", defaultValue = "false", category = "config", documentationCategory = OptionDocumentationCategory.UNCATEGORIZED, effectTags = {OptionEffectTag.UNKNOWN}, help = "Path to the shrunk jar from a Proguard run with shrinking enabled.") public boolean useProtoApk; } public static void main(String[] args) throws Exception { final Profiler profiler = LoggingProfiler.createAndStart("shrink").startTask("flags"); // Parse arguments. OptionsParser optionsParser = OptionsParser.newOptionsParser( ImmutableList.of(Options.class, Aapt2ConfigOptions.class, Aapt2ShrinkOptions.class)); optionsParser.enableParamsFileSupport( new ShellQuotedParamsFilePreProcessor(FileSystems.getDefault())); optionsParser.parseAndExitUponError(args); Aapt2ConfigOptions aapt2ConfigOptions = optionsParser.getOptions(Aapt2ConfigOptions.class); Options options = optionsParser.getOptions(Options.class); Aapt2ShrinkOptions aapt2ShrinkOptions = optionsParser.getOptions(Aapt2ShrinkOptions.class); profiler.recordEndOf("flags").startTask("setup"); try (ScopedTemporaryDirectory scopedTmp = new ScopedTemporaryDirectory("android_resources_tmp"); ExecutorServiceCloser executorService = ExecutorServiceCloser.createWithFixedPoolOf(15)) { final ResourcesZip resourcesZip = ResourcesZip.createFrom( options.resourcesZip, scopedTmp.subDirectoryOf("merged-resources")); Path workingResourcesDirectory = scopedTmp.subDirectoryOf("resources"); final ResourceLinker linker = ResourceLinker.create( aapt2ConfigOptions.aapt2, executorService, scopedTmp.subDirectoryOf("linking")) .profileUsing(profiler) .dependencies(ImmutableList.of(StaticLibrary.from(aapt2ConfigOptions.androidJar))); final Set