Merge "Add supported ABIs to test description xml" into lmp-dev
diff --git a/CtsBuild.mk b/CtsBuild.mk
index f6d0d5c..4521b7e 100644
--- a/CtsBuild.mk
+++ b/CtsBuild.mk
@@ -30,6 +30,9 @@
 # File indicating which tests should be blacklisted due to problems.
 CTS_EXPECTATIONS := cts/tests/expectations/knownfailures.txt
 
+# File indicating which tests should be blacklisted due to unsupported abi.
+CTS_UNSUPPORTED_ABIS := cts/tests/expectations/unsupportedabis.txt
+
 # Functions to get the paths of the build outputs.
 
 define cts-get-lib-paths
diff --git a/build/test_executable.mk b/build/test_executable.mk
index fb41b73..1439663 100644
--- a/build/test_executable.mk
+++ b/build/test_executable.mk
@@ -31,7 +31,7 @@
 $(cts_executable_xml): PRIVATE_EXECUTABLE := $(LOCAL_MODULE)
 $(cts_executable_xml): PRIVATE_LIST_EXECUTABLE := $(HOST_OUT_EXECUTABLES)/$(LOCAL_MODULE)_list
 $(cts_executable_xml): $(HOST_OUT_EXECUTABLES)/$(LOCAL_MODULE)_list
-$(cts_executable_xml): $(addprefix $(LOCAL_PATH)/,$(LOCAL_SRC_FILES)) $(CTS_EXPECTATIONS) $(CTS_NATIVE_TEST_SCANNER) $(CTS_XML_GENERATOR) $(cts_list_executable)
+$(cts_executable_xml): $(addprefix $(LOCAL_PATH)/,$(LOCAL_SRC_FILES)) $(CTS_EXPECTATIONS) $(CTS_UNSUPPORTED_ABIS) $(CTS_NATIVE_TEST_SCANNER) $(CTS_XML_GENERATOR) $(cts_list_executable)
 	$(hide) echo Generating test description for native package $(PRIVATE_TEST_PACKAGE)
 	$(hide) mkdir -p $(CTS_TESTCASES_OUT)
 	$(hide) $(PRIVATE_LIST_EXECUTABLE) --gtest_list_tests | \
@@ -40,4 +40,6 @@
 						-n $(PRIVATE_EXECUTABLE) \
 						-p $(PRIVATE_TEST_PACKAGE) \
 						-e $(CTS_EXPECTATIONS) \
+						-b $(CTS_UNSUPPORTED_ABIS) \
+						-a $(TARGET_ARCH) \
 						-o $@
diff --git a/build/test_gtest_package.mk b/build/test_gtest_package.mk
index cbd9414..eeb8bbe 100644
--- a/build/test_gtest_package.mk
+++ b/build/test_gtest_package.mk
@@ -49,4 +49,6 @@
 						-n $(PRIVATE_EXECUTABLE) \
 						-p $(PRIVATE_TEST_PACKAGE) \
 						-e $(CTS_EXPECTATIONS) \
+						-b $(CTS_UNSUPPORTED_ABIS) \
+						-a $(TARGET_ARCH) \
 						-o $@
diff --git a/build/test_host_java_library.mk b/build/test_host_java_library.mk
index 9512bfa..c502b83 100644
--- a/build/test_host_java_library.mk
+++ b/build/test_host_java_library.mk
@@ -25,7 +25,7 @@
 $(cts_library_xml): PRIVATE_TEST_PACKAGE := $(LOCAL_CTS_TEST_PACKAGE)
 $(cts_library_xml): PRIVATE_LIBRARY := $(LOCAL_MODULE)
 $(cts_library_xml): PRIVATE_JAR_PATH := $(LOCAL_MODULE).jar
-$(cts_library_xml): $(HOST_OUT_JAVA_LIBRARIES)/$(LOCAL_MODULE).jar $(CTS_EXPECTATIONS) $(CTS_JAVA_TEST_SCANNER_DOCLET) $(CTS_JAVA_TEST_SCANNER) $(CTS_XML_GENERATOR)
+$(cts_library_xml): $(HOST_OUT_JAVA_LIBRARIES)/$(LOCAL_MODULE).jar $(CTS_EXPECTATIONS) $(CTS_UNSUPPORTED_ABIS) $(CTS_JAVA_TEST_SCANNER_DOCLET) $(CTS_JAVA_TEST_SCANNER) $(CTS_XML_GENERATOR)
 	$(hide) echo Generating test description for host library $(PRIVATE_LIBRARY)
 	$(hide) mkdir -p $(CTS_TESTCASES_OUT)
 	$(hide) $(CTS_JAVA_TEST_SCANNER) -s $(PRIVATE_PATH) \
