diff options
Diffstat (limited to 'src/tools/android/java/com/google')
4 files changed, 61 insertions, 99 deletions
diff --git a/src/tools/android/java/com/google/devtools/build/android/AndroidDataDeserializer.java b/src/tools/android/java/com/google/devtools/build/android/AndroidDataDeserializer.java index e9e1f3e22c..c42e870bbd 100644 --- a/src/tools/android/java/com/google/devtools/build/android/AndroidDataDeserializer.java +++ b/src/tools/android/java/com/google/devtools/build/android/AndroidDataDeserializer.java @@ -13,63 +13,24 @@ // limitations under the License. package com.google.devtools.build.android; -import com.android.ide.common.res2.MergingException; import com.google.common.base.Stopwatch; import com.google.common.collect.Maps; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.ListeningExecutorService; -import com.google.common.util.concurrent.MoreExecutors; -import com.google.devtools.build.android.ParsedAndroidData.Builder; import com.google.devtools.build.android.ParsedAndroidData.KeyValueConsumer; import com.google.devtools.build.android.proto.SerializeFormat; import com.google.devtools.build.android.proto.SerializeFormat.Header; -import java.io.Closeable; import java.io.IOException; import java.io.InputStream; import java.nio.file.FileSystem; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardOpenOption; -import java.util.ArrayList; -import java.util.List; import java.util.Map; import java.util.Map.Entry; -import java.util.concurrent.Callable; -import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.logging.Logger; /** Deserializes {@link DataKey}, {@link DataValue} entries from a binary file. */ public class AndroidDataDeserializer { - /** Task to deserialize resources from a path. */ - static final class Deserialize implements Callable<Boolean> { - - private final Path symbolPath; - - private final Builder finalDataBuilder; - private final AndroidDataDeserializer deserializer; - - private Deserialize( - AndroidDataDeserializer deserializer, Path symbolPath, Builder finalDataBuilder) { - this.deserializer = deserializer; - this.symbolPath = symbolPath; - this.finalDataBuilder = finalDataBuilder; - } - - @Override - public Boolean call() throws Exception { - final Builder parsedDataBuilder = ParsedAndroidData.Builder.newBuilder(); - deserializer.read(symbolPath, parsedDataBuilder.consumers()); - // The builder isn't threadsafe, so synchronize the copyTo call. - synchronized (finalDataBuilder) { - // All the resources are sorted before writing, so they can be aggregated in - // whatever order here. - parsedDataBuilder.copyTo(finalDataBuilder); - } - return Boolean.TRUE; - } - } - private static final Logger logger = Logger.getLogger(AndroidDataDeserializer.class.getName()); public static AndroidDataDeserializer create() { @@ -153,35 +114,4 @@ public class AndroidDataDeserializer { } } } - - /** Deserializes a list of serialized resource paths to a {@link ParsedAndroidData}. */ - public static ParsedAndroidData deserializeSymbolsToData(List<Path> symbolPaths) - throws IOException, MergingException { - AndroidDataDeserializer deserializer = create(); - final ListeningExecutorService executorService = - MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(15)); - final Builder deserializedDataBuilder = ParsedAndroidData.Builder.newBuilder(); - try (Closeable closeable = ExecutorServiceCloser.createWith(executorService)) { - List<ListenableFuture<Boolean>> deserializing = new ArrayList<>(); - for (final Path symbolPath : symbolPaths) { - deserializing.add( - executorService.submit( - new AndroidDataDeserializer.Deserialize( - deserializer, symbolPath, deserializedDataBuilder))); - } - FailedFutureAggregator<MergingException> aggregator = - FailedFutureAggregator.createForMergingExceptionWithMessage( - "Failure(s) during dependency parsing"); - aggregator.aggregateAndMaybeThrow(deserializing); - } - return deserializedDataBuilder.build(); - } - - public static ParsedAndroidData deserializeSingleAndroidData(SerializedAndroidData data) - throws MergingException { - final ParsedAndroidData.Builder builder = ParsedAndroidData.Builder.newBuilder(); - final AndroidDataDeserializer deserializer = create(); - data.deserialize(deserializer, builder.consumers()); - return builder.build(); - } } diff --git a/src/tools/android/java/com/google/devtools/build/android/AndroidResourceMerger.java b/src/tools/android/java/com/google/devtools/build/android/AndroidResourceMerger.java index e0a40362f7..0ab4c32275 100644 --- a/src/tools/android/java/com/google/devtools/build/android/AndroidResourceMerger.java +++ b/src/tools/android/java/com/google/devtools/build/android/AndroidResourceMerger.java @@ -28,13 +28,12 @@ import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.logging.Logger; -/** Collects all the functionality for an action to merge resources. */ -// TODO(bazel-team): Turn into an instance object, in order to use an external ExecutorService. +/** Collects all the functionationality for an action to merge resources. */ public class AndroidResourceMerger { static final Logger logger = Logger.getLogger(AndroidResourceProcessor.class.getName()); /** Merges all secondary resources with the primary resources. */ - public static MergedAndroidData mergeData( + static MergedAndroidData mergeData( final ParsedAndroidData primary, final Path primaryManifest, final List<? extends SerializedAndroidData> direct, @@ -50,14 +49,11 @@ public class AndroidResourceMerger { final ListeningExecutorService executorService = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(15)); try (Closeable closeable = ExecutorServiceCloser.createWith(executorService)) { + AndroidDataMerger merger = AndroidDataMerger.createWithPathDeduplictor(executorService); UnwrittenMergedAndroidData merged = - mergeData( - executorService, - transitive, - direct, - primary, - primaryManifest, - type != VariantType.LIBRARY); + merger.loadAndMerge( + transitive, direct, primary, primaryManifest, type != VariantType.LIBRARY); + logger.fine(String.format("merge finished in %sms", timer.elapsed(TimeUnit.MILLISECONDS))); timer.reset().start(); if (symbolsOut != null) { AndroidDataSerializer serializer = AndroidDataSerializer.create(); @@ -86,24 +82,6 @@ public class AndroidResourceMerger { } } - public static UnwrittenMergedAndroidData mergeData( - ListeningExecutorService executorService, - List<? extends SerializedAndroidData> transitive, - List<? extends SerializedAndroidData> direct, - ParsedAndroidData primary, - Path primaryManifest, - boolean allowPrimaryOverrideAll) - throws MergingException { - Stopwatch timer = Stopwatch.createStarted(); - try { - AndroidDataMerger merger = AndroidDataMerger.createWithPathDeduplictor(executorService); - return merger.loadAndMerge( - transitive, direct, primary, primaryManifest, allowPrimaryOverrideAll); - } finally { - logger.fine(String.format("merge finished in %sms", timer.elapsed(TimeUnit.MILLISECONDS))); - } - } - /** * Merges all secondary resources with the primary resources, given that the primary resources * have not yet been parsed and serialized. diff --git a/src/tools/android/java/com/google/devtools/build/android/AndroidResourceProcessor.java b/src/tools/android/java/com/google/devtools/build/android/AndroidResourceProcessor.java index 4da08f1ee3..e33928d19c 100644 --- a/src/tools/android/java/com/google/devtools/build/android/AndroidResourceProcessor.java +++ b/src/tools/android/java/com/google/devtools/build/android/AndroidResourceProcessor.java @@ -28,6 +28,7 @@ import com.android.builder.model.AaptOptions; import com.android.ide.common.internal.CommandLineRunner; import com.android.ide.common.internal.ExecutorSingleton; import com.android.ide.common.internal.LoggedErrorException; +import com.android.ide.common.res2.MergingException; import com.android.io.FileWrapper; import com.android.io.StreamException; import com.android.repository.Revision; @@ -45,6 +46,7 @@ import com.google.common.util.concurrent.ListeningExecutorService; import com.google.common.util.concurrent.MoreExecutors; import com.google.devtools.build.android.Converters.ExistingPathConverter; import com.google.devtools.build.android.Converters.RevisionConverter; +import com.google.devtools.build.android.ParsedAndroidData.Builder; import com.google.devtools.build.android.SplitConfigurationFilter.UnrecognizedSplitsException; import com.google.devtools.build.android.resources.RClassGenerator; import com.google.devtools.common.options.Converters.CommaSeparatedOptionListConverter; @@ -705,4 +707,55 @@ public class AndroidResourceProcessor { } return Files.createDirectories(out); } + + /** Deserializes a list of serialized resource paths to a {@link ParsedAndroidData}. */ + public ParsedAndroidData deserializeSymbolsToData(List<Path> symbolPaths) + throws IOException, MergingException { + AndroidDataDeserializer deserializer = AndroidDataDeserializer.create(); + final ListeningExecutorService executorService = + MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(15)); + final Builder deserializedDataBuilder = ParsedAndroidData.Builder.newBuilder(); + try (Closeable closeable = ExecutorServiceCloser.createWith(executorService)) { + List<ListenableFuture<Boolean>> deserializing = new ArrayList<>(); + for (final Path symbolPath : symbolPaths) { + deserializing.add( + executorService.submit( + new Deserialize(deserializer, symbolPath, deserializedDataBuilder))); + } + FailedFutureAggregator<MergingException> aggregator = + FailedFutureAggregator.createForMergingExceptionWithMessage( + "Failure(s) during dependency parsing"); + aggregator.aggregateAndMaybeThrow(deserializing); + } + return deserializedDataBuilder.build(); + } + + /** Task to deserialize resources from a path. */ + private static final class Deserialize implements Callable<Boolean> { + + private final Path symbolPath; + + private final Builder finalDataBuilder; + private final AndroidDataDeserializer deserializer; + + private Deserialize( + AndroidDataDeserializer deserializer, Path symbolPath, Builder finalDataBuilder) { + this.deserializer = deserializer; + this.symbolPath = symbolPath; + this.finalDataBuilder = finalDataBuilder; + } + + @Override + public Boolean call() throws Exception { + final Builder parsedDataBuilder = ParsedAndroidData.Builder.newBuilder(); + deserializer.read(symbolPath, parsedDataBuilder.consumers()); + // The builder isn't threadsafe, so synchronize the copyTo call. + synchronized (finalDataBuilder) { + // All the resources are sorted before writing, so they can be aggregated in + // whatever order here. + parsedDataBuilder.copyTo(finalDataBuilder); + } + return Boolean.TRUE; + } + } } diff --git a/src/tools/android/java/com/google/devtools/build/android/LibraryRClassGeneratorAction.java b/src/tools/android/java/com/google/devtools/build/android/LibraryRClassGeneratorAction.java index 1cb816c01e..51c771946b 100644 --- a/src/tools/android/java/com/google/devtools/build/android/LibraryRClassGeneratorAction.java +++ b/src/tools/android/java/com/google/devtools/build/android/LibraryRClassGeneratorAction.java @@ -93,10 +93,11 @@ public class LibraryRClassGeneratorAction { Strings.nullToEmpty(options.packageForR)); resourceClassWriter.setIncludeClassFile(true); resourceClassWriter.setIncludeJavaFile(false); + final AndroidResourceProcessor resourceProcessor = new AndroidResourceProcessor(stdLogger); logger.fine(String.format("Setup finished at %sms", timer.elapsed(TimeUnit.MILLISECONDS))); final ParsedAndroidData data = - AndroidDataDeserializer.deserializeSymbolsToData(options.symbols); + resourceProcessor.deserializeSymbolsToData(options.symbols); logger.fine( String.format("Deserialization finished at %sms", timer.elapsed(TimeUnit.MILLISECONDS))); |