summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYigit Boyar <yboyar@google.com>2015-11-10 18:16:36 -0800
committerYigit Boyar <yboyar@google.com>2015-11-11 13:18:22 -0800
commit28e7064d455e2ef9da31c817dfc05ec7405c60df (patch)
tree82dcf9066526452f185cbddcc189b3c43c6a235c
parentfccc888b6465488b9ad74f4ca0b58c85502ae089 (diff)
downloaddata-binding-28e7064d455e2ef9da31c817dfc05ec7405c60df.tar.gz
Override layout file metadata from module
If a layout file is inherited from a module but also exists in the app, w~e force the app version to the metadata of the module version. This means forcing its created class location to be the same as the module. This usually happens when gradle or aapt generates some layout during app compilation. Bug: 25369165 Change-Id: I5d2002ac04d16cfe9935fe5580548344b19b4aca
-rw-r--r--compiler/src/main/java/android/databinding/annotationprocessor/ProcessDataBinding.java12
-rw-r--r--compiler/src/main/java/android/databinding/annotationprocessor/ProcessExpressions.java131
-rw-r--r--compilerCommon/src/main/java/android/databinding/tool/LayoutXmlProcessor.java39
-rw-r--r--compilerCommon/src/main/java/android/databinding/tool/store/ResourceBundle.java52
-rw-r--r--integration-tests/IndependentLibrary/app/src/main/res/layout-sw600dp-land/library_layout.xml29
-rw-r--r--integration-tests/MultiModuleTestApp/app/src/androidTest/java/com/android/databinding/multimoduletestapp/EventIdsTest.java1
-rw-r--r--integration-tests/MultiModuleTestApp/app/src/androidTest/java/com/android/databinding/multimoduletestapp/GeneratedLayoutTest.java56
7 files changed, 251 insertions, 69 deletions
diff --git a/compiler/src/main/java/android/databinding/annotationprocessor/ProcessDataBinding.java b/compiler/src/main/java/android/databinding/annotationprocessor/ProcessDataBinding.java
index d63ec410..4d1fadb3 100644
--- a/compiler/src/main/java/android/databinding/annotationprocessor/ProcessDataBinding.java
+++ b/compiler/src/main/java/android/databinding/annotationprocessor/ProcessDataBinding.java
@@ -20,6 +20,7 @@ import android.databinding.BindingBuildInfo;
import android.databinding.tool.CompilerChef;
import android.databinding.tool.processing.Scope;
import android.databinding.tool.reflection.ModelAnalyzer;
+import android.databinding.tool.util.L;
import android.databinding.tool.util.Preconditions;
import android.databinding.tool.writer.AnnotationJavaFileWriter;
import android.databinding.tool.writer.BRWriter;
@@ -35,6 +36,7 @@ import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.TypeElement;
+import javax.xml.bind.JAXBException;
@SupportedAnnotationTypes({
"android.databinding.BindingAdapter",
@@ -60,7 +62,11 @@ public class ProcessDataBinding extends AbstractProcessor {
}
boolean done = true;
for (ProcessingStep step : mProcessingSteps) {
- done = step.runStep(roundEnv, processingEnv, buildInfo) && done;
+ try {
+ done = step.runStep(roundEnv, processingEnv, buildInfo) && done;
+ } catch (JAXBException e) {
+ L.e(e, "Exception while handling step %s", step);
+ }
}
if (roundEnv.processingOver()) {
for (ProcessingStep step : mProcessingSteps) {
@@ -141,7 +147,7 @@ public class ProcessDataBinding extends AbstractProcessor {
private boolean runStep(RoundEnvironment roundEnvironment,
ProcessingEnvironment processingEnvironment,
- BindingBuildInfo buildInfo) {
+ BindingBuildInfo buildInfo) throws JAXBException {
if (mDone) {
return true;
}
@@ -156,7 +162,7 @@ public class ProcessDataBinding extends AbstractProcessor {
*/
abstract public boolean onHandleStep(RoundEnvironment roundEnvironment,
ProcessingEnvironment processingEnvironment,
- BindingBuildInfo buildInfo);
+ BindingBuildInfo buildInfo) throws JAXBException;
/**
* Invoked when processing is done. A good place to generate the output if the
diff --git a/compiler/src/main/java/android/databinding/annotationprocessor/ProcessExpressions.java b/compiler/src/main/java/android/databinding/annotationprocessor/ProcessExpressions.java
index 26706a6a..0fca9c0f 100644
--- a/compiler/src/main/java/android/databinding/annotationprocessor/ProcessExpressions.java
+++ b/compiler/src/main/java/android/databinding/annotationprocessor/ProcessExpressions.java
@@ -23,17 +23,21 @@ import org.apache.commons.lang3.SystemUtils;
import android.databinding.BindingBuildInfo;
import android.databinding.tool.CompilerChef;
+import android.databinding.tool.LayoutXmlProcessor;
import android.databinding.tool.reflection.SdkUtil;
import android.databinding.tool.store.ResourceBundle;
import android.databinding.tool.util.GenerationalClassUtil;
import android.databinding.tool.util.L;
+import android.databinding.tool.util.Preconditions;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -50,30 +54,55 @@ public class ProcessExpressions extends ProcessDataBinding.ProcessingStep {
@Override
public boolean onHandleStep(RoundEnvironment roundEnvironment,
- ProcessingEnvironment processingEnvironment, BindingBuildInfo buildInfo) {
+ ProcessingEnvironment processingEnvironment, BindingBuildInfo buildInfo)
+ throws JAXBException {
ResourceBundle resourceBundle;
SdkUtil.initialize(buildInfo.minSdk(), new File(buildInfo.sdkRoot()));
resourceBundle = new ResourceBundle(buildInfo.modulePackage());
- List<Intermediate> intermediateList =
- GenerationalClassUtil.loadObjects(
- GenerationalClassUtil.ExtensionFilter.LAYOUT);
- IntermediateV1 mine = createIntermediateFromLayouts(buildInfo.layoutInfoDir());
+ List<IntermediateV2> intermediateList = loadDependencyIntermediates();
+ for (Intermediate intermediate : intermediateList) {
+ try {
+ intermediate.appendTo(resourceBundle);
+ } catch (Throwable throwable) {
+ L.e(throwable, "unable to prepare resource bundle");
+ }
+ }
+
+ IntermediateV2 mine = createIntermediateFromLayouts(buildInfo.layoutInfoDir(),
+ intermediateList);
if (mine != null) {
- mine.removeOverridden(intermediateList);
+ mine.updateOverridden(resourceBundle);
intermediateList.add(mine);
saveIntermediate(processingEnvironment, buildInfo, mine);
+ mine.appendTo(resourceBundle);
}
// generate them here so that bindable parser can read
try {
- generateBinders(resourceBundle, buildInfo, intermediateList);
+ writeResourceBundle(resourceBundle, buildInfo.isLibrary(), buildInfo.minSdk(),
+ buildInfo.exportClassListTo());
} catch (Throwable t) {
L.e(t, "cannot generate view binders");
}
return true;
}
+ private List<IntermediateV2> loadDependencyIntermediates() {
+ final List<IntermediateV2> original = GenerationalClassUtil.loadObjects(
+ GenerationalClassUtil.ExtensionFilter.LAYOUT);
+ final List<IntermediateV2> upgraded = new ArrayList<IntermediateV2>(original.size());
+ for (Intermediate intermediate : original) {
+ final Intermediate updatedIntermediate = intermediate.upgrade();
+ Preconditions.check(updatedIntermediate instanceof IntermediateV2, "Incompatible data"
+ + " binding dependency. Please update your dependencies or recompile them with"
+ + " application module's data binding version.");
+ //noinspection ConstantConditions
+ upgraded.add((IntermediateV2) updatedIntermediate);
+ }
+ return upgraded;
+ }
+
private void saveIntermediate(ProcessingEnvironment processingEnvironment,
- BindingBuildInfo buildInfo, IntermediateV1 intermediate) {
+ BindingBuildInfo buildInfo, IntermediateV2 intermediate) {
GenerationalClassUtil.writeIntermediateFile(processingEnvironment,
buildInfo.modulePackage(), buildInfo.modulePackage() +
GenerationalClassUtil.ExtensionFilter.LAYOUT.getExtension(),
@@ -85,27 +114,22 @@ public class ProcessExpressions extends ProcessDataBinding.ProcessingStep {
ProcessingEnvironment processingEnvironment, BindingBuildInfo buildInfo) {
}
- private void generateBinders(ResourceBundle resourceBundle, BindingBuildInfo buildInfo,
- List<Intermediate> intermediates)
- throws Throwable {
- for (Intermediate intermediate : intermediates) {
- intermediate.appendTo(resourceBundle);
+ private IntermediateV2 createIntermediateFromLayouts(String layoutInfoFolderPath,
+ List<IntermediateV2> intermediateList) {
+ final Set<String> excludeList = new HashSet<String>();
+ for (IntermediateV2 lib : intermediateList) {
+ excludeList.addAll(lib.mLayoutInfoMap.keySet());
}
- writeResourceBundle(resourceBundle, buildInfo.isLibrary(), buildInfo.minSdk(),
- buildInfo.exportClassListTo());
- }
-
- private IntermediateV1 createIntermediateFromLayouts(String layoutInfoFolderPath) {
final File layoutInfoFolder = new File(layoutInfoFolderPath);
if (!layoutInfoFolder.isDirectory()) {
L.d("layout info folder does not exist, skipping for %s", layoutInfoFolderPath);
return null;
}
- IntermediateV1 result = new IntermediateV1();
+ IntermediateV2 result = new IntermediateV2();
for (File layoutFile : layoutInfoFolder.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
- return name.endsWith(".xml");
+ return name.endsWith(".xml") && !excludeList.contains(name);
}
})) {
try {
@@ -146,11 +170,11 @@ public class ProcessExpressions extends ProcessDataBinding.ProcessingStep {
mCallback.onChefReady(compilerChef, forLibraryModule, minSdk);
}
- public static interface Intermediate extends Serializable {
+ public interface Intermediate extends Serializable {
Intermediate upgrade();
- public void appendTo(ResourceBundle resourceBundle) throws Throwable;
+ void appendTo(ResourceBundle resourceBundle) throws Throwable;
}
public static class IntermediateV1 implements Intermediate {
@@ -162,7 +186,10 @@ public class ProcessExpressions extends ProcessDataBinding.ProcessingStep {
@Override
public Intermediate upgrade() {
- return this;
+ final IntermediateV2 updated = new IntermediateV2();
+ updated.mLayoutInfoMap = mLayoutInfoMap;
+ updated.mUnmarshaller = mUnmarshaller;
+ return updated;
}
@Override
@@ -189,19 +216,53 @@ public class ProcessExpressions extends ProcessDataBinding.ProcessingStep {
mLayoutInfoMap.put(name, contents);
}
+ // keeping the method to match deserialized structure
+ @SuppressWarnings("unused")
public void removeOverridden(List<Intermediate> existing) {
- // this is the way we get rid of files that are copied from previous modules
- // it is important to do this before saving the intermediate file
- for (Intermediate old : existing) {
- if (old instanceof IntermediateV1) {
- IntermediateV1 other = (IntermediateV1) old;
- for (String key : other.mLayoutInfoMap.keySet()) {
- // TODO we should consider the original file as the key here
- // but aapt probably cannot provide that information
- if (mLayoutInfoMap.remove(key) != null) {
- L.d("removing %s from bundle because it came from another module", key);
- }
- }
+ }
+ }
+
+ public static class IntermediateV2 extends IntermediateV1 {
+ // specify so that we can define updates ourselves.
+ private static final long serialVersionUID = 2L;
+ @Override
+ public void appendTo(ResourceBundle resourceBundle) throws JAXBException {
+ for (Map.Entry<String, String> entry : mLayoutInfoMap.entrySet()) {
+ final InputStream is = IOUtils.toInputStream(entry.getValue());
+ try {
+ final ResourceBundle.LayoutFileBundle bundle = ResourceBundle.LayoutFileBundle
+ .fromXML(is);
+ resourceBundle.addLayoutBundle(bundle);
+ L.d("loaded layout info file %s", bundle);
+ } finally {
+ IOUtils.closeQuietly(is);
+ }
+ }
+ }
+
+ /**
+ * if a layout is overridden from a module (which happens when layout is auto-generated),
+ * we need to update its contents from the class that overrides it.
+ * This must be done before this bundle is saved, otherwise, it will not be recognized
+ * when it is used in another project.
+ */
+ public void updateOverridden(ResourceBundle bundle) throws JAXBException {
+ // When a layout is copied from inherited module, it is eleminated while reading
+ // info files. (createIntermediateFromLayouts).
+ // Build process may also duplicate some files at compile time. This is where
+ // we detect those copies and force inherit their module and classname information.
+ final HashMap<String, List<ResourceBundle.LayoutFileBundle>> bundles = bundle
+ .getLayoutBundles();
+ for (Map.Entry<String, String> info : mLayoutInfoMap.entrySet()) {
+ String key = LayoutXmlProcessor.exportLayoutNameFromInfoFileName(info.getKey());
+ final List<ResourceBundle.LayoutFileBundle> existingList = bundles.get(key);
+ if (existingList != null && !existingList.isEmpty()) {
+ ResourceBundle.LayoutFileBundle myBundle = ResourceBundle.LayoutFileBundle
+ .fromXML(IOUtils.toInputStream(info.getValue()));
+ final ResourceBundle.LayoutFileBundle inheritFrom = existingList.get(0);
+ myBundle.inheritConfigurationFrom(inheritFrom);
+ L.d("inheriting data for %s (%s) from %s", info.getKey(), key, inheritFrom);
+ mLayoutInfoMap.put(info.getKey(), myBundle.toXML());
}
}
}
diff --git a/compilerCommon/src/main/java/android/databinding/tool/LayoutXmlProcessor.java b/compilerCommon/src/main/java/android/databinding/tool/LayoutXmlProcessor.java
index 22835f1a..382c2654 100644
--- a/compilerCommon/src/main/java/android/databinding/tool/LayoutXmlProcessor.java
+++ b/compilerCommon/src/main/java/android/databinding/tool/LayoutXmlProcessor.java
@@ -14,7 +14,6 @@
package android.databinding.tool;
import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.filefilter.FileFilterUtils;
import org.apache.commons.lang3.StringEscapeUtils;
import org.xml.sax.SAXException;
@@ -27,13 +26,11 @@ import android.databinding.tool.writer.JavaFileWriter;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
-import java.io.StringWriter;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
-import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.parsers.ParserConfigurationException;
@@ -236,13 +233,10 @@ public class LayoutXmlProcessor {
if (mWritten) {
return;
}
- JAXBContext context = JAXBContext.newInstance(ResourceBundle.LayoutFileBundle.class);
- Marshaller marshaller = context.createMarshaller();
-
for (List<ResourceBundle.LayoutFileBundle> layouts : mResourceBundle.getLayoutBundles()
.values()) {
for (ResourceBundle.LayoutFileBundle layout : layouts) {
- writeXmlFile(xmlOutDir, layout, marshaller);
+ writeXmlFile(xmlOutDir, layout);
}
}
for (File file : mResourceBundle.getRemovedFiles()) {
@@ -252,24 +246,16 @@ public class LayoutXmlProcessor {
mWritten = true;
}
- private void writeXmlFile(File xmlOutDir, ResourceBundle.LayoutFileBundle layout,
- Marshaller marshaller) throws JAXBException {
+ private void writeXmlFile(File xmlOutDir, ResourceBundle.LayoutFileBundle layout)
+ throws JAXBException {
String filename = generateExportFileName(layout);
- String xml = toXML(layout, marshaller);
- mFileWriter.writeToFile(new File(xmlOutDir, filename), xml);
+ mFileWriter.writeToFile(new File(xmlOutDir, filename), layout.toXML());
}
public String getInfoClassFullName() {
return RESOURCE_BUNDLE_PACKAGE + "." + CLASS_NAME;
}
- private String toXML(ResourceBundle.LayoutFileBundle layout, Marshaller marshaller)
- throws JAXBException {
- StringWriter writer = new StringWriter();
- marshaller.marshal(layout, writer);
- return writer.getBuffer().toString();
- }
-
/**
* Generates a string identifier that can uniquely identify the given layout bundle.
* This identifier can be used when we need to export data about this layout bundle.
@@ -285,18 +271,11 @@ public class LayoutXmlProcessor {
}
public static String generateExportFileName(String fileName, String dirName) {
- StringBuilder name = new StringBuilder(fileName);
- name.append('-').append(dirName);
- for (int i = name.length() - 1; i >= 0; i--) {
- char c = name.charAt(i);
- if (c == '-') {
- name.deleteCharAt(i);
- c = Character.toUpperCase(name.charAt(i));
- name.setCharAt(i, c);
- }
- }
- name.append(".xml");
- return name.toString();
+ return fileName + '-' + dirName + ".xml";
+ }
+
+ public static String exportLayoutNameFromInfoFileName(String infoFileName) {
+ return infoFileName.substring(0, infoFileName.indexOf('-'));
}
public void writeInfoClass(/*Nullable*/ File sdkDir, File xmlOutDir,
diff --git a/compilerCommon/src/main/java/android/databinding/tool/store/ResourceBundle.java b/compilerCommon/src/main/java/android/databinding/tool/store/ResourceBundle.java
index 072eea3a..3ae7e2d8 100644
--- a/compilerCommon/src/main/java/android/databinding/tool/store/ResourceBundle.java
+++ b/compilerCommon/src/main/java/android/databinding/tool/store/ResourceBundle.java
@@ -25,7 +25,9 @@ import android.databinding.tool.util.ParserHelper;
import android.databinding.tool.util.Preconditions;
import java.io.File;
+import java.io.InputStream;
import java.io.Serializable;
+import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@@ -34,6 +36,10 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
@@ -425,6 +431,21 @@ public class ResourceBundle implements Serializable {
public LayoutFileBundle() {
}
+ /**
+ * Updates configuration fields from the given bundle but does not change variables,
+ * binding expressions etc.
+ */
+ public void inheritConfigurationFrom(LayoutFileBundle other) {
+ mFileName = other.mFileName;
+ mModulePackage = other.mModulePackage;
+ mBindingClass = other.mBindingClass;
+ mFullBindingClass = other.mFullBindingClass;
+ mBindingClassName = other.mBindingClassName;
+ mBindingPackage = other.mBindingPackage;
+ mHasVariations = other.mHasVariations;
+ mIsMerge = other.mIsMerge;
+ }
+
public LayoutFileBundle(File file, String fileName, String directory,
String modulePackage, boolean isMerge) {
mFileName = fileName;
@@ -604,6 +625,37 @@ public class ResourceBundle implements Serializable {
public String provideScopeFilePath() {
return mAbsoluteFilePath;
}
+
+ private static Marshaller sMarshaller;
+ private static Unmarshaller sUmarshaller;
+
+ public String toXML() throws JAXBException {
+ StringWriter writer = new StringWriter();
+ getMarshaller().marshal(this, writer);
+ return writer.getBuffer().toString();
+ }
+
+ public static LayoutFileBundle fromXML(InputStream inputStream) throws JAXBException {
+ return (LayoutFileBundle) getUnmarshaller().unmarshal(inputStream);
+ }
+
+ private static Marshaller getMarshaller() throws JAXBException {
+ if (sMarshaller == null) {
+ JAXBContext context = JAXBContext
+ .newInstance(ResourceBundle.LayoutFileBundle.class);
+ sMarshaller = context.createMarshaller();
+ }
+ return sMarshaller;
+ }
+
+ private static Unmarshaller getUnmarshaller() throws JAXBException {
+ if (sUmarshaller == null) {
+ JAXBContext context = JAXBContext
+ .newInstance(ResourceBundle.LayoutFileBundle.class);
+ sUmarshaller = context.createUnmarshaller();
+ }
+ return sUmarshaller;
+ }
}
@XmlAccessorType(XmlAccessType.NONE)
diff --git a/integration-tests/IndependentLibrary/app/src/main/res/layout-sw600dp-land/library_layout.xml b/integration-tests/IndependentLibrary/app/src/main/res/layout-sw600dp-land/library_layout.xml
new file mode 100644
index 00000000..301663b0
--- /dev/null
+++ b/integration-tests/IndependentLibrary/app/src/main/res/layout-sw600dp-land/library_layout.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 The Android Open Source Project
+ ~
+ ~ 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.
+ -->
+<layout xmlns:android="http://schemas.android.com/apk/res/android">
+ <data class=".IndependentLibraryBinding">
+ <variable name="foo"
+ type="android.databinding.test.independentlibrary.vo.MyBindableObject"/>
+ </data>
+ <LinearLayout
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <TextView android:layout_width="match_parent" android:layout_height="wrap_content"
+ android:id="@+id/fooTextView"
+ android:text='@{foo.field + " " + foo.field}'/>
+ </LinearLayout>
+</layout>
diff --git a/integration-tests/MultiModuleTestApp/app/src/androidTest/java/com/android/databinding/multimoduletestapp/EventIdsTest.java b/integration-tests/MultiModuleTestApp/app/src/androidTest/java/com/android/databinding/multimoduletestapp/EventIdsTest.java
index 9a04368c..8ef36b45 100644
--- a/integration-tests/MultiModuleTestApp/app/src/androidTest/java/com/android/databinding/multimoduletestapp/EventIdsTest.java
+++ b/integration-tests/MultiModuleTestApp/app/src/androidTest/java/com/android/databinding/multimoduletestapp/EventIdsTest.java
@@ -20,7 +20,6 @@ import android.databinding.testlibrary.ObservableInLibrary;
import android.databinding.Observable;
import android.databinding.Observable.OnPropertyChangedCallback;
-import android.os.Debug;
import android.test.AndroidTestCase;
import java.util.HashMap;
diff --git a/integration-tests/MultiModuleTestApp/app/src/androidTest/java/com/android/databinding/multimoduletestapp/GeneratedLayoutTest.java b/integration-tests/MultiModuleTestApp/app/src/androidTest/java/com/android/databinding/multimoduletestapp/GeneratedLayoutTest.java
new file mode 100644
index 00000000..f83e9c04
--- /dev/null
+++ b/integration-tests/MultiModuleTestApp/app/src/androidTest/java/com/android/databinding/multimoduletestapp/GeneratedLayoutTest.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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.android.databinding.multimoduletestapp;
+
+import android.databinding.DataBindingUtil;
+import android.databinding.ViewDataBinding;
+import android.databinding.multimoduletestapp.R;
+import android.test.AndroidTestCase;
+import android.view.LayoutInflater;
+import android.view.View;
+
+public class GeneratedLayoutTest extends AndroidTestCase {
+ public void testBindToGeneratedLayout() {
+ LayoutInflater inflater = LayoutInflater.from(getContext());
+ View view = inflater.inflate(R.layout.library_layout, null);
+ // force override tag
+ view.setTag("layout-sw600dp-land-v13/library_layout_0");
+ ViewDataBinding bind = DataBindingUtil.bind(view);
+ assertEquals("IndependentLibraryBindingSw600dpLandV13Impl",
+ bind.getClass().getSimpleName());
+ }
+
+ public void testBindToDefault() {
+ LayoutInflater inflater = LayoutInflater.from(getContext());
+ View view = inflater.inflate(R.layout.library_layout, null);
+ // force override tag
+ view.setTag("layout/library_layout_0");
+ ViewDataBinding bind = DataBindingUtil.bind(view);
+ assertEquals("IndependentLibraryBindingImpl",
+ bind.getClass().getSimpleName());
+ }
+
+ public void testBindToSw600() {
+ LayoutInflater inflater = LayoutInflater.from(getContext());
+ View view = inflater.inflate(R.layout.library_layout, null);
+ // force override tag
+ view.setTag("layout-sw600dp-land/library_layout_0");
+ ViewDataBinding bind = DataBindingUtil.bind(view);
+ assertEquals("IndependentLibraryBindingSw600dpLandImpl",
+ bind.getClass().getSimpleName());
+ }
+}