Merge "Tests for set/get organization color"
diff --git a/CtsTestCaseList.mk b/CtsTestCaseList.mk
index c5dc051..39a58ad 100644
--- a/CtsTestCaseList.mk
+++ b/CtsTestCaseList.mk
@@ -182,6 +182,12 @@
     CtsNetTestCases \
     CtsNetTestCasesLegacyApi22 \
     CtsNetTestCasesLegacyPermission22 \
+    CtsNetSecConfigAttributeTestCases \
+    CtsNetSecConfigBasicDebugDisabledTestCases \
+    CtsNetSecConfigBasicDebugEnabledTestCases \
+    CtsNetSecConfigBasicDomainConfigTestCases \
+    CtsNetSecConfigInvalidPinTestCases \
+    CtsNetSecConfigNestedDomainConfigTestCases \
     CtsOpenGLTestCases \
     CtsOpenGlPerfTestCases \
     CtsOpenGlPerf2TestCases \
diff --git a/apps/CtsVerifier/res/values-television/strings.xml b/apps/CtsVerifier/res/values-television/strings.xml
index 1042fa8..50f7628 100644
--- a/apps/CtsVerifier/res/values-television/strings.xml
+++ b/apps/CtsVerifier/res/values-television/strings.xml
@@ -18,5 +18,6 @@
     <string-array name="disabled_tests">
         <item>com.android.cts.verifier.notifications.NotificationAttentionManagementVerifierActivity</item>
         <item>com.android.cts.verifier.notifications.NotificationListenerVerifierActivity</item>
+        <item>com.android.cts.verifier.widget.WidgetTestActivity</item>
     </string-array>
-</resources>
\ No newline at end of file
+</resources>
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/DynamicConfigDeviceSide.java b/common/device-side/util/src/com/android/compatibility/common/util/DynamicConfigDeviceSide.java
index 303efec..b50b4f7 100644
--- a/common/device-side/util/src/com/android/compatibility/common/util/DynamicConfigDeviceSide.java
+++ b/common/device-side/util/src/com/android/compatibility/common/util/DynamicConfigDeviceSide.java
@@ -28,6 +28,7 @@
  * Load dynamic config for device side test cases
  */
 public class DynamicConfigDeviceSide extends DynamicConfig {
+
     private static String LOG_TAG = DynamicConfigDeviceSide.class.getSimpleName();
 
     public DynamicConfigDeviceSide(String moduleName) throws XmlPullParserException, IOException {
@@ -35,6 +36,6 @@
             throw new IOException("External storage is not mounted");
         }
         File configFile = getConfigFile(new File(CONFIG_FOLDER_ON_DEVICE), moduleName);
-        initConfigFromXml(configFile);
+        initializeConfig(configFile);
     }
 }
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/DynamicConfigPusher.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/DynamicConfigPusher.java
index 8c455cd..fabc4e1 100644
--- a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/DynamicConfigPusher.java
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/DynamicConfigPusher.java
@@ -88,11 +88,11 @@
         }
 
         String apfeConfigInJson = null;
-        String OriginUrl = buildHelper.getDynamicConfigUrl();
+        String originUrl = buildHelper.getDynamicConfigUrl();
 
-        if (OriginUrl != null) {
+        if (originUrl != null) {
             try {
-                String requestUrl = OriginUrl
+                String requestUrl = originUrl
                         .replace("{module-name}", mModuleName).replace("{version-name}", mVersion);
                 java.net.URL request = new URL(requestUrl);
                 apfeConfigInJson = StreamUtil.getStringFromStream(request.openStream());
@@ -128,7 +128,9 @@
 
             case HOST:
                 File storageDir = new File(DynamicConfig.CONFIG_FOLDER_ON_HOST);
-                if (!storageDir.exists()) storageDir.mkdir();
+                if (!storageDir.exists()) {
+                    storageDir.mkdir();
+                }
                 File hostDest = new File(DynamicConfig.CONFIG_FOLDER_ON_HOST + src.getName());
                 try {
                     FileUtil.copyFile(src, hostDest);
@@ -159,4 +161,4 @@
                 new File(mFilePushed).delete();
         }
     }
-}
\ No newline at end of file
+}
diff --git a/common/host-side/util/src/com/android/compatibility/common/util/DynamicConfigHandler.java b/common/host-side/util/src/com/android/compatibility/common/util/DynamicConfigHandler.java
index b42faca..bedcecd 100644
--- a/common/host-side/util/src/com/android/compatibility/common/util/DynamicConfigHandler.java
+++ b/common/host-side/util/src/com/android/compatibility/common/util/DynamicConfigHandler.java
@@ -37,90 +37,66 @@
 
     private static final String LOG_TAG = DynamicConfigHandler.class.getSimpleName();
 
-    // xml constant
-    private static final String NS = null; //representing null namespace
+    private static final String NS = null; //xml constant representing null namespace
     private static final String ENCODING = "UTF-8";
 
