Merge "Remove cell / wifi manipulation from ApacheHttpClientTest" into mnc-dev
diff --git a/libs/testserver/src/android/webkit/cts/CtsTestServer.java b/libs/testserver/src/android/webkit/cts/CtsTestServer.java
index e39e435..de8a30d 100644
--- a/libs/testserver/src/android/webkit/cts/CtsTestServer.java
+++ b/libs/testserver/src/android/webkit/cts/CtsTestServer.java
@@ -229,12 +229,30 @@
             // request for shutdown and having the server's one thread
             // sequentially call accept() and close().
             URL url = new URL(mServerUri + SHUTDOWN_PREFIX);
-            URLConnection connection = openConnection(url);
-            connection.connect();
+            if (url.getProtocol().equalsIgnoreCase("http")) {
+                // Use Socket instead of HttpURLConnection when the server is in cleartext HTTP mode
+                // to avoid the request being blocked by NetworkSecurityPolicy.
+                Socket socket = null;
+                try {
+                    socket = new Socket(url.getHost(), url.getPort());
+                    socket.getOutputStream().write(
+                        ("GET " + SHUTDOWN_PREFIX + " HTTP/1.0\r\n\r\n").getBytes("US-ASCII"));
+                    socket.getOutputStream().flush();
+                } finally {
+                    if (socket != null) {
+                        try {
+                            socket.close();
+                        } catch (Exception ignored) {}
+                    }
+                }
+            } else {
+                URLConnection connection = openConnection(url);
+                connection.connect();
 
-            // Read the input from the stream to send the request.
-            InputStream is = connection.getInputStream();
-            is.close();
+                // Read the input from the stream to send the request.
+                InputStream is = connection.getInputStream();
+                is.close();
+            }
 
             // Block until the server thread is done shutting down.
             mServerThread.join();