@@ -35,4 +35,6 @@
 						-n $(PRIVATE_LIBRARY) \
 						-p $(PRIVATE_TEST_PACKAGE) \
 						-e $(CTS_EXPECTATIONS) \
+						-b $(CTS_UNSUPPORTED_ABIS) \
+						-a $(TARGET_ARCH) \
 						-o $@
diff --git a/build/test_package.mk b/build/test_package.mk
index a0adb5f..97f9c43 100644
--- a/build/test_package.mk
+++ b/build/test_package.mk
@@ -44,7 +44,7 @@
 $(cts_package_xml): PRIVATE_TEST_PACKAGE := $(PRIVATE_CTS_TEST_PACKAGE_NAME_)
 $(cts_package_xml): PRIVATE_MANIFEST := $(LOCAL_PATH)/AndroidManifest.xml
 $(cts_package_xml): PRIVATE_TEST_TYPE := $(if $(LOCAL_CTS_TEST_RUNNER),$(LOCAL_CTS_TEST_RUNNER),'')
-$(cts_package_xml): $(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME))/package.apk $(CTS_EXPECTATIONS) $(CTS_JAVA_TEST_SCANNER_DOCLET) $(CTS_JAVA_TEST_SCANNER) $(CTS_XML_GENERATOR)
+$(cts_package_xml): $(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME))/package.apk $(CTS_EXPECTATIONS) $(CTS_UNSUPPORTED_ABIS) $(CTS_JAVA_TEST_SCANNER_DOCLET) $(CTS_JAVA_TEST_SCANNER) $(CTS_XML_GENERATOR)
 	$(hide) echo Generating test description for java package $(PRIVATE_PACKAGE)
 	$(hide) mkdir -p $(CTS_TESTCASES_OUT)
 	$(hide) $(CTS_JAVA_TEST_SCANNER) \
@@ -57,4 +57,6 @@
 						-n $(PRIVATE_PACKAGE) \
 						-p $(PRIVATE_TEST_PACKAGE) \
 						-e $(CTS_EXPECTATIONS) \
+						-b $(CTS_UNSUPPORTED_ABIS) \
+						-a $(TARGET_ARCH) \
 						-o $@
diff --git a/build/test_target_java_library.mk b/build/test_target_java_library.mk
index 7e14f97..204bddc 100644
--- a/build/test_target_java_library.mk
+++ b/build/test_target_java_library.mk
@@ -30,7 +30,7 @@
 $(cts_library_xml): PRIVATE_LIBRARY := $(LOCAL_MODULE)
 $(cts_library_xml): PRIVATE_JAR_PATH := $(LOCAL_MODULE).jar
 $(cts_library_xml): PRIVATE_RUNTIME_ARGS := $(LOCAL_CTS_TARGET_RUNTIME_ARGS)
-$(cts_library_xml): $(TARGET_OUT_JAVA_LIBRARIES)/$(LOCAL_MODULE).jar $(CTS_EXPECTATIONS) $(CTS_JAVA_TEST_SCANNER_DOCLET) $(CTS_JAVA_TEST_SCANNER) $(CTS_XML_GENERATOR)
+$(cts_library_xml): $(TARGET_OUT_JAVA_LIBRARIES)/$(LOCAL_MODULE).jar $(CTS_EXPECTATIONS) $(CTS_UNSUPPORTED_ABIS) $(CTS_JAVA_TEST_SCANNER_DOCLET) $(CTS_JAVA_TEST_SCANNER) $(CTS_XML_GENERATOR)
 	$(hide) echo Generating test description for target library $(PRIVATE_LIBRARY)
 	$(hide) mkdir -p $(CTS_TESTCASES_OUT)
 	$(hide) $(CTS_JAVA_TEST_SCANNER) -s $(PRIVATE_PATH) \
