Merge "Fix delegated cert installer test" into nyc-dev
diff --git a/CtsTestCaseList.mk b/CtsTestCaseList.mk
index 3bcc80d..64bbf2b 100644
--- a/CtsTestCaseList.mk
+++ b/CtsTestCaseList.mk
@@ -114,6 +114,7 @@
     CtsSimpleApp \
     CtsSimplePreMApp \
     CtsSomeAccessibilityServices \
+    CtsSystemUiDeviceApp \
     CtsThemeDeviceApp \
     TestDeviceSetup \
     CtsUiAutomatorTestApp \
@@ -257,7 +258,8 @@
     CtsServicesHostTestCases \
     CtsThemeHostTestCases \
     CtsUiHostTestCases \
-    CtsUsbTests
+    CtsUsbTests \
+    CtsSystemUiHostTestCases \
 
 # List of native tests. For 32 bit targets, assumes that there will be
 # one test executable, and it will end in 32. For 64 bit targets, assumes
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/InfoStore.java b/common/device-side/util/src/com/android/compatibility/common/util/InfoStore.java
index 62decdc..a8dbeff 100644
--- a/common/device-side/util/src/com/android/compatibility/common/util/InfoStore.java
+++ b/common/device-side/util/src/com/android/compatibility/common/util/InfoStore.java
@@ -284,7 +284,7 @@
 
     private static String checkString(String value) {
         if (value == null || value.isEmpty()) {
-            return "null";
+            return "";
         }
         if (value.length() > MAX_STRING_LENGTH) {
             return value.substring(0, MAX_STRING_LENGTH);
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/DeviceInfoCollector.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/DeviceInfoCollector.java
index d4ca49d..6cf1ff7 100644
--- a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/DeviceInfoCollector.java
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/DeviceInfoCollector.java
@@ -53,6 +53,8 @@
         BUILD_KEYS.put("build_type", "ro.build.type");
         BUILD_KEYS.put("build_tags", "ro.build.tags");
         BUILD_KEYS.put("build_fingerprint", "ro.build.fingerprint");
+        BUILD_KEYS.put("build_abi", "ro.product.cpu.abi");
+        BUILD_KEYS.put("build_abi2", "ro.product.cpu.abi2");
         BUILD_KEYS.put("build_abis", "ro.product.cpu.abilist");
         BUILD_KEYS.put("build_abis_32", "ro.product.cpu.abilist32");
         BUILD_KEYS.put("build_abis_64", "ro.product.cpu.abilist64");
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ClearDeviceOwnerTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ClearDeviceOwnerTest.java
index f10124a..70829ed 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ClearDeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ClearDeviceOwnerTest.java
@@ -30,12 +30,12 @@
         mDevicePolicyManager = (DevicePolicyManager)
                 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
         if (mDevicePolicyManager != null) {
-            removeActiveAdmin(BaseDeviceOwnerTest.getWho());
             if (mDevicePolicyManager.isDeviceOwnerApp(BaseDeviceOwnerTest.PACKAGE_NAME)) {
                 mDevicePolicyManager.clearDeviceOwnerApp(BaseDeviceOwnerTest.PACKAGE_NAME);
             }
-            assertFalse(mDevicePolicyManager.isAdminActive(BaseDeviceOwnerTest.getWho()));
             assertFalse(mDevicePolicyManager.isDeviceOwnerApp(BaseDeviceOwnerTest.PACKAGE_NAME));
+
+            waitForActiveAdminRemoved(BaseDeviceOwnerTest.getWho());
         }
 
         super.tearDown();
@@ -46,12 +46,10 @@
     public void testClearDeviceOwner() {
     }
 
-    private void removeActiveAdmin(ComponentName cn) throws InterruptedException {
-        if (mDevicePolicyManager.isAdminActive(cn)) {
-            mDevicePolicyManager.removeActiveAdmin(cn);
-            for (int i = 0; i < 1000 && mDevicePolicyManager.isAdminActive(cn); i++) {
-                Thread.sleep(100);
-            }
+    private void waitForActiveAdminRemoved(ComponentName cn) throws InterruptedException {
+        for (int i = 0; i < 1000 && mDevicePolicyManager.isAdminActive(cn); i++) {
+            Thread.sleep(100);
         }
+        assertFalse(mDevicePolicyManager.isAdminActive(cn));
     }
 }
diff --git a/hostsidetests/devicepolicy/app/PackageInstaller/src/com/android/cts/packageinstaller/ClearDeviceOwnerTest.java b/hostsidetests/devicepolicy/app/PackageInstaller/src/com/android/cts/packageinstaller/ClearDeviceOwnerTest.java
index a06271b..d4718df 100644
--- a/hostsidetests/devicepolicy/app/PackageInstaller/src/com/android/cts/packageinstaller/ClearDeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/app/PackageInstaller/src/com/android/cts/packageinstaller/ClearDeviceOwnerTest.java
@@ -52,10 +52,9 @@
 
     @Override
     protected void tearDown() throws Exception {
-        removeActiveAdmin(ADMIN_RECEIVER_COMPONENT);
         mDevicePolicyManager.clearDeviceOwnerApp(PACKAGE_NAME);
-        assertFalse(mDevicePolicyManager.isAdminActive(ADMIN_RECEIVER_COMPONENT));
         assertFalse(mDevicePolicyManager.isDeviceOwnerApp(PACKAGE_NAME));
+        waitForActiveAdminRemoved(ADMIN_RECEIVER_COMPONENT);
 
         super.tearDown();
     }
@@ -65,12 +64,10 @@
     public void testClearDeviceOwner() {
     }
 
-    private void removeActiveAdmin(ComponentName cn) throws InterruptedException {
-        if (mDevicePolicyManager.isAdminActive(cn)) {
-            mDevicePolicyManager.removeActiveAdmin(cn);
-            for (int i = 0; i < 1000 && mDevicePolicyManager.isAdminActive(cn); i++) {
-                Thread.sleep(100);
-            }
+    private void waitForActiveAdminRemoved(ComponentName cn) throws InterruptedException {
+        for (int i = 0; i < 1000 && mDevicePolicyManager.isAdminActive(cn); i++) {
+            Thread.sleep(100);
         }
+        assertFalse(mDevicePolicyManager.isAdminActive(cn));
     }
 }
diff --git a/hostsidetests/net/app/src/com/android/cts/net/hostside/ConnectivityManagerTest.java b/hostsidetests/net/app/src/com/android/cts/net/hostside/ConnectivityManagerTest.java
index 300e39d..34c8d28 100644
--- a/hostsidetests/net/app/src/com/android/cts/net/hostside/ConnectivityManagerTest.java
+++ b/hostsidetests/net/app/src/com/android/cts/net/hostside/ConnectivityManagerTest.java
@@ -25,9 +25,14 @@
 import android.content.Context;
 import android.content.SharedPreferences;
 import android.net.ConnectivityManager;
+import android.net.Network;
+import android.net.NetworkInfo;
 import android.test.InstrumentationTestCase;
 import android.util.Log;
 
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
 /**
  * Tests for the {@link ConnectivityManager} API.
  *
@@ -38,27 +43,36 @@
 public class ConnectivityManagerTest extends InstrumentationTestCase {
     private static final String TAG = "ConnectivityManagerTest";
 
-    static final String MANIFEST_RECEIVER = "ManifestReceiver";
-    static final String DYNAMIC_RECEIVER = "DynamicReceiver";
+    private static final String MANIFEST_RECEIVER = "ManifestReceiver";
+    private static final String DYNAMIC_RECEIVER = "DynamicReceiver";
 
-    private ConnectivityManager mCM;
+    private static final String STATUS_NETWORK_UNAVAILABLE_PREFIX = "NetworkUnavailable:";
+    private static final String STATUS_NETWORK_AVAILABLE_PREFIX = "NetworkAvailable:";
+
+    private ConnectivityManager mCm;
+    private int mUid;
 
     @Override
     public void setUp() throws Exception {
         super.setUp();
-        mCM = (ConnectivityManager) getInstrumentation().getContext().getSystemService(
-                Activity.CONNECTIVITY_SERVICE);
+        final Context context = getInstrumentation().getContext();
+        mCm = (ConnectivityManager) context.getSystemService(Activity.CONNECTIVITY_SERVICE);
+        mUid = context.getPackageManager()
+                .getPackageInfo(context.getPackageName(), 0).applicationInfo.uid;
+        final boolean metered = mCm.isActiveNetworkMetered();
+        Log.i(TAG, getName() + ": uid=" + mUid + ", metered=" + metered);
+        assertTrue("Active network is not metered", metered);
    }
 
-    public void testGetRestrictBackgroundStatus_disabled() {
+    public void testGetRestrictBackgroundStatus_disabled() throws Exception {
         assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED);
     }
 
-    public void testGetRestrictBackgroundStatus_whitelisted() {
+    public void testGetRestrictBackgroundStatus_whitelisted() throws Exception {
         assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_WHITELISTED);
     }
 
-    public void testGetRestrictBackgroundStatus_enabled() {
+    public void testGetRestrictBackgroundStatus_enabled() throws Exception {
         assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_ENABLED);
     }
 
@@ -102,11 +116,34 @@
         return prefs.getInt(action, 0);
     }
 
-    private void assertRestrictBackgroundStatus(int expectedStatus) {
-        final String expected = toString(expectedStatus);
+    private void assertRestrictBackgroundStatus(int expectedApiStatus) throws InterruptedException {
+        // First asserts the API returns the proper value...
+        final String expected = toString(expectedApiStatus);
         Log.d(TAG, getName() + " (expecting " + expected + ")");
-        final int actualStatus = mCM.getRestrictBackgroundStatus();
-        assertEquals("wrong status", expected, toString(actualStatus));
+        final int apiStatus = mCm.getRestrictBackgroundStatus();
+        String actualApiStatus = toString(apiStatus);
+        assertEquals("wrong status", expected, actualApiStatus);
+
+        //...then use a background thread to verify the actual network status.
+        final LinkedBlockingQueue<String> result = new LinkedBlockingQueue<>(1);
+        new Thread(new Runnable() {
+            @Override
+            public void run() {
+              Log.d(TAG, "Running on thread " + Thread.currentThread().getName());
+              final Network network = mCm.getActiveNetwork();
+              final NetworkInfo networkInfo = mCm.getActiveNetworkInfo();
+              Log.d(TAG, "activeNetwork: " + network + " activeNetworkInfo: " + networkInfo);
+              final String prefix = network == null ?
+                      STATUS_NETWORK_UNAVAILABLE_PREFIX : STATUS_NETWORK_AVAILABLE_PREFIX;
+              result.offer(prefix + networkInfo);
+            }
+        }, "CheckNetworkThread").start();
+        final String actualNetworkStatus = result.poll(10, TimeUnit.SECONDS);
+        assertNotNull("timeout waiting for background thread", actualNetworkStatus);
+        final String expectedPrefix = apiStatus == RESTRICT_BACKGROUND_STATUS_ENABLED ?
+                STATUS_NETWORK_UNAVAILABLE_PREFIX : STATUS_NETWORK_AVAILABLE_PREFIX;
+        assertTrue("Wrong network status for API status " + actualApiStatus + ": "
+                + actualNetworkStatus, actualNetworkStatus.startsWith(expectedPrefix));
     }
 
     private String toString(int status) {
diff --git a/hostsidetests/net/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java b/hostsidetests/net/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java
index 9f0bfb8..2b0b1c1 100644
--- a/hostsidetests/net/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java
+++ b/hostsidetests/net/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java
@@ -18,23 +18,29 @@
 
 import com.android.ddmlib.Log;
 import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.WifiHelper;
 
 public class HostsideRestrictBackgroundNetworkTests extends HostsideNetworkTestCase {
     private static final String TEST_APP2_PKG = "com.android.cts.net.hostside.app2";
     private static final String TEST_APP2_APK = "CtsHostsideNetworkTestsApp2.apk";
 
     private int mUid;
+    private WifiHelper mWifiHelper;
 
     @Override
     protected void setUp() throws Exception {
         super.setUp();
 
+        mUid = getUid(TEST_PKG);
+        mWifiHelper = new WifiHelper(getDevice());
+
+        setWifiMeteredStatus(true);
         setRestrictBackground(false);
+
         uninstallPackage(TEST_APP2_PKG, false);
         installPackage(TEST_APP2_APK);
 
         startBroadcastReceiverService();
-        mUid = getUid(TEST_PKG);
     }
 
     @Override
@@ -43,6 +49,7 @@
 
         uninstallPackage(TEST_APP2_PKG, true);
         setRestrictBackground(false);
+        setWifiMeteredStatus(false);
     }
 
     public void testGetRestrictBackgroundStatus_disabled() throws Exception {
@@ -151,6 +158,25 @@
                 + expected + ", got " + actual);
     }
 
+    private void setWifiMeteredStatus(boolean metered) throws DeviceNotAvailableException {
+        mWifiHelper.enableWifi();
+        // TODO: if it's not guaranteed the device has wi-fi, we need to change the tests
+        // to make the actual verification of restrictions optional.
+        final String netId = mWifiHelper.getSSID();
+        assertNotNull("null SSID", netId);
+        assertFalse("empty SSID", netId.trim().isEmpty());
+
+        Log.i(TAG, "Setting wi-fi network " + netId + " metered status to " + metered);
+        final String setCommand = "cmd netpolicy set metered-network " + netId + " "+ metered;
+        final String result = runCommand(setCommand);
+        assertTrue("Command '" + setCommand + "' failed: " + result, result.trim().isEmpty());
+
+        // Sanity check.
+        final String newStatus = runCommand("cmd netpolicy get metered-network " + netId);
+        assertEquals("Metered status of wi-fi network " + netId + " not set properly",
+                newStatus.trim(), Boolean.toString(metered));
+    }
+
     private void setRestrictBackground(boolean enabled) throws DeviceNotAvailableException {
         runCommand("cmd netpolicy set restrict-background " + enabled);
         final String output = runCommand("cmd netpolicy get restrict-background ").trim();
diff --git a/hostsidetests/systemui/Android.mk b/hostsidetests/systemui/Android.mk
new file mode 100644
index 0000000..a8704bf
--- /dev/null
+++ b/hostsidetests/systemui/Android.mk
@@ -0,0 +1,38 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_MODULE := CtsSystemUiHostTestCases
+
+LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed-prebuilt
+
+LOCAL_STATIC_JAVA_LIBRARIES := cts-migration-lib
+
+LOCAL_CTS_TEST_PACKAGE := android.host.systemui
+
+LOCAL_SDK_VERSION := current
+
+# Tag this module as a cts_v2 test artifact
+LOCAL_COMPATIBILITY_SUITE := cts_v2
+
+include $(BUILD_CTS_HOST_JAVA_LIBRARY)
+
+include $(call all-subdir-makefiles)
diff --git a/hostsidetests/systemui/AndroidTest.xml b/hostsidetests/systemui/AndroidTest.xml
new file mode 100644
index 0000000..c8b1883
--- /dev/null
+++ b/hostsidetests/systemui/AndroidTest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for CTS System UI host test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsSystemUiDeviceApp.apk" />
+    </target_preparer>
+    <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
+        <option name="jar" value="CtsSystemUiHostTestCases.jar" />
+    </test>
+</configuration>
diff --git a/hostsidetests/systemui/app/Android.mk b/hostsidetests/systemui/app/Android.mk
new file mode 100644
index 0000000..556756b
--- /dev/null
+++ b/hostsidetests/systemui/app/Android.mk
@@ -0,0 +1,37 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# Don't include this package in any target
+LOCAL_MODULE_TAGS := tests
+# When built, explicitly put it in the data partition.
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_DEX_PREOPT := false
+
+LOCAL_PROGUARD_ENABLED := disabled
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+# tag this module as a cts_v2 test artifact
+LOCAL_COMPATIBILITY_SUITE := cts_v2
+
+LOCAL_PACKAGE_NAME := CtsSystemUiDeviceApp
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/systemui/app/AndroidManifest.xml b/hostsidetests/systemui/app/AndroidManifest.xml
new file mode 100755
index 0000000..5296111
--- /dev/null
+++ b/hostsidetests/systemui/app/AndroidManifest.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.systemui.cts">
+
+    <application>
+        <service android:name=".TestTileService"
+            android:icon="@android:drawable/ic_delete"
+            android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
+            <intent-filter>
+                <action android:name="android.service.quicksettings.action.QS_TILE" />
+            </intent-filter>
+        </service>
+
+        <service android:name=".TestActiveTileService"
+            android:icon="@android:drawable/ic_delete"
+            android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
+            <intent-filter>
+                <action android:name="android.service.quicksettings.action.QS_TILE" />
+            </intent-filter>
+        </service>
+
+        <receiver
+            android:name=".TestActiveTileService$Receiver">
+            <intent-filter>
+                <action android:name="android.sysui.testtile.REQUEST_LISTENING" />
+            </intent-filter>
+        </receiver>
+
+    </application>
+
+</manifest>
+
diff --git a/hostsidetests/systemui/app/src/android/systemui/cts/TestActiveTileService.java b/hostsidetests/systemui/app/src/android/systemui/cts/TestActiveTileService.java
new file mode 100644
index 0000000..013a21b
--- /dev/null
+++ b/hostsidetests/systemui/app/src/android/systemui/cts/TestActiveTileService.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package android.systemui.cts;
+
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+
+public class TestActiveTileService extends TestTileService {
+
+    @Override
+    public int onTileAdded() {
+        Log.i(TAG, TEST_PREFIX + "onTileAdded");
+        return TILE_MODE_ACTIVE;
+    }
+
+    public static class Receiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            Log.i(TestActiveTileService.class.getSimpleName(),
+                    TEST_PREFIX + "requestListeningState");
+            requestListeningState(context, new ComponentName(context, TestActiveTileService.class));
+        }
+    }
+}
diff --git a/hostsidetests/systemui/app/src/android/systemui/cts/TestTileService.java b/hostsidetests/systemui/app/src/android/systemui/cts/TestTileService.java
new file mode 100644
index 0000000..f2b50f7
--- /dev/null
+++ b/hostsidetests/systemui/app/src/android/systemui/cts/TestTileService.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package android.systemui.cts;
+
+import android.app.Dialog;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.graphics.drawable.Icon;
+import android.provider.Settings;
+import android.service.quicksettings.Tile;
+import android.service.quicksettings.TileService;
+import android.util.Log;
+import android.view.View;
+
+/**
+ * A test tile that logs everything that happens to it.
+ * The tests will manipulate the state of the QS tile through ADB and verify
+ * the correct callbacks actually happened.
+ */
+public class TestTileService extends TileService {
+    protected final String TAG = getClass().getSimpleName();
+
+    public static final String SHOW_DIALOG = "android.sysui.testtile.action.SHOW_DIALOG";
+    public static final String START_ACTIVITY = "android.sysui.testtile.action.START_ACTIVITY";
+
+    public static final String TEST_PREFIX = "TileTest_";
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        Log.i(TAG, TEST_PREFIX + "onCreate");
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        Log.i(TAG, TEST_PREFIX + "onDestroy");
+    }
+
+    @Override
+    public int onTileAdded() {
+        Log.i(TAG, TEST_PREFIX + "onTileAdded");
+        return super.onTileAdded();
+    }
+
+    @Override
+    public void onTileRemoved() {
+        Log.i(TAG, TEST_PREFIX + "onTileRemoved");
+        super.onTileRemoved();
+    }
+
+    @Override
+    public void onStartListening() {
+        super.onStartListening();
+        Log.i(TAG, TEST_PREFIX + "onStartListening");
+        IntentFilter filter = new IntentFilter(SHOW_DIALOG);
+        filter.addAction(START_ACTIVITY);
+        registerReceiver(mReceiver, filter);
+
+        // Set up some initial good state.
+        getQsTile().setLabel(TAG);
+        getQsTile().setContentDescription("CTS Test Tile");
+        getQsTile().setIcon(Icon.createWithResource(this, android.R.drawable.ic_secure));
+        getQsTile().setState(Tile.STATE_ACTIVE);
+        getQsTile().updateTile();
+    }
+
+    @Override
+    public void onStopListening() {
+        super.onStopListening();
+        Log.i(TAG, TEST_PREFIX + "onStopListening");
+        unregisterReceiver(mReceiver);
+    }
+
+    @Override
+    public void onClick() {
+        super.onClick();
+        Log.i(TAG, TEST_PREFIX + "onClick");
+        Log.i(TAG, TEST_PREFIX + "is_secure_" + isSecure());
+        Log.i(TAG, TEST_PREFIX + "is_locked_" + isLocked());
+        unlockAndRun(new Runnable() {
+            @Override
+            public void run() {
+                Log.i(TAG, TEST_PREFIX + "unlockAndRunRun");
+            }
+        });
+    }
+
+    private void handleStartActivity() {
+        startActivityAndCollapse(new Intent(Settings.ACTION_SETTINGS)
+                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
+    }
+
+    private void handleShowDialog() {
+        Log.i(TAG, TEST_PREFIX + "handleShowDialog");
+        final Dialog dialog = new Dialog(this);
+        dialog.setContentView(new FocusView(this, dialog));
+        try {
+            showDialog(dialog);
+        } catch (Exception e) {
+            Log.i(TAG, TEST_PREFIX + "onWindowAddFailed", e);
+        }
+    }
+
+    private class FocusView extends View {
+        private final Dialog mDialog;
+
+        public FocusView(Context context, Dialog dialog) {
+            super(context);
+            mDialog = dialog;
+        }
+
+        @Override
+        public void onWindowFocusChanged(boolean hasWindowFocus) {
+            Log.i(TAG, TEST_PREFIX + "onWindowFocusChanged_" + hasWindowFocus);
+            if (hasWindowFocus) {
+                post(new Runnable() {
+                    @Override
+                    public void run() {
+                        mDialog.dismiss();
+                    }
+                });
+            }
+            super.onWindowFocusChanged(hasWindowFocus);
+        }
+    }
+
+    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (intent.getAction().equals(SHOW_DIALOG)) {
+                handleShowDialog();
+            } else {
+                handleStartActivity();
+            }
+        }
+    };
+}
diff --git a/hostsidetests/systemui/src/android/host/systemui/ActiveTileServiceTest.java b/hostsidetests/systemui/src/android/host/systemui/ActiveTileServiceTest.java
new file mode 100644
index 0000000..5325b29
--- /dev/null
+++ b/hostsidetests/systemui/src/android/host/systemui/ActiveTileServiceTest.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package android.host.systemui;
+
+/**
+ * Tests the differences in behavior between tiles in TileService#TILE_MODE_PASSIVE
+ * and TileService#TILE_MODE_ACTIVE.
+ */
+public class ActiveTileServiceTest extends BaseTileServiceTest {
+    // Constants for generating commands below.
+    private static final String SERVICE = "TestActiveTileService";
+
+    private static final String ACTION_REQUEST_LISTENING =
+            "android.sysui.testtile.REQUEST_LISTENING";
+
+    private static final String REQUEST_LISTENING = "am broadcast -a " + ACTION_REQUEST_LISTENING;
+
+    public ActiveTileServiceTest() {
+        super(SERVICE);
+    }
+
+    public void testNotListening() throws Exception {
+        addTile();
+        assertTrue(waitFor("onDestroy"));
+
+        // Open quick settings and verify that this service doesn't get put in
+        // a listening state since its an active tile.
+        openSettings();
+        assertFalse(waitFor("onStartListening"));
+    }
+
+    public void testRequestListening() throws Exception {
+        addTile();
+        assertTrue(waitFor("onDestroy"));
+
+        // Request the listening state and verify that it gets an onStartListening.
+        getDevice().executeShellCommand(REQUEST_LISTENING);
+        assertTrue(waitFor("requestListeningState"));
+        assertTrue(waitFor("onStartListening"));
+    }
+
+    public void testClick() throws Exception {
+        addTile();
+        assertTrue(waitFor("onDestroy"));
+
+        // Open the quick settings.
+        openSettings();
+
+        // Click on the tile and verify it happens.
+        clickTile();
+        assertTrue(waitFor("onStartListening"));
+        assertTrue(waitFor("onClick"));
+    }
+
+}
diff --git a/hostsidetests/systemui/src/android/host/systemui/BaseTileServiceTest.java b/hostsidetests/systemui/src/android/host/systemui/BaseTileServiceTest.java
new file mode 100644
index 0000000..368cff9
--- /dev/null
+++ b/hostsidetests/systemui/src/android/host/systemui/BaseTileServiceTest.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package android.host.systemui;
+
+import com.android.compatibility.common.util.AbiUtils;
+import com.android.cts.migration.MigrationHelper;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.testtype.IAbi;
+import com.android.tradefed.testtype.IAbiReceiver;
+import com.android.tradefed.testtype.IBuildReceiver;
+
+import java.io.File;
+
+public class BaseTileServiceTest extends DeviceTestCase implements IBuildReceiver {
+    // Constants for generating commands below.
+    private static final String PACKAGE = "android.systemui.cts";
+    private static final String ACTION_SHOW_DIALOG = "android.sysui.testtile.action.SHOW_DIALOG";
+
+    private static final String APK_NAME = "CtsSystemUiDeviceApp";
+
+    // Commands used on the device.
+    private static final String ADD_TILE   = "cmd statusbar add-tile ";
+    private static final String REM_TILE   = "cmd statusbar remove-tile ";
+    private static final String CLICK_TILE = "cmd statusbar click-tile ";
+
+    private static final String OPEN_NOTIFICATIONS = "cmd statusbar expand-notifications";
+    private static final String OPEN_SETTINGS      = "cmd statusbar expand-settings";
+    private static final String COLLAPSE           = "cmd statusbar collapse";
+
+    private static final String SHOW_DIALOG = "am broadcast -a " + ACTION_SHOW_DIALOG;
+
+    public static final String TEST_PREFIX = "TileTest_";
+
+    // Time between checks for logs we expect.
+    private static final long CHECK_DELAY = 500;
+    // Number of times to check before failing.
+    private static final long CHECK_RETRIES = 15;
+
+    private final String mService;
+    private final String mComponent;
+
+    /** A reference to the build. */
+    private IBuildInfo mBuildInfo;
+
+    public BaseTileServiceTest(String service) {
+        mService = service;
+        mComponent = PACKAGE + "/." + mService;
+    }
+
+    @Override
+    public void setBuild(IBuildInfo buildInfo) {
+        mBuildInfo = buildInfo;
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        assertNotNull(mBuildInfo);  // ensure build has been set before test is run.
+        // Get the APK from the build.
+        final File app = MigrationHelper.getTestFile(mBuildInfo, String.format("%s.apk", APK_NAME));
+
+        getDevice().installPackage(app, true);
+
+        clearLogcat();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+
+        collapse();
+        remTile();
+        // Try to wait for a onTileRemoved.
+        waitFor("onTileRemoved");
+
+        ITestDevice device = getDevice();
+        device.uninstallPackage(PACKAGE);
+    }
+
+    protected void showDialog() throws Exception {
+        execute(SHOW_DIALOG);
+    }
+
+    protected void addTile() throws Exception {
+        execute(ADD_TILE + mComponent);
+    }
+
+    protected void remTile() throws Exception {
+        execute(REM_TILE + mComponent);
+    }
+
+    protected void clickTile() throws Exception {
+        execute(CLICK_TILE + mComponent);
+    }
+
+    protected void openNotifications() throws Exception {
+        execute(OPEN_NOTIFICATIONS);
+    }
+
+    protected void openSettings() throws Exception {
+        execute(OPEN_SETTINGS);
+    }
+
+    protected void collapse() throws Exception {
+        execute(COLLAPSE);
+    }
+
+    private void execute(String cmd) throws Exception {
+        getDevice().executeShellCommand(cmd);
+        // All of the status bar commands tend to have animations associated
+        // everything seems to be happier if you give them time to finish.
+        Thread.sleep(100);
+    }
+
+    protected boolean waitFor(String str) throws DeviceNotAvailableException, InterruptedException {
+        final String searchStr = TEST_PREFIX + str;
+        int ct = 0;
+        while (!hasLog(searchStr) && (ct++ < CHECK_RETRIES)) {
+            Thread.sleep(CHECK_DELAY);
+        }
+        return hasLog(searchStr);
+    }
+
+    protected boolean hasLog(String str) throws DeviceNotAvailableException {
+        String logs = getDevice().executeAdbCommand("logcat", "-v", "brief", "-d", mService + ":I",
+                "*:S");
+        return logs.contains(str);
+    }
+
+    private void clearLogcat() throws DeviceNotAvailableException {
+        getDevice().executeAdbCommand("logcat", "-c");
+    }
+}
diff --git a/hostsidetests/systemui/src/android/host/systemui/TileServiceTest.java b/hostsidetests/systemui/src/android/host/systemui/TileServiceTest.java
new file mode 100644
index 0000000..3c92918
--- /dev/null
+++ b/hostsidetests/systemui/src/android/host/systemui/TileServiceTest.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package android.host.systemui;
+
+/**
+ * Tests the lifecycle of a TileService by adding/removing it and opening/closing
+ * the notification/settings shade through adb commands.
+ */
+public class TileServiceTest extends BaseTileServiceTest {
+
+    private static final String SERVICE = "TestTileService";
+
+    public static final String ACTION_START_ACTIVITY =
+            "android.sysui.testtile.action.START_ACTIVITY";
+
+    public static final String START_ACTIVITY_AND_COLLAPSE =
+            "am broadcast -a " + ACTION_START_ACTIVITY;
+
+    public TileServiceTest() {
+        super(SERVICE);
+    }
+
+    public void testAddTile() throws Exception {
+        addTile();
+        // Verify that the service starts up and gets a onTileAdded callback.
+        assertTrue(waitFor("onCreate"));
+        assertTrue(waitFor("onTileAdded"));
+        assertTrue(waitFor("onDestroy"));
+    }
+
+    public void testRemoveTile() throws Exception {
+        addTile();
+        // Verify that the service starts up and gets a onTileAdded callback.
+        assertTrue(waitFor("onCreate"));
+        assertTrue(waitFor("onTileAdded"));
+        assertTrue(waitFor("onDestroy"));
+
+        remTile();
+        assertTrue(waitFor("onTileRemoved"));
+    }
+
+    public void testListeningNotifications() throws Exception {
+        addTile();
+        assertTrue(waitFor("onDestroy"));
+
+        // Open the notification shade and make sure the tile gets a chance to listen.
+        openNotifications();
+        assertTrue(waitFor("onStartListening"));
+        // Collapse the shade and make sure the listening ends.
+        collapse();
+        assertTrue(waitFor("onStopListening"));
+    }
+
+    public void testListeningSettings() throws Exception {
+        addTile();
+        assertTrue(waitFor("onDestroy"));
+
+        // Open the quick settings and make sure the tile gets a chance to listen.
+        openSettings();
+        assertTrue(waitFor("onStartListening"));
+        // Collapse the shade and make sure the listening ends.
+        collapse();
+        assertTrue(waitFor("onStopListening"));
+    }
+
+    public void testCantAddDialog() throws Exception {
+        addTile();
+        assertTrue(waitFor("onDestroy"));
+
+        // Wait for the tile to be added.
+        assertTrue(waitFor("onTileAdded"));
+
+        // Open the quick settings and make sure the tile gets a chance to listen.
+        openSettings();
+        assertTrue(waitFor("onStartListening"));
+
+        // Try to open a dialog, verify it doesn't happen.
+        showDialog();
+        assertTrue(waitFor("handleShowDialog"));
+        assertTrue(waitFor("onWindowAddFailed"));
+    }
+
+    public void testClick() throws Exception {
+        addTile();
+        // Wait for the tile to be added.
+        assertTrue(waitFor("onTileAdded"));
+
+        // Open the quick settings and make sure the tile gets a chance to listen.
+        openSettings();
+        assertTrue(waitFor("onStartListening"));
+
+        // Click on the tile and verify it happens.
+        clickTile();
+        assertTrue(waitFor("onClick"));
+
+        // Verify the state that gets dumped during a click.
+        // Device is expected to be unlocked and unsecure during CTS.
+        // The unlock callback should be triggered immediately.
+        assertTrue(waitFor("is_secure_false"));
+        assertTrue(waitFor("is_locked_false"));
+        assertTrue(waitFor("unlockAndRunRun"));
+    }
+
+    public void testClickAndShowDialog() throws Exception {
+        addTile();
+        assertTrue(waitFor("onDestroy"));
+
+        // Open the quick settings and make sure the tile gets a chance to listen.
+        openSettings();
+        assertTrue(waitFor("onStartListening"));
+
+        // Click on the tile and verify it happens.
+        clickTile();
+        assertTrue(waitFor("onClick"));
+
+        // Try to open a dialog, verify it doesn't happen.
+        showDialog();
+        assertTrue(waitFor("handleShowDialog"));
+        assertTrue(waitFor("onWindowFocusChanged_true"));
+    }
+
+    public void testStartActivity() throws Exception {
+        addTile();
+        // Wait for the tile to be added.
+        assertTrue(waitFor("onTileAdded"));
+
+        // Open the quick settings and make sure the tile gets a chance to listen.
+        openSettings();
+        assertTrue(waitFor("onStartListening"));
+
+        // Trigger the startActivityAndCollapse call and verify we get taken out of listening
+        // because the shade gets collapsed.
+        getDevice().executeShellCommand(START_ACTIVITY_AND_COLLAPSE);
+        assertTrue(waitFor("onStopListening"));
+    }
+
+}
diff --git a/tests/tests/media/src/android/media/cts/LoudnessEnhancerTest.java b/tests/tests/media/src/android/media/cts/LoudnessEnhancerTest.java
index 7c36588..8923445 100644
--- a/tests/tests/media/src/android/media/cts/LoudnessEnhancerTest.java
+++ b/tests/tests/media/src/android/media/cts/LoudnessEnhancerTest.java
@@ -91,7 +91,7 @@
         try {
             // this test will play a 1kHz sine wave with peaks at -40dB, and apply 6 db gain
             // using loudness enhancement
-            mp = MediaPlayer.create(getContext(), R.raw.sine1khzm40db);
+            mp = MediaPlayer.create(getContext(), R.raw.sine1khzs40dblong);
             final int LOUDNESS_GAIN = 600;
             final int MAX_MEASUREMENT_ERROR_MB = 200;
             assertNotNull("null MediaPlayer", mp);
@@ -122,6 +122,7 @@
             assertTrue("visualizer not enabled", visualizer.getEnabled());
             Thread.sleep(100);
             int status = visualizer.setMeasurementMode(Visualizer.MEASUREMENT_MODE_PEAK_RMS);
+            Thread.sleep(500);
             assertEquals("setMeasurementMode() for PEAK_RMS doesn't report success",
                     Visualizer.SUCCESS, status);
             // make sure we're playing long enough so the measurement is valid
@@ -147,7 +148,7 @@
 
             visualizer.setMeasurementMode(Visualizer.MEASUREMENT_MODE_PEAK_RMS);
             currentPosition = mp.getCurrentPosition();
-            maxTry = 5;
+            maxTry = 10;
             tryCount = 0;
             while (tryCount < maxTry) {
                 Thread.sleep(50);
diff --git a/tests/tests/provider/src/android/provider/cts/BlockedNumberContractTest.java b/tests/tests/provider/src/android/provider/cts/BlockedNumberContractTest.java
new file mode 100644
index 0000000..d4f81b5
--- /dev/null
+++ b/tests/tests/provider/src/android/provider/cts/BlockedNumberContractTest.java
@@ -0,0 +1,345 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.provider.cts;
+
+import android.annotation.Nullable;
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteConstraintException;
+import android.net.Uri;
+import android.os.ParcelFileDescriptor;
+import android.provider.BlockedNumberContract;
+import android.provider.BlockedNumberContract.BlockedNumbers;
+
+import junit.framework.Assert;
+
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * CTS tests for blockednumber provider accessed through {@link BlockedNumberContract}.
+ */
+// To run the tests in this file w/o running all the cts tests:
+// make cts
+// cts-tradefed
+// run cts -c android.provider.cts.BlockedNumberContractTest
+public class BlockedNumberContractTest extends TestCaseThatRunsIfTelephonyIsEnabled {
+    private ContentResolver mContentResolver;
+    private Context mContext;
+    private ArrayList<Uri> mAddedUris;
+
+    private static final String[] BLOCKED_NUMBERS_PROJECTION = new String[]{
+            BlockedNumbers.COLUMN_ORIGINAL_NUMBER,
+            BlockedNumbers.COLUMN_E164_NUMBER};
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mContext = getInstrumentation().getContext();
+        mContentResolver = mContext.getContentResolver();
+        mAddedUris = new ArrayList<>();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        for (Uri row : mAddedUris) {
+            mContentResolver.delete(row, null, null);
+        }
+        mAddedUris.clear();
+        setDefaultSmsApp(false);
+
+        super.tearDown();
+    }
+
+    public void testProviderInteractionsAsRegularApp_fails() {
+        try {
+            mAddedUris.add(mContentResolver.insert(
+                    BlockedNumbers.CONTENT_URI, getContentValues("1234567890")));
+            fail("Should throw SecurityException");
+        } catch (SecurityException expected) {
+        }
+
+        try {
+            mContentResolver.query(BlockedNumbers.CONTENT_URI, null, null, null, null);
+            fail("Should throw SecurityException");
+        } catch (SecurityException expected) {
+        }
+
+        try {
+            BlockedNumberContract.isBlocked(mContext, "1234567890");
+            fail("Should throw SecurityException");
+        } catch (SecurityException expected) {
+        }
+
+        try {
+            mContentResolver.update(
+                    BlockedNumbers.CONTENT_URI, getContentValues("123"), null, null);
+            fail("Should throw UnsupportedOperationException");
+        } catch (UnsupportedOperationException expected) {
+        }
+    }
+
+    public void testGetType() throws Exception {
+        assertEquals(BlockedNumbers.CONTENT_TYPE,
+                mContentResolver.getType(BlockedNumbers.CONTENT_URI));
+        assertEquals(BlockedNumbers.CONTENT_ITEM_TYPE,
+                mContentResolver.getType(
+                        ContentUris.withAppendedId(BlockedNumbers.CONTENT_URI, 0)));
+
+        assertNull(mContentResolver.getType(BlockedNumberContract.AUTHORITY_URI));
+    }
+
+    public void testInsertAndBlockCheck_succeeds() throws Exception {
+        setDefaultSmsApp(true);
+        assertInsertBlockedNumberSucceeds("1234567890", null);
+        assertTrue(BlockedNumberContract.isBlocked(mContext, "1234567890"));
+        assertFalse(BlockedNumberContract.isBlocked(mContext, "2234567890"));
+
+        assertInsertBlockedNumberSucceeds("2345678901", "+12345678901");
+        assertTrue(BlockedNumberContract.isBlocked(mContext, "2345678901"));
+        assertTrue(BlockedNumberContract.isBlocked(mContext, "+12345678901"));
+
+        assertInsertBlockedNumberSucceeds("1234@abcd.com", null);
+        assertTrue(BlockedNumberContract.isBlocked(mContext, "1234@abcd.com"));
+
+        assertInsertBlockedNumberSucceeds("2345@abcd.com", null);
+        assertTrue(BlockedNumberContract.isBlocked(mContext, "2345@abcd.com"));
+
+        assertFalse(BlockedNumberContract.isBlocked(mContext, "9999@abcd.com"));
+        assertFalse(BlockedNumberContract.isBlocked(mContext, "random string"));
+    }
+
+    public void testInsert_failsWithInvalidInputs() throws Exception {
+        setDefaultSmsApp(true);
+
+        try {
+            ContentValues cv = new ContentValues();
+            cv.put(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, "1234");
+            mAddedUris.add(mContentResolver.insert(
+                    ContentUris.withAppendedId(BlockedNumbers.CONTENT_URI, 1),
+                    new ContentValues()));
+            fail("Should throw IllegalArgumentException.");
+        } catch (IllegalArgumentException expected) {
+            assertTrue(expected.getMessage().contains("Unsupported URI"));
+        }
+
+        try {
+            mAddedUris.add(
+                    mContentResolver.insert(BlockedNumbers.CONTENT_URI, new ContentValues()));
+            fail("Should throw IllegalArgumentException.");
+        } catch (IllegalArgumentException expected) {
+            assertTrue(expected.getMessage().contains("Missing a required column"));
+        }
+
+        try {
+            ContentValues cv = new ContentValues();
+            cv.put(BlockedNumbers.COLUMN_E164_NUMBER, "+1234");
+            mAddedUris.add(mContentResolver.insert(BlockedNumbers.CONTENT_URI, cv));
+            fail("Should throw IllegalArgumentException.");
+        } catch (IllegalArgumentException expected) {
+            assertTrue(expected.getMessage().contains("Missing a required column"));
+        }
+
+        try {
+            ContentValues cv = new ContentValues();
+            cv.put(BlockedNumbers.COLUMN_ID, "1");
+            mAddedUris.add(mContentResolver.insert(BlockedNumbers.CONTENT_URI, cv));
+            fail("Should throw IllegalArgumentException.");
+        } catch (IllegalArgumentException expected) {
+            assertTrue(expected.getMessage().contains("must not be specified"));
+        }
+
+        assertInsertBlockedNumberSucceeds("12345", null);
+        // Attempting to insert a duplicate fails.
+        ContentValues cv = new ContentValues();
+        cv.put(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, "12345");
+        cv.put(BlockedNumbers.COLUMN_E164_NUMBER, "+112345");
+        try {
+            mAddedUris.add(mContentResolver.insert(BlockedNumbers.CONTENT_URI, cv));
+        } catch (SQLiteConstraintException expected) {
+        }
+    }
+
+    public void testUpdate_isUnsupported() throws  Exception {
+        setDefaultSmsApp(true);
+        try {
+            mContentResolver.update(
+                    BlockedNumbers.CONTENT_URI, getContentValues("123"), null, null);
+            fail("Should throw UnsupportedOperationException");
+        } catch (UnsupportedOperationException expected) {
+        }
+    }
+
+    public void testIsBlocked_returnsFalseForNullAndEmpty() throws Exception {
+        setDefaultSmsApp(true);
+        assertFalse(BlockedNumberContract.isBlocked(mContext, null));
+        assertFalse(BlockedNumberContract.isBlocked(mContext, ""));
+    }
+
+    public void testDelete() throws Exception {
+        setDefaultSmsApp(true);
+
+        assertInsertBlockedNumberSucceeds("12345", "+112345");
+        assertInsertBlockedNumberSucceeds("012345", "+112345");
+        assertEquals(2,
+                mContentResolver.delete(
+                        BlockedNumbers.CONTENT_URI,
+                        BlockedNumbers.COLUMN_E164_NUMBER + "= ?",
+                        new String[] {"+112345"}));
+
+        assertInsertBlockedNumberSucceeds("12345", "");
+        assertEquals(1,
+                mContentResolver.delete(
+                        BlockedNumbers.CONTENT_URI,
+                        BlockedNumbers.COLUMN_ORIGINAL_NUMBER + "= ?",
+                        new String[] {"12345"}));
+
+        Uri insertedUri = assertInsertBlockedNumberSucceeds("12345", "");
+        assertEquals(1,
+                mContentResolver.delete(
+                        BlockedNumbers.CONTENT_URI,
+                        BlockedNumbers.COLUMN_ID + "= ?",
+                        new String[] {Long.toString(ContentUris.parseId(insertedUri))}));
+
+        insertedUri = assertInsertBlockedNumberSucceeds("12345", "");
+        assertEquals(1,
+                mContentResolver.delete(
+                        ContentUris.withAppendedId(
+                                BlockedNumbers.CONTENT_URI, ContentUris.parseId(insertedUri)),
+                        null, null));
+
+        insertedUri = assertInsertBlockedNumberSucceeds("12345", "");
+        assertEquals(1, mContentResolver.delete(insertedUri, null, null));
+
+        assertEquals(0,
+                mContentResolver.delete(
+                        BlockedNumbers.CONTENT_URI,
+                        BlockedNumbers.COLUMN_ORIGINAL_NUMBER + "= ?",
+                        new String[] {"12345"}));
+    }
+
+    public void testDelete_failsOnInvalidInputs() throws Exception {
+        setDefaultSmsApp(true);
+
+        try {
+            mContentResolver.delete(Uri.parse("foobar"), null, null);
+        } catch (IllegalArgumentException expected) {
+        }
+
+        Uri insertedUri = assertInsertBlockedNumberSucceeds("12345", "");
+        try {
+            mContentResolver.delete(
+                    insertedUri,
+                    BlockedNumbers.COLUMN_E164_NUMBER + "= ?",
+                    new String[] {"+112345"});
+            fail("Should throw IllegalArgumentException");
+        } catch (IllegalArgumentException expected) {
+            assertTrue(expected.getMessage().contains("selection must be null"));
+        }
+    }
+
+    public void testProviderNotifiesChangesUsingContentObserver() throws Exception {
+        setDefaultSmsApp(true);
+
+        Cursor cursor = mContentResolver.query(BlockedNumbers.CONTENT_URI, null, null, null, null);
+
+        final CountDownLatch latch = new CountDownLatch(2);
+        ContentObserver contentObserver = new ContentObserver(null) {
+            @Override
+            public void onChange(boolean selfChange) {
+                Assert.assertFalse(selfChange);
+                latch.notify();
+            }
+        };
+        cursor.registerContentObserver(contentObserver);
+
+        try {
+            Uri uri = assertInsertBlockedNumberSucceeds("12345", "");
+            mContentResolver.delete(uri, null, null);
+            latch.await(10, TimeUnit.SECONDS);
+        } catch (Exception e) {
+            fail(e.toString());
+        } finally {
+            cursor.unregisterContentObserver(contentObserver);
+        }
+    }
+
+    public void testAccessingNonExistentMethod_fails() throws Exception {
+        setDefaultSmsApp(true);
+
+        try {
+            mContext.getContentResolver()
+                    .call(BlockedNumberContract.AUTHORITY_URI, "nonExistentMethod", "1234", null);
+        } catch (IllegalArgumentException expected) {
+            assertTrue(expected.getMessage().contains("Unsupported method"));
+        }
+    }
+
+    private Uri assertInsertBlockedNumberSucceeds(
+            String originalNumber, @Nullable String e164Number) {
+        ContentValues cv = new ContentValues();
+        cv.put(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, originalNumber);
+        if (e164Number != null) {
+            cv.put(BlockedNumbers.COLUMN_E164_NUMBER, e164Number);
+        }
+        Uri insertedUri = mContentResolver.insert(BlockedNumbers.CONTENT_URI, cv);
+        mAddedUris.add(insertedUri);
+
+        Cursor cursor = mContentResolver.query(
+                BlockedNumbers.CONTENT_URI,
+                BLOCKED_NUMBERS_PROJECTION,
+                BlockedNumbers.COLUMN_ORIGINAL_NUMBER + "= ?",
+                new String[]{originalNumber},
+                null);
+        assertTrue(cursor.moveToFirst());
+
+        assertEquals(originalNumber, cursor.getString(0));
+        if (e164Number != null) {
+            assertEquals(e164Number, cursor.getString(1));
+        }
+        cursor.close();
+        return insertedUri;
+    }
+
+    private ContentValues getContentValues(String originalNumber) {
+        ContentValues cv = new ContentValues();
+        cv.put(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, originalNumber);
+        return cv;
+    }
+
+    private void setDefaultSmsApp(boolean setToSmsApp) throws Exception {
+        StringBuilder command = new StringBuilder();
+        command.append("appops set ");
+        command.append(mContext.getPackageName());
+        command.append(" WRITE_SMS ");
+        command.append(setToSmsApp ? "allow" : "default");
+
+        ParcelFileDescriptor pfd = getInstrumentation().getUiAutomation()
+                .executeShellCommand(command.toString());
+
+        InputStream is = new FileInputStream(pfd.getFileDescriptor());
+        final byte[] buffer = new byte[8192];
+        while ((is.read(buffer)) != -1);
+    }
+}
diff --git a/tests/tests/provider/src/android/provider/cts/TestCaseThatRunsIfTelephonyIsEnabled.java b/tests/tests/provider/src/android/provider/cts/TestCaseThatRunsIfTelephonyIsEnabled.java
new file mode 100644
index 0000000..9d2b093
--- /dev/null
+++ b/tests/tests/provider/src/android/provider/cts/TestCaseThatRunsIfTelephonyIsEnabled.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.provider.cts;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.test.InstrumentationTestCase;
+
+/**
+ * An {@link InstrumentationTestCase} that runs tests only if
+ * {@link android.content.pm.PackageManager#FEATURE_TELEPHONY} is enabled.
+ */
+public class TestCaseThatRunsIfTelephonyIsEnabled extends InstrumentationTestCase {
+    @Override
+    protected void runTest() throws Throwable {
+        if (isTelephonySupported(getInstrumentation().getContext())) {
+            super.runTest();
+        }
+    }
+
+    private static boolean isTelephonySupported(Context context) {
+        return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
+    }
+}
diff --git a/tests/tests/telecom/src/android/telecom/cts/ConnectionServiceTest.java b/tests/tests/telecom/src/android/telecom/cts/ConnectionServiceTest.java
index 836ca48..21b00a0 100644
--- a/tests/tests/telecom/src/android/telecom/cts/ConnectionServiceTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/ConnectionServiceTest.java
@@ -77,6 +77,7 @@
 
         // Add second connection (add existing connection)
         final Connection connection2 = new MockConnection();
+        connection2.setActive();
         CtsConnectionService.addExistingConnectionToTelecom(TEST_PHONE_ACCOUNT_HANDLE, connection2);
         assertNumCalls(mInCallCallbacks.getService(), 2);
         mInCallCallbacks.lock.drainPermits();
diff --git a/tests/tests/tv/src/android/media/tv/cts/TvInputServiceTest.java b/tests/tests/tv/src/android/media/tv/cts/TvInputServiceTest.java
index aacb9e8..c18a1cd 100644
--- a/tests/tests/tv/src/android/media/tv/cts/TvInputServiceTest.java
+++ b/tests/tests/tv/src/android/media/tv/cts/TvInputServiceTest.java
@@ -266,7 +266,7 @@
 
     public void verifyCommandStartRecording() {
         resetCounts();
-        mTvRecordingClient.startRecording();
+        mTvRecordingClient.startRecording(null);
         new PollingCheck(TIME_OUT) {
             @Override
             protected boolean check() {
@@ -956,7 +956,7 @@
             }
 
             @Override
-            public void onStartRecording() {
+            public void onStartRecording(Uri programHint) {
                 mStartRecordingCount++;
             }
 
diff --git a/tests/tests/widget/src/android/widget/cts/EditTextTest.java b/tests/tests/widget/src/android/widget/cts/EditTextTest.java
index 88fa2e0..acf5f38 100644
--- a/tests/tests/widget/src/android/widget/cts/EditTextTest.java
+++ b/tests/tests/widget/src/android/widget/cts/EditTextTest.java
@@ -20,6 +20,7 @@
 
 import android.content.Context;
 import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
 import android.text.TextUtils;
 import android.text.method.ArrowKeyMovementMethod;
 import android.text.method.MovementMethod;
@@ -238,6 +239,78 @@
         }
     }
 
+    @SmallTest
+    public void testOnSaveInstanceState_savesTextStateWhenFreezesTextIsTrue() {
+        // prepare TextView for before saveInstanceState
+        final String testStr = "This is a test str";
+        EditText editText1 = new EditText(mContext);
+        editText1.setFreezesText(true);
+        editText1.setText(testStr);
+
+        // prepare TextView for after saveInstanceState
+        EditText editText2 = new EditText(mContext);
+        editText2.setFreezesText(true);
+
+        editText2.onRestoreInstanceState(editText1.onSaveInstanceState());
+
+        assertEquals(editText1.getText().toString(), editText2.getText().toString());
+    }
+
+    @SmallTest
+    public void testOnSaveInstanceState_savesTextStateWhenFreezesTextIfFalse() {
+        // prepare TextView for before saveInstanceState
+        final String testStr = "This is a test str";
+        EditText editText1 = new EditText(mContext);
+        editText1.setFreezesText(false);
+        editText1.setText(testStr);
+
+        // prepare TextView for after saveInstanceState
+        EditText editText2 = new EditText(mContext);
+        editText2.setFreezesText(false);
+
+        editText2.onRestoreInstanceState(editText1.onSaveInstanceState());
+
+        assertEquals(editText1.getText().toString(), editText2.getText().toString());
+    }
+
+    @SmallTest
+    public void testOnSaveInstanceState_savesSelectionStateWhenFreezesTextIsFalse() {
+        // prepare TextView for before saveInstanceState
+        final String testStr = "This is a test str";
+        EditText editText1 = new EditText(mContext);
+        editText1.setFreezesText(false);
+        editText1.setText(testStr);
+        editText1.setSelection(2, testStr.length() - 2);
+
+        // prepare TextView for after saveInstanceState
+        EditText editText2 = new EditText(mContext);
+        editText2.setFreezesText(false);
+
+        editText2.onRestoreInstanceState(editText1.onSaveInstanceState());
+
+        assertEquals(editText1.getSelectionStart(), editText2.getSelectionStart());
+        assertEquals(editText1.getSelectionEnd(), editText2.getSelectionEnd());
+    }
+
+    @SmallTest
+    public void testOnSaveInstanceState_savesSelectionStateWhenFreezesTextIsTrue() {
+        // prepare TextView for before saveInstanceState
+        final String testStr = "This is a test str";
+        EditText editText1 = new EditText(mContext);
+        editText1.setFreezesText(true);
+        editText1.setText(testStr);
+        editText1.setSelection(2, testStr.length() - 2);
+
+        // prepare TextView for after saveInstanceState
+        EditText editText2 = new EditText(mContext);
+        editText2.setFreezesText(true);
+
+        editText2.onRestoreInstanceState(editText1.onSaveInstanceState());
+
+        assertEquals(editText1.getSelectionStart(), editText2.getSelectionStart());
+        assertEquals(editText1.getSelectionEnd(), editText2.getSelectionEnd());
+    }
+
     private class MockEditText extends EditText {
         public MockEditText(Context context) {
             super(context);
diff --git a/tests/tests/widget/src/android/widget/cts/TextViewTest.java b/tests/tests/widget/src/android/widget/cts/TextViewTest.java
index 8d67d06..d0b4503 100644
--- a/tests/tests/widget/src/android/widget/cts/TextViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TextViewTest.java
@@ -17,6 +17,7 @@
 package android.widget.cts;
 
 import android.graphics.drawable.ColorDrawable;
+import android.test.suitebuilder.annotation.SmallTest;
 import android.text.Html;
 import android.text.Spanned;
 import android.widget.cts.R;
@@ -46,7 +47,6 @@
 import android.os.Bundle;
 import android.os.Parcelable;
 import android.test.ActivityInstrumentationTestCase2;
-import android.test.MoreAsserts;
 import android.test.TouchUtils;
 import android.test.UiThreadTest;
 import android.text.Editable;
@@ -1923,6 +1923,7 @@
 
     @UiThreadTest
     public void testSaveInstanceState() {
+        // should save text when freezesText=true
         TextView originalTextView = new TextView(mActivity);
         final String text = "This is a string";
         originalTextView.setText(text);
@@ -1935,23 +1936,104 @@
     }
 
     @UiThreadTest
-    public void testSaveInstanceStateSelection() {
-        TextView originalTextView = new TextView(mActivity);
+    public void testOnSaveInstanceState_whenFreezesTextIsFalse() {
         final String text = "This is a string";
-        final Spannable spannable = new SpannableString(text);
-        originalTextView.setText(spannable);
-        originalTextView.setTextIsSelectable(true);
-        Selection.setSelection((Spannable) originalTextView.getText(), 5, 7);
-        originalTextView.setFreezesText(true);  // needed to actually save state
-        Parcelable state = originalTextView.onSaveInstanceState();
+        { // should not save text when freezesText=false
+            // prepare TextView for before saveInstanceState
+            TextView textView1 = new TextView(mActivity);
+            textView1.setFreezesText(false);
+            textView1.setText(text);
 
-        TextView restoredTextView = new TextView(mActivity);
-        // Setting a selection only has an effect on a TextView when it is selectable.
-        restoredTextView.setTextIsSelectable(true);
-        restoredTextView.onRestoreInstanceState(state);
-        assertEquals(text, restoredTextView.getText().toString());
-        assertEquals(5, restoredTextView.getSelectionStart());
-        assertEquals(7, restoredTextView.getSelectionEnd());
+            // prepare TextView for after saveInstanceState
+            TextView textView2 = new TextView(mActivity);
+            textView2.setFreezesText(false);
+
+            textView2.onRestoreInstanceState(textView1.onSaveInstanceState());
+
+            assertEquals("", textView2.getText().toString());
+        }
+
+        { // should not save text even when textIsSelectable=true
+            // prepare TextView for before saveInstanceState
+            TextView textView1 = new TextView(mActivity);
+            textView1.setFreezesText(false);
+            textView1.setTextIsSelectable(true);
+            textView1.setText(text);
+
+            // prepare TextView for after saveInstanceState
+            TextView textView2 = new TextView(mActivity);
+            textView2.setFreezesText(false);
+            textView2.setTextIsSelectable(true);
+
+            textView2.onRestoreInstanceState(textView1.onSaveInstanceState());
+
+            assertEquals("", textView2.getText().toString());
+        }
+    }
+
+    @UiThreadTest
+    @SmallTest
+    public void testOnSaveInstanceState_doesNotSaveSelectionWhenDoesNotExist() {
+        // prepare TextView for before saveInstanceState
+        final String text = "This is a string";
+        TextView textView1 = new TextView(mActivity);
+        textView1.setFreezesText(true);
+        textView1.setText(text);
+
+        // prepare TextView for after saveInstanceState
+        TextView textView2 = new TextView(mActivity);
+        textView2.setFreezesText(true);
+
+        textView2.onRestoreInstanceState(textView1.onSaveInstanceState());
+
+        assertEquals(-1, textView2.getSelectionStart());
+        assertEquals(-1, textView2.getSelectionEnd());
+    }
+
+    @UiThreadTest
+    @SmallTest
+    public void testOnSaveInstanceState_doesNotRestoreSelectionWhenTextIsAbsent() {
+        // prepare TextView for before saveInstanceState
+        final String text = "This is a string";
+        TextView textView1 = new TextView(mActivity);
+        textView1.setFreezesText(false);
+        textView1.setTextIsSelectable(true);
+        textView1.setText(text);
+        Selection.setSelection((Spannable) textView1.getText(), 2, text.length() - 2);
+
+        // prepare TextView for after saveInstanceState
+        TextView textView2 = new TextView(mActivity);
+        textView2.setFreezesText(false);
+        textView2.setTextIsSelectable(true);
+
+        textView2.onRestoreInstanceState(textView1.onSaveInstanceState());
+
+        assertEquals("", textView2.getText().toString());
+        //when textIsSelectable, selection start and end are initialized to 0
+        assertEquals(0, textView2.getSelectionStart());
+        assertEquals(0, textView2.getSelectionEnd());
+    }
+
+    @UiThreadTest
+    @SmallTest
+    public void testOnSaveInstanceState_savesSelectionWhenExists() {
+        final String text = "This is a string";
+        // prepare TextView for before saveInstanceState
+        TextView textView1 = new TextView(mActivity);
+        textView1.setFreezesText(true);
+        textView1.setTextIsSelectable(true);
+        textView1.setText(text);
+        Selection.setSelection((Spannable) textView1.getText(), 2, text.length() - 2);
+
+        // prepare TextView for after saveInstanceState
+        TextView textView2 = new TextView(mActivity);
+        textView2.setFreezesText(true);
+        textView2.setTextIsSelectable(true);
+
+        textView2.onRestoreInstanceState(textView1.onSaveInstanceState());
+
+        assertEquals(textView1.getSelectionStart(), textView2.getSelectionStart());
+        assertEquals(textView1.getSelectionEnd(), textView2.getSelectionEnd());
     }
 
     @UiThreadTest