diff --git a/tests/netsecpolicy/Android.mk b/tests/netsecpolicy/Android.mk
new file mode 100644
index 0000000..137672e
--- /dev/null
+++ b/tests/netsecpolicy/Android.mk
@@ -0,0 +1,17 @@
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/netsecpolicy/usescleartexttraffic-false/Android.mk b/tests/netsecpolicy/usescleartexttraffic-false/Android.mk
new file mode 100644
index 0000000..1af3b49
--- /dev/null
+++ b/tests/netsecpolicy/usescleartexttraffic-false/Android.mk
@@ -0,0 +1,30 @@
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, \
+    ../usescleartexttraffic-shared/src)
+
+LOCAL_PACKAGE_NAME := CtsNetSecPolicyUsesCleartextTrafficFalse
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/tests/netsecpolicy/usescleartexttraffic-false/AndroidManifest.xml b/tests/netsecpolicy/usescleartexttraffic-false/AndroidManifest.xml
new file mode 100644
index 0000000..013821e
--- /dev/null
+++ b/tests/netsecpolicy/usescleartexttraffic-false/AndroidManifest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="android.netsecpolicy.usescleartext.false.cts">
+    <uses-permission android:name="android.permission.INTERNET"/>
+    <application android:usesCleartextTraffic="false">
+    </application>
+</manifest>
diff --git a/tests/netsecpolicy/usescleartexttraffic-shared/src/Dummy.java b/tests/netsecpolicy/usescleartexttraffic-shared/src/Dummy.java
new file mode 100644
index 0000000..2705a5f
--- /dev/null
+++ b/tests/netsecpolicy/usescleartexttraffic-shared/src/Dummy.java
@@ -0,0 +1,2 @@
+public class Dummy {
+}
diff --git a/tests/netsecpolicy/usescleartexttraffic-true/Android.mk b/tests/netsecpolicy/usescleartexttraffic-true/Android.mk
new file mode 100644
index 0000000..5effc57
--- /dev/null
+++ b/tests/netsecpolicy/usescleartexttraffic-true/Android.mk
@@ -0,0 +1,30 @@
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, \
+    ../usescleartexttraffic-shared/src)
+
+LOCAL_PACKAGE_NAME := CtsNetSecPolicyUsesCleartextTrafficTrue
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/tests/netsecpolicy/usescleartexttraffic-true/AndroidManifest.xml b/tests/netsecpolicy/usescleartexttraffic-true/AndroidManifest.xml
new file mode 100644
index 0000000..f50295e
--- /dev/null
+++ b/tests/netsecpolicy/usescleartexttraffic-true/AndroidManifest.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="android.netsecpolicy.usescleartext.true.cts">
+    <uses-permission android:name="android.permission.INTERNET"/>
+    <uses-library android:name="org.apache.http.legacy"/>
+
+    <application android:usesCleartextTraffic="true">
+    </application>
+</manifest>
diff --git a/tests/netsecpolicy/usescleartexttraffic-unspecified/Android.mk b/tests/netsecpolicy/usescleartexttraffic-unspecified/Android.mk
new file mode 100644
index 0000000..685a16f
--- /dev/null
+++ b/tests/netsecpolicy/usescleartexttraffic-unspecified/Android.mk
@@ -0,0 +1,30 @@
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, \
+    ../usescleartexttraffic-shared/src)
+
+LOCAL_PACKAGE_NAME := CtsNetSecPolicyUsesCleartextTrafficUnspecified
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/tests/netsecpolicy/usescleartexttraffic-unspecified/AndroidManifest.xml b/tests/netsecpolicy/usescleartexttraffic-unspecified/AndroidManifest.xml
new file mode 100644
index 0000000..7e735c7
--- /dev/null
+++ b/tests/netsecpolicy/usescleartexttraffic-unspecified/AndroidManifest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="android.netsecpolicy.usescleartext.unspecified.cts">
+     <uses-permission android:name="android.permission.INTERNET"/>
+    <application>
+    </application>
+</manifest>
diff --git a/tests/tests/graphics/res/drawable/rippledrawable_radius.xml b/tests/tests/graphics/res/drawable/rippledrawable_radius.xml
new file mode 100644
index 0000000..4701ef7
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/rippledrawable_radius.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2015 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+        android:radius="10px"/>
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/RippleDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/RippleDrawableTest.java
new file mode 100644
index 0000000..b04433c
--- /dev/null
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/RippleDrawableTest.java
@@ -0,0 +1,44 @@
+/*
+ * 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.graphics.drawable.cts;
+
+import com.android.cts.graphics.R;
+
+import android.content.res.ColorStateList;
+import android.graphics.drawable.RippleDrawable;
+import android.graphics.Color;
+import android.test.AndroidTestCase;
+
+public class RippleDrawableTest extends AndroidTestCase {
+    public void testConstructor() {
+        new RippleDrawable(ColorStateList.valueOf(Color.RED), null, null);
+    }
+
+    public void testAccessRadius() {
+        RippleDrawable drawable =
+            new RippleDrawable(ColorStateList.valueOf(Color.RED), null, null);
+        assertEquals(RippleDrawable.RADIUS_AUTO, drawable.getRadius());
+        drawable.setRadius(10);
+        assertEquals(10, drawable.getRadius());
+    }
+
+    public void testRadiusAttr() {
+        RippleDrawable drawable =
+                (RippleDrawable) getContext().getDrawable(R.drawable.rippledrawable_radius);
+        assertEquals(10, drawable.getRadius());
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/AndroidKeyPairGeneratorTest.java b/tests/tests/keystore/src/android/keystore/cts/KeyPairGeneratorTest.java
similarity index 99%
rename from tests/tests/keystore/src/android/keystore/cts/AndroidKeyPairGeneratorTest.java
rename to tests/tests/keystore/src/android/keystore/cts/KeyPairGeneratorTest.java
index 5ed169b..ff46e87 100644
--- a/tests/tests/keystore/src/android/keystore/cts/AndroidKeyPairGeneratorTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/KeyPairGeneratorTest.java
@@ -64,7 +64,7 @@
 import libcore.javax.net.ssl.TestKeyManager;
 import libcore.javax.net.ssl.TestSSLContext;
 
-public class AndroidKeyPairGeneratorTest extends AndroidTestCase {
+public class KeyPairGeneratorTest extends AndroidTestCase {
     private KeyStore mKeyStore;
 
     private CountingSecureRandom mRng;
diff --git a/tests/tests/netsecpolicy/Android.mk b/tests/tests/netsecpolicy/Android.mk
new file mode 100644
index 0000000..137672e
--- /dev/null
+++ b/tests/tests/netsecpolicy/Android.mk
@@ -0,0 +1,17 @@
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/tests/netsecpolicy/src/android/security/NetworkSecurityPolicyTestBase.java b/tests/tests/netsecpolicy/src/android/security/NetworkSecurityPolicyTestBase.java
new file mode 100644
index 0000000..0ab07ae
--- /dev/null
+++ b/tests/tests/netsecpolicy/src/android/security/NetworkSecurityPolicyTestBase.java
@@ -0,0 +1,380 @@
+package android.security;
+
+import android.app.DownloadManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ApplicationInfo;
+import android.database.Cursor;
+import android.media.MediaPlayer;
+import android.net.Uri;
+import android.net.http.AndroidHttpClient;
+import android.test.AndroidTestCase;
+import android.webkit.cts.CtsTestServer;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpGet;
+
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.UnknownServiceException;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+abstract class NetworkSecurityPolicyTestBase extends AndroidTestCase {
+    private CtsTestServer mHttpOnlyWebServer;
+
+    private final boolean mCleartextTrafficExpectedToBePermitted;
+
+    NetworkSecurityPolicyTestBase(boolean cleartextTrafficExpectedToBePermitted) {
+        mCleartextTrafficExpectedToBePermitted = cleartextTrafficExpectedToBePermitted;
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mHttpOnlyWebServer = new CtsTestServer(mContext, false);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        try {
+            mHttpOnlyWebServer.shutdown();
+        } finally {
+            super.tearDown();
+        }
+    }
+
+    public void testNetworkSecurityPolicy() {
+        assertEquals(mCleartextTrafficExpectedToBePermitted,
+                NetworkSecurityPolicy.getInstance().isCleartextTrafficPermitted());
+    }
+
+    public void testApplicationInfoFlag() {
+        ApplicationInfo appInfo = getContext().getApplicationInfo();
+        int expectedValue = (mCleartextTrafficExpectedToBePermitted)
+                ? ApplicationInfo.FLAG_USES_CLEARTEXT_TRAFFIC : 0;
+        assertEquals(expectedValue, appInfo.flags & ApplicationInfo.FLAG_USES_CLEARTEXT_TRAFFIC);
+    }
+
+    public void testDefaultHttpURLConnection() throws Exception {
+        if (mCleartextTrafficExpectedToBePermitted) {
+            assertCleartextHttpURLConnectionSucceeds();
+        } else {
+            assertCleartextHttpURLConnectionBlocked();
+        }
+    }
+
+    private void assertCleartextHttpURLConnectionSucceeds() throws Exception {
+        URL url = new URL(mHttpOnlyWebServer.getUserAgentUrl());
+        HttpURLConnection conn = null;
+        try {
+            mHttpOnlyWebServer.resetRequestState();
+            conn = (HttpURLConnection) url.openConnection();
+            conn.setConnectTimeout(5000);
+            conn.setReadTimeout(5000);
+            assertEquals(200, conn.getResponseCode());
+        } finally {
+            if (conn != null) {
+                conn.disconnect();
+            }
+        }
+        Uri uri = Uri.parse(url.toString()).buildUpon().scheme(null).authority(null).build();
+        assertTrue(mHttpOnlyWebServer.wasResourceRequested(uri.toString()));
+    }
+
+    private void assertCleartextHttpURLConnectionBlocked() throws Exception {
+        URL url = new URL(mHttpOnlyWebServer.getUserAgentUrl());
+        HttpURLConnection conn = null;
+        try {
+            mHttpOnlyWebServer.resetRequestState();
+            conn = (HttpURLConnection) url.openConnection();
+            conn.setConnectTimeout(5000);
+            conn.setReadTimeout(5000);
+            conn.getResponseCode();
+            fail();
+        } catch (UnknownServiceException e) {
+            if ((e.getMessage() == null) || (!e.getMessage().toLowerCase().contains("cleartext"))) {
+                fail("Exception with which request failed does not mention cleartext: " + e);
+            }
+        } finally {
+            if (conn != null) {
+                conn.disconnect();
+            }
+        }
+        Uri uri = Uri.parse(url.toString()).buildUpon().scheme(null).authority(null).build();
+        assertFalse(mHttpOnlyWebServer.wasResourceRequested(uri.toString()));
+    }
+
+    public void testAndroidHttpClient() throws Exception {
+        if (mCleartextTrafficExpectedToBePermitted) {
+            assertAndroidHttpClientCleartextRequestSucceeds();
+        } else {
+            assertAndroidHttpClientCleartextRequestBlocked();
+        }
+    }
+
+    private void assertAndroidHttpClientCleartextRequestSucceeds() throws Exception {
+        URL url = new URL(mHttpOnlyWebServer.getUserAgentUrl());
+        AndroidHttpClient httpClient = AndroidHttpClient.newInstance(null);
+        try {
+            HttpResponse response = httpClient.execute(new HttpGet(url.toString()));
+            assertEquals(200, response.getStatusLine().getStatusCode());
+        } finally {
+            httpClient.close();
+        }
+        Uri uri = Uri.parse(url.toString()).buildUpon().scheme(null).authority(null).build();
+        assertTrue(mHttpOnlyWebServer.wasResourceRequested(uri.toString()));
+    }
+
+    private void assertAndroidHttpClientCleartextRequestBlocked() throws Exception {
+        URL url = new URL(mHttpOnlyWebServer.getUserAgentUrl());
+        AndroidHttpClient httpClient = AndroidHttpClient.newInstance(null);
+        try {
+            HttpResponse response = httpClient.execute(new HttpGet(url.toString()));
+            fail();
+        } catch (IOException e) {
+            if ((e.getMessage() == null) || (!e.getMessage().toLowerCase().contains("cleartext"))) {
+                fail("Exception with which request failed does not mention cleartext: " + e);
+            }
+        } finally {
+            httpClient.close();
+        }
+        Uri uri = Uri.parse(url.toString()).buildUpon().scheme(null).authority(null).build();
+        assertFalse(mHttpOnlyWebServer.wasResourceRequested(uri.toString()));
+    }
+
+    public void testMediaPlayer() throws Exception {
+        if (mCleartextTrafficExpectedToBePermitted) {
+            assertMediaPlayerCleartextRequestSucceeds();
+        } else {
+            assertMediaPlayerCleartextRequestBlocked();
+        }
+    }
+
+    private void assertMediaPlayerCleartextRequestSucceeds() throws Exception {
+        MediaPlayer mediaPlayer = new MediaPlayer();
+        Uri uri = Uri.parse(mHttpOnlyWebServer.getUserAgentUrl());
+        mediaPlayer.setDataSource(getContext(), uri);
+
+        try {
+            mediaPlayer.prepare();
+        } catch (IOException expected) {
+        } finally {
+            try {
+                mediaPlayer.stop();
+            } catch (IllegalStateException ignored) {
+            }
+        }
+        uri = uri.buildUpon().scheme(null).authority(null).build();
+        assertTrue(mHttpOnlyWebServer.wasResourceRequested(uri.toString()));
+    }
+
+    private void assertMediaPlayerCleartextRequestBlocked() throws Exception {
+        MediaPlayer mediaPlayer = new MediaPlayer();
+        Uri uri = Uri.parse(mHttpOnlyWebServer.getUserAgentUrl());
+        mediaPlayer.setDataSource(getContext(), uri);
+
+        try {
+            mediaPlayer.prepare();
+        } catch (IOException expected) {
+        } finally {
+            try {
+                mediaPlayer.stop();
+            } catch (IllegalStateException ignored) {
+            }
+        }
+        uri = uri.buildUpon().scheme(null).authority(null).build();
+        assertFalse(mHttpOnlyWebServer.wasResourceRequested(uri.toString()));
+    }
+
+    public void testDownloadManager() throws Exception {
+        Uri uri = Uri.parse(mHttpOnlyWebServer.getTestDownloadUrl("netsecpolicy", 0));
+        int[] result = downloadUsingDownloadManager(uri);
+        int status = result[0];
+        int reason = result[1];
+        uri = uri.buildUpon().scheme(null).authority(null).build();
+        if (mCleartextTrafficExpectedToBePermitted) {
+            assertEquals(DownloadManager.STATUS_SUCCESSFUL, status);
+            assertTrue(mHttpOnlyWebServer.wasResourceRequested(uri.toString()));
+        } else {
+            assertEquals(DownloadManager.STATUS_FAILED, status);
+            assertEquals(400, reason);
+            assertFalse(mHttpOnlyWebServer.wasResourceRequested(uri.toString()));
+        }
+    }
+
+
+    private int[] downloadUsingDownloadManager(Uri uri) throws Exception {
+        DownloadManager downloadManager =
+                (DownloadManager) getContext().getSystemService(Context.DOWNLOAD_SERVICE);
+        removeAllDownloads(downloadManager);
+        BroadcastReceiver downloadCompleteReceiver = null;
+        try {
+            final SettableFuture<Intent> downloadCompleteIntentFuture = new SettableFuture<Intent>();
+            downloadCompleteReceiver = new BroadcastReceiver() {
+                @Override
+                public void onReceive(Context context, Intent intent) {
+                    downloadCompleteIntentFuture.set(intent);
+                }
+            };
+            getContext().registerReceiver(
+                    downloadCompleteReceiver,
+                    new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
+
+            Intent downloadCompleteIntent;
+
+            long downloadId = downloadManager.enqueue(new DownloadManager.Request(uri));
+            downloadCompleteIntent = downloadCompleteIntentFuture.get(5, TimeUnit.SECONDS);
+
+            assertEquals(downloadId,
+                    downloadCompleteIntent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1));
+            Cursor c = downloadManager.query(
+                    new DownloadManager.Query().setFilterById(downloadId));
+            try {
+                if (!c.moveToNext()) {
+                    fail("Download not found");
+                    return null;
+                }
+                int status = c.getInt(c.getColumnIndexOrThrow(DownloadManager.COLUMN_STATUS));
+                int reason = c.getInt(c.getColumnIndexOrThrow(DownloadManager.COLUMN_REASON));
+                return new int[] {status, reason};
+            } finally {
+                c.close();
+            }
+        } finally {
+            if (downloadCompleteReceiver != null) {
+                getContext().unregisterReceiver(downloadCompleteReceiver);
+            }
+            removeAllDownloads(downloadManager);
+        }
+    }
+
+    private static void removeAllDownloads(DownloadManager downloadManager) {
+        Cursor cursor = null;
+        try {
+            DownloadManager.Query query = new DownloadManager.Query();
+            cursor = downloadManager.query(query);
+            if (cursor.getCount() == 0) {
+                return;
+            }
+            long[] removeIds = new long[cursor.getCount()];
+            int columnIndex = cursor.getColumnIndex(DownloadManager.COLUMN_ID);
+            for (int i = 0; cursor.moveToNext(); i++) {
+                removeIds[i] = cursor.getLong(columnIndex);
+            }
+            assertEquals(removeIds.length, downloadManager.remove(removeIds));
+        } finally {
+            if (cursor != null) {
+                cursor.close();
+            }
+        }
+    }
+
+    private static class SettableFuture<T> implements Future<T> {
+
+        private final Object mLock = new Object();
+        private boolean mDone;
+        private boolean mCancelled;
+        private T mValue;
+        private Throwable mException;
+
+        public void set(T value) {
+            synchronized (mLock) {
+                if (!mDone) {
+                    mValue = value;
+                    mDone = true;
+                    mLock.notifyAll();
+                }
+            }
+        }
+
+        public void setException(Throwable exception) {
+            synchronized (mLock) {
+                if (!mDone) {
+                    mException = exception;
+                    mDone = true;
+                    mLock.notifyAll();
+                }
+            }
+        }
+
+        @Override
+        public boolean cancel(boolean mayInterruptIfRunning) {
+            synchronized (mLock) {
+                if (mDone) {
+                    return false;
+                }
+                mCancelled = true;
+                mDone = true;
+                mLock.notifyAll();
+                return true;
+            }
+        }
+
+        @Override
+        public T get() throws InterruptedException, ExecutionException {
+            synchronized (mLock) {
+                while (!mDone) {
+                    mLock.wait();
+                }
+                return getValue();
+            }
+        }
+
+        @Override
+        public T get(long timeout, TimeUnit timeUnit)
+                throws InterruptedException, ExecutionException, TimeoutException {
+            synchronized (mLock) {
+                if (mDone) {
+                    return getValue();
+                }
+                long timeoutMillis = timeUnit.toMillis(timeout);
+                long deadlineTimeMillis = System.currentTimeMillis() + timeoutMillis;
+
+                while (!mDone) {
+                    long millisTillDeadline = deadlineTimeMillis - System.currentTimeMillis();
+                    if ((millisTillDeadline <= 0) || (millisTillDeadline > timeoutMillis)) {
+                        throw new TimeoutException();
+                    }
+                    mLock.wait(millisTillDeadline);
+                }
+                return getValue();
+            }
+        }
+
+        private T getValue() throws ExecutionException {
+            synchronized (mLock) {
+                if (!mDone) {
+                    throw new IllegalStateException("Not yet done");
+                }
+                if (mCancelled) {
+                    throw new CancellationException();
+                }
+                if (mException != null) {
+                    throw new ExecutionException(mException);
+                }
+                return mValue;
+            }
+        }
+
+        @Override
+        public boolean isCancelled() {
+            synchronized (mLock) {
+                return mCancelled;
+            }
+        }
+
+        @Override
+        public boolean isDone() {
+            synchronized (mLock) {
+                return mDone;
+            }
+        }
+    }
+}
diff --git a/tests/tests/netsecpolicy/usescleartexttraffic-false/Android.mk b/tests/tests/netsecpolicy/usescleartexttraffic-false/Android.mk
new file mode 100644
index 0000000..0441f2b
--- /dev/null
+++ b/tests/tests/netsecpolicy/usescleartexttraffic-false/Android.mk
@@ -0,0 +1,35 @@
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner \
+    ctstestserver \
+    org.apache.http.legacy
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src ../src)
+
+LOCAL_PACKAGE_NAME := CtsNetSecPolicyUsesCleartextTrafficFalseTestCases
+
+LOCAL_INSTRUMENTATION_FOR := CtsNetSecPolicyUsesCleartextTrafficFalse
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/netsecpolicy/usescleartexttraffic-false/AndroidManifest.xml b/tests/tests/netsecpolicy/usescleartexttraffic-false/AndroidManifest.xml
new file mode 100644
index 0000000..49385f8
--- /dev/null
+++ b/tests/tests/netsecpolicy/usescleartexttraffic-false/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.cts.netsecpolicy.usescleartext.false">
+
+  <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+  <application>
+      <uses-library android:name="android.test.runner"/>
+  </application>
+
+  <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                   android:targetPackage="android.netsecpolicy.usescleartext.false.cts"
+                   android:label="Tests for NetworkSecurityPolicy cleartext traffic policy when it is set to denied.">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+
+</manifest>
diff --git a/tests/tests/netsecpolicy/usescleartexttraffic-false/src/android/security/NetworkSecurityPolicyCleartextDeniedTest.java b/tests/tests/netsecpolicy/usescleartexttraffic-false/src/android/security/NetworkSecurityPolicyCleartextDeniedTest.java
new file mode 100644
index 0000000..f5d9770
--- /dev/null
+++ b/tests/tests/netsecpolicy/usescleartexttraffic-false/src/android/security/NetworkSecurityPolicyCleartextDeniedTest.java
@@ -0,0 +1,9 @@
+package android.security;
+
+public class NetworkSecurityPolicyCleartextDeniedTest extends NetworkSecurityPolicyTestBase {
+
+    public NetworkSecurityPolicyCleartextDeniedTest() {
+        super(false // expect cleartext traffic to be blocked
+                );
+    }
+}
diff --git a/tests/tests/netsecpolicy/usescleartexttraffic-true/Android.mk b/tests/tests/netsecpolicy/usescleartexttraffic-true/Android.mk
new file mode 100644
index 0000000..5a4a41d
--- /dev/null
+++ b/tests/tests/netsecpolicy/usescleartexttraffic-true/Android.mk
@@ -0,0 +1,35 @@
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner \
+    ctstestserver \
+    org.apache.http.legacy
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src ../src)
+
+LOCAL_PACKAGE_NAME := CtsNetSecPolicyUsesCleartextTrafficTrueTestCases
+
+LOCAL_INSTRUMENTATION_FOR := CtsNetSecPolicyUsesCleartextTrafficTrue
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/netsecpolicy/usescleartexttraffic-true/AndroidManifest.xml b/tests/tests/netsecpolicy/usescleartexttraffic-true/AndroidManifest.xml
new file mode 100644
index 0000000..be698f2
--- /dev/null
+++ b/tests/tests/netsecpolicy/usescleartexttraffic-true/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.cts.netsecpolicy.usescleartext.true">
+
+  <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+  <application>
+      <uses-library android:name="android.test.runner"/>
+  </application>
+
+  <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                   android:targetPackage="android.netsecpolicy.usescleartext.true.cts"
+                   android:label="Tests for NetworkSecurityPolicy cleartext traffic policy when it is set to permitted.">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+
+</manifest>
diff --git a/tests/tests/netsecpolicy/usescleartexttraffic-true/src/android/security/NetworkSecurityPolicyCleartextPermittedTest.java b/tests/tests/netsecpolicy/usescleartexttraffic-true/src/android/security/NetworkSecurityPolicyCleartextPermittedTest.java
new file mode 100644
index 0000000..83c1049
--- /dev/null
+++ b/tests/tests/netsecpolicy/usescleartexttraffic-true/src/android/security/NetworkSecurityPolicyCleartextPermittedTest.java
@@ -0,0 +1,9 @@
+package android.security;
+
+public class NetworkSecurityPolicyCleartextPermittedTest extends NetworkSecurityPolicyTestBase {
+
+    public NetworkSecurityPolicyCleartextPermittedTest() {
+        super(true // expect cleartext traffic to be permitted
+                );
+    }
+}
diff --git a/tests/tests/netsecpolicy/usescleartexttraffic-unspecified/Android.mk b/tests/tests/netsecpolicy/usescleartexttraffic-unspecified/Android.mk
new file mode 100644
index 0000000..faa3c23
--- /dev/null
+++ b/tests/tests/netsecpolicy/usescleartexttraffic-unspecified/Android.mk
@@ -0,0 +1,35 @@
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner \
+    ctstestserver \
+    org.apache.http.legacy
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src ../src)
+
+LOCAL_PACKAGE_NAME := CtsNetSecPolicyUsesCleartextTrafficUnspecifiedTestCases
+
+LOCAL_INSTRUMENTATION_FOR := CtsNetSecPolicyUsesCleartextTrafficUnspecified
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/netsecpolicy/usescleartexttraffic-unspecified/AndroidManifest.xml b/tests/tests/netsecpolicy/usescleartexttraffic-unspecified/AndroidManifest.xml
new file mode 100644
index 0000000..7bd8742
--- /dev/null
+++ b/tests/tests/netsecpolicy/usescleartexttraffic-unspecified/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.cts.netsecpolicy.usescleartext.unspecified">
+
+  <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+  <application>
+      <uses-library android:name="android.test.runner"/>
+  </application>
+
+  <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                   android:targetPackage="android.netsecpolicy.usescleartext.unspecified.cts"
+                   android:label="Tests for NetworkSecurityPolicy cleartext traffic policy when it is not specified.">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+
+</manifest>
diff --git a/tests/tests/netsecpolicy/usescleartexttraffic-unspecified/src/android/security/NetworkSecurityPolicyCleartextUnspecifiedTest.java b/tests/tests/netsecpolicy/usescleartexttraffic-unspecified/src/android/security/NetworkSecurityPolicyCleartextUnspecifiedTest.java
new file mode 100644
index 0000000..5690f31
--- /dev/null
+++ b/tests/tests/netsecpolicy/usescleartexttraffic-unspecified/src/android/security/NetworkSecurityPolicyCleartextUnspecifiedTest.java
@@ -0,0 +1,9 @@
+package android.security;
+
+public class NetworkSecurityPolicyCleartextUnspecifiedTest extends NetworkSecurityPolicyTestBase {
+
+    public NetworkSecurityPolicyCleartextUnspecifiedTest() {
+        super(true // expect cleartext traffic to be permitted
+                );
+    }
+}
diff --git a/tests/tests/provider/src/android/provider/cts/ContactsContract_QuickContactsTest.java b/tests/tests/provider/src/android/provider/cts/ContactsContract_QuickContactsTest.java
new file mode 100644
index 0000000..79633e7
--- /dev/null
+++ b/tests/tests/provider/src/android/provider/cts/ContactsContract_QuickContactsTest.java
@@ -0,0 +1,83 @@
+/*
+ * 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.provider.cts;
+
+import android.content.ContentUris;
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.content.Intent;
+import android.graphics.Rect;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.UserHandle;
+import android.provider.Contacts;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.QuickContact;
+import android.test.InstrumentationTestCase;
+import android.test.UiThreadTest;
+import android.view.View;
+
+import java.util.Arrays;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+public class ContactsContract_QuickContactsTest extends InstrumentationTestCase {
+
+    final String EXCLUDED_MIME_TYPES[] = {"exclude1", "exclude2"};
+    final String PLAIN_MIME_TYPE = "text/plain";
+    final Uri FAKE_CONTACT_URI = ContentUris.withAppendedId(Contacts.CONTENT_URI, 0);
+
+    @UiThreadTest
+    public void testPrioritizedMimeTypeAndExcludedMimeTypes() throws InterruptedException {
+        final CountDownLatch latch = new CountDownLatch(2);
+        Context context = new ContextWrapper(getInstrumentation().getContext()) {
+            @Override
+            public void startActivity(Intent intent) {
+                testCallback(intent);
+            }
+
+            @Override
+            public void startActivityAsUser(Intent intent, UserHandle user) {
+                testCallback(intent);
+            }
+
+            @Override
+            public void startActivityAsUser(Intent intent, Bundle options, UserHandle user) {
+                testCallback(intent);
+            }
+
+            private void testCallback(Intent intent) {
+                assertEquals(PLAIN_MIME_TYPE, intent.getStringExtra(
+                        QuickContact.EXTRA_PRIORITIZED_MIMETYPE));
+                String excludedMimeTypes[]
+                        = intent.getStringArrayExtra(QuickContact.EXTRA_EXCLUDE_MIMES);
+                assertTrue(Arrays.equals(excludedMimeTypes, EXCLUDED_MIME_TYPES));
+                latch.countDown();
+            }
+        };
+
+        // Execute
+        ContactsContract.QuickContact.showQuickContact(context, new View(context),
+                FAKE_CONTACT_URI, EXCLUDED_MIME_TYPES, PLAIN_MIME_TYPE);
+        ContactsContract.QuickContact.showQuickContact(context, (Rect) null,
+                FAKE_CONTACT_URI, EXCLUDED_MIME_TYPES, PLAIN_MIME_TYPE);
+
+        // Verify: the start activity call sets the prioritized mimetype and excludes mimetypes.
+        // We don't know which method will be used to start the activity, so we check all options.
+        assertTrue(latch.await(1, TimeUnit.SECONDS));
+    }
+}
\ No newline at end of file
diff --git a/tests/tests/telecom/AndroidManifest.xml b/tests/tests/telecom/AndroidManifest.xml
index 700f398..6e9e675 100644
--- a/tests/tests/telecom/AndroidManifest.xml
+++ b/tests/tests/telecom/AndroidManifest.xml
@@ -25,7 +25,7 @@
     <application>
         <uses-library android:name="android.test.runner" />
 
-        <service android:name="android.telecom.cts.MockConnectionService"
+        <service android:name="android.telecom.cts.CtsConnectionService"
             android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE" >
             <intent-filter>
                 <action android:name="android.telecom.ConnectionService" />
diff --git a/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java b/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java
index 61fe2e9..fb62f26 100644
--- a/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java
+++ b/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java
@@ -20,32 +20,34 @@
 
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
 import android.graphics.Color;
 import android.net.Uri;
 import android.os.Bundle;
 import android.telecom.Call;
 import android.telecom.CallAudioState;
 import android.telecom.Connection;
-import android.telecom.ConnectionRequest;
 import android.telecom.InCallService;
 import android.telecom.PhoneAccount;
 import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
 import android.telecom.VideoProfile;
-import android.telecom.cts.MockConnectionService.ConnectionServiceCallbacks;
 import android.telecom.cts.MockInCallService.InCallServiceCallbacks;
 import android.test.InstrumentationTestCase;
 import android.text.TextUtils;
 import android.util.Log;
 
-import java.util.Arrays;
 import java.util.concurrent.TimeUnit;
 
 /**
- * Base class for Telecom CTS tests that require a {@link MockConnectionService} and
+ * Base class for Telecom CTS tests that require a {@link CtsConnectionService} and
  * {@link MockInCallService} to verify Telecom functionality.
  */
 public class BaseTelecomTestWithMockServices extends InstrumentationTestCase {
+
+    public static final int FLAG_REGISTER = 0x1;
+    public static final int FLAG_ENABLE = 0x2;
+
     public static final PhoneAccountHandle TEST_PHONE_ACCOUNT_HANDLE =
             new PhoneAccountHandle(new ComponentName(PACKAGE, COMPONENT), ACCOUNT_ID);
 
@@ -57,7 +59,8 @@
                     PhoneAccount.CAPABILITY_VIDEO_CALLING)
             .setHighlightColor(Color.RED)
             .setShortDescription(LABEL)