-    public static File getMergedDynamicConfigFile(File localConfigFile, String apfeConfigJson,
+    public static File getMergedDynamicConfigFile(File localConfigFile, String apbsConfigJson,
             String moduleName) throws IOException, XmlPullParserException, JSONException {
 
-        DynamicConfig.Params localConfig = DynamicConfig.genParamsFromFile(localConfigFile);
-        DynamicConfig.Params apfeOverride = parseJsonToParam(apfeConfigJson);
-
-        localConfig.mDynamicParams.putAll(apfeOverride.mDynamicParams);
-        localConfig.mDynamicArrayParams.putAll(apfeOverride.mDynamicArrayParams);
-
-        File mergedConfigFile = storeMergedConfigFile(localConfig, moduleName);
-        return mergedConfigFile;
+        Map<String, List<String>> localConfig = DynamicConfig.createConfigMap(localConfigFile);
+        Map<String, List<String>> apbsConfig = parseJsonToConfigMap(apbsConfigJson);
+        localConfig.putAll(apbsConfig);
+        return storeMergedConfigFile(localConfig, moduleName);
     }
 
-    private static DynamicConfig.Params parseJsonToParam(String apfeConfigJson)
+    private static Map<String, List<String>> parseJsonToConfigMap(String apbsConfigJson)
             throws JSONException {
-        if (apfeConfigJson == null) return new DynamicConfig.Params();
 
-        Map<String, String> configMap = new HashMap<>();
-        Map<String, List<String>> configListMap = new HashMap<>();
-
-        JSONObject rootObj  = new JSONObject(new JSONTokener(apfeConfigJson));
-        if (rootObj.has("config")) {
-            JSONArray configArr = rootObj.getJSONArray("config");
-            for (int i = 0; i < configArr.length(); i++) {
-                JSONObject config = configArr.getJSONObject(i);
-                configMap.put(config.getString("key"), config.getString("value"));
-            }
-        }
-        if (rootObj.has("configList")) {
-            JSONArray configListArr = rootObj.getJSONArray("configList");
-            for (int i = 0; i < configListArr.length(); i++) {
-                JSONObject configList = configListArr.getJSONObject(i);
-                String key = configList.getString("key");
-                List<String> values = new ArrayList<>();
-                JSONArray configListValuesArr = configList.getJSONArray("value");
-                for (int j = 0; j < configListValuesArr.length(); j++) {
-                    values.add(configListValuesArr.getString(j));
-                }
-                configListMap.put(key, values);
-            }
+        Map<String, List<String>> configMap = new HashMap<String, List<String>>();
+        if (apbsConfigJson == null) {
+            return configMap;
         }
 
-        DynamicConfig.Params param = new DynamicConfig.Params();
-        param.mDynamicParams = configMap;
-        param.mDynamicArrayParams = configListMap;
-        return param;
+        JSONObject rootObj  = new JSONObject(new JSONTokener(apbsConfigJson));
+        JSONArray configEntries = rootObj.getJSONArray("dynamicConfigEntries");
+        for (int i = 0; i < configEntries.length(); i++) {
+            JSONObject configEntry = configEntries.getJSONObject(i);
+            String key = configEntry.getString("configAttribute");
+            JSONArray configValues = configEntry.getJSONArray("configValues");
+            List<String> values = new ArrayList<>();
+            for (int j = 0; j < configValues.length(); j++) {
+                values.add(configValues.getString(j));
+            }
+            configMap.put(key, values);
+        }
+        return configMap;
     }
 
-    private static File storeMergedConfigFile(DynamicConfig.Params p, String moduleName)
-            throws XmlPullParserException, IOException {
-        XmlSerializer serializer = XmlPullParserFactory.newInstance().newSerializer();
+    private static File storeMergedConfigFile(Map<String, List<String>> configMap,
+            String moduleName) throws XmlPullParserException, IOException {
 
-        File parentFolder = new File(DynamicConfig.CONFIG_FOLDER_ON_HOST);
-        if (!parentFolder.exists()) parentFolder.mkdir();
         File folder = new File(DynamicConfig.MERGED_CONFIG_FILE_FOLDER);
-        if (!folder.exists()) folder.mkdir();
-        File mergedConfigFile = new File(folder, moduleName+".dynamic");
+        folder.mkdirs();
+
+        File mergedConfigFile = new File(folder, moduleName + ".dynamic");
         OutputStream stream = new FileOutputStream(mergedConfigFile);
+        XmlSerializer serializer = XmlPullParserFactory.newInstance().newSerializer();
         serializer.setOutput(stream, ENCODING);
         serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
         serializer.startDocument(ENCODING, false);
 
-        serializer.startTag(NS, DynamicConfig.DYNAMIC_CONFIG_TAG);
-        for (String key : p.mDynamicParams.keySet()) {
-            serializer.startTag(NS, DynamicConfig.CONFIG_TAG);
+        serializer.startTag(NS, DynamicConfig.CONFIG_TAG);
+        for (String key : configMap.keySet()) {
+            serializer.startTag(NS, DynamicConfig.ENTRY_TAG);
             serializer.attribute(NS, DynamicConfig.KEY_ATTR, key);
-            serializer.text(p.mDynamicParams.get(key));
-            serializer.endTag(NS, DynamicConfig.CONFIG_TAG);
-        }
-        for (String key : p.mDynamicArrayParams.keySet()) {
-            serializer.startTag(NS, DynamicConfig.CONFIG_LIST_TAG);
-            serializer.attribute(NS, DynamicConfig.KEY_ATTR, key);
-            for (String item: p.mDynamicArrayParams.get(key)) {
-                serializer.startTag(NS, DynamicConfig.ITEM_TAG);
-                serializer.text(item);
-                serializer.endTag(NS, DynamicConfig.ITEM_TAG);
+            for (String value : configMap.get(key)) {
+                serializer.startTag(NS, DynamicConfig.VALUE_TAG);
+                serializer.text(value);
+                serializer.endTag(NS, DynamicConfig.VALUE_TAG);
             }
-            serializer.endTag(NS, DynamicConfig.CONFIG_LIST_TAG);
+            serializer.endTag(NS, DynamicConfig.ENTRY_TAG);
         }
-        serializer.endTag(NS, DynamicConfig.DYNAMIC_CONFIG_TAG);
+        serializer.endTag(NS, DynamicConfig.CONFIG_TAG);
         serializer.endDocument();
         return mergedConfigFile;
     }
diff --git a/common/host-side/util/src/com/android/compatibility/common/util/DynamicConfigHostSide.java b/common/host-side/util/src/com/android/compatibility/common/util/DynamicConfigHostSide.java
index ac69034..3e94d36 100644
--- a/common/host-side/util/src/com/android/compatibility/common/util/DynamicConfigHostSide.java
+++ b/common/host-side/util/src/com/android/compatibility/common/util/DynamicConfigHostSide.java
@@ -25,10 +25,11 @@
  * Load dynamic config for device side test cases
  */
 public class DynamicConfigHostSide extends DynamicConfig {
+
     private static String LOG_TAG = DynamicConfigHostSide.class.getSimpleName();
 
     public DynamicConfigHostSide(String moduleName) throws IOException, XmlPullParserException {
         File configFile = getConfigFile(new File(CONFIG_FOLDER_ON_HOST), moduleName);
-        initConfigFromXml(configFile);
+        initializeConfig(configFile);
     }
 }
diff --git a/common/util/src/com/android/compatibility/common/util/DynamicConfig.java b/common/util/src/com/android/compatibility/common/util/DynamicConfig.java
index a0b1d5e..a72216d 100644
--- a/common/util/src/com/android/compatibility/common/util/DynamicConfig.java
+++ b/common/util/src/com/android/compatibility/common/util/DynamicConfig.java
@@ -34,14 +34,14 @@
  * Load dynamic config for test cases
  */
 public class DynamicConfig {
+
     public final static String MODULE_NAME = "module-name";
 
     //XML constant
     public static final String NS = null;
-    public static final String DYNAMIC_CONFIG_TAG = "DynamicConfig";
-    public static final String CONFIG_TAG = "Config";
-    public static final String CONFIG_LIST_TAG = "ConfigList";
-    public static final String ITEM_TAG = "Item";
+    public static final String CONFIG_TAG = "dynamicConfig";
+    public static final String ENTRY_TAG = "entry";
+    public static final String VALUE_TAG = "value";
     public static final String KEY_ATTR = "key";
 
     public final static String CONFIG_FOLDER_ON_DEVICE = "/sdcard/dynamic-config-files/";
@@ -50,19 +50,18 @@
     public final static String MERGED_CONFIG_FILE_FOLDER =
             System.getProperty("java.io.tmpdir") + "/dynamic-config-files/merged";
 
+    protected Map<String, List<String>> mDynamicConfigMap = new HashMap<String, List<String>>();
 
-    protected Params params;
-
-    protected void initConfigFromXml(File file) throws XmlPullParserException, IOException {
-        params = genParamsFromFile(file);
+    protected void initializeConfig(File file) throws XmlPullParserException, IOException {
+        mDynamicConfigMap = createConfigMap(file);
     }
 
-    public String getConfig(String key) {
-        return params.mDynamicParams.get(key);
+    public String getValue(String key) {
+        return mDynamicConfigMap.get(key).get(0);
     }
 
-    public List<String> getConfigList(String key) {
-        return params.mDynamicArrayParams.get(key);
+    public List<String> getValues(String key) {
+        return mDynamicConfigMap.get(key);
     }
 
     public static File getConfigFile(File configFolder, String moduleName)
@@ -74,44 +73,31 @@
         return config;
     }
 
-    public static class Params {
-        public Map<String, String> mDynamicParams = new HashMap<>();
-        public Map<String, List<String>> mDynamicArrayParams = new HashMap<>();
-    }
+    public static Map<String, List<String>> createConfigMap(File file)
+            throws XmlPullParserException, IOException {
 
-    public static Params genParamsFromFile(File file) throws XmlPullParserException, IOException {
-        Params param = new Params();
-
+        Map<String, List<String>> dynamicConfigMap = new HashMap<String, List<String>>();
         XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser();
         parser.setInput(new InputStreamReader(new FileInputStream(file)));
-
         parser.nextTag();
-        parser.require(XmlPullParser.START_TAG, NS, DYNAMIC_CONFIG_TAG);
+        parser.require(XmlPullParser.START_TAG, NS, CONFIG_TAG);
 
         while (parser.nextTag() == XmlPullParser.START_TAG) {
-            if (parser.getName().equals(CONFIG_TAG)) {
-                String key = parser.getAttributeValue(NS, KEY_ATTR);
-                String value = parser.nextText();
-                parser.require(XmlPullParser.END_TAG, NS, CONFIG_TAG);
-                if (key != null && !key.isEmpty()) {
-                    param.mDynamicParams.put(key, value);
-                }
-            } else {
-                List<String> arrayValue = new ArrayList<>();
-                parser.require(XmlPullParser.START_TAG, NS, CONFIG_LIST_TAG);
-                String key = parser.getAttributeValue(NS, KEY_ATTR);
-                while (parser.nextTag() == XmlPullParser.START_TAG) {
-                    parser.require(XmlPullParser.START_TAG, NS, ITEM_TAG);
-                    arrayValue.add(parser.nextText());
-                    parser.require(XmlPullParser.END_TAG, NS, ITEM_TAG);
-                }
-                parser.require(XmlPullParser.END_TAG, NS, CONFIG_LIST_TAG);
-                if (key != null && !key.isEmpty()) {
-                    param.mDynamicArrayParams.put(key, arrayValue);
-                }
+            parser.require(XmlPullParser.START_TAG, NS, ENTRY_TAG);
+            String key = parser.getAttributeValue(NS, KEY_ATTR);
+            List<String> valueList = new ArrayList<String>();
+            while (parser.nextTag() == XmlPullParser.START_TAG) {
+                parser.require(XmlPullParser.START_TAG, NS, VALUE_TAG);
+                valueList.add(parser.nextText());
+                parser.require(XmlPullParser.END_TAG, NS, VALUE_TAG);
+            }
+            parser.require(XmlPullParser.END_TAG, NS, ENTRY_TAG);
+            if (key != null && !key.isEmpty() && !valueList.isEmpty()) {
+                dynamicConfigMap.put(key, valueList);
             }
         }
-        parser.require(XmlPullParser.END_TAG, NS, DYNAMIC_CONFIG_TAG);
-        return param;
+
+        parser.require(XmlPullParser.END_TAG, NS, CONFIG_TAG);
+        return dynamicConfigMap;
     }
 }
diff --git a/common/util/tests/src/com/android/compatibility/common/util/DynamicConfigTest.java b/common/util/tests/src/com/android/compatibility/common/util/DynamicConfigTest.java
index 6d6ba2d..cf1892a 100644
--- a/common/util/tests/src/com/android/compatibility/common/util/DynamicConfigTest.java
+++ b/common/util/tests/src/com/android/compatibility/common/util/DynamicConfigTest.java
@@ -30,56 +30,64 @@
 public class DynamicConfigTest extends TestCase {
     private static final String correctConfig =
             "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
-            "<DynamicConfig>\n" +
-            "    <Config key=\"test-config-1\">test config 1</Config>\n" +
-            "    <Config key=\"test-config-2\">testconfig2</Config>\n" +
-            "    <ConfigList key=\"config-list\">\n" +
-            "        <Item>config0</Item>\n" +
-            "        <Item>config1</Item>\n" +
-            "        <Item>config2</Item>\n" +
-            "        <Item>config3</Item>\n" +
-            "        <Item>config4</Item>\n" +
-            "    </ConfigList>\n" +
-            "    <ConfigList key=\"config-list-2\">\n" +
-            "        <Item>A</Item>\n" +
-            "        <Item>B</Item>\n" +
-            "        <Item>C</Item>\n" +
-            "        <Item>D</Item>\n" +
-            "        <Item>E</Item>\n" +
-            "    </ConfigList>\n" +
-            "</DynamicConfig>\n";
+            "<dynamicConfig>\n" +
+            "    <entry key=\"test-config-1\">\n" +
+            "        <value>test config 1</value>\n" +
+            "    </entry>\n" +
+            "    <entry key=\"test-config-2\">\n" +
+            "        <value>testconfig2</value>\n" +
+            "    </entry>\n" +
+            "    <entry key=\"config-list\">\n" +
+            "        <value>config0</value>\n" +
+            "        <value>config1</value>\n" +
+            "        <value>config2</value>\n" +
+            "        <value>config3</value>\n" +
+            "        <value>config4</value>\n" +
+            "    </entry>\n" +
+            "    <entry key=\"config-list-2\">\n" +
+            "        <value>A</value>\n" +
+            "        <value>B</value>\n" +
+            "        <value>C</value>\n" +
+            "        <value>D</value>\n" +
+            "        <value>E</value>\n" +
+            "    </entry>\n" +
+            "</dynamicConfig>\n";
 
     private static final String configWrongNodeName =
             "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
-            "<DynamicCsonfig>\n" +  //The node name DynamicConfig is intentionally mistyped
-            "    <Config key=\"test-config-1\">test config 1</Config>\n" +
-            "    <Config key=\"test-config-2\">testconfig2</Config>\n" +
-            "    <ConfigList key=\"config-list\">\n" +
-            "        <Item>Nevermore</Item>\n" +
-            "        <Item>Puck</Item>\n" +
-            "        <Item>Zeus</Item>\n" +
-            "        <Item>Earth Shaker</Item>\n" +
-            "        <Item>Vengeful Spirit</Item>\n" +
-            "    </ConfigList>\n" +
-            "    <ConfigList key=\"config-list-2\">\n" +
-            "        <Item>A</Item>\n" +
-            "        <Item>B</Item>\n" +
-            "        <Item>C</Item>\n" +
-            "        <Item>D</Item>\n" +
-            "        <Item>E</Item>\n" +
-            "    </ConfigList>\n" +
-            "</DynamicConfig>\n";
+            "<dynamicCsonfig>\n" +  //The node name dynamicConfig is intentionally mistyped
+            "    <entry key=\"test-config-1\">\n" +
+            "        <value>test config 1</value>\n" +
+            "    </entry>\n" +
+            "    <entry key=\"test-config-2\">\n" +
+            "        <value>testconfig2</value>\n" +
+            "    </entry>\n" +
+            "    <entry key=\"config-list\">\n" +
+            "        <value>Nevermore</value>\n" +
+            "        <value>Puck</value>\n" +
+            "        <value>Zeus</value>\n" +
+            "        <value>Earth Shaker</value>\n" +
+            "        <value>Vengeful Spirit</value>\n" +
+            "    </entry>\n" +
+            "    <entry key=\"config-list-2\">\n" +
+            "        <value>A</value>\n" +
+            "        <value>B</value>\n" +
+            "        <value>C</value>\n" +
+            "        <value>D</value>\n" +
+            "        <value>E</value>\n" +
+            "    </entry>\n" +
+            "</dynamicConfig>\n";
 
     public void testCorrectConfig() throws Exception {
         DynamicConfig config = new DynamicConfig();
         File file = createFileFromStr(correctConfig);
-        config.initConfigFromXml(file);
+        config.initializeConfig(file);
 
-        assertEquals("Wrong Config", config.getConfig("test-config-1"), "test config 1");
-        assertEquals("Wrong Config", config.getConfig("test-config-2"), "testconfig2");
-        assertEquals("Wrong Config List", config.getConfigList("config-list").get(0), "config0");
-        assertEquals("Wrong Config List", config.getConfigList("config-list").get(2), "config2");
-        assertEquals("Wrong Config List", config.getConfigList("config-list-2").get(2), "C");
+        assertEquals("Wrong Config", config.getValue("test-config-1"), "test config 1");
+        assertEquals("Wrong Config", config.getValue("test-config-2"), "testconfig2");
+        assertEquals("Wrong Config List", config.getValues("config-list").get(0), "config0");
+        assertEquals("Wrong Config List", config.getValues("config-list").get(2), "config2");
+        assertEquals("Wrong Config List", config.getValues("config-list-2").get(2), "C");
     }
 
     public void testConfigWithWrongNodeName() throws Exception {
@@ -87,7 +95,7 @@
         File file = createFileFromStr(configWrongNodeName);
 
         try {
-            config.initConfigFromXml(file);
+            config.initializeConfig(file);
             fail("Cannot detect error when config file has wrong node name");
         } catch (XmlPullParserException e) {
             //expected
diff --git a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityNodeInfoTest.java b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityNodeInfoTest.java
index 30847a5..6b28541 100644
--- a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityNodeInfoTest.java
+++ b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityNodeInfoTest.java
@@ -35,7 +35,7 @@
 public class AccessibilityNodeInfoTest extends AndroidTestCase {
 
     /** The number of properties of the {@link AccessibilityNodeInfo} class. */
-    private static final int NON_STATIC_FIELD_COUNT = 30;
+    private static final int NON_STATIC_FIELD_COUNT = 31;
 
     @SmallTest
     public void testMarshaling() throws Exception {
@@ -198,6 +198,7 @@
         info.setLabeledBy(new View(getContext()));
         info.setLabelFor(new View(getContext()));
         info.setViewIdResourceName("foo.bar:id/baz");
+        info.setDrawingOrder(5);
     }
 
     /**
@@ -260,6 +261,8 @@
                 receivedInfo.getMovementGranularities());
         assertEquals("viewId has incorrect value", expectedInfo.getViewIdResourceName(),
                 receivedInfo.getViewIdResourceName());
+        assertEquals("drawing order has incorrect value", expectedInfo.getDrawingOrder(),
+                receivedInfo.getDrawingOrder());
     }
 
     /**
@@ -293,5 +296,6 @@
         assertSame("movementGranularities not properly recycled", 0,
                 info.getMovementGranularities());
         assertNull("viewId not properly recycled", info.getViewIdResourceName());
+        assertEquals(0, info.getDrawingOrder());
     }
 }
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityViewTreeReportingTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityViewTreeReportingTest.java
index 04a9d9d..2a35e93 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityViewTreeReportingTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityViewTreeReportingTest.java
@@ -14,10 +14,18 @@
 
 package android.accessibilityservice.cts;
 
+import android.accessibilityservice.AccessibilityServiceInfo;
+import android.app.UiAutomation;
+import android.content.Context;
 import android.test.suitebuilder.annotation.MediumTest;
+import android.view.View;
 import android.view.accessibility.AccessibilityNodeInfo;
 
 import android.accessibilityservice.cts.R;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import java.util.ArrayList;
 
 /**
  * Test cases for testing the accessibility focus APIs exposed to accessibility
@@ -33,88 +41,230 @@
 
     @MediumTest
     public void testDescendantsOfNotImportantViewReportedInOrder1() throws Exception {
-        AccessibilityNodeInfo firstFrameLayout = getInstrumentation().getUiAutomation()
-            .getRootInActiveWindow().findAccessibilityNodeInfosByText(
-                    getString(R.string.firstFrameLayout)).get(0);
+        UiAutomation uiAutomation = getUiAutomation(false);
+        AccessibilityNodeInfo firstFrameLayout =
+                getNodeByText(uiAutomation, R.string.firstFrameLayout);
         assertNotNull(firstFrameLayout);
         assertSame(3, firstFrameLayout.getChildCount());
 
         // Check if the first child is the right one.
-        AccessibilityNodeInfo firstTextView = getInstrumentation().getUiAutomation()
-            .getRootInActiveWindow().findAccessibilityNodeInfosByText(getString(
-                    R.string.firstTextView)).get(0);
+        AccessibilityNodeInfo firstTextView = getNodeByText(uiAutomation, R.string.firstTextView);
         assertEquals(firstTextView, firstFrameLayout.getChild(0));
 
         // Check if the second child is the right one.
-        AccessibilityNodeInfo firstEditText = getInstrumentation().getUiAutomation()
-            .getRootInActiveWindow().findAccessibilityNodeInfosByText(getString(
-                    R.string.firstEditText)).get(0);
+        AccessibilityNodeInfo firstEditText = getNodeByText(uiAutomation, R.string.firstEditText);
         assertEquals(firstEditText, firstFrameLayout.getChild(1));
 
         // Check if the third child is the right one.
-        AccessibilityNodeInfo firstButton = getInstrumentation().getUiAutomation()
-            .getRootInActiveWindow().findAccessibilityNodeInfosByText(
-                    getString(R.string.firstButton)).get(0);
+        AccessibilityNodeInfo firstButton = getNodeByText(uiAutomation, R.string.firstButton);
         assertEquals(firstButton, firstFrameLayout.getChild(2));
     }
 
     @MediumTest
     public void testDescendantsOfNotImportantViewReportedInOrder2() throws Exception {
-        AccessibilityNodeInfo secondFrameLayout = getInstrumentation().getUiAutomation()
-            .getRootInActiveWindow().findAccessibilityNodeInfosByText(
-                    getString(R.string.secondFrameLayout)).get(0);
+        UiAutomation uiAutomation = getUiAutomation(false);
+        AccessibilityNodeInfo secondFrameLayout =
+                getNodeByText(uiAutomation, R.string.secondFrameLayout);
         assertNotNull(secondFrameLayout);
         assertSame(3, secondFrameLayout.getChildCount());
 
         // Check if the first child is the right one.
-        AccessibilityNodeInfo secondTextView = getInstrumentation().getUiAutomation()
-            .getRootInActiveWindow().findAccessibilityNodeInfosByText(
-                    getString(R.string.secondTextView)).get(0);
+        AccessibilityNodeInfo secondTextView = getNodeByText(uiAutomation, R.string.secondTextView);
         assertEquals(secondTextView, secondFrameLayout.getChild(0));
 
         // Check if the second child is the right one.
-        AccessibilityNodeInfo secondEditText = getInstrumentation().getUiAutomation()
-            .getRootInActiveWindow().findAccessibilityNodeInfosByText(
-                    getString(R.string.secondEditText)).get(0);
+        AccessibilityNodeInfo secondEditText = getNodeByText(uiAutomation, R.string.secondEditText);
         assertEquals(secondEditText, secondFrameLayout.getChild(1));
 
         // Check if the third child is the right one.
-        AccessibilityNodeInfo secondButton = getInstrumentation().getUiAutomation()
-            .getRootInActiveWindow().findAccessibilityNodeInfosByText(
-                    getString(R.string.secondButton)).get(0);
+        AccessibilityNodeInfo secondButton = getNodeByText(uiAutomation, R.string.secondButton);
         assertEquals(secondButton, secondFrameLayout.getChild(2));
     }
 
     @MediumTest
     public void testDescendantsOfNotImportantViewReportedInOrder3() throws Exception {
-        AccessibilityNodeInfo rootLinearLayout = getInstrumentation().getUiAutomation()
-            .getRootInActiveWindow().findAccessibilityNodeInfosByText(
-                    getString(R.string.rootLinearLayout)).get(0);
+        UiAutomation uiAutomation = getUiAutomation(false);
+        AccessibilityNodeInfo rootLinearLayout =
+                getNodeByText(uiAutomation, R.string.rootLinearLayout);
         assertNotNull(rootLinearLayout);
         assertSame(4, rootLinearLayout.getChildCount());
 
         // Check if the first child is the right one.
-        AccessibilityNodeInfo firstFrameLayout = getInstrumentation().getUiAutomation()
-            .getRootInActiveWindow().findAccessibilityNodeInfosByText(
-                    getString(R.string.firstFrameLayout)).get(0);
+        AccessibilityNodeInfo firstFrameLayout =
+                getNodeByText(uiAutomation, R.string.firstFrameLayout);
         assertEquals(firstFrameLayout, rootLinearLayout.getChild(0));
 
         // Check if the second child is the right one.
-        AccessibilityNodeInfo secondTextView = getInstrumentation().getUiAutomation()
-            .getRootInActiveWindow().findAccessibilityNodeInfosByText(
-                    getString(R.string.secondTextView)).get(0);
+        AccessibilityNodeInfo secondTextView = getNodeByText(uiAutomation, R.string.secondTextView);
         assertEquals(secondTextView, rootLinearLayout.getChild(1));
 
         // Check if the third child is the right one.
-        AccessibilityNodeInfo secondEditText = getInstrumentation().getUiAutomation()
-            .getRootInActiveWindow().findAccessibilityNodeInfosByText(
-                    getString(R.string.secondEditText)).get(0);
+        AccessibilityNodeInfo secondEditText = getNodeByText(uiAutomation, R.string.secondEditText);
         assertEquals(secondEditText, rootLinearLayout.getChild(2));
 
         // Check if the fourth child is the right one.
-        AccessibilityNodeInfo secondButton = getInstrumentation().getUiAutomation()
-            .getRootInActiveWindow().findAccessibilityNodeInfosByText(
-                    getString(R.string.secondButton)).get(0);
+        AccessibilityNodeInfo secondButton = getNodeByText(uiAutomation, R.string.secondButton);
         assertEquals(secondButton, rootLinearLayout.getChild(3));
     }
+
+    @MediumTest
+    public void testDrawingOrderInImportantParentFollowsXmlOrder() throws Exception {
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                getActivity().findViewById(R.id.firstLinearLayout)
+                        .setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
+            }
+        });
+
+        UiAutomation uiAutomation = getUiAutomation(false);
+        AccessibilityNodeInfo firstTextView = getNodeByText(uiAutomation, R.string.firstTextView);
+        AccessibilityNodeInfo firstEditText = getNodeByText(uiAutomation, R.string.firstEditText);
+        AccessibilityNodeInfo firstButton = getNodeByText(uiAutomation, R.string.firstButton);
+
+        // Drawing order is: firstTextView, firstEditText, firstButton
+        assertTrue(firstTextView.getDrawingOrder() < firstEditText.getDrawingOrder());
+        assertTrue(firstEditText.getDrawingOrder() < firstButton.getDrawingOrder());
+
+        // Confirm that obtaining copies doesn't change our results
+        AccessibilityNodeInfo copyOfFirstEditText = AccessibilityNodeInfo.obtain(firstEditText);
+        assertTrue(firstTextView.getDrawingOrder() < copyOfFirstEditText.getDrawingOrder());
+        assertTrue(copyOfFirstEditText.getDrawingOrder() < firstButton.getDrawingOrder());
+    }
+
+    @MediumTest
+    public void testDrawingOrderGettingAllViewsFollowsXmlOrder() throws Exception {
+        UiAutomation uiAutomation = getUiAutomation(true);
+        AccessibilityNodeInfo firstTextView = getNodeByText(uiAutomation, R.string.firstTextView);
+        AccessibilityNodeInfo firstEditText = getNodeByText(uiAutomation, R.string.firstEditText);
+        AccessibilityNodeInfo firstButton = getNodeByText(uiAutomation, R.string.firstButton);
+
+        // Drawing order is: firstTextView, firstEditText, firstButton
+        assertTrue(firstTextView.getDrawingOrder() < firstEditText.getDrawingOrder());
+        assertTrue(firstEditText.getDrawingOrder() < firstButton.getDrawingOrder());
+    }
+
+    @MediumTest
+    public void testDrawingOrderWithZCoordsDrawsHighestZLast() throws Exception {
+        getInstrumentation().runOnMainSync(new Runnable() {
+           @Override
+           public void run() {
+               AccessibilityViewTreeReportingActivity activity = getActivity();
+               activity.findViewById(R.id.firstTextView).setZ(50);
+               activity.findViewById(R.id.firstEditText).setZ(100);
+           }
+        });
+
+        UiAutomation uiAutomation = getUiAutomation(true);
+        AccessibilityNodeInfo firstTextView = getNodeByText(uiAutomation, R.string.firstTextView);
+        AccessibilityNodeInfo firstEditText = getNodeByText(uiAutomation, R.string.firstEditText);
+        AccessibilityNodeInfo firstButton = getNodeByText(uiAutomation, R.string.firstButton);
+
+        // Drawing order is firstButton (no z), firstTextView (z=50), firstEditText (z=100)
+        assertTrue(firstButton.getDrawingOrder() < firstTextView.getDrawingOrder());
+        assertTrue(firstTextView.getDrawingOrder() < firstEditText.getDrawingOrder());
+    }
+
+    @MediumTest
+    public void testDrawingOrderWithCustomDrawingOrder() throws Exception {
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                // Reorganize the hiearchy to replace firstLinearLayout with one that allows us to
+                // control the draw order
+                AccessibilityViewTreeReportingActivity activity = getActivity();
+                LinearLayout rootLinearLayout =
+                        (LinearLayout) activity.findViewById(R.id.rootLinearLayout);
+                LinearLayout firstLinearLayout =
+                        (LinearLayout) activity.findViewById(R.id.firstLinearLayout);
+                View firstTextView = activity.findViewById(R.id.firstTextView);
+                View firstEditText = activity.findViewById(R.id.firstEditText);
+                View firstButton = activity.findViewById(R.id.firstButton);
+                firstLinearLayout.removeAllViews();
+                LinearLayoutWithDrawingOrder layoutWithDrawingOrder =
+                        new LinearLayoutWithDrawingOrder(activity);
+                rootLinearLayout.addView(layoutWithDrawingOrder);
+                layoutWithDrawingOrder.addView(firstTextView);
+                layoutWithDrawingOrder.addView(firstEditText);
+                layoutWithDrawingOrder.addView(firstButton);
+                layoutWithDrawingOrder.childDrawingOrder = new int[] {2, 0, 1};
+            }
+        });
+
+        UiAutomation uiAutomation = getUiAutomation(true);
+        AccessibilityNodeInfo firstTextView = getNodeByText(uiAutomation, R.string.firstTextView);
+        AccessibilityNodeInfo firstEditText = getNodeByText(uiAutomation, R.string.firstEditText);
+        AccessibilityNodeInfo firstButton = getNodeByText(uiAutomation, R.string.firstButton);
+
+        // Drawing order is firstEditText, firstButton, firstTextView
+        assertTrue(firstEditText.getDrawingOrder() < firstButton.getDrawingOrder());
+        assertTrue(firstButton.getDrawingOrder() < firstTextView.getDrawingOrder());
+    }
+
+    @MediumTest
+    public void testDrawingOrderWithNotImportantSiblingConsidersItsChildren() throws Exception {
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                // Make the first frame layout a higher Z so it's drawn last
+                getActivity().findViewById(R.id.firstFrameLayout).setZ(100);
+            }
+        });
+        UiAutomation uiAutomation = getUiAutomation(false);
+        AccessibilityNodeInfo secondTextView = getNodeByText(uiAutomation, R.string.secondTextView);
+        AccessibilityNodeInfo secondEditText = getNodeByText(uiAutomation, R.string.secondEditText);
+        AccessibilityNodeInfo secondButton = getNodeByText(uiAutomation, R.string.secondButton);
+        AccessibilityNodeInfo firstFrameLayout =
+                getNodeByText(uiAutomation, R.string.firstFrameLayout);
+        assertTrue(secondTextView.getDrawingOrder() < firstFrameLayout.getDrawingOrder());
+        assertTrue(secondEditText.getDrawingOrder() < firstFrameLayout.getDrawingOrder());
+        assertTrue(secondButton.getDrawingOrder() < firstFrameLayout.getDrawingOrder());
+    }
+
+    @MediumTest
+    public void testDrawingOrderWithNotImportantParentConsidersParentSibling() throws Exception {
+        UiAutomation uiAutomation = getUiAutomation(false);
+        AccessibilityNodeInfo firstFrameLayout =
+                getNodeByText(uiAutomation, R.string.firstFrameLayout);
+        AccessibilityNodeInfo secondTextView = getNodeByText(uiAutomation, R.string.secondTextView);
+        AccessibilityNodeInfo secondEditText = getNodeByText(uiAutomation, R.string.secondEditText);
+        AccessibilityNodeInfo secondButton = getNodeByText(uiAutomation, R.string.secondButton);
+
+        assertTrue(secondTextView.getDrawingOrder() > firstFrameLayout.getDrawingOrder());
+        assertTrue(secondEditText.getDrawingOrder() > firstFrameLayout.getDrawingOrder());
+        assertTrue(secondButton.getDrawingOrder() > firstFrameLayout.getDrawingOrder());
+    }
+
+    @MediumTest
+    public void testDrawingOrderRootNodeHasIndex0() throws Exception {
+        assertEquals(0, getUiAutomation(false).getRootInActiveWindow().getDrawingOrder());
+    }
+
+    private UiAutomation getUiAutomation(boolean getNonImportantViews) {
+        UiAutomation uiAutomation = getInstrumentation().getUiAutomation();
+        AccessibilityServiceInfo serviceInfo = uiAutomation.getServiceInfo();
+        serviceInfo.flags &= ~AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
+        serviceInfo.flags |= getNonImportantViews ?
+                AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS : 0;
+        uiAutomation.setServiceInfo(serviceInfo);
+        return uiAutomation;
+    }
+
+    private AccessibilityNodeInfo getNodeByText(UiAutomation uiAutomation, int stringId) {
+        return uiAutomation.getRootInActiveWindow()
+                .findAccessibilityNodeInfosByText(getString(stringId)).get(0);
+    }
+
+    class LinearLayoutWithDrawingOrder extends LinearLayout {
+        public int[] childDrawingOrder;
+        LinearLayoutWithDrawingOrder(Context context) {
+            super(context);
+            setChildrenDrawingOrderEnabled(true);
+        }
+
+        @Override
+        protected int getChildDrawingOrder(int childCount, int i) {
+            return childDrawingOrder[i];
+        }
+    }
 }
diff --git a/tests/camera/src/android/hardware/camera2/cts/CaptureResultTest.java b/tests/camera/src/android/hardware/camera2/cts/CaptureResultTest.java
index 199552f..8510016 100644
--- a/tests/camera/src/android/hardware/camera2/cts/CaptureResultTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/CaptureResultTest.java
@@ -463,6 +463,9 @@
         waiverKeys.add(CaptureResult.JPEG_QUALITY);
         waiverKeys.add(CaptureResult.JPEG_THUMBNAIL_QUALITY);
         waiverKeys.add(CaptureResult.JPEG_THUMBNAIL_SIZE);
+        // Waived until framework implemented deriving logic for this key
+        // b/26625646
+        waiverKeys.add(CaptureResult.CONTROL_POST_RAW_SENSITIVITY_BOOST);
 
         // Keys only present when corresponding control is on are being
         // verified in its own functional test
@@ -748,6 +751,7 @@
         resultKeys.add(CaptureResult.CONTROL_AE_STATE);
         resultKeys.add(CaptureResult.CONTROL_AF_STATE);
         resultKeys.add(CaptureResult.CONTROL_AWB_STATE);
+        resultKeys.add(CaptureResult.CONTROL_POST_RAW_SENSITIVITY_BOOST);
         resultKeys.add(CaptureResult.EDGE_MODE);
         resultKeys.add(CaptureResult.FLASH_MODE);
         resultKeys.add(CaptureResult.FLASH_STATE);
diff --git a/tests/tests/media/DynamicConfig.xml b/tests/tests/media/DynamicConfig.xml
index 702157d..1299440 100644
--- a/tests/tests/media/DynamicConfig.xml
+++ b/tests/tests/media/DynamicConfig.xml
@@ -13,17 +13,41 @@
      limitations under the License.
 -->
 
-<DynamicConfig>
-    <Config key="DecoderTest-VIDEO_URL">http://redirector.gvt1.com/videoplayback?id=c80658495af60617&amp;itag=18&amp;source=youtube&amp;ip=0.0.0.0&amp;ipbits=0&amp;expire=19000000000&amp;sparams=ip,ipbits,expire,id,itag,source&amp;signature=46A04ED550CA83B79B60060BA80C79FDA5853D26.49582D382B4A9AFAA163DED38D2AE531D85603C0&amp;key=ik0&amp;user=android-device-test</Config>
-    <Config key="StreamingMediaPlayerTest-testHTTP_H264Base_AAC_Video1">http://redirector.gvt1.com/videoplayback?id=271de9756065677e&amp;itag=18&amp;source=youtube&amp;ip=0.0.0.0&amp;ipbits=0&amp;expire=19000000000&amp;sparams=ip,ipbits,expire,id,itag,source&amp;signature=667AEEF54639926662CE62361400B8F8C1753B3F.15F46C382C68A9F121BA17BF1F56BEDEB4B06091&amp;key=ik0&amp;user=android-device-test</Config>
-    <Config key="StreamingMediaPlayerTest-testHTTP_H264Base_AAC_Video2">http://www.youtube.com/api/manifest/hls_variant/id/0168724d02bd9945/itag/5/source/youtube/playlist_type/DVR/ip/0.0.0.0/ipbits/0/expire/19000000000/sparams/ip,ipbits,expire,id,itag,source,playlist_type/signature/773AB8ACC68A96E5AA481996AD6A1BBCB70DCB87.95733B544ACC5F01A1223A837D2CF04DF85A3360/key/ik0/file/m3u8</Config>
-    <Config key="MediaCodecCapabilitiesTest-testAvcHigh31">http://redirector.gvt1.com/videoplayback?id=271de9756065677e&amp;itag=22&amp;source=youtube&amp;user=android-device-test&amp;sparams=ip,ipbits,expire,id,itag,source,user&amp;ip=0.0.0.0&amp;ipbits=0&amp;expire=19000000000&amp;signature=179525311196616BD8E1381759B0E5F81A9E91B5.C4A50E44059FEBCC6BBC78E3B3A4E0E0065777&amp;key=ik0</Config>
-    <Config key="StreamingMediaPlayerTest-testHTTP_MPEG4SP_AAC_Video2">http://redirector.gvt1.com/videoplayback?id=c80658495af60617&amp;itag=17&amp;source=youtube&amp;ip=0.0.0.0&amp;ipbits=0&amp;expire=19000000000&amp;sparams=ip,ipbits,expire,id,itag,source&amp;signature=70E979A621001201BC18622BDBF914FA870BDA40.6E78890B80F4A33A18835F775B1FF64F0A4D0003&amp;key=ik0&amp;user=android-device-test</Config>
-    <Config key="StreamingMediaPlayerTest-testHTTP_MPEG4SP_AAC_Video1">http://redirector.gvt1.com/videoplayback?id=271de9756065677e&amp;itag=17&amp;source=youtube&amp;ip=0.0.0.0&amp;ipbits=0&amp;expire=19000000000&amp;sparams=ip,ipbits,expire,id,itag,source&amp;signature=837198AAADF6F36BA6B2D324F690A7C5B7AFE3FF.7138CE5E36D718220726C1FC305497FF2D082249&amp;key=ik0&amp;user=android-device-test</Config>
-    <Config key="MediaCodecCapabilitiesTest-testAvcBaseline12">http://redirector.gvt1.com/videoplayback?id=271de9756065677e&amp;itag=160&amp;source=youtube&amp;user=android-device-test&amp;sparams=ip,ipbits,expire,id,itag,source,user&amp;ip=0.0.0.0&amp;ipbits=0&amp;expire=19000000000&amp;signature=9EDCA0B395B8A949C511FD5E59B9F805CFF797FD.702DE9BA7AF96785FD6930AD2DD693A0486C880E&amp;key=ik0</Config>
-    <Config key="DecoderTest-AUDIO_URL">http://redirector.gvt1.com/videoplayback?id=c80658495af60617&amp;itag=18&amp;source=youtube&amp;ip=0.0.0.0&amp;ipbits=0&amp;expire=19000000000&amp;sparams=ip,ipbits,expire,id,itag,source&amp;signature=46A04ED550CA83B79B60060BA80C79FDA5853D26.49582D382B4A9AFAA163DED38D2AE531D85603C0&amp;key=ik0&amp;user=android-device-test</Config>
-    <Config key="MediaCodecCapabilitiesTest-testAvcBaseline30">http://redirector.gvt1.com/videoplayback?id=271de9756065677e&amp;itag=18&amp;source=youtube&amp;user=android-device-test&amp;sparams=ip,ipbits,expire,id,itag,source,user&amp;ip=0.0.0.0&amp;ipbits=0&amp;expire=19000000000&amp;signature=7DCDE3A6594D0B91A27676A3CDC3A87B149F82EA.7A83031734CB1EDCE06766B6228842F954927960&amp;key=ik0</Config>
-    <Config key="MediaCodecCapabilitiesTest-testAvcHigh40">http://redirector.gvt1.com/videoplayback?id=271de9756065677e&amp;itag=137&amp;source=youtube&amp;user=android-device-test&amp;sparams=ip,ipbits,expire,id,itag,source,user&amp;ip=0.0.0.0&amp;ipbits=0&amp;expire=19000000000&amp;signature=B0976085596DD42DEA3F08307F76587241CB132B.043B719C039E8B92F45391ADC0BE3665E2332930&amp;key=ik0</Config>
-    <Config key="StreamingMediaPlayerTest-testHTTP_H263_AMR_Video2">http://redirector.gvt1.com/videoplayback?id=c80658495af60617&amp;itag=13&amp;source=youtube&amp;ip=0.0.0.0&amp;ipbits=0&amp;expire=19000000000&amp;sparams=ip,ipbits,expire,id,itag,source&amp;signature=508D82AB36939345BF6B8D0623CB6CABDD9C64C3.9B3336A96846DF38E5343C46AA57F6CF2956E427&amp;key=ik0&amp;user=android-device-test</Config>
-    <Config key="StreamingMediaPlayerTest-testHTTP_H263_AMR_Video1">http://redirector.gvt1.com/videoplayback?id=271de9756065677e&amp;itag=13&amp;source=youtube&amp;ip=0.0.0.0&amp;ipbits=0&amp;expire=19000000000&amp;sparams=ip,ipbits,expire,id,itag,source&amp;signature=5729247E22691EBB3E804DDD523EC42DC17DD8CE.443B81C1E8E6D64E4E1555F568BA46C206507D78&amp;key=ik0&amp;user=android-device-test</Config>
-</DynamicConfig>
+<dynamicConfig>
+    <entry key="DecoderTest-VIDEO_URL">
+        <value>http://redirector.gvt1.com/videoplayback?id=c80658495af60617&amp;itag=18&amp;source=youtube&amp;ip=0.0.0.0&amp;ipbits=0&amp;expire=19000000000&amp;sparams=ip,ipbits,expire,id,itag,source&amp;signature=46A04ED550CA83B79B60060BA80C79FDA5853D26.49582D382B4A9AFAA163DED38D2AE531D85603C0&amp;key=ik0&amp;user=android-device-test</value>
+    </entry>
+    <entry key="StreamingMediaPlayerTest-testHTTP_H264Base_AAC_Video1">
+        <value>http://redirector.gvt1.com/videoplayback?id=271de9756065677e&amp;itag=18&amp;source=youtube&amp;ip=0.0.0.0&amp;ipbits=0&amp;expire=19000000000&amp;sparams=ip,ipbits,expire,id,itag,source&amp;signature=667AEEF54639926662CE62361400B8F8C1753B3F.15F46C382C68A9F121BA17BF1F56BEDEB4B06091&amp;key=ik0&amp;user=android-device-test</value>
+    </entry>
+    <entry key="StreamingMediaPlayerTest-testHTTP_H264Base_AAC_Video2">
+        <value>http://www.youtube.com/api/manifest/hls_variant/id/0168724d02bd9945/itag/5/source/youtube/playlist_type/DVR/ip/0.0.0.0/ipbits/0/expire/19000000000/sparams/ip,ipbits,expire,id,itag,source,playlist_type/signature/773AB8ACC68A96E5AA481996AD6A1BBCB70DCB87.95733B544ACC5F01A1223A837D2CF04DF85A3360/key/ik0/file/m3u8</value>
+    </entry>
+    <entry key="MediaCodecCapabilitiesTest-testAvcHigh31">
+        <value>http://redirector.gvt1.com/videoplayback?id=271de9756065677e&amp;itag=22&amp;source=youtube&amp;user=android-device-test&amp;sparams=ip,ipbits,expire,id,itag,source,user&amp;ip=0.0.0.0&amp;ipbits=0&amp;expire=19000000000&amp;signature=179525311196616BD8E1381759B0E5F81A9E91B5.C4A50E44059FEBCC6BBC78E3B3A4E0E0065777&amp;key=ik0</value>
+    </entry>
+    <entry key="StreamingMediaPlayerTest-testHTTP_MPEG4SP_AAC_Video2">
+        <value>http://redirector.gvt1.com/videoplayback?id=c80658495af60617&amp;itag=17&amp;source=youtube&amp;ip=0.0.0.0&amp;ipbits=0&amp;expire=19000000000&amp;sparams=ip,ipbits,expire,id,itag,source&amp;signature=70E979A621001201BC18622BDBF914FA870BDA40.6E78890B80F4A33A18835F775B1FF64F0A4D0003&amp;key=ik0&amp;user=android-device-test</value>
+    </entry>
+    <entry key="StreamingMediaPlayerTest-testHTTP_MPEG4SP_AAC_Video1">
+        <value>http://redirector.gvt1.com/videoplayback?id=271de9756065677e&amp;itag=17&amp;source=youtube&amp;ip=0.0.0.0&amp;ipbits=0&amp;expire=19000000000&amp;sparams=ip,ipbits,expire,id,itag,source&amp;signature=837198AAADF6F36BA6B2D324F690A7C5B7AFE3FF.7138CE5E36D718220726C1FC305497FF2D082249&amp;key=ik0&amp;user=android-device-test</value>
+    </entry>
+    <entry key="MediaCodecCapabilitiesTest-testAvcBaseline12">
+        <value>http://redirector.gvt1.com/videoplayback?id=271de9756065677e&amp;itag=160&amp;source=youtube&amp;user=android-device-test&amp;sparams=ip,ipbits,expire,id,itag,source,user&amp;ip=0.0.0.0&amp;ipbits=0&amp;expire=19000000000&amp;signature=9EDCA0B395B8A949C511FD5E59B9F805CFF797FD.702DE9BA7AF96785FD6930AD2DD693A0486C880E&amp;key=ik0</value>
+    </entry>
+    <entry key="DecoderTest-AUDIO_URL">
+        <value>http://redirector.gvt1.com/videoplayback?id=c80658495af60617&amp;itag=18&amp;source=youtube&amp;ip=0.0.0.0&amp;ipbits=0&amp;expire=19000000000&amp;sparams=ip,ipbits,expire,id,itag,source&amp;signature=46A04ED550CA83B79B60060BA80C79FDA5853D26.49582D382B4A9AFAA163DED38D2AE531D85603C0&amp;key=ik0&amp;user=android-device-test</value>
+    </entry>
+    <entry key="MediaCodecCapabilitiesTest-testAvcBaseline30">
+        <value>http://redirector.gvt1.com/videoplayback?id=271de9756065677e&amp;itag=18&amp;source=youtube&amp;user=android-device-test&amp;sparams=ip,ipbits,expire,id,itag,source,user&amp;ip=0.0.0.0&amp;ipbits=0&amp;expire=19000000000&amp;signature=7DCDE3A6594D0B91A27676A3CDC3A87B149F82EA.7A83031734CB1EDCE06766B6228842F954927960&amp;key=ik0</value>
+    </entry>
+    <entry key="MediaCodecCapabilitiesTest-testAvcHigh40">
+        <value>http://redirector.gvt1.com/videoplayback?id=271de9756065677e&amp;itag=137&amp;source=youtube&amp;user=android-device-test&amp;sparams=ip,ipbits,expire,id,itag,source,user&amp;ip=0.0.0.0&amp;ipbits=0&amp;expire=19000000000&amp;signature=B0976085596DD42DEA3F08307F76587241CB132B.043B719C039E8B92F45391ADC0BE3665E2332930&amp;key=ik0</value>
+    </entry>
+    <entry key="StreamingMediaPlayerTest-testHTTP_H263_AMR_Video2">
+        <value>http://redirector.gvt1.com/videoplayback?id=c80658495af60617&amp;itag=13&amp;source=youtube&amp;ip=0.0.0.0&amp;ipbits=0&amp;expire=19000000000&amp;sparams=ip,ipbits,expire,id,itag,source&amp;signature=508D82AB36939345BF6B8D0623CB6CABDD9C64C3.9B3336A96846DF38E5343C46AA57F6CF2956E427&amp;key=ik0&amp;user=android-device-test</value>
+    </entry>
+    <entry key="StreamingMediaPlayerTest-testHTTP_H263_AMR_Video1">
+        <value>http://redirector.gvt1.com/videoplayback?id=271de9756065677e&amp;itag=13&amp;source=youtube&amp;ip=0.0.0.0&amp;ipbits=0&amp;expire=19000000000&amp;sparams=ip,ipbits,expire,id,itag,source&amp;signature=5729247E22691EBB3E804DDD523EC42DC17DD8CE.443B81C1E8E6D64E4E1555F568BA46C206507D78&amp;key=ik0&amp;user=android-device-test</value>
+    </entry>
+</dynamicConfig>
diff --git a/tests/tests/mediastress/preconditions/src/android/mediastress/cts/preconditions/MediaPreparer.java b/tests/tests/mediastress/preconditions/src/android/mediastress/cts/preconditions/MediaPreparer.java
index ab5b65d..b996e4a 100644
--- a/tests/tests/mediastress/preconditions/src/android/mediastress/cts/preconditions/MediaPreparer.java
+++ b/tests/tests/mediastress/preconditions/src/android/mediastress/cts/preconditions/MediaPreparer.java
@@ -229,7 +229,7 @@
         URL url;
         try {
             DynamicConfigHostSide config = new DynamicConfigHostSide(DYNAMIC_CONFIG_MODULE);
-            String mediaUrlString = config.getConfig(MEDIA_FILES_URL_KEY);
+            String mediaUrlString = config.getValue(MEDIA_FILES_URL_KEY);
             url = new URL(mediaUrlString);
         } catch (IOException | XmlPullParserException e) {
             throw new TargetSetupError("Trouble finding media file download location with " +
diff --git a/tests/tests/networksecurityconfig/Android.mk b/tests/tests/networksecurityconfig/Android.mk
new file mode 100644
index 0000000..4312beb
--- /dev/null
+++ b/tests/tests/networksecurityconfig/Android.mk
@@ -0,0 +1,15 @@
+# Copyright (C) 2016 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.
+#
+include $(call all-subdir-makefiles)
diff --git a/tests/tests/networksecurityconfig/build_apk.mk b/tests/tests/networksecurityconfig/build_apk.mk
new file mode 100644
index 0000000..3c7c230
--- /dev/null
+++ b/tests/tests/networksecurityconfig/build_apk.mk
@@ -0,0 +1,24 @@
+# Copyright (C) 2016 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.
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+LOCAL_CTS_TEST_PACKAGE := android.security.net.config
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner \
+    org.apache.http.legacy
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_SRC_FILES += $(call all-java-files-under, ../src)
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res/
+LOCAL_SDK_VERSION := current
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/networksecurityconfig/manifest.xml b/tests/tests/networksecurityconfig/manifest.xml
new file mode 100644
index 0000000..0c1e85d
--- /dev/null
+++ b/tests/tests/networksecurityconfig/manifest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ * Copyright (C) 2016 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="android.security.net.config.cts">
+  <application>
+      <uses-library android:name="android.test.runner"/>
+      <meta-data android:name="android.security.net.config"
+                 android:resource="@xml/network_security_config" />
+  </application>
+
+  <uses-permission android:name="android.permission.INTERNET" />
+  <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                   android:targetPackage="android.security.net.config.cts"
+                   android:label="">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+</manifest>
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-attributes/Android.mk b/tests/tests/networksecurityconfig/networksecurityconfig-attributes/Android.mk
new file mode 100644
index 0000000..6c0a92b
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-attributes/Android.mk
@@ -0,0 +1,19 @@
+# Copyright (C) 2016 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.
+#
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_PACKAGE_NAME := CtsNetSecConfigAttributeTestCases
+include $(LOCAL_PATH)/../build_apk.mk
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-attributes/AndroidManifest.xml b/tests/tests/networksecurityconfig/networksecurityconfig-attributes/AndroidManifest.xml
new file mode 100644
index 0000000..c2018ba
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-attributes/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ * Copyright (C) 2016 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="android.security.net.config.cts.CtsNetSecConfigAttributeTestCases">
+  <application>
+      <uses-library android:name="android.test.runner"/>
+      <meta-data android:name="android.security.net.config"
+                 android:resource="@xml/network_security_config" />
+  </application>
+
+  <uses-permission android:name="android.permission.INTERNET" />
+  <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                   android:targetPackage="android.security.net.config.cts.CtsNetSecConfigAttributeTestCases"
+                   android:label="">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+</manifest>
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-attributes/res/xml/network_security_config.xml b/tests/tests/networksecurityconfig/networksecurityconfig-attributes/res/xml/network_security_config.xml
new file mode 100644
index 0000000..1e68b7d
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-attributes/res/xml/network_security_config.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+  <base-config cleartextTrafficPermitted="true">
+  </base-config>
+  <!-- Cleartext traffic is not permitted for connections to foo.bar -->
+  <domain-config cleartextTrafficPermitted="false">
+        <domain includeSubdomains="false">foo.bar</domain>
+  </domain-config>
+  <!-- cleartextTrafficPermitted not set, should inherit from the base-config -->
+  <domain-config>
+      <domain includeSubdomains="true">android.com</domain>
+  </domain-config>
+  <!-- Cleartext traffic is explicitly permitted to google.com and all subdomains -->
+  <domain-config cleartextTrafficPermitted="true">
+      <domain includeSubdomains="true">google.com</domain>
+  </domain-config>
+</network-security-config>
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-attributes/src/android/security/net/config/cts/TestAttributes.java b/tests/tests/networksecurityconfig/networksecurityconfig-attributes/src/android/security/net/config/cts/TestAttributes.java
new file mode 100644
index 0000000..4d23e5b
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-attributes/src/android/security/net/config/cts/TestAttributes.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2016 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 android.security.net.config.cts;
+
+import android.security.NetworkSecurityPolicy;
+import junit.framework.TestCase;
+
+public class TestAttributes extends TestCase {
+    public void testCleartextTrafficPermitted() throws Exception {
+        NetworkSecurityPolicy instance = NetworkSecurityPolicy.getInstance();
+        // Since there are some configs that do not allow cleartext the non-hostname aware version
+        // should return False.
+        assertFalse(instance.isCleartextTrafficPermitted());
+        // Domain that explicitly does not allow cleartext traffic.
+        assertFalse(instance.isCleartextTrafficPermitted("foo.bar"));
+        // Subdomains are not included in the above rule, they should use the base-config's value.
+        assertTrue(instance.isCleartextTrafficPermitted("example.foo.bar"));
+        // Domains in a domain-config that do not specify the flag, should inherit from the
+        // base-config.
+        assertTrue(instance.isCleartextTrafficPermitted("android.com"));
+        assertTrue(instance.isCleartextTrafficPermitted("foo.android.com"));
+        // Domains in a domain-config that explicitly allow cleartext.
+        assertTrue(instance.isCleartextTrafficPermitted("google.com"));
+        assertTrue(instance.isCleartextTrafficPermitted("test.google.com"));
+        // Domain not specified in a domain-config, should use the base-config's value.
+        assertTrue(instance.isCleartextTrafficPermitted("example.com"));
+    }
+}
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-basic-domain/Android.mk b/tests/tests/networksecurityconfig/networksecurityconfig-basic-domain/Android.mk
new file mode 100644
index 0000000..1224198
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-basic-domain/Android.mk
@@ -0,0 +1,19 @@
+# Copyright (C) 2016 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.
+#
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_PACKAGE_NAME := CtsNetSecConfigBasicDomainConfigTestCases
+include $(LOCAL_PATH)/../build_apk.mk
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-basic-domain/AndroidManifest.xml b/tests/tests/networksecurityconfig/networksecurityconfig-basic-domain/AndroidManifest.xml
new file mode 100644
index 0000000..0fd1a59
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-basic-domain/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ * Copyright (C) 2016 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="android.security.net.config.cts.CtsNetSecConfigBasicDomainConfigTestCases">
+  <application>
+      <uses-library android:name="android.test.runner"/>
+      <meta-data android:name="android.security.net.config"
+                 android:resource="@xml/network_security_config" />
+  </application>
+
+  <uses-permission android:name="android.permission.INTERNET" />
+  <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                   android:targetPackage="android.security.net.config.cts.CtsNetSecConfigBasicDomainConfigTestCases"
+                   android:label="">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+</manifest>
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-basic-domain/res/xml/network_security_config.xml b/tests/tests/networksecurityconfig/networksecurityconfig-basic-domain/res/xml/network_security_config.xml
new file mode 100644
index 0000000..6d8565c
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-basic-domain/res/xml/network_security_config.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+  <base-config>
+    <trust-anchors>
+    </trust-anchors>
+  </base-config>
+  <domain-config>
+    <domain>android.com</domain>
+    <trust-anchors>
+      <certificates src="system" />
+      <certificates src="user" />
+    </trust-anchors>
+  </domain-config>
+</network-security-config>
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-basic-domain/src/android/security/net/config/cts/DomainConfigTest.java b/tests/tests/networksecurityconfig/networksecurityconfig-basic-domain/src/android/security/net/config/cts/DomainConfigTest.java
new file mode 100644
index 0000000..73ddd33
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-basic-domain/src/android/security/net/config/cts/DomainConfigTest.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2016 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 android.security.net.config.cts;
+
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import javax.net.ssl.X509TrustManager;
+import junit.framework.TestCase;
+
+public class DomainConfigTest extends TestCase {
+
+    public void testDomainConfig() throws Exception {
+        TestUtils.assertTlsConnectionSucceeds("android.com", 443);
+    }
+
+    public void testDefaultConfig() throws Exception {
+        // The default config in this case has no trusted CAs, so all connections should fail.
+        TestUtils.assertTlsConnectionFails("developer.android.com", 443);
+        TestUtils.assertTlsConnectionFails("google.com", 443);
+    }
+
+    public void testHostnameAwareCheckServerTrustedRequired() throws Exception {
+        X509TrustManager x509tm = TestUtils.getDefaultTrustManager();
+        try {
+            x509tm.checkServerTrusted(new X509Certificate[] {}, "RSA");
+            fail("checkServerTrusted passed");
+        } catch (CertificateException e) {
+            if (!e.getMessage().contains("hostname aware checkServerTrusted")) {
+                fail("Hostname aware checkServerTrusted not required with a domain config");
+            }
+        }
+    }
+}
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-disabled/Android.mk b/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-disabled/Android.mk
new file mode 100644
index 0000000..70b9060
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-disabled/Android.mk
@@ -0,0 +1,19 @@
+# Copyright (C) 2016 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.
+#
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_PACKAGE_NAME := CtsNetSecConfigBasicDebugDisabledTestCases
+include $(LOCAL_PATH)/../build_apk.mk
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-disabled/AndroidManifest.xml b/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-disabled/AndroidManifest.xml
new file mode 100644
index 0000000..9464950
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-disabled/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ * Copyright (C) 2016 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="android.security.net.config.cts.CtsNetSecConfigBasicDebugDisabledTestCases">
+  <application android:debuggable="false">
+      <uses-library android:name="android.test.runner"/>
+      <meta-data android:name="android.security.net.config"
+                 android:resource="@xml/network_security_config" />
+  </application>
+
+  <uses-permission android:name="android.permission.INTERNET" />
+  <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                   android:targetPackage="android.security.net.config.cts.CtsNetSecConfigBasicDebugDisabledTestCases"
+                   android:label="">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+</manifest>
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-disabled/res/xml/network_security_config.xml b/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-disabled/res/xml/network_security_config.xml
new file mode 100644
index 0000000..c44d9de
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-disabled/res/xml/network_security_config.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+  <!-- default config that trusts nothing. Will always cause TLS errors -->
+  <base-config>
+    <trust-anchors>
+    </trust-anchors>
+  </base-config>
+  <!-- debug overrides, should be ignored in this case since the app is not debuggable -->
+  <debug-overrides>
+    <trust-anchors>
+      <certificates src="system" />
+    </trust-anchors>
+  </debug-overrides>
+</network-security-config>
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-disabled/src/android/security/net/config/cts/BasicDebugOverrideDisabledTest.java b/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-disabled/src/android/security/net/config/cts/BasicDebugOverrideDisabledTest.java
new file mode 100644
index 0000000..862dd9b
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-disabled/src/android/security/net/config/cts/BasicDebugOverrideDisabledTest.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2016 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 android.security.net.config.cts;
+
+import junit.framework.TestCase;
+
+public class BasicDebugOverrideDisabledTest extends TestCase {
+
+    public void testDefaultConfig() throws Exception {
+        TestUtils.assertTlsConnectionFails("android.com", 443);
+    }
+}
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-enabled/Android.mk b/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-enabled/Android.mk
new file mode 100644
index 0000000..433cf84
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-enabled/Android.mk
@@ -0,0 +1,19 @@
+# Copyright (C) 2016 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.
+#
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_PACKAGE_NAME := CtsNetSecConfigBasicDebugEnabledTestCases
+include $(LOCAL_PATH)/../build_apk.mk
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-enabled/AndroidManifest.xml b/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-enabled/AndroidManifest.xml
new file mode 100644
index 0000000..2a46c8c
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-enabled/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ * Copyright (C) 2016 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="android.security.net.config.cts.CtsNetSecConfigBasicDebugEnabledTestCases">
+  <application android:debuggable="true">
+      <uses-library android:name="android.test.runner"/>
+      <meta-data android:name="android.security.net.config"
+                 android:resource="@xml/network_security_config" />
+  </application>
+
+  <uses-permission android:name="android.permission.INTERNET" />
+  <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                   android:targetPackage="android.security.net.config.cts.CtsNetSecConfigBasicDebugEnabledTestCases"
+                   android:label="">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+</manifest>
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-enabled/res/xml/network_security_config.xml b/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-enabled/res/xml/network_security_config.xml
new file mode 100644
index 0000000..f2c800a
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-enabled/res/xml/network_security_config.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+  <!-- default config that trusts nothing. Will always cause TLS errors -->
+  <base-config>
+    <trust-anchors>
+    </trust-anchors>
+  </base-config>
+  <!-- debug override that trusts the system CA store. Connections will work as normal when the
+       application is debuggable. -->
+  <debug-overrides>
+    <trust-anchors>
+      <certificates src="system" />
+    </trust-anchors>
+  </debug-overrides>
+</network-security-config>
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-enabled/src/android/security/net/config/cts/BasicDebugOverrideEnabledTest.java b/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-enabled/src/android/security/net/config/cts/BasicDebugOverrideEnabledTest.java
new file mode 100644
index 0000000..c0d9814
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-enabled/src/android/security/net/config/cts/BasicDebugOverrideEnabledTest.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2016 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 android.security.net.config.cts;
+
+import junit.framework.TestCase;
+
+public class BasicDebugOverrideEnabledTest extends TestCase {
+
+    public void testDefaultConfig() throws Exception {
+        // Connections should work thanks to the debug overrides adding the system CA store.
+        TestUtils.assertTlsConnectionSucceeds("android.com", 443);
+    }
+}
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-invalid-pin/Android.mk b/tests/tests/networksecurityconfig/networksecurityconfig-invalid-pin/Android.mk
new file mode 100644
index 0000000..3d7febb
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-invalid-pin/Android.mk
@@ -0,0 +1,19 @@
+# Copyright (C) 2016 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.
+#
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_PACKAGE_NAME := CtsNetSecConfigInvalidPinTestCases
+include $(LOCAL_PATH)/../build_apk.mk
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-invalid-pin/AndroidManifest.xml b/tests/tests/networksecurityconfig/networksecurityconfig-invalid-pin/AndroidManifest.xml
new file mode 100644
index 0000000..e01dc07
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-invalid-pin/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ * Copyright (C) 2016 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="android.security.net.config.cts.CtsNetSecConfigInvalidPinTestCases">
+  <application>
+      <uses-library android:name="android.test.runner"/>
+      <meta-data android:name="android.security.net.config"
+                 android:resource="@xml/network_security_config" />
+  </application>
+
+  <uses-permission android:name="android.permission.INTERNET" />
+  <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                   android:targetPackage="android.security.net.config.cts.CtsNetSecConfigInvalidPinTestCases"
+                   android:label="">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+</manifest>
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-invalid-pin/res/xml/network_security_config.xml b/tests/tests/networksecurityconfig/networksecurityconfig-invalid-pin/res/xml/network_security_config.xml
new file mode 100644
index 0000000..163b238
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-invalid-pin/res/xml/network_security_config.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+  <domain-config>
+    <domain>android.com</domain>
+    <pin-set>
+      <!-- Invalid pin for android.com -->
+      <pin digest="SHA-256">1HIpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y=</pin>
+    </pin-set>
+  </domain-config>
+</network-security-config>
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-invalid-pin/src/android/security/net/config/cts/InvalidPinTest.java b/tests/tests/networksecurityconfig/networksecurityconfig-invalid-pin/src/android/security/net/config/cts/InvalidPinTest.java
new file mode 100644
index 0000000..fb0444a
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-invalid-pin/src/android/security/net/config/cts/InvalidPinTest.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2016 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 android.security.net.config.cts;
+
+import junit.framework.TestCase;
+
+public class InvalidPinTest extends TestCase {
+
+    public void testPinFailure() throws Exception {
+        TestUtils.assertTlsConnectionFails("android.com", 443);
+    }
+
+    public void testDefaultDomainUnaffected() throws Exception {
+        TestUtils.assertTlsConnectionSucceeds("google.com", 443);
+        TestUtils.assertTlsConnectionSucceeds("developer.android.com", 443);
+    }
+}
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-nested-domains/Android.mk b/tests/tests/networksecurityconfig/networksecurityconfig-nested-domains/Android.mk
new file mode 100644
index 0000000..66fef09
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-nested-domains/Android.mk
@@ -0,0 +1,19 @@
+# Copyright (C) 2016 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.
+#
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_PACKAGE_NAME := CtsNetSecConfigNestedDomainConfigTestCases
+include $(LOCAL_PATH)/../build_apk.mk
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-nested-domains/AndroidManifest.xml b/tests/tests/networksecurityconfig/networksecurityconfig-nested-domains/AndroidManifest.xml
new file mode 100644
index 0000000..358644e
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-nested-domains/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ * Copyright (C) 2016 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="android.security.net.config.cts.CtsNetSecConfigNestedDomainConfigTestCases">
+  <application>
+      <uses-library android:name="android.test.runner"/>
+      <meta-data android:name="android.security.net.config"
+                 android:resource="@xml/network_security_config" />
+  </application>
+
+  <uses-permission android:name="android.permission.INTERNET" />
+  <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                   android:targetPackage="android.security.net.config.cts.CtsNetSecConfigNestedDomainConfigTestCases"
+                   android:label="">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+</manifest>
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-nested-domains/res/xml/network_security_config.xml b/tests/tests/networksecurityconfig/networksecurityconfig-nested-domains/res/xml/network_security_config.xml
new file mode 100644
index 0000000..9e91dc7
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-nested-domains/res/xml/network_security_config.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+  <domain-config cleartextTrafficPermitted="true">
+    <domain includeSubdomains="true">android.com</domain>
+    <!-- Empty trust anchors, all TLS connections will fail -->
+    <trust-anchors>
+    </trust-anchors>
+    <!-- Nested config, should inherit all unset values from the parent domain -->
+    <domain-config cleartextTrafficPermitted="false">
+      <domain>developer.android.com</domain>
+    </domain-config>
+  </domain-config>
+  <base-config>
+  </base-config>
+</network-security-config>
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-nested-domains/src/android/security/net/config/cts/NestedDomainConfigTest.java b/tests/tests/networksecurityconfig/networksecurityconfig-nested-domains/src/android/security/net/config/cts/NestedDomainConfigTest.java
new file mode 100644
index 0000000..b77ad5a
--- /dev/null
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-nested-domains/src/android/security/net/config/cts/NestedDomainConfigTest.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2016 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 android.security.net.config.cts;
+
+import android.security.NetworkSecurityPolicy;
+
+import junit.framework.TestCase;
+
+public class NestedDomainConfigTest extends TestCase {
+
+    public void testRootDomainConfig() throws Exception {
+        TestUtils.assertTlsConnectionFails("android.com", 443);
+        NetworkSecurityPolicy instance = NetworkSecurityPolicy.getInstance();
+        assertTrue(instance.isCleartextTrafficPermitted("android.com"));
+    }
+
+    public void testNestedDomainConfig() throws Exception {
+        TestUtils.assertTlsConnectionFails("developer.android.com", 443);
+        NetworkSecurityPolicy instance = NetworkSecurityPolicy.getInstance();
+        assertFalse(instance.isCleartextTrafficPermitted("developer.android.com"));
+    }
+}
diff --git a/tests/tests/networksecurityconfig/src/android/security/net/config/cts/TestUtils.java b/tests/tests/networksecurityconfig/src/android/security/net/config/cts/TestUtils.java
new file mode 100644
index 0000000..0952cd3
--- /dev/null
+++ b/tests/tests/networksecurityconfig/src/android/security/net/config/cts/TestUtils.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2016 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 android.security.net.config.cts;
+
+import android.net.http.AndroidHttpClient;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.net.Socket;
+import java.net.URL;
+import java.security.KeyStore;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.List;
+import java.util.ArrayList;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLHandshakeException;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509TrustManager;
+
+import junit.framework.Assert;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpGet;
+
+public final class TestUtils extends Assert {
+
+    private TestUtils() {
+    }
+
+
+    public static void assertTlsConnectionSucceeds(String host, int port) throws Exception {
+        assertSslSocketSucceeds(host, port);
+        assertHttpClientHttpsSucceeds(host, port);
+        assertUrlConnectionHttpsSucceeds(host, port);
+    }
+
+    public static void assertTlsConnectionFails(String host, int port) throws Exception {
+        assertSslSocketFails(host, port);
+        assertHttpClientHttpsFails(host, port);
+        assertUrlConnectionHttpsFails(host, port);
+    }
+
+    public static X509TrustManager getDefaultTrustManager() throws Exception {
+        TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");
+        tmf.init((KeyStore)null);
+        for (TrustManager tm : tmf.getTrustManagers()) {
+            if (tm instanceof X509TrustManager) {
+                return (X509TrustManager) tm;
+            }
+        }
+        fail("Unable to find X509TrustManager");
+        return null;
+    }
+
+    public static List<X509Certificate> loadCertificates(InputStream is) throws Exception {
+        CertificateFactory factory = CertificateFactory.getInstance("X.509");
+        ArrayList<X509Certificate> result = new ArrayList<>();
+        for (Certificate c : factory.generateCertificates(is)) {
+            result.add((X509Certificate) c);
+        }
+        return result;
+    }
+
+    private static void assertSslSocketFails(String host, int port)
+            throws Exception {
+        try {
+            Socket s = SSLContext.getDefault().getSocketFactory().createSocket(host, port);
+            s.getInputStream();
+            fail("Connection to " + host + ":" + port + " succeeded");
+        } catch (SSLHandshakeException expected) {
+        }
+    }
+
+    private static void assertSslSocketSucceeds(String host, int port)
+            throws Exception {
+        Socket s = SSLContext.getDefault().getSocketFactory().createSocket(host, port);
+        s.getInputStream();
+    }
+
+    private static void assertUrlConnectionHttpsFails(String host, int port)
+            throws Exception {
+        URL url = new URL("https://" + host + ":" + port);
+        HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
+        try {
+            connection.getInputStream();
+            fail("Connection to " + host + ":" + port + " succeeded");
+        } catch (SSLHandshakeException expected) {
+        }
+    }
+
+    private static void assertUrlConnectionHttpsSucceeds(String host, int port)
+            throws Exception {
+        URL url = new URL("https://" + host + ":" + port);
+        HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
+        connection.getInputStream();
+    }
+
+    private static void assertHttpClientHttpsSucceeds(String host, int port) throws Exception {
+        URL url = new URL("https://" + host + ":" + port);
+        AndroidHttpClient httpClient = AndroidHttpClient.newInstance(null);
+        try {
+            HttpResponse response = httpClient.execute(new HttpGet(url.toString()));
+        } finally {
+            httpClient.close();
+        }
+    }
+
+    private static void assertHttpClientHttpsFails(String host, int port) throws Exception {
+        URL url = new URL("https://" + host + ":" + port);
+        AndroidHttpClient httpClient = AndroidHttpClient.newInstance(null);
+        try {
+            HttpResponse response = httpClient.execute(new HttpGet(url.toString()));
+            fail("Connection to " + host + ":" + port + " succeeded");
+        } catch (IOException expected) {
+        } finally {
+            httpClient.close();
+        }
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/SingleSourceAllocationTest.java b/tests/tests/renderscript/src/android/renderscript/cts/SingleSourceAllocationTest.java
new file mode 100644
index 0000000..88b96ac
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/SingleSourceAllocationTest.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2015-2016 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 android.renderscript.cts;
+
+import android.util.Log;
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.Script;
+import android.renderscript.Type;
+import android.renderscript.Type.Builder;
+
+public class SingleSourceAllocationTest extends RSBaseCompute {
+
+    private static final String TAG = "SingleSourceAllocationTest";
+
+    private ScriptC_single_source_alloc s;
+    private static final int dimX = 3;
+    private static final int dimY = 4;
+    private static final int dimZ = 5;
+    private static final int start = 23;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        s = new ScriptC_single_source_alloc(mRS);
+        s.set_gDimX(dimX);
+        s.set_gDimY(dimY);
+        s.set_gDimZ(dimZ);
+        s.set_gStart(start);
+    }
+
+    public void testElementCreation() {
+        s.invoke_TestElementCreation();
+        waitForMessage();
+        checkForErrors();
+    }
+
+    public void testTypeCreation() {
+        s.invoke_TestTypeCreation();
+        waitForMessage();
+        checkForErrors();
+    }
+
+    public void testAllocationCreationWithUsage() {
+        s.invoke_TestAllocationCreationWithUsage();
+        waitForMessage();
+        checkForErrors();
+    }
+
+    public void testAllocationCreationHelperFunctions() {
+        s.invoke_TestHelperFunctions();
+        waitForMessage();
+        checkForErrors();
+    }
+
+    public void testAllocationCreationAndAccess() {
+        s.invoke_TestAllocationCreationAndAccess();
+        waitForMessage();
+        checkForErrors();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/SingleSourceForEachTest.java b/tests/tests/renderscript/src/android/renderscript/cts/SingleSourceForEachTest.java
new file mode 100644
index 0000000..e005013
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/SingleSourceForEachTest.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2015-2016 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 android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.Script;
+import android.renderscript.Type;
+import android.renderscript.Type.Builder;
+
+public class SingleSourceForEachTest extends RSBaseCompute {
+
+    private static final int X = 1024;
+    private static final int Y = 768;
+
+    private Allocation testInputAlloc;
+    private Allocation testInputAlloc2;
+    private Allocation testOutputAlloc;
+    private Allocation baselineOutputAlloc;
+    private int testInputArray[];
+    private int testInputArray2[];
+    private int testOutputArray[];
+    private int baselineOutputArray[];
+    private ScriptC_single_source_script s;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        Type.Builder i32TypeBuilder = new Type.Builder(mRS, Element.I32(mRS));
+        i32TypeBuilder.setX(X).setY(Y);
+        testInputAlloc = Allocation.createTyped(mRS, i32TypeBuilder.create());
+        testInputAlloc2 = Allocation.createTyped(mRS, i32TypeBuilder.create());
+        testOutputAlloc = Allocation.createTyped(mRS, i32TypeBuilder.create());
+        baselineOutputAlloc = Allocation.createTyped(mRS, i32TypeBuilder.create());
+
+        testInputArray = new int[X * Y];
+        testInputArray2 = new int[X * Y];
+        testOutputArray = new int[X * Y];
+        baselineOutputArray = new int[X * Y];
+
+        s = new ScriptC_single_source_script(mRS);
+
+        RSUtils.genRandomInts(0x900d5eed, testInputArray, true, 32);
+        testInputAlloc.copyFrom(testInputArray);
+
+        for (int i = 0; i < testInputArray2.length; i++) {
+            testInputArray2[i] = i + 1;
+        }
+        testInputAlloc2.copyFrom(testInputArray2);
+    }
+
+    public void testSingleInputKernelLaunch() {
+        s.forEach_foo(testInputAlloc, baselineOutputAlloc);
+        s.invoke_testSingleInput(testInputAlloc, testOutputAlloc);
+        testOutputAlloc.copyTo(testOutputArray);
+        baselineOutputAlloc.copyTo(baselineOutputArray);
+        checkArray(baselineOutputArray, testOutputArray, Y, X, X);
+    }
+
+    public void testMultiInputKernelLaunch() {
+        s.forEach_goo(testInputAlloc, testInputAlloc2,
+                      baselineOutputAlloc);
+        s.invoke_testMultiInput(testInputAlloc, testInputAlloc2,
+                                testOutputAlloc);
+        testOutputAlloc.copyTo(testOutputArray);
+        baselineOutputAlloc.copyTo(baselineOutputArray);
+        checkArray(baselineOutputArray, testOutputArray, Y, X, X);
+    }
+
+    public void testKernelLaunchWithOptions() {
+        Script.LaunchOptions sc = new Script.LaunchOptions();
+        sc.setX(0, X);
+        sc.setY(0, Y / 2);
+        s.forEach_foo(testInputAlloc, baselineOutputAlloc, sc);
+        s.invoke_testLaunchOptions(testInputAlloc, testOutputAlloc, X, Y);
+        testOutputAlloc.copyTo(testOutputArray);
+        baselineOutputAlloc.copyTo(baselineOutputArray);
+        checkArray(baselineOutputArray, testOutputArray, Y, X, X);
+    }
+
+    public void testAllocationlessKernelLaunch() {
+        baselineOutputAlloc.copyFrom(testInputArray);
+        testOutputAlloc.copyFrom(testInputArray);
+
+        Script.LaunchOptions sc = new Script.LaunchOptions();
+        sc.setX(0, X);
+        sc.setY(0, Y);
+        s.set_gAllocOut(baselineOutputAlloc);
+        s.forEach_bar(sc);
+
+        s.invoke_testAllocationlessLaunch(testOutputAlloc, X, Y);
+
+        testOutputAlloc.copyTo(testOutputArray);
+        baselineOutputAlloc.copyTo(baselineOutputArray);
+        checkArray(baselineOutputArray, testOutputArray, Y, X, X);
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/get_allocation.rs b/tests/tests/renderscript/src/android/renderscript/cts/get_allocation.rs
index 0149e6c..01cb47c 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/get_allocation.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/get_allocation.rs
@@ -6,11 +6,11 @@
 rs_allocation alloc_in;
 rs_allocation alloc_out;
 
-void root(const int* in, int *out) {
-    *out = *in;
+int __attribute__((kernel)) copy(int in) {
+    return in;
 }
 
 void start() {
     alloc_in = rsGetAllocation(pointer);
-    rsForEach(script, alloc_in, alloc_out);
+    rsForEach(copy, alloc_in, alloc_out);
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/shared.rsh b/tests/tests/renderscript/src/android/renderscript/cts/shared.rsh
index 2ad81fc..6fd78f6 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/shared.rsh
+++ b/tests/tests/renderscript/src/android/renderscript/cts/shared.rsh
@@ -21,6 +21,9 @@
 \
 } while (0)
 
+#define _RS_ASSERT_EQU(e1, e2) \
+  (((e1) != (e2)) ? (failed = true, rsDebug(#e1 " != " #e2, (e1), (e2)), false) : true)
+
 /* These constants must match those in UnitTest.java */
 static const int RS_MSG_TEST_PASSED = 100;
 static const int RS_MSG_TEST_FAILED = 101;
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/single_source_alloc.rs b/tests/tests/renderscript/src/android/renderscript/cts/single_source_alloc.rs
new file mode 100644
index 0000000..2575d54
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/single_source_alloc.rs
@@ -0,0 +1,463 @@
+/*
+ * Copyright (C) 2015-2016 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.
+ */
+
+#include "shared.rsh"
+
+int gDimX;
+int gDimY;
+int gDimZ;
+int gStart;
+static bool failed = false;
+
+// For each type, define 4 kernels, one per vector variant, that walk an
+// allocation and validate each cell.  The value in a cell must be gStart +
+// "index-of-the-cell-starting-from-zero".  For vector types, the 'x' field
+// must have this value.  The expected values for 'y', 'z' and 'w' follow the
+// 'x' value in increments of one.
+//
+// 'z' will be zero for 2D and 1D allocations.  'y' will be zero for 1D
+// allocations.
+
+#define VERIFY_KERNEL(CT)                                                      \
+    void RS_KERNEL verify_##CT(CT in, int x, int y, int z) {                   \
+        int val = (gStart + x + y * gDimX + z * gDimY * gDimX);                \
+        _RS_ASSERT_EQU(in, (CT) val);                                          \
+    }                                                                          \
+    void RS_KERNEL verify_##CT##2(CT##2 in, int x, int y, int z) {             \
+        int val = (gStart + x + y * gDimX + z * gDimY * gDimX);                \
+        _RS_ASSERT_EQU(in.x, (CT) val);                                        \
+        _RS_ASSERT_EQU(in.y, (CT) (val + 1));                                  \
+    }                                                                          \
+    void RS_KERNEL verify_##CT##3(CT##3 in, int x, int y, int z) {             \
+        int val = (gStart + x + y * gDimX + z * gDimY * gDimX);                \
+        _RS_ASSERT_EQU(in.x, (CT) val);                                        \
+        _RS_ASSERT_EQU(in.y, (CT) (val + 1));                                  \
+        _RS_ASSERT_EQU(in.z, (CT) (val + 2));                                  \
+    }                                                                          \
+    void RS_KERNEL verify_##CT##4(CT##4 in, int x, int y, int z) {             \
+        int val = (gStart + x + y * gDimX + z * gDimY * gDimX);                \
+        _RS_ASSERT_EQU(in.x, (CT) val);                                        \
+        _RS_ASSERT_EQU(in.y, (CT) (val + 1));                                  \
+        _RS_ASSERT_EQU(in.z, (CT) (val + 2));                                  \
+        _RS_ASSERT_EQU(in.w, (CT) (val + 3));                                  \
+    }                                                                          \
+
+VERIFY_KERNEL(float)
+VERIFY_KERNEL(double)
+VERIFY_KERNEL(char)
+VERIFY_KERNEL(short)
+VERIFY_KERNEL(int)
+VERIFY_KERNEL(long)
+VERIFY_KERNEL(uchar)
+VERIFY_KERNEL(ushort)
+VERIFY_KERNEL(uint)
+VERIFY_KERNEL(ulong)
+
+// Store to an allocation based on the vector size and dimensionality being
+// tested.  SETELEMENTAT, STORE_TO_ALLOC capture the following variables from
+// the context where they get instantiated:
+//     vecSize, gAlloc, val, x, y, z
+
+#define SETELEMENTAT(CT)                                                      \
+    if (gDimZ != 0) {                                                         \
+        rsSetElementAt_##CT(gAlloc, storeVal, x, y, z);                       \
+    }                                                                         \
+    else if (gDimY != 0) {                                                    \
+        rsSetElementAt_##CT(gAlloc, storeVal, x, y);                          \
+    }                                                                         \
+    else {                                                                    \
+        rsSetElementAt_##CT(gAlloc, storeVal, x);                             \
+    }
+
+#define STORE_TO_ALLOC(RST, CT)                                               \
+    case RST:                                                                 \
+        switch (vecSize) {                                                    \
+            case 1: {                                                         \
+                CT storeVal = (CT) val;                                       \
+                SETELEMENTAT(CT);                                             \
+                     }                                                        \
+                break;                                                        \
+            case 2: {                                                         \
+                CT##2 storeVal = {(CT) val, (CT) (val + 1)};                  \
+                SETELEMENTAT(CT##2);                                          \
+                    }                                                         \
+                break;                                                        \
+            case 3: {                                                         \
+                CT##3 storeVal = {(CT) val, (CT) (val + 1), (CT) (val + 2)};  \
+                SETELEMENTAT(CT##3);                                          \
+                    }                                                         \
+                break;                                                        \
+            case 4: {                                                         \
+                CT##4 storeVal = {(CT) val, (CT) (val + 1), (CT) (val + 2),   \
+                                  (CT) (val + 3)};                            \
+                SETELEMENTAT(CT##4);                                          \
+                    }                                                         \
+                break;                                                        \
+        }                                                                     \
+        break;                                                                \
+
+
+// Launch the verify_kernel based on the appropriate type and vector size.
+#define LAUNCH_VERIFY_KERNEL(RST, CT)                                         \
+    case RST:                                                                 \
+        if (vecSize == 1) rsForEach(verify_##CT, gAlloc);                     \
+        else if (vecSize == 2) rsForEach(verify_##CT##2, gAlloc);             \
+        else if (vecSize == 3) rsForEach(verify_##CT##3, gAlloc);             \
+        else if (vecSize == 4) rsForEach(verify_##CT##4, gAlloc);             \
+        break;
+
+void checkAndSendResult() {
+    if (failed) {
+        rsDebug("Single Source Alloc Test Failed", 0);
+        rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+    }
+    else {
+        rsDebug("Single Source Alloc Test Passed", 0);
+        rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+    }
+}
+
+static void CreateAndTestAlloc(rs_data_type dt, int vecSize, int dimX, int dimY, int dimZ) {
+    failed = false;
+
+    if (dimZ != 0 && dimY == 0) {
+        _RS_ASSERT(false); // Invalid test
+        return;
+    }
+
+    if (dimX == 0) {
+        _RS_ASSERT(false); // Invalid test
+        return;
+    }
+
+    rs_element element;
+    rs_type type;
+    rs_allocation gAlloc;
+
+    // Create and validate the rs_element object
+    if (vecSize == 1)
+        element = rsCreateElement((rs_data_type) dt);
+    else
+        element = rsCreateVectorElement((rs_data_type) dt, vecSize);
+    _RS_ASSERT(rsIsObject(element));
+    if (!rsIsObject(element)) {
+        return;
+    }
+
+    // Create and validate the rs_type object
+    type = rsCreateType(element, dimX, dimY, dimZ);
+    _RS_ASSERT(rsIsObject(type));
+    if (!rsIsObject(type)) {
+        return;
+    }
+
+    // Create and validate the rs_allocation object
+    gAlloc = rsCreateAllocation(type);
+    if (!rsIsObject(gAlloc)) {
+        return;
+    }
+
+    // Handle RenderScript's distinction between Y or Z dimension being absent
+    // and having a size of 1
+    int zEnd = (dimZ != 0) ? dimZ: 1;
+    int yEnd = (dimY != 0) ? dimY: 1;
+    for (int z = 0; z < zEnd; z ++) {
+        for (int y = 0; y < yEnd; y ++) {
+            for (int x = 0; x < dimX; x ++) {
+                int val = gStart + (x + y * dimX + z * dimY * dimX);
+
+                // Store to a cell based on the type, vector size and
+                // dimensionality
+                switch (dt) {
+                    STORE_TO_ALLOC(RS_TYPE_FLOAT_32, float);
+                    STORE_TO_ALLOC(RS_TYPE_FLOAT_64, double);
+                    STORE_TO_ALLOC(RS_TYPE_SIGNED_8, char);
+                    STORE_TO_ALLOC(RS_TYPE_SIGNED_16, short);
+                    STORE_TO_ALLOC(RS_TYPE_SIGNED_32, int);
+                    STORE_TO_ALLOC(RS_TYPE_SIGNED_64, long);
+                    STORE_TO_ALLOC(RS_TYPE_UNSIGNED_8, uchar);
+                    STORE_TO_ALLOC(RS_TYPE_UNSIGNED_16, ushort);
+                    STORE_TO_ALLOC(RS_TYPE_UNSIGNED_32, uint);
+                    STORE_TO_ALLOC(RS_TYPE_UNSIGNED_64, ulong);
+                    default:
+                        // Invalid test
+                        _RS_ASSERT(false);
+                        break;
+                }
+            }
+        }
+    }
+
+    // Launch the appropriate verify_ kernel
+    switch (dt) {
+        LAUNCH_VERIFY_KERNEL(RS_TYPE_FLOAT_32, float);
+        LAUNCH_VERIFY_KERNEL(RS_TYPE_FLOAT_64, double);
+        LAUNCH_VERIFY_KERNEL(RS_TYPE_SIGNED_8, char);
+        LAUNCH_VERIFY_KERNEL(RS_TYPE_SIGNED_16, short);
+        LAUNCH_VERIFY_KERNEL(RS_TYPE_SIGNED_32, int);
+        LAUNCH_VERIFY_KERNEL(RS_TYPE_SIGNED_64, long);
+        LAUNCH_VERIFY_KERNEL(RS_TYPE_UNSIGNED_8, uchar);
+        LAUNCH_VERIFY_KERNEL(RS_TYPE_UNSIGNED_16, ushort);
+        LAUNCH_VERIFY_KERNEL(RS_TYPE_UNSIGNED_32, uint);
+        LAUNCH_VERIFY_KERNEL(RS_TYPE_UNSIGNED_64, ulong);
+
+        default:
+            // Invalid test
+            _RS_ASSERT(false);
+            break;
+    }
+}
+
+void TestAllocationCreationAndAccess() {
+    rs_data_type all_types[] = {
+        RS_TYPE_BOOLEAN,
+        // Bug 24862914: Uncomment the following line to add half once the bug is fixed
+        // RS_TYPE_FLOAT_16,
+        RS_TYPE_FLOAT_32,
+        RS_TYPE_FLOAT_64,
+        RS_TYPE_SIGNED_8,
+        RS_TYPE_SIGNED_16,
+        RS_TYPE_SIGNED_32,
+        RS_TYPE_SIGNED_64,
+        RS_TYPE_UNSIGNED_8,
+        RS_TYPE_UNSIGNED_16,
+        RS_TYPE_UNSIGNED_32,
+        RS_TYPE_UNSIGNED_64,
+    };
+
+    for (int i = 0; i < sizeof(all_types) / sizeof(all_types[0]); i++) {
+        for (int vecSize = 1; vecSize <= 4; vecSize ++) {
+            for (int nDims = 1; nDims <= 3; nDims ++) {
+                int dimY = nDims > 1 ? gDimY : 0;
+                int dimZ = nDims > 2 ? gDimZ : 0;
+                CreateAndTestAlloc(all_types[i], vecSize, gDimX, dimY, dimZ);
+            }
+        }
+    }
+
+    checkAndSendResult();
+}
+
+#define TEST_DATA_TYPE(dt, allowSimple, allowVector, allowPixel) {             \
+    if (allowSimple)                                                           \
+        _RS_ASSERT(rsIsObject(rsCreateElement(dt)));                           \
+    else                                                                       \
+        _RS_ASSERT(!rsIsObject(rsCreateElement(dt)));                          \
+    if (allowVector)                                                           \
+        _RS_ASSERT(rsIsObject(rsCreateVectorElement(dt, 3)));                  \
+    else                                                                       \
+        _RS_ASSERT(!rsIsObject(rsCreateVectorElement(dt, 3)));                 \
+    if (allowPixel)                                                            \
+        _RS_ASSERT(rsIsObject(rsCreatePixelElement(dt, RS_KIND_PIXEL_DEPTH))); \
+    else                                                                       \
+        _RS_ASSERT(!rsIsObject(rsCreatePixelElement(dt, RS_KIND_PIXEL_DEPTH)));\
+}
+
+#define TEST_SUPPORTED_PIXEL(dt, dk) {                                         \
+    _RS_ASSERT(rsIsObject(rsCreatePixelElement(dt, dk)));                      \
+}
+
+#define TEST_UNSUPPORTED_PIXEL(dt, dk) {                                       \
+    _RS_ASSERT(!rsIsObject(rsCreatePixelElement(dt, dk)));                     \
+}
+
+#define TEST_HELPER(suffix) {                                     \
+    _RS_ASSERT(rsIsObject(rsCreateAllocation_##suffix(3)));       \
+    _RS_ASSERT(rsIsObject(rsCreateAllocation_##suffix(3, 4)));    \
+    _RS_ASSERT(rsIsObject(rsCreateAllocation_##suffix(3, 4, 5))); \
+    }
+
+#define TEST_HELPERS(CT) { \
+    TEST_HELPER(CT);       \
+    TEST_HELPER(CT##2);    \
+    TEST_HELPER(CT##3);    \
+    TEST_HELPER(CT##4);    \
+}
+
+void TestElementCreation() {
+    failed = false;
+
+    // vector_width must be at least 2
+    rs_element oneElt = rsCreateVectorElement(RS_TYPE_SIGNED_32, 1);
+    _RS_ASSERT(!rsIsObject(oneElt));
+
+    // vector_width must be at most 4
+    rs_element fiveElt = rsCreateVectorElement(RS_TYPE_SIGNED_32, 5);
+    _RS_ASSERT(!rsIsObject(fiveElt));
+
+    /////////////////////////////////////////////////////////////////
+    // Element validation
+    /////////////////////////////////////////////////////////////////
+    // These types are valid for scalar and vectors, but don't support pixel
+    TEST_DATA_TYPE(RS_TYPE_BOOLEAN,     true, true, false);
+    TEST_DATA_TYPE(RS_TYPE_FLOAT_32,    true, true, false);
+    TEST_DATA_TYPE(RS_TYPE_FLOAT_64,    true, true, false);
+    TEST_DATA_TYPE(RS_TYPE_SIGNED_8,    true, true, false);
+    TEST_DATA_TYPE(RS_TYPE_SIGNED_16,   true, true, false);
+    TEST_DATA_TYPE(RS_TYPE_SIGNED_32,   true, true, false);
+    TEST_DATA_TYPE(RS_TYPE_SIGNED_64,   true, true, false);
+    TEST_DATA_TYPE(RS_TYPE_UNSIGNED_32, true, true, false);
+    TEST_DATA_TYPE(RS_TYPE_UNSIGNED_64, true, true, false);
+
+    // These types are valid only for scalars
+    TEST_DATA_TYPE(RS_TYPE_MATRIX_4X4, true, false, false);
+    TEST_DATA_TYPE(RS_TYPE_MATRIX_3X3, true, false, false);
+    TEST_DATA_TYPE(RS_TYPE_MATRIX_2X2, true, false, false);
+    TEST_DATA_TYPE(RS_TYPE_ELEMENT,    true, false, false);
+    TEST_DATA_TYPE(RS_TYPE_TYPE,       true, false, false);
+    TEST_DATA_TYPE(RS_TYPE_ALLOCATION, true, false, false);
+    TEST_DATA_TYPE(RS_TYPE_SCRIPT,     true, false, false);
+
+    // U8, U16 are valid for scalar, vector and pixel
+    TEST_DATA_TYPE(RS_TYPE_UNSIGNED_8,  true, true, true);
+    TEST_DATA_TYPE(RS_TYPE_UNSIGNED_16, true, true, true);
+
+    // These data types are only for pixels and a particular data_kind
+    TEST_SUPPORTED_PIXEL  (RS_TYPE_UNSIGNED_5_6_5,   RS_KIND_PIXEL_RGB);
+    TEST_UNSUPPORTED_PIXEL(RS_TYPE_UNSIGNED_5_6_5,   RS_KIND_PIXEL_L);
+    TEST_SUPPORTED_PIXEL  (RS_TYPE_UNSIGNED_5_5_5_1, RS_KIND_PIXEL_RGBA);
+    TEST_UNSUPPORTED_PIXEL(RS_TYPE_UNSIGNED_5_5_5_1, RS_KIND_PIXEL_L);
+    TEST_SUPPORTED_PIXEL  (RS_TYPE_UNSIGNED_4_4_4_4, RS_KIND_PIXEL_RGBA);
+    TEST_UNSUPPORTED_PIXEL(RS_TYPE_UNSIGNED_4_4_4_4, RS_KIND_PIXEL_L);
+    TEST_SUPPORTED_PIXEL  (RS_TYPE_UNSIGNED_16,      RS_KIND_PIXEL_DEPTH);
+    TEST_UNSUPPORTED_PIXEL(RS_TYPE_UNSIGNED_4_4_4_4, RS_KIND_PIXEL_L);
+
+    // These data types are not supported from single-source
+    TEST_DATA_TYPE(RS_TYPE_NONE,             false, false, false);
+    TEST_DATA_TYPE(RS_TYPE_SAMPLER,          false, false, false);
+    TEST_DATA_TYPE(RS_TYPE_MESH,             false, false, false);
+    TEST_DATA_TYPE(RS_TYPE_PROGRAM_FRAGMENT, false, false, false);
+    TEST_DATA_TYPE(RS_TYPE_PROGRAM_VERTEX,   false, false, false);
+    TEST_DATA_TYPE(RS_TYPE_PROGRAM_RASTER,   false, false, false);
+    TEST_DATA_TYPE(RS_TYPE_PROGRAM_STORE,    false, false, false);
+    TEST_DATA_TYPE(RS_TYPE_FONT,             false, false, false);
+    TEST_DATA_TYPE(RS_TYPE_INVALID,          false, false, false);
+
+    checkAndSendResult();
+}
+
+void TestTypeCreation() {
+    failed = false;
+
+    /////////////////////////////////////////////////////////////////
+    // Test rs_type creation
+    /////////////////////////////////////////////////////////////////
+    rs_element I32_3 = rsCreateVectorElement(RS_TYPE_SIGNED_32, 3);
+
+    // Create 1D, 2D, 3D types
+    _RS_ASSERT(rsIsObject(rsCreateType(I32_3, 3)));
+    _RS_ASSERT(rsIsObject(rsCreateType(I32_3, 3, 4)));
+    _RS_ASSERT(rsIsObject(rsCreateType(I32_3, 3, 4, 5)));
+    _RS_ASSERT(rsIsObject(rsCreateType(I32_3, 0))); // x = 0 is allowed
+
+    // Invalid dimensionality
+    _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 0, 4))); // x is 0 but y isn't
+    _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 0, 4, 5))); // x is 0 but z isn't
+    _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 0, 5))); // y is 0 but z isn't
+
+    // shape attributes
+    // Valid yuv_format
+    _RS_ASSERT(rsIsObject(rsCreateType(I32_3, 3, 4, 0, false, false,
+                    RS_YUV_NONE)));
+    _RS_ASSERT(rsIsObject(rsCreateType(I32_3, 3, 4, 0, false, false,
+                    RS_YUV_YV12)));
+    _RS_ASSERT(rsIsObject(rsCreateType(I32_3, 3, 4, 0, false, false,
+                    RS_YUV_NV21)));
+    _RS_ASSERT(rsIsObject(rsCreateType(I32_3, 3, 4, 0, false, false,
+                    RS_YUV_420_888)));
+
+    // Invalid yuv_format
+    _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 4, 5, false, false, 1024)));
+    // yuv_format with 1D or 3D is invalid
+    _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 0, 0, false, false,
+                    RS_YUV_YV12)));
+    _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 4, 5, false, false,
+                    RS_YUV_YV12)));
+
+    // yuv_format with mipmaps or cubemap is invalid
+    _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 4, 0, false, true,
+                    RS_YUV_YV12)));
+    _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 4, 0, true, false,
+                    RS_YUV_YV12)));
+
+    // mipmaps with 1D or 3D is invalid
+    _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 0, 0, true, false,
+                    RS_YUV_NONE)));
+    _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 4, 5, true, false,
+                    RS_YUV_NONE)));
+
+    // cubemap with 1D or 3D is invalid
+    _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 0, 0, false, true,
+                    RS_YUV_NONE)));
+    _RS_ASSERT(!rsIsObject(rsCreateType(I32_3, 3, 4, 5, false, true,
+                    RS_YUV_NONE)));
+
+    checkAndSendResult();
+}
+
+void TestAllocationCreationWithUsage() {
+    failed = false;
+
+    /////////////////////////////////////////////////////////////////
+    // Test rs_allocation creation
+    /////////////////////////////////////////////////////////////////
+    rs_element I32_3 = rsCreateVectorElement(RS_TYPE_SIGNED_32, 3);
+    rs_type I32_3_2D = rsCreateType(I32_3, 3, 4);
+
+    // Valid uses
+    _RS_ASSERT(rsIsObject(rsCreateAllocation(I32_3_2D)));
+    _RS_ASSERT(rsIsObject(rsCreateAllocation(I32_3_2D,\
+                    (uint32_t) RS_ALLOCATION_USAGE_SCRIPT)));
+    _RS_ASSERT(rsIsObject(rsCreateAllocation(I32_3_2D,\
+                    (uint32_t) RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE)));
+    _RS_ASSERT(rsIsObject(rsCreateAllocation(I32_3_2D,
+                    (uint32_t) RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE |
+                               RS_ALLOCATION_USAGE_SCRIPT)));
+
+    // Invalid uses
+    _RS_ASSERT(!rsIsObject(rsCreateAllocation(I32_3_2D,
+                    (uint32_t) RS_ALLOCATION_USAGE_GRAPHICS_VERTEX)));
+    _RS_ASSERT(!rsIsObject(rsCreateAllocation(I32_3_2D,
+                    (uint32_t) RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS)));
+    _RS_ASSERT(!rsIsObject(rsCreateAllocation(I32_3_2D,
+                    (uint32_t) RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET)));
+    _RS_ASSERT(!rsIsObject(rsCreateAllocation(I32_3_2D,
+                    (uint32_t) RS_ALLOCATION_USAGE_IO_INPUT)));
+    _RS_ASSERT(!rsIsObject(rsCreateAllocation(I32_3_2D,
+                    (uint32_t) RS_ALLOCATION_USAGE_IO_OUTPUT)));
+    _RS_ASSERT(!rsIsObject(rsCreateAllocation(I32_3_2D,
+                    (uint32_t) RS_ALLOCATION_USAGE_SHARED)));
+
+    checkAndSendResult();
+}
+
+void TestHelperFunctions() {
+    failed = false;
+
+    // Bug: 24862914: Add half once the bug is fixed
+    TEST_HELPERS(float);
+    TEST_HELPERS(double);
+    TEST_HELPERS(char);
+    TEST_HELPERS(short);
+    TEST_HELPERS(int);
+    TEST_HELPERS(long);
+    TEST_HELPERS(uchar);
+    TEST_HELPERS(ushort);
+    TEST_HELPERS(uint);
+    TEST_HELPERS(ulong);
+
+    checkAndSendResult();
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/single_source_script.rs b/tests/tests/renderscript/src/android/renderscript/cts/single_source_script.rs
new file mode 100644
index 0000000..5e35aa3
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/single_source_script.rs
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2015-2016 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.
+ */
+
+#include "shared.rsh"
+
+rs_allocation gAllocOut;
+
+int RS_KERNEL foo(int a) {
+    return a * 2;
+}
+
+int RS_KERNEL goo(int a, int b) {
+    return a + b;
+}
+
+void RS_KERNEL bar(int x, int y) {
+  int a = rsGetElementAt_int(gAllocOut, x, y);
+  a++;
+  rsSetElementAt_int(gAllocOut, a, x, y);
+}
+
+void testSingleInput(rs_allocation in, rs_allocation out) {
+    rsForEach(foo, in, out);
+}
+
+void testMultiInput(rs_allocation in1, rs_allocation in2, rs_allocation out) {
+    rsForEach(goo, in1, in2, out);
+}
+
+void testLaunchOptions(rs_allocation in, rs_allocation out, int dimX, int dimY) {
+    rs_script_call_t opts = {};
+    opts.xStart = 0;
+    opts.xEnd = dimX;
+    opts.yStart = 0;
+    opts.yEnd = dimY / 2;
+    rsForEachWithOptions(foo, &opts, in, out);
+}
+
+void testAllocationlessLaunch(rs_allocation inAndOut, int dimX, int dimY) {
+    gAllocOut = inAndOut;
+    rs_script_call_t opts = {};
+    opts.xStart = 0;
+    opts.xEnd = dimX;
+    opts.yStart = 0;
+    opts.yEnd = dimY;
+    rsForEachWithOptions(bar, &opts);
+}
diff --git a/tests/tests/transition/res/layout/scene6.xml b/tests/tests/transition/res/layout/scene6.xml
new file mode 100644
index 0000000..8cffee5
--- /dev/null
+++ b/tests/tests/transition/res/layout/scene6.xml
@@ -0,0 +1,38 @@
+<?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.
+-->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:transitionName="holder"
+                android:id="@+id/holder">
+    <View android:layout_width="30dp"
+          android:layout_height="30dp"
+          android:background="#0F0"
+          android:transitionName="green"
+          android:id="@+id/greenSquare" />
+    <View android:layout_width="30dp"
+          android:layout_height="30dp"
+          android:background="#F00"
+          android:transitionName="red"
+          android:id="@+id/redSquare"
+          android:layout_below="@+id/greenSquare" />
+    <TextView android:layout_width="wrap_content"
+              android:layout_height="wrap_content"
+              android:transitionName="hello"
+              android:text="@string/hello"
+              android:id="@+id/hello"/>
+</RelativeLayout>
diff --git a/tests/tests/transition/src/android/transition/cts/BaseTransitionTest.java b/tests/tests/transition/src/android/transition/cts/BaseTransitionTest.java
index 13badf3..9f41f21 100644
--- a/tests/tests/transition/src/android/transition/cts/BaseTransitionTest.java
+++ b/tests/tests/transition/src/android/transition/cts/BaseTransitionTest.java
@@ -19,6 +19,7 @@
 import android.animation.ObjectAnimator;
 import android.test.ActivityInstrumentationTestCase2;
 import android.transition.Scene;
+import android.transition.Transition;
 import android.transition.TransitionManager;
 import android.transition.TransitionValues;
 import android.transition.Visibility;
@@ -38,7 +39,8 @@
     protected FrameLayout mSceneRoot;
     public float mAnimatedValue;
     protected ArrayList<View> mTargets = new ArrayList<View>();
-    protected TestTransition mTransition;
+    protected Transition mTransition;
+    protected SimpleTransitionListener mListener;
 
     public BaseTransitionTest() {
         super(TransitionActivity.class);
@@ -52,18 +54,21 @@
         mSceneRoot = (FrameLayout) mActivity.findViewById(R.id.container);
         mTargets.clear();
         mTransition = new TestTransition();
+        mListener = new SimpleTransitionListener();
+        mTransition.addListener(mListener);
     }
 
     protected void waitForStart() throws InterruptedException {
-        waitForStart(mTransition.listener);
+        waitForStart(mListener);
     }
 
     protected void waitForStart(SimpleTransitionListener listener) throws InterruptedException {
-        assertTrue(listener.startLatch.await(100, TimeUnit.MILLISECONDS));
+        assertTrue(listener.startLatch.await(4000, TimeUnit.MILLISECONDS));
     }
 
     protected void waitForEnd(long waitMillis) throws InterruptedException {
-        waitForEnd(mTransition.listener, waitMillis);
+        waitForEnd(mListener, waitMillis);
+        getInstrumentation().waitForIdleSync();
     }
 
     protected static void waitForEnd(SimpleTransitionListener listener, long waitMillis)
@@ -121,10 +126,8 @@
     }
 
     public class TestTransition extends Visibility {
-        public final SimpleTransitionListener listener = new SimpleTransitionListener();
 
         public TestTransition() {
-            addListener(listener);
             setDuration(200);
         }
 
diff --git a/tests/tests/transition/src/android/transition/cts/ChangeBoundsTest.java b/tests/tests/transition/src/android/transition/cts/ChangeBoundsTest.java
new file mode 100644
index 0000000..a99f175
--- /dev/null
+++ b/tests/tests/transition/src/android/transition/cts/ChangeBoundsTest.java
@@ -0,0 +1,293 @@
+/*
+ * 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 android.transition.cts;
+
+import android.content.res.Resources;
+import android.graphics.Rect;
+import android.transition.ChangeBounds;
+import android.transition.cts.R;
+import android.util.TypedValue;
+import android.view.View;
+
+public class ChangeBoundsTest extends BaseTransitionTest {
+    private static final int SMALL_SQUARE_SIZE_DP = 10;
+    private static final int LARGE_SQUARE_SIZE_DP = 30;
+    private static final int SMALL_OFFSET_DP = 2;
+
+    ChangeBounds mChangeBounds;
+
+    public ChangeBoundsTest() {
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        resetChangeBoundsTransition();
+    }
+
+    private void resetChangeBoundsTransition() {
+        mListener = new SimpleTransitionListener();
+        mChangeBounds = new ChangeBounds();
+        mChangeBounds.setDuration(400);
+        mChangeBounds.addListener(mListener);
+        mTransition = mChangeBounds;
+    }
+
+    public void testBasicChangeBounds() throws Throwable {
+        enterScene(R.layout.scene1);
+
+        validateInScene1();
+
+        startTransition(R.layout.scene6);
+
+        // now delay for at least a few frames before checking intermediate values:
+        Thread.sleep(150);
+        validateNormalIntermediate();
+        waitForEnd(400);
+
+        validateInScene6();
+    }
+
+    public void testResizeClip() throws Throwable {
+        mChangeBounds.setResizeClip(true);
+        enterScene(R.layout.scene1);
+
+        validateInScene1();
+
+        startTransition(R.layout.scene6);
+
+        // now delay for at least a few frames before checking intermediate values:
+        Thread.sleep(150);
+        validateClippedIntermediate();
+        waitForEnd(400);
+
+        validateInScene6();
+    }
+
+    public void testResizeClipSmaller() throws Throwable {
+        mChangeBounds.setResizeClip(true);
+        enterScene(R.layout.scene6);
+
+        validateInScene6();
+
+        startTransition(R.layout.scene1);
+
+        // now delay for at least a few frames before checking intermediate values:
+        Thread.sleep(150);
+        validateClippedIntermediate();
+        waitForEnd(400);
+
+        validateInScene1();
+    }
+
+    public void testInterruptSameDestination() throws Throwable {
+        enterScene(R.layout.scene1);
+
+        validateInScene1();
+
+        startTransition(R.layout.scene6);
+
+        // now delay for at least a few frames before interrupting the transition
+        Thread.sleep(150);
+        resetChangeBoundsTransition();
+        startTransition(R.layout.scene6);
+
+        assertFalse(isRestartingAnimation());
+        waitForEnd(500);
+        validateInScene6();
+    }
+
+    public void testInterruptSameDestinationResizeClip() throws Throwable {
+        mChangeBounds.setResizeClip(true);
+        enterScene(R.layout.scene1);
+
+        validateInScene1();
+
+        startTransition(R.layout.scene6);
+
+        // now delay for at least a few frames before interrupting the transition
+        Thread.sleep(150);
+
+        resetChangeBoundsTransition();
+        mChangeBounds.setResizeClip(true);
+        startTransition(R.layout.scene6);
+
+        assertFalse(isRestartingAnimation());
+        assertFalse(isRestartingClip());
+        waitForEnd(500);
+        validateInScene6();
+    }
+
+    public void testInterruptWithReverse() throws Throwable {
+        enterScene(R.layout.scene1);
+
+        validateInScene1();
+
+        startTransition(R.layout.scene6);
+
+        // now delay for at least a few frames before reversing
+        Thread.sleep(150);
+        // reverse the transition back to scene1
+        resetChangeBoundsTransition();
+        startTransition(R.layout.scene1);
+
+        assertFalse(isRestartingAnimation());
+        waitForEnd(500);
+        validateInScene1();
+    }
+
+    public void testInterruptWithReverseResizeClip() throws Throwable {
+        mChangeBounds.setResizeClip(true);
+        enterScene(R.layout.scene1);
+
+        validateInScene1();
+
+        startTransition(R.layout.scene6);
+
+        // now delay for at least a few frames before reversing
+        Thread.sleep(150);
+
+        // reverse the transition back to scene1
+        resetChangeBoundsTransition();
+        mChangeBounds.setResizeClip(true);
+        startTransition(R.layout.scene1);
+
+        assertFalse(isRestartingAnimation());
+        assertFalse(isRestartingClip());
+        waitForEnd(500);
+        validateInScene1();
+    }
+
+    private boolean isRestartingAnimation() {
+        View red = mActivity.findViewById(R.id.redSquare);
+        View green = mActivity.findViewById(R.id.greenSquare);
+        Resources resources = mActivity.getResources();
+        float closestDistance = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+                SMALL_OFFSET_DP, resources.getDisplayMetrics());
+        return red.getTop() < closestDistance || green.getTop() < closestDistance;
+    }
+
+    private boolean isRestartingClip() {
+        Resources resources = mActivity.getResources();
+        float smallDim = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+                SMALL_SQUARE_SIZE_DP + SMALL_OFFSET_DP, resources.getDisplayMetrics());
+        float largeDim = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+                LARGE_SQUARE_SIZE_DP - SMALL_OFFSET_DP, resources.getDisplayMetrics());
+
+        View red = mActivity.findViewById(R.id.redSquare);
+        Rect redClip = red.getClipBounds();
+        View green = mActivity.findViewById(R.id.greenSquare);
+        Rect greenClip = green.getClipBounds();
+        return redClip == null || redClip.width() < smallDim || redClip.width() > largeDim ||
+                greenClip == null || greenClip.width() < smallDim || greenClip.width() > largeDim;
+    }
+
+    private void validateInScene1() {
+        validateViewPlacement(R.id.redSquare, R.id.greenSquare, SMALL_SQUARE_SIZE_DP);
+    }
+
+    private void validateInScene6() {
+        validateViewPlacement(R.id.greenSquare, R.id.redSquare, LARGE_SQUARE_SIZE_DP);
+    }
+
+    private void validateViewPlacement(int topViewResource, int bottomViewResource, int dim) {
+        Resources resources = mActivity.getResources();
+        float expectedDim = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dim,
+                resources.getDisplayMetrics());
+        View aboveSquare = mActivity.findViewById(topViewResource);
+        assertEquals(0, aboveSquare.getLeft());
+        assertEquals(0, aboveSquare.getTop());
+        assertTrue(aboveSquare.getRight() != 0);
+        final int aboveSquareBottom = aboveSquare.getBottom();
+        assertTrue(aboveSquareBottom != 0);
+
+        View belowSquare = mActivity.findViewById(bottomViewResource);
+        assertEquals(0, belowSquare.getLeft());
+        assertEquals(aboveSquareBottom, belowSquare.getTop());
+        assertEquals(aboveSquareBottom + aboveSquare.getHeight(), belowSquare.getBottom());
+        assertEquals(aboveSquare.getRight(), belowSquare.getRight());
+
+        assertTrue(isWithinAPixel(expectedDim, aboveSquare.getHeight()));
+        assertTrue(isWithinAPixel(expectedDim, aboveSquare.getWidth()));
+        assertTrue(isWithinAPixel(expectedDim, belowSquare.getHeight()));
+        assertTrue(isWithinAPixel(expectedDim, belowSquare.getWidth()));
+
+        assertNull(aboveSquare.getClipBounds());
+        assertNull(belowSquare.getClipBounds());
+    }
+
+    private void validateIntermediatePosition() {
+        Resources resources = mActivity.getResources();
+        float smallDim = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+                SMALL_SQUARE_SIZE_DP, resources.getDisplayMetrics());
+        float largeDim = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+                LARGE_SQUARE_SIZE_DP, resources.getDisplayMetrics());
+
+        View redSquare = mActivity.findViewById(R.id.redSquare);
+        View greenSquare = mActivity.findViewById(R.id.greenSquare);
+        assertTrue(redSquare.getTop() != 0);
+        assertTrue(greenSquare.getTop() != 0);
+        assertFalse(isWithinAPixel(smallDim, redSquare.getTop()));
+        assertFalse(isWithinAPixel(largeDim, redSquare.getTop()));
+        assertFalse(isWithinAPixel(smallDim, greenSquare.getTop()));
+        assertFalse(isWithinAPixel(largeDim, greenSquare.getTop()));
+    }
+
+    private void validateClippedIntermediate() {
+        validateIntermediatePosition();
+        Resources resources = mActivity.getResources();
+        float largeDim = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+                LARGE_SQUARE_SIZE_DP, resources.getDisplayMetrics());
+        View redSquare = mActivity.findViewById(R.id.redSquare);
+        View greenSquare = mActivity.findViewById(R.id.greenSquare);
+
+        assertTrue(isWithinAPixel(largeDim, redSquare.getWidth()));
+        assertTrue(isWithinAPixel(largeDim, redSquare.getHeight()));
+        assertTrue(isWithinAPixel(largeDim, greenSquare.getWidth()));
+        assertTrue(isWithinAPixel(largeDim, greenSquare.getHeight()));
+
+        assertNotNull(redSquare.getClipBounds());
+        assertNotNull(greenSquare.getClipBounds());
+    }
+
+    private void validateNormalIntermediate() {
+        validateIntermediatePosition();
+        Resources resources = mActivity.getResources();
+        float smallDim = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+                SMALL_SQUARE_SIZE_DP, resources.getDisplayMetrics());
+        float largeDim = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+                LARGE_SQUARE_SIZE_DP, resources.getDisplayMetrics());
+        View redSquare = mActivity.findViewById(R.id.redSquare);
+        View greenSquare = mActivity.findViewById(R.id.greenSquare);
+        assertFalse(isWithinAPixel(smallDim, redSquare.getWidth()));
+        assertFalse(isWithinAPixel(smallDim, redSquare.getHeight()));
+        assertFalse(isWithinAPixel(largeDim, redSquare.getWidth()));
+        assertFalse(isWithinAPixel(largeDim, redSquare.getHeight()));
+
+        assertFalse(isWithinAPixel(smallDim, greenSquare.getWidth()));
+        assertFalse(isWithinAPixel(smallDim, greenSquare.getHeight()));
+        assertFalse(isWithinAPixel(largeDim, greenSquare.getWidth()));
+        assertFalse(isWithinAPixel(largeDim, greenSquare.getHeight()));
+
+        assertNull(redSquare.getClipBounds());
+        assertNull(greenSquare.getClipBounds());
+    }
+
+    private static boolean isWithinAPixel(float expectedDim, int dim) {
+        return (Math.abs(dim - expectedDim) < 1);
+    }
+}
+
diff --git a/tests/tests/transition/src/android/transition/cts/TransitionManagerTest.java b/tests/tests/transition/src/android/transition/cts/TransitionManagerTest.java
index 8e545ec..9eacd1b 100644
--- a/tests/tests/transition/src/android/transition/cts/TransitionManagerTest.java
+++ b/tests/tests/transition/src/android/transition/cts/TransitionManagerTest.java
@@ -42,12 +42,12 @@
 
         waitForStart();
         waitForEnd(300);
-        assertEquals(1, mTransition.listener.resumeLatch.getCount());
-        assertEquals(1, mTransition.listener.pauseLatch.getCount());
-        assertEquals(1, mTransition.listener.cancelLatch.getCount());
-        assertNotNull(mTransition.listener.transition);
-        assertEquals(TestTransition.class, mTransition.listener.transition.getClass());
-        assertTrue(mTransition != mTransition.listener.transition);
+        assertEquals(1, mListener.resumeLatch.getCount());
+        assertEquals(1, mListener.pauseLatch.getCount());
+        assertEquals(1, mListener.cancelLatch.getCount());
+        assertNotNull(mListener.transition);
+        assertEquals(TestTransition.class, mListener.transition.getClass());
+        assertTrue(mTransition != mListener.transition);
         runTestOnUiThread(new Runnable() {
             @Override
             public void run() {
@@ -62,12 +62,12 @@
         waitForStart();
         waitForEnd(300);
 
-        assertEquals(1, mTransition.listener.resumeLatch.getCount());
-        assertEquals(1, mTransition.listener.pauseLatch.getCount());
-        assertEquals(1, mTransition.listener.cancelLatch.getCount());
-        assertNotNull(mTransition.listener.transition);
-        assertEquals(TestTransition.class, mTransition.listener.transition.getClass());
-        assertTrue(mTransition != mTransition.listener.transition);
+        assertEquals(1, mListener.resumeLatch.getCount());
+        assertEquals(1, mListener.pauseLatch.getCount());
+        assertEquals(1, mListener.cancelLatch.getCount());
+        assertNotNull(mListener.transition);
+        assertEquals(TestTransition.class, mListener.transition.getClass());
+        assertTrue(mTransition != mListener.transition);
         runTestOnUiThread(new Runnable() {
             @Override
             public void run() {
@@ -91,24 +91,24 @@
 
         waitForStart();
         waitForEnd(300);
-        assertEquals(1, mTransition.listener.resumeLatch.getCount());
-        assertEquals(1, mTransition.listener.pauseLatch.getCount());
-        assertEquals(1, mTransition.listener.cancelLatch.getCount());
-        assertNotNull(mTransition.listener.transition);
-        assertEquals(TestTransition.class, mTransition.listener.transition.getClass());
-        assertTrue(mTransition != mTransition.listener.transition);
+        assertEquals(1, mListener.resumeLatch.getCount());
+        assertEquals(1, mListener.pauseLatch.getCount());
+        assertEquals(1, mListener.cancelLatch.getCount());
+        assertNotNull(mListener.transition);
+        assertEquals(TestTransition.class, mListener.transition.getClass());
+        assertTrue(mTransition != mListener.transition);
         runTestOnUiThread(new Runnable() {
             @Override
             public void run() {
-                mTransition.listener.startLatch = new CountDownLatch(1);
-                mTransition.listener.endLatch = new CountDownLatch(1);
+                mListener.startLatch = new CountDownLatch(1);
+                mListener.endLatch = new CountDownLatch(1);
                 assertNotNull(mActivity.findViewById(R.id.redSquare));
                 assertNotNull(mActivity.findViewById(R.id.greenSquare));
                 Scene scene = Scene.getSceneForLayout(mSceneRoot, R.layout.scene2, mActivity);
                 transitionManager.transitionTo(scene);
             }
         });
-        assertFalse(mTransition.listener.startLatch.await(50, TimeUnit.MILLISECONDS));
+        assertFalse(mListener.startLatch.await(50, TimeUnit.MILLISECONDS));
         endTransition();
     }
 
@@ -126,7 +126,7 @@
                 transitionManager.transitionTo(scenes[0]);
             }
         });
-        assertFalse(mTransition.listener.startLatch.await(100, TimeUnit.MILLISECONDS));
+        assertFalse(mListener.startLatch.await(100, TimeUnit.MILLISECONDS));
 
         runTestOnUiThread(new Runnable() {
             @Override
@@ -137,21 +137,21 @@
 
         waitForStart();
         waitForEnd(300);
-        assertEquals(1, mTransition.listener.resumeLatch.getCount());
-        assertEquals(1, mTransition.listener.pauseLatch.getCount());
-        assertEquals(1, mTransition.listener.cancelLatch.getCount());
-        assertNotNull(mTransition.listener.transition);
-        assertEquals(TestTransition.class, mTransition.listener.transition.getClass());
-        assertTrue(mTransition != mTransition.listener.transition);
+        assertEquals(1, mListener.resumeLatch.getCount());
+        assertEquals(1, mListener.pauseLatch.getCount());
+        assertEquals(1, mListener.cancelLatch.getCount());
+        assertNotNull(mListener.transition);
+        assertEquals(TestTransition.class, mListener.transition.getClass());
+        assertTrue(mTransition != mListener.transition);
         runTestOnUiThread(new Runnable() {
             @Override
             public void run() {
-                mTransition.listener.startLatch = new CountDownLatch(1);
-                mTransition.listener.endLatch = new CountDownLatch(1);
+                mListener.startLatch = new CountDownLatch(1);
+                mListener.endLatch = new CountDownLatch(1);
                 transitionManager.transitionTo(scenes[2]);
             }
         });
-        assertFalse(mTransition.listener.startLatch.await(50, TimeUnit.MILLISECONDS));
+        assertFalse(mListener.startLatch.await(50, TimeUnit.MILLISECONDS));
         endTransition();
     }
 
@@ -175,8 +175,8 @@
                 TransitionManager.endTransitions(mSceneRoot);
             }
         });
-        assertFalse(mTransition.listener.startLatch.await(100, TimeUnit.MILLISECONDS));
-        assertFalse(mTransition.listener.endLatch.await(10, TimeUnit.MILLISECONDS));
+        assertFalse(mListener.startLatch.await(100, TimeUnit.MILLISECONDS));
+        assertFalse(mListener.endLatch.await(10, TimeUnit.MILLISECONDS));
     }
 }
 
diff --git a/tests/tests/transition/src/android/transition/cts/TransitionTest.java b/tests/tests/transition/src/android/transition/cts/TransitionTest.java
index 71c85c5..e87be84 100644
--- a/tests/tests/transition/src/android/transition/cts/TransitionTest.java
+++ b/tests/tests/transition/src/android/transition/cts/TransitionTest.java
@@ -54,11 +54,11 @@
 
         waitForStart(listener2);
 
-        assertEquals(0, mTransition.listener.pauseLatch.getCount());
-        assertEquals(0, mTransition.listener.resumeLatch.getCount());
-        assertEquals(1, mTransition.listener.cancelLatch.getCount());
-        assertEquals(1, mTransition.listener.endLatch.getCount());
-        assertEquals(0, mTransition.listener.startLatch.getCount());
+        assertEquals(0, mListener.pauseLatch.getCount());
+        assertEquals(0, mListener.resumeLatch.getCount());
+        assertEquals(1, mListener.cancelLatch.getCount());
+        assertEquals(1, mListener.endLatch.getCount());
+        assertEquals(0, mListener.startLatch.getCount());
 
         assertEquals(1, listener2.pauseLatch.getCount());
         assertEquals(1, listener2.resumeLatch.getCount());
@@ -75,11 +75,11 @@
         runTestOnUiThread(new Runnable() {
             @Override
             public void run() {
-                mTransition.removeListener(mTransition.listener);
+                mTransition.removeListener(mListener);
             }
         });
 
-        assertFalse(mTransition.listener.endLatch.await(250, TimeUnit.MILLISECONDS));
+        assertFalse(mListener.endLatch.await(250, TimeUnit.MILLISECONDS));
     }
 
     public void testAddTargetId() throws Throwable {
diff --git a/tests/tests/view/Android.mk b/tests/tests/view/Android.mk
index 24a351f..e57e10e 100644
--- a/tests/tests/view/Android.mk
+++ b/tests/tests/view/Android.mk
@@ -26,7 +26,7 @@
 
 LOCAL_JAVA_LIBRARIES := android.test.runner
 
-LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner
+LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner mockito-target
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
diff --git a/tests/tests/view/res/layout/focus_finder_layout.xml b/tests/tests/view/res/layout/focus_finder_layout.xml
index 0502fd8..610ffc8 100644
--- a/tests/tests/view/res/layout/focus_finder_layout.xml
+++ b/tests/tests/view/res/layout/focus_finder_layout.xml
@@ -22,21 +22,21 @@
             android:layout_centerInParent="true">
         <TableRow>
             <android.view.cts.TestButton android:id="@+id/top_left_button"
-                    android:layout_width="match_parent"
+                    android:layout_width="60dp"
                     android:layout_height="match_parent"
                     android:text="TL" />
             <android.view.cts.TestButton android:id="@+id/top_right_button"
-                    android:layout_width="match_parent"
+                    android:layout_width="60dp"
                     android:layout_height="match_parent"
                     android:text="TR" />
         </TableRow>
         <TableRow>
             <android.view.cts.TestButton android:id="@+id/bottom_left_button"
-                    android:layout_width="match_parent"
+                    android:layout_width="60dp"
                     android:layout_height="match_parent"
                     android:text="BL" />
             <android.view.cts.TestButton android:id="@+id/bottom_right_button"
-                    android:layout_width="match_parent"
+                    android:layout_width="60dp"
                     android:layout_height="match_parent"
                     android:text="BR" />
         </TableRow>  
diff --git a/tests/tests/view/src/android/view/cts/ViewGroupTest.java b/tests/tests/view/src/android/view/cts/ViewGroupTest.java
index f688d1f..10e743a 100644
--- a/tests/tests/view/src/android/view/cts/ViewGroupTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewGroupTest.java
@@ -16,20 +16,18 @@
 
 package android.view.cts;
 
-import android.view.cts.util.XmlUtils;
-
-
 import android.content.Context;
 import android.content.Intent;
-import android.cts.util.CTSResult;
 import android.content.res.XmlResourceParser;
+import android.cts.util.CTSResult;
 import android.graphics.Bitmap;
+import android.graphics.Bitmap.Config;
 import android.graphics.Canvas;
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.Region;
-import android.graphics.Bitmap.Config;
 import android.graphics.drawable.BitmapDrawable;
+import android.os.Build;
 import android.os.Parcelable;
 import android.os.SystemClock;
 import android.test.InstrumentationTestCase;
@@ -44,22 +42,22 @@
 import android.view.MenuItem;
 import android.view.MotionEvent;
 import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
 import android.view.View.BaseSavedState;
 import android.view.View.MeasureSpec;
 import android.view.View.OnTouchListener;
+import android.view.ViewGroup;
 import android.view.ViewGroup.LayoutParams;
 import android.view.ViewGroup.OnHierarchyChangeListener;
+import android.view.WindowManager;
 import android.view.animation.AlphaAnimation;
 import android.view.animation.Animation;
+import android.view.animation.Animation.AnimationListener;
 import android.view.animation.LayoutAnimationController;
 import android.view.animation.RotateAnimation;
 import android.view.animation.Transformation;
-import android.view.animation.Animation.AnimationListener;
+import android.view.cts.util.XmlUtils;
 import android.widget.TextView;
 
-import java.lang.IndexOutOfBoundsException;
 import java.util.ArrayList;
 
 public class ViewGroupTest extends InstrumentationTestCase implements CTSResult{
@@ -536,6 +534,7 @@
         MockTextView textView = new MockTextView(mContext);
         mMotionEvent = null;
         textView.setOnTouchListener(new OnTouchListener() {
+            @Override
             public boolean onTouch(View v, MotionEvent event) {
                 mMotionEvent = event;
                 return true;
@@ -812,12 +811,15 @@
 
         AnimationListener al = new AnimationListener() {
 
+            @Override
             public void onAnimationEnd(Animation animation) {
             }
 
+            @Override
             public void onAnimationRepeat(Animation animation) {
             }
 
+            @Override
             public void onAnimationStart(Animation animation) {
             }
         };
@@ -1009,6 +1011,18 @@
         assertEquals(2, rect.top);
         assertEquals(1, rect.left);
         assertEquals(1, rect.right);
+
+        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M || Build.VERSION.CODENAME.equals("N")) {
+            textView.setTranslationX(2);
+            textView.setTranslationY(1);
+
+            rect.setEmpty();
+            vg.offsetDescendantRectToMyCoords(textView, rect);
+            assertEquals(3, rect.bottom);
+            assertEquals(3, rect.top);
+            assertEquals(3, rect.left);
+            assertEquals(3, rect.right);
+        }
     }
 
     public void testOffsetRectIntoDescendantCoords() {
@@ -1032,6 +1046,18 @@
         assertEquals(4, rect.top);
         assertEquals(4, rect.left);
         assertEquals(6, rect.right);
+
+        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M || Build.VERSION.CODENAME.equals("N")) {
+            textView.setTranslationX(2);
+            textView.setTranslationY(1);
+
+            rect.set(5, 6, 7, 8);
+            vg.offsetRectIntoDescendantCoords(textView, rect);
+            assertEquals(5, rect.bottom);
+            assertEquals(3, rect.top);
+            assertEquals(2, rect.left);
+            assertEquals(4, rect.right);
+        }
     }
 
     public void testOnAnimationEnd() {
@@ -1172,9 +1198,11 @@
         public View sParent;
         public View sChild;
 
+        @Override
         public void onChildViewAdded(View parent, View child) {
         }
 
+        @Override
         public void onChildViewRemoved(View parent, View child) {
             sParent = parent;
             sChild = child;
@@ -2021,7 +2049,6 @@
         public int debugDepth;
         public int drawChildCalledTime;
         public Canvas canvas;
-        public boolean isInvalidateChildInParentCalled;
         public boolean isDrawableStateChangedCalled;
         public boolean isRequestLayoutCalled;
         public boolean isOnLayoutCalled;
@@ -2420,6 +2447,7 @@
         }
     }
 
+    @Override
     public void setResult(int resultCode) {
         synchronized (mSync) {
             mSync.mHasNotify = true;
diff --git a/tests/tests/view/src/android/view/cts/ViewTest.java b/tests/tests/view/src/android/view/cts/ViewTest.java
index 0191072..18868e4 100644
--- a/tests/tests/view/src/android/view/cts/ViewTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewTest.java
@@ -16,8 +16,8 @@
 
 package android.view.cts;
 
-import android.view.ViewTreeObserver;
-import android.view.cts.R;
+import static org.mockito.Mockito.*;
+
 import com.android.internal.view.menu.ContextMenuBuilder;
 
 import android.content.Context;
@@ -74,10 +74,12 @@
 import android.view.ViewConfiguration;
 import android.view.ViewGroup;
 import android.view.ViewParent;
+import android.view.ViewTreeObserver;
 import android.view.WindowManager;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.animation.AlphaAnimation;
 import android.view.animation.Animation;
+import android.view.cts.R;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputConnection;
 import android.view.inputmethod.InputMethodManager;
@@ -160,6 +162,7 @@
         final CountDownLatch latch = new CountDownLatch(1);
         sCtorException = null;
         new Thread() {
+            @Override
             public void run() {
                 final Class<?>[] ctorSignature = new Class[] {
                         Context.class, AttributeSet.class};
@@ -258,6 +261,7 @@
 
         // check whether it has started
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.startAnimation(animation);
             }
@@ -326,6 +330,7 @@
         final int WRAP_CONTENT = ViewGroup.LayoutParams.WRAP_CONTENT;
         final int btnHeight = view.getHeight()/3;
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 mActivity.addContentView(button,
                         new LinearLayout.LayoutParams(WRAP_CONTENT, btnHeight));
@@ -407,6 +412,7 @@
         assertEquals(-1, mockView.getOldWOnSizeChanged());
         assertEquals(-1, mockView.getOldHOnSizeChanged());
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 viewGroup.addView(mockView);
             }
@@ -425,6 +431,7 @@
         int oldh = view.getHeight();
         final LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(200, 100);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setLayoutParams(layoutParams);
             }
@@ -499,6 +506,7 @@
         view.reset();
         assertFalse(view.hasCalledOnLayout());
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.requestLayout();
             }
@@ -647,6 +655,7 @@
         // width is 0
         final LinearLayout.LayoutParams layoutParams1 = new LinearLayout.LayoutParams(0, 300);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setLayoutParams(layoutParams1);
             }
@@ -657,6 +666,7 @@
         // height is -10
         final LinearLayout.LayoutParams layoutParams2 = new LinearLayout.LayoutParams(200, -10);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setLayoutParams(layoutParams2);
             }
@@ -671,6 +681,7 @@
         final LinearLayout.LayoutParams layoutParams3 =
                 new LinearLayout.LayoutParams(halfWidth, halfHeight);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setLayoutParams(layoutParams3);
             }
@@ -701,6 +712,7 @@
         // width is 0
         final LinearLayout.LayoutParams layoutParams1 = new LinearLayout.LayoutParams(0, 300);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setLayoutParams(layoutParams1);
             }
@@ -711,6 +723,7 @@
         // height is -10
         final LinearLayout.LayoutParams layoutParams2 = new LinearLayout.LayoutParams(200, -10);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setLayoutParams(layoutParams2);
             }
@@ -725,6 +738,7 @@
         final LinearLayout.LayoutParams layoutParams3 =
                 new LinearLayout.LayoutParams(halfWidth, halfHeight);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setLayoutParams(layoutParams3);
             }
@@ -745,6 +759,7 @@
         assertEquals(view.getWidth(), view.computeHorizontalScrollExtent());
 
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.scrollTo(12, 0);
             }
@@ -755,6 +770,7 @@
         assertEquals(view.getWidth(), view.computeHorizontalScrollExtent());
 
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.scrollBy(12, 0);
             }
@@ -767,6 +783,7 @@
         int newWidth = 200;
         final LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(newWidth, 100);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setLayoutParams(layoutParams);
             }
@@ -787,6 +804,7 @@
 
         final int scrollToY = 34;
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.scrollTo(0, scrollToY);
             }
@@ -798,6 +816,7 @@
 
         final int scrollByY = 200;
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.scrollBy(0, scrollByY);
             }
@@ -810,6 +829,7 @@
         int newHeight = 333;
         final LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(200, newHeight);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setLayoutParams(layoutParams);
             }
@@ -830,6 +850,7 @@
         assertEquals(0f, view.getBottomFadingEdgeStrength());
 
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.scrollTo(10, 10);
             }
@@ -841,6 +862,7 @@
         assertEquals(0f, view.getBottomFadingEdgeStrength());
 
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.scrollTo(-10, -10);
             }
@@ -997,7 +1019,7 @@
 
     public void testAddFocusables() {
         View view = new View(mActivity);
-        ArrayList<View> viewList = new ArrayList<View>();
+        ArrayList<View> viewList = new ArrayList<>();
 
         // view is not focusable
         assertFalse(view.isFocusable());
@@ -1307,6 +1329,24 @@
         assertTrue(mMockParent.hasShowContextMenuForChild());
     }
 
+    public void testShowContextMenuXY() {
+        MockViewParent parent = new MockViewParent(mActivity);
+        MockView view = new MockView(mActivity);
+
+        assertNull(view.getParent());
+        try {
+            view.showContextMenu(0, 0);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+        }
+
+        view.setParent(parent);
+        assertFalse(parent.hasShowContextMenuForChildXY());
+
+        assertFalse(view.showContextMenu(0, 0));
+        assertTrue(parent.hasShowContextMenuForChildXY());
+    }
+
     public void testFitSystemWindows() {
         final XmlResourceParser parser = mResources.getLayout(R.layout.view_layout);
         final AttributeSet attrs = Xml.asAttributeSet(parser);
@@ -1375,6 +1415,41 @@
         assertTrue(listener.hasOnLongClick());
     }
 
+    public void testPerformLongClickXY() {
+        MockViewParent parent = new MockViewParent(mActivity);
+        MockView view = new MockView(mActivity);
+
+        try {
+            view.performLongClick(0, 0);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+        }
+
+        parent.addView(view);
+        assertFalse(parent.hasShowContextMenuForChildXY());
+
+        // Verify default context menu behavior.
+        assertFalse(view.performLongClick(0, 0));
+        assertTrue(parent.hasShowContextMenuForChildXY());
+    }
+
+    public void testPerformLongClickXY_WithListener() {
+        OnLongClickListener listener = mock(OnLongClickListener.class);
+        MockViewParent parent = new MockViewParent(mActivity);
+        MockView view = new MockView(mActivity);
+
+        view.setOnLongClickListener(listener);
+        verify(listener, never()).onLongClick(any(View.class));
+
+        parent.addView(view);
+        assertFalse(parent.hasShowContextMenuForChildXY());
+
+        // Verify listener is preferred over default context menu.
+        assertTrue(view.performLongClick(0, 0));
+        assertFalse(parent.hasShowContextMenuForChildXY());
+        verify(listener).onLongClick(view);
+    }
+
     public void testSetOnLongClickListener() {
         MockView view = new MockView(mActivity);
         view.setParent(mMockParent);
@@ -1503,6 +1578,7 @@
 
         view.reset();
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.requestLayout();
             }
@@ -1515,6 +1591,7 @@
         view.reset();
         final LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(200, 100);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setLayoutParams(layoutParams);
             }
@@ -1572,6 +1649,7 @@
         View view = new View(mActivity);
         Drawable drawable = new StateListDrawable();
         Runnable what = new Runnable() {
+            @Override
             public void run() {
                 // do nothing
             }
@@ -1599,6 +1677,7 @@
         View view = new View(mActivity);
         Drawable drawable = new StateListDrawable();
         Runnable what = new Runnable() {
+            @Override
             public void run() {
                 // do nothing
             }
@@ -1759,7 +1838,6 @@
     }
 
     public void testGetLocationOnScreen() {
-        View view = new View(mActivity);
         int[] location = new int[] { -1, -1 };
 
         // mAttachInfo is not null
@@ -1792,7 +1870,7 @@
 
     public void testAddTouchables() {
         View view = new View(mActivity);
-        ArrayList<View> result = new ArrayList<View>();
+        ArrayList<View> result = new ArrayList<>();
         assertEquals(0, result.size());
 
         view.addTouchables(result);
@@ -1938,6 +2016,7 @@
     public void testOnKeyShortcut() throws Throwable {
         final MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setFocusable(true);
                 view.requestFocus();
@@ -1956,6 +2035,7 @@
     public void testOnKeyMultiple() throws Throwable {
         final MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setFocusable(true);
             }
@@ -1985,6 +2065,7 @@
     public void testOnTrackballEvent() throws Throwable {
         final MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setEnabled(true);
                 view.setFocusable(true);
@@ -2036,6 +2117,7 @@
     public void testDispatchUnhandledMove() throws Throwable {
         final MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setFocusable(true);
                 view.requestFocus();
@@ -2054,6 +2136,7 @@
         final ViewGroup viewGroup = (ViewGroup) mActivity.findViewById(R.id.viewlayout_root);
 
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 viewGroup.addView(mockView);
             }
@@ -2063,6 +2146,7 @@
 
         mockView.reset();
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 getActivity().setVisible(false);
             }
@@ -2073,6 +2157,7 @@
 
         mockView.reset();
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 getActivity().setVisible(true);
             }
@@ -2083,6 +2168,7 @@
 
         mockView.reset();
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 viewGroup.removeView(mockView);
             }
@@ -2103,6 +2189,7 @@
 
         final LinearLayout.LayoutParams layoutParams1 = new LinearLayout.LayoutParams(0, 300);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setLayoutParams(layoutParams1);
             }
@@ -2112,6 +2199,7 @@
 
         final LinearLayout.LayoutParams layoutParams2 = new LinearLayout.LayoutParams(200, -10);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setLayoutParams(layoutParams2);
             }
@@ -2126,6 +2214,7 @@
         final LinearLayout.LayoutParams layoutParams3 =
                 new LinearLayout.LayoutParams(halfWidth, halfHeight);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setLayoutParams(layoutParams3);
                 view.scrollTo(20, -30);
@@ -2184,7 +2273,7 @@
     public void testSaveAndRestoreHierarchyState() {
         int viewId = R.id.mock_view;
         MockView view = (MockView) mActivity.findViewById(viewId);
-        SparseArray<Parcelable> container = new SparseArray<Parcelable>();
+        SparseArray<Parcelable> container = new SparseArray<>();
         view.saveHierarchyState(container);
         assertTrue(view.hasCalledDispatchSaveInstanceState());
         assertTrue(view.hasCalledOnSaveInstanceState());
@@ -2228,6 +2317,7 @@
     public void testOnKeyDownOrUp() throws Throwable {
         final MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setFocusable(true);
                 view.requestFocus();
@@ -2254,6 +2344,7 @@
         assertTrue(view.hasCalledOnKeyDown());
 
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setEnabled(true);
                 view.setClickable(true);
@@ -2328,6 +2419,7 @@
         // Remove the child view from the parent, test that parent is 0xparentHeight
         final CountDownLatch countDownLatch1 = new CountDownLatch(1);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 viewGroup.removeAllViews();
                 viewGroup.addView(parent);
@@ -2338,6 +2430,7 @@
 
         final CountDownLatch countDownLatch2 = new CountDownLatch(1);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 parent.addView(child);
                 checkBounds(viewGroup, parent, countDownLatch2, 0, 0, childWidth, parentHeight);
@@ -2347,6 +2440,7 @@
 
         final CountDownLatch countDownLatch3 = new CountDownLatch(1);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 parent.removeView(child);
                 checkBounds(viewGroup, parent, countDownLatch3, 0, 0, 0, parentHeight);
@@ -2463,6 +2557,7 @@
 
         view.reset();
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.invalidate();
             }
@@ -2477,6 +2572,7 @@
 
         view.reset();
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setVisibility(View.INVISIBLE);
                 view.invalidate();
@@ -2500,6 +2596,7 @@
         final Rect dirty = new Rect(view.getLeft() + 1, view.getTop() + 1,
                 view.getLeft() + view.getWidth() / 2, view.getTop() + view.getHeight() / 2);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.invalidate(dirty);
             }
@@ -2514,6 +2611,7 @@
 
         view.reset();
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setVisibility(View.INVISIBLE);
                 view.invalidate(dirty);
@@ -2531,6 +2629,7 @@
         final Rect dirty = new Rect(view.getLeft() + 1, view.getTop() + 1,
                 view.getLeft() + view.getWidth() / 2, view.getTop() + view.getHeight() / 2);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.invalidate(dirty.left, dirty.top, dirty.right, dirty.bottom);
             }
@@ -2545,6 +2644,7 @@
 
         view.reset();
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setVisibility(View.INVISIBLE);
                 view.invalidate(dirty.left, dirty.top, dirty.right, dirty.bottom);
@@ -2561,6 +2661,7 @@
 
         view.reset();
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setBackgroundDrawable(d1);
                 view.invalidateDrawable(d1);
@@ -2576,6 +2677,7 @@
 
         view.reset();
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.invalidateDrawable(d2);
             }
@@ -2650,6 +2752,7 @@
         }.run();
 
         new PollingCheck() {
+            @Override
             protected boolean check() {
                 return view.hasCalledOnWindowFocusChanged();
             }
@@ -2681,6 +2784,7 @@
     public void testDraw() throws Throwable {
         final MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.requestLayout();
             }
@@ -2807,6 +2911,7 @@
         assertTrue(view.hasCalledOnTouchEvent());
 
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setEnabled(true);
                 view.setClickable(true);
@@ -3096,6 +3201,7 @@
                 Context.INPUT_METHOD_SERVICE);
         final LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(300, 500);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 mockView.setBackgroundDrawable(d);
                 mockView.setHorizontalFadingEdgeEnabled(true);
@@ -3115,6 +3221,7 @@
         // FIXME: why the size of view doesn't change?
 
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 imm.hideSoftInputFromInputMethod(mockView.getWindowToken(), 0);
             }
@@ -3126,6 +3233,7 @@
         final MockView mockView = (MockView) mActivity.findViewById(R.id.mock_view);
         final View fitWindowsView = mActivity.findViewById(R.id.fit_windows);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 mockView.setFocusableInTouchMode(true);
                 fitWindowsView.setFocusable(true);
@@ -3146,6 +3254,7 @@
         assertFalse(fitWindowsView.isFocused());
         assertFalse(mockView.isFocused());
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 mockView.requestFocus();
             }
@@ -3153,6 +3262,7 @@
         getInstrumentation().waitForIdleSync();
         assertTrue(mockView.isFocused());
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 fitWindowsView.requestFocus();
             }
@@ -3167,6 +3277,7 @@
         assertTrue(mockView.isFocused());
         assertFalse(fitWindowsView.isFocused());
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 fitWindowsView.requestFocus();
             }
@@ -3320,9 +3431,10 @@
         items.add("1");
         items.add("2");
         items.add("3");
-        final Adapter<String> adapter = new Adapter<String>(mActivity, 0, items);
+        final Adapter<String> adapter = new Adapter<>(mActivity, 0, items);
 
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 mActivity.setContentView(listView);
                 listView.setAdapter(adapter);
@@ -3332,6 +3444,7 @@
         final MockView focusChild = (MockView) listView.getChildAt(0);
 
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 focusChild.requestFocus();
             }
@@ -3340,6 +3453,7 @@
         assertTrue(listView.getChildAt(0).isFocused());
 
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 listView.detachViewFromParent(focusChild);
             }
@@ -3389,7 +3503,7 @@
     }
 
     private static class Adapter<T> extends ArrayAdapter<T> {
-        ArrayList<MockView> views = new ArrayList<MockView>();
+        ArrayList<MockView> views = new ArrayList<>();
 
         public Adapter(Context context, int textViewResourceId, List<T> objects) {
             super(context, textViewResourceId, objects);
@@ -3419,6 +3533,7 @@
         final MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
 
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 view.setFocusable(true);
                 view.requestFocus();
@@ -3642,6 +3757,7 @@
 
         final MockView view2 = new MockView(mActivity);
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 viewGroup.addView(view2);
             }
@@ -3668,6 +3784,7 @@
         assertTrue(view2.hasCalledOnHoverEvent());
 
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 viewGroup.removeView(view2);
             }
@@ -3677,6 +3794,7 @@
         assertFalse(view2.hasPointerCapture());
 
         runTestOnUiThread(new Runnable() {
+            @Override
             public void run() {
                 viewGroup.addView(view2);
             }
@@ -3873,19 +3991,16 @@
     }
 
     private final static class MockViewParent extends ViewGroup {
-        private boolean mHasClearChildFocus = false;
         private boolean mHasRequestLayout = false;
         private boolean mHasCreateContextMenu = false;
         private boolean mHasShowContextMenuForChild = false;
-        private boolean mHasGetChildVisibleRect = false;
-        private boolean mHasInvalidateChild = false;
-        private boolean mHasOnCreateDrawableState = false;
+        private boolean mHasShowContextMenuForChildXY = false;
         private boolean mHasChildDrawableStateChanged = false;
         private boolean mHasBroughtChildToFront = false;
-        private Rect mTempRect;
 
         private final static int[] DEFAULT_PARENT_STATE_SET = new int[] { 789 };
 
+        @Override
         public boolean requestChildRectangleOnScreen(View child, Rect rectangle,
                 boolean immediate) {
             return false;
@@ -3895,6 +4010,7 @@
             super(context);
         }
 
+        @Override
         public void bringChildToFront(View child) {
             mHasBroughtChildToFront = true;
         }
@@ -3903,6 +4019,7 @@
             return mHasBroughtChildToFront;
         }
 
+        @Override
         public void childDrawableStateChanged(View child) {
             mHasChildDrawableStateChanged = true;
         }
@@ -3921,14 +4038,12 @@
             super.dispatchSetSelected(selected);
         }
 
+        @Override
         public void clearChildFocus(View child) {
-            mHasClearChildFocus = true;
+
         }
 
-        public boolean hasClearChildFocus() {
-            return mHasClearChildFocus;
-        }
-
+        @Override
         public void createContextMenu(ContextMenu menu) {
             mHasCreateContextMenu = true;
         }
@@ -3937,16 +4052,18 @@
             return mHasCreateContextMenu;
         }
 
+        @Override
         public View focusSearch(View v, int direction) {
             return v;
         }
 
+        @Override
         public void focusableViewAvailable(View v) {
 
         }
 
+        @Override
         public boolean getChildVisibleRect(View child, Rect r, Point offset) {
-            mHasGetChildVisibleRect = true;
             return false;
         }
 
@@ -3955,26 +4072,27 @@
 
         }
 
-        public boolean hasGetChildVisibleRect() {
-            return mHasGetChildVisibleRect;
-        }
-
+        @Override
         public ViewParent invalidateChildInParent(int[] location, Rect r) {
             return null;
         }
 
+        @Override
         public boolean isLayoutRequested() {
             return false;
         }
 
+        @Override
         public void recomputeViewAttributes(View child) {
 
         }
 
+        @Override
         public void requestChildFocus(View child, View focused) {
 
         }
 
+        @Override
         public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
 
         }
@@ -3988,20 +4106,30 @@
             return mHasRequestLayout;
         }
 
+        @Override
         public void requestTransparentRegion(View child) {
 
         }
 
+        @Override
         public boolean showContextMenuForChild(View originalView) {
             mHasShowContextMenuForChild = true;
             return false;
         }
 
+        @Override
+        public boolean showContextMenuForChild(View originalView, float x, float y) {
+            mHasShowContextMenuForChildXY = true;
+            return false;
+        }
+
+        @Override
         public ActionMode startActionModeForChild(View originalView,
                 ActionMode.Callback callback) {
             return null;
         }
 
+        @Override
         public ActionMode startActionModeForChild(View originalView,
                 ActionMode.Callback callback, int type) {
             return null;
@@ -4011,40 +4139,29 @@
             return mHasShowContextMenuForChild;
         }
 
+        public boolean hasShowContextMenuForChildXY() {
+            return mHasShowContextMenuForChildXY;
+        }
+
         @Override
         protected int[] onCreateDrawableState(int extraSpace) {
-            mHasOnCreateDrawableState = true;
             return DEFAULT_PARENT_STATE_SET;
         }
 
+        @Override
         public boolean requestSendAccessibilityEvent(View child, AccessibilityEvent event) {
             return false;
         }
 
-        public static int[] getDefaultParentStateSet() {
-            return DEFAULT_PARENT_STATE_SET;
-        }
-
-        public boolean hasOnCreateDrawableState() {
-            return mHasOnCreateDrawableState;
-        }
-
         public void reset() {
-            mHasClearChildFocus = false;
             mHasRequestLayout = false;
             mHasCreateContextMenu = false;
             mHasShowContextMenuForChild = false;
-            mHasGetChildVisibleRect = false;
-            mHasInvalidateChild = false;
-            mHasOnCreateDrawableState = false;
+            mHasShowContextMenuForChildXY = false;
             mHasChildDrawableStateChanged = false;
             mHasBroughtChildToFront = false;
         }
 
-        public void childOverlayStateChanged(View child) {
-
-        }
-
         @Override
         public void childHasTransientStateChanged(View child, boolean hasTransientState) {
 
@@ -4103,6 +4220,7 @@
     private final class OnCreateContextMenuListenerImpl implements OnCreateContextMenuListener {
         private boolean mHasOnCreateContextMenu = false;
 
+        @Override
         public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
             mHasOnCreateContextMenu = true;
         }
@@ -4152,6 +4270,7 @@
     private static final class OnClickListenerImpl implements OnClickListener {
         private boolean mHasOnClick = false;
 
+        @Override
         public void onClick(View v) {
             mHasOnClick = true;
         }
@@ -4176,6 +4295,7 @@
             mHasOnLongClick = false;
         }
 
+        @Override
         public boolean onLongClick(View v) {
             mHasOnLongClick = true;
             return true;
@@ -4195,6 +4315,7 @@
             mLastViewContextClicked = null;
         }
 
+        @Override
         public boolean onContextClick(View v) {
             mHasContextClick = true;
             mLastViewContextClicked = v;
@@ -4209,6 +4330,7 @@
     private static final class OnFocusChangeListenerImpl implements OnFocusChangeListener {
         private boolean mHasOnFocusChange = false;
 
+        @Override
         public void onFocusChange(View v, boolean hasFocus) {
             mHasOnFocusChange = true;
         }
@@ -4225,6 +4347,7 @@
     private static final class OnKeyListenerImpl implements OnKeyListener {
         private boolean mHasOnKey = false;
 
+        @Override
         public boolean onKey(View v, int keyCode, KeyEvent event) {
             mHasOnKey = true;
             return true;
@@ -4242,6 +4365,7 @@
     private static final class OnTouchListenerImpl implements OnTouchListener {
         private boolean mHasOnTouch = false;
 
+        @Override
         public boolean onTouch(View v, MotionEvent event) {
             mHasOnTouch = true;
             return true;
@@ -4276,7 +4400,7 @@
         public void reset() {
             mCalledOnTouchEvent = false;
         }
-    };
+    }
 
     private static final class ViewData {
         public int childCount;
@@ -4287,6 +4411,7 @@
     private static final class MockRunnable implements Runnable {
         public boolean hasRun = false;
 
+        @Override
         public void run() {
             hasRun = true;
         }
diff --git a/tools/cts-tradefed/DynamicConfig.xml b/tools/cts-tradefed/DynamicConfig.xml
index 6acffc0..e02d61e 100644
--- a/tools/cts-tradefed/DynamicConfig.xml
+++ b/tools/cts-tradefed/DynamicConfig.xml
@@ -13,6 +13,8 @@
      limitations under the License.
 -->
 
-<DynamicConfig>
-    <Config key="MediaFilesUrl">https://dl.google.com/dl/android/cts/android-cts-media-1.1.zip</Config>
-</DynamicConfig>
+<dynamicConfig>
+    <entry key="MediaFilesUrl">
+         <value>https://dl.google.com/dl/android/cts/android-cts-media-1.1.zip</value>
+    </entry>
+</dynamicConfig>
diff --git a/tools/vm-tests-tf/Android.mk b/tools/vm-tests-tf/Android.mk
index 7578fa9..1e7be8a 100644
--- a/tools/vm-tests-tf/Android.mk
+++ b/tools/vm-tests-tf/Android.mk
@@ -66,7 +66,6 @@
 intermediates := $(call intermediates-dir-for,JAVA_LIBRARIES,vm-tests-tf,HOST)
 vmteststf_jar := $(intermediates)/android.core.vm-tests-tf.jar
 vmteststf_dep_jars := $(addprefix $(HOST_OUT_JAVA_LIBRARIES)/, cts-tf-dalvik-buildutil.jar dasm.jar dx.jar cfassembler.jar junit.jar)
-vmteststf_dep_jars += $(addprefix $(HOST_OUT_JAVA_LIBRARIES)/, jack.jar)
 vmteststf_dep_jars += $(private_jill_jarjar_asm)
 
 $(vmteststf_jar): PRIVATE_JACK_EXTRA_ARGS := $(LOCAL_JACK_EXTRA_ARGS)
@@ -83,7 +82,7 @@
 $(vmteststf_jar): PRIVATE_INTERMEDIATES_HOSTJUNIT_FILES := $(intermediates)/hostjunit_files
 $(vmteststf_jar): PRIVATE_CLASS_PATH := $(subst $(space),:,$(vmteststf_dep_jars)):$(HOST_JDK_TOOLS_JAR)
 ifndef LOCAL_JACK_ENABLED
-$(vmteststf_jar) : $(vmteststf_dep_jars) $(JACK_JAR) $(JILL_JAR) $(HOST_OUT_JAVA_LIBRARIES)/tradefed-prebuilt.jar
+$(vmteststf_jar) : $(vmteststf_dep_jars) $(JILL_JAR) $(HOST_OUT_JAVA_LIBRARIES)/tradefed-prebuilt.jar
 	$(hide) rm -rf $(dir $@) && mkdir -p $(dir $@)
 	$(hide) mkdir -p $(PRIVATE_INTERMEDIATES_HOSTJUNIT_FILES)/dot/junit $(dir $(PRIVATE_INTERMEDIATES_DEXCORE_JAR))
 	# generated and compile the host side junit tests
@@ -102,12 +101,12 @@
 oj_jack := $(call intermediates-dir-for,JAVA_LIBRARIES,core-oj,,COMMON)/classes.jack
 libart_jack := $(call intermediates-dir-for,JAVA_LIBRARIES,core-libart,,COMMON)/classes.jack
 $(vmteststf_jar): PRIVATE_DALVIK_SUITE_CLASSPATH := $(oj_jack):$(libart_jack):$(cts-tf-dalvik-lib.jack):$(HOST_OUT_JAVA_LIBRARIES)/tradefed-prebuilt.jar
-$(vmteststf_jar) : $(vmteststf_dep_jars) $(JACK_JAR) $(JILL_JAR) $(oj_jack) $(libart_jack) $(HOST_OUT_JAVA_LIBRARIES)/tradefed-prebuilt.jar
+$(vmteststf_jar) : $(vmteststf_dep_jars) $(JACK) $(JILL_JAR) $(oj_jack) $(libart_jack) $(HOST_OUT_JAVA_LIBRARIES)/tradefed-prebuilt.jar | setup-jack-server
 	$(hide) rm -rf $(dir $@) && mkdir -p $(dir $@)
 	$(hide) mkdir -p $(PRIVATE_INTERMEDIATES_HOSTJUNIT_FILES)/dot/junit $(dir $(PRIVATE_INTERMEDIATES_DEXCORE_JAR))
 	# generated and compile the host side junit tests
 	@echo "Write generated Main_*.java files to $(PRIVATE_INTERMEDIATES_MAIN_FILES)"
-	$(hide) java -cp $(PRIVATE_CLASS_PATH) util.build.JackBuildDalvikSuite $(PRIVATE_SRC_FOLDER) $(PRIVATE_INTERMEDIATES) \
+	$(hide) JACK_VERSION=$(JACK_DEFAULT_VERSION) java -cp $(PRIVATE_CLASS_PATH) util.build.JackBuildDalvikSuite $(PRIVATE_SRC_FOLDER) $(PRIVATE_INTERMEDIATES) \
 		$(PRIVATE_DALVIK_SUITE_CLASSPATH) \
 		$(PRIVATE_INTERMEDIATES_MAIN_FILES) $(PRIVATE_INTERMEDIATES_CLASSES) $(PRIVATE_INTERMEDIATES_HOSTJUNIT_FILES) $$RUN_VM_TESTS_RTO
 	@echo "Generate $(PRIVATE_INTERMEDIATES_DEXCORE_JAR)"
diff --git a/tools/vm-tests-tf/src/util/build/BytesStreamSucker.java b/tools/vm-tests-tf/src/util/build/BytesStreamSucker.java
new file mode 100644
index 0000000..f243c17
--- /dev/null
+++ b/tools/vm-tests-tf/src/util/build/BytesStreamSucker.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2012 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 util.build;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import javax.annotation.Nonnull;
+
+/**
+ * Class that continuously read an {@link InputStream} and optionally could write the input in a
+ * {@link OutputStream}.
+ */
+public class BytesStreamSucker {
+
+  private static final int BUFFER_SIZE = 4096;
+
+  @Nonnull
+  private final byte[] buffer = new byte[BUFFER_SIZE];
+
+  @Nonnull
+  private final InputStream is;
+
+  @Nonnull
+  private final OutputStream os;
+
+  private final boolean toBeClose;
+
+  public BytesStreamSucker(
+      @Nonnull InputStream is, @Nonnull OutputStream os, boolean toBeClose) {
+    this.is = is;
+    this.os = os;
+    this.toBeClose = toBeClose;
+  }
+
+  public BytesStreamSucker(@Nonnull InputStream is, @Nonnull OutputStream os) {
+    this(is, os, false);
+  }
+
+  public void suck() throws IOException {
+    try {
+      int bytesRead;
+      while ((bytesRead = is.read(buffer)) >= 0) {
+        os.write(buffer, 0, bytesRead);
+        os.flush();
+      }
+    } finally {
+      if (toBeClose) {
+        os.close();
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/tools/vm-tests-tf/src/util/build/CharactersStreamSucker.java b/tools/vm-tests-tf/src/util/build/CharactersStreamSucker.java
new file mode 100644
index 0000000..ce4dfb1
--- /dev/null
+++ b/tools/vm-tests-tf/src/util/build/CharactersStreamSucker.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2012 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 util.build;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintStream;
+
+import javax.annotation.Nonnull;
+
+/**
+ * Class that continuously read an {@link InputStream} and optionally could print the input in a
+ * {@link PrintStream}.
+ */
+public class CharactersStreamSucker {
+
+  @Nonnull
+  private final BufferedReader ir;
+
+  @Nonnull
+  private final PrintStream os;
+
+  private final boolean toBeClose;
+
+  public CharactersStreamSucker(
+      @Nonnull InputStream is, @Nonnull PrintStream os, boolean toBeClose) {
+    this.ir = new BufferedReader(new InputStreamReader(is));
+    this.os = os;
+    this.toBeClose = toBeClose;
+  }
+
+  public CharactersStreamSucker(@Nonnull InputStream is, @Nonnull PrintStream os) {
+    this(is, os, false);
+  }
+
+  public void suck() throws IOException {
+    String line;
+
+    try {
+      while ((line = ir.readLine()) != null) {
+        os.println(line);
+      }
+    } finally {
+      if (toBeClose) {
+        os.close();
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/tools/vm-tests-tf/src/util/build/ExecuteFile.java b/tools/vm-tests-tf/src/util/build/ExecuteFile.java
new file mode 100644
index 0000000..a0e5ce5
--- /dev/null
+++ b/tools/vm-tests-tf/src/util/build/ExecuteFile.java
@@ -0,0 +1,274 @@
+/*
+ * Copyright (C) 2012 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 util.build;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.StreamTokenizer;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
+
+/**
+ * Class to handle the execution of an external process
+ */
+public class ExecuteFile {
+  @Nonnull
+  private final String[] cmdLine;
+
+  @CheckForNull
+  private File workDir;
+
+  @CheckForNull
+  private InputStream inStream;
+  private boolean inToBeClose;
+
+  @CheckForNull
+  private OutputStream outStream;
+  private boolean outToBeClose;
+
+  @CheckForNull
+  private OutputStream errStream;
+  private boolean errToBeClose;
+  private boolean verbose;
+
+  @Nonnull
+  private final Logger logger = Logger.getLogger(this.getClass().getName());
+
+  public void setErr(@Nonnull File file) throws FileNotFoundException {
+    errStream = new FileOutputStream(file);
+    errToBeClose = true;
+  }
+
+  public void setOut(@Nonnull File file) throws FileNotFoundException {
+    outStream = new FileOutputStream(file);
+    outToBeClose = true;
+  }
+
+  public void setIn(@Nonnull File file) throws FileNotFoundException {
+    inStream = new FileInputStream(file);
+    inToBeClose = true;
+  }
+
+  public void setErr(@Nonnull OutputStream stream) {
+    errStream = stream;
+  }
+
+  public void setOut(@Nonnull OutputStream stream) {
+    outStream = stream;
+  }
+
+  public void setIn(@Nonnull InputStream stream) {
+    inStream = stream;
+  }
+
+  public void setWorkingDir(@Nonnull File dir, boolean create) throws IOException {
+    if (!dir.isDirectory()) {
+      if (create && !dir.exists()) {
+        if (!dir.mkdirs()) {
+          throw new IOException("Directory creation failed");
+        }
+      } else {
+        throw new FileNotFoundException(dir.getPath() + " is not a directory");
+      }
+    }
+
+    workDir = dir;
+  }
+
+  public void setVerbose(boolean verbose) {
+    this.verbose = verbose;
+  }
+
+  public ExecuteFile(@Nonnull File exec, @Nonnull String[] args) {
+    cmdLine = new String[args.length + 1];
+    System.arraycopy(args, 0, cmdLine, 1, args.length);
+
+    cmdLine[0] = exec.getAbsolutePath();
+  }
+
+  public ExecuteFile(@Nonnull String exec, @Nonnull String[] args) {
+    cmdLine = new String[args.length + 1];
+    System.arraycopy(args, 0, cmdLine, 1, args.length);
+
+    cmdLine[0] = exec;
+  }
+
+  public ExecuteFile(@Nonnull File exec) {
+    cmdLine = new String[1];
+    cmdLine[0] = exec.getAbsolutePath();
+  }
+
+  public ExecuteFile(@Nonnull String[] cmdLine) {
+    this.cmdLine = cmdLine.clone();
+  }
+
+  public ExecuteFile(@Nonnull String cmdLine) throws IOException {
+    StringReader reader = new StringReader(cmdLine);
+    StreamTokenizer tokenizer = new StreamTokenizer(reader);
+    tokenizer.resetSyntax();
+    // Only standard spaces are recognized as whitespace chars
+    tokenizer.whitespaceChars(' ', ' ');
+    // Matches alphanumerical and common special symbols like '(' and ')'
+    tokenizer.wordChars('!', 'z');
+    // Quote chars will be ignored when parsing strings
+    tokenizer.quoteChar('\'');
+    tokenizer.quoteChar('\"');
+    ArrayList<String> tokens = new ArrayList<String>();
+    while (tokenizer.nextToken() != StreamTokenizer.TT_EOF) {
+      String token = tokenizer.sval;
+      if (token != null) {
+        tokens.add(token);
+      }
+    }
+    this.cmdLine = tokens.toArray(new String[0]);
+  }
+
+  public boolean run() {
+    int ret;
+    Process proc = null;
+    Thread suckOut = null;
+    Thread suckErr = null;
+    Thread suckIn = null;
+
+    try {
+      StringBuilder cmdLineBuilder = new StringBuilder();
+      for (String arg : cmdLine) {
+        cmdLineBuilder.append(arg).append(' ');
+      }
+      if (verbose) {
+        PrintStream printStream;
+        if (outStream instanceof PrintStream) {
+          printStream = (PrintStream) outStream;
+        } else {
+          printStream = System.out;
+        }
+
+        if (printStream != null) {
+          printStream.println(cmdLineBuilder);
+        }
+      } else {
+        logger.log(Level.FINE, "Execute: {0}", cmdLineBuilder);
+      }
+
+      proc = Runtime.getRuntime().exec(cmdLine, null, workDir);
+
+      InputStream localInStream = inStream;
+      if (localInStream != null) {
+        suckIn = new Thread(
+            new ThreadBytesStreamSucker(localInStream, proc.getOutputStream(), inToBeClose));
+      } else {
+        proc.getOutputStream().close();
+      }
+
+      OutputStream localOutStream = outStream;
+      if (localOutStream != null) {
+        if (localOutStream instanceof PrintStream) {
+          suckOut = new Thread(new ThreadCharactersStreamSucker(proc.getInputStream(),
+              (PrintStream) localOutStream, outToBeClose));
+        } else {
+          suckOut = new Thread(
+              new ThreadBytesStreamSucker(proc.getInputStream(), localOutStream, outToBeClose));
+        }
+      }
+
+      OutputStream localErrStream = errStream;
+      if (localErrStream != null) {
+        if (localErrStream instanceof PrintStream) {
+          suckErr = new Thread(new ThreadCharactersStreamSucker(proc.getErrorStream(),
+              (PrintStream) localErrStream, errToBeClose));
+        } else {
+          suckErr = new Thread(
+              new ThreadBytesStreamSucker(proc.getErrorStream(), localErrStream, errToBeClose));
+        }
+      }
+
+      if (suckIn != null) {
+        suckIn.start();
+      }
+      if (suckOut != null) {
+        suckOut.start();
+      }
+      if (suckErr != null) {
+        suckErr.start();
+      }
+
+      proc.waitFor();
+      if (suckIn != null) {
+        suckIn.join();
+      }
+      if (suckOut != null) {
+        suckOut.join();
+      }
+      if (suckErr != null) {
+        suckErr.join();
+      }
+
+      ret = proc.exitValue();
+      proc.destroy();
+
+      return ret == 0;
+    } catch (Throwable e) {
+      return false;
+    }
+  }
+
+  private static class ThreadBytesStreamSucker extends BytesStreamSucker implements Runnable {
+
+    public ThreadBytesStreamSucker(@Nonnull InputStream is, @Nonnull OutputStream os,
+        boolean toBeClose) {
+      super(is, os, toBeClose);
+    }
+
+    @Override
+    public void run() {
+      try {
+        suck();
+      } catch (IOException e) {
+        // Best effort
+      }
+    }
+  }
+
+  private static class ThreadCharactersStreamSucker extends CharactersStreamSucker implements
+      Runnable {
+
+    public ThreadCharactersStreamSucker(@Nonnull InputStream is, @Nonnull PrintStream ps,
+        boolean toBeClose) {
+      super(is, ps, toBeClose);
+    }
+
+    @Override
+    public void run() {
+      try {
+        suck();
+      } catch (IOException e) {
+        // Best effort
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/tools/vm-tests-tf/src/util/build/JackBuildStep.java b/tools/vm-tests-tf/src/util/build/JackBuildStep.java
index 061ff07..29df8260 100644
--- a/tools/vm-tests-tf/src/util/build/JackBuildStep.java
+++ b/tools/vm-tests-tf/src/util/build/JackBuildStep.java
@@ -16,16 +16,10 @@
 
 package util.build;
 
-import com.android.jack.CLILogConfiguration;
-import com.android.jack.CLILogConfiguration.LogConfigurationException;
-
-import util.build.BuildStep.BuildFile;
-
-import com.android.jack.Jack;
-import com.android.jack.Main;
-import com.android.jack.Options;
 import java.io.File;
+import java.io.FileWriter;
 import java.io.IOException;
+import java.io.Writer;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
@@ -33,14 +27,6 @@
 
 public class JackBuildStep extends SourceBuildStep {
 
-    static {
-        try {
-              CLILogConfiguration.setupLogs();
-            } catch (LogConfigurationException e) {
-              throw new Error("Failed to setup logs", e);
-            }
-    }
-
     private final String destPath;
     private final String classPath;
     private final Set<String> sourceFiles = new HashSet<String>();
@@ -78,7 +64,18 @@
             }
             File tmpDex = new File(tmpOutDir, "classes.dex");
 
+            File tmpArgs = new File(outDir, outputFile.fileName.getName() + ".args");
+
+            Writer argsOut = null;
             try {
+                argsOut = new FileWriter(tmpArgs);
+                for (String source : sourceFiles) {
+                    argsOut.append(source);
+                    argsOut.append('\n');
+                }
+                argsOut.close();
+                argsOut = null;
+
                 List<String> commandLine = new ArrayList<String>(6 + sourceFiles.size());
                 commandLine.add("--verbose");
                 commandLine.add("error");
@@ -86,10 +83,14 @@
                 commandLine.add(classPath);
                 commandLine.add("--output-dex");
                 commandLine.add(tmpOutDir.getAbsolutePath());
-                commandLine.addAll(sourceFiles);
+                commandLine.add("@" + tmpArgs.getPath());
 
-                Options options = Main.parseCommandLine(commandLine);
-                Jack.checkAndRun(options);
+                ExecuteFile exec = new ExecuteFile("jack", commandLine.toArray(new String[commandLine.size()]));
+                exec.setErr(System.err);
+                exec.setOut(System.out);
+                if (!exec.run()) {
+                    return false;
+                }
 
                 JarBuildStep jarStep = new JarBuildStep(
                     new BuildFile(tmpDex),
@@ -104,8 +105,16 @@
                 ex.printStackTrace();
                 return false;
             } finally {
-              tmpDex.delete();
-              tmpOutDir.delete();
+                tmpDex.delete();
+                tmpArgs.delete();
+                tmpOutDir.delete();
+                if (argsOut != null) {
+                    try {
+                        argsOut.close();
+                    } catch (IOException io) {
+                        // Ignore, don't override already thrown exception
+                    }
+                }
             }
         }
         return false;
diff --git a/tools/vm-tests-tf/src/util/build/JackDexBuildStep.java b/tools/vm-tests-tf/src/util/build/JackDexBuildStep.java
index 8734cf0..3702973 100644
--- a/tools/vm-tests-tf/src/util/build/JackDexBuildStep.java
+++ b/tools/vm-tests-tf/src/util/build/JackDexBuildStep.java
@@ -16,10 +16,6 @@
 
 package util.build;
 
-import com.android.jack.Jack;
-import com.android.jack.Main;
-import com.android.jack.Options;
-
 import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
@@ -69,8 +65,12 @@
                 commandLine.add("--import");
                 commandLine.add(inputFile.fileName.getAbsolutePath());
 
-                Options options = Main.parseCommandLine(commandLine);
-                Jack.checkAndRun(options);
+                ExecuteFile exec = new ExecuteFile("jack", commandLine.toArray(new String[commandLine.size()]));
+                exec.setErr(System.err);
+                exec.setOut(System.out);
+                if (!exec.run()) {
+                  return false;
+                }
 
                 JarBuildStep jarStep = new JarBuildStep(
                     new BuildFile(tmpDex),