@@ -40,5 +40,7 @@
 						-n $(PRIVATE_LIBRARY) \
 						-p $(PRIVATE_TEST_PACKAGE) \
 						-e $(CTS_EXPECTATIONS) \
+						-b $(CTS_UNSUPPORTED_ABIS) \
+						-a $(TARGET_ARCH) \
 						-x "runtimeArgs->$(PRIVATE_RUNTIME_ARGS)" \
 						-o $@
diff --git a/build/test_uiautomator.mk b/build/test_uiautomator.mk
index c17f12b..be78f6c 100644
--- a/build/test_uiautomator.mk
+++ b/build/test_uiautomator.mk
@@ -35,7 +35,7 @@
 $(cts_library_xml): PRIVATE_TEST_APK := $(LOCAL_CTS_TEST_APK)
 $(cts_library_xml): PRIVATE_LIBRARY := $(LOCAL_MODULE)
 $(cts_library_xml): PRIVATE_JAR_PATH := $(LOCAL_MODULE).jar
-$(cts_library_xml): $(call intermediates-dir-for,JAVA_LIBRARIES,$(LOCAL_MODULE))/javalib.jar $(CTS_EXPECTATIONS) $(CTS_JAVA_TEST_SCANNER_DOCLET) $(CTS_JAVA_TEST_SCANNER) $(CTS_XML_GENERATOR)
+$(cts_library_xml): $(call intermediates-dir-for,JAVA_LIBRARIES,$(LOCAL_MODULE))/javalib.jar $(CTS_EXPECTATIONS) $(CTS_UNSUPPORTED_ABIS) $(CTS_JAVA_TEST_SCANNER_DOCLET) $(CTS_JAVA_TEST_SCANNER) $(CTS_XML_GENERATOR)
 	$(hide) echo Generating test description for uiautomator library $(PRIVATE_LIBRARY)
 	$(hide) mkdir -p $(CTS_TESTCASES_OUT)
 	$(hide) $(CTS_JAVA_TEST_SCANNER) -s $(PRIVATE_PATH) \
@@ -43,9 +43,11 @@
 			$(CTS_XML_GENERATOR) -t uiAutomator \
 						-i $(PRIVATE_TEST_APK) \
 						-j $(PRIVATE_JAR_PATH) \
-						-a $(PRIVATE_TEST_PACKAGE) \
+						-s $(PRIVATE_TEST_PACKAGE) \
 						-n $(PRIVATE_LIBRARY) \
 						-p $(PRIVATE_TEST_PACKAGE) \
 						-r $(PRIVATE_TEST_APP_PACKAGE) \
 						-e $(CTS_EXPECTATIONS) \
+						-b $(CTS_UNSUPPORTED_ABIS) \
+						-a $(TARGET_ARCH) \
 						-o $@
