Merge "Use exclude filters for cts retry runs" into nyc-dev
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index 157b54f..5d3914f 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -23,6 +23,7 @@
     <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="24"/>
 
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+    <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/>
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
     <uses-permission android:name="android.permission.BLUETOOTH" />
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index e14e2d9..50e1bdf 100644
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -2462,6 +2462,13 @@
     Do you see the programs named \"Dummy Program\" and their descriptions
     "Dummy Program Description" in the EPG?
     </string>
+    <string name="tv_input_discover_test_trigger_setup">
+    Select the \"Launch setup\" button and verify if the bundled TV app shows the list of installed
+    TV inputs for setup.
+    </string>
+    <string name="tv_input_discover_test_verify_trigger_setup">
+    Do you see the \"CTS Verifier\" input in the list?
+    </string>
 
     <string name="tv_parental_control_test">TV app parental controls test</string>
     <string name="tv_parental_control_test_info">
@@ -2489,6 +2496,7 @@
 
     <string name="tv_launch_tv_app">Launch TV app</string>
     <string name="tv_launch_epg">Launch EPG</string>
+    <string name="tv_launch_setup">Launch setup</string>
     <string name="tv_channel_not_found">
     CtsVerifier channel is not set up. Please set up before proceeding.
     </string>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/TvInputDiscoveryTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/TvInputDiscoveryTestActivity.java
index e8e2cee..56c8ac0 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/tv/TvInputDiscoveryTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/TvInputDiscoveryTestActivity.java
@@ -20,6 +20,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.media.tv.TvContract;
+import android.media.tv.TvInputManager;
 import android.os.AsyncTask;
 import android.view.View;
 
@@ -36,6 +37,8 @@
             TvContract.Channels.CONTENT_URI);
     private static final Intent EPG_INTENT = new Intent(Intent.ACTION_VIEW,
             TvContract.Programs.CONTENT_URI);
+    private static final Intent TV_TRIGGER_SETUP_INTENT = new Intent(
+            TvInputManager.ACTION_SETUP_INPUTS);
 
     private static final long TIMEOUT_MS = 5l * 60l * 1000l;  // 5 mins.
 
@@ -47,6 +50,8 @@
     private View mVerifyGlobalSearchItem;
     private View mGoToEpgItem;
     private View mVerifyEpgItem;
+    private View mTriggerSetupItem;
+    private View mVerifyTriggerSetupItem;
     private boolean mTuneVerified;
     private boolean mOverlayViewVerified;
     private boolean mGlobalSearchVerified;
@@ -109,6 +114,13 @@
             setButtonEnabled(mVerifyEpgItem, true);
         } else if (containsButton(mVerifyEpgItem, v)) {
             setPassState(mVerifyEpgItem, true);
+            setButtonEnabled(mTriggerSetupItem, true);
+        } else if (containsButton(mTriggerSetupItem, v)) {
+            startActivity(TV_TRIGGER_SETUP_INTENT);
+            setPassState(mTriggerSetupItem, true);
+            setButtonEnabled(mVerifyTriggerSetupItem, true);
+        } else if (containsButton(mVerifyTriggerSetupItem, v)) {
+            setPassState(mVerifyTriggerSetupItem, true);
             getPassButton().setEnabled(true);
         }
     }
@@ -130,6 +142,10 @@
                 R.string.tv_launch_epg, this);
         mVerifyEpgItem = createUserItem(R.string.tv_input_discover_test_verify_epg,
                 android.R.string.yes, this);
+        mTriggerSetupItem = createUserItem(R.string.tv_input_discover_test_trigger_setup,
+                R.string.tv_launch_setup, this);
+        mVerifyTriggerSetupItem = createUserItem(
+                R.string.tv_input_discover_test_verify_trigger_setup, android.R.string.yes, this);
     }
 
     @Override
diff --git a/common/host-side/tradefed/res/report/compatibility_result.xsl b/common/host-side/tradefed/res/report/compatibility_result.xsl
index 1fb4e83..ac5c282 100644
--- a/common/host-side/tradefed/res/report/compatibility_result.xsl
+++ b/common/host-side/tradefed/res/report/compatibility_result.xsl
@@ -16,6 +16,7 @@
 
 <!DOCTYPE xsl:stylesheet [ <!ENTITY nbsp "&#160;"> ]>
 <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
     <xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes"/>
 
     <xsl:template match="/">
@@ -31,69 +32,41 @@
                 <div>
                     <table class="title">
                         <tr>
-                            <td width="40%" align="left"><img src="logo.png"></img></td>
-                            <td width="60%" align="left">
-                                <h1>Test Report</h1>
-                            </td>
+                            <td align="left"><img src="logo.png"/></td>
                         </tr>
                     </table>
                 </div>
-                <img src="newrule_green.png" align="left"></img>
-
-                <br></br>
-
-                <center>
-                    <a href="device-info/GenericDeviceInfo.deviceinfo.json" >Device Information</a>
-                </center>
-
-                <br></br>
 
                 <div>
                     <table class="summary">
                         <tr>
-                            <th colspan="2">Test Summary</th>
+                            <th colspan="2">Summary</th>
                         </tr>
                         <tr>
-                            <td class="rowtitle">Compatibility Suite</td>
+                            <td class="rowtitle">Suite / Plan</td>
                             <td>
-                                <xsl:value-of select="Result/@suite_name"/>
+                                <xsl:value-of select="Result/@suite_name"/> / <xsl:value-of select="Result/@plan"/>
                             </td>
                         </tr>
                         <tr>
-                            <td class="rowtitle">Compatibility Version</td>
+                            <td class="rowtitle">Suite / Build</td>
                             <td>
-                                <xsl:value-of select="Result/@suite_version"/>
-                            </td>
-                        </tr>
-                        <tr>
-                            <td class="rowtitle">Report Version</td>
-                            <td>
-                                <xsl:value-of select="Result/@report_version"/>
+                                <xsl:value-of select="Result/@suite_version"/> / <xsl:value-of select="Result/@suite_build_number"/>
                             </td>
                         </tr>
                         <tr>
                             <td class="rowtitle">Host Info</td>
                             <td>
+                                Result/@start
                                 <xsl:value-of select="Result/@host_name"/>
                                 (<xsl:value-of select="Result/@os_name"/> - <xsl:value-of select="Result/@os_version"/>)
                             </td>
                         </tr>
                         <tr>
-                            <td class="rowtitle">Plan</td>
+                            <td class="rowtitle">Start time / End Time</td>
                             <td>
-                                <xsl:value-of select="Result/@plan"/>
-                            </td>
-                        </tr>
-                        <tr>
-                            <td class="rowtitle">Start time</td>
-                            <td>
-                                <xsl:value-of select="Result/@start"/>
-                            </td>
-                        </tr>
-                        <tr>
-                            <td class="rowtitle">End time</td>
-                            <td>
-                                <xsl:value-of select="Result/@end"/>
+                                <xsl:value-of select="Result/@start_display"/> /
+                                <xsl:value-of select="Result/@end_display"/>
                             </td>
                         </tr>
                         <tr>
@@ -114,11 +87,35 @@
                                 <xsl:value-of select="Result/Summary/@not_executed"/>
                             </td>
                         </tr>
+                        <tr>
+                            <td class="rowtitle">Fingerprint</td>
+                            <td>
+                                <xsl:value-of select="Result/Build/@build_fingerprint"/>
+                            </td>
+                        </tr>
+                        <tr>
+                            <td class="rowtitle">Security Patch</td>
+                            <td>
+                                <xsl:value-of select="Result/Build/@build_version_security_patch"/>
+                            </td>
+                        </tr>
+                        <tr>
+                            <td class="rowtitle">Release (SDK)</td>
+                            <td>
+                                <xsl:value-of select="Result/Build/@build_version_release"/> (<xsl:value-of select="Result/Build/@build_version_sdk"/>)
+                            </td>
+                        </tr>
+                        <tr>
+                            <td class="rowtitle">ABIs</td>
+                            <td>
+                                <xsl:value-of select="Result/Build/@build_abis"/>
+                            </td>
+                        </tr>
                     </table>
                 </div>
 
                 <!-- High level summary of test execution -->
-                <h2 align="center">Test Summary by Module</h2>
+                <br/>
                 <div>
                     <table class="testsummary">
                         <tr>
@@ -135,16 +132,16 @@
                                     <a href="#{$href}"><xsl:value-of select="@name"/> - <xsl:value-of select="@abi"/></a>
                                 </td>
                                 <td>
-                                    <xsl:value-of select="count(Test[@result = 'pass'])"/>
+                                    <xsl:value-of select="count(TestCase/Test[@result = 'pass'])"/>
                                 </td>
                                 <td>
-                                    <xsl:value-of select="count(Test[@result = 'fail'])"/>
+                                    <xsl:value-of select="count(TestCase/Test[@result = 'fail'])"/>
                                 </td>
                                 <td>
-                                    <xsl:value-of select="count(Test[@result = 'not_executed'])"/>
+                                    <xsl:value-of select="count(TestCase/Test[@result = 'not_executed'])"/>
                                 </td>
                                 <td>
-                                    <xsl:value-of select="count(Test)"/>
+                                    <xsl:value-of select="count(TestCase/Test)"/>
                                 </td>
                             </tr>
                         </xsl:for-each> <!-- end Module -->
@@ -161,7 +158,7 @@
                     <xsl:with-param name="resultFilter" select="'not_executed'" />
                 </xsl:call-template>
 
-                <h2 align="center">Detailed Test Report</h2>
+                <br/>
                 <xsl:call-template name="detailedTestReport" />
 
             </body>
@@ -201,46 +198,49 @@
                             <th>Details</th>
                         </tr>
 
-                        <!-- test -->
-                        <xsl:for-each select="Test">
-                            <xsl:if test="$resultFilter='' or $resultFilter=@result">
-                                <tr>
-                                    <td class="testname"> -- <xsl:value-of select="@name"/></td>
+                        <xsl:for-each select="TestCase">
+                            <xsl:variable name="TestCase" select="."/>
+                            <!-- test -->
+                            <xsl:for-each select="Test">
+                                <xsl:if test="$resultFilter='' or $resultFilter=@result">
+                                    <tr>
+                                        <td class="testname"> <xsl:value-of select="$TestCase/@name"/>#<xsl:value-of select="@name"/></td>
 
-                                    <!-- test results -->
-                                    <xsl:if test="@result='pass'">
-                                        <td class="pass">
-                                            <div style="text-align: center; margin-left:auto; margin-right:auto;">
-                                                <xsl:value-of select="@result"/>
-                                            </div>
-                                        </td>
-                                        <td class="failuredetails"/>
-                                    </xsl:if>
+                                        <!-- test results -->
+                                        <xsl:if test="@result='pass'">
+                                            <td class="pass">
+                                                <div style="text-align: center; margin-left:auto; margin-right:auto;">
+                                                    <xsl:value-of select="@result"/>
+                                                </div>
+                                            </td>
+                                            <td class="failuredetails"/>
+                                        </xsl:if>
 
-                                    <xsl:if test="@result='fail'">
-                                        <td class="failed">
-                                            <div style="text-align: center; margin-left:auto; margin-right:auto;">
-                                                <xsl:value-of select="@result"/>
-                                            </div>
-                                        </td>
-                                        <td class="failuredetails">
-                                            <div class="details">
-                                                <xsl:value-of select="Failure/@message"/>
-                                            </div>
-                                        </td>
-                                    </xsl:if>
+                                        <xsl:if test="@result='fail'">
+                                            <td class="failed">
+                                                <div style="text-align: center; margin-left:auto; margin-right:auto;">
+                                                    <xsl:value-of select="@result"/>
+                                                </div>
+                                            </td>
+                                            <td class="failuredetails">
+                                                <div class="details">
+                                                    <xsl:value-of select="Failure/@message"/>
+                                                </div>
+                                            </td>
+                                        </xsl:if>
 
-                                    <xsl:if test="@result='not_executed'">
-                                        <td class="not_executed">
-                                            <div style="text-align: center; margin-left:auto; margin-right:auto;">
-                                                <xsl:value-of select="@result"/>
-                                            </div>
-                                        </td>
-                                        <td class="failuredetails"></td>
-                                    </xsl:if>
-                                </tr> <!-- finished with a row -->
-                            </xsl:if>
-                        </xsl:for-each> <!-- end test -->
+                                        <xsl:if test="@result='not_executed'">
+                                            <td class="not_executed">
+                                                <div style="text-align: center; margin-left:auto; margin-right:auto;">
+                                                    <xsl:value-of select="@result"/>
+                                                </div>
+                                            </td>
+                                            <td class="failuredetails"></td>
+                                        </xsl:if>
+                                    </tr> <!-- finished with a row -->
+                                </xsl:if>
+                            </xsl:for-each> <!-- end test -->
+                        </xsl:for-each>
                     </table>
                 </xsl:if>
             </xsl:for-each> <!-- end test Module -->
diff --git a/common/host-side/tradefed/res/report/newrule_green.png b/common/host-side/tradefed/res/report/newrule_green.png
deleted file mode 100644
index 10a4194..0000000
--- a/common/host-side/tradefed/res/report/newrule_green.png
+++ /dev/null
Binary files differ
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/ResultReporter.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/ResultReporter.java
index 81d78c0..9f9728b 100644
--- a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/ResultReporter.java
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/ResultReporter.java
@@ -75,8 +75,7 @@
         "compatibility_result.css",
         "compatibility_result.xsd",
         "compatibility_result.xsl",
-        "logo.png",
-        "newrule_green.png"};
+        "logo.png"};
 
     @Option(name = CompatibilityTest.RETRY_OPTION,
             shortName = 'r',
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/result/ResultReporterTest.java b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/result/ResultReporterTest.java
index 3fcf8b5..6228cd7 100644
--- a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/result/ResultReporterTest.java
+++ b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/result/ResultReporterTest.java
@@ -62,8 +62,7 @@
         "compatibility_result.css",
         "compatibility_result.xsd",
         "compatibility_result.xsl",
-        "logo.png",
-        "newrule_green.png"};
+        "logo.png"};
 
     private ResultReporter mReporter;
     private IBuildInfo mBuildInfo;
diff --git a/common/util/src/com/android/compatibility/common/util/ResultHandler.java b/common/util/src/com/android/compatibility/common/util/ResultHandler.java
index 5f05229..d91763c 100644
--- a/common/util/src/com/android/compatibility/common/util/ResultHandler.java
+++ b/common/util/src/com/android/compatibility/common/util/ResultHandler.java
@@ -28,7 +28,9 @@
 import java.io.OutputStream;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
+import java.text.SimpleDateFormat;
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.List;
 import java.util.Map.Entry;
 import java.util.Set;
@@ -50,6 +52,7 @@
     private static final String BUILD_TAG = "Build";
     private static final String CASE_TAG = "TestCase";
     private static final String DEVICES_ATTR = "devices";
+    private static final String END_DISPLAY_TIME_ATTR = "end_display";
     private static final String END_TIME_ATTR = "end";
     private static final String FAILED_ATTR = "failed";
     private static final String FAILURE_TAG = "Failure";
@@ -72,6 +75,7 @@
     private static final String RUNTIME_ATTR = "runtime";
     private static final String SCREENSHOT_TAG = "Screenshot";
     private static final String STACK_TAG = "StackTrace";
+    private static final String START_DISPLAY_TIME_ATTR = "start_display";
     private static final String START_TIME_ATTR = "start";
     private static final String SUITE_NAME_ATTR = "suite_name";
     private static final String SUITE_PLAN_ATTR = "suite_plan";
@@ -205,10 +209,13 @@
         serializer.startDocument(ENCODING, false);
         serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
         serializer.processingInstruction(
-                "xml-stylesheet type=\"text/xsl\" href=\"compatibility-result.xsl\"");
+                "xml-stylesheet type=\"text/xsl\" href=\"compatibility_result.xsl\"");
         serializer.startTag(NS, RESULT_TAG);
         serializer.attribute(NS, START_TIME_ATTR, String.valueOf(startTime));
         serializer.attribute(NS, END_TIME_ATTR, String.valueOf(endTime));
+        serializer.attribute(NS, START_DISPLAY_TIME_ATTR, toReadableDateString(startTime));
+        serializer.attribute(NS, END_DISPLAY_TIME_ATTR, toReadableDateString(endTime));
+
         serializer.attribute(NS, SUITE_NAME_ATTR, suiteName);
         serializer.attribute(NS, SUITE_VERSION_ATTR, suiteVersion);
         serializer.attribute(NS, SUITE_PLAN_ATTR, suitePlan);
@@ -315,4 +322,15 @@
         return resultFile;
     }
 
+    /**
+     * Return the given time as a {@link String} suitable for displaying.
+     * <p/>
+     * Example: Fri Aug 20 15:13:03 PDT 2010
+     *
+     * @param time the epoch time in ms since midnight Jan 1, 1970
+     */
+    static String toReadableDateString(long time) {
+        SimpleDateFormat dateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");
+        return dateFormat.format(new Date(time));
+    }
 }
diff --git a/common/util/tests/src/com/android/compatibility/common/util/ResultHandlerTest.java b/common/util/tests/src/com/android/compatibility/common/util/ResultHandlerTest.java
index 215e2ef..1e9aa33 100644
--- a/common/util/tests/src/com/android/compatibility/common/util/ResultHandlerTest.java
+++ b/common/util/tests/src/com/android/compatibility/common/util/ResultHandlerTest.java
@@ -69,12 +69,16 @@
             "at four.big.insects.Marley.sing(Marley.java:10)";
     private static final long START_MS = 1431586801000L;
     private static final long END_MS = 1431673199000L;
+    private static final String START_DISPLAY = "Fri Aug 20 15:13:03 PDT 2010";
+    private static final String END_DISPLAY = "Fri Aug 20 15:13:04 PDT 2010";
+
     private static final String REFERENCE_URL="http://android.com";
     private static final String JOIN = "%s%s";
     private static final String XML_BASE =
             "<?xml version='1.0' encoding='UTF-8' standalone='no' ?>" +
             "<?xml-stylesheet type=\"text/xsl\" href=\"compatibility_result.xsl\"?>\n" +
-            "<Result start=\"%d\" end=\"%d\" suite_name=\"%s\" suite_version=\"%s\" " +
+            "<Result start=\"%d\" end=\"%d\" start_display=\"%s\"" +
+            "end_display=\"%s\" suite_name=\"%s\" suite_version=\"%s\" " +
             "suite_plan=\"%s\" suite_build_number=\"%s\" report_version=\"%s\" " +
             "devices=\"%s\" host_name=\"%s\"" +
             "os_name=\"%s\" os_version=\"%s\" os_arch=\"%s\" java_vendor=\"%s\"" +
@@ -204,9 +208,10 @@
             try {
                 hostName = InetAddress.getLocalHost().getHostName();
             } catch (UnknownHostException ignored) {}
-            String output = String.format(XML_BASE, START_MS, END_MS, SUITE_NAME, SUITE_VERSION,
-                    SUITE_PLAN, SUITE_BUILD, REPORT_VERSION, DEVICES, hostName, OS_NAME, OS_VERSION,
-                    OS_ARCH, JAVA_VENDOR, JAVA_VERSION, REFERENCE_URL, deviceInfo, summary, modules);
+            String output = String.format(XML_BASE, START_MS, END_MS, START_DISPLAY, END_DISPLAY,
+                    SUITE_NAME, SUITE_VERSION, SUITE_PLAN, SUITE_BUILD, REPORT_VERSION, DEVICES,
+                    hostName, OS_NAME, OS_VERSION, OS_ARCH, JAVA_VENDOR, JAVA_VERSION, REFERENCE_URL,
+                    deviceInfo, summary, modules);
             writer.write(output);
             writer.flush();
 
diff --git a/hostsidetests/appsecurity/certs/pkgsigverify/rsa-16384.pk8 b/hostsidetests/appsecurity/certs/pkgsigverify/rsa-16384.pk8
new file mode 100644
index 0000000..c8d2793
--- /dev/null
+++ b/hostsidetests/appsecurity/certs/pkgsigverify/rsa-16384.pk8
Binary files differ
diff --git a/hostsidetests/appsecurity/certs/pkgsigverify/rsa-16384.x509.pem b/hostsidetests/appsecurity/certs/pkgsigverify/rsa-16384.x509.pem
new file mode 100644
index 0000000..22b6148
--- /dev/null
+++ b/hostsidetests/appsecurity/certs/pkgsigverify/rsa-16384.x509.pem
@@ -0,0 +1,93 @@
+-----BEGIN CERTIFICATE-----
+MIIQ+zCCCOOgAwIBAgIJAOd3bpikuRKvMA0GCSqGSIb3DQEBDQUAMBQxEjAQBgNV
+BAMMCXJzYS0xNjM4NDAeFw0xNjA0MDQxOTM0MzFaFw00MzA4MjExOTM0MzFaMBQx
+EjAQBgNVBAMMCXJzYS0xNjM4NDCCCCIwDQYJKoZIhvcNAQEBBQADgggPADCCCAoC
+gggBALDYs7aIK08pNr9fdrpLmUVfSc+3n/RNU2e7o3fzwQf2IMExk/ZmxF/ORgAd
+pXPEkn7uOLYSp+fJHUgqsca+8HsxTN1ypKov0X3OeFbnBLXmsoXgjRzaMEgluupd
+B81xnAKE/Vb+HYaEJ4YP+3UgBLIItnwLtL6vdh+e4qQGF9KEAv+T+PdrNQF0EGWK
+weCaOuMKRKfSnNXMkgIgWgoEefsBXNOR/jRJVFxsnJlwsB2iw0FbKjrxnlmwBL+f
+A8YxdMoCLxjL0TuUEmRyd0jO7Td49kUIkW6ux/b4qOvcUPQiODXeayesJ1lmFepS
+ATjhgCz2+C3pcAJOPvOvC4v0+5OQ3YrU2kKsnj8G2ic3SdPUq4UUvQWqY+rCZVDH
+IqsEs/+XO++wMELkN3uiQcRIEO8aCug+VxMSRiyRSSNtxmcmedUZevbZ6+2leBtn
+AbLP33E5hC80A7WKuddQgOiA1yTUVxatZEaxHFVZlg2nzSYHipvwMVC2+zQ4yrKA
+mbNp5wiVUV5WLsUkYEuSwl+MG9vEjr2gTX+qLrvpIYS2AF/16SOEw5zQBPUcfVIz
+eJU+W//wwXdlNmA6qRCDXqLDBX1MQrChpaI2eRbv64k5C09LtEA5nt/lJt5dm8IF
+XpurOZqHTVG3CCS15SM8PyoApYKN0oM9+6Z+FDUOB+VbTW/hAqKYLNBJmNf8mRkK
++c1peoOAYw5iG8iaSD8f8bcIi3oFPMdt0Gs5vDoLjbWmK2s9P2wknA4hmVe7hvSy
+DMvyxj8j4BLadc3HafcXYPfoNPhfgoiZVLm6ijEj74iKeLSkef8F3x0Agulnitz3
+CWt7X6EXHbqR/0++VTqgnFDe+enf9oFzMsDDbOs59dpyGFSP159dTqJILimF5xUG
+Fw95hsTbdEblZ7Q2MiibB38ifz8WT+Pix72SnHrlcnKonv8Tkeoie0AP+dYkYXpC
+Dy0oIzl7Vhy1e99RjX8kKjZAfCuiQ7wnOGNu6V32UyKMvWD5E6mNLpsvyBRTxDhs
+ePpH5dZWbhg6WxhD68QG/Wi/8FRmc8/TPpPXilOG3HHtX6Q3yfGYHJB6/dJhWQQy
+iZawyEpcyZKjEyWoJayRsKSLb6gW6Idfc1Uf/yb6IHDRlYZEPF7JuznjLCaz2QC9
+8GCBGfUE9OGH+LtdMnsmn2IYEd1FtWrRGduG0HNKubmx8bJmc1HkYDQg3cksPb2o
+jwCND2ALGtTcR30yllmSmEJKpXBYB00iRvxvkBqCkL4THOXhN2V5uEMrS0r8GRZN
+QCvCoFKulPjITmlQ/ciVonN9y9qVeRbFE4ZxiiBxF41K/Mw45ugIqfg4ndJqbub6
+5p15nhYJIC2CbsVL5+1THmd+kompQhUo1ttwof0aHh3KLwe1uq2OEU7Tz71Ct5+G
+b5JjIAlQDuGcfsx3utJY3AE5ailtvaRNAz3FyTsZGkIOeqX4uswWltxGnuSMSbPi
+CPv7ngFXkytkK+3Oqs92XM8mhO1yqPzmm73+qZYDGFdy32C/Rr0enETmgkUFPToH
+28hMcOsEt+7L0GM6A5N708BaF9Csy7XTFz47Hk2CjaKTvP08Tl3bFPULrgJ5KCr6
+4hc/bVIDkU7c1lhDISJ1yuw4KHizmjuf4UeRBBDoB3MpPwZSeEkggGXuX1wkFApu
+RGhjCXQgFU9bNtUHM6Kj0tPQZrgsvx2wwBUFVOfPoej6afrJqpvep+EN1+OJCE4c
+AzuZ1CdE96vEleVbrq3BQaJbsm8JqHs7lAn1aiCK0semqAoXD4cT4L2H4E37IDlm
+PHsxIeTmgD7/TP3InuFB6sYvVM8moG1TLmtUJkpc8kkPBPNbTRHwuRvMGD1pSsP1
+aNbgKkEfGqL1iOrfoTCRGKDeDDxWGsxDOgW1hRs9wGzJuMQjl1Rlb11lnnX7UYyT
+UnD/yw7YaplScWwpsqntQewI59A4ad1wOJlabDUFwkD4i4ERTcjyea1ydE03qaOy
+0ItJbc8kjsEMWFAv1+y7/cxD7kALcytvBHhD8OVJ40qJrtwRsXnv2T74cTPh87qh
+3j2tjdJKVSLxwqg5ZdvIemnWmmFAPuRERResp5j5WLJcOFcXhbp4CAQLViRoktLf
+AKtgKSVa9FQLvombOq8GqWxqeGJEsq+8/X6UOj/RDPu8gUCdodmlxgC5BpJlMTfg
+9ElvHb4oRewPfc5MBV5i++8xagxS1+5NM6z+1qZfT+XJcJ/wFYyeSvGGdEgaDIVd
+XGqOFDmA20bUl0xWSM5j4At2CmymAn32i8FR5lNfB/f8tIGBlXQyrYzpAKoj6FrV
+3u43zKgYBzDTqNs61e+A8MScV5666gvpcOltFiaucc455JGiN2v7N+SAygWaX3nb
+jidmRaIAftup6kXVXxy1ZwpKCtUTqo0M+S/jO9clHy1EYaSX12blCL1B6OFpMRV7
+1foffUHwaPrMqqbPphgN4QRY2Ao2sKSliiP1T8s1T2iteEGiazCdWSOVVi9Acbo5
+DfeBlWwhW6OQpv1nMTznGscc4+ledP5yG5C6boz2aNwK6H6cpDfEc7tWTWhZN5Jm
+Jlra4pseqf9Lsc/Y4QMD1312C3Hu8EtJ/qlxEDhLnCW8PHxdlRsIkmcV8w+as/hu
+6/MlOYcCp9ae6nooFL7ZuDkdDWm84UXdce2ZVVGVoDa+RdpICnp79y/9CLxWue4H
+09VFEFUH//E6lOCBymUjTSO/DQ6z+ceb2W5B3WVV8gqADTDhAgMBAAGjUDBOMB0G
+A1UdDgQWBBQkHp1wX0Sfr0xz7xcip9UwEIFTLDAfBgNVHSMEGDAWgBQkHp1wX0Sf
+r0xz7xcip9UwEIFTLDAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBDQUAA4IIAQAd
+FhlHg4E7Yp8kIOfZRU5Cma6wbOSd2eHkV28WHGdwpKsvNhzgQEj+scYWSS8geozi
+vqSdJCoMmY8hWJh4SY0ED1DjPMoRvE8OotyGoCJovvYQia+gbVneT8JnfV3fkdwi
+hpUmAhokrsHkBj0jp2Ubff/D5yflA+QPCmhZZnkow+5QHXtmpy8CL9Fzfonz5uq7
+yCV5uWRicczFbQw3pDSXKn5OFqXuC8H/8R6Caq2TkJ1LusVtZJevcHBkEQ6e+XEX
+kZ+QCNtHw0a67LQEPtMXSyqZ/zR0roqwT6udUgHhdvZjbbb9GDpTW3u472IY18E+
+bf+npZl9kyuv2kyK1d2IjL45TxjBr7vLbjsP2UsmZvb3Wfb/kiMscvTBcxOL7/WA
+GNJ0XifmJWiDTDC+gUBC7LRN9lG8F7ykrMTtMUNlhow5LpIi0HA8TH58yq3/ulGq
+XWpculy33kcVAFTMGh57r8zq9DwkeW+RWggvHO2422S1bFGmKpizKASTvY6iqo4H
+yKvE9uZ41WaEbpp9WKPIaeup+ynxFpcgwMCKwvs7Yaj+mVexv7CoJ9nrEhMOHDxV
+GRyWDdBoIi08S02JHztZBXp5NZ+hqey5HrO4dhrnV1nVYJmH89KcAlXMfTZ2YHsv
+R2+dm6K8ToaX+Irqbz7Xbv8WG/aAdUqMSWkFEss7OT7VZBUiAdFaWqg0D0wtWSSE
+jZJJs9ISUTClq+97o9BEH2sAebchLFP56nY+Bj/zHBq2qPxTKdKE5BH13KcK1fwO
+eNn8a3SlSEHraa0oV6VjgSoMNdFz7b7b0r/Z8L4PEASJgH+VaGRm2TtuVWFHSqvX
+015UGITk6YgAQ25MTprJc/oAd0dut+aCPtOVElfukYvdrbw1YYQ9tc7kU+AVrzaf
+ytWj2GYR5Slfhle0inKlBvbpLTAHs82bp2Dgy9ZSQzW9/gIvLvCt+Hj0kiSYNcbX
+W7Ai5z2i6XKE7DdQO0Uzt+1bXGK3j2PI+81lCw2ejCFwjdYDWQw9f2nzQ5FgeYwG
+tc6fS4GbJM97n0yH9rj0Jb25AummZGnEL11ytPpC6Nv9cQdCuKDbaWQuQyRMCLEm
+hHaqV6k/fI4Etvuo15pyfJ9w7Xrhc6emgdg2HzJ99lDGkzZAF/3FR7N5pLPk5E0/
+PPlXUSiEx17IeWp3rNt0YSMixkGz+EbKyv9RIZzm/LV4zAzs2ZyUHHavUgZ602eg
+89ppqafaBrCwIWB1jUmnHJop9YlXQ3hE7pAV5qf9GxZLwUdzJcyLte1/vkn1yt94
+nLOZPPWUwUjIaBOZ7e/g8fHBjvAYwyoy3toKVpvkhR48NvcYD8pQ9cB6rIL0JkWV
+nQEYeISlJCUOO3K2eZ3ZH02ftha5gLshcGRXy9NS+4fNxDT3H+102RqSxmKPIxV0
+onV9RyOxUPKLRGjCZBZxs5aSxTYjFJ591azt3yAY4vwCnnHqdNGFbTat/Zc8LUOO
+J26n5cOYFGKPvZVvj8jMNYC1wo+R+A+1FeYXBV4MSVxCB7tjBlbU6OIyZSWLZ8Vw
+LMcPbuZ7ESj1LeTONwS1vspZM8Y/M8+RXv9VA8Z998tnNopdU3izVC2z6Zn9hNNI
+XBDbSe6ZRwsjXrm5TZCBgA4ZE18MwxPVhntSvl87Gc3wF4hz4BOiZXmffrXK4nQJ
+aVA8E2IsriCV+GQBN/ui+w3U9LbtsHrbauhjrru5EfYohpuInwvgPlAnTztdv9u7
+ee8RhwaCa+MInZanD6pRAAcfM6O64CPxHZtfVW6JM42N7wQXijvYzJPVR30F+6o1
+C+KwySuMBOGxOctmzLj938/OMrxuLBOmv3PJvSnHV0pWtbR7r7jH3v0uUm54zH56
+Qo/Rm/Aqf+m4Si3Xtsf9zvc89sqG5v2TT882Joja76zlJfaS31QgbnLTmKtAHtIC
+mqfQPvt1LNEJIiB6FZDHJIW5Ccm7imsixerxCBBoAt/J/dhW6N+cjZ0EWG5NiSoz
+9LmAZv8iWyqK/KvdPXUopQWqkYUvuIyNCYqzTRLKudUMohefNwghvl1gSGp4IMZ/
+4LyrJHi9eCcD9Z65PJsRTua+742N2sdhFfU/C4atOUGSK9x/Dl79Qkgsl6HqAoce
+HXiHAIvoOqC+jzEkjjxow30BzJeGsZoFwNvMUW7HcQ523DiIOx6MX8oQyKEo+W6C
+ayFvvvT3qHu2hL2ZxOXE+rGyUJnmwqctz4ChLvyYXa/eNrycs382x2U5XNXgXzNT
+3bwB9B+LnKSMJEB+UvHdbBcafYyevLptbF5xiiiUA0P3fq61AfmNiCzJWb+kaO11
+oHHQNWyG/fO49u3bZJkhvlsk8GXAp9uTqdW7YAqxjy8NohFewmtpTJPE62XKIqiq
++dqo4nUT761iaUBxgyj1v5jKcXT2JiEMnEe4AN7pZJ01pCNXQrXl+6ru4TVV3tpy
+OsDJ9UfZo8xZXEAJ/gvSyiih0xq6xhwGuUyExC3GldBz2frveWImxVEiqQIdHULH
+WwB6eAm9T1f+2hOGq7AB9Jb8CRyQniJWXtWu9uJBt+XwSt5lN6VUjeLt95SitvjO
+llqs0zhvTf52H8siwaO83Cui78iamqv7jVatB3JYW71S5cOyZ/x5Z5FYqKi8/wjO
+L4OyUs54kfcJllsxAmS014UgcTrJpbMNw7jSzLX6FxT4MEbyARK8wWQfEZQ2tCeo
+IOzfcYvlY05mG0KSzs6ZGBrWRZQDPcbJ0CKNSLTFbQ==
+-----END CERTIFICATE-----
diff --git a/hostsidetests/appsecurity/certs/pkgsigverify/rsa-8192.pk8 b/hostsidetests/appsecurity/certs/pkgsigverify/rsa-8192.pk8
new file mode 100644
index 0000000..cc7a7ec
--- /dev/null
+++ b/hostsidetests/appsecurity/certs/pkgsigverify/rsa-8192.pk8
Binary files differ
diff --git a/hostsidetests/appsecurity/certs/pkgsigverify/rsa-8192.x509.pem b/hostsidetests/appsecurity/certs/pkgsigverify/rsa-8192.x509.pem
new file mode 100644
index 0000000..42f1428
--- /dev/null
+++ b/hostsidetests/appsecurity/certs/pkgsigverify/rsa-8192.x509.pem
@@ -0,0 +1,50 @@
+-----BEGIN CERTIFICATE-----
+MIII+TCCBOGgAwIBAgIJAMMCN6DTJaAOMA0GCSqGSIb3DQEBDQUAMBMxETAPBgNV
+BAMMCHJzYS04MTkyMB4XDTE2MDQwNDE5MzI0NloXDTQzMDgyMTE5MzI0NlowEzER
+MA8GA1UEAwwIcnNhLTgxOTIwggQiMA0GCSqGSIb3DQEBAQUAA4IEDwAwggQKAoIE
+AQCt2gaOPSTn1A/WkapaytoE2RGF5nBzlfLocagG+0Bgz0RH3QQq0xBEmQivmbj4
+egyKFQQ9dYrefXRnayLQvHpfeT31QXR3iKOfMnvtxK9UnkXo9S/T+czyj91Ox51w
+HFUyMlXjFs8btxi6Lpkrgl3jmL+e4/WI8khvTrdszrO8rBHBYlD8Y7SAvPcVczYq
+nn4m6Jd0/abR5slHiyGtkTREoHmW/u4r4PfTzanLyzcsWH9/td+sYHcu1Y0XTWTR
+x2qrUmpD+7X5cvXP9rsECU82dtnyPZPIHBqzfLJ8oGELsJxgVZ0u9gW0tlmJQdVo
+Q0QPJSWivnNxPl1czJYbXimbY3Zh5hCzdyNqQewVx6iNsNh008JsXJ5/yvJQgLgZ
+UR2gWZMGzLc4V2wiqxuLzELt5RoXPehAdAiOLQu/3Fw+u4J/d7NEwpKgpdDGyG/U
+9nV6mjvomcgOdWKblaRAeiXauYy/MgW68kIu4O4SoKWRRmOF2p+tch3aDKw9M89O
+88QhEzbzDsioAxeOAqL7th3bSPZ2fX05xtM2vFK71QFM41q+FOL+062Ev/VJyU4g
+kxK643V+Cxso9CZEVtFfkNnVIGOI2h8knkOiLtbMnCx/hcxuZLm/XvYQxOO/7ScL
+rkHLUuKu/dK2ksDn8yBgaHfVlHkMmVoSll6fKB+UXpPX7xClrGQAFpVUji5oZN0s
++EcMQdcMtsb6LxnwC9XS1ELQ5FQGuJFatwY9RSV3cbwI6kNKaZiB5sDDAaAHX9GU
+U3EA2fm0u+4UFOSSmYTfx/jl0V1NMQ1oOAY9QMqzckMo2y9cepLQ3temQ/k4bNqj
+rYB3POdqS9OoT74UKU8gg9rv01PaFlLHhPKwVc+MjY36aVefbfk1KZzBpm2twUUm
+F0kz4pU3BYj0aSrTeKWaTLjdn4ndGMSe3QMQQ5GUchWCcygTyID8Wx8+eDzPIs/U
+sc++7fQRuPawcd11oQ7wTjWIjr7VnsV8hiHSyMupEad8HuBt8CNtDf/m/hD1LsEf
+0dY8nDGSPvV/ih2YqTfhcac65D4JKKbV5x65aEwM7frYwi9QsB7CK2xLMHnatp2a
+TRcA24VEsaBP2+UNSLyxkOeeuzSCksHLPBWkVfcRbKUeD9x4Dtwf2WsUtYjGzOQ7
+ApLBB4XHe+GPr/i+PmJP4IDoU1Mifbjla8rz2ZuebZgPnyV7nSvkG/FUqUYpa3Ut
+LY0nF/2dDRF0NirbWuB4Mkk/KlxCQ3w8EZFY5u6L/ee23WxbnVOEQJBtKh7/I/UV
+2dGqoVJx2UqT0MpjUCFjx+KjWvaEt+FfmjfRRqQfHLkJlYly/YdeUrGPdGgJNr0C
+csnZkAZmKDo4OVv+wVduHxHfAgMBAAGjUDBOMB0GA1UdDgQWBBRdiMpGc1L++yQc
+MtftoeGuLwJ+PzAfBgNVHSMEGDAWgBRdiMpGc1L++yQcMtftoeGuLwJ+PzAMBgNV
+HRMEBTADAQH/MA0GCSqGSIb3DQEBDQUAA4IEAQBo9lUFyV8jI0IpcQLC7hC0ILxx
+6DsDw/YpMd9lRyujKa//OVJOEO3Z+SalfoLslMPCD1eeJBxgx9/xTMxZUrunOMJu
+Ddxc5RypVwdt6NOUQ3pNYU+Qkp73aZzakm6/i1LQDOxGf1PaZooPqXaKMfyb9CQ+
+M5wR9XsLDAyQPlylft3cWsp7DaPsrcp7Sn5u33TtvCDgfMwbKZrzzmCdAHS52p0A
+czMpDgYxhxCuHPwN6XSAxlrWnfpkOsdKneiVr4aDm1fp61PQg+sOKNCNJCMmUB50
+XFj14qLmvjLERNl2vUfDqoj6DxC9OceioZljzFM2d8/DEC1/YUT8AGYZQt0ISLlq
+QW4e4iIxXxVNKwXvJZMCd3z4XX8SvAOXL0+WrOffgkQQpSr2jBXKFe0BpCUnzVkN
+jw/bVJ89jrqfupExJ6kKTLzI+H2u/7LgZUn9/QlvhWR3IL1nEvCCOPHXTreuUp2U
+KauH7WQU+mzF/K+obzYiaPc53dz0C3JcvWgv5cBbhDUsGsziZLPkR3r5TvpTNF3t
+c3Ky84q7CfOKI+hGN/S+BNSv+TdA5uOG+h8GJ6SAwVpimzguhx2/iRg7OiHmhoy4
+UfsCF/QdoF3cEoSMMzorOIM+szZ+XggJMbtWzIv4NAL2TCKJcpB6t0Uxci6JN6lM
+tnbq78QxeOoJ3D3g6ZQoGvCdKwHcMQunS2MK75j9hckX5hR+0xnH++bI+D3qXaul
+zCOAcMoGpM7WgyzAc3mh9aAJFk1J9OYzpFY34nX2cDMc0xtI2s9p2/8X14ir5suK
+R0rqm3BZewDaQVNtrZCm/sch1I0cN4GomvxZ+2xD43vsZm8QEB2fyTvazg6kW2O9
+G0coUmszwI63f7fVx+wzZZxS24N17lIO36hjBq12SKDz9C3cIOZpPYdcaNxDyiwq
++RojbgUnosJji+xZtyK5Bf1kNB+jNoNT5OrWCXCR62Z5CQ+fAdlz4NPdibYnwscF
+SD8OA2I7UIT42KAuDBEMKVXe4SlhqLzOdqXwZ7h/ZxyUlY+zpwLO9vfLVpqZiavl
+bx+RO7lkvxPGEtM4mjXt5dNx2rgML/lXSE63qaqspYLJ806A3GE0918/b+ZDfvzG
+HLbeqIVtAlXwOGFLdifLvsgFybQ5yriR/yTlHXN/T8K+Q6wPo3uNkKNgUDq0FmzF
+N9UDQ+VFAdwaGPfBox3okGPoD6/HdiokuwZm4mlioHjZc513qhDapS3fJcXV6tu9
+OhIPBJ5NXVw3IVXwB+eskd2W5y8QlHZKBNTwzc/PBqL93QA2PxOFispDtevAuyTq
+OhRConYsMhoLf/9NqhEsyKVhwtYhYrUh0Q+hCiAg+YpjKuE2YJoUNMVyF3dY
+-----END CERTIFICATE-----
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-md5-16384.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-md5-16384.apk
new file mode 100644
index 0000000..3ce1737
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-md5-16384.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-md5-8192.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-md5-8192.apk
new file mode 100644
index 0000000..10f4654
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-md5-8192.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha1-16384.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha1-16384.apk
new file mode 100644
index 0000000..784e569
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha1-16384.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha1-8192.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha1-8192.apk
new file mode 100644
index 0000000..b8f979d
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha1-8192.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha224-16384.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha224-16384.apk
new file mode 100644
index 0000000..7656ece
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha224-16384.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha224-8192.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha224-8192.apk
new file mode 100644
index 0000000..99bcba2
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha224-8192.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha256-16384.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha256-16384.apk
new file mode 100644
index 0000000..21bf67f
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha256-16384.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha256-8192.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha256-8192.apk
new file mode 100644
index 0000000..d8630b6
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha256-8192.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha384-16384.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha384-16384.apk
new file mode 100644
index 0000000..bb0caf0
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha384-16384.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha384-8192.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha384-8192.apk
new file mode 100644
index 0000000..f0b47f6
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha384-8192.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha512-16384.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha512-16384.apk
new file mode 100644
index 0000000..8cf9eba
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha512-16384.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha512-8192.apk b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha512-8192.apk
new file mode 100644
index 0000000..ffa6be1
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v1-only-with-rsa-pkcs1-sha512-8192.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha256-16384.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha256-16384.apk
new file mode 100644
index 0000000..a832366
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha256-16384.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha256-8192.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha256-8192.apk
new file mode 100644
index 0000000..1c9f131
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha256-8192.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha512-16384.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha512-16384.apk
new file mode 100644
index 0000000..2b332b1
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha512-16384.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha512-8192.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha512-8192.apk
new file mode 100644
index 0000000..146534e
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pkcs1-sha512-8192.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pss-sha256-16384.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pss-sha256-16384.apk
new file mode 100644
index 0000000..a205741
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pss-sha256-16384.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pss-sha256-8192.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pss-sha256-8192.apk
new file mode 100644
index 0000000..c879ffe
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pss-sha256-8192.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pss-sha512-16384.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pss-sha512-16384.apk
new file mode 100644
index 0000000..d398584
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pss-sha512-16384.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pss-sha512-8192.apk b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pss-sha512-8192.apk
new file mode 100644
index 0000000..1bdd017
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v2-only-with-rsa-pss-sha512-8192.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/PkgInstallSignatureVerificationTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/PkgInstallSignatureVerificationTest.java
index e3d5817..f6c6f18 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/PkgInstallSignatureVerificationTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/PkgInstallSignatureVerificationTest.java
@@ -40,8 +40,9 @@
 
     private static final String[] DSA_KEY_NAMES = {"1024", "2048", "3072"};
     private static final String[] EC_KEY_NAMES = {"p256", "p384", "p521"};
-    private static final String[] RSA_KEY_NAMES = {"1024", "2048", "3072", "4096"};
-    private static final String[] RSA_KEY_NAMES_2048_AND_LARGER = {"2048", "3072", "4096"};
+    private static final String[] RSA_KEY_NAMES = {"1024", "2048", "3072", "4096", "8192", "16384"};
+    private static final String[] RSA_KEY_NAMES_2048_AND_LARGER =
+            {"2048", "3072", "4096", "8192", "16384"};
 
 
     /** Device under test. */
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/WifiTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/WifiTest.java
index c4c02e8..685ad82 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/WifiTest.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/WifiTest.java
@@ -44,7 +44,7 @@
     private static final String NETWORK_SSID = "com.android.cts.xwde7ktvh8rmjuhr";
 
     // Time duration to allow before assuming that a WiFi operation failed and ceasing to wait.
-    private static final long UPDATE_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(30);
+    private static final long UPDATE_TIMEOUT_MS = TimeUnit.MINUTES.toMillis(5);
     private static final long UPDATE_INTERVAL_MS = TimeUnit.SECONDS.toMillis(1);
 
     // Shared WifiManager instance.
diff --git a/libs/runner/Android.mk b/libs/runner/Android.mk
index 9642f53..15f64a3 100644
--- a/libs/runner/Android.mk
+++ b/libs/runner/Android.mk
@@ -16,9 +16,7 @@
 
 include $(CLEAR_VARS)
 
-LOCAL_SRC_FILES := $(call all-java-files-under, ../../tests/core/runner/src)
-
-LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
+LOCAL_STATIC_JAVA_LIBRARIES := cts-test-runner
 
 LOCAL_MODULE_TAGS := optional
 
diff --git a/tests/accessibilityservice/AndroidManifest.xml b/tests/accessibilityservice/AndroidManifest.xml
index 02477e4..227602f 100644
--- a/tests/accessibilityservice/AndroidManifest.xml
+++ b/tests/accessibilityservice/AndroidManifest.xml
@@ -21,7 +21,7 @@
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
 
-    <application android:theme="@android:style/Theme.Material.NoActionBar">
+    <application android:theme="@android:style/Theme.Holo.NoActionBar">
 
         <uses-library android:name="android.test.runner" />
 
diff --git a/tests/camera/src/android/hardware/camera2/cts/PerformanceTest.java b/tests/camera/src/android/hardware/camera2/cts/PerformanceTest.java
index 9ecdc2d..5c97d5c 100644
--- a/tests/camera/src/android/hardware/camera2/cts/PerformanceTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/PerformanceTest.java
@@ -301,7 +301,7 @@
                     // simulate real scenario (preview runs a bit)
                     waitForNumResults(previewResultListener, NUM_RESULTS_WAIT);
 
-                    stopPreview();
+                    stopPreviewAndDrain();
 
                 }
                 mReportLog.addValues("Camera " + id
diff --git a/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2SurfaceViewTestCase.java b/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2SurfaceViewTestCase.java
index 539304c..76c91aa 100644
--- a/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2SurfaceViewTestCase.java
+++ b/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2SurfaceViewTestCase.java
@@ -216,12 +216,25 @@
     }
 
     /**
-     * Stop preview for current camera device.
+     * Stop preview for current camera device by closing the session.
+     * Does _not_ wait for the device to go idle
      */
     protected void stopPreview() throws Exception {
+        if (VERBOSE) Log.v(TAG, "Stopping preview");
+        // Stop repeat, wait for captures to complete, and disconnect from surfaces
+        mSession.close();
+    }
+
+    /**
+     * Stop preview for current camera device by closing the session and waiting for it to close,
+     * resulting in an idle device.
+     */
+    protected void stopPreviewAndDrain() throws Exception {
         if (VERBOSE) Log.v(TAG, "Stopping preview and waiting for idle");
         // Stop repeat, wait for captures to complete, and disconnect from surfaces
         mSession.close();
+        mSessionListener.getStateWaiter().waitForState(BlockingSessionCallback.SESSION_CLOSED,
+                /*timeoutMs*/WAIT_FOR_RESULT_TIMEOUT_MS);
     }
 
     /**
diff --git a/tests/core/libcore/tests/Android.mk b/tests/core/libcore/tests/Android.mk
index 82ab12e..6429558 100644
--- a/tests/core/libcore/tests/Android.mk
+++ b/tests/core/libcore/tests/Android.mk
@@ -16,6 +16,6 @@
 
 include $(CLEAR_VARS)
 LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.tests
-LOCAL_STATIC_JAVA_LIBRARIES := core-tests
+LOCAL_STATIC_JAVA_LIBRARIES := core-tests mockito-target-minus-junit4
 LOCAL_JAVA_LANGUAGE_VERSION := 1.8
 include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/runner/Android.mk b/tests/core/runner/Android.mk
index 158a1f1..1355512 100644
--- a/tests/core/runner/Android.mk
+++ b/tests/core/runner/Android.mk
@@ -23,12 +23,44 @@
 # include this package in the tests target for continuous testing
 LOCAL_MODULE_TAGS := tests
 
-LOCAL_SRC_FILES := $(call all-java-files-under,src)
-
 LOCAL_PACKAGE_NAME := android.core.tests.runner
 
-LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
+LOCAL_STATIC_JAVA_LIBRARIES := cts-test-runner
 
 LOCAL_JAVA_LANGUAGE_VERSION := 1.8
 
 include $(BUILD_CTSCORE_PACKAGE)
+
+#==========================================================
+# Build the core runner.
+#==========================================================
+
+# Build library
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_SRC_FILES := $(call all-java-files-under,src)
+LOCAL_MODULE := cts-core-test-runner
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    compatibility-device-util \
+    android-support-test \
+    android.test.runner \
+    vogarexpect
+
+LOCAL_JAVA_LANGUAGE_VERSION := 1.8
+
+include $(BUILD_JAVA_LIBRARY)
+
+#==========================================================
+# Build the run listener
+#==========================================================
+
+# Build library
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_SRC_FILES := $(call all-java-files-under,src/com/android/cts/runner)
+LOCAL_MODULE := cts-test-runner
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
+
+include $(BUILD_JAVA_LIBRARY)
diff --git a/tests/tests/icu/src/android/icu/cts/AndroidJUnitRunnerConstants.java b/tests/core/runner/src/com/android/cts/core/runner/AndroidJUnitRunnerConstants.java
similarity index 95%
rename from tests/tests/icu/src/android/icu/cts/AndroidJUnitRunnerConstants.java
rename to tests/core/runner/src/com/android/cts/core/runner/AndroidJUnitRunnerConstants.java
index 24d8819..c6c8504 100644
--- a/tests/tests/icu/src/android/icu/cts/AndroidJUnitRunnerConstants.java
+++ b/tests/core/runner/src/com/android/cts/core/runner/AndroidJUnitRunnerConstants.java
@@ -14,14 +14,14 @@
  * limitations under the License.
  */
 
-package android.icu.cts;
+package com.android.cts.core.runner;
 
 import android.support.test.runner.AndroidJUnitRunner;
 
 /**
  * Constants used to communicate to and from {@link AndroidJUnitRunner}.
  */
-interface AndroidJUnitRunnerConstants {
+public interface AndroidJUnitRunnerConstants {
 
     /**
      * The names of the file containing the names of the tests to run.
@@ -82,5 +82,5 @@
     /**
      * An identifier for tests run using this class.
      */
-    String REPORT_VALUE_ID = "IcuTestRunner";
+    String REPORT_VALUE_ID = "CoreTestRunner";
 }
diff --git a/tests/tests/icu/src/android/icu/cts/IcuTestRunner.java b/tests/core/runner/src/com/android/cts/core/runner/CoreTestRunner.java
similarity index 72%
rename from tests/tests/icu/src/android/icu/cts/IcuTestRunner.java
rename to tests/core/runner/src/com/android/cts/core/runner/CoreTestRunner.java
index 51c4999..144e9e2 100644
--- a/tests/tests/icu/src/android/icu/cts/IcuTestRunner.java
+++ b/tests/core/runner/src/com/android/cts/core/runner/CoreTestRunner.java
@@ -14,21 +14,21 @@
  * limitations under the License.
  */
 
-package android.icu.cts;
+package com.android.cts.core.runner;
 
 import android.app.Activity;
 import android.app.Instrumentation;
-import android.icu.junit.IcuTestRunnerBuilder;
+import com.android.cts.core.runner.support.ExtendedAndroidRunnerBuilder;
 import android.os.Bundle;
 import android.os.Debug;
 import android.support.test.internal.util.AndroidRunnerParams;
 import android.util.Log;
+import com.google.common.base.Splitter;
 import java.io.BufferedReader;
 import java.io.FileReader;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Set;
@@ -45,22 +45,26 @@
 import vogar.ExpectationStore;
 import vogar.ModeId;
 
-import static android.icu.cts.AndroidJUnitRunnerConstants.ARGUMENT_COUNT;
-import static android.icu.cts.AndroidJUnitRunnerConstants.ARGUMENT_DEBUG;
-import static android.icu.cts.AndroidJUnitRunnerConstants.ARGUMENT_LOG_ONLY;
-import static android.icu.cts.AndroidJUnitRunnerConstants.ARGUMENT_TEST_CLASS;
-import static android.icu.cts.AndroidJUnitRunnerConstants.ARGUMENT_TEST_FILE;
+import static com.android.cts.core.runner.AndroidJUnitRunnerConstants.ARGUMENT_COUNT;
+import static com.android.cts.core.runner.AndroidJUnitRunnerConstants.ARGUMENT_DEBUG;
+import static com.android.cts.core.runner.AndroidJUnitRunnerConstants.ARGUMENT_LOG_ONLY;
+import static com.android.cts.core.runner.AndroidJUnitRunnerConstants.ARGUMENT_TEST_CLASS;
+import static com.android.cts.core.runner.AndroidJUnitRunnerConstants.ARGUMENT_TEST_FILE;
 
 /**
  * A drop-in replacement for AndroidJUnitTestRunner, which understands the same arguments, and has
- * similar functionality, but runs ICU tests instead of calling the JUnit wrapper.
+ * similar functionality, but can filter by expectations and allows a custom runner-builder to be
+ * provided.
  */
-public final class IcuTestRunner extends Instrumentation {
+public class CoreTestRunner extends Instrumentation {
 
-    public static final String TAG = "IcuTestRunner";
+    public static final String TAG = "LibcoreTestRunner";
 
-    private static final List<String> EXPECTATIONS_PATHS =
-            Collections.singletonList("expectations/icu-known-failures.txt");
+    private static final java.lang.String ARGUMENT_ROOT_CLASSES = "core-root-classes";
+
+    private static final String ARGUMENT_EXPECTATIONS = "core-expectations";
+
+    private static final Splitter CLASS_LIST_SPLITTER = Splitter.on(',').trimResults();
 
     /** The args for the runner. */
     private Bundle args;
@@ -80,10 +84,10 @@
     /**
      * The list of tests to run.
      */
-    private IcuTestList icuTestList;
+    private TestList testList;
 
     @Override
-    public void onCreate(Bundle args) {
+    public void onCreate(final Bundle args) {
         super.onCreate(args);
         this.args = args;
 
@@ -102,7 +106,9 @@
         this.testCountOnly = args.getBoolean(ARGUMENT_COUNT);
 
         try {
-            Set<String> expectationResources = new LinkedHashSet<>(EXPECTATIONS_PATHS);
+            // Get the set of resource names containing the expectations.
+            Set<String> expectationResources = new LinkedHashSet<>(
+                    CLASS_LIST_SPLITTER.splitToList(args.getString(ARGUMENT_EXPECTATIONS)));
             expectationStore = ExpectationStore.parseResources(
                     getClass(), expectationResources, ModeId.DEVICE);
         } catch (IOException e) {
@@ -131,11 +137,16 @@
         }
 
         if (testNameList == null) {
-            icuTestList = IcuTestList.rootList(Arrays.asList(
-                    "android.icu.cts.coverage.TestAll",
-                    "android.icu.dev.test.TestAll"));
+            String rootClasses = args.getString(ARGUMENT_ROOT_CLASSES);
+            if (rootClasses == null) {
+                throw new IllegalStateException(
+                        "No tests specified, neither exclusive list or root class");
+            } else {
+                List<String> roots = CLASS_LIST_SPLITTER.splitToList(rootClasses);
+                testList = TestList.rootList(roots);
+            }
         } else {
-            icuTestList = IcuTestList.exclusiveList(testNameList);
+            testList = TestList.exclusiveList(testNameList);
         }
 
         start();
@@ -157,15 +168,15 @@
         Request request;
         int totalTestCount;
         try {
-            RunnerBuilder runnerBuilder = new IcuTestRunnerBuilder(runnerParams);
-            Class[] classes = icuTestList.getClassesToRun();
+            RunnerBuilder runnerBuilder = new ExtendedAndroidRunnerBuilder(runnerParams);
+            Class[] classes = testList.getClassesToRun();
             Runner suite = new Computer().getSuite(runnerBuilder, classes);
 
             if (suite instanceof Filterable) {
                 Filterable filterable = (Filterable) suite;
 
                 // Filter out all the tests that are expected to fail.
-                Filter filter = new IcuTestFilter(icuTestList, expectationStore);
+                Filter filter = new TestFilter(testList, expectationStore);
 
                 try {
                     filterable.filter(filter);
@@ -183,17 +194,18 @@
             throw new RuntimeException("Could not create a suite", e);
         }
 
-        IcuRunListener icuRunListener = new IcuRunListener(this, runnerParams, totalTestCount);
-        core.addListener(icuRunListener);
+        StatusUpdaterRunListener statusUpdaterRunListener =
+                new StatusUpdaterRunListener(this, runnerParams, totalTestCount);
+        core.addListener(statusUpdaterRunListener);
         core.run(request);
 
         Bundle results;
         if (testCountOnly) {
-            results = icuRunListener.getCountResults();
+            results = statusUpdaterRunListener.getCountResults();
             Log.d(TAG, "test count only: " + results);
         } else {
             // Get the final results to send back.
-            results = icuRunListener.getFinalResults();
+            results = statusUpdaterRunListener.getFinalResults();
         }
 
         Log.d(TAG, "Finished");
diff --git a/tests/tests/icu/src/android/icu/cts/IcuRunListener.java b/tests/core/runner/src/com/android/cts/core/runner/StatusUpdaterRunListener.java
similarity index 92%
rename from tests/tests/icu/src/android/icu/cts/IcuRunListener.java
rename to tests/core/runner/src/com/android/cts/core/runner/StatusUpdaterRunListener.java
index 0a6f355..429ae92 100644
--- a/tests/tests/icu/src/android/icu/cts/IcuRunListener.java
+++ b/tests/core/runner/src/com/android/cts/core/runner/StatusUpdaterRunListener.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.icu.cts;
+package com.android.cts.core.runner;
 
 import android.app.Instrumentation;
 import android.os.Bundle;
@@ -30,8 +30,8 @@
 
 import static android.app.Instrumentation.REPORT_KEY_IDENTIFIER;
 import static android.app.Instrumentation.REPORT_KEY_STREAMRESULT;
-import static android.icu.cts.AndroidJUnitRunnerConstants.REPORT_KEY_RUNTIME;
-import static android.icu.cts.AndroidJUnitRunnerConstants.REPORT_VALUE_ID;
+import static com.android.cts.core.runner.AndroidJUnitRunnerConstants.REPORT_KEY_RUNTIME;
+import static com.android.cts.core.runner.AndroidJUnitRunnerConstants.REPORT_VALUE_ID;
 import static android.test.InstrumentationTestRunner.REPORT_KEY_NAME_CLASS;
 import static android.test.InstrumentationTestRunner.REPORT_KEY_NAME_TEST;
 import static android.test.InstrumentationTestRunner.REPORT_KEY_NUM_CURRENT;
@@ -47,7 +47,7 @@
  * Listens to result of running tests, collates details and sends intermediate status information
  * back to the host.
  */
-class IcuRunListener extends RunListener {
+class StatusUpdaterRunListener extends RunListener {
 
     /**
      * The {@link Instrumentation} for which this will report information.
@@ -77,7 +77,8 @@
 
     private long testStartTime;
 
-    public IcuRunListener(Instrumentation instrumentation, AndroidRunnerParams runnerParams,
+    public StatusUpdaterRunListener(Instrumentation instrumentation,
+            AndroidRunnerParams runnerParams,
             int totalTestCount) {
         this.instrumentation = instrumentation;
         this.runnerParams = runnerParams;
@@ -135,6 +136,7 @@
         } else {
             resultStatus = REPORT_VALUE_RESULT_ERROR;
         }
+
         String information = failure.getTrace();
         currentTestResult.putString(REPORT_KEY_STACK, information);
         String output = "Error: " + description + "\n" + information;
@@ -165,7 +167,7 @@
 
     public Bundle getFinalResults() {
         int totalTests = totalFailures + totalSuccess;
-        Log.d(IcuTestRunner.TAG, (runnerParams.isSkipExecution() ? "Skipped " : "Ran ")
+        Log.d(CoreTestRunner.TAG, (runnerParams.isSkipExecution() ? "Skipped " : "Ran ")
                 + totalTests + " tests, " + totalSuccess + " passed, " + totalFailures + " failed");
         Bundle results = new Bundle();
         results.putString(REPORT_KEY_IDENTIFIER, REPORT_VALUE_ID);
@@ -189,7 +191,7 @@
     }
 
     public Bundle getCountResults() {
-        Log.d(IcuTestRunner.TAG, "Counted " + (totalFailures + totalSuccess) + " tests, "
+        Log.d(CoreTestRunner.TAG, "Counted " + (totalFailures + totalSuccess) + " tests, "
                 + totalSuccess + " passed, " + totalFailures + " failed");
         Bundle results = new Bundle();
         results.putString(REPORT_KEY_IDENTIFIER, REPORT_VALUE_ID);
diff --git a/tests/tests/icu/src/android/icu/cts/IcuTestFilter.java b/tests/core/runner/src/com/android/cts/core/runner/TestFilter.java
similarity index 90%
rename from tests/tests/icu/src/android/icu/cts/IcuTestFilter.java
rename to tests/core/runner/src/com/android/cts/core/runner/TestFilter.java
index 3da2976..8cadbcf 100644
--- a/tests/tests/icu/src/android/icu/cts/IcuTestFilter.java
+++ b/tests/core/runner/src/com/android/cts/core/runner/TestFilter.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package android.icu.cts;
+package com.android.cts.core.runner;
 
 import android.util.Log;
 import java.util.List;
@@ -61,15 +61,15 @@
  * {@link ParentRunner}, as that would prevent it from traversing the hierarchy and finding
  * the leaf nodes.
  */
-class IcuTestFilter extends Filter {
+class TestFilter extends Filter {
 
     private final ExpectationStore expectationStore;
 
-    private final IcuTestList icuTestList;
+    private final TestList testList;
 
-    public IcuTestFilter(IcuTestList icuTestList, @Nullable ExpectationStore expectationStore) {
+    public TestFilter(TestList testList, @Nullable ExpectationStore expectationStore) {
         this.expectationStore = expectationStore;
-        this.icuTestList = icuTestList;
+        this.testList = testList;
     }
 
     @Override
@@ -84,14 +84,14 @@
             String testName = className + "#" + methodName;
 
             // If the test isn't in the list of tests to run then do not run it.
-            if (!icuTestList.shouldRunTest(testName)) {
+            if (!testList.shouldRunTest(testName)) {
                 return false;
             }
 
             if (expectationStore != null) {
                 Expectation expectation = expectationStore.get(testName);
                 if (expectation.getResult() != Result.SUCCESS) {
-                    Log.d(IcuTestRunner.TAG, "Excluding test " + description
+                    Log.d(CoreTestRunner.TAG, "Excluding test " + testDescription
                             + " as it matches expectation: " + expectation);
                     return false;
                 }
@@ -126,6 +126,6 @@
 
     @Override
     public String describe() {
-        return "IcuTestFilter";
+        return "TestFilter";
     }
 }
diff --git a/tests/tests/icu/src/android/icu/cts/IcuTestList.java b/tests/core/runner/src/com/android/cts/core/runner/TestList.java
similarity index 84%
rename from tests/tests/icu/src/android/icu/cts/IcuTestList.java
rename to tests/core/runner/src/com/android/cts/core/runner/TestList.java
index a9c3c5f..4b0452d 100644
--- a/tests/tests/icu/src/android/icu/cts/IcuTestList.java
+++ b/tests/core/runner/src/com/android/cts/core/runner/TestList.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package android.icu.cts;
+package com.android.cts.core.runner;
 
 import android.util.Log;
 import java.util.ArrayList;
@@ -25,7 +25,7 @@
 /**
  * A list of the tests to run.
  */
-class IcuTestList {
+class TestList {
 
     /**
      * The names of the set of tests to run, if null then all tests should be run.
@@ -35,7 +35,7 @@
 
     private final List<Class<?>> classesToRun;
 
-    public static IcuTestList exclusiveList(List<String> testNameList) {
+    public static TestList exclusiveList(List<String> testNameList) {
         Set<String> classNamesToRun = new LinkedHashSet<>();
         Set<String> testsToRun = new LinkedHashSet<>(testNameList);
 
@@ -50,19 +50,19 @@
             classNamesToRun.add(className);
         }
 
-        Log.d(IcuTestRunner.TAG, "Running only the following tests: " + testsToRun);
-        return new IcuTestList(getClasses(classNamesToRun), testsToRun);
+        Log.d(CoreTestRunner.TAG, "Running only the following tests: " + testsToRun);
+        return new TestList(getClasses(classNamesToRun), testsToRun);
     }
 
-    public static IcuTestList rootList(List<String> rootList) {
+    public static TestList rootList(List<String> rootList) {
 
         // Run from the root test class.
         Set<String> classNamesToRun = new LinkedHashSet<>(rootList);
-        Log.d(IcuTestRunner.TAG, "Running all tests rooted at " + classNamesToRun);
+        Log.d(CoreTestRunner.TAG, "Running all tests rooted at " + classNamesToRun);
 
         List<Class<?>> classesToRun1 = getClasses(classNamesToRun);
 
-        return new IcuTestList(classesToRun1, null);
+        return new TestList(classesToRun1, null);
     }
 
     private static List<Class<?>> getClasses(Set<String> classNames) {
@@ -83,7 +83,7 @@
      * @param testsToRun The exclusive set of tests to run or null if all tests reachable from the
      * classes are to be run.
      */
-    private IcuTestList(List<Class<?>> classes, Set<String> testsToRun) {
+    private TestList(List<Class<?>> classes, Set<String> testsToRun) {
         this.testsToRun = testsToRun;
         this.classesToRun = classes;
     }
diff --git a/tests/core/runner/src/com/android/cts/core/runner/support/AndroidRunnerBuilder.java b/tests/core/runner/src/com/android/cts/core/runner/support/AndroidRunnerBuilder.java
new file mode 100644
index 0000000..bdb3e57
--- /dev/null
+++ b/tests/core/runner/src/com/android/cts/core/runner/support/AndroidRunnerBuilder.java
@@ -0,0 +1,81 @@
+/*
+ * 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 com.android.cts.core.runner.support;
+
+import android.support.test.internal.runner.junit3.AndroidJUnit3Builder;
+import android.support.test.internal.runner.junit3.AndroidSuiteBuilder;
+import android.support.test.internal.runner.junit4.AndroidAnnotatedBuilder;
+import android.support.test.internal.runner.junit4.AndroidJUnit4Builder;
+import android.support.test.internal.util.AndroidRunnerParams;
+
+import org.junit.internal.builders.AllDefaultPossibilitiesBuilder;
+import org.junit.internal.builders.AnnotatedBuilder;
+import org.junit.internal.builders.IgnoredBuilder;
+import org.junit.internal.builders.JUnit3Builder;
+import org.junit.internal.builders.JUnit4Builder;
+import org.junit.runners.model.RunnerBuilder;
+
+/**
+ * A {@link RunnerBuilder} that can handle all types of tests.
+ */
+// A copy of package private class android.support.test.internal.runner.AndroidRunnerBuilder.
+// Copied here so that it can be extended.
+class AndroidRunnerBuilder extends AllDefaultPossibilitiesBuilder {
+
+    private final AndroidJUnit3Builder mAndroidJUnit3Builder;
+    private final AndroidJUnit4Builder mAndroidJUnit4Builder;
+    private final AndroidSuiteBuilder mAndroidSuiteBuilder;
+    private final AndroidAnnotatedBuilder mAndroidAnnotatedBuilder;
+    // TODO: customize for Android ?
+    private final IgnoredBuilder mIgnoredBuilder;
+
+    /**
+     * @param runnerParams {@link AndroidRunnerParams} that stores common runner parameters
+     */
+    AndroidRunnerBuilder(AndroidRunnerParams runnerParams) {
+        super(true);
+        mAndroidJUnit3Builder = new AndroidJUnit3Builder(runnerParams);
+        mAndroidJUnit4Builder = new AndroidJUnit4Builder(runnerParams);
+        mAndroidSuiteBuilder = new AndroidSuiteBuilder(runnerParams);
+        mAndroidAnnotatedBuilder = new AndroidAnnotatedBuilder(this, runnerParams);
+        mIgnoredBuilder = new IgnoredBuilder();
+    }
+
+    @Override
+    protected JUnit4Builder junit4Builder() {
+        return mAndroidJUnit4Builder;
+    }
+
+    @Override
+    protected JUnit3Builder junit3Builder() {
+        return mAndroidJUnit3Builder;
+    }
+
+    @Override
+    protected AnnotatedBuilder annotatedBuilder() {
+        return mAndroidAnnotatedBuilder;
+    }
+
+    @Override
+    protected IgnoredBuilder ignoredBuilder() {
+        return mIgnoredBuilder;
+    }
+
+    @Override
+    protected RunnerBuilder suiteMethodBuilder() {
+        return mAndroidSuiteBuilder;
+    }
+}
diff --git a/tests/core/runner/src/com/android/cts/core/runner/support/ExtendedAndroidAnnotatedBuilder.java b/tests/core/runner/src/com/android/cts/core/runner/support/ExtendedAndroidAnnotatedBuilder.java
new file mode 100644
index 0000000..05c6623
--- /dev/null
+++ b/tests/core/runner/src/com/android/cts/core/runner/support/ExtendedAndroidAnnotatedBuilder.java
@@ -0,0 +1,89 @@
+/*
+ * 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 com.android.cts.core.runner.support;
+
+import android.support.test.internal.runner.junit4.AndroidAnnotatedBuilder;
+import android.support.test.internal.util.AndroidRunnerParams;
+import android.support.test.runner.AndroidJUnit4;
+import junit.framework.TestCase;
+import org.junit.runner.RunWith;
+import org.junit.runner.Runner;
+import org.junit.runners.BlockJUnit4ClassRunner;
+import org.junit.runners.JUnit4;
+import org.junit.runners.model.RunnerBuilder;
+
+/**
+ * Extends {@link AndroidAnnotatedBuilder} to add support for passing the
+ * {@link AndroidRunnerParams} object to the constructor of any {@link RunnerBuilder}
+ * implementation that is not a {@link BlockJUnit4ClassRunner}.
+ *
+ * <p>If {@link AndroidRunnerParams#isSkipExecution()} is {@code true} the super class will create
+ * a {@link RunnerBuilder} that will fire appropriate events as if the tests are being run but will
+ * not actually run the test. Unfortunately, when it does that it appears to assume that the runner
+ * extends {@link BlockJUnit4ClassRunner}, returns a skipping {@link RunnerBuilder} appropriate for
+ * that and ignores the actual {@code runnerClass}. That is a problem because it will not work for
+ * custom {@link RunnerBuilder} instances that do not extend {@link BlockJUnit4ClassRunner}.
+ *
+ * <p>Therefore, when skipping execution this does some additional checks to make sure that the
+ * {@code runnerClass} does extend {@link BlockJUnit4ClassRunner} before calling the overridden
+ * method.
+ *
+ * <p>It then attempts to construct a {@link RunnerBuilder} by calling the constructor with the
+ * signature {@code <init>(Class, AndroidRunnerParams)}. If that doesn't exist it falls back to
+ * the overridden behavior.
+ */
+class ExtendedAndroidAnnotatedBuilder extends AndroidAnnotatedBuilder {
+
+    private final AndroidRunnerParams runnerParams;
+
+    public ExtendedAndroidAnnotatedBuilder(RunnerBuilder suiteBuilder,
+            AndroidRunnerParams runnerParams) {
+        super(suiteBuilder, runnerParams);
+        this.runnerParams = runnerParams;
+    }
+
+    @Override
+    public Runner runnerForClass(Class<?> testClass) throws Exception {
+
+        RunWith annotation = testClass.getAnnotation(RunWith.class);
+        if (annotation != null) {
+            Class<? extends Runner> runnerClass = annotation.value();
+
+            // If the runner is expected to skip execution and it is a JUnit4, AndroidJUnit4 or
+            // a JUnit3 test class then return a special skipping runner.
+            if (runnerParams.isSkipExecution()) {
+                if (runnerClass == AndroidJUnit4.class || runnerClass == JUnit4.class
+                        || TestCase.class.isAssignableFrom(testClass)) {
+                    return super.runnerForClass(testClass);
+                }
+            }
+
+            try {
+                // try to build an AndroidJUnit4 runner
+                Runner runner = buildAndroidRunner(runnerClass, testClass);
+                if (runner != null) {
+                    return runner;
+                }
+            } catch (NoSuchMethodException e) {
+                // let the super class handle the error for us and throw an InitializationError
+                // exception.
+                return super.buildRunner(runnerClass, testClass);
+            }
+        }
+
+        return null;
+    }
+}
diff --git a/tests/core/runner/src/com/android/cts/core/runner/support/ExtendedAndroidRunnerBuilder.java b/tests/core/runner/src/com/android/cts/core/runner/support/ExtendedAndroidRunnerBuilder.java
new file mode 100644
index 0000000..ed16318
--- /dev/null
+++ b/tests/core/runner/src/com/android/cts/core/runner/support/ExtendedAndroidRunnerBuilder.java
@@ -0,0 +1,43 @@
+/*
+ * 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 com.android.cts.core.runner.support;
+
+import android.support.test.internal.runner.junit4.AndroidAnnotatedBuilder;
+import android.support.test.internal.util.AndroidRunnerParams;
+import org.junit.internal.builders.AnnotatedBuilder;
+import org.junit.runners.model.RunnerBuilder;
+
+/**
+ * Extends {@link AndroidRunnerBuilder} in order to provide alternate {@link RunnerBuilder}
+ * implementations.
+ */
+public class ExtendedAndroidRunnerBuilder extends AndroidRunnerBuilder {
+
+    private final AndroidAnnotatedBuilder mAndroidAnnotatedBuilder;
+
+    /**
+     * @param runnerParams {@link AndroidRunnerParams} that stores common runner parameters
+     */
+    public ExtendedAndroidRunnerBuilder(AndroidRunnerParams runnerParams) {
+        super(runnerParams);
+        mAndroidAnnotatedBuilder = new ExtendedAndroidAnnotatedBuilder(this, runnerParams);
+    }
+
+    @Override
+    protected AnnotatedBuilder annotatedBuilder() {
+        return mAndroidAnnotatedBuilder;
+    }
+}
diff --git a/tests/core/runner/src/com/android/cts/core/runner/support/package-info.java b/tests/core/runner/src/com/android/cts/core/runner/support/package-info.java
new file mode 100644
index 0000000..3ccec3c
--- /dev/null
+++ b/tests/core/runner/src/com/android/cts/core/runner/support/package-info.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.
+ */
+
+/**
+ * Contains all the changes needed to the {@code android.support.test.internal.runner} classes.
+ *
+ * <p>As its name suggests {@code android.support.test.internal.runner} are internal classes that
+ * are not designed to be extended from outside those packages. This package encapsulates all the
+ * workarounds needed to overcome that limitation, from duplicating classes to using reflection.
+ * The intention is that these changes are temporary and they (or a better equivalent) will be
+ * quickly integrated into the internal classes.
+ */
+package com.android.cts.core.runner.support;
diff --git a/tests/tests/app/Android.mk b/tests/tests/app/Android.mk
new file mode 100644
index 0000000..08201a6
--- /dev/null
+++ b/tests/tests/app/Android.mk
@@ -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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsAndroidAppTestCases
+
+# don't include this package in any target
+LOCAL_MODULE_TAGS := optional
+
+# and when built explicitly put it in the data partition
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/app/AndroidManifest.xml b/tests/tests/app/AndroidManifest.xml
new file mode 100644
index 0000000..be903e3
--- /dev/null
+++ b/tests/tests/app/AndroidManifest.xml
@@ -0,0 +1,36 @@
+<?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.app.cts">
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+
+        <activity android:name=".ApplyOverrideConfigurationActivity"
+                  android:configChanges="orientation|screenSize" />
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="android.app.cts"
+                     android:label="CTS tests of android.app">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+
+</manifest>
+
diff --git a/tests/tests/app/AndroidTest.xml b/tests/tests/app/AndroidTest.xml
new file mode 100644
index 0000000..739e0ba
--- /dev/null
+++ b/tests/tests/app/AndroidTest.xml
@@ -0,0 +1,25 @@
+<?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.
+-->
+<configuration description="Configuration for app Tests">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsAndroidAppTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.app.cts" />
+        <option name="runtime-hint" value="1s" />
+    </test>
+</configuration>
diff --git a/tests/tests/app/src/android/app/cts/ApplyOverrideConfigurationActivity.java b/tests/tests/app/src/android/app/cts/ApplyOverrideConfigurationActivity.java
new file mode 100644
index 0000000..305d0a8
--- /dev/null
+++ b/tests/tests/app/src/android/app/cts/ApplyOverrideConfigurationActivity.java
@@ -0,0 +1,66 @@
+/*
+ * 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.app.cts;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.res.Configuration;
+
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Future;
+
+public class ApplyOverrideConfigurationActivity extends Activity {
+    public static final int OVERRIDE_SMALLEST_WIDTH = 99999;
+
+    private CompletableFuture<Configuration> mOnConfigurationChangedFuture = null;
+
+    @Override
+    protected void attachBaseContext(Context newBase) {
+        super.attachBaseContext(newBase);
+
+        final Configuration overrideConfig = new Configuration();
+        overrideConfig.smallestScreenWidthDp = OVERRIDE_SMALLEST_WIDTH;
+        applyOverrideConfiguration(overrideConfig);
+    }
+
+    @Override
+    public void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+
+        synchronized (this) {
+            if (mOnConfigurationChangedFuture != null) {
+                mOnConfigurationChangedFuture.complete(new Configuration(newConfig));
+                mOnConfigurationChangedFuture = null;
+            }
+        }
+    }
+
+    /**
+     * Hands back a Future that will be completed when onConfigurationChanged() is called.
+     * It will only report a single call to onConfigurationChanged(). Subsequent calls can be
+     * captured by calling this method again. Calling this method will cancel all past
+     * Futures received from this method.
+     * @return A Future that completes with the configuration passed in to onConfigurationChanged().
+     */
+    public synchronized Future<Configuration> watchForSingleOnConfigurationChangedCallback() {
+        if (mOnConfigurationChangedFuture != null) {
+            mOnConfigurationChangedFuture.cancel(true);
+        }
+
+        mOnConfigurationChangedFuture = new CompletableFuture<>();
+        return mOnConfigurationChangedFuture;
+    }
+}
diff --git a/tests/tests/app/src/android/app/cts/ApplyOverrideConfigurationTest.java b/tests/tests/app/src/android/app/cts/ApplyOverrideConfigurationTest.java
new file mode 100644
index 0000000..a8f1473
--- /dev/null
+++ b/tests/tests/app/src/android/app/cts/ApplyOverrideConfigurationTest.java
@@ -0,0 +1,69 @@
+/*
+ * 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.app.cts;
+
+import android.app.UiAutomation;
+import android.content.res.Configuration;
+import android.support.test.filters.SmallTest;
+import android.test.ActivityInstrumentationTestCase2;
+
+import java.util.concurrent.Future;
+
+/**
+ * Tests the {@link android.view.ContextThemeWrapper#applyOverrideConfiguration(Configuration)}
+ * method and how it affects the Activity's resources and lifecycle callbacks.
+ */
+public class ApplyOverrideConfigurationTest extends
+        ActivityInstrumentationTestCase2<ApplyOverrideConfigurationActivity> {
+    public ApplyOverrideConfigurationTest() {
+        super(ApplyOverrideConfigurationActivity.class);
+    }
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        getInstrumentation().getUiAutomation().setRotation(UiAutomation.ROTATION_FREEZE_0);
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        getInstrumentation().getUiAutomation().setRotation(UiAutomation.ROTATION_UNFREEZE);
+        super.tearDown();
+    }
+
+    @SmallTest
+    public void testOverriddenConfigurationIsPassedIntoCallback() throws Exception {
+        final Configuration config = getActivity().getResources().getConfiguration();
+        final int originalOrientation = config.orientation;
+        assertEquals(ApplyOverrideConfigurationActivity.OVERRIDE_SMALLEST_WIDTH,
+                config.smallestScreenWidthDp);
+
+        Future<Configuration> callback =
+                getActivity().watchForSingleOnConfigurationChangedCallback();
+
+        getInstrumentation().getUiAutomation().setRotation(UiAutomation.ROTATION_FREEZE_90);
+
+        final Configuration callbackConfig = callback.get();
+        assertNotNull(callbackConfig);
+
+        final Configuration newConfig = getActivity().getResources().getConfiguration();
+        assertTrue(newConfig.orientation != originalOrientation);
+        assertEquals(ApplyOverrideConfigurationActivity.OVERRIDE_SMALLEST_WIDTH,
+                newConfig.smallestScreenWidthDp);
+
+        assertEquals(newConfig, callbackConfig);
+    }
+}
diff --git a/tests/tests/content/src/android/content/cts/ContextTest.java b/tests/tests/content/src/android/content/cts/ContextTest.java
index 4cb85cc..0d9c56d 100644
--- a/tests/tests/content/src/android/content/cts/ContextTest.java
+++ b/tests/tests/content/src/android/content/cts/ContextTest.java
@@ -27,15 +27,19 @@
 import android.database.sqlite.SQLiteDatabase;
 import android.test.AndroidTestCase;
 import android.util.AttributeSet;
+import android.util.Log;
 import android.util.Xml;
 import android.view.WindowManager;
 
 import org.xmlpull.v1.XmlPullParserException;
 
 import java.io.File;
+import java.io.FileOutputStream;
 import java.io.IOException;
 
 public class ContextTest extends AndroidTestCase {
+    private static final String TAG = "ContextTest";
+
     private Context mContext;
 
     @Override
@@ -303,6 +307,44 @@
         assertEquals(0xffffff00, color);
     }
 
+    /**
+     * Developers have come to expect at least ext4-style filename behavior, so
+     * verify that the underlying filesystem supports them.
+     */
+    public void testFilenames() throws Exception {
+        final File base = mContext.getFilesDir();
+        assertValidFile(new File(base, "foo"));
+        assertValidFile(new File(base, ".bar"));
+        assertValidFile(new File(base, "foo.bar"));
+        assertValidFile(new File(base, "\u2603"));
+        assertValidFile(new File(base, "\uD83D\uDCA9"));
+
+        final int pid = android.os.Process.myPid();
+        final StringBuilder sb = new StringBuilder(255);
+        while (sb.length() <= 255) {
+            sb.append(pid);
+            sb.append(mContext.getPackageName());
+        }
+        sb.setLength(255);
+
+        final String longName = sb.toString();
+        final File longDir = new File(base, longName);
+        assertValidFile(longDir);
+        longDir.mkdir();
+        final File longFile = new File(longDir, longName);
+        assertValidFile(longFile);
+    }
+
+    private void assertValidFile(File file) throws Exception {
+        Log.d(TAG, "Checking " + file);
+        assertTrue("Failed to create " + file, file.createNewFile());
+        assertTrue("Doesn't exist after create " + file, file.exists());
+        assertTrue("Failed to delete after create " + file, file.delete());
+        new FileOutputStream(file).close();
+        assertTrue("Doesn't exist after stream " + file, file.exists());
+        assertTrue("Failed to delete after stream " + file, file.delete());
+    }
+
     private AttributeSet getAttributeSet(int resourceId) {
         final XmlResourceParser parser = getContext().getResources().getXml(
                 resourceId);
diff --git a/tests/tests/icu/Android.mk b/tests/tests/icu/Android.mk
index 39a4b53..6f183d5 100644
--- a/tests/tests/icu/Android.mk
+++ b/tests/tests/icu/Android.mk
@@ -31,9 +31,7 @@
 # The aim of this package is to run tests against the implementation in use by
 # the current android system.
 LOCAL_STATIC_JAVA_LIBRARIES := \
-	compatibility-device-util \
-	android-support-test \
-	vogarexpect \
+	cts-core-test-runner \
 	android-icu4j-tests
 
 # Tag this module as a cts test artifact
diff --git a/tests/tests/icu/AndroidManifest.xml b/tests/tests/icu/AndroidManifest.xml
index 7d99c0a..c743375 100644
--- a/tests/tests/icu/AndroidManifest.xml
+++ b/tests/tests/icu/AndroidManifest.xml
@@ -22,7 +22,7 @@
         <uses-library android:name="android.test.runner" />
     </application>
 
-    <instrumentation android:name="android.icu.cts.IcuTestRunner"
+    <instrumentation android:name="com.android.cts.core.runner.CoreTestRunner"
                      android:targetPackage="android.icu.cts"
-                     android:label="ICU4J library tests."/>
+                     android:label="CTS Repackaged ICU4J library tests."/>
 </manifest>
diff --git a/tests/tests/icu/AndroidTest.xml b/tests/tests/icu/AndroidTest.xml
index 18c95cd..769b789 100644
--- a/tests/tests/icu/AndroidTest.xml
+++ b/tests/tests/icu/AndroidTest.xml
@@ -18,8 +18,13 @@
         <option name="test-file-name" value="CtsIcuTestCases.apk" />
     </target_preparer>
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
-        <option name="runner" value="android.icu.cts.IcuTestRunner" /><!-- override AJUR -->
+        <!-- override AJUR -->
+        <option name="runner" value="com.android.cts.core.runner.CoreTestRunner" />
         <option name="package" value="android.icu.cts" />
+        <option name="instrumentation-arg" key="core-root-classes"
+                value="android.icu.cts.coverage.TestAll,android.icu.dev.test.TestAll" />
+        <option name="instrumentation-arg" key="core-expectations"
+                value="/android/icu/cts/expectations/icu-known-failures.txt" />
         <option name="runtime-hint" value="30m19s" />
     </test>
 </configuration>
diff --git a/tests/tests/location/src/android/location/cts/GnssMeasurementRegistrationTest.java b/tests/tests/location/src/android/location/cts/GnssMeasurementRegistrationTest.java
index 42e555d..d3a310e 100644
--- a/tests/tests/location/src/android/location/cts/GnssMeasurementRegistrationTest.java
+++ b/tests/tests/location/src/android/location/cts/GnssMeasurementRegistrationTest.java
@@ -92,7 +92,7 @@
         mMeasurementListener = new TestGnssMeasurementListener(TAG, GPS_EVENTS_COUNT);
         mTestLocationManager.registerGnssMeasurementCallback(mMeasurementListener);
 
-        assertTrue(mMeasurementListener.await());
+        mMeasurementListener.await();
         if (!mMeasurementListener.verifyState()) {
             return;
         }
@@ -113,8 +113,7 @@
         mTestLocationManager.requestLocationUpdates(mLocationListener);
 
         // Wait for location updates
-        assertTrue(mLocationListener.await());
-
+        mLocationListener.await();
         Log.i(TAG, "Location received = " + mLocationListener.isLocationReceived());
 
         // Register for Gps Status updates
@@ -122,8 +121,7 @@
         mTestLocationManager.addGpsStatusListener(mGpsStatusListener);
 
         // wait for Gps Status updates
-        assertTrue(mGpsStatusListener.await());
-
+        mGpsStatusListener.await();
         if (!mGpsStatusListener.isGpsStatusReceived()) {
             // Skip the Test. No Satellites are visible. Device may be Indoor
             Log.i(TAG, "No Satellites are visible. Device may be Indoor. Skipping Test.");
diff --git a/tests/tests/location/src/android/location/cts/GnssMeasurementWhenNoLocationTest.java b/tests/tests/location/src/android/location/cts/GnssMeasurementWhenNoLocationTest.java
index b3cb0ab..6752a34 100644
--- a/tests/tests/location/src/android/location/cts/GnssMeasurementWhenNoLocationTest.java
+++ b/tests/tests/location/src/android/location/cts/GnssMeasurementWhenNoLocationTest.java
@@ -115,7 +115,7 @@
         mTestLocationManager.requestLocationUpdates(mLocationListener);
 
         // Wait for Gps Status updates.
-        assertTrue(mGpsStatusListener.await());
+        mGpsStatusListener.await();
         if (!mMeasurementListener.verifyState()) {
             return;
         }
diff --git a/tests/tests/location/src/android/location/cts/GnssNavigationMessageRegistrationTest.java b/tests/tests/location/src/android/location/cts/GnssNavigationMessageRegistrationTest.java
index 4b87919..0b40d53 100644
--- a/tests/tests/location/src/android/location/cts/GnssNavigationMessageRegistrationTest.java
+++ b/tests/tests/location/src/android/location/cts/GnssNavigationMessageRegistrationTest.java
@@ -93,7 +93,7 @@
                 new TestGnssNavigationMessageListener(TAG, EVENTS_COUNT);
         mTestLocationManager.registerGnssNavigationMessageCallback(mTestGnssNavigationMessageListener);
 
-        assertTrue(mTestGnssNavigationMessageListener.await());
+        mTestGnssNavigationMessageListener.await();
         if (!mTestGnssNavigationMessageListener.verifyState()) {
             return;
         }
@@ -116,8 +116,7 @@
         mTestLocationManager.requestLocationUpdates(mLocationListener);
 
         // Wait for location updates
-        assertTrue(mLocationListener.await());
-
+        mLocationListener.await();
         Log.i(TAG, "Location received = " + mLocationListener.isLocationReceived());
 
         // Register for Gps Status updates
@@ -125,8 +124,7 @@
         mTestLocationManager.addGpsStatusListener(mGpsStatusListener);
 
         // Wait for Gps Status updates
-        assertTrue(mGpsStatusListener.await());
-
+        mGpsStatusListener.await();
         if (!mGpsStatusListener.isGpsStatusReceived()) {
             // Skip the Test. No Satellites are visible. Device may be Indoor
             Log.i(TAG, "No Satellites are visible. Device may be Indoor. Skipping Test.");
diff --git a/tests/tests/location/src/android/location/cts/GnssNavigationMessageTest.java b/tests/tests/location/src/android/location/cts/GnssNavigationMessageTest.java
index 262232e..032c090 100644
--- a/tests/tests/location/src/android/location/cts/GnssNavigationMessageTest.java
+++ b/tests/tests/location/src/android/location/cts/GnssNavigationMessageTest.java
@@ -77,7 +77,7 @@
                 new TestGnssNavigationMessageListener(TAG, EVENTS_COUNT);
         mTestLocationManager.registerGnssNavigationMessageCallback(mTestGnssNavigationMessageListener);
 
-        assertTrue(mTestGnssNavigationMessageListener.await());
+        mTestGnssNavigationMessageListener.await();
         if (!mTestGnssNavigationMessageListener.verifyState()) {
             return;
         }
diff --git a/tests/tests/location/src/android/location/cts/TestUtils.java b/tests/tests/location/src/android/location/cts/TestUtils.java
index 61f63d9..82d644e 100644
--- a/tests/tests/location/src/android/location/cts/TestUtils.java
+++ b/tests/tests/location/src/android/location/cts/TestUtils.java
@@ -22,7 +22,7 @@
 public class TestUtils {
     private static final long STANDARD_WAIT_TIME_MS = 50;
     private static final long STANDARD_SLEEP_TIME_MS = 50;
-    private static final long STANDARD_WAIT_TIME_ROUNDS = 3000;
+    private static final long STANDARD_WAIT_TIME_ROUNDS = 1200;
 
     public static boolean waitFor(CountDownLatch latch) throws InterruptedException {
         // Since late 2014, if the main thread has been occupied for long enough, Android will
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayerTest.java b/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
index 1d0ab26..4eaefc3 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
@@ -688,55 +688,63 @@
     }
 
     private void testGapless(int resid1, int resid2) throws Exception {
-
-        MediaPlayer mp1 = new MediaPlayer();
-        mp1.setAudioStreamType(AudioManager.STREAM_MUSIC);
+        MediaPlayer mp1 = null;
+        MediaPlayer mp2 = null;
+        AudioEffect vc = null;
+        Visualizer vis = null;
+        AudioManager am = null;
+        int oldRingerMode = Integer.MIN_VALUE;
+        int oldVolume = Integer.MIN_VALUE;
         try {
+            Utils.toggleNotificationPolicyAccess(
+                    mContext.getPackageName(), getInstrumentation(), true /* on */);
+
+            mp1 = new MediaPlayer();
+            mp1.setAudioStreamType(AudioManager.STREAM_MUSIC);
+
             AssetFileDescriptor afd = mContext.getResources().openRawResourceFd(resid1);
             mp1.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
             afd.close();
             mp1.prepare();
-        } catch (Exception e) {
-            assertTrue(false);
-        }
-        int session = mp1.getAudioSessionId();
 
-        MediaPlayer mp2 = new MediaPlayer();
-        mp2.setAudioSessionId(session);
-        mp2.setAudioStreamType(AudioManager.STREAM_MUSIC);
-        try {
-            AssetFileDescriptor afd = mContext.getResources().openRawResourceFd(resid2);
+            int session = mp1.getAudioSessionId();
+
+            mp2 = new MediaPlayer();
+            mp2.setAudioSessionId(session);
+            mp2.setAudioStreamType(AudioManager.STREAM_MUSIC);
+
+            afd = mContext.getResources().openRawResourceFd(resid2);
             mp2.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
             afd.close();
             mp2.prepare();
-        } catch (Exception e) {
-            assertTrue(false);
-        }
-        // creating a volume controller on output mix ensures that ro.audio.silent mutes
-        // audio after the effects and not before
-        AudioEffect vc = new AudioEffect(
+
+            // creating a volume controller on output mix ensures that ro.audio.silent mutes
+            // audio after the effects and not before
+            vc = new AudioEffect(
                             AudioEffect.EFFECT_TYPE_NULL,
                             UUID.fromString("119341a0-8469-11df-81f9-0002a5d5c51b"),
                             0,
                             session);
-        vc.setEnabled(true);
-        int captureintervalms = mp1.getDuration() + mp2.getDuration() - 2000;
-        int size = 256;
-        int[] range = Visualizer.getCaptureSizeRange();
-        if (size < range[0]) {
-            size = range[0];
-        }
-        if (size > range[1]) {
-            size = range[1];
-        }
-        byte [] vizdata = new byte[size];
-        Visualizer vis = new Visualizer(session);
-        AudioManager am = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
-        int oldRingerMode = am.getRingerMode();
-        am.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
-        int oldvolume = am.getStreamVolume(AudioManager.STREAM_MUSIC);
-        am.setStreamVolume(AudioManager.STREAM_MUSIC, 1, 0);
-        try {
+            vc.setEnabled(true);
+            int captureintervalms = mp1.getDuration() + mp2.getDuration() - 2000;
+            int size = 256;
+            int[] range = Visualizer.getCaptureSizeRange();
+            if (size < range[0]) {
+                size = range[0];
+            }
+            if (size > range[1]) {
+                size = range[1];
+            }
+            byte[] vizdata = new byte[size];
+
+            vis = new Visualizer(session);
+            am = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
+            oldRingerMode = am.getRingerMode();
+            // make sure we aren't in silent mode
+            am.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
+            oldVolume = am.getStreamVolume(AudioManager.STREAM_MUSIC);
+            am.setStreamVolume(AudioManager.STREAM_MUSIC, 1, 0);
+
             assertEquals("setCaptureSize failed",
                     Visualizer.SUCCESS, vis.setCaptureSize(vizdata.length));
             assertEquals("setEnabled failed", Visualizer.SUCCESS, vis.setEnabled(true));
@@ -770,12 +778,26 @@
                 first = false;
             }
         } finally {
-            mp1.release();
-            mp2.release();
-            vis.release();
-            vc.release();
-            am.setRingerMode(oldRingerMode);
-            am.setStreamVolume(AudioManager.STREAM_MUSIC, oldvolume, 0);
+            if (mp1 != null) {
+                mp1.release();
+            }
+            if (mp2 != null) {
+                mp2.release();
+            }
+            if (vis != null) {
+                vis.release();
+            }
+            if (vc != null) {
+                vc.release();
+            }
+            if (oldRingerMode != Integer.MIN_VALUE) {
+                am.setRingerMode(oldRingerMode);
+            }
+            if (oldVolume != Integer.MIN_VALUE) {
+                am.setStreamVolume(AudioManager.STREAM_MUSIC, oldVolume, 0);
+            }
+            Utils.toggleNotificationPolicyAccess(
+                    mContext.getPackageName(), getInstrumentation(), false  /* on == false */);
         }
     }
 
diff --git a/tests/tests/media/src/android/media/cts/MediaScannerConnectionTest.java b/tests/tests/media/src/android/media/cts/MediaScannerConnectionTest.java
index 0272298..952e03f 100644
--- a/tests/tests/media/src/android/media/cts/MediaScannerConnectionTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaScannerConnectionTest.java
@@ -48,10 +48,10 @@
 
         FileCopyHelper copier = new FileCopyHelper(mContext);
         String fileName = "test" + System.currentTimeMillis();
-        copier.copy(R.raw.testmp3, fileName);
-
-        File dir = getContext().getFilesDir();
+        File dir = getContext().getExternalFilesDir(null);
         mMediaFile = new File(dir, fileName);
+        copier.copyToExternalStorage(R.raw.testmp3, mMediaFile);
+
         assertTrue(mMediaFile.exists());
     }
 
diff --git a/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java
index 9a99c22..6ed4368 100644
--- a/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java
+++ b/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java
@@ -265,13 +265,16 @@
         }
 
         // We will register for a WIFI network being available or lost.
-        NetworkRequest request = new NetworkRequest.Builder()
+        final NetworkRequest request = new NetworkRequest.Builder()
                 .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
                 .build();
-        TestNetworkCallback callback = new TestNetworkCallback();
+        final TestNetworkCallback callback = new TestNetworkCallback();
         mCm.registerNetworkCallback(request, callback);
 
-        boolean previousWifiEnabledState = mWifiManager.isWifiEnabled();
+        final TestNetworkCallback defaultTrackingCallback = new TestNetworkCallback();
+        mCm.registerDefaultNetworkCallback(defaultTrackingCallback);
+
+        final boolean previousWifiEnabledState = mWifiManager.isWifiEnabled();
 
         try {
             // Make sure WiFi is connected to an access point to start with.
@@ -284,12 +287,16 @@
             // is registered.
             assertTrue("Did not receive NetworkCallback.onAvailable for TRANSPORT_WIFI",
                     callback.waitForAvailable());
+
+            assertTrue("Did not receive NetworkCallback.onAvailable for any default network",
+                    defaultTrackingCallback.waitForAvailable());
         } catch (InterruptedException e) {
             fail("Broadcast receiver or NetworkCallback wait was interrupted.");
         } finally {
             mCm.unregisterNetworkCallback(callback);
+            mCm.unregisterNetworkCallback(defaultTrackingCallback);
 
-            // Return WiFI to its original enabled/disabled state.
+            // Return WiFi to its original enabled/disabled state.
             if (!previousWifiEnabledState) {
                 disconnectFromWifi();
             }
@@ -327,7 +334,7 @@
                 .build();
         mCm.registerNetworkCallback(request, pendingIntent);
 
-        boolean previousWifiEnabledState = mWifiManager.isWifiEnabled();
+        final boolean previousWifiEnabledState = mWifiManager.isWifiEnabled();
 
         try {
             // Make sure WiFi is connected to an access point to start with.
@@ -347,7 +354,7 @@
             pendingIntent.cancel();
             mContext.unregisterReceiver(receiver);
 
-            // Return WiFI to its original enabled/disabled state.
+            // Return WiFi to its original enabled/disabled state.
             if (!previousWifiEnabledState) {
                 disconnectFromWifi();
             }
diff --git a/tests/tests/os/src/android/os/cts/BuildTest.java b/tests/tests/os/src/android/os/cts/BuildTest.java
index 26b07f1..a0446bf 100644
--- a/tests/tests/os/src/android/os/cts/BuildTest.java
+++ b/tests/tests/os/src/android/os/cts/BuildTest.java
@@ -38,15 +38,15 @@
 
     /** Tests that check the values of {@link Build#CPU_ABI} and {@link Build#CPU_ABI2}. */
     public void testCpuAbi() throws Exception {
-        testCpuAbiCommon();
+        runTestCpuAbiCommon();
         if (VMRuntime.getRuntime().is64Bit()) {
-            testCpuAbi64();
+            runTestCpuAbi64();
         } else {
-            testCpuAbi32();
+            runTestCpuAbi32();
         }
     }
 
-    private void testCpuAbiCommon() throws Exception {
+    private void runTestCpuAbiCommon() throws Exception {
         // The build property must match Build.SUPPORTED_ABIS exactly.
         final String[] abiListProperty = getStringList(RO_PRODUCT_CPU_ABILIST);
         assertEquals(Arrays.toString(abiListProperty), Arrays.toString(Build.SUPPORTED_ABIS));
@@ -75,7 +75,7 @@
         }
     }
 
-    private void testCpuAbi32() throws Exception {
+    private void runTestCpuAbi32() throws Exception {
         List<String> abi32 = Arrays.asList(Build.SUPPORTED_32_BIT_ABIS);
         assertTrue(abi32.contains(Build.CPU_ABI));
 
@@ -84,7 +84,7 @@
         }
     }
 
-    private void testCpuAbi64() {
+    private void runTestCpuAbi64() {
         List<String> abi64 = Arrays.asList(Build.SUPPORTED_64_BIT_ABIS);
         assertTrue(abi64.contains(Build.CPU_ABI));
 
diff --git a/tests/tests/provider/src/android/provider/cts/BlockedNumberBackupRestoreTest.java b/tests/tests/provider/src/android/provider/cts/BlockedNumberBackupRestoreTest.java
index 5ea4caf..adf558b 100644
--- a/tests/tests/provider/src/android/provider/cts/BlockedNumberBackupRestoreTest.java
+++ b/tests/tests/provider/src/android/provider/cts/BlockedNumberBackupRestoreTest.java
@@ -42,6 +42,7 @@
     private Context mContext;
     private UiAutomation mUiAutomation;
     private String mOldTransport;
+    private boolean mOldBackupEnabled;
     private boolean mHasFeature;
 
     @Override
@@ -59,6 +60,7 @@
 
             mOldTransport = ProviderTestUtils.setBackupTransport(
                     LOCAL_BACKUP_COMPONENT, mUiAutomation);
+            mOldBackupEnabled = ProviderTestUtils.setBackupEnabled(true, mUiAutomation);
             clearBlockedNumbers();
             wipeBackup();
         }
@@ -69,6 +71,7 @@
         if (mHasFeature) {
             wipeBackup();
             clearBlockedNumbers();
+            ProviderTestUtils.setBackupEnabled(mOldBackupEnabled, mUiAutomation);
             ProviderTestUtils.setBackupTransport(mOldTransport, mUiAutomation);
             ProviderTestUtils.setDefaultSmsApp(false, mContext.getPackageName(), mUiAutomation);
         }
diff --git a/tests/tests/provider/src/android/provider/cts/ProviderTestUtils.java b/tests/tests/provider/src/android/provider/cts/ProviderTestUtils.java
index 874a0a7..e2ed68d 100644
--- a/tests/tests/provider/src/android/provider/cts/ProviderTestUtils.java
+++ b/tests/tests/provider/src/android/provider/cts/ProviderTestUtils.java
@@ -34,7 +34,9 @@
  */
 public class ProviderTestUtils {
 
-    static final int BACKUP_TIMEOUT_MILLIS = 4000;
+    private static final int BACKUP_TIMEOUT_MILLIS = 4000;
+    private static final Pattern BMGR_ENABLED_PATTERN = Pattern.compile(
+            "^Backup Manager currently (enabled|disabled)$");
 
     static void setDefaultSmsApp(boolean setToSmsApp, String packageName, UiAutomation uiAutomation)
             throws Exception {
@@ -73,6 +75,22 @@
         }
     }
 
+    static boolean setBackupEnabled(boolean enable, UiAutomation uiAutomation) throws Exception {
+        // Check to see the previous state of the backup service
+        boolean previouslyEnabled = false;
+        String output = executeShellCommand("bmgr enabled", uiAutomation);
+        Matcher matcher = BMGR_ENABLED_PATTERN.matcher(output.trim());
+        if (matcher.find()) {
+            previouslyEnabled = "enabled".equals(matcher.group(1));
+        } else {
+            throw new RuntimeException("Backup output format changed.  No longer matches"
+                    + " expected regex: " + BMGR_ENABLED_PATTERN + "\nactual: '" + output + "'");
+        }
+
+        executeShellCommand("bmgr enable " + enable, uiAutomation);
+        return previouslyEnabled;
+    }
+
     static boolean hasBackupTransport(String transport, UiAutomation uiAutomation)
             throws Exception {
         String output = executeShellCommand("bmgr list transports", uiAutomation);
diff --git a/tests/tests/provider/src/android/provider/cts/SmsBackupRestoreTest.java b/tests/tests/provider/src/android/provider/cts/SmsBackupRestoreTest.java
index f5e3033..fad1019 100644
--- a/tests/tests/provider/src/android/provider/cts/SmsBackupRestoreTest.java
+++ b/tests/tests/provider/src/android/provider/cts/SmsBackupRestoreTest.java
@@ -24,6 +24,7 @@
 import android.content.ContentUris;
 import android.content.ContentValues;
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.database.Cursor;
 import android.net.Uri;
 import android.provider.BaseColumns;
@@ -65,6 +66,8 @@
     private ContentResolver mContentResolver;
     private UiAutomation mUiAutomation;
     private String mOldTransport;
+    private boolean mOldBackupEnabled;
+    private boolean mHasFeature;
 
     @Override
     protected void setUp() throws Exception {
@@ -74,21 +77,35 @@
         mContext = getInstrumentation().getContext();
         mContentResolver = mContext.getContentResolver();
         mUiAutomation = getInstrumentation().getUiAutomation();
-        ProviderTestUtils.setDefaultSmsApp(true, mContext.getPackageName(), mUiAutomation);
-        mOldTransport = ProviderTestUtils.setBackupTransport(LOCAL_BACKUP_COMPONENT, mUiAutomation);
-        clearMessages();
-        wipeBackup();
+        mHasFeature = isFeatureSupported();
+        if (mHasFeature) {
+            ProviderTestUtils.setDefaultSmsApp(true, mContext.getPackageName(), mUiAutomation);
+            mOldTransport =
+                    ProviderTestUtils.setBackupTransport(LOCAL_BACKUP_COMPONENT, mUiAutomation);
+            mOldBackupEnabled = ProviderTestUtils.setBackupEnabled(true, mUiAutomation);
+            clearMessages();
+            wipeBackup();
+        }
     }
 
     @Override
     protected void tearDown() throws Exception {
-        wipeBackup();
-        clearMessages();
-        ProviderTestUtils.setBackupTransport(mOldTransport, mUiAutomation);
-        ProviderTestUtils.setDefaultSmsApp(false, mContext.getPackageName(), mUiAutomation);
+        if (mHasFeature) {
+            wipeBackup();
+            clearMessages();
+            ProviderTestUtils.setBackupEnabled(mOldBackupEnabled, mUiAutomation);
+            ProviderTestUtils.setBackupTransport(mOldTransport, mUiAutomation);
+            ProviderTestUtils.setDefaultSmsApp(false, mContext.getPackageName(), mUiAutomation);
+        }
+
         super.tearDown();
     }
 
+    private boolean isFeatureSupported() throws Exception {
+        return (ProviderTestUtils.hasBackupTransport(LOCAL_BACKUP_COMPONENT, mUiAutomation)
+                && mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY));
+    }
+
     private void clearMessages() {
         mContentResolver.delete(Telephony.Sms.CONTENT_URI, SMS_SELECTION, smsAddressBody1);
         mContentResolver.delete(Telephony.Sms.CONTENT_URI, SMS_SELECTION, smsAddressBody2);
@@ -117,8 +134,9 @@
      * @throws Exception
      */
     public void testSmsBackupRestore() throws Exception {
-        if (!ProviderTestUtils.hasBackupTransport(LOCAL_BACKUP_COMPONENT, mUiAutomation)) {
+        if (!mHasFeature) {
             Log.i(TAG, "skipping testSmsBackupRestore");
+            return;
         }
 
         ContentValues smsContentValues[] = new ContentValues[] {
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/reduce.rs b/tests/tests/renderscript/src/android/renderscript/cts/reduce.rs
index c30cb9c..d731561 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/reduce.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/reduce.rs
@@ -375,7 +375,7 @@
 }
 
 static void fz3Combine(int3 *accum, const int3 *accum2) {
-  if (accum->x >= 0) *accum = *accum2;
+  if (accum2->x >= 0) *accum = *accum2;
 }
 
 /////////////////////////////////////////////////////////////////////////
diff --git a/tests/tests/security/jni/Android.mk b/tests/tests/security/jni/Android.mk
index cc182b3..d39ac7e 100644
--- a/tests/tests/security/jni/Android.mk
+++ b/tests/tests/security/jni/Android.mk
@@ -26,23 +26,16 @@
 		android_security_cts_CharDeviceTest.cpp \
 		android_security_cts_KernelSettingsTest.cpp \
 		android_security_cts_LinuxRngTest.cpp \
-		android_security_cts_LoadEffectLibraryTest.cpp \
 		android_security_cts_NativeCodeTest.cpp \
 		android_security_cts_SELinuxTest.cpp \
 		android_security_cts_MMapExecutableTest.cpp \
-		android_security_cts_AudioPolicyBinderTest.cpp \
 		android_security_cts_EncryptionTest.cpp \
-		android_security_cts_AudioFlingerBinderTest.cpp \
-		android_security_cts_AudioEffectBinderTest.cpp \
-		android_security_cts_MediaPlayerInfoLeakTest.cpp \
-		android_security_cts_GraphicBufferInfoLeakTest.cpp
 
 LOCAL_C_INCLUDES := $(JNI_H_INCLUDE) \
 										$(TOP)/frameworks/native/include/media/openmax
 
 LOCAL_SHARED_LIBRARIES := libnativehelper \
 		liblog \
-		libbinder \
 		libutils \
 		libmedia \
 		libselinux \
diff --git a/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp b/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp
index 24c87b1..198baa00 100644
--- a/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp
+++ b/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp
@@ -21,15 +21,9 @@
 extern int register_android_security_cts_CharDeviceTest(JNIEnv*);
 extern int register_android_security_cts_LinuxRngTest(JNIEnv*);
 extern int register_android_security_cts_NativeCodeTest(JNIEnv*);
-extern int register_android_security_cts_LoadEffectLibraryTest(JNIEnv*);
 extern int register_android_security_cts_SELinuxTest(JNIEnv*);
 extern int register_android_security_cts_MMapExecutableTest(JNIEnv* env);
-extern int register_android_security_cts_AudioPolicyBinderTest(JNIEnv* env);
-extern int register_android_security_cts_AudioFlingerBinderTest(JNIEnv* env);
 extern int register_android_security_cts_EncryptionTest(JNIEnv* env);
-extern int register_android_security_cts_AudioEffectBinderTest(JNIEnv* env);
-extern int register_android_security_cts_MediaPlayerInfoLeakTest(JNIEnv* env);
-extern int register_android_security_cts_GraphicBufferInfoLeakTest(JNIEnv* env);
 
 jint JNI_OnLoad(JavaVM *vm, void *reserved) {
     JNIEnv *env = NULL;
@@ -50,10 +44,6 @@
         return JNI_ERR;
     }
 
-    if (register_android_security_cts_LoadEffectLibraryTest(env)) {
-        return JNI_ERR;
-    }
-
     if (register_android_security_cts_SELinuxTest(env)) {
         return JNI_ERR;
     }
@@ -66,33 +56,9 @@
         return JNI_ERR;
     }
 
-    if (register_android_security_cts_AudioPolicyBinderTest(env)) {
-        return JNI_ERR;
-    }
-
     if (register_android_security_cts_EncryptionTest(env)) {
         return JNI_ERR;
     }
 
-    if (register_android_security_cts_AudioFlingerBinderTest(env)) {
-        return JNI_ERR;
-    }
-
-    if (register_android_security_cts_AudioEffectBinderTest(env)) {
-        return JNI_ERR;
-    }
-
-    if (register_android_security_cts_MediaPlayerInfoLeakTest(env)) {
-        return JNI_ERR;
-    }
-
-    if (register_android_security_cts_AudioFlingerBinderTest(env)) {
-        return JNI_ERR;
-    }
-
-    if (register_android_security_cts_GraphicBufferInfoLeakTest(env)) {
-        return JNI_ERR;
-    }
-
     return JNI_VERSION_1_4;
 }
diff --git a/tests/tests/security/jni/android_security_cts_AudioEffectBinderTest.cpp b/tests/tests/security/jni/android_security_cts_AudioEffectBinderTest.cpp
deleted file mode 100644
index 6e94fce..0000000
--- a/tests/tests/security/jni/android_security_cts_AudioEffectBinderTest.cpp
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * 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.
- */
-
-#define LOG_TAG "AudioEffectBinderTest-JNI"
-
-#include <jni.h>
-#include <media/AudioEffect.h>
-#include <media/IEffect.h>
-
-using namespace android;
-
-/*
- * Native methods used by
- * cts/tests/tests/security/src/android/security/cts/AudioEffectBinderTest.java
- */
-
-struct EffectClient : public BnEffectClient {
-    EffectClient() { }
-    virtual void controlStatusChanged(bool controlGranted __unused) { }
-    virtual void enableStatusChanged(bool enabled __unused) { }
-    virtual void commandExecuted(uint32_t cmdCode __unused,
-            uint32_t cmdSize __unused,
-            void *pCmdData __unused,
-            uint32_t replySize __unused,
-            void *pReplyData __unused) { }
-};
-
-struct DeathRecipient : public IBinder::DeathRecipient {
-    DeathRecipient() : mDied(false) { }
-    virtual void binderDied(const wp<IBinder>& who __unused) { mDied = true; }
-    bool died() const { return mDied; }
-    bool mDied;
-};
-
-static bool isIEffectCommandSecure(IEffect *effect)
-{
-    // some magic constants here
-    const int COMMAND_SIZE = 1024 + 12; // different than reply size to get different heap frag
-    char cmdData[COMMAND_SIZE];
-    memset(cmdData, 0xde, sizeof(cmdData));
-
-    const int REPLY_DATA_SIZE = 256;
-    char replyData[REPLY_DATA_SIZE];
-    bool secure = true;
-    for (int k = 0; k < 10; ++k) {
-        Parcel data;
-        data.writeInterfaceToken(effect->getInterfaceDescriptor());
-        data.writeInt32(0);  // 0 is EFFECT_CMD_INIT
-        data.writeInt32(sizeof(cmdData));
-        data.write(cmdData, sizeof(cmdData));
-        data.writeInt32(sizeof(replyData));
-
-        Parcel reply;
-        status_t status = effect->asBinder(effect)->transact(3, data, &reply);  // 3 is COMMAND
-        ALOGV("transact status: %d", status);
-        if (status != NO_ERROR) {
-            ALOGW("invalid transaction status %d", status);
-            continue;
-        }
-
-        ALOGV("reply data avail %zu", reply.dataAvail());
-        status = reply.readInt32();
-        ALOGV("reply status %d", status);
-        if (status == NO_ERROR) {
-            continue;
-        }
-
-        int size = reply.readInt32();
-        ALOGV("reply size %d", size);
-        if (size != sizeof(replyData)) { // we expect 0 or full reply data if command failed
-            ALOGW_IF(size != 0, "invalid reply size: %d", size);
-            continue;
-        }
-
-        // Note that if reply.read() returns success, it should completely fill replyData.
-        status = reply.read(replyData, sizeof(replyData));
-        if (status != NO_ERROR) {
-            ALOGW("invalid reply read - ignoring");
-            continue;
-        }
-        unsigned int *out = (unsigned int *)replyData;
-        for (size_t index = 0; index < sizeof(replyData) / sizeof(*out); ++index) {
-            if (out[index] != 0) {
-                secure = false;
-                ALOGI("leaked data = %#08x", out[index]);
-            }
-        }
-    }
-    ALOGI("secure: %s", secure ? "YES" : "NO");
-    return secure;
-}
-
-static jboolean android_security_cts_AudioEffect_test_isCommandSecure()
-{
-    const sp<IAudioFlinger> &audioFlinger = AudioSystem::get_audio_flinger();
-    if (audioFlinger.get() == NULL) {
-        ALOGE("could not get audioflinger");
-        return JNI_FALSE;
-    }
-
-    static const effect_uuid_t EFFECT_UIID_EQUALIZER =  // type
-        { 0x0bed4300, 0xddd6, 0x11db, 0x8f34, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b }};
-    sp<EffectClient> effectClient(new EffectClient());
-    effect_descriptor_t descriptor;
-    memset(&descriptor, 0, sizeof(descriptor));
-    descriptor.type = EFFECT_UIID_EQUALIZER;
-    descriptor.uuid = *EFFECT_UUID_NULL;
-    const int32_t priority = 0;
-    const audio_session_t sessionId = AUDIO_SESSION_OUTPUT_MIX;
-    const audio_io_handle_t io = AUDIO_IO_HANDLE_NONE;
-    const String16 opPackageName("Exploitable");
-    status_t status;
-    int32_t id;
-    int enabled;
-    sp<IEffect> effect = audioFlinger->createEffect(&descriptor, effectClient,
-            priority, io, sessionId, opPackageName, &status, &id, &enabled);
-    if (effect.get() == NULL || status != NO_ERROR) {
-        ALOGW("could not create effect");
-        return JNI_TRUE;
-    }
-
-    sp<DeathRecipient> deathRecipient(new DeathRecipient());
-    IInterface::asBinder(effect)->linkToDeath(deathRecipient);
-
-    // check exploit
-    if (!isIEffectCommandSecure(effect.get())) {
-        ALOGE("not secure!");
-        return JNI_FALSE;
-    }
-
-    sleep(1); // wait to check death
-    if (deathRecipient->died()) {
-        ALOGE("effect binder died");
-        return JNI_FALSE;
-    }
-    return JNI_TRUE;
-}
-
-int register_android_security_cts_AudioEffectBinderTest(JNIEnv *env)
-{
-    static JNINativeMethod methods[] = {
-        { "native_test_isCommandSecure", "()Z",
-                (void *) android_security_cts_AudioEffect_test_isCommandSecure },
-    };
-
-    jclass clazz = env->FindClass("android/security/cts/AudioEffectBinderTest");
-    return env->RegisterNatives(clazz, methods, sizeof(methods) / sizeof(methods[0]));
-}
diff --git a/tests/tests/security/jni/android_security_cts_AudioFlingerBinderTest.cpp b/tests/tests/security/jni/android_security_cts_AudioFlingerBinderTest.cpp
deleted file mode 100644
index f4e79e5..0000000
--- a/tests/tests/security/jni/android_security_cts_AudioFlingerBinderTest.cpp
+++ /dev/null
@@ -1,342 +0,0 @@
-/*
- * 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.
- */
-
-#define LOG_TAG "AudioFlingerBinderTest-JNI"
-
-#include <jni.h>
-#include <binder/IServiceManager.h>
-#include <binder/IPCThreadState.h>
-#include <binder/ProcessState.h>
-#include <media/IAudioFlinger.h>
-#include <media/AudioSystem.h>
-#include <system/audio.h>
-#include <utils/Log.h>
-#include <utils/SystemClock.h>
-
-using namespace android;
-
-/*
- * Native methods used by
- * cts/tests/tests/security/src/android/security/cts/AudioFlingerBinderTest.java
- */
-
-#define TEST_ARRAY_SIZE 10000
-#define MAX_ARRAY_SIZE 1024
-#define TEST_PATTERN 0x55
-
-class MyDeathClient: public IBinder::DeathRecipient
-{
-public:
-    MyDeathClient() :
-        mAfIsDead(false) {
-    }
-
-    bool afIsDead() const { return mAfIsDead; }
-
-    // DeathRecipient
-    virtual void binderDied(const wp<IBinder>& who __unused) { mAfIsDead = true; }
-
-private:
-    bool mAfIsDead;
-};
-
-
-static bool connectAudioFlinger(sp<IAudioFlinger>& af, sp<MyDeathClient> &dr)
-{
-    int64_t startTime = 0;
-    while (af == 0) {
-        sp<IBinder> binder = defaultServiceManager()->checkService(String16("media.audio_flinger"));
-        if (binder == 0) {
-            if (startTime == 0) {
-                startTime = uptimeMillis();
-            } else if ((uptimeMillis()-startTime) > 10000) {
-                ALOGE("timeout while getting audio flinger service");
-                return false;
-            }
-            sleep(1);
-        } else {
-            af = interface_cast<IAudioFlinger>(binder);
-            dr = new MyDeathClient();
-            binder->linkToDeath(dr);
-        }
-    }
-    // Allow binderDied() to be called on MyDeathClient
-    sp<ProcessState> proc(ProcessState::self());
-    ProcessState::self()->startThreadPool();
-    return true;
-}
-
-/*
- * Checks that AudioSystem::setMasterMute() does not crash mediaserver if a duplicated output
- * is opened.
- */
-jboolean android_security_cts_AudioFlinger_test_setMasterMute(JNIEnv* env __unused,
-                                                           jobject thiz __unused)
-{
-    sp<IAudioFlinger> af;
-    sp<MyDeathClient> dr;
-
-    if (!connectAudioFlinger(af, dr)) {
-        return false;
-    }
-
-    // force opening of a duplicating output
-    status_t status = AudioSystem::setDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
-                                          AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
-                                          "0", "");
-    if (status != NO_ERROR) {
-        return false;
-    }
-
-    bool mute;
-    status = AudioSystem::getMasterMute(&mute);
-    if (status != NO_ERROR) {
-        return false;
-    }
-
-    AudioSystem::setMasterMute(!mute);
-
-    sleep(1);
-
-    // Check that mediaserver did not crash
-    if (dr->afIsDead()) {
-        return false;
-    }
-
-    AudioSystem::setMasterMute(mute);
-
-    AudioSystem::setDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
-                                          AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
-                                          "0", "");
-
-    AudioSystem::setMasterMute(false);
-
-    return true;
-}
-
-jboolean android_security_cts_AudioFlinger_test_setMasterVolume(JNIEnv* env __unused,
-                                                           jobject thiz __unused)
-{
-    sp<IAudioFlinger> af;
-    sp<MyDeathClient> dr;
-
-    if (!connectAudioFlinger(af, dr)) {
-        return false;
-    }
-
-    // force opening of a duplicating output
-    status_t status = AudioSystem::setDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
-                                          AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
-                                          "0", "");
-    if (status != NO_ERROR) {
-        return false;
-    }
-
-    float vol;
-    status = AudioSystem::getMasterVolume(&vol);
-    if (status != NO_ERROR) {
-        return false;
-    }
-
-    AudioSystem::setMasterVolume(vol < 0.5 ? 1.0 : 0.0);
-
-    sleep(1);
-
-    // Check that mediaserver did not crash
-    if (dr->afIsDead()) {
-        return false;
-    }
-
-    AudioSystem::setMasterMute(vol);
-
-    AudioSystem::setDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
-                                          AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
-                                          "0", "");
-
-    return true;
-}
-
-jboolean android_security_cts_AudioFlinger_test_listAudioPorts(JNIEnv* env __unused,
-                                                           jobject thiz __unused)
-{
-    sp<IAudioFlinger> af;
-    sp<MyDeathClient> dr;
-
-    if (!connectAudioFlinger(af, dr)) {
-        return false;
-    }
-
-    unsigned int num_ports = TEST_ARRAY_SIZE;
-    struct audio_port *ports =
-            (struct audio_port *)calloc(TEST_ARRAY_SIZE, sizeof(struct audio_port));
-
-    memset(ports, TEST_PATTERN, TEST_ARRAY_SIZE * sizeof(struct audio_port));
-
-    status_t status = af->listAudioPorts(&num_ports, ports);
-
-    sleep(1);
-
-    // Check that the memory content above the max allowed array size was not changed
-    char *ptr = (char *)(ports + MAX_ARRAY_SIZE);
-    for (size_t i = 0; i < TEST_ARRAY_SIZE - MAX_ARRAY_SIZE; i++) {
-        if (ptr[i * sizeof(struct audio_port)] != TEST_PATTERN) {
-            free(ports);
-            return false;
-        }
-    }
-
-    free(ports);
-
-    // Check that mediaserver did not crash
-    if (dr->afIsDead()) {
-        return false;
-    }
-
-    return true;
-}
-
-jboolean android_security_cts_AudioFlinger_test_listAudioPatches(JNIEnv* env __unused,
-                                                           jobject thiz __unused)
-{
-    sp<IAudioFlinger> af;
-    sp<MyDeathClient> dr;
-
-    if (!connectAudioFlinger(af, dr)) {
-        return false;
-    }
-
-    unsigned int num_patches = TEST_ARRAY_SIZE;
-    struct audio_patch *patches =
-            (struct audio_patch *)calloc(TEST_ARRAY_SIZE, sizeof(struct audio_patch));
-
-    memset(patches, TEST_PATTERN, TEST_ARRAY_SIZE * sizeof(struct audio_patch));
-
-    status_t status = af->listAudioPatches(&num_patches, patches);
-
-    sleep(1);
-
-    // Check that the memory content above the max allowed array size was not changed
-    char *ptr = (char *)(patches + MAX_ARRAY_SIZE);
-    for (size_t i = 0; i < TEST_ARRAY_SIZE - MAX_ARRAY_SIZE; i++) {
-        if (ptr[i * sizeof(struct audio_patch)] != TEST_PATTERN) {
-            free(patches);
-            return false;
-        }
-    }
-
-    free(patches);
-
-    // Check that mediaserver did not crash
-    if (dr->afIsDead()) {
-        return false;
-    }
-
-    return true;
-}
-
-jboolean android_security_cts_AudioFlinger_test_createEffect(JNIEnv* env __unused,
-                                                             jobject thiz __unused)
-{
-    sp<IAudioFlinger> af;
-    sp<MyDeathClient> dr;
-
-    if (!connectAudioFlinger(af, dr)) {
-        return false;
-    }
-
-    for (int j = 0; j < 10; ++j) {
-        Parcel data, reply;
-        data.writeInterfaceToken(af->getInterfaceDescriptor());
-        data.writeInt32((int32_t)j);
-        status_t status = af->asBinder(af)->transact(40, data, &reply); // 40 is CREATE_EFFECT
-        if (status != NO_ERROR) {
-            return false;
-        }
-
-        status = (status_t)reply.readInt32();
-        if (status == NO_ERROR) {
-            continue;
-        }
-
-        int id = reply.readInt32();
-        int enabled = reply.readInt32();
-        sp<IEffect> effect = interface_cast<IEffect>(reply.readStrongBinder());
-        effect_descriptor_t desc;
-        effect_descriptor_t descTarget;
-        memset(&desc, 0, sizeof(effect_descriptor_t));
-        memset(&descTarget, 0, sizeof(effect_descriptor_t));
-        reply.read(&desc, sizeof(effect_descriptor_t));
-        if (id != 0 || enabled != 0 || memcmp(&desc, &descTarget, sizeof(effect_descriptor_t))) {
-            return false;
-        }
-    }
-
-    sleep(1);
-
-    // Check that mediaserver did not crash
-    if (dr->afIsDead()) {
-        return false;
-    }
-
-    return true;
-}
-
-
-#define NUM_ATTEMPTS 5
-
-jboolean android_security_cts_AudioFlinger_test_getInputBufferSize(JNIEnv* env __unused,
-                                                             jobject thiz __unused)
-{
-    sp<IAudioFlinger> af;
-    sp<MyDeathClient> dr;
-
-    if (!connectAudioFlinger(af, dr)) {
-        return false;
-    }
-
-    for (size_t i = 0; i < NUM_ATTEMPTS; i++) {
-        af->getInputBufferSize(0, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_MONO);
-        sleep(1);
-        // Check that mediaserver did not crash
-        if (dr->afIsDead()) {
-            return false;
-        }
-    }
-
-    return true;
-}
-
-static JNINativeMethod gMethods[] = {
-    {  "native_test_setMasterMute", "()Z",
-            (void *) android_security_cts_AudioFlinger_test_setMasterMute },
-    {  "native_test_setMasterVolume", "()Z",
-            (void *) android_security_cts_AudioFlinger_test_setMasterVolume },
-    {  "native_test_listAudioPorts", "()Z",
-            (void *) android_security_cts_AudioFlinger_test_listAudioPorts },
-    {  "native_test_listAudioPatches", "()Z",
-            (void *) android_security_cts_AudioFlinger_test_listAudioPatches },
-    {  "native_test_createEffect", "()Z",
-            (void *) android_security_cts_AudioFlinger_test_createEffect },
-    {  "native_test_getInputBufferSize", "()Z",
-            (void *) android_security_cts_AudioFlinger_test_getInputBufferSize },
-};
-
-int register_android_security_cts_AudioFlingerBinderTest(JNIEnv* env)
-{
-    jclass clazz = env->FindClass("android/security/cts/AudioFlingerBinderTest");
-    return env->RegisterNatives(clazz, gMethods,
-            sizeof(gMethods) / sizeof(JNINativeMethod));
-}
diff --git a/tests/tests/security/jni/android_security_cts_AudioPolicyBinderTest.cpp b/tests/tests/security/jni/android_security_cts_AudioPolicyBinderTest.cpp
deleted file mode 100644
index d0a8ec9..0000000
--- a/tests/tests/security/jni/android_security_cts_AudioPolicyBinderTest.cpp
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Copyright (C) 2014 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.
- */
-
-#define LOG_TAG "AudioPolicyBinderTest-JNI"
-
-#include <jni.h>
-#include <binder/IServiceManager.h>
-#include <binder/Parcel.h>
-#include <media/IAudioPolicyService.h>
-#include <media/AudioSystem.h>
-#include <system/audio.h>
-#include <utils/Log.h>
-#include <utils/SystemClock.h>
-
-using namespace android;
-
-/*
- * Native methods used by
- * cts/tests/tests/security/src/android/security/cts/AudioPolicyBinderTest.java
- */
-
-static bool init(sp<IAudioPolicyService>& aps, audio_io_handle_t *output, int *session)
-{
-    aps = 0;
-    if (output != NULL) {
-        *output = AUDIO_IO_HANDLE_NONE;
-    }
-    if (session != NULL) {
-        *session = AUDIO_UNIQUE_ID_ALLOCATE;
-    }
-
-    int64_t startTime = 0;
-    sp<IServiceManager> sm = defaultServiceManager();
-    while (aps == 0) {
-        sp<IBinder> binder = defaultServiceManager()->checkService(String16("media.audio_policy"));
-        if (binder == 0) {
-            if (startTime == 0) {
-                startTime = uptimeMillis();
-            } else if ((uptimeMillis()-startTime) > 10000) {
-                ALOGE("timeout while getting audio policy service");
-                return false;
-            }
-            sleep(1);
-        } else {
-            aps = interface_cast<IAudioPolicyService>(binder);
-        }
-    }
-
-    if (output != NULL) {
-        // get a valid output. Any use case will do.
-        for (int stream = AUDIO_STREAM_MIN; stream < AUDIO_STREAM_CNT; stream++) {
-            *output = AudioSystem::getOutput((audio_stream_type_t)stream);
-            if (*output != AUDIO_IO_HANDLE_NONE) {
-                break;
-            }
-        }
-        if (*output == AUDIO_IO_HANDLE_NONE) {
-            ALOGE("cannot get valid audio output");
-            return false;
-        }
-    }
-    if (session != NULL) {
-        //get a valid session
-        *session = AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
-        if (*session == AUDIO_UNIQUE_ID_ALLOCATE) {
-            ALOGE("cannot get valid audio session");
-            return false;
-        }
-    }
-    return true;
-}
-
-/*
- * Checks that IAudioPolicyService::startOutput() cannot be called with an
- * invalid stream type.
- */
-jboolean android_security_cts_AudioPolicy_test_startOutput(JNIEnv* env __unused,
-                                                           jobject thiz __unused)
-{
-    sp<IAudioPolicyService> aps;
-    audio_io_handle_t output;
-    int session;
-
-    if (!init(aps, &output, &session)) {
-        return false;
-    }
-
-    status_t status = aps->startOutput(output, (audio_stream_type_t)(AUDIO_STREAM_MIN -1),
-                                       (audio_session_t)session);
-    if (status == NO_ERROR) {
-        return false;
-    }
-    status = aps->startOutput(output, (audio_stream_type_t)AUDIO_STREAM_CNT,
-                              (audio_session_t)session);
-    if (status == NO_ERROR) {
-        return false;
-    }
-    return true;
-}
-
-/*
- * Checks that IAudioPolicyService::stopOutput() cannot be called with an
- * invalid stream type.
- */
-jboolean android_security_cts_AudioPolicy_test_stopOutput(JNIEnv* env __unused,
-                                                           jobject thiz __unused)
-{
-    sp<IAudioPolicyService> aps;
-    audio_io_handle_t output;
-    int session;
-
-    if (!init(aps, &output, &session)) {
-        return false;
-    }
-
-    status_t status = aps->stopOutput(output, (audio_stream_type_t)(AUDIO_STREAM_MIN -1),
-                                      (audio_session_t)session);
-    if (status == NO_ERROR) {
-        return false;
-    }
-    status = aps->stopOutput(output, (audio_stream_type_t)AUDIO_STREAM_CNT,
-                             (audio_session_t)session);
-    if (status == NO_ERROR) {
-        return false;
-    }
-    return true;
-}
-
-/*
- * Checks that IAudioPolicyService::isStreamActive() cannot be called with an
- * invalid stream type.
- */
-jboolean android_security_cts_AudioPolicy_test_isStreamActive(JNIEnv* env __unused,
-                                                           jobject thiz __unused)
-{
-    sp<IAudioPolicyService> aps;
-
-    if (!init(aps, NULL, NULL)) {
-        return false;
-    }
-
-    bool status = aps->isStreamActive((audio_stream_type_t)(-1), 0);
-    if (status) {
-        return false;
-    }
-    status = aps->isStreamActive((audio_stream_type_t)AUDIO_STREAM_CNT, 0);
-    if (status) {
-        return false;
-    }
-    return true;
-}
-
-/*
- * Checks that IAudioPolicyService::isStreamActiveRemotely() cannot be called with an
- * invalid stream type.
- * Test with NUM_RANDOM_TESTS random values for stream type.
- */
-jboolean android_security_cts_AudioPolicy_test_isStreamActiveRemotely(JNIEnv* env __unused,
-                                                           jobject thiz __unused)
-{
-    sp<IAudioPolicyService> aps;
-
-    if (!init(aps, NULL, NULL)) {
-        return false;
-    }
-
-    if (aps->isStreamActiveRemotely((audio_stream_type_t)(AUDIO_STREAM_MIN -1), 0)) {
-        return false;
-    }
-
-    if (aps->isStreamActiveRemotely((audio_stream_type_t)AUDIO_STREAM_CNT, 0)) {
-        return false;
-    }
-    return true;
-}
-
-jint android_security_cts_AudioPolicy_test_getStreamVolumeLeak(JNIEnv* env __unused,
-                                                           jobject thiz __unused)
-{
-    sp<IAudioPolicyService> aps;
-
-    if (!init(aps, NULL, NULL)) {
-        return -1;
-    }
-
-    // Keep synchronized with IAudioPolicyService.cpp!
-    enum {
-        GET_STREAM_VOLUME = 17,
-    };
-
-    Parcel data, reply;
-    status_t err;
-    data.writeInterfaceToken(aps->getInterfaceDescriptor());
-    data.writeInt32(-1); // stream type
-    data.writeInt32(-1); // device
-    IInterface::asBinder(aps)->transact(GET_STREAM_VOLUME, data, &reply);
-    int index = reply.readInt32();
-    err = reply.readInt32();
-
-    return index;
-}
-
-jboolean android_security_cts_AudioPolicy_test_startAudioSource(JNIEnv* env __unused,
-                                                                jobject thiz __unused)
-{
-    sp<IAudioPolicyService> aps;
-
-    if (!init(aps, NULL, NULL)) {
-        return false;
-    }
-
-    // Keep synchronized with IAudioPolicyService.cpp!
-    enum {
-        START_AUDIO_SOURCE = 41,
-    };
-
-    for (int i = 0; i < 10; ++i) {
-        Parcel data, reply;
-        data.writeInterfaceToken(aps->getInterfaceDescriptor());
-        data.writeInt32(-i);
-        IInterface::asBinder(aps)->transact(START_AUDIO_SOURCE, data, &reply);
-        status_t err = (status_t)reply.readInt32();
-        if (err == NO_ERROR) {
-            continue;
-        }
-        audio_io_handle_t handle = (audio_io_handle_t)reply.readInt32();
-        if (handle != 0) {
-            return false;
-        }
-    }
-
-    return true;
-}
-
-static JNINativeMethod gMethods[] = {
-    {  "native_test_startOutput", "()Z",
-            (void *) android_security_cts_AudioPolicy_test_startOutput },
-    {  "native_test_stopOutput", "()Z",
-                (void *) android_security_cts_AudioPolicy_test_stopOutput },
-    {  "native_test_isStreamActive", "()Z",
-                (void *) android_security_cts_AudioPolicy_test_isStreamActive },
-    {  "native_test_isStreamActiveRemotely", "()Z",
-                (void *) android_security_cts_AudioPolicy_test_isStreamActiveRemotely },
-    {  "native_test_getStreamVolumeLeak", "()I",
-                (void *) android_security_cts_AudioPolicy_test_getStreamVolumeLeak },
-    {  "native_test_startAudioSource", "()Z",
-                (void *) android_security_cts_AudioPolicy_test_startAudioSource },
-};
-
-int register_android_security_cts_AudioPolicyBinderTest(JNIEnv* env)
-{
-    jclass clazz = env->FindClass("android/security/cts/AudioPolicyBinderTest");
-    return env->RegisterNatives(clazz, gMethods,
-            sizeof(gMethods) / sizeof(JNINativeMethod));
-}
diff --git a/tests/tests/security/jni/android_security_cts_GraphicBufferInfoLeakTest.cpp b/tests/tests/security/jni/android_security_cts_GraphicBufferInfoLeakTest.cpp
deleted file mode 100644
index d0cd347..0000000
--- a/tests/tests/security/jni/android_security_cts_GraphicBufferInfoLeakTest.cpp
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * 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.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "GraphicBufferInfoLeakTest-JNI"
-
-#include <jni.h>
-#include <JNIHelp.h>
-
-#include <binder/Parcel.h>
-#include <binder/IServiceManager.h>
-
-#include <gui/IGraphicBufferProducer.h>
-#include <gui/IGraphicBufferConsumer.h>
-#include <media/IMediaPlayerService.h>
-#include <media/IMediaRecorder.h>
-#include <media/IOMX.h>
-#include <media/stagefright/MediaErrors.h>
-
-#include <sys/stat.h>
-#include <fcntl.h>
-
-using namespace android;
-
-static sp<IMediaPlayerService> getMediaPlayerService()
-{
-   sp<IServiceManager> sm = defaultServiceManager();
-   sp<IBinder> mediaPlayerService = sm->checkService(String16("media.player"));
-
-   sp<IMediaPlayerService> iMPService = IMediaPlayerService::asInterface(mediaPlayerService);
-   return iMPService;
-}
-
-jint android_security_cts_GraphicBuffer_test_attachBufferInfoLeak(JNIEnv* env,
-                                                           jobject thiz __unused)
-{
-    sp<IMediaPlayerService> iMPService = getMediaPlayerService();
-
-    // get IOMX
-    // Keep synchronized with IMediaPlayerService.cpp!
-    enum {
-        GET_OMX = 4,
-    };
-
-    status_t  err;
-    Parcel data, reply;
-    data.writeInterfaceToken(iMPService->getInterfaceDescriptor());
-    err = IMediaPlayerService::asBinder(iMPService)->transact(GET_OMX, data, &reply);
-    if (err != NO_ERROR) {
-        jniThrowException(env, "java/lang/RuntimeException", "GET_OMX failed");
-    }
-
-    // get IGraphicBufferConsumer
-    sp<IGraphicBufferProducer> iBufferProducer;
-    sp<IGraphicBufferConsumer> iBufferConsumer;
-    sp<IOMX> iOmx = interface_cast<IOMX>(reply.readStrongBinder());
-    err = iOmx->createPersistentInputSurface(&iBufferProducer, &iBufferConsumer);
-    if (err != NO_ERROR) {
-        jniThrowException(env, "java/lang/RuntimeException", "createPersistentInputSurface failed");
-        return err;
-    }
-
-    // Keep synchronized with IGraphicBufferConsumer.cpp!
-    enum {
-        ATTACH_BUFFER = 3,
-    };
-
-    for (;;) {
-        Parcel data2, reply2;
-        data2.writeInterfaceToken(iBufferConsumer->getInterfaceDescriptor());
-        err = IGraphicBufferConsumer::asBinder(iBufferConsumer)->transact(ATTACH_BUFFER, data2, &reply2);
-        if (err != NO_ERROR) {
-            jniThrowException(env, "java/lang/RuntimeException", "ATTACH_BUFFER failed");
-        }
-
-        int32_t slot = reply2.readInt32();
-        status_t result = reply2.readInt32();
-        ALOGV("slot %d", slot);
-        if (result != 0) {
-            // only check for leaked data in error case
-            return slot;
-        }
-    }
-}
-
-jint android_security_cts_GraphicBuffer_test_queueBufferInfoLeak(JNIEnv* env,
-                                                           jobject thiz __unused)
-{
-    sp<IMediaPlayerService> iMPService = getMediaPlayerService();
-    sp<IMediaRecorder> recorder = iMPService->createMediaRecorder(String16("GraphicBufferInfoLeakTest"));
-
-    const char *fileName = "/dev/null";
-    int fd = open(fileName, O_RDWR | O_CREAT, 0744);
-    if (fd < 0) {
-        jniThrowException(env, "java/lang/RuntimeException", "open output failed");
-        return fd;
-    }
-
-    recorder->setVideoSource(2);
-    recorder->setOutputFile(fd, 0, 0);
-    recorder->setOutputFormat(0);
-    recorder->init();
-    recorder->prepare();
-    recorder->start();
-
-    //get IGraphicBufferProducer
-    sp<IGraphicBufferProducer> iGBP = recorder->querySurfaceMediaSource();
-    ALOGV("fd %d, Get iGBP instance, 0x%08x\n", fd, iGBP.get());
-
-    // Keep synchronized with IGraphicBufferProducer.cpp!
-    enum {
-        QUEUE_BUFFER = 7,
-    };
-
-    for (;;) {
-        status_t err;
-        Parcel data, reply;
-        data.writeInterfaceToken(iGBP->getInterfaceDescriptor());
-        data.writeInt32(-1);
-        err = IGraphicBufferProducer::asBinder(iGBP)->transact(QUEUE_BUFFER, data, &reply);
-        if (err != NO_ERROR) {
-            recorder->stop();
-            recorder->release();
-            jniThrowException(env, "java/lang/RuntimeException", "QUEUE_BUFFER failed");
-            return err;
-        }
-
-        size_t len = reply.dataAvail();
-        int32_t result; // last sizeof(int32_t) bytes of Parcel
-        ALOGV("dataAvail = %zu\n", len);
-        if (len < sizeof(result)) {
-            // must contain result
-            recorder->stop();
-            recorder->release();
-            jniThrowException(env, "java/lang/RuntimeException", "reply malformed");
-            return ERROR_MALFORMED;
-        }
-
-        uint8_t *reply_data = (uint8_t *)reply.data();
-        memcpy(&result, reply_data + len - sizeof(result), sizeof(result));
-        if (result == NO_ERROR) {
-            // only check for leaked data in error case
-            continue;
-        }
-
-        uint8_t leaked_data = 0;
-        for (size_t i = 0; i < len - sizeof(result); ++i) {
-            ALOGV("IGraphicBufferProducer_InfoLeak reply_data[%d] = 0x%08x", i, reply_data[i]);
-            if (reply_data[i]) {
-                leaked_data = reply_data[i];
-                break;
-            }
-        }
-
-        recorder->stop();
-        recorder->release();
-        return leaked_data;
-    }
-}
-
-static JNINativeMethod gMethods[] = {
-    {  "native_test_attachBufferInfoLeak", "()I",
-            (void *) android_security_cts_GraphicBuffer_test_attachBufferInfoLeak },
-    {  "native_test_queueBufferInfoLeak", "()I",
-            (void *) android_security_cts_GraphicBuffer_test_queueBufferInfoLeak },
-};
-
-int register_android_security_cts_GraphicBufferInfoLeakTest(JNIEnv* env)
-{
-    jclass clazz = env->FindClass("android/security/cts/GraphicBufferInfoLeakTest");
-    return env->RegisterNatives(clazz, gMethods,
-            sizeof(gMethods) / sizeof(JNINativeMethod));
-}
diff --git a/tests/tests/security/jni/android_security_cts_LoadEffectLibraryTest.cpp b/tests/tests/security/jni/android_security_cts_LoadEffectLibraryTest.cpp
deleted file mode 100644
index 6e0f6e1..0000000
--- a/tests/tests/security/jni/android_security_cts_LoadEffectLibraryTest.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2013 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 <jni.h>
-#include <binder/IServiceManager.h>
-#include <media/IAudioFlinger.h>
-#include <media/AudioEffect.h>
-
-
-using namespace android;
-
-
-/*
- * Native method used by
- * cts/tests/tests/security/src/android/security/cts/LoadEffectLibraryTest.java
- *
- * Checks that no IAudioFlinger binder transaction manages to load an effect library
- * as LOAD_EFFECT_LIBRARY did in gingerbread.
- */
-
-jboolean android_security_cts_LoadEffectLibraryTest_doLoadLibraryTest(JNIEnv* env, jobject thiz)
-{
-    sp<IServiceManager> sm = defaultServiceManager();
-    if (sm == 0) {
-        return false;
-    }
-
-    sp<IBinder> binder = sm->getService(String16("media.audio_flinger"));
-    if (binder == 0) {
-        return false;
-    }
-
-    Parcel data, reply;
-    sp<IAudioFlinger> af = interface_cast<IAudioFlinger>(binder);
-
-    data.writeInterfaceToken(af->getInterfaceDescriptor());
-    // test library path defined in cts/tests/tests/security/testeffect/Android.mk
-    data.writeCString("/system/lib/soundfx/libctstesteffect.so");
-
-    // test 100 IAudioFlinger binder transaction values and check that none corresponds
-    // to LOAD_EFFECT_LIBRARY and successfully loads our test library
-    for (uint32_t i = IBinder::FIRST_CALL_TRANSACTION;
-            i < IBinder::FIRST_CALL_TRANSACTION + 100;
-            i++) {
-        status_t status = binder->transact(i, data, &reply);
-        if (status != NO_ERROR) {
-            continue;
-        }
-        status = reply.readInt32();
-        if (status != NO_ERROR) {
-            continue;
-        }
-
-        // Effect UUID defined in cts/tests/tests/security/testeffect/CTSTestEffect.cpp
-        effect_uuid_t uuid =
-                    {0xff93e360, 0x0c3c, 0x11e3, 0x8a97, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
-        effect_descriptor_t desc;
-
-        status = AudioEffect::getEffectDescriptor(&uuid, &desc);
-        if (status == NO_ERROR) {
-            return false;
-        }
-    }
-    return true;
-}
-
-static JNINativeMethod gMethods[] = {
-    {  "doLoadLibraryTest", "()Z",
-            (void *) android_security_cts_LoadEffectLibraryTest_doLoadLibraryTest },
-};
-
-int register_android_security_cts_LoadEffectLibraryTest(JNIEnv* env)
-{
-    jclass clazz = env->FindClass("android/security/cts/LoadEffectLibraryTest");
-    return env->RegisterNatives(clazz, gMethods,
-            sizeof(gMethods) / sizeof(JNINativeMethod));
-}
diff --git a/tests/tests/security/jni/android_security_cts_MediaPlayerInfoLeakTest.cpp b/tests/tests/security/jni/android_security_cts_MediaPlayerInfoLeakTest.cpp
deleted file mode 100644
index 0c61f25..0000000
--- a/tests/tests/security/jni/android_security_cts_MediaPlayerInfoLeakTest.cpp
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * 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.
- */
-
-#define LOG_TAG "MediaPlayerInfoLeakTest-JNI"
-
-#include <jni.h>
-
-#include <binder/Parcel.h>
-#include <binder/IServiceManager.h>
-
-#include <media/IMediaPlayer.h>
-#include <media/IMediaPlayerService.h>
-#include <media/IMediaPlayerClient.h>
-
-#include <sys/stat.h>
-
-using namespace android;
-
-static status_t connectMediaPlayer(sp<IMediaPlayer>& iMP)
-{
-   sp<IServiceManager> sm = defaultServiceManager();
-   sp<IBinder> mediaPlayerService = sm->checkService(String16("media.player"));
-
-   sp<IMediaPlayerService> iMPService = IMediaPlayerService::asInterface(mediaPlayerService);
-   sp<IMediaPlayerClient> client;
-   Parcel data, reply;
-   int dummyAudioSessionId = 1;
-   data.writeInterfaceToken(iMPService->getInterfaceDescriptor());
-   data.writeStrongBinder(IInterface::asBinder(client));
-   data.writeInt32(dummyAudioSessionId);
-
-   // Keep synchronized with IMediaPlayerService.cpp!
-    enum {
-        CREATE = IBinder::FIRST_CALL_TRANSACTION,
-    };
-   status_t err = IInterface::asBinder(iMPService)->transact(CREATE, data, &reply);
-   if (err == NO_ERROR) {
-       iMP = interface_cast<IMediaPlayer>(reply.readStrongBinder());
-   }
-   return err;
-}
-
-int testMediaPlayerInfoLeak(int command)
-{
-    sp<IMediaPlayer> iMP;
-    if (NO_ERROR != connectMediaPlayer(iMP)) {
-        return false;
-    }
-
-
-    Parcel data, reply;
-    data.writeInterfaceToken(iMP->getInterfaceDescriptor());
-    IInterface::asBinder(iMP)->transact(command, data, &reply);
-
-    int leak = reply.readInt32();
-    status_t err = reply.readInt32();
-    return  leak;
-}
-
-jint android_security_cts_MediaPlayer_test_getCurrentPositionLeak(JNIEnv* env __unused,
-                                                           jobject thiz __unused)
-{
-  // Keep synchronized with IMediaPlayer.cpp!
-  enum {
-      GET_CURRENT_POSITION = 16,
-  };
-  return testMediaPlayerInfoLeak(GET_CURRENT_POSITION);
-}
-
-jint android_security_cts_MediaPlayer_test_getDurationLeak(JNIEnv* env __unused,
-                                                           jobject thiz __unused)
-{
-  // Keep synchronized with IMediaPlayer.cpp!
-  enum {
-      GET_DURATION = 17,
-  };
-  return testMediaPlayerInfoLeak(GET_DURATION);
-}
-
-static JNINativeMethod gMethods[] = {
-    {  "native_test_getCurrentPositionLeak", "()I",
-            (void *) android_security_cts_MediaPlayer_test_getCurrentPositionLeak },
-    {  "native_test_getDurationLeak", "()I",
-            (void *) android_security_cts_MediaPlayer_test_getDurationLeak },
-};
-
-int register_android_security_cts_MediaPlayerInfoLeakTest(JNIEnv* env)
-{
-    jclass clazz = env->FindClass("android/security/cts/MediaPlayerInfoLeakTest");
-    return env->RegisterNatives(clazz, gMethods,
-            sizeof(gMethods) / sizeof(JNINativeMethod));
-}
diff --git a/tests/tests/security/src/android/security/cts/AudioEffectBinderTest.java b/tests/tests/security/src/android/security/cts/AudioEffectBinderTest.java
deleted file mode 100644
index 20d9615..0000000
--- a/tests/tests/security/src/android/security/cts/AudioEffectBinderTest.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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.security.cts;
-
-import android.media.audiofx.AudioEffect;
-
-import java.util.UUID;
-
-import junit.framework.TestCase;
-
-public class AudioEffectBinderTest extends TestCase {
-
-    static {
-        System.loadLibrary("ctssecurity_jni");
-    }
-
-    /**
-     * Checks that IEffect::command() cannot leak data.
-     */
-    public void test_isCommandSecure() throws Exception {
-        if (isEffectTypeAvailable(AudioEffect.EFFECT_TYPE_EQUALIZER)) {
-            assertTrue(native_test_isCommandSecure());
-        }
-    }
-
-    /* see AudioEffect.isEffectTypeAvailable(), implements hidden function */
-    private static boolean isEffectTypeAvailable(UUID type) {
-        AudioEffect.Descriptor[] desc = AudioEffect.queryEffects();
-        if (desc == null) {
-            return false;
-        }
-
-        for (int i = 0; i < desc.length; i++) {
-            if (desc[i].type.equals(type)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private static native boolean native_test_isCommandSecure();
-}
diff --git a/tests/tests/security/src/android/security/cts/AudioFlingerBinderTest.java b/tests/tests/security/src/android/security/cts/AudioFlingerBinderTest.java
deleted file mode 100644
index e84d851..0000000
--- a/tests/tests/security/src/android/security/cts/AudioFlingerBinderTest.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * 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.security.cts;
-
-import junit.framework.TestCase;
-
-public class AudioFlingerBinderTest extends TestCase {
-
-    static {
-        System.loadLibrary("ctssecurity_jni");
-    }
-
-    /**
-     * Checks that AudioSystem::setMasterMute() does not crash mediaserver if a duplicated output
-     * is opened.
-     */
-    public void test_setMasterMute() throws Exception {
-        assertTrue(native_test_setMasterMute());
-    }
-
-    /**
-     * Checks that AudioSystem::setMasterVolume() does not crash mediaserver if a duplicated output
-     * is opened.
-     */
-    public void test_setMasterVolume() throws Exception {
-        assertTrue(native_test_setMasterVolume());
-    }
-
-    /**
-     * Checks that IAudioFlinger::listAudioPorts() does not cause a memory overflow when passed a
-     * large number of ports.
-     */
-    public void test_listAudioPorts() throws Exception {
-        assertTrue(native_test_listAudioPorts());
-    }
-
-    /**
-     * Checks that IAudioFlinger::listAudioPatches() does not cause a memory overflow when passed a
-     * large number of ports.
-     */
-    public void test_listAudioPatches() throws Exception {
-        assertTrue(native_test_listAudioPatches());
-    }
-
-    /**
-     * Checks that IAudioFlinger::createEffect() does not leak information on the server side.
-     */
-    public void test_createEffect() throws Exception {
-        assertTrue(native_test_createEffect());
-    }
-
-    /**
-     * Checks that passing a sample rate of 0 to IAudioFlinger::getInputBufferSize()
-     * does not cause a crash in audioserver.
-     */
-    public void test_getInputBufferSize() throws Exception {
-        assertTrue(native_test_getInputBufferSize());
-    }
-
-    private static native boolean native_test_setMasterMute();
-    private static native boolean native_test_setMasterVolume();
-    private static native boolean native_test_listAudioPorts();
-    private static native boolean native_test_listAudioPatches();
-    private static native boolean native_test_createEffect();
-    private static native boolean native_test_getInputBufferSize();
-}
diff --git a/tests/tests/security/src/android/security/cts/AudioPolicyBinderTest.java b/tests/tests/security/src/android/security/cts/AudioPolicyBinderTest.java
deleted file mode 100644
index 82346a1..0000000
--- a/tests/tests/security/src/android/security/cts/AudioPolicyBinderTest.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2014 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.cts;
-
-import junit.framework.TestCase;
-
-public class AudioPolicyBinderTest extends TestCase {
-
-    static {
-        System.loadLibrary("ctssecurity_jni");
-    }
-
-    /**
-     * Checks that IAudioPolicyService::startOutput() cannot be called with an
-     * invalid stream type.
-     */
-    public void test_startOutput() throws Exception {
-        assertTrue(native_test_startOutput());
-    }
-
-    /**
-     * Checks that IAudioPolicyService::stopOutput() cannot be called with an
-     * invalid stream type.
-     */
-    public void test_stopOutput() throws Exception {
-        assertTrue(native_test_stopOutput());
-    }
-
-    /**
-     * Checks that IAudioPolicyService::isStreamActive() cannot be called with an
-     * invalid stream type.
-     */
-    public void test_isStreamActive() throws Exception {
-        assertTrue(native_test_isStreamActive());
-    }
-
-    /**
-     * Checks that IAudioPolicyService::isStreamActiveRemotely() cannot be called with an
-     * invalid stream type.
-     */
-    public void test_isStreamActiveRemotely() throws Exception {
-        assertTrue(native_test_isStreamActiveRemotely());
-    }
-
-    /**
-     * Checks that IAudioPolicyService::getStreamVolumeIndex() does not leak information
-     * when called with an invalid stream/device type.
-     */
-    public void test_getStreamVolumeLeak() throws Exception {
-        int volume = native_test_getStreamVolumeLeak();
-        assertTrue(String.format("Leaked volume 0x%08X", volume), volume == 0);
-    }
-
-    /**
-     * Checks that IAudioPolicyService::startAudioSource() cannot leak information from
-     * server side.
-     */
-    public void test_startAudioSource() throws Exception {
-        assertTrue(native_test_startAudioSource());
-    }
-
-    private static native boolean native_test_startOutput();
-    private static native boolean native_test_stopOutput();
-    private static native boolean native_test_isStreamActive();
-    private static native boolean native_test_isStreamActiveRemotely();
-    private static native int native_test_getStreamVolumeLeak();
-    private static native boolean native_test_startAudioSource();
-}
diff --git a/tests/tests/security/src/android/security/cts/GraphicBufferInfoLeakTest.java b/tests/tests/security/src/android/security/cts/GraphicBufferInfoLeakTest.java
deleted file mode 100644
index 6005e37..0000000
--- a/tests/tests/security/src/android/security/cts/GraphicBufferInfoLeakTest.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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.cts;
-
-import junit.framework.TestCase;
-
-public class GraphicBufferInfoLeakTest extends TestCase {
-
-    static {
-        System.loadLibrary("ctssecurity_jni");
-    }
-
-    /**
-     * Check that IGraphicBufferConsumer::attachBuffer does not leak info in error case
-     */
-    public void test_attachBufferInfoLeak() throws Exception {
-        int slot = native_test_attachBufferInfoLeak();
-        assertTrue(String.format("Leaked slot 0x%08X", slot), slot == -1);
-    }
-
-    /**
-     * Check that IGraphicBufferProducer::queueBuffer does not leak info in error case
-     */
-    public void test_queueBufferInfoLeak() throws Exception {
-        int data = native_test_queueBufferInfoLeak();
-        assertTrue(String.format("Leaked buffer data 0x%08X", data), data == 0);
-    }
-
-    private static native int native_test_attachBufferInfoLeak();
-    private static native int native_test_queueBufferInfoLeak();
-}
diff --git a/tests/tests/security/src/android/security/cts/LoadEffectLibraryTest.java b/tests/tests/security/src/android/security/cts/LoadEffectLibraryTest.java
deleted file mode 100644
index 900ac7f..0000000
--- a/tests/tests/security/src/android/security/cts/LoadEffectLibraryTest.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2013 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.cts;
-
-import junit.framework.TestCase;
-
-public class LoadEffectLibraryTest extends TestCase {
-
-    static {
-        System.loadLibrary("ctssecurity_jni");
-    }
-
-    /**
-     * Checks that no binder calls to IAudioFlinger manages to load an effect library.
-     */
-    public void testLoadLibrary() throws Exception {
-        assertTrue(doLoadLibraryTest());
-    }
-
-    private static native boolean doLoadLibraryTest();
-
-}
diff --git a/tests/tests/security/src/android/security/cts/MediaPlayerInfoLeakTest.java b/tests/tests/security/src/android/security/cts/MediaPlayerInfoLeakTest.java
deleted file mode 100644
index e34fc05..0000000
--- a/tests/tests/security/src/android/security/cts/MediaPlayerInfoLeakTest.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.security.cts;
-
-import junit.framework.TestCase;
-
-public class MediaPlayerInfoLeakTest extends TestCase {
-
-    static {
-        System.loadLibrary("ctssecurity_jni");
-    }
-
-
-    /**
-     * Checks that IMediaPlayer::getCurrentPosition() does not leak info in error case
-     */
-    public void test_getCurrentPositionLeak() throws Exception {
-        int pos = native_test_getCurrentPositionLeak();
-        assertTrue(String.format("Leaked pos 0x%08X", pos), pos == 0);
-    }
-
-    /**
-     * Checks that IMediaPlayer::getDuration() does not leak info in error case
-     */
-    public void test_getDurationLeak() throws Exception {
-        int dur = native_test_getDurationLeak();
-        assertTrue(String.format("Leaked dur 0x%08X", dur), dur == 0);
-    }
-
-    private static native int native_test_getCurrentPositionLeak();
-    private static native int native_test_getDurationLeak();
-}
diff --git a/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java b/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java
index 8cf20bd..074712e 100644
--- a/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java
+++ b/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java
@@ -45,6 +45,7 @@
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Objects;
 import java.util.concurrent.TimeUnit;
 
 /**
@@ -81,6 +82,11 @@
     InvokeCounter mOnCallAudioStateChangedCounter;
     InvokeCounter mOnPostDialWaitCounter;
     InvokeCounter mOnCannedTextResponsesLoadedCounter;
+    InvokeCounter mOnConnectionEventCounter;
+    InvokeCounter mOnExtrasChangedCounter;
+    InvokeCounter mOnPropertiesChangedCounter;
+    Bundle mPreviousExtras;
+    int mPreviousProperties = -1;
 
     InCallServiceCallbacks mInCallCallbacks;
     String mPreviousDefaultDialer = null;
@@ -192,6 +198,17 @@
             @Override
             public void onDetailsChanged(Call call, Call.Details details) {
                 Log.i(TAG, "onDetailsChanged, Call: " + call + ", Details: " + details);
+                if (!areBundlesEqual(mPreviousExtras, details.getExtras())) {
+                    mOnExtrasChangedCounter.invoke(call, details);
+                }
+                mPreviousExtras = details.getExtras();
+
+                if (mPreviousProperties != details.getCallProperties()) {
+                    mOnPropertiesChangedCounter.invoke(call, details);
+                    Log.i(TAG, "onDetailsChanged; properties changed from " + Call.Details.propertiesToString(mPreviousProperties) +
+                            " to " + Call.Details.propertiesToString(details.getCallProperties()));
+                }
+                mPreviousProperties = details.getCallProperties();
             }
             @Override
             public void onCallDestroyed(Call call) {
@@ -218,6 +235,10 @@
             public void onCannedTextResponsesLoaded(Call call, List<String> cannedTextResponses) {
                 mOnCannedTextResponsesLoadedCounter.invoke(call, cannedTextResponses);
             }
+            @Override
+            public void onConnectionEvent(Call call, String event, Bundle extras) {
+                mOnConnectionEventCounter.invoke(call, event, extras);
+            }
         };
 
         MockInCallService.setCallbacks(mInCallCallbacks);
@@ -228,6 +249,9 @@
         mOnCallAudioStateChangedCounter = new InvokeCounter("OnCallAudioStateChanged");
         mOnPostDialWaitCounter = new InvokeCounter("OnPostDialWait");
         mOnCannedTextResponsesLoadedCounter = new InvokeCounter("OnCannedTextResponsesLoaded");
+        mOnConnectionEventCounter = new InvokeCounter("OnConnectionEvent");
+        mOnExtrasChangedCounter = new InvokeCounter("OnDetailsChangedCounter");
+        mOnPropertiesChangedCounter = new InvokeCounter("OnPropertiesChangedCounter");
     }
 
     /**
@@ -297,6 +321,7 @@
         if (mInCallCallbacks.getService() != null) {
             currentCallCount = mInCallCallbacks.getService().getCallCount();
         }
+        int currentConnectionCount = getNumberOfConnections();
         placeNewCallWithPhoneAccount(extras, videoState);
 
         try {
@@ -311,6 +336,20 @@
         assertEquals("InCallService should contain 1 more call after adding a call.",
                 currentCallCount + 1,
                 mInCallCallbacks.getService().getCallCount());
+
+        // The connectionService.lock is released in
+        // MockConnectionService#onCreateOutgoingConnection, however the connection will not
+        // actually be added to the list of connections in the ConnectionService until shortly
+        // afterwards.  So there is still a potential for the lock to be released before it would
+        // be seen by calls to ConnectionService#getAllConnections().
+        // We will wait here until the list of connections includes one more connection to ensure
+        // that placing the call has fully completed.
+        final int expectedConnectionCount = currentConnectionCount + 1;
+        assertCSConnections(expectedConnectionCount);
+    }
+
+    int getNumberOfConnections() {
+        return CtsConnectionService.getAllConnectionsFromTelecom().size();
     }
 
     MockConnection verifyConnectionForOutgoingCall() {
@@ -520,6 +559,24 @@
     );
     }
 
+    void assertCSConnections(final int numConnections) {
+        waitUntilConditionIsTrueOrTimeout(new Condition() {
+                                              @Override
+                                              public Object expected() {
+                                                  return numConnections;
+                                              }
+
+                                              @Override
+                                              public Object actual() {
+                                                  return CtsConnectionService
+                                                          .getAllConnectionsFromTelecom()
+                                                          .size();
+                                              }
+                                          },
+                WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "ConnectionService should contain " + numConnections + " connections."
+        );
+    }
 
     void assertNumConnections(final MockConnectionService connService, final int numConnections) {
         waitUntilConditionIsTrueOrTimeout(new Condition() {
@@ -865,6 +922,30 @@
         );
     }
 
+    /**
+     * Asserts that a call's properties are as expected.
+     *
+     * @param call The call.
+     * @param properties The expected properties.
+     */
+    public void assertCallProperties(final Call call, final int properties) {
+        waitUntilConditionIsTrueOrTimeout(
+                new Condition() {
+                    @Override
+                    public Object expected() {
+                        return true;
+                    }
+
+                    @Override
+                    public Object actual() {
+                        return call.getDetails().hasProperty(properties);
+                    }
+                },
+                TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "Call should have properties " + properties
+        );
+    }
+
     void waitUntilConditionIsTrueOrTimeout(Condition condition, long timeout,
             String description) {
         final long start = System.currentTimeMillis();
@@ -982,4 +1063,25 @@
             }
         }
     }
+
+    public static boolean areBundlesEqual(Bundle extras, Bundle newExtras) {
+        if (extras == null || newExtras == null) {
+            return extras == newExtras;
+        }
+
+        if (extras.size() != newExtras.size()) {
+            return false;
+        }
+
+        for (String key : extras.keySet()) {
+            if (key != null) {
+                final Object value = extras.get(key);
+                final Object newValue = newExtras.get(key);
+                if (!Objects.equals(value, newValue)) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
 }
diff --git a/tests/tests/telecom/src/android/telecom/cts/CallDetailsTest.java b/tests/tests/telecom/src/android/telecom/cts/CallDetailsTest.java
index 0be05d6..c8e927f 100644
--- a/tests/tests/telecom/src/android/telecom/cts/CallDetailsTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/CallDetailsTest.java
@@ -29,24 +29,32 @@
 import android.telecom.ConnectionRequest;
 import android.telecom.DisconnectCause;
 import android.telecom.GatewayInfo;
-import android.telecom.InCallService;
 import android.telecom.PhoneAccount;
 import android.telecom.PhoneAccountHandle;
 import android.telecom.StatusHints;
 import android.telecom.TelecomManager;
+import android.util.Log;
+
+import java.util.Arrays;
+import java.util.List;
 
 /**
  * Suites of tests that verifies the various Call details.
  */
 public class CallDetailsTest extends BaseTelecomTestWithMockServices {
 
+    /**
+     * {@link Connection#PROPERTY_HIGH_DEF_AUDIO} is @hide, so define it here for now.
+     */
+    public static final int PROPERTY_HIGH_DEF_AUDIO = 1<<2;
+
+    /**
+     * {@link Connection#PROPERTY_WIFI} is @hide, so define it here for now.
+     */
+    public static final int PROPERTY_WIFI = 1<<3;
+    public static final int CONNECTION_PROPERTIES =  PROPERTY_HIGH_DEF_AUDIO | PROPERTY_WIFI;
     public static final int CONNECTION_CAPABILITIES =
-            Connection.CAPABILITY_HOLD | Connection.CAPABILITY_MUTE |
-            /**
-             * CAPABILITY_HIGH_DEF_AUDIO & CAPABILITY_WIFI are hidden, so
-             * hardcoding the values for now.
-             */
-            0x00008000 | 0x00010000;
+            Connection.CAPABILITY_HOLD | Connection.CAPABILITY_MUTE;
     public static final int CALL_CAPABILITIES =
             Call.Details.CAPABILITY_HOLD | Call.Details.CAPABILITY_MUTE;
     public static final int CALL_PROPERTIES =
@@ -57,14 +65,17 @@
     public static final String TEST_CHILD_NUMBER = "650-555-1212";
     public static final String TEST_FORWARDED_NUMBER = "650-555-1212";
     public static final String TEST_EXTRA_KEY = "com.test.extra.TEST";
+    public static final String TEST_EXTRA_KEY2 = "com.test.extra.TEST2";
+    public static final String TEST_EXTRA_KEY3 = "com.test.extra.TEST3";
     public static final int TEST_EXTRA_VALUE = 10;
+    public static final String TEST_EVENT = "com.test.event.TEST";
 
     private StatusHints mStatusHints;
     private Bundle mExtras = new Bundle();
 
     private MockInCallService mInCallService;
     private Call mCall;
-    private Connection mConnection;
+    private MockConnection mConnection;
 
     @Override
     protected void setUp() throws Exception {
@@ -79,9 +90,10 @@
                             Connection connection = super.onCreateOutgoingConnection(
                                     connectionManagerPhoneAccount,
                                     request);
-                            mConnection = connection;
+                            mConnection = (MockConnection) connection;
                             // Modify the connection object created with local values.
                             connection.setConnectionCapabilities(CONNECTION_CAPABILITIES);
+                            connection.setConnectionProperties(CONNECTION_PROPERTIES);
                             connection.setCallerDisplayName(
                                     CALLER_DISPLAY_NAME,
                                     CALLER_DISPLAY_NAME_PRESENTATION);
@@ -402,6 +414,189 @@
     }
 
     /**
+     * Tests that {@link Connection} extras changes made via {@link Connection#putExtras(Bundle)}
+     * are propagated to the {@link Call} via
+     * {@link android.telecom.Call.Callback#onDetailsChanged(Call, Call.Details)}.
+     */
+    public void testConnectionPutExtras() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        Bundle testBundle = new Bundle();
+        testBundle.putString(TEST_EXTRA_KEY, TEST_SUBJECT);
+        testBundle.putInt(TEST_EXTRA_KEY2, TEST_EXTRA_VALUE);
+        mConnection.putExtras(testBundle);
+        // Wait for the 2nd invocation; setExtras is called in the setup method.
+        mOnExtrasChangedCounter.waitForCount(2, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+
+        Bundle extras = mCall.getDetails().getExtras();
+        assertEquals(2, extras.size());
+        assertTrue(extras.containsKey(TEST_EXTRA_KEY));
+        assertEquals(TEST_SUBJECT, extras.getString(TEST_EXTRA_KEY));
+        assertTrue(extras.containsKey(TEST_EXTRA_KEY2));
+        assertEquals(TEST_EXTRA_VALUE, extras.getInt(TEST_EXTRA_KEY2));
+    }
+
+    /**
+     * Tests that {@link Connection} extras changes made via {@link Connection#removeExtras(List)}
+     * are propagated to the {@link Call} via
+     * {@link android.telecom.Call.Callback#onDetailsChanged(Call, Call.Details)}.
+     */
+    public void testConnectionRemoveExtras() {
+        testConnectionPutExtras();
+
+        mConnection.removeExtras(Arrays.asList(TEST_EXTRA_KEY));
+        // testConnectionPutExtra will have waited for the 2nd invocation, so wait for the 3rd here.
+        mOnExtrasChangedCounter.waitForCount(3, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+
+        Bundle extras = mCall.getDetails().getExtras();
+        assertEquals(1, extras.size());
+        assertFalse(extras.containsKey(TEST_EXTRA_KEY));
+        assertTrue(extras.containsKey(TEST_EXTRA_KEY2));
+        assertEquals(TEST_EXTRA_VALUE, extras.getInt(TEST_EXTRA_KEY2));
+    }
+
+    /**
+     * Tests that {@link Call} extras changes made via {@link Call#putExtras(Bundle)} are propagated
+     * to {@link Connection#onExtrasChanged(Bundle)}.
+     */
+    public void testCallPutExtras() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        Bundle testBundle = new Bundle();
+        testBundle.putString(TEST_EXTRA_KEY, TEST_SUBJECT);
+        final InvokeCounter counter = mConnection.getInvokeCounter(
+                MockConnection.ON_EXTRAS_CHANGED);
+        mCall.putExtras(testBundle);
+        counter.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        Bundle extras = mConnection.getExtras();
+
+        assertNotNull(extras);
+        assertTrue(extras.containsKey(TEST_EXTRA_KEY));
+        assertEquals(TEST_SUBJECT, extras.getString(TEST_EXTRA_KEY));
+    }
+
+    /**
+     * Tests that {@link Call} extra operations using {@link Call#removeExtras(List)} are propagated
+     * to the {@link Connection} via {@link Connection#onExtrasChanged(Bundle)}.
+     *
+     * This test specifically tests addition and removal of extras values.
+     */
+    public void testCallRemoveExtras() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        Bundle testBundle = new Bundle();
+        testBundle.putString(TEST_EXTRA_KEY, TEST_SUBJECT);
+        testBundle.putInt(TEST_EXTRA_KEY2, TEST_EXTRA_VALUE);
+        testBundle.putString(TEST_EXTRA_KEY3, TEST_SUBJECT);
+        final InvokeCounter counter = mConnection.getInvokeCounter(
+                MockConnection.ON_EXTRAS_CHANGED);
+        mCall.putExtras(testBundle);
+        counter.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        Bundle extras = mConnection.getExtras();
+
+        assertNotNull(extras);
+        assertTrue(extras.containsKey(TEST_EXTRA_KEY));
+        assertEquals(TEST_SUBJECT, extras.getString(TEST_EXTRA_KEY));
+        assertTrue(extras.containsKey(TEST_EXTRA_KEY2));
+        assertEquals(TEST_EXTRA_VALUE, extras.getInt(TEST_EXTRA_KEY2));
+        assertTrue(extras.containsKey(TEST_EXTRA_KEY3));
+        assertEquals(TEST_SUBJECT, extras.getString(TEST_EXTRA_KEY3));
+
+        mCall.removeExtras(Arrays.asList(TEST_EXTRA_KEY));
+        counter.waitForCount(2, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        extras = mConnection.getExtras();
+        assertNotNull(extras);
+        assertFalse(extras.containsKey(TEST_EXTRA_KEY));
+        assertTrue(extras.containsKey(TEST_EXTRA_KEY2));
+        assertEquals(TEST_EXTRA_VALUE, extras.getInt(TEST_EXTRA_KEY2));
+        assertTrue(extras.containsKey(TEST_EXTRA_KEY3));
+        assertEquals(TEST_SUBJECT, extras.getString(TEST_EXTRA_KEY3));
+
+        mCall.removeExtras(Arrays.asList(TEST_EXTRA_KEY2, TEST_EXTRA_KEY3));
+        counter.waitForCount(3, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        extras = mConnection.getExtras();
+        assertTrue(extras.isEmpty());
+    }
+
+    /**
+     * Tests that {@link Connection} events are propagated from
+     * {@link Connection#sendConnectionEvent(String, Bundle)} to
+     * {@link android.telecom.Call.Callback#onConnectionEvent(Call, String, Bundle)}.
+     */
+    public void testConnectionEvent() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        Bundle testBundle = new Bundle();
+        testBundle.putString(TEST_EXTRA_KEY, TEST_SUBJECT);
+
+        mConnection.sendConnectionEvent(Connection.EVENT_CALL_PULL_FAILED, testBundle);
+        mOnConnectionEventCounter.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        String event = (String) (mOnConnectionEventCounter.getArgs(0)[1]);
+        Bundle extras = (Bundle) (mOnConnectionEventCounter.getArgs(0)[2]);
+
+        assertEquals(Connection.EVENT_CALL_PULL_FAILED, event);
+        assertNotNull(extras);
+        assertTrue(extras.containsKey(TEST_EXTRA_KEY));
+        assertEquals(TEST_SUBJECT, extras.getString(TEST_EXTRA_KEY));
+    }
+
+    /**
+     * Tests that {@link Call} events are propagated from {@link Call#sendCallEvent(String, Bundle)}
+     * to {@link Connection#onCallEvent(String, Bundle)}.
+     */
+    public void testCallEvent() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        Bundle testBundle = new Bundle();
+        testBundle.putString(TEST_EXTRA_KEY, TEST_SUBJECT);
+        final InvokeCounter counter = mConnection.getInvokeCounter(MockConnection.ON_CALL_EVENT);
+        mCall.sendCallEvent(TEST_EVENT, testBundle);
+        counter.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+
+        String event = (String) (counter.getArgs(0)[0]);
+        Bundle extras = (Bundle) (counter.getArgs(0)[1]);
+
+        assertEquals(TEST_EVENT, event);
+        assertNotNull(extras);
+        assertTrue(extras.containsKey(TEST_EXTRA_KEY));
+        assertEquals(TEST_SUBJECT, extras.getString(TEST_EXTRA_KEY));
+    }
+
+    /**
+     * Tests that a request to pull an external call via {@link Call#pullExternalCall()} is
+     * communicated to the {@link Connection} via {@link Connection#onPullExternalCall()}.
+     */
+    public void testPullExternalCall() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        // First, configure the connection as an external call which is pullable.
+        int properties = mConnection.getConnectionProperties();
+        int capabilities = mConnection.getConnectionCapabilities();
+        properties |= Connection.PROPERTY_IS_EXTERNAL_CALL;
+        capabilities |= Connection.CAPABILITY_CAN_PULL_CALL;
+        mConnection.setConnectionCapabilities(capabilities);
+        mConnection.setConnectionProperties(properties);
+        assertCallProperties(mCall, Call.Details.PROPERTY_IS_EXTERNAL_CALL);
+
+        final InvokeCounter counter = mConnection.getInvokeCounter(
+                MockConnection.ON_PULL_EXTERNAL_CALL);
+        mCall.pullExternalCall();
+        counter.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+    }
+
+    /**
      * Asserts that a call's capabilities are as expected.
      *
      * @param call The call.
diff --git a/tests/tests/telecom/src/android/telecom/cts/CallTest.java b/tests/tests/telecom/src/android/telecom/cts/CallTest.java
index efbb69f..b892ede 100644
--- a/tests/tests/telecom/src/android/telecom/cts/CallTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/CallTest.java
@@ -31,6 +31,8 @@
         assertTrue(Call.Details.can(CAPABILITY_MERGE_CONFERENCE
                 | CAPABILITY_DISCONNECT_FROM_CONFERENCE | CAPABILITY_MUTE,
                 CAPABILITY_MUTE));
+        assertTrue(Call.Details.can(CAPABILITY_CAN_PAUSE_VIDEO, CAPABILITY_CAN_PAUSE_VIDEO));
+        assertTrue(Call.Details.can(CAPABILITY_CAN_PULL_CALL, CAPABILITY_CAN_PULL_CALL));
 
         assertFalse(Call.Details.can(CAPABILITY_MUTE, CAPABILITY_HOLD));
         assertFalse(Call.Details.can(CAPABILITY_MERGE_CONFERENCE
@@ -78,6 +80,7 @@
         assertTrue(Call.Details.hasProperty(PROPERTY_HIGH_DEF_AUDIO, PROPERTY_HIGH_DEF_AUDIO));
         assertTrue(Call.Details.hasProperty(PROPERTY_HIGH_DEF_AUDIO | PROPERTY_CONFERENCE
                 | PROPERTY_WIFI, PROPERTY_CONFERENCE));
+        assertTrue(Call.Details.hasProperty(PROPERTY_IS_EXTERNAL_CALL, PROPERTY_IS_EXTERNAL_CALL));
 
         assertFalse(Call.Details.hasProperty(PROPERTY_WIFI, PROPERTY_CONFERENCE));
         assertFalse(Call.Details.hasProperty(PROPERTY_HIGH_DEF_AUDIO | PROPERTY_CONFERENCE
diff --git a/tests/tests/telecom/src/android/telecom/cts/ConferenceTest.java b/tests/tests/telecom/src/android/telecom/cts/ConferenceTest.java
index 508870c..c3168f6 100644
--- a/tests/tests/telecom/src/android/telecom/cts/ConferenceTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/ConferenceTest.java
@@ -29,8 +29,11 @@
 import android.telecom.StatusHints;
 import android.telecom.TelecomManager;
 import android.telecom.VideoProfile;
+import android.util.Log;
 
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
 
 /**
  * Extended suite of tests that use {@link CtsConnectionService} and {@link MockInCallService} to
@@ -38,6 +41,11 @@
  */
 public class ConferenceTest extends BaseTelecomTestWithMockServices {
 
+    private static final String TEST_EXTRA_KEY_1 = "android.telecom.test.KEY1";
+    private static final String TEST_EXTRA_KEY_2 = "android.telecom.test.KEY2";
+    private static final String TEST_EXTRA_VALUE_1 = "test";
+    private static final int TEST_EXTRA_VALUE_2 = 42;
+
     public static final int CONF_CAPABILITIES = Connection.CAPABILITY_SEPARATE_FROM_CONFERENCE |
             Connection.CAPABILITY_DISCONNECT_FROM_CONFERENCE | Connection.CAPABILITY_HOLD |
             Connection.CAPABILITY_MERGE_CONFERENCE | Connection.CAPABILITY_SWAP_CONFERENCE;
@@ -45,7 +53,7 @@
     private Call mCall1, mCall2;
     private MockConnection mConnection1, mConnection2;
     MockInCallService mInCallService;
-    Conference mConferenceObject;
+    MockConference mConferenceObject;
 
     @Override
     protected void setUp() throws Exception {
@@ -213,6 +221,94 @@
         assertCallState(conf, Call.STATE_DISCONNECTED);
     }
 
+    /**
+     * Tests end to end propagation of the {@link Conference} properties to the associated
+     * {@link Call}.
+     */
+    public void testConferenceProperties() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+        final Call conf = mInCallService.getLastConferenceCall();
+        assertCallState(conf, Call.STATE_ACTIVE);
+
+        int properties  = mConferenceObject.getConnectionProperties();
+        properties |= Connection.PROPERTY_IS_EXTERNAL_CALL;
+
+        mConferenceObject.setConnectionProperties(properties);
+
+        // Wait for 2nd properties change; the first will be when the conference is marked with
+        // Call.Details.PROPERTY_CONFERENCE.
+        assertCallProperties(conf, Call.Details.PROPERTY_IS_EXTERNAL_CALL);
+        assertTrue(conf.getDetails().hasProperty(Call.Details.PROPERTY_IS_EXTERNAL_CALL));
+    }
+
+    /**
+     * Verifies {@link Conference#putExtras(Bundle)} calls are propagated to
+     * {@link android.telecom.Call.Callback#onDetailsChanged(Call, Call.Details)}.
+     */
+    public void testConferencePutExtras() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+        final Call conf = mInCallService.getLastConferenceCall();
+        assertCallState(conf, Call.STATE_ACTIVE);
+
+        Bundle extras = new Bundle();
+        extras.putString(TEST_EXTRA_KEY_1, TEST_EXTRA_VALUE_1);
+        extras.putInt(TEST_EXTRA_KEY_2, TEST_EXTRA_VALUE_2);
+        mConferenceObject.putExtras(extras);
+
+        mOnExtrasChangedCounter.waitForCount(1);
+
+        assertTrue(areBundlesEqual(extras, conf.getDetails().getExtras()));
+    }
+
+    /**
+     * Verifies {@link Conference#removeExtras(List)} calls are propagated to
+     * {@link android.telecom.Call.Callback#onDetailsChanged(Call, Call.Details)}.
+     */
+    public void testConferenceRemoveExtras() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+        final Call conf = mInCallService.getLastConferenceCall();
+        assertCallState(conf, Call.STATE_ACTIVE);
+
+        Bundle extras = new Bundle();
+        extras.putString(TEST_EXTRA_KEY_1, TEST_EXTRA_VALUE_1);
+        extras.putInt(TEST_EXTRA_KEY_2, TEST_EXTRA_VALUE_2);
+        mConferenceObject.putExtras(extras);
+        mOnExtrasChangedCounter.waitForCount(1);
+
+        mConferenceObject.removeExtras(Arrays.asList(TEST_EXTRA_KEY_1));
+        mOnExtrasChangedCounter.waitForCount(2);
+        extras = mConferenceObject.getExtras();
+
+        assertFalse(extras.containsKey(TEST_EXTRA_KEY_1));
+        assertTrue(extras.containsKey(TEST_EXTRA_KEY_2));
+    }
+
+    /**
+     * Verifies {@link android.telecom.Call#putExtras(Bundle)} changes are propagated to
+     * {@link Conference#onExtrasChanged(Bundle)}.
+     */
+    public void testConferenceOnExtraschanged() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+        final Call conf = mInCallService.getLastConferenceCall();
+        assertCallState(conf, Call.STATE_ACTIVE);
+
+        Bundle extras = new Bundle();
+        extras.putString(TEST_EXTRA_KEY_1, TEST_EXTRA_VALUE_1);
+        extras.putInt(TEST_EXTRA_KEY_2, TEST_EXTRA_VALUE_2);
+        conf.putExtras(extras);
+        mConferenceObject.mOnExtrasChanged.waitForCount(1);
+
+        assertTrue(areBundlesEqual(extras, mConferenceObject.getExtras()));
+    }
+
     public void testConferenceAddAndRemoveConnection() {
         if (!mShouldTestTelecom) {
             return;
diff --git a/tests/tests/telecom/src/android/telecom/cts/ConnectionTest.java b/tests/tests/telecom/src/android/telecom/cts/ConnectionTest.java
index b6818c8..874f116 100644
--- a/tests/tests/telecom/src/android/telecom/cts/ConnectionTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/ConnectionTest.java
@@ -27,6 +27,8 @@
 import android.telecom.TelecomManager;
 import android.test.AndroidTestCase;
 
+import java.util.Arrays;
+import java.util.List;
 import java.util.concurrent.Semaphore;
 import java.util.concurrent.TimeUnit;
 
@@ -162,6 +164,22 @@
         assertEquals(capabilities, connection.getConnectionCapabilities());
     }
 
+    public void testSetAndGetConnectionProperties() {
+        if (!shouldTestTelecom(getContext())) {
+            return;
+        }
+
+        final Semaphore lock = new Semaphore(0);
+        Connection connection = createConnection(lock);
+        waitForStateChange(lock);
+
+        final int properties = Connection.PROPERTY_IS_EXTERNAL_CALL;
+
+        connection.setConnectionProperties(properties);
+
+        assertEquals(properties, connection.getConnectionProperties());
+    }
+
     public void testSetAndGetDisconnectCause() {
         if (!shouldTestTelecom(getContext())) {
             return;
@@ -215,6 +233,79 @@
         assertTrue(extras.getBoolean("test-extra-key"));
     }
 
+    /**
+     * Basic local test of adding extra keys via {@link Connection#removeExtras(List)}.
+     *
+     * Extended end-to-end passing of extras is verified in
+     * {@link CallDetailsTest#testConnectionPutExtras()} and
+     * @link CallDetailsTest#testConnectionRemoveExtras()}.
+     */
+    public void testPutExtras() {
+        if (!shouldTestTelecom(getContext())) {
+            return;
+        }
+
+        final Semaphore lock = new Semaphore(0);
+        Connection connection = createConnection(lock);
+        waitForStateChange(lock);
+
+        assertEquals(null, connection.getExtras());
+
+        final Bundle extras = new Bundle();
+        extras.putBoolean("test-extra-key", true);
+        connection.putExtras(extras);
+
+        final Bundle retrieved = connection.getExtras();
+        assertNotNull(retrieved);
+        assertTrue(extras.getBoolean("test-extra-key"));
+    }
+
+    /**
+     * Basic local test of removing extra keys via {@link Connection#removeExtras(List)}.
+     *
+     * Extended end-to-end passing of extras is verified in
+     * {@link CallDetailsTest#testConnectionPutExtras()} and
+     * @link CallDetailsTest#testConnectionRemoveExtras()}.
+     */
+    public void testRemoveExtras() {
+        if (!shouldTestTelecom(getContext())) {
+            return;
+        }
+
+        final Semaphore lock = new Semaphore(0);
+        Connection connection = createConnection(lock);
+        waitForStateChange(lock);
+
+        assertEquals(null, connection.getExtras());
+
+        final Bundle extras = new Bundle();
+        extras.putBoolean("test-extra-key", true);
+        connection.putExtras(extras);
+        connection.removeExtras(Arrays.asList("test-extra-key"));
+
+        final Bundle retrieved = connection.getExtras();
+        assertNotNull(retrieved);
+        assertFalse(extras.containsKey("test-extra-key"));
+    }
+
+    /**
+     * Tests that the {@link Connection#sendConnectionEvent(String, Bundle)} method exists and can
+     * be called.
+     *
+     * Actual end-to-end tests can be found in {@link CallDetailsTest#testConnectionEvent()}.
+     */
+    public void testSendConnectionEvent() {
+        if (!shouldTestTelecom(getContext())) {
+            return;
+        }
+
+        final Semaphore lock = new Semaphore(0);
+        Connection connection = createConnection(lock);
+        waitForStateChange(lock);
+
+        connection.sendConnectionEvent("test", null);
+    }
+
     public void testSetAndGetStatusHints() {
         if (!shouldTestTelecom(getContext())) {
             return;
@@ -293,6 +384,18 @@
                         | Connection.CAPABILITY_MANAGE_CONFERENCE));
     }
 
+    /**
+     * Tests the {@link Connection#propertiesToString(int)} method.
+     */
+    public void testPropertiesToString() {
+        if (!shouldTestTelecom(getContext())) {
+            return;
+        }
+
+        assertEquals("[Properties: PROPERTY_IS_EXTERNAL_CALL]",
+                Connection.propertiesToString(Connection.PROPERTY_IS_EXTERNAL_CALL));
+    }
+
     private static Connection createConnection(final Semaphore lock) {
         BasicConnection connection = new BasicConnection();
         connection.setLock(lock);
diff --git a/tests/tests/telecom/src/android/telecom/cts/CtsConnectionService.java b/tests/tests/telecom/src/android/telecom/cts/CtsConnectionService.java
index 2364986..e820e10 100644
--- a/tests/tests/telecom/src/android/telecom/cts/CtsConnectionService.java
+++ b/tests/tests/telecom/src/android/telecom/cts/CtsConnectionService.java
@@ -29,6 +29,7 @@
 import android.util.Log;
 
 import java.util.Collection;
+import java.util.Collections;
 
 /**
  * This is the official ConnectionService for Telecom's CTS App. Since telecom requires that a
@@ -154,6 +155,9 @@
 
     public static Collection<Connection> getAllConnectionsFromTelecom() {
         synchronized(sLock) {
+            if (sTelecomConnectionService == null) {
+                return Collections.EMPTY_LIST;
+            }
             return sTelecomConnectionService.getAllConnections();
         }
     }
diff --git a/tests/tests/telecom/src/android/telecom/cts/MockConference.java b/tests/tests/telecom/src/android/telecom/cts/MockConference.java
index 647d039..d84610d 100644
--- a/tests/tests/telecom/src/android/telecom/cts/MockConference.java
+++ b/tests/tests/telecom/src/android/telecom/cts/MockConference.java
@@ -16,6 +16,7 @@
 
 package android.telecom.cts;
 
+import android.os.Bundle;
 import android.telecom.Conference;
 import android.telecom.Connection;
 import android.telecom.DisconnectCause;
@@ -31,6 +32,8 @@
 
     private RemoteConference mRemoteConference = null;
     private String mDtmfString = "";
+    public BaseTelecomTestWithMockServices.InvokeCounter mOnExtrasChanged =
+            new BaseTelecomTestWithMockServices.InvokeCounter("onExtrasChanged");
 
     public MockConference(PhoneAccountHandle phoneAccount) {
         super(phoneAccount);
@@ -149,4 +152,9 @@
     public String getDtmfString() {
         return mDtmfString;
     }
+
+    @Override
+    public void onExtrasChanged(Bundle extras) {
+        mOnExtrasChanged.invoke(extras);
+    }
 }
diff --git a/tests/tests/telecom/src/android/telecom/cts/MockConnection.java b/tests/tests/telecom/src/android/telecom/cts/MockConnection.java
index fe33a8d..4436219 100644
--- a/tests/tests/telecom/src/android/telecom/cts/MockConnection.java
+++ b/tests/tests/telecom/src/android/telecom/cts/MockConnection.java
@@ -17,6 +17,8 @@
 package android.telecom.cts;
 
 import static android.telecom.CallAudioState.*;
+
+import android.os.Bundle;
 import android.telecom.CallAudioState;
 import android.telecom.Connection;
 import android.telecom.DisconnectCause;
@@ -32,6 +34,9 @@
  */
 public class MockConnection extends Connection {
     public static final int ON_POST_DIAL_WAIT = 1;
+    public static final int ON_CALL_EVENT = 2;
+    public static final int ON_PULL_EXTERNAL_CALL = 3;
+    public static final int ON_EXTRAS_CHANGED = 4;
 
     private CallAudioState mCallAudioState =
             new CallAudioState(false, CallAudioState.ROUTE_EARPIECE, ROUTE_EARPIECE | ROUTE_SPEAKER);
@@ -158,6 +163,30 @@
         }
     }
 
+    @Override
+    public void onCallEvent(String event, Bundle extras) {
+        super.onCallEvent(event, extras);
+        if (mInvokeCounterMap.get(ON_CALL_EVENT) != null) {
+            mInvokeCounterMap.get(ON_CALL_EVENT).invoke(event, extras);
+        }
+    }
+
+    @Override
+    public void onPullExternalCall() {
+        super.onPullExternalCall();
+        if (mInvokeCounterMap.get(ON_PULL_EXTERNAL_CALL) != null) {
+            mInvokeCounterMap.get(ON_PULL_EXTERNAL_CALL).invoke();
+        }
+    }
+
+    @Override
+    public void onExtrasChanged(Bundle extras) {
+        super.onExtrasChanged(extras);
+        if (mInvokeCounterMap.get(ON_EXTRAS_CHANGED) != null) {
+            mInvokeCounterMap.get(ON_EXTRAS_CHANGED).invoke(extras);
+        }
+    }
+
     public int getCurrentState()  {
         return mState;
     }
@@ -239,6 +268,12 @@
         switch (counterIndex) {
             case ON_POST_DIAL_WAIT:
                 return "onPostDialWait";
+            case ON_CALL_EVENT:
+                return "onCallEvent";
+            case ON_PULL_EXTERNAL_CALL:
+                return "onPullExternalCall";
+            case ON_EXTRAS_CHANGED:
+                return "onExtrasChanged";
             default:
                 return "Callback";
         }
diff --git a/tests/tests/telecom/src/android/telecom/cts/MockInCallService.java b/tests/tests/telecom/src/android/telecom/cts/MockInCallService.java
index c371ed1..9776c64 100644
--- a/tests/tests/telecom/src/android/telecom/cts/MockInCallService.java
+++ b/tests/tests/telecom/src/android/telecom/cts/MockInCallService.java
@@ -19,6 +19,7 @@
 import static org.junit.Assert.assertTrue;
 
 import android.content.Intent;
+import android.os.Bundle;
 import android.telecom.Call;
 import android.telecom.CallAudioState;
 import android.telecom.InCallService;
@@ -58,6 +59,7 @@
         public void onCallAudioStateChanged(CallAudioState audioState) {}
         public void onPostDialWait(Call call, String remainingPostDialSequence) {}
         public void onCannedTextResponsesLoaded(Call call, List<String> cannedTextResponses) {}
+        public void onConnectionEvent(Call call, String event, Bundle extras) {}
 
         final public MockInCallService getService() {
             return mService;
@@ -142,6 +144,14 @@
                 getCallbacks().onCannedTextResponsesLoaded(call, cannedTextResponses);
             }
         }
+
+        @Override
+        public void onConnectionEvent(Call call, String event, Bundle extras) {
+            super.onConnectionEvent(call, event, extras);
+            if (getCallbacks() != null) {
+                getCallbacks().onConnectionEvent(call, event, extras);
+            }
+        }
     };
 
     private void saveVideoCall(Call call, VideoCall videoCall) {
diff --git a/tests/tests/telecom/src/android/telecom/cts/PhoneAccountOperationsTest.java b/tests/tests/telecom/src/android/telecom/cts/PhoneAccountOperationsTest.java
index cc03288..4374516 100644
--- a/tests/tests/telecom/src/android/telecom/cts/PhoneAccountOperationsTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/PhoneAccountOperationsTest.java
@@ -22,6 +22,7 @@
 import android.content.Context;
 import android.graphics.Color;
 import android.net.Uri;
+import android.os.Bundle;
 import android.telecom.PhoneAccount;
 import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
@@ -38,6 +39,16 @@
 public class PhoneAccountOperationsTest extends InstrumentationTestCase {
     public static final PhoneAccountHandle TEST_PHONE_ACCOUNT_HANDLE =
             new PhoneAccountHandle(new ComponentName(PACKAGE, COMPONENT), ACCOUNT_ID);
+    public static final Bundle TEST_BUNDLE = createTestBundle();
+    public static final int TEST_LENGTH = 10;
+    public static final String TEST_ENCODING = "enUS";
+
+    private static Bundle createTestBundle() {
+        Bundle testBundle = new Bundle();
+        testBundle.putInt(PhoneAccount.EXTRA_CALL_SUBJECT_MAX_LENGTH, TEST_LENGTH);
+        testBundle.putString(PhoneAccount.EXTRA_CALL_SUBJECT_CHARACTER_ENCODING, TEST_ENCODING);
+        return testBundle;
+    }
 
     public static final PhoneAccount TEST_SIM_PHONE_ACCOUNT = PhoneAccount.builder(
             TEST_PHONE_ACCOUNT_HANDLE, ACCOUNT_LABEL)
@@ -59,6 +70,7 @@
             .setShortDescription(ACCOUNT_LABEL)
             .setSupportedUriSchemes(Arrays.asList(
                     PhoneAccount.SCHEME_TEL, PhoneAccount.SCHEME_VOICEMAIL))
+            .setExtras(TEST_BUNDLE)
             .build();
 
     public static final PhoneAccount TEST_CALL_MANAGER_PHONE_ACCOUNT = PhoneAccount.builder(
@@ -185,6 +197,22 @@
                         PhoneAccount.CAPABILITY_VIDEO_CALLING));
     }
 
+    public void testRegisterPhoneAccount_CheckExtras() throws Exception {
+        if (!shouldTestTelecom(mContext)) {
+            return;
+        }
+        mTelecomManager.registerPhoneAccount(TEST_NO_SIM_PHONE_ACCOUNT);
+        PhoneAccount retrievedPhoneAccount = mTelecomManager.getPhoneAccount(
+                TEST_PHONE_ACCOUNT_HANDLE);
+        Bundle extras = retrievedPhoneAccount.getExtras();
+        assertTrue(extras.containsKey(PhoneAccount.EXTRA_CALL_SUBJECT_CHARACTER_ENCODING));
+        assertEquals(TEST_ENCODING,
+                extras.getString(PhoneAccount.EXTRA_CALL_SUBJECT_CHARACTER_ENCODING));
+        assertTrue(extras.containsKey(PhoneAccount.EXTRA_CALL_SUBJECT_MAX_LENGTH));
+        assertEquals(TEST_LENGTH,
+                extras.getInt(PhoneAccount.EXTRA_CALL_SUBJECT_MAX_LENGTH));
+    }
+
     public void testRegisterPhoneAccount_CheckURISchemeSupported() throws Exception {
         if (!shouldTestTelecom(mContext)) {
             return;
diff --git a/tests/tests/telecom/src/android/telecom/cts/RemoteConferenceTest.java b/tests/tests/telecom/src/android/telecom/cts/RemoteConferenceTest.java
index 787966a..eeb2ad7 100644
--- a/tests/tests/telecom/src/android/telecom/cts/RemoteConferenceTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/RemoteConferenceTest.java
@@ -343,6 +343,35 @@
         mRemoteConferenceObject.unregisterCallback(callback);
     }
 
+    public void testRemoteConferenceCallbacks_ConnectionProperties() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+        Handler handler = setupRemoteConferenceCallbacksTest();
+
+        final InvokeCounter callbackInvoker =
+                new InvokeCounter("testRemoteConferenceCallbacks_ConnectionProperties");
+        RemoteConference.Callback callback;
+
+        callback = new RemoteConference.Callback() {
+            @Override
+            public void onConnectionPropertiesChanged(
+                    RemoteConference conference,
+                    int connectionProperties) {
+                super.onConnectionPropertiesChanged(conference, connectionProperties);
+                callbackInvoker.invoke(conference, connectionProperties);
+            }
+        };
+        mRemoteConferenceObject.registerCallback(callback, handler);
+        int properties = mRemoteConference.getConnectionCapabilities()
+                | Connection.PROPERTY_IS_EXTERNAL_CALL;
+        mRemoteConference.setConnectionProperties(properties);
+        callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        assertEquals(mRemoteConferenceObject, callbackInvoker.getArgs(0)[0]);
+        assertEquals(properties, callbackInvoker.getArgs(0)[1]);
+        mRemoteConferenceObject.unregisterCallback(callback);
+    }
+
     public void testRemoteConferenceCallbacks_ConferenceableConnections() {
         if (!mShouldTestTelecom) {
             return;
@@ -402,6 +431,7 @@
         mRemoteConferenceObject.unregisterCallback(callback);
     }
 
+
     public void testRemoteConferenceCallbacks_Extras() {
         if (!mShouldTestTelecom) {
             return;
@@ -425,7 +455,7 @@
         mRemoteConference.setExtras(extras);
         callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
         assertEquals(mRemoteConferenceObject, callbackInvoker.getArgs(0)[0]);
-        assertEquals(extras, callbackInvoker.getArgs(0)[1]);
+        assertTrue(areBundlesEqual(extras, (Bundle) callbackInvoker.getArgs(0)[1]));
         mRemoteConferenceObject.unregisterCallback(callback);
     }
 
diff --git a/tests/tests/telecom/src/android/telecom/cts/RemoteConnectionTest.java b/tests/tests/telecom/src/android/telecom/cts/RemoteConnectionTest.java
index 7d095db..81080b0 100644
--- a/tests/tests/telecom/src/android/telecom/cts/RemoteConnectionTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/RemoteConnectionTest.java
@@ -238,7 +238,36 @@
         assertEquals(mRemoteConnectionObject, callbackInvoker.getArgs(0)[0]);
         assertEquals(capabilities, callbackInvoker.getArgs(0)[1]);
         mRemoteConnectionObject.unregisterCallback(callback);
+    }
 
+    public void testRemoteConnectionCallbacks_ConnectionProperties() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        Handler handler = setupRemoteConnectionCallbacksTest();
+
+        final InvokeCounter callbackInvoker =
+                new InvokeCounter("testRemoteConnectionCallbacks_ConnectionCapabilities");
+        RemoteConnection.Callback callback;
+
+        callback = new RemoteConnection.Callback() {
+            @Override
+            public void onConnectionPropertiesChanged(
+                    RemoteConnection connection,
+                    int connectionProperties) {
+                super.onConnectionPropertiesChanged(connection, connectionProperties);
+                callbackInvoker.invoke(connection, connectionProperties);
+            }
+        };
+        mRemoteConnectionObject.registerCallback(callback, handler);
+        int properties = mRemoteConnection.getConnectionCapabilities()
+                | Connection.PROPERTY_IS_EXTERNAL_CALL;
+        mRemoteConnection.setConnectionProperties(properties);
+        callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        assertEquals(mRemoteConnectionObject, callbackInvoker.getArgs(0)[0]);
+        assertEquals(properties, callbackInvoker.getArgs(0)[1]);
+        mRemoteConnectionObject.unregisterCallback(callback);
     }
 
     public void testRemoteConnectionCallbacks_PostDialWait() {
@@ -525,9 +554,42 @@
         mRemoteConnection.setExtras(extras);
         callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
         assertEquals(mRemoteConnectionObject, callbackInvoker.getArgs(0)[0]);
-        assertEquals(extras, callbackInvoker.getArgs(0)[1]);
+        assertTrue(areBundlesEqual(extras, (Bundle) callbackInvoker.getArgs(0)[1]));
         mRemoteConnectionObject.unregisterCallback(callback);
+    }
 
+    /**
+     * Verifies that a {@link RemoteConnection} receives a
+     * {@link Connection#sendConnectionEvent(String, Bundle)} notification.
+     */
+    public void testRemoteConnectionCallbacks_ConnectionEvent() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        Handler handler = setupRemoteConnectionCallbacksTest();
+
+        final InvokeCounter callbackInvoker =
+                new InvokeCounter("testRemoteConnectionCallbacks_Extras");
+        RemoteConnection.Callback callback;
+
+        callback = new RemoteConnection.Callback() {
+            @Override
+            public void onConnectionEvent(RemoteConnection connection, String event,
+                    Bundle extras) {
+                super.onConnectionEvent(connection, event, extras);
+                callbackInvoker.invoke(connection, event, extras);
+            }
+        };
+        mRemoteConnectionObject.registerCallback(callback, handler);
+        Bundle extras = new Bundle();
+        extras.putString(TelecomManager.EXTRA_CALL_DISCONNECT_MESSAGE, "Test");
+        mRemoteConnection.sendConnectionEvent(Connection.EVENT_CALL_PULL_FAILED, extras);
+        callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        assertEquals(mRemoteConnectionObject, callbackInvoker.getArgs(0)[0]);
+        assertEquals(Connection.EVENT_CALL_PULL_FAILED, callbackInvoker.getArgs(0)[1]);
+        assertTrue(areBundlesEqual(extras, (Bundle) callbackInvoker.getArgs(0)[2]));
+        mRemoteConnectionObject.unregisterCallback(callback);
     }
 
     public void testRemoteConnectionCallbacks_Disconnect() {
@@ -559,6 +621,23 @@
         mRemoteConnectionObject.unregisterCallback(callback);
     }
 
+    /**
+     * Verifies that a call to {@link RemoteConnection#pullExternalCall()} is proxied to
+     * {@link Connection#onPullExternalCall()}.
+     */
+    public void testRemoteConnectionCallbacks_PullExternalCall() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        Handler handler = setupRemoteConnectionCallbacksTest();
+
+        InvokeCounter counter =
+                mRemoteConnection.getInvokeCounter(MockConnection.ON_PULL_EXTERNAL_CALL);
+        mRemoteConnectionObject.pullExternalCall();
+        counter.waitForCount(1);
+    }
+
     public void testRemoteConnectionCallbacks_Destroy() {
         if (!mShouldTestTelecom) {
             return;
@@ -1106,6 +1185,8 @@
                 remoteConnection.getCallerDisplayNamePresentation());
         assertEquals(connection.getConnectionCapabilities(),
                 remoteConnection.getConnectionCapabilities());
+        assertEquals(connection.getConnectionProperties(),
+                remoteConnection.getConnectionProperties());
         assertEquals(connection.getDisconnectCause(), remoteConnection.getDisconnectCause());
         assertEquals(connection.getExtras(), remoteConnection.getExtras());
         assertEquals(connection.getStatusHints(), remoteConnection.getStatusHints());
diff --git a/tests/tests/text/src/android/text/cts/BoringLayoutTest.java b/tests/tests/text/src/android/text/cts/BoringLayoutTest.java
index 36d2f93..13465ae 100644
--- a/tests/tests/text/src/android/text/cts/BoringLayoutTest.java
+++ b/tests/tests/text/src/android/text/cts/BoringLayoutTest.java
@@ -82,11 +82,10 @@
 
     private void verifyMultAddScale(float spacingMult, float spacingAdd) {
         final int height = METRICS_BOTTOM - METRICS_TOP;
-        final int bottomPadding = METRICS_BOTTOM - METRICS_DESCENT;
 
         BoringLayout boringLayout = makeBoringLayout(spacingMult, spacingAdd);
         assertEquals(height, boringLayout.getHeight());
-        assertEquals(height + bottomPadding + METRICS_TOP, boringLayout.getLineDescent(0));
+        assertEquals(height + METRICS_TOP, boringLayout.getLineDescent(0));
     }
 
     public void testScale() {
@@ -172,10 +171,8 @@
     }
 
     public void testGetLineDescent_withIncludePadding() {
-        final int bottomPadding = METRICS_BOTTOM - METRICS_DESCENT;
         final int height = METRICS_BOTTOM - METRICS_TOP;
-        assertEquals(height + METRICS_TOP + bottomPadding,
-                mBoringLayout.getLineDescent(0));
+        assertEquals(height + METRICS_TOP, mBoringLayout.getLineDescent(0));
     }
 
     public void testGetLineDescent_withoutIncludePadding() {
diff --git a/tests/tests/tv/AndroidManifest.xml b/tests/tests/tv/AndroidManifest.xml
index 7acfc94..cc64363 100644
--- a/tests/tests/tv/AndroidManifest.xml
+++ b/tests/tests/tv/AndroidManifest.xml
@@ -85,6 +85,16 @@
                        android:resource="@xml/stub_tv_input_service" />
         </service>
 
+        <service android:name="android.media.tv.cts.TvInputServiceTest$FaultyTvInputService"
+                 android:permission="android.permission.BIND_TV_INPUT"
+                 android:process=":faultyTvInputService">
+            <intent-filter>
+                <action android:name="android.media.tv.TvInputService" />
+            </intent-filter>
+            <meta-data android:name="android.media.tv.input"
+                       android:resource="@xml/stub_tv_input_service" />
+        </service>
+
         <service android:name="android.media.tv.cts.HardwareSessionTest$HardwareProxyTvInputService"
                  android:permission="android.permission.BIND_TV_INPUT">
             <intent-filter>
diff --git a/tests/tests/tv/src/android/media/tv/cts/TvInputServiceTest.java b/tests/tests/tv/src/android/media/tv/cts/TvInputServiceTest.java
index a821d97..9b60967 100644
--- a/tests/tests/tv/src/android/media/tv/cts/TvInputServiceTest.java
+++ b/tests/tests/tv/src/android/media/tv/cts/TvInputServiceTest.java
@@ -32,6 +32,7 @@
 import android.media.tv.cts.TvInputServiceTest.CountingTvInputService.CountingRecordingSession;
 import android.net.Uri;
 import android.os.Bundle;
+import android.os.Process;
 import android.os.SystemClock;
 import android.test.ActivityInstrumentationTestCase2;
 import android.view.InputDevice;
@@ -65,6 +66,7 @@
     private Instrumentation mInstrumentation;
     private TvInputManager mManager;
     private TvInputInfo mStubInfo;
+    private TvInputInfo mFaultyStubInfo;
     private final StubCallback mCallback = new StubCallback();
     private final StubTimeShiftPositionCallback mTimeShiftPositionCallback =
             new StubTimeShiftPositionCallback();
@@ -177,6 +179,11 @@
         for (TvInputInfo info : mManager.getTvInputList()) {
             if (info.getServiceInfo().name.equals(CountingTvInputService.class.getName())) {
                 mStubInfo = info;
+            }
+            if (info.getServiceInfo().name.equals(FaultyTvInputService.class.getName())) {
+                mFaultyStubInfo = info;
+            }
+            if (mStubInfo != null && mFaultyStubInfo != null) {
                 break;
             }
         }
@@ -233,13 +240,16 @@
             return;
         }
         verifyCommandTuneForRecording();
+        verifyCallbackConnectionFailed();
         verifyCommandTuneForRecordingWithBundle();
         verifyCallbackTuned();
         verifyCommandStartRecording();
         verifyCommandStopRecording();
+        verifyCommandSendAppPrivateCommandForRecording();
         verifyCallbackRecordingStopped();
         verifyCallbackError();
         verifyCommandRelease();
+        verifyCallbackDisconnected();
     }
 
     public void verifyCommandTuneForRecording() {
@@ -263,7 +273,7 @@
             @Override
             protected boolean check() {
                 CountingRecordingSession session = CountingTvInputService.sRecordingSession;
-                return session != null && session.mTuneCount > 0;
+                return session != null && session.mTuneWithBundleCount > 0;
             }
         }.run();
     }
@@ -304,6 +314,20 @@
         }.run();
     }
 
+    public void verifyCommandSendAppPrivateCommandForRecording() {
+        resetCounts();
+        String action = "android.media.tv.cts.TvInputServiceTest.privateCommand";
+        mTvRecordingClient.sendAppPrivateCommand(action, null);
+        new PollingCheck(TIME_OUT) {
+            @Override
+            protected boolean check() {
+                CountingRecordingSession session = CountingTvInputService.sRecordingSession;
+                return session != null && session.mAppPrivateCommandCount > 0;
+            }
+        }.run();
+    }
+
+
     public void verifyCallbackTuned() {
         resetCounts();
         CountingRecordingSession session = CountingTvInputService.sRecordingSession;
@@ -345,16 +369,26 @@
         }.run();
     }
 
-    public void verifyCommandSendAppPrivateCommand() {
+    public void verifyCallbackConnectionFailed() {
         resetCounts();
-        String action = "android.media.tv.cts.TvInputServiceTest.privateCommand";
-        mTvView.sendAppPrivateCommand(action, null);
-        mInstrumentation.waitForIdleSync();
+        Uri fakeChannelUri = TvContract.buildChannelUri(0);
+        mTvRecordingClient.tune("invalid_input_id", fakeChannelUri);
         new PollingCheck(TIME_OUT) {
             @Override
             protected boolean check() {
-                CountingSession session = CountingTvInputService.sSession;
-                return session != null && session.mSendAppPrivateCommand > 0;
+                return mRecordingCallback.mConnectionFailedCount > 0;
+            }
+        }.run();
+    }
+
+    public void verifyCallbackDisconnected() {
+        resetCounts();
+        Uri fakeChannelUri = TvContract.buildChannelUri(0);
+        mTvRecordingClient.tune(mFaultyStubInfo.getId(), fakeChannelUri);
+        new PollingCheck(TIME_OUT) {
+            @Override
+            protected boolean check() {
+                return mRecordingCallback.mDisconnectedCount > 0;
             }
         }.run();
     }
@@ -382,7 +416,7 @@
             @Override
             protected boolean check() {
                 CountingSession session = CountingTvInputService.sSession;
-                return session != null && session.mTuneCount > 0;
+                return session != null && session.mTuneWithBundleCount > 0;
             }
         }.run();
     }
@@ -613,6 +647,20 @@
         }.run();
     }
 
+    public void verifyCommandSendAppPrivateCommand() {
+        resetCounts();
+        String action = "android.media.tv.cts.TvInputServiceTest.privateCommand";
+        mTvView.sendAppPrivateCommand(action, null);
+        mInstrumentation.waitForIdleSync();
+        new PollingCheck(TIME_OUT) {
+            @Override
+            protected boolean check() {
+                CountingSession session = CountingTvInputService.sSession;
+                return session != null && session.mAppPrivateCommandCount > 0;
+            }
+        }.run();
+    }
+
     public void verifyCallbackChannelRetuned() {
         resetCounts();
         CountingSession session = CountingTvInputService.sSession;
@@ -792,8 +840,8 @@
         }
 
         public static class CountingSession extends Session {
-            public volatile int mSendAppPrivateCommand;
             public volatile int mTuneCount;
+            public volatile int mTuneWithBundleCount;
             public volatile int mSetStreamVolumeCount;
             public volatile int mSetCaptionEnabledCount;
             public volatile int mSelectTrackCount;
@@ -813,14 +861,15 @@
             public volatile int mTimeShiftPlayCount;
             public volatile long mTimeShiftGetCurrentPositionCount;
             public volatile long mTimeShiftGetStartPositionCount;
+            public volatile int mAppPrivateCommandCount;
 
             CountingSession(Context context) {
                 super(context);
             }
 
             public void resetCounts() {
-                mSendAppPrivateCommand = 0;
                 mTuneCount = 0;
+                mTuneWithBundleCount = 0;
                 mSetStreamVolumeCount = 0;
                 mSetCaptionEnabledCount = 0;
                 mSelectTrackCount = 0;
@@ -840,11 +889,7 @@
                 mTimeShiftPlayCount = 0;
                 mTimeShiftGetCurrentPositionCount = 0;
                 mTimeShiftGetStartPositionCount = 0;
-            }
-
-            @Override
-            public void onAppPrivateCommand(String action, Bundle data) {
-                mSendAppPrivateCommand++;
+                mAppPrivateCommandCount = 0;
             }
 
             @Override
@@ -863,6 +908,15 @@
             }
 
             @Override
+            public boolean onTune(Uri channelUri, Bundle data) {
+                mTuneWithBundleCount++;
+                // Also calls {@link #onTune(Uri)} since it will never be called if the
+                // implementation overrides {@link #onTune(Uri, Bundle)}.
+                onTune(channelUri);
+                return false;
+            }
+
+            @Override
             public void onSetStreamVolume(float volume) {
                 mSetStreamVolumeCount++;
             }
@@ -965,13 +1019,20 @@
             public void onOverlayViewSizeChanged(int width, int height) {
                 mOverlayViewSizeChangedCount++;
             }
+
+            @Override
+            public void onAppPrivateCommand(String action, Bundle data) {
+                mAppPrivateCommandCount++;
+            }
         }
 
         public static class CountingRecordingSession extends RecordingSession {
             public volatile int mTuneCount;
+            public volatile int mTuneWithBundleCount;
             public volatile int mReleaseCount;
             public volatile int mStartRecordingCount;
             public volatile int mStopRecordingCount;
+            public volatile int mAppPrivateCommandCount;
 
             CountingRecordingSession(Context context) {
                 super(context);
@@ -979,9 +1040,11 @@
 
             public void resetCounts() {
                 mTuneCount = 0;
+                mTuneWithBundleCount = 0;
                 mReleaseCount = 0;
                 mStartRecordingCount = 0;
                 mStopRecordingCount = 0;
+                mAppPrivateCommandCount = 0;
             }
 
             @Override
@@ -990,6 +1053,14 @@
             }
 
             @Override
+            public void onTune(Uri channelUri, Bundle data) {
+                mTuneWithBundleCount++;
+                // Also calls {@link #onTune(Uri)} since it will never be called if the
+                // implementation overrides {@link #onTune(Uri, Bundle)}.
+                onTune(channelUri);
+            }
+
+            @Override
             public void onRelease() {
                 mReleaseCount++;
             }
@@ -1003,6 +1074,11 @@
             public void onStopRecording() {
                 mStopRecordingCount++;
             }
+
+            @Override
+            public void onAppPrivateCommand(String action, Bundle data) {
+                mAppPrivateCommandCount++;
+            }
         }
     }
 
@@ -1010,6 +1086,8 @@
         private int mTunedCount;
         private int mRecordingStoppedCount;
         private int mErrorCount;
+        private int mConnectionFailedCount;
+        private int mDisconnectedCount;
 
         @Override
         public void onTuned(Uri channelUri) {
@@ -1026,10 +1104,49 @@
             mErrorCount++;
         }
 
+        @Override
+        public void onConnectionFailed(String inputId) {
+            mConnectionFailedCount++;
+        }
+
+        @Override
+        public void onDisconnected(String inputId) {
+            mDisconnectedCount++;
+        }
+
         public void resetCounts() {
             mTunedCount = 0;
             mRecordingStoppedCount = 0;
             mErrorCount = 0;
+            mConnectionFailedCount = 0;
+            mDisconnectedCount = 0;
+        }
+    }
+
+    public static class FaultyTvInputService extends StubTvInputService {
+        @Override
+        public RecordingSession onCreateRecordingSession(String inputId) {
+            return new FaultyRecordingSession(this);
+        }
+
+        public static class FaultyRecordingSession extends RecordingSession {
+            FaultyRecordingSession(Context context) {
+                super(context);
+            }
+
+            @Override
+            public void onTune(Uri channelUri) {
+                Process.killProcess(android.os.Process.myPid());
+            }
+
+            @Override
+            public void onStartRecording(Uri programHint) { }
+
+            @Override
+            public void onStopRecording() { }
+
+            @Override
+            public void onRelease() { }
         }
     }
 }
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/BitmapFilterTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/BitmapFilterTests.java
index d0820e2..a2f0305 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/BitmapFilterTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/BitmapFilterTests.java
@@ -16,7 +16,6 @@
 package android.uirendering.cts.testclasses;
 
 import android.graphics.Bitmap;
-import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Paint;
 import android.graphics.PaintFlagsDrawFilter;
@@ -112,18 +111,15 @@
         final Paint paint = new Paint(filterEnum.equals(FilterEnum.ADD_FILTER) ?
                 0 : Paint.FILTER_BITMAP_FLAG);
 
-        CanvasClient canvasClient = new CanvasClient() {
-            @Override
-            public void draw(Canvas canvas, int width, int height) {
-                canvas.scale(1.0f * width / gridWidth, 1.0f * height / gridWidth);
-                if (filterEnum.equals(FilterEnum.ADD_FILTER)) {
-                    canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.FILTER_BITMAP_FLAG));
-                } else if (filterEnum.equals(FilterEnum.REMOVE_FILTER)) {
-                    canvas.setDrawFilter(new PaintFlagsDrawFilter(Paint.FILTER_BITMAP_FLAG, 0));
-                }
-                canvas.drawBitmap(scaleUp ? mSmallGridBitmap : mBigGridBitmap, 0, 0, paint);
-                canvas.setDrawFilter(null);
+        CanvasClient canvasClient = (canvas, width, height) -> {
+            canvas.scale(1.0f * width / gridWidth, 1.0f * height / gridWidth);
+            if (filterEnum.equals(FilterEnum.ADD_FILTER)) {
+                canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.FILTER_BITMAP_FLAG));
+            } else if (filterEnum.equals(FilterEnum.REMOVE_FILTER)) {
+                canvas.setDrawFilter(new PaintFlagsDrawFilter(Paint.FILTER_BITMAP_FLAG, 0));
             }
+            canvas.drawBitmap(scaleUp ? mSmallGridBitmap : mBigGridBitmap, 0, 0, paint);
+            canvas.setDrawFilter(null);
         };
         createTest()
                 .addCanvasClient(canvasClient)
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/CanvasStateTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/CanvasStateTests.java
index 38d884d..1e7a832 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/CanvasStateTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/CanvasStateTests.java
@@ -22,7 +22,6 @@
 import android.graphics.Region;
 import android.test.suitebuilder.annotation.MediumTest;
 import android.uirendering.cts.testinfrastructure.ActivityTestBase;
-import android.uirendering.cts.testinfrastructure.CanvasClient;
 import org.junit.Test;
 
 import static org.junit.Assert.assertFalse;
@@ -39,17 +38,14 @@
     @Test
     public void testClipRectReturnValues() {
         createTest()
-                .addCanvasClient(new CanvasClient() {
-                    @Override
-                    public void draw(Canvas canvas, int width, int height) {
-                        canvas.save();
-                        boolean isNonEmpty = canvas.clipRect(0, 0, 20, 20);
-                        assertTrue("clip state should be non empty", isNonEmpty);
+                .addCanvasClient((canvas, width, height) -> {
+                    canvas.save();
+                    boolean isNonEmpty = canvas.clipRect(0, 0, 20, 20);
+                    assertTrue("clip state should be non empty", isNonEmpty);
 
-                        isNonEmpty = canvas.clipRect(0, 40, 20, 60);
-                        assertFalse("clip state should be empty", isNonEmpty);
-                        canvas.restore();
-                    }
+                    isNonEmpty = canvas.clipRect(0, 40, 20, 60);
+                    assertFalse("clip state should be empty", isNonEmpty);
+                    canvas.restore();
                 })
                 .runWithoutVerification();
     }
@@ -57,32 +53,29 @@
     @Test
     public void testClipRegionReturnValues() {
         createTest()
-                .addCanvasClient(new CanvasClient() {
-                    @Override
-                    public void draw(Canvas canvas, int width, int height) {
-                        canvas.save();
-                        RectF clipRectF = new RectF(0, 0, 20, 20);
+                .addCanvasClient((canvas, width, height) -> {
+                    canvas.save();
+                    RectF clipRectF = new RectF(0, 0, 20, 20);
 
-                        assertFalse(canvas.quickReject(0, 0, 20, 20, Canvas.EdgeType.BW));
-                        if (!canvas.isHardwareAccelerated()) {
-                            // SW canvas may not be in View space, so we offset the clipping region
-                            // so it will operate within the canvas client's window.
-                            // (Currently, this isn't necessary, since SW layer size == draw area)
-                            canvas.getMatrix().mapRect(clipRectF);
-                        }
-
-                        Region rectRegion = new Region();
-                        rectRegion.set((int) clipRectF.left, (int) clipRectF.top,
-                                (int) clipRectF.right, (int) clipRectF.bottom);
-
-                        boolean isNonEmpty = canvas.clipRegion(rectRegion);
-                        assertTrue("clip state should be non empty", isNonEmpty);
-
-                        // Note: we don't test that non-intersecting clip regions empty the clip,
-                        // For region clipping, the impl is allowed to return true conservatively
-                        // in many cases.
-                        canvas.restore();
+                    assertFalse(canvas.quickReject(0, 0, 20, 20, Canvas.EdgeType.BW));
+                    if (!canvas.isHardwareAccelerated()) {
+                        // SW canvas may not be in View space, so we offset the clipping region
+                        // so it will operate within the canvas client's window.
+                        // (Currently, this isn't necessary, since SW layer size == draw area)
+                        canvas.getMatrix().mapRect(clipRectF);
                     }
+
+                    Region rectRegion = new Region();
+                    rectRegion.set((int) clipRectF.left, (int) clipRectF.top,
+                            (int) clipRectF.right, (int) clipRectF.bottom);
+
+                    boolean isNonEmpty = canvas.clipRegion(rectRegion);
+                    assertTrue("clip state should be non empty", isNonEmpty);
+
+                    // Note: we don't test that non-intersecting clip regions empty the clip,
+                    // For region clipping, the impl is allowed to return true conservatively
+                    // in many cases.
+                    canvas.restore();
                 })
                 .runWithoutVerification();
     }
@@ -90,40 +83,34 @@
     @Test
     public void testClipPathReturnValues() {
         createTest()
-                .addCanvasClient(new CanvasClient() {
-                    @Override
-                    public void draw(Canvas canvas, int width, int height) {
-                        canvas.save();
-                        Path rectPath = new Path();
-                        rectPath.addRect(0, 0, 20, 20, Path.Direction.CW);
+                .addCanvasClient((canvas, width, height) -> {
+                    canvas.save();
+                    Path rectPath = new Path();
+                    rectPath.addRect(0, 0, 20, 20, Path.Direction.CW);
 
-                        boolean isNonEmpty = canvas.clipPath(rectPath);
-                        assertTrue("clip state should be non empty", isNonEmpty);
+                    boolean isNonEmpty = canvas.clipPath(rectPath);
+                    assertTrue("clip state should be non empty", isNonEmpty);
 
-                        rectPath.offset(0, 40);
-                        isNonEmpty = canvas.clipPath(rectPath);
-                        assertFalse("clip state should be empty", isNonEmpty);
-                        canvas.restore();
-                    }
+                    rectPath.offset(0, 40);
+                    isNonEmpty = canvas.clipPath(rectPath);
+                    assertFalse("clip state should be empty", isNonEmpty);
+                    canvas.restore();
                 })
                 .runWithoutVerification();
     }
     @Test
     public void testQuickReject() {
         createTest()
-                .addCanvasClient(new CanvasClient() {
-                    @Override
-                    public void draw(Canvas canvas, int width, int height) {
-                        canvas.save();
-                        canvas.clipRect(0, 0, 20, 20);
+                .addCanvasClient((canvas, width, height) -> {
+                    canvas.save();
+                    canvas.clipRect(0, 0, 20, 20);
 
-                        // not rejected!
-                        assertFalse(canvas.quickReject(0, 0, 20, 20, Canvas.EdgeType.BW));
+                    // not rejected!
+                    assertFalse(canvas.quickReject(0, 0, 20, 20, Canvas.EdgeType.BW));
 
-                        // rejected!
-                        assertTrue(canvas.quickReject(0, 40, 20, 60, Canvas.EdgeType.BW));
-                        canvas.restore();
-                    }
+                    // rejected!
+                    assertTrue(canvas.quickReject(0, 40, 20, 60, Canvas.EdgeType.BW));
+                    canvas.restore();
                 })
                 .runWithoutVerification();
     }
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ExactCanvasTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ExactCanvasTests.java
index bf68f3e..2a2599b 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ExactCanvasTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ExactCanvasTests.java
@@ -16,7 +16,6 @@
 
 package android.uirendering.cts.testclasses;
 
-import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Paint;
 import android.graphics.PorterDuff;
@@ -28,7 +27,6 @@
 import android.uirendering.cts.bitmapverifiers.BitmapVerifier;
 import android.uirendering.cts.bitmapverifiers.RectVerifier;
 import android.uirendering.cts.testinfrastructure.ActivityTestBase;
-import android.uirendering.cts.testinfrastructure.CanvasClient;
 import android.uirendering.cts.R;
 import org.junit.Test;
 
@@ -40,14 +38,11 @@
     public void testBlueRect() {
         final Rect rect = new Rect(10, 10, 80, 80);
         createTest()
-                .addCanvasClient(new CanvasClient() {
-                    @Override
-                    public void draw(Canvas canvas, int width, int height) {
-                        Paint p = new Paint();
-                        p.setAntiAlias(false);
-                        p.setColor(Color.BLUE);
-                        canvas.drawRect(rect, p);
-                    }
+                .addCanvasClient((canvas, width, height) -> {
+                    Paint p = new Paint();
+                    p.setAntiAlias(false);
+                    p.setColor(Color.BLUE);
+                    canvas.drawRect(rect, p);
                 })
                 .runWithVerifier(new RectVerifier(Color.WHITE, Color.BLUE, rect));
     }
@@ -55,16 +50,13 @@
     @Test
     public void testPoints() {
         createTest()
-                .addCanvasClient(new CanvasClient() {
-                    @Override
-                    public void draw(Canvas canvas, int width, int height) {
-                        Paint p = new Paint();
-                        p.setAntiAlias(false);
-                        p.setStrokeWidth(1f);
-                        p.setColor(Color.BLACK);
-                        for (int i = 0; i < 10; i++) {
-                            canvas.drawPoint(i * 10, i * 10, p);
-                        }
+                .addCanvasClient((canvas, width, height) -> {
+                    Paint p = new Paint();
+                    p.setAntiAlias(false);
+                    p.setStrokeWidth(1f);
+                    p.setColor(Color.BLACK);
+                    for (int i = 0; i < 10; i++) {
+                        canvas.drawPoint(i * 10, i * 10, p);
                     }
                 })
                 .runWithComparer(mExactComparer);
@@ -73,17 +65,14 @@
     @Test
     public void testBlackRectWithStroke() {
         createTest()
-                .addCanvasClient(new CanvasClient() {
-                    @Override
-                    public void draw(Canvas canvas, int width, int height) {
-                        Paint p = new Paint();
-                        p.setColor(Color.RED);
-                        canvas.drawRect(0, 0, ActivityTestBase.TEST_WIDTH,
-                                ActivityTestBase.TEST_HEIGHT, p);
-                        p.setColor(Color.BLACK);
-                        p.setStrokeWidth(5);
-                        canvas.drawRect(10, 10, 80, 80, p);
-                    }
+                .addCanvasClient((canvas, width, height) -> {
+                    Paint p = new Paint();
+                    p.setColor(Color.RED);
+                    canvas.drawRect(0, 0, ActivityTestBase.TEST_WIDTH,
+                            ActivityTestBase.TEST_HEIGHT, p);
+                    p.setColor(Color.BLACK);
+                    p.setStrokeWidth(5);
+                    canvas.drawRect(10, 10, 80, 80, p);
                 })
                 .runWithComparer(mExactComparer);
     }
@@ -91,15 +80,12 @@
     @Test
     public void testBlackLineOnGreenBack() {
         createTest()
-                .addCanvasClient(new CanvasClient() {
-                    @Override
-                    public void draw(Canvas canvas, int width, int height) {
-                        canvas.drawColor(Color.GREEN);
-                        Paint p = new Paint();
-                        p.setColor(Color.BLACK);
-                        p.setStrokeWidth(10);
-                        canvas.drawLine(0, 0, 50, 0, p);
-                    }
+                .addCanvasClient((canvas, width, height) -> {
+                    canvas.drawColor(Color.GREEN);
+                    Paint p = new Paint();
+                    p.setColor(Color.BLACK);
+                    p.setStrokeWidth(10);
+                    canvas.drawLine(0, 0, 50, 0, p);
                 })
                 .runWithComparer(mExactComparer);
     }
@@ -107,14 +93,11 @@
     @Test
     public void testDrawRedRectOnBlueBack() {
         createTest()
-                .addCanvasClient(new CanvasClient() {
-                    @Override
-                    public void draw(Canvas canvas, int width, int height) {
-                        canvas.drawColor(Color.BLUE);
-                        Paint p = new Paint();
-                        p.setColor(Color.RED);
-                        canvas.drawRect(10, 10, 40, 40, p);
-                    }
+                .addCanvasClient((canvas, width, height) -> {
+                    canvas.drawColor(Color.BLUE);
+                    Paint p = new Paint();
+                    p.setColor(Color.RED);
+                    canvas.drawRect(10, 10, 40, 40, p);
                 })
                 .runWithComparer(mExactComparer);
     }
@@ -122,17 +105,14 @@
     @Test
     public void testDrawLine() {
         createTest()
-                .addCanvasClient(new CanvasClient() {
-                    @Override
-                    public void draw(Canvas canvas, int width, int height) {
-                        Paint p = new Paint();
-                        canvas.drawColor(Color.WHITE);
-                        p.setColor(Color.BLACK);
-                        float[] pts = {
-                                0, 0, 80, 80, 80, 0, 0, 80, 40, 50, 60, 50
-                        };
-                        canvas.drawLines(pts, p);
-                    }
+                .addCanvasClient((canvas, width, height) -> {
+                    Paint p = new Paint();
+                    canvas.drawColor(Color.WHITE);
+                    p.setColor(Color.BLACK);
+                    float[] pts = {
+                            0, 0, 80, 80, 80, 0, 0, 80, 40, 50, 60, 50
+                    };
+                    canvas.drawLines(pts, p);
                 })
                 .runWithComparer(mExactComparer);
     }
@@ -140,12 +120,7 @@
     @Test
     public void testDrawWhiteScreen() {
         createTest()
-                .addCanvasClient(new CanvasClient() {
-                    @Override
-                    public void draw(Canvas canvas, int width, int height) {
-                        canvas.drawColor(Color.WHITE);
-                    }
-                })
+                .addCanvasClient((canvas, width, height) -> canvas.drawColor(Color.WHITE))
                 .runWithComparer(mExactComparer);
     }
 
@@ -153,15 +128,12 @@
     public void testBasicText() {
         final String testString = "THIS IS A TEST";
         createTest()
-                .addCanvasClient(new CanvasClient() {
-                    @Override
-                    public void draw(Canvas canvas, int width, int height) {
-                        Paint p = new Paint();
-                        canvas.drawColor(Color.BLACK);
-                        p.setColor(Color.WHITE);
-                        p.setStrokeWidth(5);
-                        canvas.drawText(testString, 30, 50, p);
-                    }
+                .addCanvasClient((canvas, width, height) -> {
+                    Paint p = new Paint();
+                    canvas.drawColor(Color.BLACK);
+                    p.setColor(Color.WHITE);
+                    p.setStrokeWidth(5);
+                    canvas.drawText(testString, 30, 50, p);
                 })
                 .runWithComparer(mExactComparer);
     }
@@ -169,12 +141,9 @@
     @Test
     public void testBasicColorXfermode() {
         createTest()
-                .addCanvasClient(new CanvasClient() {
-                    @Override
-                    public void draw(Canvas canvas, int width, int height) {
-                        canvas.drawColor(Color.GRAY);
-                        canvas.drawColor(Color.BLUE, PorterDuff.Mode.MULTIPLY);
-                    }
+                .addCanvasClient((canvas, width, height) -> {
+                    canvas.drawColor(Color.GRAY);
+                    canvas.drawColor(Color.BLUE, PorterDuff.Mode.MULTIPLY);
                 })
                 .runWithComparer(mExactComparer);
     }
@@ -189,21 +158,13 @@
                 new Rect(10, 10, 80, 80));
 
         createTest()
-                .addCanvasClient(new CanvasClient() {
-                    @Override
-                    public void draw(Canvas canvas, int width, int height) {
-                        canvas.drawColor(Color.WHITE);
-                        Paint p = new Paint();
-                        p.setColor(Color.BLUE);
-                        canvas.drawRect(10, 10, 80, 80, p);
-                    }
+                .addCanvasClient((canvas, width, height) -> {
+                    canvas.drawColor(Color.WHITE);
+                    Paint p = new Paint();
+                    p.setColor(Color.BLUE);
+                    canvas.drawRect(10, 10, 80, 80, p);
                 })
-                .addCanvasClient(new CanvasClient() {
-                    @Override
-                    public void draw(Canvas canvas, int width, int height) {
-                        ninePatchDrawable.draw(canvas);
-                    }
-                })
+                .addCanvasClient((canvas, width, height) -> ninePatchDrawable.draw(canvas))
                 .addLayout(R.layout.blue_padded_square, null)
                 .runWithVerifier(verifier);
     }
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/FontRenderingTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/FontRenderingTests.java
index 738dcfb..73779d6 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/FontRenderingTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/FontRenderingTests.java
@@ -53,18 +53,15 @@
 
         final Typeface typeface = Typeface.create(family, style);
         createTest()
-                .addCanvasClient(new CanvasClient() {
-                    @Override
-                    public void draw(Canvas canvas, int width, int height) {
-                        Paint p = new Paint();
-                        p.setAntiAlias(true);
-                        p.setColor(Color.BLACK);
-                        p.setTextSize(26);
-                        p.setTypeface(typeface);
-                        canvas.drawText(sTestString1, 1, 20, p);
-                        canvas.drawText(sTestString2, 1, 50, p);
-                        canvas.drawText(sTestString3, 1, 80, p);
-                    }
+                .addCanvasClient((canvas, width, height) -> {
+                    Paint p = new Paint();
+                    p.setAntiAlias(true);
+                    p.setColor(Color.BLACK);
+                    p.setTextSize(26);
+                    p.setTypeface(typeface);
+                    canvas.drawText(sTestString1, 1, 20, p);
+                    canvas.drawText(sTestString2, 1, 50, p);
+                    canvas.drawText(sTestString3, 1, 80, p);
                 })
                 .runWithVerifier(new GoldenImageVerifier(goldenBitmap, comparer));
     }
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/InfrastructureTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/InfrastructureTests.java
index c070b96..212e666 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/InfrastructureTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/InfrastructureTests.java
@@ -19,7 +19,6 @@
 import android.test.suitebuilder.annotation.MediumTest;
 import android.uirendering.cts.R;
 
-import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Rect;
 import android.uirendering.cts.bitmapcomparers.BitmapComparer;
@@ -49,11 +48,8 @@
      */
     @Test
     public void testRenderSpecIsolation() {
-        CanvasClient canvasClient = new CanvasClient() {
-            @Override
-            public void draw(Canvas canvas, int width, int height) {
-                canvas.drawColor(canvas.isHardwareAccelerated() ? Color.BLACK : Color.WHITE);
-            }
+        CanvasClient canvasClient = (canvas, width, height) -> {
+            canvas.drawColor(canvas.isHardwareAccelerated() ? Color.BLACK : Color.WHITE);
         };
         BitmapComparer inverseComparer = new BitmapComparer() {
             @Override
@@ -75,12 +71,7 @@
     @Test
     public void testViewInitializer() {
         final Rect clipRect = new Rect(0, 0, 50, 50);
-        ViewInitializer viewInitializer = new ViewInitializer() {
-            @Override
-            public void initializeView(View view) {
-                view.setClipBounds(clipRect);
-            }
-        };
+        ViewInitializer viewInitializer = view -> view.setClipBounds(clipRect);
         createTest()
                 .addLayout(R.layout.simple_red_layout, viewInitializer)
                 .runWithVerifier(new RectVerifier(Color.WHITE, Color.RED, clipRect));
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/LayerTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/LayerTests.java
index 30dbb03..53112d6 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/LayerTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/LayerTests.java
@@ -43,17 +43,14 @@
         @ColorInt
         final int expectedColor = Color.rgb(255, 191, 191);
         createTest()
-                .addLayout(R.layout.simple_red_layout, new ViewInitializer() {
-                    @Override
-                    public void initializeView(View view) {
-                        // reduce alpha by 50%
-                        Paint paint = new Paint();
-                        paint.setAlpha(128);
-                        view.setLayerType(View.LAYER_TYPE_HARDWARE, paint);
+                .addLayout(R.layout.simple_red_layout, (ViewInitializer) view -> {
+                    // reduce alpha by 50%
+                    Paint paint = new Paint();
+                    paint.setAlpha(128);
+                    view.setLayerType(View.LAYER_TYPE_HARDWARE, paint);
 
-                        // reduce alpha by another 50% (ensuring two alphas combine correctly)
-                        view.setAlpha(0.5f);
-                    }
+                    // reduce alpha by another 50% (ensuring two alphas combine correctly)
+                    view.setAlpha(0.5f);
                 })
                 .runWithVerifier(new ColorVerifier(expectedColor));
     }
@@ -65,15 +62,12 @@
         @ColorInt
         final int expectedColor = Color.rgb(54, 54, 54);
         createTest()
-                .addLayout(R.layout.simple_red_layout, new ViewInitializer() {
-                    @Override
-                    public void initializeView(View view) {
-                        Paint paint = new Paint();
-                        ColorMatrix desatMatrix = new ColorMatrix();
-                        desatMatrix.setSaturation(0.0f);
-                        paint.setColorFilter(new ColorMatrixColorFilter(desatMatrix));
-                        view.setLayerType(View.LAYER_TYPE_HARDWARE, paint);
-                    }
+                .addLayout(R.layout.simple_red_layout, (ViewInitializer) view -> {
+                    Paint paint = new Paint();
+                    ColorMatrix desatMatrix = new ColorMatrix();
+                    desatMatrix.setSaturation(0.0f);
+                    paint.setColorFilter(new ColorMatrixColorFilter(desatMatrix));
+                    view.setLayerType(View.LAYER_TYPE_HARDWARE, paint);
                 })
                 .runWithVerifier(new ColorVerifier(expectedColor));
     }
@@ -85,20 +79,17 @@
         @ColorInt
         final int expectedColor = Color.WHITE;
         createTest()
-                .addLayout(R.layout.simple_red_layout, new ViewInitializer() {
-                    @Override
-                    public void initializeView(View view) {
-                        Paint paint = new Paint();
-                        /* Note that when drawing in SW, we're blending within an otherwise empty
-                         * SW layer, as opposed to in the frame buffer (which has a white
-                         * background).
-                         *
-                         * For this reason we use just use DST, which just throws out the SRC
-                         * content, regardless of the DST alpha channel.
-                         */
-                        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST));
-                        view.setLayerType(View.LAYER_TYPE_HARDWARE, paint);
-                    }
+                .addLayout(R.layout.simple_red_layout, (ViewInitializer) view -> {
+                    Paint paint = new Paint();
+                    /* Note that when drawing in SW, we're blending within an otherwise empty
+                     * SW layer, as opposed to in the frame buffer (which has a white
+                     * background).
+                     *
+                     * For this reason we use just use DST, which just throws out the SRC
+                     * content, regardless of the DST alpha channel.
+                     */
+                    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST));
+                    view.setLayerType(View.LAYER_TYPE_HARDWARE, paint);
                 })
                 .runWithVerifier(new ColorVerifier(expectedColor));
     }
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/PathClippingTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/PathClippingTests.java
index 03f5e89..7c8a301 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/PathClippingTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/PathClippingTests.java
@@ -40,57 +40,41 @@
 @MediumTest
 public class PathClippingTests extends ActivityTestBase {
     // draw circle with hole in it, with stroked circle
-    static final CanvasClient sTorusDrawCanvasClient = new CanvasClient() {
-        @Override
-        public String getDebugString() {
-            return "TorusDraw";
-        }
-
-        @Override
-        public void draw(Canvas canvas, int width, int height) {
-            Paint paint = new Paint();
-            paint.setAntiAlias(false);
-            paint.setColor(Color.BLUE);
-            paint.setStyle(Paint.Style.STROKE);
-            paint.setStrokeWidth(20);
-            canvas.drawCircle(30, 30, 40, paint);
-        }
+    static final CanvasClient sTorusDrawCanvasClient = (canvas, width, height) -> {
+        Paint paint = new Paint();
+        paint.setAntiAlias(false);
+        paint.setColor(Color.BLUE);
+        paint.setStyle(Paint.Style.STROKE);
+        paint.setStrokeWidth(20);
+        canvas.drawCircle(30, 30, 40, paint);
     };
 
     // draw circle with hole in it, by path operations + path clipping
-    static final CanvasClient sTorusClipCanvasClient = new CanvasClient() {
-        @Override
-        public String getDebugString() {
-            return "TorusClipDraw";
-        }
+    static final CanvasClient sTorusClipCanvasClient = (canvas, width, height) -> {
+        canvas.save();
 
-        @Override
-        public void draw(Canvas canvas, int width, int height) {
-            canvas.save();
+        Path path = new Path();
+        path.addCircle(30, 30, 50, Path.Direction.CW);
+        path.addCircle(30, 30, 30, Path.Direction.CCW);
 
-            Path path = new Path();
-            path.addCircle(30, 30, 50, Path.Direction.CW);
-            path.addCircle(30, 30, 30, Path.Direction.CCW);
+        canvas.clipPath(path);
+        canvas.drawColor(Color.BLUE);
 
-            canvas.clipPath(path);
-            canvas.drawColor(Color.BLUE);
-
-            canvas.restore();
-        }
+        canvas.restore();
     };
 
     @Test
     public void testCircleWithCircle() {
         createTest()
-                .addCanvasClient(sTorusDrawCanvasClient, false)
-                .addCanvasClient(sTorusClipCanvasClient)
+                .addCanvasClient("TorusDraw", sTorusDrawCanvasClient, false)
+                .addCanvasClient("TorusClip", sTorusClipCanvasClient)
                 .runWithComparer(new MSSIMComparer(0.90));
     }
 
     @Test
     public void testCircleWithPoints() {
         createTest()
-                .addCanvasClient(sTorusClipCanvasClient)
+                .addCanvasClient("TorusClip", sTorusClipCanvasClient)
                 .runWithVerifier(new SamplePointVerifier(
                         new Point[] {
                                 // inside of circle
@@ -112,17 +96,13 @@
     @Test
     public void testViewRotate() {
         createTest()
-                .addLayout(R.layout.blue_padded_layout, new ViewInitializer() {
-                    @Override
-                    public void initializeView(View view) {
-                        ViewGroup rootView = (ViewGroup) view;
-                        rootView.setClipChildren(true);
-                        View childView = rootView.getChildAt(0);
-                        childView.setPivotX(40);
-                        childView.setPivotY(40);
-                        childView.setRotation(45f);
-
-                    }
+                .addLayout(R.layout.blue_padded_layout, (ViewInitializer) view -> {
+                    ViewGroup rootView = (ViewGroup) view;
+                    rootView.setClipChildren(true);
+                    View childView = rootView.getChildAt(0);
+                    childView.setPivotX(40);
+                    childView.setPivotY(40);
+                    childView.setRotation(45f);
                 })
                 .runWithVerifier(new SamplePointVerifier(
                         new Point[] {
@@ -144,24 +124,21 @@
     @Test
     public void testTextClip() {
         createTest()
-                .addCanvasClient(new CanvasClient() {
-                    @Override
-                    public void draw(Canvas canvas, int width, int height) {
-                        canvas.save();
+                .addCanvasClient((canvas, width, height) -> {
+                    canvas.save();
 
-                        Path path = new Path();
-                        path.addCircle(0, 45, 45, Path.Direction.CW);
-                        path.addCircle(90, 45, 45, Path.Direction.CW);
-                        canvas.clipPath(path);
+                    Path path = new Path();
+                    path.addCircle(0, 45, 45, Path.Direction.CW);
+                    path.addCircle(90, 45, 45, Path.Direction.CW);
+                    canvas.clipPath(path);
 
-                        Paint paint = new Paint();
-                        paint.setAntiAlias(true);
-                        paint.setTextSize(90);
-                        paint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
-                        canvas.drawText("STRING", 0, 90, paint);
+                    Paint paint = new Paint();
+                    paint.setAntiAlias(true);
+                    paint.setTextSize(90);
+                    paint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
+                    canvas.drawText("STRING", 0, 90, paint);
 
-                        canvas.restore();
-                    }
+                    canvas.restore();
                 })
                 .runWithComparer(new MSSIMComparer(0.90));
     }
@@ -173,23 +150,17 @@
         }
         createTest()
                 // golden client - draw a simple non-AA circle
-                .addCanvasClient(new CanvasClient() {
-                    @Override
-                    public void draw(Canvas canvas, int width, int height) {
-                        Paint paint = new Paint();
-                        paint.setAntiAlias(false);
-                        paint.setColor(Color.BLUE);
-                        canvas.drawOval(0, 0, width, height, paint);
-                    }
+                .addCanvasClient((canvas, width, height) -> {
+                    Paint paint = new Paint();
+                    paint.setAntiAlias(false);
+                    paint.setColor(Color.BLUE);
+                    canvas.drawOval(0, 0, width, height, paint);
                 }, false)
                 // verify against solid color webview, clipped to its parent oval
-                .addLayout(R.layout.circle_clipped_webview, new ViewInitializer() {
-                    @Override
-                    public void initializeView(View view) {
-                        WebView webview = (WebView)view.findViewById(R.id.webview);
-                        assertNotNull(webview);
-                        webview.loadData("<body style=\"background-color:blue\">", null, null);
-                    }
+                .addLayout(R.layout.circle_clipped_webview, (ViewInitializer) view -> {
+                    WebView webview = (WebView)view.findViewById(R.id.webview);
+                    assertNotNull(webview);
+                    webview.loadData("<body style=\"background-color:blue\">", null, null);
                 })
                 .runWithComparer(new MSSIMComparer(0.95));
     }
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/PictureTest.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/PictureTest.java
index 9c8f9ba..a2f3730 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/PictureTest.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/PictureTest.java
@@ -25,7 +25,6 @@
 import android.uirendering.cts.bitmapverifiers.ColorVerifier;
 import android.uirendering.cts.bitmapverifiers.RectVerifier;
 import android.uirendering.cts.testinfrastructure.ActivityTestBase;
-import android.uirendering.cts.testinfrastructure.CanvasClient;
 import org.junit.Test;
 
 @MediumTest
@@ -38,8 +37,8 @@
         Paint pt = new Paint();
         pt.setColor(Color.GREEN);
         Picture pic = new Picture();
-        Canvas subcanvas = pic.beginRecording(ActivityTestBase.TEST_WIDTH,
-                                              ActivityTestBase.TEST_HEIGHT);
+        Canvas subcanvas = pic.beginRecording(
+                ActivityTestBase.TEST_WIDTH, ActivityTestBase.TEST_HEIGHT);
         subcanvas.drawRect(sRect, pt);
         pic.endRecording();
 
@@ -50,14 +49,11 @@
     public void testPictureRespectsClip() throws Exception {
         createTest()
             .addCanvasClient(
-                new CanvasClient() {
-                    @Override
-                    public void draw(Canvas canvas, int width, int height) {
+                    (canvas, width, height) -> {
                         Picture pic = greenSquare();
                         canvas.clipRect(sOffsetRect);
                         pic.draw(canvas);  // should be clipped out
                     }
-                }
             ).runWithVerifier(new ColorVerifier(Color.WHITE));
     }
 
@@ -65,14 +61,11 @@
     public void testPictureRespectsTranslate() throws Exception {
         createTest()
             .addCanvasClient(
-                new CanvasClient() {
-                    @Override
-                    public void draw(Canvas canvas, int width, int height) {
+                    (canvas, width, height) -> {
                         Picture pic = greenSquare();
                         canvas.translate(40, 0);
                         pic.draw(canvas);  // should be offset
                     }
-                }
             ).runWithVerifier(
                 new RectVerifier(Color.WHITE, Color.GREEN, sOffsetRect));
     }
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/SweepTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/SweepTests.java
index f5f59b3..3f51bbe 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/SweepTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/SweepTests.java
@@ -108,23 +108,21 @@
         ResourceModifier.init(getActivity().getResources());
         // For each modification combination, we will get the CanvasClient associated with it and
         // from there execute a normal canvas test with that.
-        CanvasClient canvasClient = new CanvasClient() {
-            @Override
-            public void draw(Canvas canvas, int width, int height) {
-                Paint paint = new Paint();
-                modifierAccessor.modifyDrawing(canvas, paint);
-                if (drawOp != null) {
-                    drawOp.modifyDrawing(paint, canvas);
-                }
+        CanvasClient canvasClient = (canvas, width, height) -> {
+            Paint paint = new Paint();
+            modifierAccessor.modifyDrawing(canvas, paint);
+            if (drawOp != null) {
+                drawOp.modifyDrawing(paint, canvas);
             }
         };
 
         int index = 0;
         // Create the test cases with each combination
         do {
-            canvasClient.setDebugString(modifierAccessor.getDebugString());
             int arrIndex = Math.min(index, bitmapComparers.length - 1);
-            createTest().addCanvasClient(canvasClient).runWithComparer(bitmapComparers[arrIndex]);
+            createTest()
+                    .addCanvasClient(modifierAccessor.getDebugString(), canvasClient)
+                    .runWithComparer(bitmapComparers[arrIndex]);
             index++;
         } while (modifierAccessor.step());
     }
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ViewClippingTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ViewClippingTests.java
index 3b1df30..c8ca8c3 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ViewClippingTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ViewClippingTests.java
@@ -2,6 +2,7 @@
 
 import android.graphics.Color;
 import android.graphics.Outline;
+import android.graphics.Path;
 import android.graphics.Rect;
 import android.test.suitebuilder.annotation.MediumTest;
 import android.uirendering.cts.bitmapverifiers.BitmapVerifier;
@@ -15,6 +16,8 @@
 import android.uirendering.cts.R;
 import org.junit.Test;
 
+import static org.junit.Assert.assertFalse;
+
 /**
  * This tests view clipping by modifying properties of blue_padded_layout, and validating
  * the resulting rect of content.
@@ -23,46 +26,35 @@
  */
 @MediumTest
 public class ViewClippingTests extends ActivityTestBase {
-    final Rect FULL_RECT = new Rect(0, 0, 90, 90);
-    final Rect BOUNDS_RECT = new Rect(0, 0, 80, 80);
-    final Rect PADDED_RECT = new Rect(15, 16, 63, 62);
-    final Rect OUTLINE_RECT = new Rect(1, 2, 78, 79);
-    final Rect CLIP_BOUNDS_RECT = new Rect(10, 20, 50, 60);
+    static final Rect FULL_RECT = new Rect(0, 0, 90, 90);
+    static final Rect BOUNDS_RECT = new Rect(0, 0, 80, 80);
+    static final Rect PADDED_RECT = new Rect(15, 16, 63, 62);
+    static final Rect OUTLINE_RECT = new Rect(1, 2, 78, 79);
+    static final Rect CLIP_BOUNDS_RECT = new Rect(10, 20, 50, 60);
 
-    final ViewInitializer BOUNDS_CLIP_INIT = new ViewInitializer() {
-        @Override
-        public void initializeView(View rootView) {
-            ((ViewGroup)rootView).setClipChildren(true);
-        }
+    static final ViewInitializer BOUNDS_CLIP_INIT =
+            rootView -> ((ViewGroup)rootView).setClipChildren(true);
+
+    static final ViewInitializer PADDING_CLIP_INIT = rootView -> {
+        ViewGroup child = (ViewGroup) rootView.findViewById(R.id.child);
+        child.setClipToPadding(true);
+        child.setWillNotDraw(true);
+        child.addView(new UnclippedBlueView(rootView.getContext()));
     };
-    final ViewInitializer PADDING_CLIP_INIT = new ViewInitializer() {
-        @Override
-        public void initializeView(View rootView) {
-            ViewGroup child = (ViewGroup) rootView.findViewById(R.id.child);
-            child.setClipToPadding(true);
-            child.setWillNotDraw(true);
-            child.addView(new UnclippedBlueView(rootView.getContext()));
-        }
+
+    static final ViewInitializer OUTLINE_CLIP_INIT = rootView -> {
+        View child = rootView.findViewById(R.id.child);
+        child.setOutlineProvider(new ViewOutlineProvider() {
+            @Override
+            public void getOutline(View view, Outline outline) {
+                outline.setRect(OUTLINE_RECT);
+            }
+        });
+        child.setClipToOutline(true);
     };
-    final ViewInitializer OUTLINE_CLIP_INIT = new ViewInitializer() {
-        @Override
-        public void initializeView(View rootView) {
-            View child = rootView.findViewById(R.id.child);
-            child.setOutlineProvider(new ViewOutlineProvider() {
-                @Override
-                public void getOutline(View view, Outline outline) {
-                    outline.setRect(OUTLINE_RECT);
-                }
-            });
-            child.setClipToOutline(true);
-        }
-    };
-    final ViewInitializer CLIP_BOUNDS_CLIP_INIT = new ViewInitializer() {
-        @Override
-        public void initializeView(View view) {
-            view.setClipBounds(CLIP_BOUNDS_RECT);
-        }
-    };
+
+    static final ViewInitializer CLIP_BOUNDS_CLIP_INIT =
+            view -> view.setClipBounds(CLIP_BOUNDS_RECT);
 
     static BitmapVerifier makeClipVerifier(Rect blueBoundsRect) {
         // very high error tolerance, since all these tests care about is clip alignment
@@ -96,6 +88,7 @@
                 .addLayout(R.layout.blue_padded_layout, PADDING_CLIP_INIT)
                 .runWithVerifier(makeClipVerifier(PADDED_RECT));
     }
+    // TODO: add tests with clip + scroll, and with interesting combinations of the above
 
     @Test
     public void testSimpleOutlineClip() {
@@ -110,5 +103,25 @@
                 .runWithVerifier(makeClipVerifier(FULL_RECT));
     }
 
-    // TODO: add tests with clip + scroll, and with interesting combinations of the above
+    @Test
+    public void testOvalOutlineClip() {
+        // In hw this works because clipping to a non-round rect isn't supported, and is no-op'd.
+        // In sw this works because Outline clipping isn't supported.
+        createTest()
+                .addLayout(R.layout.blue_padded_layout, view -> {
+                    view.setOutlineProvider(new ViewOutlineProvider() {
+                        Path mPath = new Path();
+                        @Override
+                        public void getOutline(View view, Outline outline) {
+                            mPath.reset();
+                            mPath.addOval(0, 0, view.getWidth(), view.getHeight(),
+                                    Path.Direction.CW);
+                            outline.setConvexPath(mPath);
+                            assertFalse(outline.canClip()); // NOTE: non-round-rect, so can't clip
+                        }
+                    });
+                    view.setClipToOutline(true); // should do nothing, since non-rect clip
+                })
+                .runWithVerifier(makeClipVerifier(FULL_RECT));
+    }
 }
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/ActivityTestBase.java b/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/ActivityTestBase.java
index f82bb40..e634528 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/ActivityTestBase.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/ActivityTestBase.java
@@ -145,7 +145,7 @@
     protected Bitmap captureRenderSpec(TestCase testCase) {
         Point testOffset = getActivity().enqueueRenderSpecAndWait(
                 testCase.layoutID, testCase.canvasClient,
-                testCase.webViewUrl, testCase.viewInitializer, testCase.useHardware);
+                null, testCase.viewInitializer, testCase.useHardware);
         testCase.wasTestRan = true;
         return takeScreenshot(testOffset);
     }
@@ -260,36 +260,33 @@
             });
         }
 
-        public TestCaseBuilder addWebView(String webViewUrl,
-                @Nullable ViewInitializer viewInitializer) {
-            return addWebView(webViewUrl, viewInitializer, false)
-                    .addWebView(webViewUrl, viewInitializer, true);
-        }
-
         public TestCaseBuilder addLayout(int layoutId, @Nullable ViewInitializer viewInitializer) {
             return addLayout(layoutId, viewInitializer, false)
                     .addLayout(layoutId, viewInitializer, true);
         }
 
-        public TestCaseBuilder addCanvasClient(CanvasClient canvasClient) {
-            return addCanvasClient(canvasClient, false)
-                    .addCanvasClient(canvasClient, true);
-        }
-
-        public TestCaseBuilder addWebView(String webViewUrl,
-                @Nullable ViewInitializer viewInitializer, boolean useHardware) {
-            mTestCases.add(new TestCase(null, 0, webViewUrl, viewInitializer, useHardware));
-            return this;
-        }
-
         public TestCaseBuilder addLayout(int layoutId, @Nullable ViewInitializer viewInitializer,
-                boolean useHardware) {
-            mTestCases.add(new TestCase(null, layoutId, null, viewInitializer, useHardware));
+                                         boolean useHardware) {
+            mTestCases.add(new TestCase(layoutId, viewInitializer, useHardware));
             return this;
         }
 
+        public TestCaseBuilder addCanvasClient(CanvasClient canvasClient) {
+            return addCanvasClient(null, canvasClient);
+        }
+
         public TestCaseBuilder addCanvasClient(CanvasClient canvasClient, boolean useHardware) {
-            mTestCases.add(new TestCase(canvasClient, 0, null, null, useHardware));
+            return addCanvasClient(null, canvasClient, useHardware);
+        }
+
+        public TestCaseBuilder addCanvasClient(String debugString, CanvasClient canvasClient) {
+            return addCanvasClient(debugString, canvasClient, false)
+                    .addCanvasClient(debugString, canvasClient, true);
+        }
+
+        public TestCaseBuilder addCanvasClient(String debugString,
+                    CanvasClient canvasClient, boolean useHardware) {
+            mTestCases.add(new TestCase(canvasClient, debugString, useHardware));
             return this;
         }
 
@@ -300,39 +297,35 @@
 
     private class TestCase {
         public int layoutID;
-        public CanvasClient canvasClient;
-        public String webViewUrl;
         public ViewInitializer viewInitializer;
-        public boolean useHardware;
-        public boolean wasTestRan;
 
-        public TestCase(CanvasClient client, int id, String viewUrl,
-                ViewInitializer viewInitializer, boolean useHardware) {
-            int count = 0;
-            count += (client == null ? 0 : 1);
-            count += (viewUrl == null ? 0 : 1);
-            count += (id == 0 ? 0 : 1);
-            assert(count == 1);
-            assert(client == null || viewInitializer == null);
-            this.layoutID = id;
-            this.canvasClient = client;
-            this.webViewUrl = viewUrl;
+        public CanvasClient canvasClient;
+        public String canvasClientDebugString;
+
+        public boolean useHardware;
+        public boolean wasTestRan = false;
+
+        public TestCase(int layoutId, ViewInitializer viewInitializer, boolean useHardware) {
+            this.layoutID = layoutId;
             this.viewInitializer = viewInitializer;
             this.useHardware = useHardware;
-            this.wasTestRan = false;
+        }
+
+        public TestCase(CanvasClient client, String debugString, boolean useHardware) {
+            this.canvasClient = client;
+            this.canvasClientDebugString = debugString;
+            this.useHardware = useHardware;
         }
 
         public String getDebugString() {
             String debug = "";
             if (canvasClient != null) {
                 debug += "CanvasClient : ";
-                if (canvasClient.getDebugString() != null) {
-                    debug += canvasClient.getDebugString();
+                if (canvasClientDebugString != null) {
+                    debug += canvasClientDebugString;
                 } else {
                     debug += "no debug string given";
                 }
-            } else if (webViewUrl != null) {
-                debug += "WebView URL : " + webViewUrl;
             } else {
                 debug += "Layout resource : " +
                         getActivity().getResources().getResourceName(layoutID);
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/CanvasClient.java b/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/CanvasClient.java
index a99c576..99f6cc7 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/CanvasClient.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/CanvasClient.java
@@ -20,16 +20,6 @@
 /**
  * A class that the tester will implement and create a set of drawing calls the tests would use
  */
-public abstract class CanvasClient {
-    private String mDebugString;
-
-    public abstract void draw(Canvas canvas, int width, int height);
-
-    public String getDebugString() {
-        return mDebugString;
-    }
-
-    public void setDebugString(String debugString) {
-        mDebugString = debugString;
-    }
+public interface CanvasClient {
+    void draw(Canvas canvas, int width, int height);
 }
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/ViewInitializer.java b/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/ViewInitializer.java
index 9a3cbb1..43e1fa6 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/ViewInitializer.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/ViewInitializer.java
@@ -20,6 +20,6 @@
 /**
  * Called after a view is created to set various properties on the view
  */
-public abstract class ViewInitializer {
-    public abstract void initializeView(View view);
+public interface ViewInitializer {
+    void initializeView(View view);
 }
diff --git a/tests/tests/view/src/android/view/cts/ContextThemeWrapperTest.java b/tests/tests/view/src/android/view/cts/ContextThemeWrapperTest.java
index b25f733..ccf37949 100644
--- a/tests/tests/view/src/android/view/cts/ContextThemeWrapperTest.java
+++ b/tests/tests/view/src/android/view/cts/ContextThemeWrapperTest.java
@@ -17,6 +17,7 @@
 package android.view.cts;
 
 import android.content.Context;
+import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.content.res.Resources.Theme;
@@ -25,7 +26,6 @@
 
 import android.view.cts.R;
 
-
 public class ContextThemeWrapperTest extends AndroidTestCase {
     private static final int SYSTEM_DEFAULT_THEME = 0;
 
@@ -103,6 +103,22 @@
         }).test());
     }
 
+    public void testApplyOverrideConfiguration() {
+        Context context = getContext();
+        final int realDensity = context.getResources().getConfiguration().densityDpi;
+        final int expectedDensity = realDensity + 1;
+
+        ContextThemeWrapper contextThemeWrapper = new ContextThemeWrapper(
+                context, SYSTEM_DEFAULT_THEME);
+
+        Configuration overrideConfig = new Configuration();
+        overrideConfig.densityDpi = expectedDensity;
+        contextThemeWrapper.applyOverrideConfiguration(overrideConfig);
+
+        Configuration actualConfiguration = contextThemeWrapper.getResources().getConfiguration();
+        assertEquals(expectedDensity, actualConfiguration.densityDpi);
+    }
+
     private void assertEqualsTextAppearanceStyle(TypedArray ta) {
         final int defValue = -1;
         // get Theme and assert
diff --git a/tests/tests/widget/AndroidManifest.xml b/tests/tests/widget/AndroidManifest.xml
index 5acfc18..dcfe4c1 100644
--- a/tests/tests/widget/AndroidManifest.xml
+++ b/tests/tests/widget/AndroidManifest.xml
@@ -77,7 +77,15 @@
         </activity>
 
         <activity android:name="android.widget.cts.ImageViewCtsActivity"
-            android:label="ImageViewCtsActivity">
+                  android:label="ImageViewCtsActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name="android.widget.cts.SwitchCtsActivity"
+                  android:label="SwitchCtsActivity">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
@@ -352,6 +360,14 @@
             </intent-filter>
         </activity>
 
+        <activity android:name="android.widget.cts.CalendarViewCtsActivity"
+                  android:label="CalendarViewCtsActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+            </intent-filter>
+        </activity>
+
         <activity android:name="android.app.ActivityGroup"
             android:label="ActivityGroup" />
 
diff --git a/tests/tests/widget/res/drawable/magenta_fill.xml b/tests/tests/widget/res/drawable/magenta_fill.xml
new file mode 100644
index 0000000..cbb594f
--- /dev/null
+++ b/tests/tests/widget/res/drawable/magenta_fill.xml
@@ -0,0 +1,21 @@
+<?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.
+-->
+
+<shape
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <solid android:color="#FF00FF" />
+</shape>
\ No newline at end of file
diff --git a/tests/tests/widget/res/drawable/yellow_fill.xml b/tests/tests/widget/res/drawable/yellow_fill.xml
new file mode 100644
index 0000000..3bd8097
--- /dev/null
+++ b/tests/tests/widget/res/drawable/yellow_fill.xml
@@ -0,0 +1,21 @@
+<?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.
+-->
+
+<shape
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <solid android:color="#FFFF00" />
+</shape>
\ No newline at end of file
diff --git a/tests/tests/widget/res/layout/calendarview_layout.xml b/tests/tests/widget/res/layout/calendarview_layout.xml
new file mode 100644
index 0000000..3bc5e47
--- /dev/null
+++ b/tests/tests/widget/res/layout/calendarview_layout.xml
@@ -0,0 +1,57 @@
+<?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
+  -->
+
+<ScrollView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:fillViewport="true">
+
+    <LinearLayout
+        android:id="@+id/container"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical">
+
+        <CalendarView
+            android:id="@+id/calendar_view_material"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:firstDayOfWeek="2"
+            android:dateTextAppearance="@style/TextAppearance.WithColor"
+            android:weekDayTextAppearance="@style/TextAppearance.WithColorGreen" />
+
+        <!-- CalendarView in Holo Light style for testing attributes and APIs that control
+             the deprecated visual aspects of this widget. -->
+        <CalendarView
+            style="@android:style/Widget.Holo.Light.CalendarView"
+            android:id="@+id/calendar_view_holoyolo"
+            android:layout_width="match_parent"
+            android:layout_height="320dip"
+            android:firstDayOfWeek="3"
+            android:shownWeekCount="5"
+            android:showWeekNumber="false"
+            android:selectedWeekBackgroundColor="@color/calendarview_week_background"
+            android:focusedMonthDateColor="@color/calendarview_focusedmonthdate"
+            android:unfocusedMonthDateColor="@color/calendarview_unfocusedmonthdate"
+            android:dateTextAppearance="@style/TextAppearance.WithColor"
+            android:weekDayTextAppearance="@style/TextAppearance.WithColorGreen"
+            android:selectedDateVerticalBar="@drawable/blue_fill" />
+
+    </LinearLayout>
+
+</ScrollView>
diff --git a/tests/tests/widget/res/layout/popupwindow.xml b/tests/tests/widget/res/layout/popupwindow.xml
index d84770d..cf69831 100644
--- a/tests/tests/widget/res/layout/popupwindow.xml
+++ b/tests/tests/widget/res/layout/popupwindow.xml
@@ -20,40 +20,76 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent">
 
-    <android.widget.cts.MockViewForListPopupWindow
+    <View
         android:id="@+id/anchor_upper_left"
         android:layout_width="10dp"
         android:layout_height="10dp"
-        android:layout_alignParentTop="true"
         android:layout_alignParentLeft="true"
-        android:background="#f0f" />
-
-    <View android:id="@+id/anchor_upper"
-        android:layout_width="10dp"
-        android:layout_height="30dp"
         android:layout_alignParentTop="true"
-        android:layout_centerHorizontal="true"
         android:background="#f00" />
 
-    <View android:id="@+id/anchor_lower"
+    <View
+        android:id="@+id/anchor_upper"
         android:layout_width="10dp"
-        android:layout_height="30dp"
-        android:layout_alignParentBottom="true"
+        android:layout_height="10dp"
         android:layout_centerHorizontal="true"
-        android:background="#0f0" />
+        android:layout_alignParentTop="true"
+        android:background="#f00" />
 
-    <View android:id="@+id/anchor_middle_left"
-        android:layout_width="30dp"
+    <View
+        android:id="@+id/anchor_upper_right"
+        android:layout_width="10dp"
+        android:layout_height="10dp"
+        android:layout_alignParentRight="true"
+        android:layout_alignParentTop="true"
+        android:background="#f00" />
+
+    <View
+        android:id="@+id/anchor_middle_left"
+        android:layout_width="10dp"
         android:layout_height="10dp"
         android:layout_alignParentLeft="true"
         android:layout_centerVertical="true"
-        android:background="#00f" />
+        android:background="#0f0" />
 
-    <View android:id="@+id/anchor_middle_right"
-        android:layout_width="30dp"
+    <View
+        android:id="@+id/anchor_middle"
+        android:layout_width="10dp"
+        android:layout_height="10dp"
+        android:layout_centerHorizontal="true"
+        android:layout_centerVertical="true"
+        android:background="#0f0" />
+
+    <View
+        android:id="@+id/anchor_middle_right"
+        android:layout_width="10dp"
         android:layout_height="10dp"
         android:layout_alignParentRight="true"
         android:layout_centerVertical="true"
-        android:background="#ff0" />
+        android:background="#0f0" />
+
+    <View
+        android:id="@+id/anchor_lower_left"
+        android:layout_width="10dp"
+        android:layout_height="10dp"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentBottom="true"
+        android:background="#00f" />
+
+    <View
+        android:id="@+id/anchor_lower"
+        android:layout_width="10dp"
+        android:layout_height="10dp"
+        android:layout_centerHorizontal="true"
+        android:layout_alignParentBottom="true"
+        android:background="#00f" />
+
+    <View
+        android:id="@+id/anchor_lower_right"
+        android:layout_width="10dp"
+        android:layout_height="10dp"
+        android:layout_alignParentRight="true"
+        android:layout_alignParentBottom="true"
+        android:background="#00f" />
 
 </RelativeLayout>
diff --git a/tests/tests/widget/res/layout/switch_layout.xml b/tests/tests/widget/res/layout/switch_layout.xml
index a34845b..12e10d2 100644
--- a/tests/tests/widget/res/layout/switch_layout.xml
+++ b/tests/tests/widget/res/layout/switch_layout.xml
@@ -16,6 +16,7 @@
   -->
 
 <Switch xmlns:android="http://schemas.android.com/apk/res/android"
+        android:id="@+id/switch_view"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:thumbTint="@android:color/white"
diff --git a/tests/tests/widget/res/values/colors.xml b/tests/tests/widget/res/values/colors.xml
index f3cc325..f104a6d2 100644
--- a/tests/tests/widget/res/values/colors.xml
+++ b/tests/tests/widget/res/values/colors.xml
@@ -23,4 +23,14 @@
     <color name="testcolor1">#ff00ff00</color>
     <color name="testcolor2">#ffff0000</color>
     <color name="failColor">#ff0000ff</color>
+
+    <color name="calendarview_week_background">#40FF0000</color>
+    <color name="calendarview_focusedmonthdate">#9080A0FF</color>
+    <color name="calendarview_unfocusedmonthdate">#9070F080</color>
+
+    <color name="calendarview_week_background_new">#60808000</color>
+    <color name="calendarview_focusedmonthdate_new">#A0B020FF</color>
+    <color name="calendarview_unfocusedmonthdate_new">#4070F0F0</color>
+    <color name="calendarview_week_number_new">#9090FF</color>
+    <color name="calendarview_week_separatorline_new">#AFAF00</color>
 </resources>
diff --git a/tests/tests/widget/res/values/styles.xml b/tests/tests/widget/res/values/styles.xml
index da22652..345b450 100644
--- a/tests/tests/widget/res/values/styles.xml
+++ b/tests/tests/widget/res/values/styles.xml
@@ -71,6 +71,18 @@
         <item name="android:textColor">#ffff0000</item>
     </style>
 
+    <style name="TextAppearance.WithColorGreen">
+        <item name="android:textColor">#ff00ff00</item>
+    </style>
+
+    <style name="TextAppearance.WithColorBlue">
+        <item name="android:textColor">#ff0000ff</item>
+    </style>
+
+    <style name="TextAppearance.WithColorMagenta">
+        <item name="android:textColor">#ffff00ff</item>
+    </style>
+
     <style name="TextAppearance.All">
         <item name="android:textColor">@drawable/black</item>
         <item name="android:textSize">20px</item>
@@ -188,4 +200,6 @@
         <item name="android:tabStripLeft">@drawable/icon_green</item>
         <item name="android:tabStripRight">@drawable/icon_red</item>
     </style>
+
+    <style name="ToolbarPopupTheme_Test" parent="@android:style/ThemeOverlay.Material.Light" />
 </resources>
diff --git a/tests/tests/widget/src/android/widget/cts/CalendarViewCtsActivity.java b/tests/tests/widget/src/android/widget/cts/CalendarViewCtsActivity.java
new file mode 100644
index 0000000..b0a15bf
--- /dev/null
+++ b/tests/tests/widget/src/android/widget/cts/CalendarViewCtsActivity.java
@@ -0,0 +1,37 @@
+/*
+ * 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.widget.cts;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.CalendarView;
+import android.widget.Toolbar;
+
+/**
+ * A minimal application for {@link CalendarView} test.
+ */
+public class CalendarViewCtsActivity extends Activity {
+    /**
+     * Called with the activity is first created.
+     */
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.calendarview_layout);
+    }
+}
+
diff --git a/tests/tests/widget/src/android/widget/cts/CalendarViewTest.java b/tests/tests/widget/src/android/widget/cts/CalendarViewTest.java
new file mode 100644
index 0000000..31ad341
--- /dev/null
+++ b/tests/tests/widget/src/android/widget/cts/CalendarViewTest.java
@@ -0,0 +1,210 @@
+/*
+ * 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.widget.cts;
+
+import android.annotation.ColorInt;
+import android.app.Instrumentation;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.widget.CalendarView;
+import android.widget.cts.util.TestUtils;
+
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+
+@MediumTest
+public class CalendarViewTest extends ActivityInstrumentationTestCase2<CalendarViewCtsActivity> {
+    private CalendarViewCtsActivity mActivity;
+    private CalendarView mCalendarViewMaterial;
+    private CalendarView mCalendarViewHolo;
+
+    public CalendarViewTest() {
+        super("android.widget.cts", CalendarViewCtsActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mActivity = getActivity();
+        mCalendarViewMaterial = (CalendarView) mActivity.findViewById(R.id.calendar_view_material);
+        mCalendarViewHolo = (CalendarView) mActivity.findViewById(R.id.calendar_view_holoyolo);
+
+        // Initialize both calendar views to the current date
+        final long currentDate = new GregorianCalendar().getTime().getTime();
+        getInstrumentation().runOnMainSync(() -> {
+            mCalendarViewMaterial.setDate(currentDate);
+            mCalendarViewHolo.setDate(currentDate);
+        });
+    }
+
+    public void testConstructor() {
+        new CalendarView(mActivity);
+
+        new CalendarView(mActivity, null);
+
+        new CalendarView(mActivity, null, android.R.attr.calendarViewStyle);
+
+        new CalendarView(mActivity, null, 0, android.R.style.Widget_Material_Light_CalendarView);
+    }
+
+    public void testAccessDate() {
+        final Instrumentation instrumentation = getInstrumentation();
+
+        // Go back one year
+        final Calendar newCalendar = new GregorianCalendar();
+        newCalendar.set(Calendar.YEAR, newCalendar.get(Calendar.YEAR) - 1);
+        final long yearAgoDate = newCalendar.getTime().getTime();
+
+        instrumentation.runOnMainSync(
+                () -> mCalendarViewMaterial.setDate(yearAgoDate));
+        assertEquals(yearAgoDate, mCalendarViewMaterial.getDate());
+
+        // Go forward two years (one year from current date in aggregate)
+        newCalendar.set(Calendar.YEAR, newCalendar.get(Calendar.YEAR) + 2);
+        final long yearHenceDate = newCalendar.getTime().getTime();
+
+        instrumentation.runOnMainSync(
+                () -> mCalendarViewMaterial.setDate(yearHenceDate, true, false));
+        assertEquals(yearHenceDate, mCalendarViewMaterial.getDate());
+    }
+
+    public void testAccessMinMaxDate() {
+        final Instrumentation instrumentation = getInstrumentation();
+
+        // Use a range of minus/plus one year as min/max dates
+        final Calendar minCalendar = new GregorianCalendar();
+        minCalendar.set(Calendar.YEAR, minCalendar.get(Calendar.YEAR) - 1);
+        final Calendar maxCalendar = new GregorianCalendar();
+        maxCalendar.set(Calendar.YEAR, maxCalendar.get(Calendar.YEAR) + 1);
+
+        final long minDate = minCalendar.getTime().getTime();
+        final long maxDate = maxCalendar.getTime().getTime();
+
+        instrumentation.runOnMainSync(() -> {
+            mCalendarViewMaterial.setMinDate(minDate);
+            mCalendarViewMaterial.setMaxDate(maxDate);
+        });
+
+        assertEquals(mCalendarViewMaterial.getMinDate(), minDate);
+        assertEquals(mCalendarViewMaterial.getMaxDate(), maxDate);
+    }
+
+    public void testAppearanceMaterial() {
+        // The logic in this method is performed on a Material-styled CalendarView and
+        // non-deprecated attributes / visual appearance APIs
+
+        // Test the initial appearance defined in the layout XML
+        assertEquals(2, mCalendarViewMaterial.getFirstDayOfWeek());
+        assertEquals(R.style.TextAppearance_WithColor,
+                mCalendarViewMaterial.getDateTextAppearance());
+        assertEquals(R.style.TextAppearance_WithColorGreen,
+                mCalendarViewMaterial.getWeekDayTextAppearance());
+
+        final Instrumentation instrumentation = getInstrumentation();
+
+        // Change the visual appearance of the widget
+        instrumentation.runOnMainSync(() -> {
+            mCalendarViewMaterial.setFirstDayOfWeek(3);
+            mCalendarViewMaterial.setDateTextAppearance(R.style.TextAppearance_WithColorBlue);
+            mCalendarViewMaterial.setWeekDayTextAppearance(R.style.TextAppearance_WithColorMagenta);
+        });
+
+        assertEquals(3, mCalendarViewMaterial.getFirstDayOfWeek());
+        assertEquals(R.style.TextAppearance_WithColorBlue,
+                mCalendarViewMaterial.getDateTextAppearance());
+        assertEquals(R.style.TextAppearance_WithColorMagenta,
+                mCalendarViewMaterial.getWeekDayTextAppearance());
+    }
+
+    public void testAppearanceHolo() {
+        // All the logic in this method is performed on a Holo-styled CalendarView, as
+        // under Material design we are ignoring most of these decorative attributes
+
+        // Test the initial appearance defined in the layout XML
+        assertEquals(3, mCalendarViewHolo.getFirstDayOfWeek());
+        assertEquals(5, mCalendarViewHolo.getShownWeekCount());
+        assertFalse(mCalendarViewHolo.getShowWeekNumber());
+        assertEquals(R.style.TextAppearance_WithColor,
+                mCalendarViewHolo.getDateTextAppearance());
+        assertEquals(R.style.TextAppearance_WithColorGreen,
+                mCalendarViewHolo.getWeekDayTextAppearance());
+        assertEquals(mActivity.getColor(R.color.calendarview_week_background),
+                mCalendarViewHolo.getSelectedWeekBackgroundColor());
+        assertEquals(mActivity.getColor(R.color.calendarview_focusedmonthdate),
+                mCalendarViewHolo.getFocusedMonthDateColor());
+        assertEquals(mActivity.getColor(R.color.calendarview_unfocusedmonthdate),
+                mCalendarViewHolo.getUnfocusedMonthDateColor());
+        TestUtils.assertAllPixelsOfColor("Selected date vertical bar blue",
+                mCalendarViewHolo.getSelectedDateVerticalBar(), 40, 40, true, 0xFF0000FF, 1, true);
+
+        final Instrumentation instrumentation = getInstrumentation();
+
+        // Change the visual appearance of the widget
+        final @ColorInt int newSelectedWeekBackgroundColor =
+                mActivity.getColor(R.color.calendarview_week_background_new);
+        final @ColorInt int newFocusedMonthDateColor =
+                mActivity.getColor(R.color.calendarview_focusedmonthdate_new);
+        final @ColorInt int newUnfocusedMonthDataColor =
+                mActivity.getColor(R.color.calendarview_unfocusedmonthdate_new);
+        final @ColorInt int newWeekNumberColor =
+                mActivity.getColor(R.color.calendarview_week_number_new);
+        final @ColorInt int newWeekSeparatorLineColor =
+                mActivity.getColor(R.color.calendarview_week_separatorline_new);
+
+        instrumentation.runOnMainSync(() -> {
+            mCalendarViewHolo.setFirstDayOfWeek(1);
+            mCalendarViewHolo.setShownWeekCount(4);
+            mCalendarViewHolo.setShowWeekNumber(true);
+            mCalendarViewHolo.setDateTextAppearance(R.style.TextAppearance_WithColorBlue);
+            mCalendarViewHolo.setWeekDayTextAppearance(R.style.TextAppearance_WithColorMagenta);
+            mCalendarViewHolo.setSelectedWeekBackgroundColor(newSelectedWeekBackgroundColor);
+            mCalendarViewHolo.setFocusedMonthDateColor(newFocusedMonthDateColor);
+            mCalendarViewHolo.setUnfocusedMonthDateColor(newUnfocusedMonthDataColor);
+            mCalendarViewHolo.setWeekNumberColor(newWeekNumberColor);
+            mCalendarViewHolo.setWeekSeparatorLineColor(newWeekSeparatorLineColor);
+        });
+
+        assertEquals(1, mCalendarViewHolo.getFirstDayOfWeek());
+        assertEquals(4, mCalendarViewHolo.getShownWeekCount());
+        assertTrue(mCalendarViewHolo.getShowWeekNumber());
+        assertEquals(R.style.TextAppearance_WithColorBlue,
+                mCalendarViewHolo.getDateTextAppearance());
+        assertEquals(R.style.TextAppearance_WithColorMagenta,
+                mCalendarViewHolo.getWeekDayTextAppearance());
+        assertEquals(newSelectedWeekBackgroundColor,
+                mCalendarViewHolo.getSelectedWeekBackgroundColor());
+        assertEquals(newFocusedMonthDateColor,
+                mCalendarViewHolo.getFocusedMonthDateColor());
+        assertEquals(newUnfocusedMonthDataColor,
+                mCalendarViewHolo.getUnfocusedMonthDateColor());
+        assertEquals(newWeekNumberColor,
+                mCalendarViewHolo.getWeekNumberColor());
+        assertEquals(newWeekSeparatorLineColor,
+                mCalendarViewHolo.getWeekSeparatorLineColor());
+
+        instrumentation.runOnMainSync(
+                () -> mCalendarViewHolo.setSelectedDateVerticalBar(R.drawable.yellow_fill));
+        TestUtils.assertAllPixelsOfColor("Selected date vertical bar yellow",
+                mCalendarViewHolo.getSelectedDateVerticalBar(), 40, 40, true, 0xFFFFFF00, 1, true);
+
+        instrumentation.runOnMainSync(
+                () -> mCalendarViewHolo.setSelectedDateVerticalBar(
+                        mActivity.getDrawable(R.drawable.magenta_fill)));
+        TestUtils.assertAllPixelsOfColor("Selected date vertical bar magenta",
+                mCalendarViewHolo.getSelectedDateVerticalBar(), 40, 40, true, 0xFFFF00FF, 1, true);
+    }
+}
diff --git a/tests/tests/widget/src/android/widget/cts/PopupWindowTest.java b/tests/tests/widget/src/android/widget/cts/PopupWindowTest.java
index 658307a..15a79bf 100644
--- a/tests/tests/widget/src/android/widget/cts/PopupWindowTest.java
+++ b/tests/tests/widget/src/android/widget/cts/PopupWindowTest.java
@@ -16,12 +16,16 @@
 
 package android.widget.cts;
 
+import junit.framework.AssertionFailedError;
+
 import android.app.Activity;
 import android.app.Instrumentation;
 import android.content.Context;
 import android.graphics.Color;
+import android.graphics.Rect;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
+import android.os.Debug;
 import android.os.SystemClock;
 import android.test.ActivityInstrumentationTestCase2;
 import android.test.UiThreadTest;
@@ -296,33 +300,281 @@
         assertEquals(width, mPopupWindow.getWidth());
     }
 
+    private static final int TOP = 0x00;
+    private static final int BOTTOM = 0x01;
+
+    private static final int LEFT = 0x00;
+    private static final int RIGHT = 0x01;
+
+    private static final int GREATER_THAN = 1;
+    private static final int LESS_THAN = -1;
+    private static final int EQUAL_TO = 0;
+
     public void testShowAsDropDown() {
-        int[] anchorXY = new int[2];
-        int[] viewOnScreenXY = new int[2];
-        int[] viewInWindowXY = new int[2];
+        final PopupWindow popup = createPopupWindow(createPopupContent(50, 50));
+        popup.setClipToScreenEnabled(false);
+        popup.setOverlapAnchor(false);
+        popup.setAnimationStyle(0);
+        popup.setExitTransition(null);
+        popup.setEnterTransition(null);
 
-        mPopupWindow = createPopupWindow(createPopupContent());
-        final View upperAnchor = mActivity.findViewById(R.id.anchor_upper);
+        assertPosition(popup, R.id.anchor_upper_left,
+                LEFT, EQUAL_TO, LEFT, TOP, EQUAL_TO, BOTTOM);
+        assertPosition(popup, R.id.anchor_upper,
+                LEFT, EQUAL_TO, LEFT, TOP, EQUAL_TO, BOTTOM);
+        assertPosition(popup, R.id.anchor_upper_right,
+                RIGHT, EQUAL_TO, RIGHT, TOP, EQUAL_TO, BOTTOM);
 
-        mInstrumentation.runOnMainSync(() -> mPopupWindow.showAsDropDown(upperAnchor));
-        mInstrumentation.waitForIdleSync();
+        assertPosition(popup, R.id.anchor_middle_left,
+                LEFT, EQUAL_TO, LEFT, TOP, EQUAL_TO, BOTTOM);
+        assertPosition(popup, R.id.anchor_middle,
+                LEFT, EQUAL_TO, LEFT, TOP, EQUAL_TO, BOTTOM);
+        assertPosition(popup, R.id.anchor_middle_right,
+                RIGHT, EQUAL_TO, RIGHT, TOP, EQUAL_TO, BOTTOM);
 
-        assertTrue(mPopupWindow.isShowing());
+        assertPosition(popup, R.id.anchor_lower_left,
+                LEFT, EQUAL_TO, LEFT, BOTTOM, EQUAL_TO, TOP);
+        assertPosition(popup, R.id.anchor_lower,
+                LEFT, EQUAL_TO, LEFT, BOTTOM, EQUAL_TO, TOP);
+        assertPosition(popup, R.id.anchor_lower_right,
+                RIGHT, EQUAL_TO, RIGHT, BOTTOM, EQUAL_TO, TOP);
+    }
 
-        mPopupWindow.getContentView().getLocationOnScreen(viewOnScreenXY);
-        upperAnchor.getLocationOnScreen(anchorXY);
-        mPopupWindow.getContentView().getLocationInWindow(viewInWindowXY);
-        assertEquals(anchorXY[0] + viewInWindowXY[0], viewOnScreenXY[0]);
-        assertEquals(anchorXY[1] + viewInWindowXY[1] + upperAnchor.getHeight(), viewOnScreenXY[1]);
+    public void testShowAsDropDown_ClipToScreen() {
+        final PopupWindow popup = createPopupWindow(createPopupContent(50, 50));
+        popup.setClipToScreenEnabled(true);
+        popup.setOverlapAnchor(false);
+        popup.setAnimationStyle(0);
+        popup.setExitTransition(null);
+        popup.setEnterTransition(null);
 
-        dismissPopup();
+        assertPosition(popup, R.id.anchor_upper_left,
+                LEFT, EQUAL_TO, LEFT, TOP, EQUAL_TO, BOTTOM);
+        assertPosition(popup, R.id.anchor_upper,
+                LEFT, EQUAL_TO, LEFT, TOP, EQUAL_TO, BOTTOM);
+        assertPosition(popup, R.id.anchor_upper_right,
+                RIGHT, EQUAL_TO, RIGHT, TOP, EQUAL_TO, BOTTOM);
+
+        assertPosition(popup, R.id.anchor_middle_left,
+                LEFT, EQUAL_TO, LEFT, TOP, EQUAL_TO, BOTTOM);
+        assertPosition(popup, R.id.anchor_middle,
+                LEFT, EQUAL_TO, LEFT, TOP, EQUAL_TO, BOTTOM);
+        assertPosition(popup, R.id.anchor_middle_right,
+                RIGHT, EQUAL_TO, RIGHT, TOP, EQUAL_TO, BOTTOM);
+
+        assertPosition(popup, R.id.anchor_lower_left,
+                LEFT, EQUAL_TO, LEFT, BOTTOM, EQUAL_TO, TOP);
+        assertPosition(popup, R.id.anchor_lower,
+                LEFT, EQUAL_TO, LEFT, BOTTOM, EQUAL_TO, TOP);
+        assertPosition(popup, R.id.anchor_lower_right,
+                RIGHT, EQUAL_TO, RIGHT, BOTTOM, EQUAL_TO, TOP);
+    }
+
+    public void testShowAsDropDown_ClipToScreen_Overlap() {
+        final PopupWindow popup = createPopupWindow(createPopupContent(50, 50));
+        popup.setClipToScreenEnabled(true);
+        popup.setOverlapAnchor(true);
+        popup.setAnimationStyle(0);
+        popup.setExitTransition(null);
+        popup.setEnterTransition(null);
+
+        assertPosition(popup, R.id.anchor_upper_left,
+                LEFT, EQUAL_TO, LEFT, TOP, EQUAL_TO, TOP);
+        assertPosition(popup, R.id.anchor_upper,
+                LEFT, EQUAL_TO, LEFT, TOP, EQUAL_TO, TOP);
+        assertPosition(popup, R.id.anchor_upper_right,
+                RIGHT, EQUAL_TO, RIGHT, TOP, EQUAL_TO, TOP);
+
+        assertPosition(popup, R.id.anchor_middle_left,
+                LEFT, EQUAL_TO, LEFT, TOP, EQUAL_TO, TOP);
+        assertPosition(popup, R.id.anchor_middle,
+                LEFT, EQUAL_TO, LEFT, TOP, EQUAL_TO, TOP);
+        assertPosition(popup, R.id.anchor_middle_right,
+                RIGHT, EQUAL_TO, RIGHT, TOP, EQUAL_TO, TOP);
+
+        assertPosition(popup, R.id.anchor_lower_left,
+                LEFT, EQUAL_TO, LEFT, BOTTOM, EQUAL_TO, TOP);
+        assertPosition(popup, R.id.anchor_lower,
+                LEFT, EQUAL_TO, LEFT, BOTTOM, EQUAL_TO, TOP);
+        assertPosition(popup, R.id.anchor_lower_right,
+                RIGHT, EQUAL_TO, RIGHT, BOTTOM, EQUAL_TO, TOP);
+    }
+
+    public void testShowAsDropDown_ClipToScreen_Overlap_Offset() {
+        final PopupWindow popup = createPopupWindow(createPopupContent(50, 50));
+        popup.setClipToScreenEnabled(true);
+        popup.setOverlapAnchor(true);
+        popup.setAnimationStyle(0);
+        popup.setExitTransition(null);
+        popup.setEnterTransition(null);
+
+        final int offsetX = mActivity.findViewById(R.id.anchor_upper).getWidth() / 2;
+        final int offsetY = mActivity.findViewById(R.id.anchor_upper).getHeight() / 2;
+        final int gravity = Gravity.TOP | Gravity.START;
+
+        assertPosition(popup, R.id.anchor_upper_left,
+                LEFT, GREATER_THAN, LEFT, TOP, GREATER_THAN, TOP,
+                offsetX, offsetY, gravity);
+        assertPosition(popup, R.id.anchor_upper,
+                LEFT, GREATER_THAN, LEFT, TOP, GREATER_THAN, TOP,
+                offsetX, offsetY, gravity);
+        assertPosition(popup, R.id.anchor_upper_right,
+                RIGHT, EQUAL_TO, RIGHT, TOP, GREATER_THAN, TOP,
+                offsetX, offsetY, gravity);
+
+        assertPosition(popup, R.id.anchor_middle_left,
+                LEFT, GREATER_THAN, LEFT, TOP, GREATER_THAN, TOP,
+                offsetX, offsetY, gravity);
+        assertPosition(popup, R.id.anchor_middle,
+                LEFT, GREATER_THAN, LEFT, TOP, GREATER_THAN, TOP,
+                offsetX, offsetY, gravity);
+        assertPosition(popup, R.id.anchor_middle_right,
+                RIGHT, EQUAL_TO, RIGHT, TOP, GREATER_THAN, TOP,
+                offsetX, offsetY, gravity);
+
+        assertPosition(popup, R.id.anchor_lower_left,
+                LEFT, GREATER_THAN, LEFT, BOTTOM, LESS_THAN, BOTTOM,
+                offsetX, offsetY, gravity);
+        assertPosition(popup, R.id.anchor_lower,
+                LEFT, GREATER_THAN, LEFT, BOTTOM, LESS_THAN, BOTTOM,
+                offsetX, offsetY, gravity);
+        assertPosition(popup, R.id.anchor_lower_right,
+                RIGHT, EQUAL_TO, RIGHT, BOTTOM, LESS_THAN, BOTTOM,
+                offsetX, offsetY, gravity);
+    }
+
+    public void testShowAsDropDown_ClipToScreen_TooBig() {
+        final View rootView = mActivity.findViewById(R.id.anchor_upper_left).getRootView();
+        final int width = rootView.getWidth() * 2;
+        final int height = rootView.getHeight() * 2;
+
+        final PopupWindow popup = createPopupWindow(createPopupContent(width, height));
+        popup.setWidth(width);
+        popup.setHeight(height);
+
+        popup.setClipToScreenEnabled(true);
+        popup.setOverlapAnchor(false);
+        popup.setAnimationStyle(0);
+        popup.setExitTransition(null);
+        popup.setEnterTransition(null);
+
+        assertPosition(popup, R.id.anchor_upper_left,
+                LEFT, EQUAL_TO, LEFT, TOP, LESS_THAN, TOP);
+        assertPosition(popup, R.id.anchor_upper,
+                LEFT, LESS_THAN, LEFT, TOP, LESS_THAN, TOP);
+        assertPosition(popup, R.id.anchor_upper_right,
+                RIGHT, EQUAL_TO, RIGHT, TOP, LESS_THAN, TOP);
+
+        assertPosition(popup, R.id.anchor_middle_left,
+                LEFT, EQUAL_TO, LEFT, TOP, LESS_THAN, TOP);
+        assertPosition(popup, R.id.anchor_middle,
+                LEFT, LESS_THAN, LEFT, TOP, LESS_THAN, TOP);
+        assertPosition(popup, R.id.anchor_middle_right,
+                RIGHT, EQUAL_TO, RIGHT, TOP, LESS_THAN, TOP);
+
+        assertPosition(popup, R.id.anchor_lower_left,
+                LEFT, EQUAL_TO, LEFT, BOTTOM, EQUAL_TO, BOTTOM);
+        assertPosition(popup, R.id.anchor_lower,
+                LEFT, LESS_THAN, LEFT, BOTTOM, EQUAL_TO, BOTTOM);
+        assertPosition(popup, R.id.anchor_lower_right,
+                RIGHT, EQUAL_TO, RIGHT, BOTTOM, EQUAL_TO, BOTTOM);
+    }
+
+    private void assertPosition(PopupWindow popup, int anchorId,
+            int contentEdgeX, int operatorX, int anchorEdgeX,
+            int contentEdgeY, int operatorY, int anchorEdgeY) {
+        assertPosition(popup, anchorId,
+                contentEdgeX, operatorX, anchorEdgeX,
+                contentEdgeY, operatorY, anchorEdgeY,
+                0, 0, Gravity.TOP | Gravity.START);
+    }
+
+    private void assertPosition(PopupWindow popup, int anchorId,
+            int contentEdgeX, int operatorX, int anchorEdgeX,
+            int contentEdgeY, int operatorY, int anchorEdgeY,
+            int offsetX, int offsetY, int gravity) {
+        final View content = popup.getContentView();
+        final View anchor = mActivity.findViewById(anchorId);
+
+        getInstrumentation().runOnMainSync(() -> popup.showAsDropDown(
+                anchor, offsetX, offsetY, gravity));
+        getInstrumentation().waitForIdleSync();
+
+        assertTrue(popup.isShowing());
+        assertPositionX(content, contentEdgeX, operatorX, anchor, anchorEdgeX);
+        assertPositionY(content, contentEdgeY, operatorY, anchor, anchorEdgeY);
+
+        // Make sure it fits in the display frame.
+        final Rect displayFrame = new Rect();
+        anchor.getWindowVisibleDisplayFrame(displayFrame);
+        final Rect contentFrame = new Rect();
+        content.getBoundsOnScreen(contentFrame);
+        assertTrue("Content (" + contentFrame + ") extends outside display (" + displayFrame + ")",
+                displayFrame.contains(contentFrame));
+
+        getInstrumentation().runOnMainSync(() -> popup.dismiss());
+        getInstrumentation().waitForIdleSync();
+
+        assertFalse(popup.isShowing());
+    }
+
+    public static void assertPositionY(View content, int contentEdge, int flags,
+            View anchor, int anchorEdge) {
+        final int[] anchorOnScreenXY = new int[2];
+        anchor.getLocationOnScreen(anchorOnScreenXY);
+        int anchorY = anchorOnScreenXY[1];
+        if ((anchorEdge & BOTTOM) == BOTTOM) {
+            anchorY += anchor.getHeight();
+        }
+
+        final int[] contentOnScreenXY = new int[2];
+        content.getLocationOnScreen(contentOnScreenXY);
+        int contentY = contentOnScreenXY[1];
+        if ((contentEdge & BOTTOM) == BOTTOM) {
+            contentY += content.getHeight();
+        }
+
+        assertComparison(contentY, flags, anchorY);
+    }
+
+    private static void assertPositionX(View content, int contentEdge, int flags,
+            View anchor, int anchorEdge) {
+        final int[] anchorOnScreenXY = new int[2];
+        anchor.getLocationOnScreen(anchorOnScreenXY);
+        int anchorX = anchorOnScreenXY[0];
+        if ((anchorEdge & RIGHT) == RIGHT) {
+            anchorX += anchor.getWidth();
+        }
+
+        final int[] contentOnScreenXY = new int[2];
+        content.getLocationOnScreen(contentOnScreenXY);
+        int contentX = contentOnScreenXY[0];
+        if ((contentEdge & RIGHT) == RIGHT) {
+            contentX += content.getWidth();
+        }
+
+        assertComparison(contentX, flags, anchorX);
+    }
+
+    private static void assertComparison(int left, int operator, int right) {
+        switch (operator) {
+            case GREATER_THAN:
+                assertTrue(left + " <= " + right, left > right);
+                break;
+            case LESS_THAN:
+                assertTrue(left + " >= " + right, left < right);
+                break;
+            case EQUAL_TO:
+                assertTrue(left + " != " + right, left == right);
+                break;
+        }
     }
 
     public void testShowAtLocation() {
         int[] popupContentViewInWindowXY = new int[2];
         int[] popupContentViewOnScreenXY = new int[2];
 
-        mPopupWindow = createPopupWindow(createPopupContent());
+        mPopupWindow = createPopupWindow(createPopupContent(50, 50));
         // Do not attach within the decor; we will be measuring location
         // with regard to screen coordinates.
         mPopupWindow.setAttachedInDecor(false);
@@ -355,7 +607,7 @@
         int[] viewOnScreenXY = new int[2];
         int[] viewInWindowXY = new int[2];
 
-        mPopupWindow = createPopupWindow(createPopupContent());
+        mPopupWindow = createPopupWindow(createPopupContent(50, 50));
         final View upperAnchor = mActivity.findViewById(R.id.anchor_upper);
         upperAnchor.getLocationOnScreen(anchorXY);
         int height = upperAnchor.getHeight();
@@ -379,7 +631,7 @@
         int[] viewOnScreenXY = new int[2];
         int[] viewInWindowXY = new int[2];
 
-        mPopupWindow = createPopupWindow(createPopupContent());
+        mPopupWindow = createPopupWindow(createPopupContent(50, 50));
         final View upperAnchor = mActivity.findViewById(R.id.anchor_upper);
         upperAnchor.getLocationOnScreen(anchorXY);
 
@@ -397,7 +649,7 @@
     }
 
     public void testAccessWindowLayoutType() {
-        mPopupWindow = createPopupWindow(createPopupContent());
+        mPopupWindow = createPopupWindow(createPopupContent(50, 50));
         assertEquals(WindowManager.LayoutParams.TYPE_APPLICATION_PANEL,
                 mPopupWindow.getWindowLayoutType());
         mPopupWindow.setWindowLayoutType(WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL);
@@ -406,7 +658,7 @@
     }
 
     public void testGetMaxAvailableHeight() {
-        mPopupWindow = createPopupWindow(createPopupContent());
+        mPopupWindow = createPopupWindow(createPopupContent(50, 50));
 
         View anchorView = mActivity.findViewById(R.id.anchor_upper);
         int avaliable = getDisplay().getHeight() - anchorView.getHeight();
@@ -447,7 +699,7 @@
 
     @UiThreadTest
     public void testDismiss() {
-        mPopupWindow = createPopupWindow(createPopupContent());
+        mPopupWindow = createPopupWindow(createPopupContent(50, 50));
         assertFalse(mPopupWindow.isShowing());
         View anchorView = mActivity.findViewById(R.id.anchor_upper);
         mPopupWindow.showAsDropDown(anchorView);
@@ -480,7 +732,7 @@
     }
 
     public void testUpdate() {
-        mPopupWindow = createPopupWindow(createPopupContent());
+        mPopupWindow = createPopupWindow(createPopupContent(50, 50));
         mPopupWindow.setBackgroundDrawable(null);
         showPopup();
 
@@ -529,7 +781,7 @@
 
         OnDismissListener dismissListener = mock(OnDismissListener.class);
 
-        mPopupWindow = createPopupWindow(createPopupContent());
+        mPopupWindow = createPopupWindow(createPopupContent(50, 50));
         mPopupWindow.setEnterTransition(enterTransition);
         mPopupWindow.setExitTransition(exitTransition);
         mPopupWindow.setOnDismissListener(dismissListener);
@@ -557,7 +809,7 @@
         int[] viewInWindowXY = new int[2];
 
         mInstrumentation.runOnMainSync(() -> {
-            mPopupWindow = createPopupWindow(createPopupContent());
+            mPopupWindow = createPopupWindow(createPopupContent(50, 50));
             // Do not attach within the decor; we will be measuring location
             // with regard to screen coordinates.
             mPopupWindow.setAttachedInDecor(false);
@@ -601,7 +853,7 @@
 
     public void testUpdateDimensionAndAlignAnchorView() {
         mInstrumentation.runOnMainSync(
-                () -> mPopupWindow = createPopupWindow(createPopupContent()));
+                () -> mPopupWindow = createPopupWindow(createPopupContent(50, 50)));
         mInstrumentation.waitForIdleSync();
 
         final View anchorView = mActivity.findViewById(R.id.anchor_upper);
@@ -636,7 +888,7 @@
         int[] viewInWindowOff = new int[2];
         int[] viewXY = new int[2];
 
-        mPopupWindow = createPopupWindow(createPopupContent());
+        mPopupWindow = createPopupWindow(createPopupContent(50, 50));
         final View anchorView = mActivity.findViewById(R.id.anchor_upper);
         // Do not update if it is not shown
         assertFalse(mPopupWindow.isShowing());
@@ -737,7 +989,8 @@
     }
 
     public void testIsAboveAnchor() {
-        mInstrumentation.runOnMainSync(() -> mPopupWindow = createPopupWindow(createPopupContent()));
+        mInstrumentation.runOnMainSync(() -> mPopupWindow = createPopupWindow(createPopupContent(50,
+                50)));
         mInstrumentation.waitForIdleSync();
         final View upperAnchor = mActivity.findViewById(R.id.anchor_upper);
 
@@ -746,7 +999,7 @@
         assertFalse(mPopupWindow.isAboveAnchor());
         dismissPopup();
 
-        mPopupWindow = createPopupWindow(createPopupContent());
+        mPopupWindow = createPopupWindow(createPopupContent(50, 50));
         final View lowerAnchor = mActivity.findViewById(R.id.anchor_lower);
 
         mInstrumentation.runOnMainSync(() -> mPopupWindow.showAsDropDown(lowerAnchor, 0, 0));
@@ -819,9 +1072,9 @@
         public void captureEndValues(TransitionValues transitionValues) {}
     }
 
-    private View createPopupContent() {
-        View popupView = new View(mActivity);
-        popupView.setLayoutParams(new ViewGroup.LayoutParams(50, 50));
+    private View createPopupContent(int width, int height) {
+        final View popupView = new View(mActivity);
+        popupView.setLayoutParams(new ViewGroup.LayoutParams(width, height));
         popupView.setBackgroundColor(Color.MAGENTA);
 
         return popupView;
@@ -831,6 +1084,7 @@
         PopupWindow window = new PopupWindow(mActivity);
         window.setWidth(100);
         window.setHeight(100);
+        window.setBackgroundDrawable(new ColorDrawable(Color.YELLOW));
         return window;
     }
 
diff --git a/tests/tests/widget/src/android/widget/cts/SwitchCtsActivity.java b/tests/tests/widget/src/android/widget/cts/SwitchCtsActivity.java
new file mode 100644
index 0000000..7be5831
--- /dev/null
+++ b/tests/tests/widget/src/android/widget/cts/SwitchCtsActivity.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.widget.cts;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.Switch;
+import android.widget.cts.R;
+
+/**
+ * A minimal application for {@link Switch} test.
+ */
+public class SwitchCtsActivity extends Activity {
+    /**
+     * Called with the activity is first created.
+     */
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.switch_layout);
+    }
+}
diff --git a/tests/tests/widget/src/android/widget/cts/SwitchTest.java b/tests/tests/widget/src/android/widget/cts/SwitchTest.java
index e1124f3..216b17b 100644
--- a/tests/tests/widget/src/android/widget/cts/SwitchTest.java
+++ b/tests/tests/widget/src/android/widget/cts/SwitchTest.java
@@ -16,65 +16,71 @@
 
 package android.widget.cts;
 
-import android.widget.cts.R;
-
-import android.content.Context;
+import android.app.Activity;
 import android.content.res.ColorStateList;
-import android.content.res.XmlResourceParser;
-import android.cts.util.WidgetTestUtils;
 import android.graphics.Color;
 import android.graphics.PorterDuff.Mode;
-import android.test.AndroidTestCase;
-import android.util.Xml;
+import android.test.ActivityInstrumentationTestCase;
+import android.test.UiThreadTest;
+import android.test.suitebuilder.annotation.SmallTest;
 import android.widget.Switch;
+import org.xmlpull.v1.XmlPullParserException;
 
 import java.io.IOException;
-import org.xmlpull.v1.XmlPullParserException;
 
 /**
  * Test {@link Switch}.
  */
-public class SwitchTest extends AndroidTestCase {
-    public void testConstructor() throws XmlPullParserException, IOException {
-        new Switch(mContext);
+@SmallTest
+public class SwitchTest extends ActivityInstrumentationTestCase<SwitchCtsActivity> {
+    private Activity mActivity;
+    private Switch mSwitch;
 
-        XmlResourceParser parser = mContext.getResources().getLayout(R.layout.switch_layout);
-        WidgetTestUtils.beginDocument(parser, "Switch");
-
-        new Switch(mContext, parser);
-
-        new Switch(mContext, parser, 0);
-
-        new Switch(mContext, parser, 0, 0);
+    public SwitchTest() {
+        super("android.widget.cts", SwitchCtsActivity.class);
     }
 
-    public void testAccessThumbTint() throws XmlPullParserException, IOException {
-        XmlResourceParser parser = mContext.getResources().getLayout(R.layout.switch_layout);
-        WidgetTestUtils.beginDocument(parser, "Switch");
-        Switch aSwitch = new Switch(mContext, parser);
-        assertEquals(Color.WHITE, aSwitch.getThumbTintList().getDefaultColor());
-        assertEquals(Mode.SRC_OVER, aSwitch.getThumbTintMode());
-
-        ColorStateList colors = ColorStateList.valueOf(Color.RED);
-        aSwitch.setThumbTintList(colors);
-        aSwitch.setThumbTintMode(Mode.XOR);
-
-        assertSame(colors, aSwitch.getThumbTintList());
-        assertEquals(Mode.XOR, aSwitch.getThumbTintMode());
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mActivity = getActivity();
+        mSwitch = (Switch) mActivity.findViewById(R.id.switch_view);
     }
 
-    public void testAccessTrackTint() throws XmlPullParserException, IOException {
-        XmlResourceParser parser = mContext.getResources().getLayout(R.layout.switch_layout);
-        WidgetTestUtils.beginDocument(parser, "Switch");
-        Switch aSwitch = new Switch(mContext, parser);
-        assertEquals(Color.BLACK, aSwitch.getTrackTintList().getDefaultColor());
-        assertEquals(Mode.SRC_ATOP, aSwitch.getTrackTintMode());
+    @UiThreadTest
+    public void testConstructor() {
+        new Switch(mActivity);
+
+        new Switch(mActivity, null);
+
+        new Switch(mActivity, null, android.R.attr.switchStyle);
+
+        new Switch(mActivity, null, 0, android.R.style.Widget_Material_Light_CompoundButton_Switch);
+    }
+
+    @UiThreadTest
+    public void testAccessThumbTint() {
+        assertEquals(Color.WHITE, mSwitch.getThumbTintList().getDefaultColor());
+        assertEquals(Mode.SRC_OVER, mSwitch.getThumbTintMode());
 
         ColorStateList colors = ColorStateList.valueOf(Color.RED);
-        aSwitch.setTrackTintList(colors);
-        aSwitch.setTrackTintMode(Mode.XOR);
+        mSwitch.setThumbTintList(colors);
+        mSwitch.setThumbTintMode(Mode.XOR);
 
-        assertSame(colors, aSwitch.getTrackTintList());
-        assertEquals(Mode.XOR, aSwitch.getTrackTintMode());
+        assertSame(colors, mSwitch.getThumbTintList());
+        assertEquals(Mode.XOR, mSwitch.getThumbTintMode());
+    }
+
+    @UiThreadTest
+    public void testAccessTrackTint() {
+        assertEquals(Color.BLACK, mSwitch.getTrackTintList().getDefaultColor());
+        assertEquals(Mode.SRC_ATOP, mSwitch.getTrackTintMode());
+
+        ColorStateList colors = ColorStateList.valueOf(Color.RED);
+        mSwitch.setTrackTintList(colors);
+        mSwitch.setTrackTintMode(Mode.XOR);
+
+        assertSame(colors, mSwitch.getTrackTintList());
+        assertEquals(Mode.XOR, mSwitch.getTrackTintMode());
     }
 }
diff --git a/tests/tests/widget/src/android/widget/cts/ToolbarTest.java b/tests/tests/widget/src/android/widget/cts/ToolbarTest.java
index 0fd98c0..7f9690c 100644
--- a/tests/tests/widget/src/android/widget/cts/ToolbarTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ToolbarTest.java
@@ -17,6 +17,9 @@
 package android.widget.cts;
 
 import android.app.Instrumentation;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Color;
 import android.graphics.drawable.Drawable;
 import android.test.ActivityInstrumentationTestCase2;
 import android.test.UiThreadTest;
@@ -24,6 +27,7 @@
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.View;
+import android.widget.ListPopupWindow;
 import android.widget.Toolbar;
 import android.widget.cts.util.TestUtils;
 import android.widget.cts.util.ViewTestUtils;
@@ -46,6 +50,16 @@
         mMainToolbar = mActivity.getMainToolbar();
     }
 
+    public void testConstructor() {
+        new Toolbar(mActivity);
+
+        new Toolbar(mActivity, null);
+
+        new Toolbar(mActivity, null, android.R.attr.toolbarStyle);
+
+        new Toolbar(mActivity, null, 0, android.R.style.Widget_Material_Toolbar);
+    }
+
     public void testTitleAndSubtitleContent() {
         // Note that this method is *not* annotated to run on the UI thread, and every
         // call to setTitle / setSubtitle is wrapped to wait until the next draw pass
@@ -72,6 +86,30 @@
         assertEquals("New subtitle", mMainToolbar.getSubtitle());
     }
 
+    public void testTitleAndSubtitleAppearance() {
+        final Instrumentation instrumentation = getInstrumentation();
+
+        ViewTestUtils.runOnMainAndDrawSync(instrumentation, mMainToolbar,
+                () -> mMainToolbar.setTitle(R.string.toolbar_title));
+        ViewTestUtils.runOnMainAndDrawSync(instrumentation, mMainToolbar,
+                () -> mMainToolbar.setSubtitle(R.string.toolbar_subtitle));
+
+        // Since there are no APIs to get reference to the underlying implementation of
+        // title and subtitle, here we are testing that calling the relevant APIs doesn't crash
+
+        ViewTestUtils.runOnMainAndDrawSync(instrumentation, mMainToolbar,
+                () -> mMainToolbar.setTitleTextColor(Color.RED));
+        ViewTestUtils.runOnMainAndDrawSync(instrumentation, mMainToolbar,
+                () -> mMainToolbar.setSubtitleTextColor(Color.BLUE));
+
+        ViewTestUtils.runOnMainAndDrawSync(instrumentation, mMainToolbar,
+                () -> mMainToolbar.setTitleTextAppearance(
+                        mActivity, R.style.TextAppearance_NotColors));
+        ViewTestUtils.runOnMainAndDrawSync(instrumentation, mMainToolbar,
+                () -> mMainToolbar.setSubtitleTextAppearance(
+                        mActivity, R.style.TextAppearance_WithColor));
+    }
+
     @UiThreadTest
     public void testGetTitleMargins() {
         assertEquals(5, mMainToolbar.getTitleMarginStart());
@@ -326,4 +364,22 @@
         assertEquals(40, mMainToolbar.getContentInsetRight());
         assertEquals(20, mMainToolbar.getContentInsetEnd());
     }
+
+    @UiThreadTest
+    public void testPopupTheme() {
+        mMainToolbar.setPopupTheme(R.style.ToolbarPopupTheme_Test);
+        assertEquals(R.style.ToolbarPopupTheme_Test, mMainToolbar.getPopupTheme());
+    }
+
+    public void testNavigationOnClickListener() {
+        View.OnClickListener mockListener = mock(View.OnClickListener.class);
+        mMainToolbar.setNavigationOnClickListener(mockListener);
+
+        verify(mockListener, never()).onClick(any(View.class));
+
+        getInstrumentation().runOnMainSync(() -> mMainToolbar.getNavigationView().performClick());
+        verify(mockListener, times(1)).onClick(any(View.class));
+
+        verifyNoMoreInteractions(mockListener);
+    }
 }
diff --git a/tests/vr/AndroidManifest.xml b/tests/vr/AndroidManifest.xml
index 67331fe..877d846 100644
--- a/tests/vr/AndroidManifest.xml
+++ b/tests/vr/AndroidManifest.xml
@@ -37,6 +37,13 @@
             android:label="@string/app_name"
             android:name="android.vr.cts.OpenGLESActivity">
          </activity>
+         <activity android:name=".CtsActivity"
+                  android:label="CtsActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+            </intent-filter>
+        </activity>
          <uses-library  android:name="android.test.runner" />
     </application>
 
diff --git a/tests/vr/src/android/vr/cts/CtsActivity.java b/tests/vr/src/android/vr/cts/CtsActivity.java
new file mode 100644
index 0000000..33fff08
--- /dev/null
+++ b/tests/vr/src/android/vr/cts/CtsActivity.java
@@ -0,0 +1,22 @@
+/*
+ * 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.vr.cts;
+
+import android.app.Activity;
+
+public class CtsActivity extends Activity {
+
+}
diff --git a/tests/vr/src/android/vr/cts/VrCpuTest.java b/tests/vr/src/android/vr/cts/VrCpuTest.java
new file mode 100644
index 0000000..f015899
--- /dev/null
+++ b/tests/vr/src/android/vr/cts/VrCpuTest.java
@@ -0,0 +1,45 @@
+/*
+ * 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.vr.cts;
+
+import android.content.pm.PackageManager;
+import android.os.Process;
+import android.test.ActivityInstrumentationTestCase2;
+
+public class VrCpuTest extends ActivityInstrumentationTestCase2<CtsActivity> {
+    private CtsActivity mActivity;
+
+    public VrCpuTest() {
+        super(CtsActivity.class);
+    }
+
+    public void testHasAtLeastTwoCores() {
+        mActivity = getActivity();
+        if (mActivity.getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) {
+            assertTrue(Runtime.getRuntime().availableProcessors() >= 2);
+        }
+    }
+
+    public void testHasExclusiveCores() {
+        mActivity = getActivity();
+        if (mActivity.getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) {
+            int[] excl_cores = Process.getExclusiveCores();
+            assertTrue(excl_cores.length >= 1);
+        }
+    }
+}
diff --git a/tools/cts-tradefed/res/config/collect-tests-only.xml b/tools/cts-tradefed/res/config/collect-tests-only.xml
index 1c22b11..9fd7757 100644
--- a/tools/cts-tradefed/res/config/collect-tests-only.xml
+++ b/tools/cts-tradefed/res/config/collect-tests-only.xml
@@ -33,4 +33,7 @@
     <!-- Tell all HostTests to only list the tests -->
     <option name="compatibility:test-arg" value="com.android.tradefed.testtype.HostTest:collect-tests-only:true" />
 
+    <!-- Tell all deqp tests to only list the tests -->
+    <option name="compatibility:test-arg" value="com.drawelements.deqp.runner.DeqpTestRunner:collect-tests-only:true" />
+
 </configuration>