-            .setSupportedUriSchemes(Arrays.asList("tel"))
+            .addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
+            .addSupportedUriScheme(PhoneAccount.SCHEME_VOICEMAIL)
             .build();
 
     private static int sCounter = 0;
@@ -65,8 +68,8 @@
     Context mContext;
     TelecomManager mTelecomManager;
     InCallServiceCallbacks mInCallCallbacks;
-    ConnectionServiceCallbacks mConnectionCallbacks;
     String mPreviousDefaultDialer = null;
+    MockConnectionService connectionService = new MockConnectionService();
 
     @Override
     protected void setUp() throws Exception {
@@ -75,8 +78,6 @@
         mTelecomManager = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
 
         if (shouldTestTelecom(mContext)) {
-            mTelecomManager.registerPhoneAccount(TEST_PHONE_ACCOUNT);
-            TestUtils.enablePhoneAccount(getInstrumentation(), TEST_PHONE_ACCOUNT_HANDLE);
             mPreviousDefaultDialer = TestUtils.getDefaultDialer(getInstrumentation());
             TestUtils.setDefaultDialer(getInstrumentation(), PACKAGE);
             setupCallbacks();
@@ -90,11 +91,45 @@
             if (!TextUtils.isEmpty(mPreviousDefaultDialer)) {
                 TestUtils.setDefaultDialer(getInstrumentation(), mPreviousDefaultDialer);
             }
-            mTelecomManager.unregisterPhoneAccount(TEST_PHONE_ACCOUNT_HANDLE);
+            tearDownConnectionService(TEST_PHONE_ACCOUNT);
         }
         super.tearDown();
     }
 