diff --git a/tests/expectations/unsupportedabis.txt b/tests/expectations/unsupportedabis.txt
new file mode 100644
index 0000000..7a244e3
--- /dev/null
+++ b/tests/expectations/unsupportedabis.txt
@@ -0,0 +1,183 @@
+[
+{
+  description: "Tests not supporting: arm64-v8a, x86_64, mips64",
+  names: [
+    "android.renderscript.cts.AllocationCopy2DRangeTest",
+    "android.renderscript.cts.AllocationResize",
+    "android.renderscript.cts.AllocationTest",
+    "android.renderscript.cts.AtomicTest",
+    "android.renderscript.cts.BaseObjTest",
+    "android.renderscript.cts.ClearObjectTest",
+    "android.renderscript.cts.CompilerTest",
+    "android.renderscript.cts.ComputeTest",
+    "android.renderscript.cts.DebugContext",
+    "android.renderscript.cts.ElementTest",
+    "android.renderscript.cts.ExceptionTest",
+    "android.renderscript.cts.FieldPackerTest",
+    "android.renderscript.cts.ForEachTest",
+    "android.renderscript.cts.GetAllocationTest",
+    "android.renderscript.cts.GetElementAt",
+    "android.renderscript.cts.GlobalSync",
+    "android.renderscript.cts.GlobalTest",
+    "android.renderscript.cts.ImageProcessingTest",
+    "android.renderscript.cts.InitTest",
+    "android.renderscript.cts.Intrinsic3DLut",
+    "android.renderscript.cts.IntrinsicBase",
+    "android.renderscript.cts.IntrinsicBlur",
+    "android.renderscript.cts.IntrinsicColorMatrix",
+    "android.renderscript.cts.IntrinsicConvolve3x3",
+    "android.renderscript.cts.IntrinsicConvolve5x5",
+    "android.renderscript.cts.IntrinsicHistogram",
+    "android.renderscript.cts.IsObjectTest",
+    "android.renderscript.cts.KernelTest",
+    "android.renderscript.cts.LeakTest",
+    "android.renderscript.cts.Matrix2fTest",
+    "android.renderscript.cts.Matrix3fTest",
+    "android.renderscript.cts.Matrix4fTest",
+    "android.renderscript.cts.RSBase",
+    "android.renderscript.cts.RSBaseCompute",
+    "android.renderscript.cts.RenderScriptTest",
+    "android.renderscript.cts.RsPackColorTo8888Test",
+    "android.renderscript.cts.RsUnpackColor8888Test",
+    "android.renderscript.cts.SampleTest",
+    "android.renderscript.cts.SamplerTest",
+    "android.renderscript.cts.ScriptGroupTest",
+    "android.renderscript.cts.ScriptTest",
+    "android.renderscript.cts.SendToClient",
+    "android.renderscript.cts.SendToClientBlockingTest",
+    "android.renderscript.cts.SetObjectTest",
+    "android.renderscript.cts.StructArrayTest",
+    "android.renderscript.cts.StructPadTest",
+    "android.renderscript.cts.TestAbs",
+    "android.renderscript.cts.TestAcos",
+    "android.renderscript.cts.TestAcosh",
+    "android.renderscript.cts.TestAcospi",
+    "android.renderscript.cts.TestAsin",
+    "android.renderscript.cts.TestAsinh",
+    "android.renderscript.cts.TestAsinpi",
+    "android.renderscript.cts.TestAtan",
+    "android.renderscript.cts.TestAtan2",
+    "android.renderscript.cts.TestAtan2pi",
+    "android.renderscript.cts.TestAtanh",
+    "android.renderscript.cts.TestAtanpi",
+    "android.renderscript.cts.TestCbrt",
+    "android.renderscript.cts.TestCeil",
+    "android.renderscript.cts.TestClamp",
+    "android.renderscript.cts.TestClz",
+    "android.renderscript.cts.TestConvert",
+    "android.renderscript.cts.TestCopysign",
+    "android.renderscript.cts.TestCos",
+    "android.renderscript.cts.TestCosh",
+    "android.renderscript.cts.TestCospi",
+    "android.renderscript.cts.TestCross",
+    "android.renderscript.cts.TestDegrees",
+    "android.renderscript.cts.TestDistance",
+    "android.renderscript.cts.TestDot",
+    "android.renderscript.cts.TestErf",
+    "android.renderscript.cts.TestErfc",
+    "android.renderscript.cts.TestExp",
+    "android.renderscript.cts.TestExp10",
+    "android.renderscript.cts.TestExp2",
+    "android.renderscript.cts.TestExpm1",
+    "android.renderscript.cts.TestFabs",
+    "android.renderscript.cts.TestFastDistance",
+    "android.renderscript.cts.TestFastLength",
+    "android.renderscript.cts.TestFastNormalize",
+    "android.renderscript.cts.TestFdim",
+    "android.renderscript.cts.TestFloor",
+    "android.renderscript.cts.TestFma",
+    "android.renderscript.cts.TestFmax",
+    "android.renderscript.cts.TestFmin",
+    "android.renderscript.cts.TestFmod",
+    "android.renderscript.cts.TestFract",
+    "android.renderscript.cts.TestFrexp",
+    "android.renderscript.cts.TestHalfRecip",
+    "android.renderscript.cts.TestHalfRsqrt",
+    "android.renderscript.cts.TestHalfSqrt",
+    "android.renderscript.cts.TestHypot",
+    "android.renderscript.cts.TestIlogb",
+    "android.renderscript.cts.TestLdexp",
+    "android.renderscript.cts.TestLength",
+    "android.renderscript.cts.TestLgamma",
+    "android.renderscript.cts.TestLog",
+    "android.renderscript.cts.TestLog10",
+    "android.renderscript.cts.TestLog1p",
+    "android.renderscript.cts.TestLog2",
+    "android.renderscript.cts.TestLogb",
+    "android.renderscript.cts.TestMad",
+    "android.renderscript.cts.TestMax",
+    "android.renderscript.cts.TestMin",
+    "android.renderscript.cts.TestMix",
+    "android.renderscript.cts.TestModf",
+    "android.renderscript.cts.TestNan",
+    "android.renderscript.cts.TestNativeAcos",
+    "android.renderscript.cts.TestNativeAcosh",
+    "android.renderscript.cts.TestNativeAcospi",
+    "android.renderscript.cts.TestNativeAsin",
+    "android.renderscript.cts.TestNativeAsinh",
+    "android.renderscript.cts.TestNativeAsinpi",
+    "android.renderscript.cts.TestNativeAtan",
+    "android.renderscript.cts.TestNativeAtan2",
+    "android.renderscript.cts.TestNativeAtan2pi",
+    "android.renderscript.cts.TestNativeAtanh",
+    "android.renderscript.cts.TestNativeAtanpi",
+    "android.renderscript.cts.TestNativeCbrt",
+    "android.renderscript.cts.TestNativeCos",
+    "android.renderscript.cts.TestNativeCosh",
+    "android.renderscript.cts.TestNativeCospi",
+    "android.renderscript.cts.TestNativeDistance",
+    "android.renderscript.cts.TestNativeDivide",
+    "android.renderscript.cts.TestNativeExp",
+    "android.renderscript.cts.TestNativeExp10",
+    "android.renderscript.cts.TestNativeExp2",
+    "android.renderscript.cts.TestNativeExpm1",
+    "android.renderscript.cts.TestNativeHypot",
+    "android.renderscript.cts.TestNativeLength",
+    "android.renderscript.cts.TestNativeLog",
+    "android.renderscript.cts.TestNativeLog10",
+    "android.renderscript.cts.TestNativeLog1p",
+    "android.renderscript.cts.TestNativeLog2",
+    "android.renderscript.cts.TestNativeNormalize",
+    "android.renderscript.cts.TestNativePowr",
+    "android.renderscript.cts.TestNativeRecip",
+    "android.renderscript.cts.TestNativeRootn",
+    "android.renderscript.cts.TestNativeRsqrt",
+    "android.renderscript.cts.TestNativeSin",
+    "android.renderscript.cts.TestNativeSincos",
+    "android.renderscript.cts.TestNativeSinh",
+    "android.renderscript.cts.TestNativeSinpi",
+    "android.renderscript.cts.TestNativeSqrt",
+    "android.renderscript.cts.TestNativeTan",
+    "android.renderscript.cts.TestNativeTanh",
+    "android.renderscript.cts.TestNativeTanpi",
+    "android.renderscript.cts.TestNextafter",
+    "android.renderscript.cts.TestNormalize",
+    "android.renderscript.cts.TestPow",
+    "android.renderscript.cts.TestPown",
+    "android.renderscript.cts.TestPowr",
+    "android.renderscript.cts.TestRadians",
+    "android.renderscript.cts.TestRemainder",
+    "android.renderscript.cts.TestRemquo",
+    "android.renderscript.cts.TestRint",
+    "android.renderscript.cts.TestRootn",
+    "android.renderscript.cts.TestRound",
+    "android.renderscript.cts.TestRsqrt",
+    "android.renderscript.cts.TestSign",
+    "android.renderscript.cts.TestSin",
+    "android.renderscript.cts.TestSincos",
+    "android.renderscript.cts.TestSinh",
+    "android.renderscript.cts.TestSinpi",
+    "android.renderscript.cts.TestSqrt",
+    "android.renderscript.cts.TestStep",
+    "android.renderscript.cts.TestTan",
+    "android.renderscript.cts.TestTanh",
+    "android.renderscript.cts.TestTanpi",
+    "android.renderscript.cts.TestTgamma",
+    "android.renderscript.cts.TestTrunc",
+    "android.renderscript.cts.TypeTest",
+    "android.renderscript.cts.VersionTest",
+    "android.renderscript.cts.VoidPtr",
+    "android.renderscript.cts.YuvTest"
+  ]
+}
+]
diff --git a/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/CtsXmlGenerator.java b/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/CtsXmlGenerator.java
index 1cf5a7e..37e94ae 100644
--- a/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/CtsXmlGenerator.java
+++ b/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/CtsXmlGenerator.java
@@ -38,7 +38,8 @@
         System.err.println("Arguments: " + Arrays.asList(args));
         System.err.println("Usage: cts-xml-generator -p PACKAGE_NAME -n NAME [-t TEST_TYPE]"
                 + " [-j JAR_PATH] [-i INSTRUMENTATION] [-m MANIFEST_FILE] [-e EXPECTATION_FILE]"
-                + " [-o OUTPUT_FILE] [-a APP_NAME_SPACE] [-x ADDITIONAL_ATTRIBUTE_KEY->VALUE]");
+                + " [-b UNSUPPORTED_ABI_FILE] [-a ARCHITECTURE] [-o OUTPUT_FILE]"
+                + " [-n APP_NAME_SPACE] [-x ADDITIONAL_ATTRIBUTE_KEY->VALUE]");
         System.exit(1);
     }
 
