aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/AndroidResourceProcessingAction.java10
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/AndroidResourceProcessor.java66
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/BUILD1
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/ResourceShrinkerAction.java3
4 files changed, 76 insertions, 4 deletions
diff --git a/src/tools/android/java/com/google/devtools/build/android/AndroidResourceProcessingAction.java b/src/tools/android/java/com/google/devtools/build/android/AndroidResourceProcessingAction.java
index 14f43f9b25..7983256ec6 100644
--- a/src/tools/android/java/com/google/devtools/build/android/AndroidResourceProcessingAction.java
+++ b/src/tools/android/java/com/google/devtools/build/android/AndroidResourceProcessingAction.java
@@ -117,6 +117,13 @@ public class AndroidResourceProcessingAction {
help = "Path to where the symbolsTxt should be written.")
public Path symbolsTxtOut;
+ @Option(name = "dataBindingInfoOut",
+ defaultValue = "null",
+ converter = PathConverter.class,
+ category = "output",
+ help = "Path to where data binding's layout info output should be written.")
+ public Path dataBindingInfoOut;
+
@Option(name = "packagePath",
defaultValue = "null",
converter = PathConverter.class,
@@ -306,7 +313,8 @@ public class AndroidResourceProcessingAction {
options.mainDexProguardOutput,
options.resourcesOutput != null
? processedData.getResourceDir().resolve("values").resolve("public.xml")
- : null);
+ : null,
+ options.dataBindingInfoOut);
logger.fine(String.format("aapt finished at %sms", timer.elapsed(TimeUnit.MILLISECONDS)));
if (options.srcJarOutput != null) {
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 53a7057fc6..d5194a098d 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
@@ -15,7 +15,10 @@ package com.google.devtools.build.android;
import static java.nio.charset.StandardCharsets.UTF_8;
+import android.databinding.AndroidDataBinding;
+import android.databinding.cli.ProcessXmlOptions;
import com.android.annotations.Nullable;
+import com.android.builder.core.DefaultManifestParser;
import com.android.builder.core.VariantConfiguration;
import com.android.builder.dependency.SymbolFileProvider;
import com.android.builder.internal.SymbolLoader;
@@ -414,10 +417,13 @@ public class AndroidResourceProcessor {
Path packageOut,
Path proguardOut,
Path mainDexProguardOut,
- Path publicResourcesOut)
+ Path publicResourcesOut,
+ Path dataBindingInfoOut)
throws IOException, InterruptedException, LoggedErrorException, UnrecognizedSplitsException {
Path androidManifest = primaryData.getManifest();
- final Path resourceDir = primaryData.getResourceDir();
+ final Path resourceDir = processDataBindings(primaryData.getResourceDir(), dataBindingInfoOut,
+ variantType, customPackageForR, androidManifest);
+
final Path assetsDir = primaryData.getAssetDir();
if (publicResourcesOut != null) {
prepareOutputPath(publicResourcesOut.getParent());
@@ -542,6 +548,62 @@ public class AndroidResourceProcessor {
return outputWithSourceContext;
}
+ /**
+ * If resources exist and a data binding layout info file is requested: processes data binding
+ * declarations over those resources, populates the output file, and creates a new resources
+ * directory with data binding expressions stripped out (so aapt, which doesn't understand
+ * data binding, can properly read them).
+ *
+ * <p>Returns the resources directory that aapt should read.
+ */
+ private Path processDataBindings(Path resourceDir, Path dataBindingInfoOut,
+ VariantConfiguration.Type variantType, String packagePath, Path androidManifest)
+ throws IOException {
+
+ if (dataBindingInfoOut == null) {
+ return resourceDir;
+ } else if (!Files.isDirectory(resourceDir)) {
+ // No resources: no data binding needed. Create a dummy file to satisfy declared outputs.
+ Files.createFile(dataBindingInfoOut);
+ return resourceDir;
+ }
+
+ // Strip the file name (the data binding library automatically adds it back in).
+ // ** The data binding library assumes this file is called "layout-info.zip". **
+ dataBindingInfoOut = dataBindingInfoOut.getParent();
+ if (Files.notExists(dataBindingInfoOut)) {
+ Files.createDirectory(dataBindingInfoOut);
+ }
+
+ Path processedResourceDir = resourceDir.resolveSibling("res_without_databindings");
+ if (Files.notExists(processedResourceDir)) {
+ Files.createDirectory(processedResourceDir);
+ }
+
+ ProcessXmlOptions options = new ProcessXmlOptions();
+ options.setAppId(packagePath);
+ options.setLibrary(variantType == VariantConfiguration.Type.LIBRARY);
+ options.setResInput(resourceDir.toFile());
+ options.setResOutput(processedResourceDir.toFile());
+ options.setLayoutInfoOutput(dataBindingInfoOut.toFile());
+ options.setZipLayoutInfo(true); // Aggregate data-bound .xml files into a single .zip.
+
+ Object minSdk = new DefaultManifestParser().getMinSdkVersion(androidManifest.toFile());
+ if (minSdk instanceof Integer) {
+ options.setMinSdk(((Integer) minSdk).intValue());
+ } else {
+ // TODO(bazel-team): Enforce the minimum SDK check.
+ options.setMinSdk(15);
+ }
+
+ try {
+ AndroidDataBinding.doRun(options);
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ return processedResourceDir;
+ }
+
/** Task to parse java package from AndroidManifest.xml */
private static final class PackageParsingTask implements Callable<String> {
diff --git a/src/tools/android/java/com/google/devtools/build/android/BUILD b/src/tools/android/java/com/google/devtools/build/android/BUILD
index aac3a058fa..f4b5689623 100644
--- a/src/tools/android/java/com/google/devtools/build/android/BUILD
+++ b/src/tools/android/java/com/google/devtools/build/android/BUILD
@@ -80,6 +80,7 @@ java_library(
"//third_party:asm",
"//third_party:guava",
"//third_party:jsr305",
+ "//third_party/java/android_databinding:exec",
"//third_party/protobuf",
],
)
diff --git a/src/tools/android/java/com/google/devtools/build/android/ResourceShrinkerAction.java b/src/tools/android/java/com/google/devtools/build/android/ResourceShrinkerAction.java
index ea5f1225ff..4d0498533f 100644
--- a/src/tools/android/java/com/google/devtools/build/android/ResourceShrinkerAction.java
+++ b/src/tools/android/java/com/google/devtools/build/android/ResourceShrinkerAction.java
@@ -234,7 +234,8 @@ public class ResourceShrinkerAction {
options.shrunkApk,
null /* proguardOutput */,
null /* mainDexProguardOutput */,
- null /* publicResourcesOut */);
+ null /* publicResourcesOut */,
+ null /* dataBindingInfoOut */);
if (options.shrunkResources != null) {
resourceProcessor.createResourcesZip(shrunkResources, resourceFiles.resolve("assets"),
options.shrunkResources);