diff options
author | corysmith <corysmith@google.com> | 2017-09-22 02:02:35 +0200 |
---|---|---|
committer | Damien Martin-Guillerez <dmarting@google.com> | 2017-09-22 12:16:02 +0200 |
commit | 54c86b4c6f29f4b0d52e1db702d30c10f3ac8b56 (patch) | |
tree | 08141e8298a2eadae818e7d8cce1198280e3c1be /src/tools/android/java/com/google/devtools/build/android/Aapt2ResourceShrinkingAction.java | |
parent | 87c70eef9cae2c2bb652ecc0baa16adb90a21eab (diff) |
Action for resource shrinking with aapt2
Introduces the ResourcesZip class to more easily handle processing merged resources.
RELNOTES: None
PiperOrigin-RevId: 169622715
Diffstat (limited to 'src/tools/android/java/com/google/devtools/build/android/Aapt2ResourceShrinkingAction.java')
-rw-r--r-- | src/tools/android/java/com/google/devtools/build/android/Aapt2ResourceShrinkingAction.java | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/src/tools/android/java/com/google/devtools/build/android/Aapt2ResourceShrinkingAction.java b/src/tools/android/java/com/google/devtools/build/android/Aapt2ResourceShrinkingAction.java new file mode 100644 index 0000000000..2fbae70f40 --- /dev/null +++ b/src/tools/android/java/com/google/devtools/build/android/Aapt2ResourceShrinkingAction.java @@ -0,0 +1,128 @@ +// 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.OptionsParser; +import java.io.Closeable; +import java.io.File; +import java.nio.file.Path; +import java.util.concurrent.ExecutionException; +import java.util.function.Function; + +/** + * An action to perform resource shrinking using the Gradle resource shrinker. + * + * <pre> + * Example Usage: + * java/com/google/build/android/ResourceShrinkerAction + * --aapt2 path to sdk/aapt2 + * --annotationJar path to sdk/annotationJar + * --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 + * </pre> + */ +public class Aapt2ResourceShrinkingAction { + + public static void main(String[] args) throws Exception { + final Profiler profiler = LoggingProfiler.createAndStart("shrink").startTask("flags"); + // Parse arguments. + OptionsParser optionsParser = + OptionsParser.newOptionsParser(Options.class, Aapt2ConfigOptions.class); + optionsParser.parseAndExitUponError(args); + Aapt2ConfigOptions aapt2ConfigOptions = optionsParser.getOptions(Aapt2ConfigOptions.class); + Options options = optionsParser.getOptions(Options.class); + options.dependencyManifests = + Converters.concatLists(options.dependencyManifests, options.deprecatedDependencyManifests); + profiler.recordEndOf("flags").startTask("setup"); + + final ListeningExecutorService executorService = ExecutorServiceCloser.createDefaultService(); + try (ScopedTemporaryDirectory scopedTmp = + new ScopedTemporaryDirectory("android_resources_tmp"); + Closeable closer = ExecutorServiceCloser.createWith(executorService)) { + + Path workingResourcesDirectory = scopedTmp.subDirectoryOf("resources"); + final ResourceCompiler resourceCompiler = + ResourceCompiler.create( + executorService, + workingResourcesDirectory, + aapt2ConfigOptions.aapt2, + aapt2ConfigOptions.buildToolsVersion); + profiler.recordEndOf("setup").startTask("compile"); + + final ResourcesZip resourcesZip = + ResourcesZip.createFrom( + options.resourcesZip, scopedTmp.subDirectoryOf("merged-resources")); + final CompiledResources compiled = + resourcesZip + .shrink( + options + .dependencyManifests + .stream() + .map(Path::toFile) + .map(manifestToPackageUsing(executorService)) + .map(futureToString()) + .collect(toSet()), + options.rTxt, + options.shrunkJar, + options.primaryManifest, + options.proguardMapping, + options.log, + scopedTmp.subDirectoryOf("shrunk-resources")) + .writeArchiveTo(options.shrunkResources, false) + .compile(resourceCompiler, workingResourcesDirectory); + profiler.recordEndOf("compile"); + + ResourceLinker.create(aapt2ConfigOptions.aapt2, scopedTmp.subDirectoryOf("linking")) + .profileUsing(profiler) + .dependencies(ImmutableList.of(StaticLibrary.from(aapt2ConfigOptions.androidJar))) + .link(compiled) + .copyPackageTo(options.shrunkApk) + .copyRTxtTo(options.rTxtOutput); + profiler.recordEndOf("shrink"); + } + } + + static Function<File, ListenableFuture<String>> manifestToPackageUsing( + ListeningExecutorService executor) { + return f -> executor.submit(() -> VariantConfiguration.getManifestPackage(f)); + } + + static Function<ListenableFuture<String>, String> futureToString() { + return f -> { + try { + return f.get(); + } catch (InterruptedException | ExecutionException e) { + throw new RuntimeException(e); + } + }; + } +} |