@@ -47,6 +48,8 @@
         String name = null;
         String outputPath = null;
         Set<File> expectationFiles = new HashSet<File>();
+        Set<File> abiFiles = new HashSet<File>();
+        String architecture = null;
         File manifestFile = null;
         String instrumentation = null;
         String testType = null;
@@ -71,9 +74,13 @@
             } else if ("-e".equals(args[i])) {
                 expectationFiles.add(new File(getArg(args, ++i,
                         "Missing value for expectation store")));
+            } else if ("-b".equals(args[i])) {
+                abiFiles.add(new File(getArg(args, ++i, "Missing value for abi store")));
+            } else if ("-a".equals(args[i])) {
+                architecture = getArg(args, ++i, "Missing value for architecture");
             } else if ("-o".equals(args[i])) {
                 outputPath = getArg(args, ++i, "Missing value for output file");
-            } else if ("-a".equals(args[i])) {
+            } else if ("-s".equals(args[i])) {
                 appNameSpace =  getArg(args, ++i, "Missing value for app name space");
             } else if ("-r".equals(args[i])) {
                 targetNameSpace =  getArg(args, ++i, "Missing value for target name space");
@@ -118,10 +125,11 @@
             usage(args);
         }
 
-        ExpectationStore store = ExpectationStore.parse(expectationFiles, ModeId.DEVICE);
-        XmlGenerator generator = new XmlGenerator(store, appNameSpace, appPackageName,
-                name, runner, instrumentation, targetNameSpace, jarPath, testType, outputPath,
-                additionalAttributes);
+        ExpectationStore failuresStore = ExpectationStore.parse(expectationFiles, ModeId.DEVICE);
+        ExpectationStore abiStore = ExpectationStore.parse(abiFiles, ModeId.DEVICE);
+        XmlGenerator generator = new XmlGenerator(failuresStore, abiStore, architecture,
+                appNameSpace, appPackageName, name, runner, instrumentation, targetNameSpace,
+                jarPath, testType, outputPath, additionalAttributes);
         generator.writePackageXml();
     }
 