+    protected PhoneAccount setupConnectionService(CtsConnectionService connectionService,
+            int flags)
+            throws Exception {
+        if (connectionService == null) {
+            connectionService = this.connectionService;
+        }
+        CtsConnectionService.setUp(TEST_PHONE_ACCOUNT, connectionService);
+
+        if ((flags & FLAG_REGISTER) != 0) {
+            mTelecomManager.registerPhoneAccount(TEST_PHONE_ACCOUNT);
+        }
+        if ((flags & FLAG_ENABLE) != 0) {
+            TestUtils.enablePhoneAccount(getInstrumentation(),
+                    TEST_PHONE_ACCOUNT_HANDLE);
+        }
+
+        return TEST_PHONE_ACCOUNT;
+    }
+
+    protected void tearDownConnectionService(PhoneAccount account) throws Exception {
+        mTelecomManager.unregisterPhoneAccount(account.getAccountHandle());
+        CtsConnectionService.tearDown();
+        this.connectionService = null;
+    }
+
+    protected void startCallTo(Uri address, PhoneAccountHandle accountHandle) {
+        final Intent intent = new Intent(Intent.ACTION_CALL, address);
+        if (accountHandle != null) {
+            intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, accountHandle);
+        }
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        mContext.startActivity(intent);
+    }
+
     private void sleep(long ms) {
         try {
             Thread.sleep(ms);
@@ -111,27 +146,11 @@
         };
 
         MockInCallService.setCallbacks(mInCallCallbacks);
-
-        mConnectionCallbacks = new ConnectionServiceCallbacks() {
-            @Override
-            public void onCreateOutgoingConnection(MockConnection connection,
-                    ConnectionRequest request) {
-                this.lock.release();
-            }
-
-            @Override
-            public void onCreateIncomingConnection(MockConnection connection,
-                    ConnectionRequest request) {
-                this.lock.release();
-            }
-        };
-
-        MockConnectionService.setCallbacks(mConnectionCallbacks);
     }
 
     /**
      * Puts Telecom in a state where there is an incoming call provided by the
-     * {@link MockConnectionService} which can be tested.
+     * {@link CtsConnectionService} which can be tested.
      */
     void addAndVerifyNewIncomingCall(Uri incomingHandle, Bundle extras) {
         if (extras == null) {
@@ -154,7 +173,7 @@
 
     /**
      *  Puts Telecom in a state where there is an active call provided by the
-     *  {@link MockConnectionService} which can be tested.
+     *  {@link CtsConnectionService} which can be tested.
      */
     void placeAndVerifyCall() {
         placeAndVerifyCall(null);
@@ -162,7 +181,7 @@
 
     /**
      *  Puts Telecom in a state where there is an active call provided by the
-     *  {@link MockConnectionService} which can be tested.
+     *  {@link CtsConnectionService} which can be tested.
      *
      *  @param videoState the video state of the call.
      */
@@ -172,7 +191,7 @@
 
     /**
      *  Puts Telecom in a state where there is an active call provided by the
-     *  {@link MockConnectionService} which can be tested.
+     *  {@link CtsConnectionService} which can be tested.
      */
     void placeAndVerifyCall(Bundle extras) {
         placeAndVerifyCall(extras, VideoProfile.STATE_AUDIO_ONLY);
@@ -180,7 +199,7 @@
 
     /**
      *  Puts Telecom in a state where there is an active call provided by the
-     *  {@link MockConnectionService} which can be tested.
+     *  {@link CtsConnectionService} which can be tested.
      */
     void placeAndVerifyCall(Bundle extras, int videoState) {
         placeNewCallWithPhoneAccount(extras, videoState);
@@ -197,48 +216,47 @@
                 mInCallCallbacks.getService().getCallCount());
     }
 
-    void verifyConnectionForOutgoingCall() {
+    MockConnection verifyConnectionForOutgoingCall() {
         try {
-            if (!mConnectionCallbacks.lock.tryAcquire(3, TimeUnit.SECONDS)) {
+            if (!connectionService.lock.tryAcquire(TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                    TimeUnit.MILLISECONDS)) {
                 fail("No outgoing call connection requested by Telecom");
             }
         } catch (InterruptedException e) {
             Log.i(TAG, "Test interrupted!");
         }
 
-        assertNotNull("Telecom should bind to and create ConnectionService",
-                mConnectionCallbacks.getService());
         assertNotNull("Telecom should create outgoing connection for outgoing call",
-                mConnectionCallbacks.outgoingConnection);
+                connectionService.outgoingConnection);
         assertNull("Telecom should not create incoming connection for outgoing call",
-                mConnectionCallbacks.incomingConnection);
+                connectionService.incomingConnection);
 
-        final MockConnection connection = mConnectionCallbacks.outgoingConnection;
-        connection.setDialing();
-        connection.setActive();
-
-        assertEquals(Connection.STATE_ACTIVE, connection.getState());
+        connectionService.outgoingConnection.setDialing();
+        connectionService.outgoingConnection.setActive();
+        assertEquals(Connection.STATE_ACTIVE,
+                connectionService.outgoingConnection.getState());
+        return connectionService.outgoingConnection;
     }
 
-    void verifyConnectionForIncomingCall() {
+    MockConnection verifyConnectionForIncomingCall() {
         try {
-            if (!mConnectionCallbacks.lock.tryAcquire(3, TimeUnit.SECONDS)) {
-                fail("No incoming call connection requested by Telecom");
+            if (!connectionService.lock.tryAcquire(TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                    TimeUnit.MILLISECONDS)) {
+                fail("No outgoing call connection requested by Telecom");
             }
         } catch (InterruptedException e) {
             Log.i(TAG, "Test interrupted!");
         }
 
-        assertNotNull("Telecom should bind to and create ConnectionService",
-                mConnectionCallbacks.getService());
         assertNull("Telecom should not create outgoing connection for outgoing call",
-                mConnectionCallbacks.outgoingConnection);
+                connectionService.outgoingConnection);
         assertNotNull("Telecom should create incoming connection for outgoing call",
-                mConnectionCallbacks.incomingConnection);
+                connectionService.incomingConnection);
 
-        final MockConnection connection = mConnectionCallbacks.incomingConnection;
-        connection.setRinging();
-        assertEquals(Connection.STATE_RINGING, connection.getState());
+        connectionService.incomingConnection.setRinging();
+        assertEquals(Connection.STATE_RINGING,
+                connectionService.incomingConnection.getState());
+        return connectionService.incomingConnection;
     }
 
     /**
@@ -252,7 +270,7 @@
     }
 
     /**
-     * Place a new outgoing call via the {@link MockConnectionService}
+     * Place a new outgoing call via the {@link CtsConnectionService}
      */
     private void placeNewCallWithPhoneAccount(Bundle extras, int videoState) {
         if (extras == null) {
diff --git a/tests/tests/telecom/src/android/telecom/cts/CtsConnectionService.java b/tests/tests/telecom/src/android/telecom/cts/CtsConnectionService.java
new file mode 100644
index 0000000..9cfa0e3
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/CtsConnectionService.java
@@ -0,0 +1,93 @@
+/*
+ * 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.telecom.cts;
+
+import android.telecom.Connection;
+import android.telecom.ConnectionRequest;
+import android.telecom.ConnectionService;
+import android.telecom.PhoneAccount;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.TelecomManager;
+
+import java.util.concurrent.Semaphore;
+
+/**
+ * This is the official ConnectionService for Telecom's CTS App. Since telecom requires that a
+ * CS be registered in the AndroidManifest.xml file, we have to have a single implementation
+ * of a CS and this is it. To test specific CS behavior, tests will implement their own CS and
+ * tell CtsConnectionService to forward any method invocations to that test's implementation.
+ * This is set up using {@link #setUp} and should be cleaned up before the end of the test using
+ * {@link #tearDown}.
+ */
+public class CtsConnectionService extends ConnectionService {
+    private static ConnectionService sConnectionService;
+
+    // ConnectionService used by default as a fallback if no connection service is specified
+    // during test setup.
+    private static ConnectionService mMockConnectionService = new MockConnectionService();
+
+    /**
+     * Used to control whether the {@link MockVideoProvider} will be created when connections are
+     * created.  Used by {@link VideoCallTest#testVideoCallDelayProvider()} to test scenario where
+     * the {@link MockVideoProvider} is not created immediately when the Connection is created.
+     */
+    private static Object sLock = new Object();
+
+    public static PhoneAccount setUp(PhoneAccount phoneAccount, ConnectionService connectionService)
+            throws Exception {
+        synchronized(sLock) {
+            if (sConnectionService != null) {
+                throw new Exception("Mock ConnectionService exists.  Failed to call tearDown().");
+            }
+            sConnectionService = connectionService;
+            return phoneAccount;
+        }
+    }
+
+    public static void tearDown() {
+        synchronized(sLock) {
+            sConnectionService = null;
+        }
+    }
+
+    @Override
+    public Connection onCreateOutgoingConnection(PhoneAccountHandle connectionManagerPhoneAccount,
+            ConnectionRequest request) {
+        synchronized(sLock) {
+            if (sConnectionService != null) {
+                return sConnectionService.onCreateOutgoingConnection(
+                        connectionManagerPhoneAccount, request);
+            } else {
+                return mMockConnectionService.onCreateOutgoingConnection(
+                        connectionManagerPhoneAccount, request);
+            }
+        }
+    }
+
+    @Override
+    public Connection onCreateIncomingConnection(PhoneAccountHandle connectionManagerPhoneAccount,
+            ConnectionRequest request) {
+        synchronized(sLock) {
+            if (sConnectionService != null) {
+                return sConnectionService.onCreateIncomingConnection(
+                        connectionManagerPhoneAccount, request);
+            }
+            return mMockConnectionService.onCreateIncomingConnection(
+                    connectionManagerPhoneAccount, request);
+        }
+    }
+}
diff --git a/tests/tests/telecom/src/android/telecom/cts/ExtendedInCallServiceTest.java b/tests/tests/telecom/src/android/telecom/cts/ExtendedInCallServiceTest.java
index 97a9a53..fbbf3ca 100644
--- a/tests/tests/telecom/src/android/telecom/cts/ExtendedInCallServiceTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/ExtendedInCallServiceTest.java
@@ -26,11 +26,19 @@
 import android.telecom.VideoProfile;
 
 /**
- * Extended suite of tests that use {@link MockConnectionService} and {@link MockInCallService} to
+ * Extended suite of tests that use {@link CtsConnectionService} and {@link MockInCallService} to
  * verify the functionality of the Telecom service.
  */
 public class ExtendedInCallServiceTest extends BaseTelecomTestWithMockServices {
 
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        if (TestUtils.shouldTestTelecom(mContext)) {
+            setupConnectionService(null, FLAG_REGISTER | FLAG_ENABLE);
+        }
+    }
+
     public void testAddNewOutgoingCallAndThenDisconnect() {
         if (!shouldTestTelecom(mContext)) {
             return;
@@ -51,18 +59,17 @@
         }
 
         placeAndVerifyCall();
-        verifyConnectionForOutgoingCall();
+        final MockConnection connection = verifyConnectionForOutgoingCall();
 
         final MockInCallService inCallService = mInCallCallbacks.getService();
 
         final Call call = inCallService.getLastCall();
-        final MockConnection connection = mConnectionCallbacks.outgoingConnection;
 
         assertCallState(call, Call.STATE_ACTIVE);
 
         assertMuteState(connection, false);
 
-        inCallService.setMuted(true);;
+        inCallService.setMuted(true);
 
         assertMuteState(connection, true);
         assertMuteState(inCallService, true);
@@ -78,10 +85,9 @@
         }
 
         placeAndVerifyCall();
-        verifyConnectionForOutgoingCall();
+        final MockConnection connection = verifyConnectionForOutgoingCall();
 
         final MockInCallService inCallService = mInCallCallbacks.getService();
-        final MockConnection connection = mConnectionCallbacks.outgoingConnection;
 
         final Call call = inCallService.getLastCall();
         assertCallState(call, Call.STATE_ACTIVE);
@@ -111,10 +117,9 @@
         }
 
         placeAndVerifyCall();
-        verifyConnectionForOutgoingCall();
+        final MockConnection connection = verifyConnectionForOutgoingCall();
 
         final MockInCallService inCallService = mInCallCallbacks.getService();
-        final MockConnection connection = mConnectionCallbacks.outgoingConnection;
 
         final Call call = inCallService.getLastCall();
         assertCallState(call, Call.STATE_ACTIVE);
@@ -145,10 +150,9 @@
         }
 
         placeAndVerifyCall();
-        verifyConnectionForOutgoingCall();
+        final MockConnection connection = verifyConnectionForOutgoingCall();
 
         final MockInCallService inCallService = mInCallCallbacks.getService();
-        final MockConnection connection = mConnectionCallbacks.outgoingConnection;
 
         final Call call = inCallService.getLastCall();
 
@@ -165,10 +169,9 @@
 
     public void testAnswerIncomingCallAudioOnly() {
         addAndVerifyNewIncomingCall(getTestNumber(), null);
-        verifyConnectionForIncomingCall();
+        final MockConnection connection = verifyConnectionForIncomingCall();
 
         final MockInCallService inCallService = mInCallCallbacks.getService();
-        final MockConnection connection = mConnectionCallbacks.incomingConnection;
 
         final Call call = inCallService.getLastCall();
 
@@ -183,10 +186,9 @@
 
     public void testAnswerIncomingCallAsVideo_SendsCorrectVideoState() {
         addAndVerifyNewIncomingCall(getTestNumber(), null);
-        verifyConnectionForIncomingCall();
+        final MockConnection connection = verifyConnectionForIncomingCall();
 
         final MockInCallService inCallService = mInCallCallbacks.getService();
-        final MockConnection connection = mConnectionCallbacks.incomingConnection;
 
         final Call call = inCallService.getLastCall();
 
@@ -203,10 +205,9 @@
 
     public void testRejectIncomingCall() {
         addAndVerifyNewIncomingCall(getTestNumber(), null);
-        verifyConnectionForIncomingCall();
+        final MockConnection connection = verifyConnectionForIncomingCall();
 
         final MockInCallService inCallService = mInCallCallbacks.getService();
-        final MockConnection connection = mConnectionCallbacks.incomingConnection;
 
         final Call call = inCallService.getLastCall();
 
diff --git a/tests/tests/telecom/src/android/telecom/cts/MockConnectionService.java b/tests/tests/telecom/src/android/telecom/cts/MockConnectionService.java
index 6dbea7c..acd93f7 100644
--- a/tests/tests/telecom/src/android/telecom/cts/MockConnectionService.java
+++ b/tests/tests/telecom/src/android/telecom/cts/MockConnectionService.java
@@ -18,137 +18,59 @@
 
 import android.telecom.Connection;
 import android.telecom.ConnectionRequest;
-import android.telecom.ConnectionService;
-import android.telecom.PhoneAccount;
 import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
 
 import java.util.concurrent.Semaphore;
 
 /**
- * This is the official ConnectionService for Telecom's CTS App. Since telecom requires that a
- * CS be registered in the AndroidManifest.xml file, we have to have a single implementation
- * of a CS and this is it. To test specific CS behavior, tests will implement their own CS and
- * tell MockConnectionService to forward any method invocations to that test's implementation.
- * This is set up using {@link #setUp} and should be cleaned up before the end of the test using
- * {@link #tearDown}.
+ * Default implementation of a {@link CtsConnectionService}. This is used for the majority
+ * of Telecom CTS tests that simply require that a outgoing call is placed, or incoming call is
+ * received.
  */
-public class MockConnectionService extends ConnectionService {
-    private static ConnectionServiceCallbacks sCallbacks;
-    private static ConnectionService sConnectionService;
-
+public class MockConnectionService extends CtsConnectionService {
     /**
      * Used to control whether the {@link MockVideoProvider} will be created when connections are
      * created.  Used by {@link VideoCallTest#testVideoCallDelayProvider()} to test scenario where
      * the {@link MockVideoProvider} is not created immediately when the Connection is created.
      */
-    private static boolean sCreateVideoProvider = true;
-    private static Object sLock = new Object();
+    private boolean mCreateVideoProvider = true;
 
-    public static abstract class ConnectionServiceCallbacks {
-        private MockConnectionService mService;
-        public MockConnection outgoingConnection;
-        public MockConnection incomingConnection;
-        public Semaphore lock = new Semaphore(0);
-
-        public void onCreateOutgoingConnection(MockConnection connection,
-                ConnectionRequest request) {};
-        public void onCreateIncomingConnection(MockConnection connection,
-                ConnectionRequest request) {};
-
-        final public MockConnectionService getService() {
-            return mService;
-        }
-
-        final public void setService(MockConnectionService service) {
-            mService = service;
-        }
-    }
-
-    public static PhoneAccount setUp(PhoneAccount phoneAccount, ConnectionService connectionService)
-            throws Exception {
-        synchronized(sLock) {
-            if (sConnectionService != null) {
-                throw new Exception("Mock ConnectionService exists.  Failed to call tearDown().");
-            }
-            sConnectionService = connectionService;
-            return phoneAccount;
-        }
-    }
-
-    public static void tearDown() {
-        synchronized(sLock) {
-            sConnectionService = null;
-        }
-    }
+    public Semaphore lock = new Semaphore(0);
+    public MockConnection outgoingConnection;
+    public MockConnection incomingConnection;
 
     @Override
     public Connection onCreateOutgoingConnection(PhoneAccountHandle connectionManagerPhoneAccount,
             ConnectionRequest request) {
-        synchronized(sLock) {
-            if (sConnectionService != null) {
-                return sConnectionService.onCreateOutgoingConnection(
-                        connectionManagerPhoneAccount, request);
-            }
-        }
         final MockConnection connection = new MockConnection();
         connection.setAddress(request.getAddress(), TelecomManager.PRESENTATION_ALLOWED);
-        if (sCreateVideoProvider) {
+        if (mCreateVideoProvider) {
             connection.createMockVideoProvider();
         } else {
-            sCreateVideoProvider = true;
+            mCreateVideoProvider = true;
         }
         connection.setVideoState(request.getVideoState());
 
-        final ConnectionServiceCallbacks callbacks = getCallbacks();
-        if (callbacks != null) {
-            callbacks.setService(this);
-            callbacks.outgoingConnection = connection;
-            callbacks.onCreateOutgoingConnection(connection, request);
-        }
+        outgoingConnection = connection;
+        lock.release();
         return connection;
     }
 
     @Override
     public Connection onCreateIncomingConnection(PhoneAccountHandle connectionManagerPhoneAccount,
             ConnectionRequest request) {
-        synchronized(sLock) {
-            if (sConnectionService != null) {
-                return sConnectionService.onCreateIncomingConnection(
-                        connectionManagerPhoneAccount, request);
-            }
-        }
-
         final MockConnection connection = new MockConnection();
         connection.setAddress(request.getAddress(), TelecomManager.PRESENTATION_ALLOWED);
         connection.createMockVideoProvider();
         connection.setVideoState(request.getVideoState());
 
-        final ConnectionServiceCallbacks callbacks = getCallbacks();
-        if (callbacks != null) {
-            callbacks.setService(this);
-            callbacks.incomingConnection = connection;
-            callbacks.onCreateIncomingConnection(connection, request);
-        }
+        incomingConnection = connection;
+        lock.release();
         return connection;
     }
 
-    public static void setCallbacks(ConnectionServiceCallbacks callbacks) {
-        synchronized (sLock) {
-            sCallbacks = callbacks;
-        }
-    }
-
-    private ConnectionServiceCallbacks getCallbacks() {
-        synchronized (sLock) {
-            if (sCallbacks != null) {
-                sCallbacks.setService(this);
-            }
-            return sCallbacks;
-        }
-    }
-
-    public static void setCreateVideoProvider(boolean createVideoProvider) {
-        sCreateVideoProvider = createVideoProvider;
+    public void setCreateVideoProvider(boolean createVideoProvider) {
+        mCreateVideoProvider = createVideoProvider;
     }
 }
diff --git a/tests/tests/telecom/src/android/telecom/cts/MockInCallService.java b/tests/tests/telecom/src/android/telecom/cts/MockInCallService.java
index f45d4c3..c3890a0 100644
--- a/tests/tests/telecom/src/android/telecom/cts/MockInCallService.java
+++ b/tests/tests/telecom/src/android/telecom/cts/MockInCallService.java
@@ -16,12 +16,9 @@
 
 package android.telecom.cts;
 
-import android.content.Intent;
-import android.os.Binder;
 import android.telecom.Call;
 import android.telecom.InCallService;
 import android.util.ArrayMap;
-import android.util.Log;
 
 import java.util.ArrayList;
 import java.util.Map;
diff --git a/tests/tests/telecom/src/android/telecom/cts/NumberDialingTest.java b/tests/tests/telecom/src/android/telecom/cts/NumberDialingTest.java
index f0df70a..673013f 100644
--- a/tests/tests/telecom/src/android/telecom/cts/NumberDialingTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/NumberDialingTest.java
@@ -18,32 +18,22 @@
 
 import static android.telecom.cts.TestUtils.shouldTestTelecom;
 
-import android.content.Context;
 import android.net.Uri;
 import android.telecom.Connection;
 import android.telecom.ConnectionRequest;
-import android.telecom.ConnectionService;
 import android.telecom.PhoneAccount;
 import android.telecom.PhoneAccountHandle;
 
 /**
  * Tests that certain numbers make their way through to the connection service.
  */
-public class NumberDialingTest extends SimpleTelecomTest {
-
-    private Context mContext;
+public class NumberDialingTest extends BaseTelecomTestWithMockServices {
 
     /**
      * Amount of time to wait for an asynchronous method invocation to ConnectionService.
      */
     private static final int CS_WAIT_MILLIS = 2000;
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mContext = getInstrumentation().getContext();
-    }
-
     public void testEndInPound() throws Exception {
         if (!shouldTestTelecom(mContext)) {
             return;
@@ -52,8 +42,8 @@
         final Object[] res = new Object[1];
         Uri address = Uri.fromParts("tel", "*1234#", null);
 
-        PhoneAccount account = setupConnectionService("testEndInPound",
-                new ConnectionService() {
+        PhoneAccount account = setupConnectionService(
+                new MockConnectionService() {
                     @Override
                     public Connection onCreateOutgoingConnection(
                             PhoneAccountHandle connectionManagerPhoneAccount,
diff --git a/tests/tests/telecom/src/android/telecom/cts/OutgoingCallTest.java b/tests/tests/telecom/src/android/telecom/cts/OutgoingCallTest.java
index c12b508..b1c77fd 100644
--- a/tests/tests/telecom/src/android/telecom/cts/OutgoingCallTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/OutgoingCallTest.java
@@ -27,6 +27,14 @@
  */
 public class OutgoingCallTest extends BaseTelecomTestWithMockServices {
 
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        if (TestUtils.shouldTestTelecom(mContext)) {
+            setupConnectionService(null, FLAG_REGISTER | FLAG_ENABLE);
+        }
+    }
+
     // TODO: Need to send some commands to the UserManager via adb to do setup
     public void testDisallowOutgoingCallsForSecondaryUser() {
 
diff --git a/tests/tests/telecom/src/android/telecom/cts/SimpleTelecomTest.java b/tests/tests/telecom/src/android/telecom/cts/SimpleTelecomTest.java
deleted file mode 100644
index 377a999..0000000
--- a/tests/tests/telecom/src/android/telecom/cts/SimpleTelecomTest.java
+++ /dev/null
@@ -1,99 +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.telecom.cts;
-
-import static android.telecom.cts.TestUtils.shouldTestTelecom;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.net.Uri;
-import android.telecom.Connection;
-import android.telecom.ConnectionRequest;
-import android.telecom.ConnectionService;
-import android.telecom.PhoneAccount;
-import android.telecom.PhoneAccountHandle;
-import android.telecom.TelecomManager;
-import android.test.InstrumentationTestCase;
-
-/**
- * Scaffolding for a simple telecom test.  Provides helper methods for registers a phone account
- * and making calls.
- */
-public class SimpleTelecomTest extends InstrumentationTestCase {
-
-    private Context mContext;
-    private TelecomManager mTelecomManager;
-
-    public static final int FLAG_REGISTER = 0x1;
-    public static final int FLAG_ENABLE = 0x2;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mContext = getInstrumentation().getContext();
-        mTelecomManager = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        MockConnectionService.tearDown();
-        super.tearDown();
-    }
-
-    protected PhoneAccount setupConnectionService(
-            String testTag, ConnectionService connectionService, int flags) throws Exception {
-
-        PhoneAccount.Builder builder = new PhoneAccount.Builder(
-                new PhoneAccountHandle(
-                        new ComponentName("com.android.cts.telecom",
-                            "android.telecom.cts.MockConnectionService"),
-                        testTag),
-                "TestPA " + testTag)
-            .setAddress(Uri.fromParts("tel:", "5417705", null))
-            .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
-            .setShortDescription("CTS Test Account with ID " + testTag)
-            .addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
-            .addSupportedUriScheme(PhoneAccount.SCHEME_VOICEMAIL);
-
-        // register and enable the phone account
-        PhoneAccount account = builder.build();
-        MockConnectionService.setUp(account, connectionService);
-
-        if ((flags & FLAG_REGISTER) != 0) {
-            mTelecomManager.registerPhoneAccount(account);
-        }
-        if ((flags & FLAG_ENABLE) != 0) {
-            TestUtils.enablePhoneAccount(getInstrumentation(), account.getAccountHandle());
-        }
-
-        return account;
-    }
-
-    protected void tearDownConnectionService(PhoneAccount account) throws Exception {
-        mTelecomManager.unregisterPhoneAccount(account.getAccountHandle());
-    }
-
-    protected void startCallTo(Uri address, PhoneAccountHandle accountHandle) {
-        final Intent intent = new Intent(Intent.ACTION_CALL, address);
-        if (accountHandle != null) {
-            intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, accountHandle);
-        }
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        mContext.startActivity(intent);
-    }
-}
diff --git a/tests/tests/telecom/src/android/telecom/cts/TestUtils.java b/tests/tests/telecom/src/android/telecom/cts/TestUtils.java
index ddc85a6..3356be0 100644
--- a/tests/tests/telecom/src/android/telecom/cts/TestUtils.java
+++ b/tests/tests/telecom/src/android/telecom/cts/TestUtils.java
@@ -37,10 +37,10 @@
     // Non-final to allow modification by tests not in this package (e.g. permission-related
     // tests in the Telecom2 test package.
     public static String PACKAGE = "com.android.cts.telecom";
-    public static final String COMPONENT = "android.telecom.cts.MockConnectionService";
+    public static final String COMPONENT = "android.telecom.cts.CtsConnectionService";
     public static final String ACCOUNT_ID = "xtstest_CALL_PROVIDER_ID";
 
-    public static final String LABEL = "CTS_MockConnectionService";
+    public static final String LABEL = "CTSConnectionService";
 
     private static final String COMMAND_SET_DEFAULT_DIALER = "telecom set-default-dialer ";
 
diff --git a/tests/tests/telecom/src/android/telecom/cts/VideoCallTest.java b/tests/tests/telecom/src/android/telecom/cts/VideoCallTest.java
index b3ceb4d..e62d125 100644
--- a/tests/tests/telecom/src/android/telecom/cts/VideoCallTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/VideoCallTest.java
@@ -43,6 +43,15 @@
  * hear back via our callback.  Suboptimal, but it works.
  */
 public class VideoCallTest extends BaseTelecomTestWithMockServices {
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        if (TestUtils.shouldTestTelecom(mContext)) {
+            setupConnectionService(null, FLAG_REGISTER | FLAG_ENABLE);
+        }
+    }
+
     /**
      * Tests ability to start a 2-way video call and retrieve its video state.
      */
@@ -53,7 +62,6 @@
 
         final MockInCallService inCallService = mInCallCallbacks.getService();
         final Call call = inCallService.getLastCall();
-        final MockConnection connection = mConnectionCallbacks.outgoingConnection;
 
         assertCallState(call, Call.STATE_ACTIVE);
         assertVideoState(call, VideoProfile.STATE_BIDIRECTIONAL);
@@ -99,11 +107,11 @@
      */
     public void testReceiveSessionModifyRequest() {
         placeAndVerifyCall(VideoProfile.STATE_AUDIO_ONLY);
-        verifyConnectionForOutgoingCall();
+        final MockConnection connection = verifyConnectionForOutgoingCall();
 
         final MockInCallService inCallService = mInCallCallbacks.getService();
         final Call call = inCallService.getLastCall();
-        final MockConnection connection = mConnectionCallbacks.outgoingConnection;
+
         assertVideoState(call, VideoProfile.STATE_AUDIO_ONLY);
         assertVideoCallbackRegistered(inCallService, call, true);
 
@@ -124,11 +132,10 @@
      */
     public void testSendSessionModifyResponse() {
         placeAndVerifyCall(VideoProfile.STATE_AUDIO_ONLY);
-        verifyConnectionForOutgoingCall();
+        final MockConnection connection = verifyConnectionForOutgoingCall();
 
         final MockInCallService inCallService = mInCallCallbacks.getService();
         final Call call = inCallService.getLastCall();
-        final MockConnection connection = mConnectionCallbacks.outgoingConnection;
         final MockVideoProvider mockVideoProvider = connection.getMockVideoProvider();
         assertVideoState(call, VideoProfile.STATE_AUDIO_ONLY);
         assertVideoCallbackRegistered(inCallService, call, true);
@@ -148,13 +155,12 @@
     public void testVideoCallDelayProvider() {
         // Don't create video provider when call is created initially; we will do this later.
         try {
-            MockConnectionService.setCreateVideoProvider(false);
+            connectionService.setCreateVideoProvider(false);
             placeAndVerifyCall(VideoProfile.STATE_BIDIRECTIONAL);
-            verifyConnectionForOutgoingCall();
+            final MockConnection connection = verifyConnectionForOutgoingCall();
 
             final MockInCallService inCallService = mInCallCallbacks.getService();
             final Call call = inCallService.getLastCall();
-            final MockConnection connection = mConnectionCallbacks.outgoingConnection;
 
             assertVideoState(call, VideoProfile.STATE_BIDIRECTIONAL);
             // After initial connection creation there should not be a video provider or callbacks
@@ -168,7 +174,7 @@
 
             // Ensure video providers are created in the future.
         } finally {
-            MockConnectionService.setCreateVideoProvider(true);
+            connectionService.setCreateVideoProvider(true);
         }
     }
 
@@ -241,9 +247,8 @@
      */
     public void testReceiveVideoQuality() {
         placeAndVerifyCall(VideoProfile.STATE_BIDIRECTIONAL);
-        verifyConnectionForOutgoingCall();
+        final MockConnection connection = verifyConnectionForOutgoingCall();
 
-        final MockConnection connection = mConnectionCallbacks.outgoingConnection;
         final MockInCallService inCallService = mInCallCallbacks.getService();
         final Call call = inCallService.getLastCall();
         assertVideoCallbackRegistered(inCallService, call, true);
@@ -274,9 +279,8 @@
      */
     public void testReceiveCallSessionEvent() {
         placeAndVerifyCall(VideoProfile.STATE_BIDIRECTIONAL);
-        verifyConnectionForOutgoingCall();
+        final MockConnection connection = verifyConnectionForOutgoingCall();
 
-        final MockConnection connection = mConnectionCallbacks.outgoingConnection;
         final MockInCallService inCallService = mInCallCallbacks.getService();
         final Call call = inCallService.getLastCall();
         assertVideoCallbackRegistered(inCallService, call, true);
@@ -297,9 +301,8 @@
      */
     public void testReceivePeerDimensionChange() {
         placeAndVerifyCall(VideoProfile.STATE_BIDIRECTIONAL);
-        verifyConnectionForOutgoingCall();
+        final MockConnection connection = verifyConnectionForOutgoingCall();
 
-        final MockConnection connection = mConnectionCallbacks.outgoingConnection;
         final MockInCallService inCallService = mInCallCallbacks.getService();
         final Call call = inCallService.getLastCall();
         assertVideoCallbackRegistered(inCallService, call, true);
@@ -319,9 +322,8 @@
      */
     public void testSetDeviceOrientation() {
         placeAndVerifyCall(VideoProfile.STATE_BIDIRECTIONAL);
-        verifyConnectionForOutgoingCall();
+        final MockConnection connection = verifyConnectionForOutgoingCall();
 
-        final MockConnection connection = mConnectionCallbacks.outgoingConnection;
         final MockInCallService inCallService = mInCallCallbacks.getService();
         final Call call = inCallService.getLastCall();
         assertVideoCallbackRegistered(inCallService, call, true);
@@ -338,9 +340,8 @@
      */
     public void testSetPreviewSurface() {
         placeAndVerifyCall(VideoProfile.STATE_BIDIRECTIONAL);
-        verifyConnectionForOutgoingCall();
+        final MockConnection connection = verifyConnectionForOutgoingCall();
 
-        final MockConnection connection = mConnectionCallbacks.outgoingConnection;
         final MockInCallService inCallService = mInCallCallbacks.getService();
         final Call call = inCallService.getLastCall();
         assertVideoCallbackRegistered(inCallService, call, true);
@@ -362,9 +363,8 @@
      */
     public void testSetDisplaySurface() {
         placeAndVerifyCall(VideoProfile.STATE_BIDIRECTIONAL);
-        verifyConnectionForOutgoingCall();
+        final MockConnection connection = verifyConnectionForOutgoingCall();
 
-        final MockConnection connection = mConnectionCallbacks.outgoingConnection;
         final MockInCallService inCallService = mInCallCallbacks.getService();
         final Call call = inCallService.getLastCall();
         assertVideoCallbackRegistered(inCallService, call, true);
@@ -386,9 +386,8 @@
      */
     public void testSetZoom() {
         placeAndVerifyCall(VideoProfile.STATE_BIDIRECTIONAL);
-        verifyConnectionForOutgoingCall();
+        final MockConnection connection = verifyConnectionForOutgoingCall();
 
-        final MockConnection connection = mConnectionCallbacks.outgoingConnection;
         final MockInCallService inCallService = mInCallCallbacks.getService();
         final Call call = inCallService.getLastCall();
         assertVideoCallbackRegistered(inCallService, call, true);
diff --git a/tests/tests/telecom/src/android/telecom/cts/WiredHeadsetTest.java b/tests/tests/telecom/src/android/telecom/cts/WiredHeadsetTest.java
index 4e154cf..f2e62dc 100644
--- a/tests/tests/telecom/src/android/telecom/cts/WiredHeadsetTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/WiredHeadsetTest.java
@@ -26,6 +26,15 @@
  * media button.
  */
 public class WiredHeadsetTest extends BaseTelecomTestWithMockServices {
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        if (TestUtils.shouldTestTelecom(mContext)) {
+            setupConnectionService(null, FLAG_REGISTER | FLAG_ENABLE);
+        }
+    }
+
     @Override
     protected void tearDown() throws Exception {
         if (mInCallCallbacks != null && mInCallCallbacks.getService() != null) {
@@ -37,9 +46,8 @@
 
     public void testIncomingCallShortPress_acceptsCall() throws Exception {
         addAndVerifyNewIncomingCall(getTestNumber(), null);
-        verifyConnectionForIncomingCall();
+        final MockConnection connection = verifyConnectionForIncomingCall();
 
-        final MockConnection connection = mConnectionCallbacks.incomingConnection;
         final Call call = mInCallCallbacks.getService().getLastCall();
         assertCallState(call, Call.STATE_RINGING);
         assertConnectionState(connection, Connection.STATE_RINGING);
@@ -51,9 +59,8 @@
 
     public void testIncomingCallLongPress_rejectsCall() throws Exception {
         addAndVerifyNewIncomingCall(getTestNumber(), null);
-        verifyConnectionForIncomingCall();
+        final MockConnection connection = verifyConnectionForIncomingCall();
 
-        final MockConnection connection = mConnectionCallbacks.incomingConnection;
         final Call call = mInCallCallbacks.getService().getLastCall();
         assertCallState(call, Call.STATE_RINGING);
         assertConnectionState(connection, Connection.STATE_RINGING);
@@ -65,8 +72,7 @@
 
     public void testInCallShortPress_togglesMute() throws Exception {
         placeAndVerifyCall();
-        verifyConnectionForOutgoingCall();
-        final MockConnection connection = mConnectionCallbacks.outgoingConnection;
+        final MockConnection connection = verifyConnectionForOutgoingCall();
         final MockInCallService incallService = mInCallCallbacks.getService();
 
         // Verify that sending short presses in succession toggles the mute state of the
@@ -84,9 +90,8 @@
 
     public void testInCallLongPress_hangupCall() throws Exception {
         placeAndVerifyCall();
-        verifyConnectionForOutgoingCall();
+        final MockConnection connection = verifyConnectionForOutgoingCall();
 
-        final MockConnection connection = mConnectionCallbacks.outgoingConnection;
         final Call call = mInCallCallbacks.getService().getLastCall();
         assertCallState(call, Call.STATE_ACTIVE);
         assertConnectionState(connection, Connection.STATE_ACTIVE);
diff --git a/tests/tests/widget/src/android/widget/cts/ArrayAdapterTest.java b/tests/tests/widget/src/android/widget/cts/ArrayAdapterTest.java
index 1e17ea7..fdca64c 100644
--- a/tests/tests/widget/src/android/widget/cts/ArrayAdapterTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ArrayAdapterTest.java
@@ -21,6 +21,7 @@
 import java.util.List;
 
 import android.content.Context;
+import android.content.res.Resources.Theme;
 import android.database.DataSetObserver;
 import android.test.InstrumentationTestCase;
 import android.test.UiThreadTest;
@@ -204,6 +205,12 @@
         mArrayAdapter.setDropDownViewResource(INVALD_ID);
     }
 
+    public void testAccessDropDownViewTheme() {
+        Theme theme = mContext.getResources().newTheme();
+        mArrayAdapter.setDropDownViewTheme(theme);
+        assertSame(theme, mArrayAdapter.getDropDownViewTheme());
+    }
+
     /**
      * insert the item to the specific position, notify data changed
      * check -1, normal, > count
diff --git a/tests/tests/widget/src/android/widget/cts/CursorAdapterTest.java b/tests/tests/widget/src/android/widget/cts/CursorAdapterTest.java
index 0916e59..7fe016f 100644
--- a/tests/tests/widget/src/android/widget/cts/CursorAdapterTest.java
+++ b/tests/tests/widget/src/android/widget/cts/CursorAdapterTest.java
@@ -19,6 +19,7 @@
 import java.io.File;
 
 import android.content.Context;
+import android.content.res.Resources.Theme;
 import android.cts.util.PollingCheck;
 import android.cts.util.ReadElf;
 import android.cts.util.TestThread;
@@ -253,6 +254,14 @@
     }
 
     @UiThreadTest
+    public void testAccessDropDownViewTheme() {
+        CursorAdapter cursorAdapter = new MockCursorAdapter(mContext, null);
+        Theme theme = mContext.getResources().newTheme();
+        cursorAdapter.setDropDownViewTheme(theme);
+        assertSame(theme, cursorAdapter.getDropDownViewTheme());
+    }
+
+    @UiThreadTest
     public void testGetFilter() {
         CursorAdapter cursorAdapter = new MockCursorAdapter(mContext, mCursor);
         Filter filter = cursorAdapter.getFilter();
diff --git a/tests/tests/widget/src/android/widget/cts/SimpleAdapterTest.java b/tests/tests/widget/src/android/widget/cts/SimpleAdapterTest.java
index c530293..5cbf524 100644
--- a/tests/tests/widget/src/android/widget/cts/SimpleAdapterTest.java
+++ b/tests/tests/widget/src/android/widget/cts/SimpleAdapterTest.java
@@ -20,6 +20,7 @@
 
 
 import android.content.Context;
+import android.content.res.Resources.Theme;
 import android.cts.util.WidgetTestUtils;
 import android.graphics.Bitmap;
 import android.graphics.drawable.BitmapDrawable;
@@ -260,6 +261,12 @@
         }
     }
 
+    public void testAccessDropDownViewTheme() {
+        Theme theme = mContext.getResources().newTheme();
+        mSimpleAdapter.setDropDownViewTheme(theme);
+        assertSame(theme, mSimpleAdapter.getDropDownViewTheme());
+    }
+
     public void testAccessViewBinder() {
         // no binder default
         assertNull(mSimpleAdapter.getViewBinder());
diff --git a/tests/tests/widget/src/android/widget/cts/SpinnerTest.java b/tests/tests/widget/src/android/widget/cts/SpinnerTest.java
index 1989626..599d308 100644
--- a/tests/tests/widget/src/android/widget/cts/SpinnerTest.java
+++ b/tests/tests/widget/src/android/widget/cts/SpinnerTest.java
@@ -23,8 +23,10 @@
 import android.app.Dialog;
 import android.content.Context;
 import android.content.res.Resources.NotFoundException;
+import android.content.res.Resources.Theme;
 import android.test.ActivityInstrumentationTestCase2;
 import android.test.UiThreadTest;
+import android.view.ContextThemeWrapper;
 import android.widget.ArrayAdapter;
 import android.widget.Spinner;
 
@@ -52,6 +54,17 @@
 
         new Spinner(mTargetContext, null, com.android.internal.R.attr.spinnerStyle);
 
+        new Spinner(mTargetContext, Spinner.MODE_DIALOG);
+
+        new Spinner(mTargetContext, null, com.android.internal.R.attr.spinnerStyle,
+                Spinner.MODE_DIALOG);
+
+        new Spinner(mTargetContext, null, com.android.internal.R.attr.spinnerStyle, 0,
+                Spinner.MODE_DIALOG);
+
+        new Spinner(mTargetContext, null, com.android.internal.R.attr.spinnerStyle, 0,
+                Spinner.MODE_DIALOG, mTargetContext.getTheme());
+
         Spinner spinner = (Spinner) getActivity().findViewById(R.id.spinner1);
         assertEquals(mTargetContext.getString(R.string.text_view_hello), spinner.getPrompt());
     }
@@ -156,6 +169,18 @@
         // TODO: find the dialog and get its title to assert whether setPromptId() takes effect?
     }
 
+    @UiThreadTest
+    public void testGetPopupContext() {
+        Theme theme = mTargetContext.getResources().newTheme();
+        Spinner themeSpinner = new Spinner(mTargetContext, null,
+                com.android.internal.R.attr.spinnerStyle, 0, Spinner.MODE_DIALOG, theme);
+        assertNotSame(mTargetContext, themeSpinner.getPopupContext());
+        assertSame(theme, themeSpinner.getPopupContext().getTheme());
+
+        ContextThemeWrapper context = (ContextThemeWrapper)themeSpinner.getPopupContext();
+        assertSame(mTargetContext, context.getBaseContext());
+    }
+
     public void testOnLayout() {
         // onLayout() is implementation details, do NOT test
     }
diff --git a/tests/tests/widget/src/android/widget/cts/TextViewTest.java b/tests/tests/widget/src/android/widget/cts/TextViewTest.java
index 291e5c2..62c4732 100644
--- a/tests/tests/widget/src/android/widget/cts/TextViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TextViewTest.java
@@ -33,6 +33,7 @@
 import android.graphics.Color;
 import android.graphics.Paint;
 import android.graphics.Path;
+import android.graphics.PorterDuff;
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.graphics.Typeface;
@@ -2831,7 +2832,7 @@
         assertEquals(40, mTextView.getPaddingBottom());
     }
 
-    public void testSetTextAppearance() {
+    public void testDeprecatedSetTextAppearance() {
         mTextView = new TextView(mActivity);
 
         mTextView.setTextAppearance(mActivity, R.style.TextAppearance_All);
@@ -2860,10 +2861,49 @@
         assertEquals(null, mTextView.getTypeface());
     }
 
+    public void testSetTextAppearance() {
+        mTextView = new TextView(mActivity);
+
+        mTextView.setTextAppearance(R.style.TextAppearance_All);
+        assertEquals(mActivity.getResources().getColor(R.drawable.black),
+                mTextView.getCurrentTextColor());
+        assertEquals(20f, mTextView.getTextSize(), 0.01f);
+        assertEquals(Typeface.BOLD, mTextView.getTypeface().getStyle());
+        assertEquals(mActivity.getResources().getColor(R.drawable.red),
+                mTextView.getCurrentHintTextColor());
+        assertEquals(mActivity.getResources().getColor(R.drawable.blue),
+                mTextView.getLinkTextColors().getDefaultColor());
+
+        mTextView.setTextAppearance(R.style.TextAppearance_Colors);
+        assertEquals(mActivity.getResources().getColor(R.drawable.black),
+                mTextView.getCurrentTextColor());
+        assertEquals(mActivity.getResources().getColor(R.drawable.blue),
+                mTextView.getCurrentHintTextColor());
+        assertEquals(mActivity.getResources().getColor(R.drawable.yellow),
+                mTextView.getLinkTextColors().getDefaultColor());
+
+        mTextView.setTextAppearance(R.style.TextAppearance_NotColors);
+        assertEquals(17f, mTextView.getTextSize(), 0.01f);
+        assertEquals(Typeface.NORMAL, mTextView.getTypeface().getStyle());
+
+        mTextView.setTextAppearance(R.style.TextAppearance_Style);
+        assertEquals(null, mTextView.getTypeface());
+    }
+
     public void testOnPreDraw() {
         // Do not test. Implementation details.
     }
 
+    public void testAccessCompoundDrawableTint() {
+        mTextView = new TextView(mActivity);
+
+        ColorStateList colors = ColorStateList.valueOf(Color.RED);
+        mTextView.setCompoundDrawableTintList(colors);
+        mTextView.setCompoundDrawableTintMode(PorterDuff.Mode.XOR);
+        assertSame(colors, mTextView.getCompoundDrawableTintList());
+        assertEquals(PorterDuff.Mode.XOR, mTextView.getCompoundDrawableTintMode());
+    }
+
     public void testSetHorizontallyScrolling() {
         // make the text view has more than one line
         mTextView = findTextView(R.id.textview_text);