diff --git a/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/XmlGenerator.java b/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/XmlGenerator.java
index b1a006e..59b9fb3 100644
--- a/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/XmlGenerator.java
+++ b/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/XmlGenerator.java
@@ -27,8 +27,11 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Map;
 import java.util.List;
+import java.util.Set;
 
 /**
  * Generator of TestPackage XML files for native tests.
@@ -47,6 +50,29 @@
  */
 class XmlGenerator {
 
+    private static final Set<String> ARM_ABI = new HashSet<String>();
+    private static final Set<String> INTEL_ABI = new HashSet<String>();
+    private static final Set<String> MIPS_ABI = new HashSet<String>();
+    private static final Set<String> SUPPORTED_ABIS = new HashSet<String>();
+    private static final Map<String, Set<String>> ARCH_TO_ABIS = new HashMap<String, Set<String>>();
+    static {
+        ARM_ABI.add("armeabi-v7a");
+        ARM_ABI.add("arm64-v8a");
+        INTEL_ABI.add("x86");
+        INTEL_ABI.add("x86_64");
+        MIPS_ABI.add("mips");
+        MIPS_ABI.add("mips64");
+        ARCH_TO_ABIS.put("arm", ARM_ABI);
+        ARCH_TO_ABIS.put("arm64", ARM_ABI);
+        ARCH_TO_ABIS.put("x86", INTEL_ABI);
+        ARCH_TO_ABIS.put("x86_64", INTEL_ABI);
+        ARCH_TO_ABIS.put("mips", MIPS_ABI);
+        ARCH_TO_ABIS.put("mips64", MIPS_ABI);
+        SUPPORTED_ABIS.addAll(ARM_ABI);
+        SUPPORTED_ABIS.addAll(INTEL_ABI);
+        SUPPORTED_ABIS.addAll(MIPS_ABI);
+    }
+
     /** Example: com.android.cts.holo */
     private final String mAppNamespace;
 
@@ -71,14 +97,19 @@
     private final String mOutputPath;
 
     /** ExpectationStore to filter out known failures. */
-    private final ExpectationStore mExpectations;
+    private final ExpectationStore mKnownFailures;
+
+    /** ExpectationStore to filter out unsupported abis. */
+    private final ExpectationStore mUnsupportedAbis;
+
+    private final String mArchitecture;
 
     private final Map<String, String> mAdditionalAttributes;
 
-    XmlGenerator(ExpectationStore expectations, String appNameSpace, String appPackageName,
-            String name, String runner, String targetBinaryName, String targetNameSpace,
-            String jarPath, String testType, String outputPath,
-            Map<String, String> additionalAttributes) {
+    XmlGenerator(ExpectationStore knownFailures, ExpectationStore unsupportedAbis,
+            String architecture, String appNameSpace, String appPackageName, String name,
+            String runner, String targetBinaryName, String targetNameSpace, String jarPath,
+            String testType, String outputPath, Map<String, String> additionalAttributes) {
         mAppNamespace = appNameSpace;
         mAppPackageName = appPackageName;
         mName = name;
@@ -88,7 +119,9 @@
         mJarPath = jarPath;
         mTestType = testType;
         mOutputPath = outputPath;
-        mExpectations = expectations;
+        mKnownFailures = knownFailures;
+        mUnsupportedAbis = unsupportedAbis;
+        mArchitecture = architecture;
         mAdditionalAttributes = additionalAttributes;
     }
 
@@ -192,9 +225,12 @@
             StringBuilder nameCollector) {
         Collection<Test> sorted = sortCollection(tests);
         for (Test test : sorted) {
+            String className = nameCollector.toString();
             nameCollector.append('#').append(test.getName());
             writer.append("<Test name=\"").append(test.getName()).append("\"");
-            if (isKnownFailure(mExpectations, nameCollector.toString())) {
+            String abis = getSupportedAbis(mUnsupportedAbis, mArchitecture, className).toString();
+            writer.append(" abis=\"" + abis.substring(1, abis.length() - 1) + "\"");
+            if (isKnownFailure(mKnownFailures, nameCollector.toString())) {
                 writer.append(" expectation=\"failure\"");
             }
             if (test.getTimeout() >= 0) {
@@ -216,4 +252,26 @@
     public static boolean isKnownFailure(ExpectationStore expectationStore, String testName) {
         return expectationStore != null && expectationStore.get(testName) != Expectation.SUCCESS;
     }
+
+    // Returns the list of ABIs supported by this TestCase on this architecture.
+    public static Set<String> getSupportedAbis(ExpectationStore expectationStore,
+            String architecture, String className) {
+        Set<String> supportedAbis = new HashSet<String>(ARCH_TO_ABIS.get(architecture));
+        Expectation e = (expectationStore == null) ? null : expectationStore.get(className);
+        if (e != null && !e.getDescription().isEmpty()) {
+            // Description should be written in the form "blah blah: abi1, abi2..."
+            String description = e.getDescription().split(":")[1];
+            String[] unsupportedAbis = description.split(",");
+            for (String a : unsupportedAbis) {
+                String abi = a.trim();
+                if (!SUPPORTED_ABIS.contains(abi)) {
+                    throw new RuntimeException(
+                            String.format("Unrecognised ABI %s in %s", abi, e.getDescription()));
+                }
+                supportedAbis.remove(abi);
+            }
+        }
+        return supportedAbis;
+    }
+
 }