Merge "Added ABI XML tag for CtsContactsProviderWipe."
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index 47f12b8..9042e16 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -13,6 +13,7 @@
                       tests/autofillservice/
                       tests/contentcaptureservice/
                       tests/tests/animation/
+                      tests/tests/content/
                       tests/tests/graphics/
                       tests/tests/hardware/
                       tests/tests/print/
diff --git a/apps/CameraITS/CameraITS.pdf b/apps/CameraITS/CameraITS.pdf
index 5eb3af3..5f1e481 100644
--- a/apps/CameraITS/CameraITS.pdf
+++ b/apps/CameraITS/CameraITS.pdf
Binary files differ
diff --git a/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py b/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py
index 779361c..658dfa0 100644
--- a/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py
+++ b/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py
@@ -260,7 +260,7 @@
                 sensor_w = props["android.sensor.info.physicalSize"]["width"]
                 pixel_h = props["android.sensor.info.pixelArraySize"]["height"]
                 pixel_w = props["android.sensor.info.pixelArraySize"]["width"]
-                fd = float(props["android.lens.info.availableFocalLengths"][0])
+                fd = float(cap_raw["metadata"]["android.lens.focalLength"])
                 fd_w_pix = pixel_w * fd / sensor_w
                 fd_h_pix = pixel_h * fd / sensor_h
                 # transformation matrix
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index 3f759ec..9d24229 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -2326,6 +2326,18 @@
                   android:label="@string/wifi_test_network_request_unavailable"
                   android:configChanges="keyboardHidden|orientation|screenSize" />
 
+        <activity android:name=".wifi.NetworkSuggestionSsidTestActivity"
+                  android:label="@string/wifi_test_network_suggestion_ssid"
+                  android:configChanges="keyboardHidden|orientation|screenSize" />
+
+        <activity android:name=".wifi.NetworkSuggestionSsidBssidTestActivity"
+                  android:label="@string/wifi_test_network_suggestion_ssid_bssid"
+                  android:configChanges="keyboardHidden|orientation|screenSize" />
+
+        <activity android:name=".wifi.NetworkSuggestionSsidPostConnectTestActivity"
+                  android:label="@string/wifi_test_network_suggestion_ssid_post_connect"
+                  android:configChanges="keyboardHidden|orientation|screenSize" />
+
         <activity android:name=".p2p.GoNegRequesterTestListActivity"
                 android:label="@string/p2p_go_neg_requester"
                 android:configChanges="keyboardHidden|orientation|screenSize" />
@@ -2714,6 +2726,10 @@
             <meta-data android:name="test_required_features" android:value="android.software.device_admin" />
         </activity>
 
+        <activity android:name=".managedprovisioning.NonMarketAppsActivity"
+                  android:label="@string/provisioning_byod_non_market_apps">
+        </activity>
+
         <activity android:name=".managedprovisioning.KeyguardDisabledFeaturesActivity"
                 android:label="@string/provisioning_byod_keyguard_disabled_features">
         </activity>
diff --git a/apps/CtsVerifier/res/layout-small-dpad/widget_layout.xml b/apps/CtsVerifier/res/layout-small-dpad/widget_layout.xml
new file mode 100644
index 0000000..518be88
--- /dev/null
+++ b/apps/CtsVerifier/res/layout-small-dpad/widget_layout.xml
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 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.
+-->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:layout_marginTop="@dimen/widget_margin_top"
+    android:layout_marginBottom="@dimen/widget_margin_bottom"
+    android:layout_marginLeft="@dimen/widget_margin_left"
+    android:layout_marginRight="@dimen/widget_margin_right"
+    android:padding="1dp"
+    android:background="#fff">
+
+    <LinearLayout
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:paddingLeft="4dp"
+        android:paddingTop="4dp"
+        android:paddingBottom="4dp"
+        android:paddingRight="4dp"
+        android:layout_gravity="center"
+        android:background="#fff">
+
+        <TextView
+            android:id="@+id/title"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="top|left"
+            android:layout_marginBottom="8dp"
+            android:fontFamily="sans-serif"
+            android:textSize="16sp"
+            android:text="@string/widget_name"
+            android:freezesText="true"/>
+
+        <TextView
+            android:id="@+id/instruction"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginBottom="12dp"
+            android:fontFamily="sans-serif-light"
+            android:textSize="14sp"
+            android:freezesText="true"/>
+
+        <TextView
+            android:id="@+id/data"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginBottom="12dp"
+            android:layout_gravity="center_horizontal"
+            android:fontFamily="sans-serif-light"
+            android:textSize="14sp"/>
+
+        <ListView
+            android:id="@+id/list"
+            android:layout_width="match_parent"
+            android:layout_height="0dp"
+            android:layout_weight="1"
+            android:layout_marginBottom="12dp"
+            android:padding="1dp"
+            android:background="#fff"
+            android:visibility="gone"/>
+
+        <LinearLayout
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="bottom|center_horizontal"
+            android:orientation="horizontal">
+            <Button
+                android:id="@+id/fail"
+                android:layout_marginRight="8dp"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:minWidth="100dp"
+                android:text="@string/widget_fail" />
+            <Button
+                android:id="@+id/pass"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:minWidth="100dp"
+                android:text="@string/widget_pass" />
+        </LinearLayout>
+
+    </LinearLayout>
+</FrameLayout>
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index 66c8f86..4ee6926 100755
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -1434,7 +1434,8 @@
     <!-- Strings for TestListActivity -->
     <string name="wifi_test">Wi-Fi Test</string>
     <string name="wifi_test_info">
-        The Wi-Fi tests requires an open (no security) access point along with the DUT.
+        The Wi-Fi tests requires an open (no security) access point in the environment along with the DUT.
+        The DUT should also not have any saved wifi networks that are visible in the environment.
     </string>
     <string name="wifi_location_not_enabled">Wi-Fi / Location Mode is not enabled</string>
     <string name="wifi_location_not_enabled_message">These tests require Wi-Fi and Location Mode to be enabled.
@@ -1449,6 +1450,8 @@
     <string name="wifi_status_initiating_scan">Initiating scan.</string>
     <string name="wifi_status_scan_failure">Unable to initiate scan.</string>
     <string name="wifi_status_open_network_not_found">Unable to find any open network in scan results.</string>
+    <string name="wifi_status_connected_to_other_network">Connected to some other network on the device. Please ensure that there is no saved networks on the device.</string>
+
     <string name="wifi_status_initiating_network_request">Initiating network request.</string>
     <string name="wifi_status_network_wait_for_available">Waiting for network connection. Please click the network in the dialog that pops up for approving the request.</string>
     <string name="wifi_status_network_available">"Connected to network."</string>
@@ -1458,6 +1461,18 @@
     <string name="wifi_status_network_lost">Disconnected from the network.</string>
     <string name="wifi_status_network_cb_timeout">Network callback timed out.</string>
 
+    <string name="wifi_status_suggestion_add">Adding suggestions to the device.</string>
+    <string name="wifi_status_suggestion_add_failure">Failed to add suggestions.</string>
+    <string name="wifi_status_suggestion_remove">Removing suggestions from the device.</string>
+    <string name="wifi_status_suggestion_remove_failure">Failed to remove suggestions.</string>
+    <string name="wifi_status_suggestion_wait_for_connect">Waiting for network connection. Please click \"Yes\" in the notification that pops up for approving the request.</string>
+    <string name="wifi_status_suggestion_connect">Connected to the network.</string>
+    <string name="wifi_status_suggestion_wait_for_post_connect_bcast">Waiting for post connection broadcast.</string>
+    <string name="wifi_status_suggestion_post_connect_bcast">Received post connection broadcast.</string>
+    <string name="wifi_status_suggestion_post_connect_bcast_failure">Failed to receive post connection broadcast.</string>
+    <string name="wifi_status_suggestion_wait_for_disconnect">Ensuring device does not disconnect from the network after removing suggestions.</string>
+    <string name="wifi_status_suggestion_disconnected">Disconnected from the network.</string>
+
     <string name="wifi_status_test_success">Test completed successfully!</string>
     <string name="wifi_status_test_failed">Test failed!</string>
 
@@ -1469,6 +1484,14 @@
     <string name="wifi_test_network_request_unavailable">Network Request with a specific network that is unavailable.</string>
     <string name="wifi_test_network_request_unavailable_info">Tests that the API fails to connect when an unavailable network is specified in the request.</string>
 
+    <string name="wifi_test_network_suggestion">Network Suggestion tests</string>
+    <string name="wifi_test_network_suggestion_ssid">Network suggestion with SSID.</string>
+    <string name="wifi_test_network_suggestion_ssid_info">Tests whether the API can be used to suggest a network with SSID to the device and the device connects to it.</string>
+    <string name="wifi_test_network_suggestion_ssid_bssid">Network Request with a specific SSID and BSSID.</string>
+    <string name="wifi_test_network_suggestion_ssid_bssid_info">Tests whether the API can be used to suggest a network with SSID and specific BSSID to the device and the device connects to it.</string>
+    <string name="wifi_test_network_suggestion_ssid_post_connect">Network Request with a specific SSID and BSSID.</string>
+    <string name="wifi_test_network_suggestion_ssid_post_connect_info">Tests whether the API can be used to suggest a network with SSID to the device and the device connects to it and sends the post connect broadcast back to the app.</string>
+
     <!-- Strings for P2pTestActivity -->
     <string name="p2p_test">Wi-Fi Direct Test</string>
     <string name="p2p_test_info">
@@ -1969,6 +1992,12 @@
     <string name="widget_pass">Pass</string>
     <string name="widget_fail">Fail</string>
 
+    <string name="provisioning_byod_non_market_apps">Non-market app installation restrictions</string>
+    <string name="provisioning_byod_non_market_apps_info">
+        This test exercises user restrictions on installation of non-market apps. Follow
+        instructions in each test.
+    </string>
+
     <string name="provisioning_byod_nonmarket_allow">Enable non-market apps</string>
     <string name="provisioning_byod_nonmarket_allow_info">
         This test verifies that non-market apps can be installed if permitted.\n
@@ -2006,18 +2035,34 @@
     <string name="provisioning_byod_nonmarket_allow_global_primary">Enable primary user non-market apps (global restriction)</string>
     <string name="provisioning_byod_nonmarket_allow_global_primary_info">
         This test verifies that non-market apps from the primary user can be installed if permitted.\n
-        1. A package installation UI should appear.\n
-        2. If \'Cts Verifier\' is not allowed to install apps, a warning dialog will appear
-        blocking the install. In this case go to step 3, else skip to step 4.\n
-        3. Allow \'Cts Verifier\' to install apps. Return to package installer.\n
-        4. Accept the installation and verify that it succeeds (no error message is displayed).
+        1. You should have received NotificationBot.apk together with the CTS verifier. If you built
+        the CTS verifier yourself, build the NotificationBot.apk by issuing the following command on
+        the host:\n
+        make NotificationBot\n
+        2. Upload the NotificationBot.apk to your device by issuing the following command on the
+        host:\n
+        adb push /path/to/NotificationBot.apk /data/local/tmp/\n
+        3. Press \"Go\" to install NotificationBot.apk in your personal profile. A package
+        installation UI should appear.\n
+        4. If \'Cts Verifier\' is not allowed to install apps, a warning dialog will appear
+        blocking the install. In this case go to step 5, else skip to step 6.\n
+        5. Allow \'Cts Verifier\' to install apps. Return to package installer.\n
+        6. Accept the installation and verify that it succeeds (no error message is displayed).
     </string>
 
     <string name="provisioning_byod_nonmarket_deny_global_primary">Disable primary user non-market apps (global restriction)</string>
     <string name="provisioning_byod_nonmarket_deny_global_primary_info">
         This test verifies that non-market apps from the primary user cannot be installed unless permitted.\n
-        1. A package installation UI should appear.\n
-        2. Verify that the installation of the package is refused.
+        1. You should have received NotificationBot.apk together with the CTS verifier. If you built
+        the CTS verifier yourself, build the NotificationBot.apk by issuing the following command on
+        the host:\n
+        make NotificationBot\n
+        2. Upload the NotificationBot.apk to your device by issuing the following command on the
+        host:\n
+        adb push /path/to/NotificationBot.apk /data/local/tmp/\n
+        3. Press \"Go\" to install NotificationBot.apk in your personal profile. A package
+        installation UI should appear.\n
+        4. Verify that the installation of the package is refused.
     </string>
 
     <string name="provisioning_byod_capture_image_support">Camera support cross profile image capture</string>
@@ -2223,9 +2268,6 @@
         2) Testing that a generated key can be hidden from users.\n
         \n
         Tap \"Prepare Test\" button below to begin.\n
-        \n
-        NOTE: A screen lock must be configured for this test. Otherwise, test preparation
-        will fail to generate a key for use by the test.
     </string>
     <string name="provisioning_byod_keychain_info_first_test">
         Once you press \'Go\', a prompt titled \"Choose certificate\" should appear.\n
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java
index f3fe451..1b18a5a 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java
@@ -365,7 +365,7 @@
                 for (String camId : devices) {
                     CameraCharacteristics chars =  mCameraManager.getCameraCharacteristics(camId);
                     Size maxYuvSize = ItsUtils.getMaxOutputSize(
-                            mCameraCharacteristics, ImageFormat.YUV_420_888);
+                            chars, ImageFormat.YUV_420_888);
                     // 4 bytes per pixel for RGBA8888 Bitmap and at least 3 Bitmaps per CDD
                     int quota = maxYuvSize.getWidth() * maxYuvSize.getHeight() * 4 * 3;
                     if (quota > mMemoryQuota) {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java
index 7970992..6015242 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java
@@ -27,8 +27,6 @@
 import android.os.Bundle;
 import android.provider.Settings;
 import android.util.Log;
-import android.view.View;
-import android.view.View.OnClickListener;
 import android.widget.Toast;
 
 import com.android.cts.verifier.ArrayTestListAdapter;
@@ -80,12 +78,7 @@
     private DialogTestListItem mCrossProfileIntentFiltersTestFromPersonal;
     private DialogTestListItem mCrossProfileIntentFiltersTestFromWork;
     private DialogTestListItem mAppLinkingTest;
-    private DialogTestListItem mDisableNonMarketTest;
-    private DialogTestListItem mEnableNonMarketTest;
-    private DialogTestListItem mDisableNonMarketWorkProfileDeviceWideTest;
-    private DialogTestListItem mEnableNonMarketWorkProfileDeviceWideTest;
-    private DialogTestListItem mDisableNonMarketPrimaryUserDeviceWideTest;
-    private DialogTestListItem mEnableNonMarketPrimaryUserDeviceWideTest;
+    private TestListItem mNonMarketAppsTest;
     private DialogTestListItem mWorkNotificationBadgedTest;
     private DialogTestListItem mWorkStatusBarIconTest;
     private DialogTestListItem mWorkStatusBarToastTest;
@@ -140,13 +133,9 @@
         mByodFlowTestHelper.setup();
 
         mPrepareTestButton.setText(R.string.provisioning_byod_start);
-        mPrepareTestButton.setOnClickListener(new OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                Utils.provisionManagedProfile(ByodFlowTestActivity.this, mAdminReceiverComponent,
-                        REQUEST_MANAGED_PROVISIONING);
-            }
-        });
+        mPrepareTestButton.setOnClickListener(v -> Utils.provisionManagedProfile(
+                ByodFlowTestActivity.this, mAdminReceiverComponent,
+                REQUEST_MANAGED_PROVISIONING));
 
         // If we are started by managed provisioning (fresh managed provisioning after encryption
         // reboot), redirect the user back to the main test list. This is because the test result
@@ -293,49 +282,10 @@
                 workStatusToast);
         */
 
-        mDisableNonMarketTest = new DialogTestListItem(this,
-                R.string.provisioning_byod_nonmarket_deny,
-                "BYOD_DisableNonMarketTest",
-                R.string.provisioning_byod_nonmarket_deny_info,
-                new Intent(ByodHelperActivity.ACTION_INSTALL_APK)
-                        .putExtra(ByodHelperActivity.EXTRA_ALLOW_NON_MARKET_APPS, false));
-
-        mEnableNonMarketTest = new DialogTestListItem(this,
-                R.string.provisioning_byod_nonmarket_allow,
-                "BYOD_EnableNonMarketTest",
-                R.string.provisioning_byod_nonmarket_allow_info,
-                new Intent(ByodHelperActivity.ACTION_INSTALL_APK)
-                        .putExtra(ByodHelperActivity.EXTRA_ALLOW_NON_MARKET_APPS, true));
-
-        mDisableNonMarketWorkProfileDeviceWideTest = new DialogTestListItem(this,
-            R.string.provisioning_byod_nonmarket_deny_global,
-            "BYOD_DisableNonMarketDeviceWideTest",
-            R.string.provisioning_byod_nonmarket_deny_global_info,
-            new Intent(ByodHelperActivity.ACTION_INSTALL_APK_WORK_PROFILE_GLOBAL_RESTRICTION)
-                .putExtra(ByodHelperActivity.EXTRA_ALLOW_NON_MARKET_APPS_DEVICE_WIDE, false));
-
-        mEnableNonMarketWorkProfileDeviceWideTest = new DialogTestListItem(this,
-            R.string.provisioning_byod_nonmarket_allow_global,
-            "BYOD_EnableNonMarketDeviceWideTest",
-            R.string.provisioning_byod_nonmarket_allow_global_info,
-            new Intent(ByodHelperActivity.ACTION_INSTALL_APK_WORK_PROFILE_GLOBAL_RESTRICTION)
-                .putExtra(ByodHelperActivity.EXTRA_ALLOW_NON_MARKET_APPS_DEVICE_WIDE, true));
-
-        mDisableNonMarketPrimaryUserDeviceWideTest = new DialogTestListItem(this,
-            R.string.provisioning_byod_nonmarket_deny_global_primary,
-            "BYOD_DisableNonMarketPrimaryUserDeviceWideTest",
-            R.string.provisioning_byod_nonmarket_deny_global_primary_info,
-            new Intent(ByodHelperActivity.ACTION_INSTALL_APK_PRIMARY_PROFILE_GLOBAL_RESTRICTION)
-                    .putExtra(ByodHelperActivity.EXTRA_ALLOW_NON_MARKET_APPS_DEVICE_WIDE,
-                            false));
-
-        mEnableNonMarketPrimaryUserDeviceWideTest = new DialogTestListItem(this,
-            R.string.provisioning_byod_nonmarket_allow_global_primary,
-            "BYOD_EnableNonMarketPrimaryUserDeviceWideTest",
-            R.string.provisioning_byod_nonmarket_allow_global_primary_info,
-            new Intent(ByodHelperActivity.ACTION_INSTALL_APK_PRIMARY_PROFILE_GLOBAL_RESTRICTION)
-                    .putExtra(ByodHelperActivity.EXTRA_ALLOW_NON_MARKET_APPS_DEVICE_WIDE,
-                            true));
+        mNonMarketAppsTest = TestListItem.newTest(this,
+                R.string.provisioning_byod_non_market_apps,
+                NonMarketAppsActivity.class.getName(),
+                new Intent(this, NonMarketAppsActivity.class), null);
 
         mProfileAccountVisibleTest = new DialogTestListItem(this,
                 R.string.provisioning_byod_profile_visible,
@@ -539,13 +489,8 @@
         /* Disable due to b/33571176
         adapter.add(mAppLinkingTest);
         */
-        adapter.add(mDisableNonMarketTest);
-        adapter.add(mEnableNonMarketTest);
-        adapter.add(mDisableNonMarketWorkProfileDeviceWideTest);
-        adapter.add(mEnableNonMarketWorkProfileDeviceWideTest);
-        adapter.add(mDisableNonMarketPrimaryUserDeviceWideTest);
-        adapter.add(mEnableNonMarketPrimaryUserDeviceWideTest);
         adapter.add(mIntentFiltersTest);
+        adapter.add(mNonMarketAppsTest);
         adapter.add(mPermissionLockdownTest);
         adapter.add(mKeyguardDisabledFeaturesTest);
         adapter.add(mAuthenticationBoundKeyTest);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/NonMarketAppsActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/NonMarketAppsActivity.java
new file mode 100644
index 0000000..25b3b80
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/NonMarketAppsActivity.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.verifier.managedprovisioning;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+
+import com.android.cts.verifier.ArrayTestListAdapter;
+import com.android.cts.verifier.DialogTestListActivity;
+import com.android.cts.verifier.R;
+
+public class NonMarketAppsActivity extends DialogTestListActivity {
+
+    protected DevicePolicyManager mDpm;
+
+    public NonMarketAppsActivity() {
+        super(R.layout.provisioning_byod,
+              R.string.provisioning_byod_non_market_apps,
+              R.string.provisioning_byod_non_market_apps_info,
+              R.string.provisioning_byod_non_market_apps_info);
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        // Hiding button from default BYOD test layout, as it is not useful in this test.
+        mPrepareTestButton = findViewById(R.id.prepare_test_button);
+        mPrepareTestButton.setVisibility(View.INVISIBLE);
+        mDpm = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
+    }
+
+    @Override
+    protected void setupTests(ArrayTestListAdapter adapter) {
+        DialogTestListItem disableNonMarketTest = new DialogTestListItem(this,
+                R.string.provisioning_byod_nonmarket_deny,
+                "BYOD_DisableNonMarketTest",
+                R.string.provisioning_byod_nonmarket_deny_info,
+                new Intent(ByodHelperActivity.ACTION_INSTALL_APK)
+                        .putExtra(ByodHelperActivity.EXTRA_ALLOW_NON_MARKET_APPS, false));
+
+        DialogTestListItem enableNonMarketTest = new DialogTestListItem(this,
+                R.string.provisioning_byod_nonmarket_allow,
+                "BYOD_EnableNonMarketTest",
+                R.string.provisioning_byod_nonmarket_allow_info,
+                new Intent(ByodHelperActivity.ACTION_INSTALL_APK)
+                        .putExtra(ByodHelperActivity.EXTRA_ALLOW_NON_MARKET_APPS, true));
+
+        DialogTestListItem disableNonMarketWorkProfileDeviceWideTest = new DialogTestListItem(
+                this,
+                R.string.provisioning_byod_nonmarket_deny_global,
+                "BYOD_DisableNonMarketDeviceWideTest",
+                R.string.provisioning_byod_nonmarket_deny_global_info,
+                new Intent(ByodHelperActivity.ACTION_INSTALL_APK_WORK_PROFILE_GLOBAL_RESTRICTION)
+                        .putExtra(ByodHelperActivity.EXTRA_ALLOW_NON_MARKET_APPS_DEVICE_WIDE,
+                                false));
+
+        DialogTestListItem enableNonMarketWorkProfileDeviceWideTest = new DialogTestListItem(
+                this,
+                R.string.provisioning_byod_nonmarket_allow_global,
+                "BYOD_EnableNonMarketDeviceWideTest",
+                R.string.provisioning_byod_nonmarket_allow_global_info,
+                new Intent(ByodHelperActivity.ACTION_INSTALL_APK_WORK_PROFILE_GLOBAL_RESTRICTION)
+                        .putExtra(ByodHelperActivity.EXTRA_ALLOW_NON_MARKET_APPS_DEVICE_WIDE,
+                                true));
+
+        DialogTestListItem disableNonMarketPrimaryUserDeviceWideTest = new DialogTestListItem(
+                this,
+                R.string.provisioning_byod_nonmarket_deny_global_primary,
+                "BYOD_DisableNonMarketPrimaryUserDeviceWideTest",
+                R.string.provisioning_byod_nonmarket_deny_global_primary_info,
+                new Intent(ByodHelperActivity.ACTION_INSTALL_APK_PRIMARY_PROFILE_GLOBAL_RESTRICTION)
+                        .putExtra(ByodHelperActivity.EXTRA_ALLOW_NON_MARKET_APPS_DEVICE_WIDE,
+                                false));
+
+        DialogTestListItem enableNonMarketPrimaryUserDeviceWideTest = new DialogTestListItem(
+                this,
+                R.string.provisioning_byod_nonmarket_allow_global_primary,
+                "BYOD_EnableNonMarketPrimaryUserDeviceWideTest",
+                R.string.provisioning_byod_nonmarket_allow_global_primary_info,
+                new Intent(ByodHelperActivity.ACTION_INSTALL_APK_PRIMARY_PROFILE_GLOBAL_RESTRICTION)
+                        .putExtra(ByodHelperActivity.EXTRA_ALLOW_NON_MARKET_APPS_DEVICE_WIDE,
+                                true));
+
+        adapter.add(disableNonMarketTest);
+        adapter.add(enableNonMarketTest);
+        adapter.add(disableNonMarketWorkProfileDeviceWideTest);
+        adapter.add(enableNonMarketWorkProfileDeviceWideTest);
+        adapter.add(disableNonMarketPrimaryUserDeviceWideTest);
+        adapter.add(enableNonMarketPrimaryUserDeviceWideTest);
+    }
+
+    protected ComponentName getAdminComponent() {
+        return DeviceAdminTestReceiver.getReceiverComponentName();
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/BaseTestCase.java b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/BaseTestCase.java
index 8382903..920119f 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/BaseTestCase.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/BaseTestCase.java
@@ -16,11 +16,15 @@
 
 package com.android.cts.verifier.wifi;
 
+import android.annotation.Nullable;
 import android.content.Context;
 import android.content.res.Resources;
+import android.net.wifi.SupplicantState;
+import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
 import android.os.Handler;
 import android.os.HandlerThread;
+import android.util.Log;
 
 import com.android.cts.verifier.R;
 
@@ -28,6 +32,7 @@
  * Base class for all Wifi test cases.
  */
 public abstract class BaseTestCase {
+    private static final String TAG = "BaseTestCase";
     protected Context mContext;
     protected Resources mResources;
     protected Listener mListener;
@@ -48,6 +53,42 @@
      */
     protected void setUp() {
         mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
+
+        // Ensure we're not connected to any wifi network before we start the tests.
+        if (isConnected(null, null)) {
+            mListener.onTestFailed(mContext.getString(
+                    R.string.wifi_status_connected_to_other_network));
+            throw new IllegalStateException("Should not be connected to any network");
+        }
+        /**
+         * TODO: Clear the state before each test. This needs to be an instrumentation to
+         * run the below shell commands.
+        SystemUtil.runShellCommand("wifi network-suggestions-set-user-approved "
+                + mContext.getPackageName() + " no");
+        SystemUtil.runShellCommand("wifi network-requests-remove-user-approved-access-points "
+                + mContext.getPackageName());
+        */
+    }
+
+    /**
+     * Checks whether the device is connected.
+     *
+     * @param ssid If ssid is specified, then check where the device is connected to a network
+     *             with the specified SSID.
+     * @param bssid If bssid is specified, then check where the device is connected to a network
+     *             with the specified BSSID.
+     * @return
+     */
+    protected boolean isConnected(@Nullable String ssid, @Nullable String bssid) {
+        WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
+        if (wifiInfo == null) {
+            Log.e(TAG, "Failed to get WifiInfo");
+            return false;
+        }
+        if (wifiInfo.getSupplicantState() != SupplicantState.COMPLETED) return false;
+        if (ssid != null && !wifiInfo.getSSID().equals(ssid)) return false;
+        if (bssid != null && !wifiInfo.getBSSID().equals(bssid)) return false;
+        return true;
     }
 
     /**
@@ -92,6 +133,7 @@
                         try {
                             setUp();
                         } catch (Exception e) {
+                            Log.e(TAG, "Setup failed", e);
                             mListener.onTestFailed(mContext.getString(R.string.wifi_setup_error));
                             return;
                         }
@@ -103,7 +145,7 @@
                                 mListener.onTestFailed(getFailureReason());
                             }
                         } catch (Exception e) {
-                            e.printStackTrace();
+                            Log.e(TAG, "Execute failed", e);
                             mListener.onTestFailed(
                                     mContext.getString(R.string.aware_unexpected_error));
                         } finally {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/NetworkSuggestionSsidBssidTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/NetworkSuggestionSsidBssidTestActivity.java
new file mode 100644
index 0000000..51a3b9e
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/NetworkSuggestionSsidBssidTestActivity.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.verifier.wifi;
+
+import android.content.Context;
+import android.os.Bundle;
+
+import com.android.cts.verifier.R;
+import com.android.cts.verifier.wifi.testcase.NetworkSuggestionTestCase;
+
+/**
+ * Test activity for suggestion with ssid and bssid specified.
+ */
+public class NetworkSuggestionSsidBssidTestActivity extends BaseTestActivity {
+    @Override
+    protected BaseTestCase getTestCase(Context context) {
+        return new NetworkSuggestionTestCase(
+                context,
+                true /* setBssid */,
+                false /* setRequiresAppInteraction */);
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setInfoResources(R.string.wifi_test_network_suggestion_ssid_bssid,
+                R.string.wifi_test_network_suggestion_ssid_bssid_info, 0);
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/NetworkSuggestionSsidPostConnectTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/NetworkSuggestionSsidPostConnectTestActivity.java
new file mode 100644
index 0000000..80a6255
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/NetworkSuggestionSsidPostConnectTestActivity.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.verifier.wifi;
+
+import android.content.Context;
+import android.os.Bundle;
+
+import com.android.cts.verifier.R;
+import com.android.cts.verifier.wifi.testcase.NetworkSuggestionTestCase;
+
+/**
+ * Test activity for suggestion with ssid specified and expecting post connect
+ * broadcast.
+ */
+public class NetworkSuggestionSsidPostConnectTestActivity extends BaseTestActivity {
+    @Override
+    protected BaseTestCase getTestCase(Context context) {
+        return new NetworkSuggestionTestCase(
+                context,
+                false /* setBssid */,
+                true /* setRequiresAppInteraction */);
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setInfoResources(R.string.wifi_test_network_suggestion_ssid_post_connect,
+                R.string.wifi_test_network_suggestion_ssid_post_connect_info, 0);
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/NetworkSuggestionSsidTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/NetworkSuggestionSsidTestActivity.java
new file mode 100644
index 0000000..5fb5d83
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/NetworkSuggestionSsidTestActivity.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.verifier.wifi;
+
+import android.content.Context;
+import android.os.Bundle;
+
+import com.android.cts.verifier.R;
+import com.android.cts.verifier.wifi.testcase.NetworkSuggestionTestCase;
+
+/**
+ * Test activity for suggestion with ssid specified.
+ */
+public class NetworkSuggestionSsidTestActivity extends BaseTestActivity {
+    @Override
+    protected BaseTestCase getTestCase(Context context) {
+        return new NetworkSuggestionTestCase(
+                context,
+                false /* setBssid */,
+                false /* setRequiresAppInteraction */);
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setInfoResources(R.string.wifi_test_network_suggestion_ssid,
+                R.string.wifi_test_network_suggestion_ssid_info, 0);
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/TestListActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/TestListActivity.java
index b4ccd3a..b7c6c8a 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/TestListActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/TestListActivity.java
@@ -74,6 +74,20 @@
                 NetworkRequestUnavailableNetworkSpecifierTestActivity.class.getName(),
                 new Intent(this, NetworkRequestUnavailableNetworkSpecifierTestActivity.class),
                 null));
+        adapter.add(TestListAdapter.TestListItem.newCategory(this,
+                R.string.wifi_test_network_suggestion));
+        adapter.add(TestListAdapter.TestListItem.newTest(this,
+                R.string.wifi_test_network_suggestion_ssid,
+                NetworkSuggestionSsidTestActivity.class.getName(),
+                new Intent(this, NetworkSuggestionSsidTestActivity.class), null));
+        adapter.add(TestListAdapter.TestListItem.newTest(this,
+                R.string.wifi_test_network_suggestion_ssid_bssid,
+                NetworkSuggestionSsidBssidTestActivity.class.getName(),
+                new Intent(this, NetworkSuggestionSsidBssidTestActivity.class), null));
+        adapter.add(TestListAdapter.TestListItem.newTest(this,
+                R.string.wifi_test_network_suggestion_ssid_post_connect,
+                NetworkSuggestionSsidPostConnectTestActivity.class.getName(),
+                new Intent(this, NetworkSuggestionSsidPostConnectTestActivity.class), null));
 
         adapter.registerDataSetObserver(new DataSetObserver() {
             @Override
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/testcase/NetworkRequestTestCase.java b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/testcase/NetworkRequestTestCase.java
index 5760ed2..528f7d6 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/testcase/NetworkRequestTestCase.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/testcase/NetworkRequestTestCase.java
@@ -33,7 +33,7 @@
 import android.net.NetworkSpecifier;
 import android.net.wifi.ScanResult;
 import android.net.wifi.WifiManager;
-import android.net.wifi.WifiNetworkConfigBuilder;
+import android.net.wifi.WifiNetworkSpecifier;
 import android.os.PatternMatcher;
 import android.text.TextUtils;
 import android.util.Log;
@@ -51,7 +51,7 @@
 
 /**
  * Test case for all {@link NetworkRequest} requests with specifier built using
- * {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()}.
+ * {@link WifiNetworkSpecifier.Builder#build()}.
  */
 public class NetworkRequestTestCase extends BaseTestCase {
     private static final String TAG = "NetworkRequestTestCase";
@@ -91,7 +91,7 @@
     // Create a network specifier based on the test type.
     private NetworkSpecifier createNetworkSpecifier(@NonNull ScanResult scanResult)
             throws InterruptedException {
-        WifiNetworkConfigBuilder configBuilder = new WifiNetworkConfigBuilder();
+        WifiNetworkSpecifier.Builder configBuilder = new WifiNetworkSpecifier.Builder();
         switch (mNetworkSpecifierType) {
             case NETWORK_SPECIFIER_SPECIFIC_SSID_BSSID:
                 configBuilder.setSsid(scanResult.SSID);
@@ -118,7 +118,7 @@
             default:
                 throw new IllegalStateException("Unknown specifier type specifier");
         }
-        return configBuilder.buildNetworkSpecifier();
+        return configBuilder.build();
     }
 
     private boolean startScanAndWaitForResults() throws InterruptedException {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/testcase/NetworkSuggestionTestCase.java b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/testcase/NetworkSuggestionTestCase.java
new file mode 100644
index 0000000..4d0cbc5
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/testcase/NetworkSuggestionTestCase.java
@@ -0,0 +1,300 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.verifier.wifi.testcase;
+
+import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
+import static android.net.wifi.WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.ConnectivityManager;
+import android.net.MacAddress;
+import android.net.Network;
+import android.net.NetworkRequest;
+import android.net.wifi.ScanResult;
+import android.net.wifi.WifiManager;
+import android.net.wifi.WifiNetworkSuggestion;
+import android.text.TextUtils;
+import android.util.Log;
+import android.util.Pair;
+
+import com.android.cts.verifier.R;
+import com.android.cts.verifier.wifi.BaseTestCase;
+import com.android.cts.verifier.wifi.CallbackUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Test cases for network suggestions {@link WifiNetworkSuggestion} added via
+ * {@link WifiManager#addNetworkSuggestions(List)}.
+ */
+public class NetworkSuggestionTestCase extends BaseTestCase {
+    private static final String TAG = "NetworkSuggestionTestCase";
+    private static final boolean DBG = true;
+
+    private static final int CALLBACK_TIMEOUT_MS = 40_000;
+    private static final int SCAN_TIMEOUT_MS = 30_000;
+
+    private final Object mLock = new Object();
+    private final List<WifiNetworkSuggestion> mNetworkSuggestions = new ArrayList<>();
+
+    private ConnectivityManager mConnectivityManager;
+    private NetworkRequest mNetworkRequest;
+    private CallbackUtils.NetworkCallback mNetworkCallback;
+    private BroadcastReceiver mBroadcastReceiver;
+    private String mFailureReason;
+
+    private final boolean mSetBssid;
+    private final boolean mSetRequiresAppInteraction;
+
+    public NetworkSuggestionTestCase(Context context, boolean setBssid,
+                                     boolean setRequiresAppInteraction) {
+        super(context);
+        mSetBssid = setBssid;
+        mSetRequiresAppInteraction = setRequiresAppInteraction;
+    }
+
+    // Create a network specifier based on the test type.
+    private WifiNetworkSuggestion createNetworkSuggestion(@NonNull ScanResult scanResult) {
+        WifiNetworkSuggestion.Builder builder = new WifiNetworkSuggestion.Builder();
+        builder.setSsid(scanResult.SSID);
+        if (mSetBssid) {
+            builder.setBssid(MacAddress.fromString(scanResult.BSSID));
+        }
+        if (mSetRequiresAppInteraction) {
+            builder.setIsAppInteractionRequired();
+        }
+        return builder.build();
+    }
+
+    private boolean startScanAndWaitForResults() throws InterruptedException {
+        IntentFilter intentFilter = new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
+        final CountDownLatch countDownLatch = new CountDownLatch(1);
+        // Scan Results available broadcast receiver.
+        mBroadcastReceiver = new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                if (DBG) Log.v(TAG, "Broadcast onReceive " + intent);
+                if (!intent.getAction().equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) return;
+                if (!intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false)) return;
+                if (DBG) Log.v(TAG, "Scan results received");
+                countDownLatch.countDown();
+            }
+        };
+        // Register the receiver for scan results broadcast.
+        mContext.registerReceiver(mBroadcastReceiver, intentFilter);
+
+        // Start scan.
+        if (DBG) Log.v(TAG, "Starting scan");
+        mListener.onTestMsgReceived(mContext.getString(R.string.wifi_status_initiating_scan));
+        if (!mWifiManager.startScan()) {
+            Log.e(TAG, "Failed to start scan");
+            setFailureReason(mContext.getString(R.string.wifi_status_scan_failure));
+            return false;
+        }
+        // Wait for scan results.
+        if (DBG) Log.v(TAG, "Wait for scan results");
+        if (!countDownLatch.await(SCAN_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
+            Log.e(TAG, "No new scan results available");
+            setFailureReason(mContext.getString(R.string.wifi_status_scan_failure));
+            return false;
+        }
+        // Unregister the scan receiver.
+        mContext.unregisterReceiver(mBroadcastReceiver);
+        mBroadcastReceiver = null;
+        return true;
+    }
+
+    // Helper to check if the scan result corresponds to an open network.
+    private static boolean isScanResultForOpenNetwork(@NonNull ScanResult scanResult) {
+        String capabilities = scanResult.capabilities;
+        return !capabilities.contains("PSK") && !capabilities.contains("EAP")
+                && !capabilities.contains("WEP") && !capabilities.contains("SAE")
+                && !capabilities.contains("SUITE-B-192") && !capabilities.contains("OWE");
+    }
+
+    private @Nullable ScanResult startScanAndFindAnyOpenNetworkInResults()
+            throws InterruptedException {
+        // Start scan and wait for new results.
+        if (!startScanAndWaitForResults()) {
+            return null;
+        }
+        // Filter results to find an open network.
+        List<ScanResult> scanResults = mWifiManager.getScanResults();
+        for (ScanResult scanResult : scanResults) {
+            if (!TextUtils.isEmpty(scanResult.SSID)
+                    && !TextUtils.isEmpty(scanResult.BSSID)
+                    && isScanResultForOpenNetwork(scanResult)) {
+                if (DBG) Log.v(TAG, "Found open network " + scanResult);
+                return scanResult;
+            }
+        }
+        Log.e(TAG, "No open networks found in scan results");
+        setFailureReason(mContext.getString(R.string.wifi_status_open_network_not_found));
+        return null;
+    }
+
+    private void setFailureReason(String reason) {
+        synchronized (mLock) {
+            mFailureReason = reason;
+        }
+    }
+
+    @Override
+    protected boolean executeTest() throws InterruptedException {
+        // Step 1: Scan and find any open network around.
+        if (DBG) Log.v(TAG, "Scan and find an open network");
+        ScanResult openNetwork = startScanAndFindAnyOpenNetworkInResults();
+        if (openNetwork == null) return false;
+
+        // Step 1.a (Optional): Register for the post connection broadcast.
+        final CountDownLatch countDownLatchForPostConnectionBcast = new CountDownLatch(1);
+        if (mSetRequiresAppInteraction) {
+            IntentFilter intentFilter =
+                    new IntentFilter(WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION);
+            // Post connection broadcast receiver.
+            mBroadcastReceiver = new BroadcastReceiver() {
+                @Override
+                public void onReceive(Context context, Intent intent) {
+                    if (DBG) Log.v(TAG, "Broadcast onReceive " + intent);
+                    if (!intent.getAction().equals(
+                            WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION)) {
+                        return;
+                    }
+                    if (DBG) Log.v(TAG, "Post connection broadcast received");
+                    countDownLatchForPostConnectionBcast.countDown();
+                }
+            };
+            // Register the receiver for post connection broadcast.
+            mContext.registerReceiver(mBroadcastReceiver, intentFilter);
+        }
+
+        // Step 1.b: Register network callback to wait for connection state.
+        mNetworkRequest = new NetworkRequest.Builder()
+                .addTransportType(TRANSPORT_WIFI)
+                .build();
+        mNetworkCallback = new CallbackUtils.NetworkCallback(CALLBACK_TIMEOUT_MS);
+        mConnectivityManager.registerNetworkCallback(mNetworkRequest, mNetworkCallback);
+
+        // Step 2: Create a suggestion for the chosen open network depending on the type of test.
+        WifiNetworkSuggestion networkSuggestion = createNetworkSuggestion(openNetwork);
+        mNetworkSuggestions.add(networkSuggestion);
+
+        // Step 4: Add a network suggestions.
+        if (DBG) Log.v(TAG, "Adding suggestion");
+        mListener.onTestMsgReceived(mContext.getString(R.string.wifi_status_suggestion_add));
+        if (mWifiManager.addNetworkSuggestions(mNetworkSuggestions)
+                != STATUS_NETWORK_SUGGESTIONS_SUCCESS) {
+            setFailureReason(mContext.getString(R.string.wifi_status_suggestion_add_failure));
+            return false;
+        }
+
+        // Step 5: Wait for connection.
+        if (DBG) Log.v(TAG, "Waiting for connection");
+        mListener.onTestMsgReceived(mContext.getString(
+                R.string.wifi_status_suggestion_wait_for_connect));
+        Pair<Boolean, Network> cbStatusForAvailable = mNetworkCallback.waitForAvailable();
+        if (!cbStatusForAvailable.first) {
+            Log.e(TAG, "Failed to get network available callback");
+            setFailureReason(mContext.getString(R.string.wifi_status_network_cb_timeout));
+            return false;
+        }
+        mListener.onTestMsgReceived(
+                mContext.getString(R.string.wifi_status_suggestion_connect));
+
+        // Step 6: Ensure that we connected to the suggested network (optionally, the correct
+        // BSSID).
+        if (!isConnected("\"" + openNetwork.SSID + "\"",
+                // TODO: This might fail if there are other BSSID's for the same network & the
+                //  device decided to connect/roam to a different BSSID. We don't turn off roaming
+                //  for suggestions.
+                mSetBssid ? openNetwork.BSSID : null)) {
+            Log.e(TAG, "Failed to connected to a wrong network");
+            setFailureReason(mContext.getString(R.string.wifi_status_connected_to_other_network));
+            return false;
+        }
+
+        if (mSetRequiresAppInteraction) {
+            // Step 7 (Optional): Ensure we received the post connect broadcast.
+            if (DBG) Log.v(TAG, "Wait for post connection broadcast");
+            mListener.onTestMsgReceived(
+                    mContext.getString(
+                            R.string.wifi_status_suggestion_wait_for_post_connect_bcast));
+            if (!countDownLatchForPostConnectionBcast.await(
+                    CALLBACK_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
+                Log.e(TAG, "Failed to get post connection broadcast");
+                setFailureReason(mContext.getString(
+                        R.string.wifi_status_suggestion_post_connect_bcast_failure));
+                return false;
+            }
+            mListener.onTestMsgReceived(
+                    mContext.getString(R.string.wifi_status_suggestion_post_connect_bcast));
+        }
+
+        // Step 7: Remove the suggestions from the app.
+        if (DBG) Log.v(TAG, "Removing suggestion");
+        mListener.onTestMsgReceived(mContext.getString(R.string.wifi_status_suggestion_remove));
+        if (mWifiManager.removeNetworkSuggestions(mNetworkSuggestions)
+                != STATUS_NETWORK_SUGGESTIONS_SUCCESS) {
+            setFailureReason(mContext.getString(R.string.wifi_status_suggestion_remove_failure));
+            return false;
+        }
+
+        // Step 8: Ensure we don't disconnect immediately on suggestion removal.
+        mListener.onTestMsgReceived(
+                mContext.getString(R.string.wifi_status_suggestion_wait_for_disconnect));
+        if (DBG) Log.v(TAG, "Ensuring we don't disconnect immediately");
+        boolean cbStatusForLost = mNetworkCallback.waitForLost();
+        if (cbStatusForLost) {
+            Log.e(TAG, "Disconnected from the network immediately");
+            setFailureReason(mContext.getString(R.string.wifi_status_suggestion_disconnected));
+            return false;
+        }
+
+        // All done!
+        return true;
+    }
+
+    @Override
+    protected String getFailureReason() {
+        synchronized (mLock) {
+            return mFailureReason;
+        }
+    }
+
+    @Override
+    protected void setUp() {
+        super.setUp();
+        mConnectivityManager = ConnectivityManager.from(mContext);
+    }
+
+    @Override
+    protected void tearDown() {
+        if (mBroadcastReceiver != null) {
+            mContext.unregisterReceiver(mBroadcastReceiver);
+        }
+        mWifiManager.removeNetworkSuggestions(new ArrayList<>());
+        super.tearDown();
+    }
+}
diff --git a/apps/VpnApp/src/com/android/cts/vpnfirewall/ReflectorVpnService.java b/apps/VpnApp/src/com/android/cts/vpnfirewall/ReflectorVpnService.java
index 1397687..e7c4ffc 100755
--- a/apps/VpnApp/src/com/android/cts/vpnfirewall/ReflectorVpnService.java
+++ b/apps/VpnApp/src/com/android/cts/vpnfirewall/ReflectorVpnService.java
@@ -40,24 +40,28 @@
 import java.net.UnknownHostException;
 
 public class ReflectorVpnService extends VpnService {
-
     private static final String TAG = "ReflectorVpnService";
     private static final String DEVICE_AND_PROFILE_OWNER_PACKAGE =
         "com.android.cts.deviceandprofileowner";
     private static final String ACTION_VPN_IS_UP = "com.android.cts.vpnfirewall.VPN_IS_UP";
+    private static final String ACTION_VPN_ON_START = "com.android.cts.vpnfirewall.VPN_ON_START";
     private static final int NOTIFICATION_ID = 1;
     private static final String NOTIFICATION_CHANNEL_ID = TAG;
-    private static int MTU = 1799;
+    private static final int MTU = 1799;
 
     private ParcelFileDescriptor mFd = null;
     private PingReflector mPingReflector = null;
     private ConnectivityManager mConnectivityManager = null;
     private ConnectivityManager.NetworkCallback mNetworkCallback = null;
 
-    public static final String RESTRICTION_ADDRESSES = "vpn.addresses";
-    public static final String RESTRICTION_ROUTES = "vpn.routes";
-    public static final String RESTRICTION_ALLOWED = "vpn.allowed";
-    public static final String RESTRICTION_DISALLOWED = "vpn.disallowed";
+    private static final String RESTRICTION_ADDRESSES = "vpn.addresses";
+    private static final String RESTRICTION_ROUTES = "vpn.routes";
+    private static final String RESTRICTION_ALLOWED = "vpn.allowed";
+    private static final String RESTRICTION_DISALLOWED = "vpn.disallowed";
+    /** Service won't create the tunnel, to test lockdown behavior in case of VPN failure. */
+    private static final String RESTRICTION_DONT_ESTABLISH = "vpn.dont_establish";
+    private static final String EXTRA_ALWAYS_ON = "always-on";
+    private static final String EXTRA_LOCKDOWN = "lockdown";
 
     @Override
     public int onStartCommand(Intent intent, int flags, int startId) {
@@ -71,7 +75,7 @@
                 .setSmallIcon(R.drawable.ic_dialog_alert)
                 .build());
         start();
-        return START_REDELIVER_INTENT;
+        return START_NOT_STICKY;
     }
 
     @Override
@@ -95,6 +99,18 @@
     }
 
     private void start() {
+        final UserManager um = (UserManager) getSystemService(Context.USER_SERVICE);
+        final Bundle restrictions = um.getApplicationRestrictions(getPackageName());
+
+        final Intent intent = new Intent(ACTION_VPN_ON_START);
+        intent.setPackage(DEVICE_AND_PROFILE_OWNER_PACKAGE);
+        sendBroadcast(intent);
+
+        if (restrictions.getBoolean(RESTRICTION_DONT_ESTABLISH)) {
+            stopSelf();
+            return;
+        }
+
         VpnService.prepare(this);
 
         ensureNetworkCallbackUnregistered();
@@ -106,9 +122,11 @@
         mNetworkCallback = new ConnectivityManager.NetworkCallback() {
                 @Override
                 public void onAvailable(final Network net) {
-                    final Intent vpnIsUpIntent = new Intent(ACTION_VPN_IS_UP);
-                    vpnIsUpIntent.setPackage(DEVICE_AND_PROFILE_OWNER_PACKAGE);
-                    sendBroadcast(vpnIsUpIntent);
+                    final Intent intent = new Intent(ACTION_VPN_IS_UP);
+                    intent.setPackage(DEVICE_AND_PROFILE_OWNER_PACKAGE);
+                    intent.putExtra(EXTRA_ALWAYS_ON, isAlwaysOn());
+                    intent.putExtra(EXTRA_LOCKDOWN, isLockdownEnabled());
+                    sendBroadcast(intent);
                     ensureNetworkCallbackUnregistered();
                 }
             };
@@ -116,8 +134,6 @@
 
         Builder builder = new Builder();
 
-        final UserManager um = (UserManager) getSystemService(Context.USER_SERVICE);
-        final Bundle restrictions = um.getApplicationRestrictions(getPackageName());
 
         String[] addressArray = restrictions.getStringArray(RESTRICTION_ADDRESSES);
         if (addressArray == null) {
diff --git a/common/device-side/util/Android.bp b/common/device-side/util/Android.bp
index be5e520..134b4f7 100644
--- a/common/device-side/util/Android.bp
+++ b/common/device-side/util/Android.bp
@@ -27,6 +27,7 @@
         "ub-uiautomator",
         "mockito-target-minus-junit4",
         "androidx.annotation_annotation",
+        "truth-prebuilt",
     ],
 
     libs: [
diff --git a/common/device-side/util/OWNERS b/common/device-side/util/OWNERS
index 6eebe3b..b7726fc 100644
--- a/common/device-side/util/OWNERS
+++ b/common/device-side/util/OWNERS
@@ -9,3 +9,5 @@
 aaronholden@google.com
 yuji@google.com
 nickrose@google.com
+
+per-file *Android.bp=*
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/BroadcastTestBase.java b/common/device-side/util/src/com/android/compatibility/common/util/BroadcastTestBase.java
index bf5dc39..7500050 100644
--- a/common/device-side/util/src/com/android/compatibility/common/util/BroadcastTestBase.java
+++ b/common/device-side/util/src/com/android/compatibility/common/util/BroadcastTestBase.java
@@ -54,6 +54,8 @@
 
     @Override
     protected void tearDown() throws Exception {
+        Log.v(TAG, getClass().getSimpleName() + ".tearDown(): hasFeature=" + mHasFeature
+                + " receiver=" + mActivityDoneReceiver);
         if (mHasFeature && mActivityDoneReceiver != null) {
             try {
                 mContext.unregisterReceiver(mActivityDoneReceiver);
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/ColorUtils.java b/common/device-side/util/src/com/android/compatibility/common/util/ColorUtils.java
index cbb44c7..c0da13d 100644
--- a/common/device-side/util/src/com/android/compatibility/common/util/ColorUtils.java
+++ b/common/device-side/util/src/com/android/compatibility/common/util/ColorUtils.java
@@ -21,7 +21,9 @@
 import android.graphics.Color;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 
+import java.util.function.Function;
 import java.util.function.IntUnaryOperator;
 
 public class ColorUtils {
@@ -50,6 +52,11 @@
         String blue = verifyChannel("blue", expected, observed, tolerance, (i) -> Color.blue(i));
         String alpha = verifyChannel("alpha", expected, observed, tolerance, (i) -> Color.alpha(i));
 
+        buildErrorString(s, red, green, blue, alpha);
+    }
+
+    private static void buildErrorString(@NonNull String s, @Nullable String red,
+            @Nullable String green, @Nullable String blue, @Nullable String alpha) {
         String err = null;
         for (String channel : new String[]{red, green, blue, alpha}) {
             if (channel == null) continue;
@@ -71,4 +78,40 @@
         return "Channel " + channelName + " mismatch: expected<0x" + Integer.toHexString(e)
             + ">, observed: <0x" + Integer.toHexString(o) + ">";
     }
+
+    /**
+     * Verify that two colors match within a per-channel tolerance.
+     *
+     * @param msg String with extra information about the test with an error.
+     * @param expected Expected color.
+     * @param observed Observed color.
+     * @param tolerance Per-channel tolerance by which the color can mismatch.
+     */
+    public static void verifyColor(@NonNull String msg, Color expected, Color observed,
+            float tolerance) {
+        if (!expected.getColorSpace().equals(observed.getColorSpace())) {
+            fail("Cannot compare Colors with different color spaces! expected: " + expected
+                    + "\tobserved: " + observed);
+        }
+        msg += " expected " + expected + ", observed " + observed + ", tolerated channel error "
+            + tolerance;
+        String red = verifyChannel("red", expected, observed, tolerance, (c) -> c.red());
+        String green = verifyChannel("green", expected, observed, tolerance, (c) -> c.green());
+        String blue = verifyChannel("blue", expected, observed, tolerance, (c) -> c.blue());
+        String alpha = verifyChannel("alpha", expected, observed, tolerance, (c) -> c.alpha());
+
+        buildErrorString(msg, red, green, blue, alpha);
+    }
+
+    private static String verifyChannel(String channelName, Color expected, Color observed,
+            float tolerance, Function<Color, Float> f) {
+        float e = f.apply(expected);
+        float o = f.apply(observed);
+        float diff = Math.abs(e - o);
+        if (diff <= tolerance) {
+            return null;
+        }
+        return "Channel " + channelName + " mismatch: expected<" + e + ">, observed: <" + o
+            + ">, difference: <" + diff + ">";
+    }
 }
diff --git a/tests/inputmethod/src/android/view/inputmethod/cts/util/ImeAwareEditText.java b/common/device-side/util/src/com/android/compatibility/common/util/ImeAwareEditText.java
similarity index 98%
rename from tests/inputmethod/src/android/view/inputmethod/cts/util/ImeAwareEditText.java
rename to common/device-side/util/src/com/android/compatibility/common/util/ImeAwareEditText.java
index b48e750..db148bf 100644
--- a/tests/inputmethod/src/android/view/inputmethod/cts/util/ImeAwareEditText.java
+++ b/common/device-side/util/src/com/android/compatibility/common/util/ImeAwareEditText.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.view.inputmethod.cts.util;
+package com.android.compatibility.common.util;
 
 import android.content.Context;
 import android.util.AttributeSet;
diff --git a/tests/autofillservice/src/android/autofillservice/cts/common/OneTimeSettingsListener.java b/common/device-side/util/src/com/android/compatibility/common/util/OneTimeSettingsListener.java
similarity index 88%
rename from tests/autofillservice/src/android/autofillservice/cts/common/OneTimeSettingsListener.java
rename to common/device-side/util/src/com/android/compatibility/common/util/OneTimeSettingsListener.java
index 296ac21..79c80c9 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/common/OneTimeSettingsListener.java
+++ b/common/device-side/util/src/com/android/compatibility/common/util/OneTimeSettingsListener.java
@@ -14,13 +14,11 @@
  * limitations under the License.
  */
 
-package android.autofillservice.cts.common;
+package com.android.compatibility.common.util;
 
-import static android.autofillservice.cts.common.SettingsHelper.NAMESPACE_GLOBAL;
-import static android.autofillservice.cts.common.SettingsHelper.NAMESPACE_SECURE;
+import static com.android.compatibility.common.util.SettingsUtils.NAMESPACE_GLOBAL;
+import static com.android.compatibility.common.util.SettingsUtils.NAMESPACE_SECURE;
 
-import android.autofillservice.cts.JUnitHelper;
-import android.autofillservice.cts.RetryableException;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.database.ContentObserver;
@@ -87,7 +85,7 @@
             final long delta = SystemClock.elapsedRealtime() - mStarted;
             // TODO: usually it's notified in ~50-150ms, but for some reason it takes ~10s
             // on some ViewAttributesTest methods, hence the 30s limit
-            Log.v(TAG, JUnitHelper.getCurrentTestName() + "/" + mKey + ": " + delta + "ms");
+            Log.v(TAG, TestNameUtils.getCurrentTestName() + "/" + mKey + ": " + delta + "ms");
         } catch (InterruptedException e) {
             Thread.currentThread().interrupt();
             throw new IllegalStateException("Interrupted", e);
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/PropertyUtil.java b/common/device-side/util/src/com/android/compatibility/common/util/PropertyUtil.java
index 08fe441..b98acee 100644
--- a/common/device-side/util/src/com/android/compatibility/common/util/PropertyUtil.java
+++ b/common/device-side/util/src/com/android/compatibility/common/util/PropertyUtil.java
@@ -16,8 +16,6 @@
 
 package com.android.compatibility.common.util;
 
-import com.android.compatibility.common.util.SystemUtil;
-
 import android.os.Build;
 import android.support.test.InstrumentationRegistry;
 
diff --git a/tests/autofillservice/src/android/autofillservice/cts/RetryRule.java b/common/device-side/util/src/com/android/compatibility/common/util/RetryRule.java
similarity index 98%
rename from tests/autofillservice/src/android/autofillservice/cts/RetryRule.java
rename to common/device-side/util/src/com/android/compatibility/common/util/RetryRule.java
index e190cda..32dedea 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/RetryRule.java
+++ b/common/device-side/util/src/com/android/compatibility/common/util/RetryRule.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.autofillservice.cts;
+package com.android.compatibility.common.util;
 
 import android.util.Log;
 
diff --git a/tests/autofillservice/src/android/autofillservice/cts/RetryableException.java b/common/device-side/util/src/com/android/compatibility/common/util/RetryableException.java
similarity index 97%
rename from tests/autofillservice/src/android/autofillservice/cts/RetryableException.java
rename to common/device-side/util/src/com/android/compatibility/common/util/RetryableException.java
index 481409c..1c6c782 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/RetryableException.java
+++ b/common/device-side/util/src/com/android/compatibility/common/util/RetryableException.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.autofillservice.cts;
+package com.android.compatibility.common.util;
 
 import androidx.annotation.Nullable;
 
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/SafeCleanerRule.java b/common/device-side/util/src/com/android/compatibility/common/util/SafeCleanerRule.java
index 9c218d2..806884c 100644
--- a/common/device-side/util/src/com/android/compatibility/common/util/SafeCleanerRule.java
+++ b/common/device-side/util/src/com/android/compatibility/common/util/SafeCleanerRule.java
@@ -40,7 +40,7 @@
 
     private static final String TAG = "SafeCleanerRule";
 
-    private final List<Runnable> mCleaners = new ArrayList<>();
+    private final List<ThrowingRunnable> mCleaners = new ArrayList<>();
     private final List<Callable<List<Throwable>>> mExtraThrowables = new ArrayList<>();
     private final List<Throwable> mThrowables = new ArrayList<>();
     private Dumper mDumper;
@@ -48,7 +48,7 @@
     /**
      * Runs {@code cleaner} after the test is finished, catching any {@link Throwable} thrown by it.
      */
-    public SafeCleanerRule run(@NonNull Runnable cleaner) {
+    public SafeCleanerRule run(@NonNull ThrowingRunnable cleaner) {
         mCleaners.add(cleaner);
         return this;
     }
@@ -96,7 +96,7 @@
                 }
 
                 // Then the cleanup runners
-                for (Runnable runner : mCleaners) {
+                for (ThrowingRunnable runner : mCleaners) {
                     try {
                         runner.run();
                     } catch (Throwable t) {
@@ -108,7 +108,7 @@
                 // And finally add the extra exceptions
                 for (Callable<List<Throwable>> extraThrowablesCallable : mExtraThrowables) {
                     final List<Throwable> extraThrowables = extraThrowablesCallable.call();
-                    if (extraThrowables != null) {
+                    if (extraThrowables != null && !extraThrowables.isEmpty()) {
                         Log.w(TAG, "Adding " + extraThrowables.size() + " extra exceptions");
                         mThrowables.addAll(extraThrowables);
                     }
diff --git a/tests/autofillservice/src/android/autofillservice/cts/common/SettingsStateChangerRule.java b/common/device-side/util/src/com/android/compatibility/common/util/SettingsStateChangerRule.java
similarity index 93%
rename from tests/autofillservice/src/android/autofillservice/cts/common/SettingsStateChangerRule.java
rename to common/device-side/util/src/com/android/compatibility/common/util/SettingsStateChangerRule.java
index 5846dcf..3e0662a 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/common/SettingsStateChangerRule.java
+++ b/common/device-side/util/src/com/android/compatibility/common/util/SettingsStateChangerRule.java
@@ -13,10 +13,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package android.autofillservice.cts.common;
+package com.android.compatibility.common.util;
 
 import android.content.Context;
 import android.provider.Settings;
+
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
@@ -37,7 +38,7 @@
      */
     public SettingsStateChangerRule(@NonNull Context context, @NonNull String key,
             @Nullable String value) {
-        this(context, SettingsHelper.NAMESPACE_SECURE, key, value);
+        this(context, SettingsUtils.NAMESPACE_SECURE, key, value);
     }
 
     /**
diff --git a/tests/autofillservice/src/android/autofillservice/cts/common/SettingsStateKeeperRule.java b/common/device-side/util/src/com/android/compatibility/common/util/SettingsStateKeeperRule.java
similarity index 89%
rename from tests/autofillservice/src/android/autofillservice/cts/common/SettingsStateKeeperRule.java
rename to common/device-side/util/src/com/android/compatibility/common/util/SettingsStateKeeperRule.java
index 5b527bb..18ca88a 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/common/SettingsStateKeeperRule.java
+++ b/common/device-side/util/src/com/android/compatibility/common/util/SettingsStateKeeperRule.java
@@ -13,10 +13,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package android.autofillservice.cts.common;
+package com.android.compatibility.common.util;
 
 import android.content.Context;
 import android.provider.Settings;
+
 import androidx.annotation.NonNull;
 
 /**
@@ -33,6 +34,6 @@
      * @param key prefence key.
      */
     public SettingsStateKeeperRule(@NonNull Context context, @NonNull String key) {
-        super(new SettingsStateManager(context, SettingsHelper.NAMESPACE_SECURE, key));
+        super(new SettingsStateManager(context, SettingsUtils.NAMESPACE_SECURE, key));
     }
 }
diff --git a/tests/autofillservice/src/android/autofillservice/cts/common/SettingsStateManager.java b/common/device-side/util/src/com/android/compatibility/common/util/SettingsStateManager.java
similarity index 91%
rename from tests/autofillservice/src/android/autofillservice/cts/common/SettingsStateManager.java
rename to common/device-side/util/src/com/android/compatibility/common/util/SettingsStateManager.java
index 37f557b..bab06a6 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/common/SettingsStateManager.java
+++ b/common/device-side/util/src/com/android/compatibility/common/util/SettingsStateManager.java
@@ -14,10 +14,11 @@
  * limitations under the License.
  */
 
-package android.autofillservice.cts.common;
+package com.android.compatibility.common.util;
 
 import android.content.Context;
 import android.provider.Settings;
+
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
@@ -48,13 +49,13 @@
 
     @Override
     public void set(@Nullable String value) {
-        SettingsHelper.syncSet(mContext, mNamespace, mKey, value);
+        SettingsUtils.syncSet(mContext, mNamespace, mKey, value);
     }
 
     @Override
     @Nullable
     public String get() {
-        return SettingsHelper.get(mNamespace, mKey);
+        return SettingsUtils.get(mNamespace, mKey);
     }
 
     @Override
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/SettingsUtils.java b/common/device-side/util/src/com/android/compatibility/common/util/SettingsUtils.java
index c34cb60..470d3df 100644
--- a/common/device-side/util/src/com/android/compatibility/common/util/SettingsUtils.java
+++ b/common/device-side/util/src/com/android/compatibility/common/util/SettingsUtils.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2017 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.
@@ -13,25 +13,162 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package com.android.compatibility.common.util;
 
-public class SettingsUtils {
+import static com.android.compatibility.common.util.ShellUtils.runShellCommand;
+
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import android.content.Context;
+import android.provider.Settings;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+/**
+ * Provides utilities to interact with the device's {@link Settings}.
+ */
+public final class SettingsUtils {
+
+    public static final String NAMESPACE_SECURE = "secure";
+    public static final String NAMESPACE_GLOBAL = "global";
+
+    /**
+     * Uses a Shell command to set the given preference.
+     */
+    public static void set(@NonNull String namespace, @NonNull String key, @Nullable String value) {
+        if (value == null) {
+            delete(namespace, key);
+            return;
+        }
+        runShellCommand("settings put %s %s %s default", namespace, key, value);
+    }
+
+    /**
+     * Sets a preference in the {@link #NAMESPACE_SECURE} namespace.
+     */
+    public static void set(@NonNull String key, @Nullable String value) {
+        set(NAMESPACE_SECURE, key, value);
+    }
+
+    /**
+     * Uses a Shell command to set the given preference, and verifies it was correctly set.
+     */
+    public static void syncSet(@NonNull Context context, @NonNull String namespace,
+            @NonNull String key, @Nullable String value) {
+        if (value == null) {
+            syncDelete(context, namespace, key);
+            return;
+        }
+
+        final String currentValue = get(namespace, key);
+        if (value.equals(currentValue)) {
+            // Already set, ignore
+            return;
+        }
+
+        final OneTimeSettingsListener observer =
+                new OneTimeSettingsListener(context, namespace, key);
+        set(namespace, key, value);
+        observer.assertCalled();
+
+        final String newValue = get(namespace, key);
+        assertWithMessage("invalid value for '%s' settings", key).that(newValue).isEqualTo(value);
+    }
+
+    /**
+     * Sets a preference in the {@link #NAMESPACE_SECURE} namespace, using a Settings listener to
+     * block until it's set.
+     */
+    public static void syncSet(@NonNull Context context, @NonNull String key,
+            @Nullable String value) {
+        syncSet(context, NAMESPACE_SECURE, key, value);
+    }
+
+    /**
+     * Uses a Shell command to delete the given preference.
+     */
+    public static void delete(@NonNull String namespace, @NonNull String key) {
+        runShellCommand("settings delete %s %s", namespace, key);
+    }
+
+    /**
+     * Deletes a preference in the {@link #NAMESPACE_SECURE} namespace.
+     */
+    public static void delete(@NonNull String key) {
+        delete(NAMESPACE_SECURE, key);
+    }
+
+    /**
+     * Uses a Shell command to delete the given preference, and verifies it was correctly deleted.
+     */
+    public static void syncDelete(@NonNull Context context, @NonNull String namespace,
+            @NonNull String key) {
+
+        final String currentValue = get(namespace, key);
+        if (currentValue == null) {
+            // Already set, ignore
+            return;
+        }
+
+        final OneTimeSettingsListener observer = new OneTimeSettingsListener(context, namespace,
+                key);
+        delete(namespace, key);
+        observer.assertCalled();
+
+        final String newValue = get(namespace, key);
+        assertWithMessage("invalid value for '%s' settings", key).that(newValue).isNull();
+    }
+
+    /**
+     * Deletes a preference in the {@link #NAMESPACE_SECURE} namespace, using a Settings listener to
+     * block until it's deleted.
+     */
+    public static void syncDelete(@NonNull Context context, @NonNull String key) {
+        syncDelete(context, NAMESPACE_SECURE, key);
+    }
+
+    /**
+     * Gets the value of a given preference using Shell command.
+     */
+    @Nullable
+    public static String get(@NonNull String namespace, @NonNull String key) {
+        final String value = runShellCommand("settings get %s %s", namespace, key);
+        if (value == null || value.equals("null")) {
+            return null;
+        } else {
+            return value;
+        }
+    }
+
+    /**
+     * Gets the value of a preference in the {@link #NAMESPACE_SECURE} namespace.
+     */
+    @NonNull
+    public static String get(@NonNull String key) {
+        return get(NAMESPACE_SECURE, key);
+    }
+
     private SettingsUtils() {
+        throw new UnsupportedOperationException("contain static methods only");
     }
 
     /**
-     * Put a global setting.
+     * @deprecated - use {@link #set(String, String, String)} with {@link #NAMESPACE_GLOBAL}
      */
+    @Deprecated
     public static void putGlobalSetting(String key, String value) {
-        // Hmm, technically we should escape a value, but if I do like '1', it won't work. ??
-        SystemUtil.runShellCommandForNoOutput("settings put global " + key + " " + value);
+        set(SettingsUtils.NAMESPACE_GLOBAL, key, value);
+
     }
 
     /**
-     * Put a global setting for the current (foreground) user.
+     * @deprecated - use {@link #set(String, String, String)} with {@link #NAMESPACE_GLOBAL}
      */
+    @Deprecated
     public static void putSecureSetting(String key, String value) {
-        SystemUtil.runShellCommandForNoOutput(
-                "settings --user current put secure " + key + " " + value);
+        set(SettingsUtils.NAMESPACE_SECURE, key, value);
+
     }
 }
diff --git a/tests/autofillservice/src/android/autofillservice/cts/common/ShellHelper.java b/common/device-side/util/src/com/android/compatibility/common/util/ShellUtils.java
similarity index 90%
rename from tests/autofillservice/src/android/autofillservice/cts/common/ShellHelper.java
rename to common/device-side/util/src/com/android/compatibility/common/util/ShellUtils.java
index 117c755..8cb3290 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/common/ShellHelper.java
+++ b/common/device-side/util/src/com/android/compatibility/common/util/ShellUtils.java
@@ -14,9 +14,9 @@
  * limitations under the License.
  */
 
-package android.autofillservice.cts.common;
+package com.android.compatibility.common.util;
 
-import static android.autofillservice.cts.common.ShellHelper.runShellCommand;
+import static com.android.compatibility.common.util.ShellUtils.runShellCommand;
 
 import android.support.test.InstrumentationRegistry;
 import android.text.TextUtils;
@@ -25,12 +25,10 @@
 
 import androidx.annotation.NonNull;
 
-import com.android.compatibility.common.util.SystemUtil;
-
 /**
  * Provides Shell-based utilities such as running a command.
  */
-public final class ShellHelper {
+public final class ShellUtils {
 
     private static final String TAG = "ShellHelper";
 
@@ -65,7 +63,7 @@
     }
 
 
-    private ShellHelper() {
+    private ShellUtils() {
         throw new UnsupportedOperationException("contain static methods only");
     }
 
diff --git a/tests/autofillservice/src/android/autofillservice/cts/common/StateChangerRule.java b/common/device-side/util/src/com/android/compatibility/common/util/StateChangerRule.java
similarity index 96%
rename from tests/autofillservice/src/android/autofillservice/cts/common/StateChangerRule.java
rename to common/device-side/util/src/com/android/compatibility/common/util/StateChangerRule.java
index 7445ff4..4e59f13 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/common/StateChangerRule.java
+++ b/common/device-side/util/src/com/android/compatibility/common/util/StateChangerRule.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.autofillservice.cts.common;
+package com.android.compatibility.common.util;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
@@ -32,6 +32,8 @@
  *
  * <p>It stores the current state before the test, changes it (if necessary), then restores it after
  * the test (if necessary).
+ *
+ * @param <T> value type
  */
 public class StateChangerRule<T> implements TestRule {
 
diff --git a/tests/autofillservice/src/android/autofillservice/cts/common/StateKeeperRule.java b/common/device-side/util/src/com/android/compatibility/common/util/StateKeeperRule.java
similarity index 96%
rename from tests/autofillservice/src/android/autofillservice/cts/common/StateKeeperRule.java
rename to common/device-side/util/src/com/android/compatibility/common/util/StateKeeperRule.java
index 9784db5..ecc02a2 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/common/StateKeeperRule.java
+++ b/common/device-side/util/src/com/android/compatibility/common/util/StateKeeperRule.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.autofillservice.cts.common;
+package com.android.compatibility.common.util;
 
 import androidx.annotation.NonNull;
 
@@ -30,6 +30,8 @@
  * JUnit rule used to restore a state after the test is run.
  *
  * <p>It stores the current state before the test, and restores it after the test (if necessary).
+ *
+ * @param <T> value type
  */
 public class StateKeeperRule<T> implements TestRule {
 
diff --git a/tests/autofillservice/src/android/autofillservice/cts/common/StateManager.java b/common/device-side/util/src/com/android/compatibility/common/util/StateManager.java
similarity index 92%
rename from tests/autofillservice/src/android/autofillservice/cts/common/StateManager.java
rename to common/device-side/util/src/com/android/compatibility/common/util/StateManager.java
index e16716b..2077e08 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/common/StateManager.java
+++ b/common/device-side/util/src/com/android/compatibility/common/util/StateManager.java
@@ -13,12 +13,14 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package android.autofillservice.cts.common;
+package com.android.compatibility.common.util;
 
 import androidx.annotation.Nullable;
 
 /**
  * Abstraction for a state that is managed somewhere, like Android Settings.
+ *
+ * @param <T> value type
  */
 public interface StateManager<T> {
 
diff --git a/tests/autofillservice/src/android/autofillservice/cts/JUnitHelper.java b/common/device-side/util/src/com/android/compatibility/common/util/TestNameUtils.java
similarity index 71%
rename from tests/autofillservice/src/android/autofillservice/cts/JUnitHelper.java
rename to common/device-side/util/src/com/android/compatibility/common/util/TestNameUtils.java
index 2920500..2dbeaab 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/JUnitHelper.java
+++ b/common/device-side/util/src/com/android/compatibility/common/util/TestNameUtils.java
@@ -14,19 +14,24 @@
  * limitations under the License.
  */
 
-package android.autofillservice.cts;
+package com.android.compatibility.common.util;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
 /**
- * Generic helper for JUnit needs.
+ * Generic helper used to set / get the the name of the test being run.
+ *
+ * <p>Typically used on {@code @Rule} classes.
  */
-public final class JUnitHelper {
+public final class TestNameUtils {
 
     private static String sCurrentTestName;
     private static String sCurrentTestClass;
 
+    /**
+     * Gets the name of the test current running.
+     */
     @NonNull
     public static String getCurrentTestName() {
         if (sCurrentTestName != null) return sCurrentTestName;
@@ -34,19 +39,29 @@
         return "(Unknown test)";
     }
 
+    /**
+     * Sets the name of the test current running
+     */
     public static void setCurrentTestName(@Nullable String name) {
         sCurrentTestName = name;
     }
 
+    /**
+     * Sets the name of the test class current running
+     */
     public static void setCurrentTestClass(@Nullable String testClass) {
         sCurrentTestClass = testClass;
     }
 
+    /**
+     * Checks whether a test is running, based on whether {@link #setCurrentTestName(String)} was
+     * called.
+     */
     public static boolean isRunningTest() {
         return sCurrentTestName != null;
     }
 
-    private JUnitHelper() {
+    private TestNameUtils() {
         throw new UnsupportedOperationException("contain static methods only");
     }
 }
diff --git a/tests/autofillservice/src/android/autofillservice/cts/Timeout.java b/common/device-side/util/src/com/android/compatibility/common/util/Timeout.java
similarity index 96%
rename from tests/autofillservice/src/android/autofillservice/cts/Timeout.java
rename to common/device-side/util/src/com/android/compatibility/common/util/Timeout.java
index d442cda..9ac6323 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/Timeout.java
+++ b/common/device-side/util/src/com/android/compatibility/common/util/Timeout.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package android.autofillservice.cts;
+package com.android.compatibility.common.util;
 
 import android.os.SystemClock;
 import android.text.TextUtils;
@@ -76,7 +76,7 @@
         mCurrentValue = initialValue;
         mMultiplier = multiplier;
         mMaxValue = maxValue;
-        Log.d(TAG, "Constructor: " + this + " at " + JUnitHelper.getCurrentTestName());
+        Log.d(TAG, "Constructor: " + this + " at " + TestNameUtils.getCurrentTestName());
     }
 
     /**
@@ -118,7 +118,7 @@
         mCurrentValue = Math.min(mMaxValue, (long) (mCurrentValue * mMultiplier));
         if (oldValue != mCurrentValue) {
             Log.w(TAG, mName + " increased from " + oldValue + "ms to " + mCurrentValue + "ms at "
-                    + JUnitHelper.getCurrentTestName());
+                    + TestNameUtils.getCurrentTestName());
         }
         return oldValue;
     }
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/WidgetTestUtils.java b/common/device-side/util/src/com/android/compatibility/common/util/WidgetTestUtils.java
index 3d98c56..a80d8bb 100644
--- a/common/device-side/util/src/com/android/compatibility/common/util/WidgetTestUtils.java
+++ b/common/device-side/util/src/com/android/compatibility/common/util/WidgetTestUtils.java
@@ -39,7 +39,8 @@
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
-import static android.view.ViewTreeObserver.*;
+import static android.view.ViewTreeObserver.OnDrawListener;
+import static android.view.ViewTreeObserver.OnGlobalLayoutListener;
 import static org.mockito.hamcrest.MockitoHamcrest.argThat;
 
 /**
diff --git a/tests/autofillservice/src/android/autofillservice/cts/RetryRuleTest.java b/common/device-side/util/tests/src/com/android/compatibility/common/util/RetryRuleTest.java
similarity index 96%
rename from tests/autofillservice/src/android/autofillservice/cts/RetryRuleTest.java
rename to common/device-side/util/tests/src/com/android/compatibility/common/util/RetryRuleTest.java
index 0c23f9f..644d95f 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/RetryRuleTest.java
+++ b/common/device-side/util/tests/src/com/android/compatibility/common/util/RetryRuleTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.autofillservice.cts;
+package com.android.compatibility.common.util;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -24,8 +24,6 @@
 import static org.testng.Assert.assertThrows;
 import static org.testng.Assert.expectThrows;
 
-import android.platform.test.annotations.AppModeFull;
-
 import org.junit.Test;
 import org.junit.runner.Description;
 import org.junit.runner.RunWith;
@@ -34,7 +32,6 @@
 import org.mockito.junit.MockitoJUnitRunner;
 
 @RunWith(MockitoJUnitRunner.class)
-@AppModeFull // Unit test
 public class RetryRuleTest {
 
     private final Description mDescription = Description.createSuiteDescription("Whatever");
@@ -54,7 +51,7 @@
 
         @Override
         public void evaluate() throws Throwable {
-            mNumberCalls ++;
+            mNumberCalls++;
             if (mNumberCalls <= mNumberFailures) {
                 throw mException;
             }
diff --git a/common/device-side/util/tests/src/com/android/compatibility/common/util/SafeCleanerRuleTest.java b/common/device-side/util/tests/src/com/android/compatibility/common/util/SafeCleanerRuleTest.java
index 99ea3c0..a56d7b2 100644
--- a/common/device-side/util/tests/src/com/android/compatibility/common/util/SafeCleanerRuleTest.java
+++ b/common/device-side/util/tests/src/com/android/compatibility/common/util/SafeCleanerRuleTest.java
@@ -58,8 +58,8 @@
     @Mock private Dumper mDumper;
 
     // Use mocks for objects that don't throw any exception.
-    @Mock private Runnable mGoodGuyRunner1;
-    @Mock private Runnable mGoodGuyRunner2;
+    @Mock private ThrowingRunnable mGoodGuyRunner1;
+    @Mock private ThrowingRunnable mGoodGuyRunner2;
     @Mock private Callable<List<Throwable>> mGoodGuyExtraExceptions1;
     @Mock private Callable<List<Throwable>> mGoodGuyExtraExceptions2;
     @Mock private Statement mGoodGuyStatement;
@@ -261,6 +261,7 @@
         final Exception extra1 = new Exception("1");
         final Exception extra2 = new Exception("2");
         final Exception extra3 = new Exception("3");
+        final Exception extra4 = new Exception("4");
         final Error error1 = new Error("one");
         final Error error2 = new Error("two");
         final RuntimeException testException  = new RuntimeException("TEST, Y U NO PASS?");
@@ -277,13 +278,18 @@
                 .run(mGoodGuyRunner2)
                 .add(() -> { return ImmutableList.of(extra3); })
                 .add(mGoodGuyExtraExceptions2)
-                .run(() -> { throw error2; });
+                .run(() -> {
+                    throw error2;
+                })
+                .run(() -> {
+                    throw extra4;
+                });
 
         final SafeCleanerRule.MultipleExceptions actualException = expectThrows(
                 SafeCleanerRule.MultipleExceptions.class,
                 () -> rule.apply(new FailureStatement(testException), mDescription).evaluate());
         assertThat(actualException.getThrowables())
-                .containsExactly(testException, error1, error2, extra1, extra2, extra3)
+                .containsExactly(testException, error1, error2, extra4, extra1, extra2, extra3)
                 .inOrder();
         verify(mGoodGuyRunner1).run();
         verify(mGoodGuyRunner2).run();
diff --git a/tests/autofillservice/src/android/autofillservice/cts/common/StateChangerRuleTest.java b/common/device-side/util/tests/src/com/android/compatibility/common/util/StateChangerRuleTest.java
similarity index 97%
rename from tests/autofillservice/src/android/autofillservice/cts/common/StateChangerRuleTest.java
rename to common/device-side/util/tests/src/com/android/compatibility/common/util/StateChangerRuleTest.java
index 6604cf4..9b1851e 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/common/StateChangerRuleTest.java
+++ b/common/device-side/util/tests/src/com/android/compatibility/common/util/StateChangerRuleTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.autofillservice.cts.common;
+package com.android.compatibility.common.util;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -28,8 +28,6 @@
 import static org.testng.Assert.assertThrows;
 import static org.testng.Assert.expectThrows;
 
-import android.platform.test.annotations.AppModeFull;
-
 import org.junit.Test;
 import org.junit.runner.Description;
 import org.junit.runner.RunWith;
@@ -38,7 +36,6 @@
 import org.mockito.junit.MockitoJUnitRunner;
 
 @RunWith(MockitoJUnitRunner.class)
-@AppModeFull // Unit test
 public class StateChangerRuleTest {
 
     private final RuntimeException mRuntimeException = new RuntimeException("D'OH");
diff --git a/tests/autofillservice/src/android/autofillservice/cts/common/StateKeeperRuleTest.java b/common/device-side/util/tests/src/com/android/compatibility/common/util/StateKeeperRuleTest.java
similarity index 96%
rename from tests/autofillservice/src/android/autofillservice/cts/common/StateKeeperRuleTest.java
rename to common/device-side/util/tests/src/com/android/compatibility/common/util/StateKeeperRuleTest.java
index 97db0a7..4599aca 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/common/StateKeeperRuleTest.java
+++ b/common/device-side/util/tests/src/com/android/compatibility/common/util/StateKeeperRuleTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.autofillservice.cts.common;
+package com.android.compatibility.common.util;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -28,8 +28,6 @@
 import static org.testng.Assert.assertThrows;
 import static org.testng.Assert.expectThrows;
 
-import android.platform.test.annotations.AppModeFull;
-
 import org.junit.Test;
 import org.junit.runner.Description;
 import org.junit.runner.RunWith;
@@ -38,7 +36,6 @@
 import org.mockito.junit.MockitoJUnitRunner;
 
 @RunWith(MockitoJUnitRunner.class)
-@AppModeFull // Unit test
 public class StateKeeperRuleTest {
 
     private final RuntimeException mRuntimeException = new RuntimeException("D'OH");
diff --git a/tests/autofillservice/src/android/autofillservice/cts/TimeoutTest.java b/common/device-side/util/tests/src/com/android/compatibility/common/util/TimeoutTest.java
similarity index 94%
rename from tests/autofillservice/src/android/autofillservice/cts/TimeoutTest.java
rename to common/device-side/util/tests/src/com/android/compatibility/common/util/TimeoutTest.java
index 9b3decc..8992d18 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/TimeoutTest.java
+++ b/common/device-side/util/tests/src/com/android/compatibility/common/util/TimeoutTest.java
@@ -14,9 +14,7 @@
  * limitations under the License.
  */
 
-package android.autofillservice.cts;
-
-import static android.autofillservice.cts.Helper.assertFloat;
+package com.android.compatibility.common.util;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -24,9 +22,10 @@
 import static org.testng.Assert.assertThrows;
 import static org.testng.Assert.expectThrows;
 
-import android.autofillservice.cts.Timeout.Sleeper;
 import android.os.SystemClock;
 
+import com.android.compatibility.common.util.Timeout.Sleeper;
+
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
@@ -140,4 +139,8 @@
             totalSleepingTime += napTimeMs;
         }
     }
+
+    public static void assertFloat(float actualValue, float expectedValue) {
+        assertThat(actualValue).isWithin(1.0e-10f).of(expectedValue);
+    }
 }
diff --git a/hostsidetests/appbinding/app/app1/AndroidManifest.xml b/hostsidetests/appbinding/app/app1/AndroidManifest.xml
index b3b55e8..b2c49db 100644
--- a/hostsidetests/appbinding/app/app1/AndroidManifest.xml
+++ b/hostsidetests/appbinding/app/app1/AndroidManifest.xml
@@ -31,9 +31,9 @@
             android:name=".MyService"
             android:exported="true"
             android:process=":persistent"
-            android:permission="android.permission.BIND_SMS_APP_SERVICE">
+            android:permission="android.permission.BIND_CARRIER_MESSAGING_CLIENT_SERVICE">
             <intent-filter>
-                <action android:name="android.telephony.action.SMS_APP_SERVICE" />
+                <action android:name="android.telephony.action.CARRIER_MESSAGING_CLIENT_SERVICE" />
             </intent-filter>
         </service>
 
diff --git a/hostsidetests/appbinding/app/app2/AndroidManifest.xml b/hostsidetests/appbinding/app/app2/AndroidManifest.xml
index 7890c6f..7be1599 100644
--- a/hostsidetests/appbinding/app/app2/AndroidManifest.xml
+++ b/hostsidetests/appbinding/app/app2/AndroidManifest.xml
@@ -31,9 +31,9 @@
             android:name=".MyService2"
             android:exported="false"
             android:process=":persistent"
-            android:permission="android.permission.BIND_SMS_APP_SERVICE" >
+            android:permission="android.permission.BIND_CARRIER_MESSAGING_CLIENT_SERVICE" >
             <intent-filter>
-                <action android:name="android.telephony.action.SMS_APP_SERVICE" />
+                <action android:name="android.telephony.action.CARRIER_MESSAGING_CLIENT_SERVICE" />
             </intent-filter>
         </service>
 
diff --git a/hostsidetests/appbinding/app/app3/AndroidManifest.xml b/hostsidetests/appbinding/app/app3/AndroidManifest.xml
index ec7a4bf..52080ee 100644
--- a/hostsidetests/appbinding/app/app3/AndroidManifest.xml
+++ b/hostsidetests/appbinding/app/app3/AndroidManifest.xml
@@ -32,7 +32,7 @@
             android:exported="false"
             android:process=":persistent">
             <intent-filter>
-                <action android:name="android.telephony.action.SMS_APP_SERVICE" />
+                <action android:name="android.telephony.action.CARRIER_MESSAGING_CLIENT_SERVICE" />
             </intent-filter>
         </service>
 
diff --git a/hostsidetests/appbinding/app/app4/AndroidManifest.xml b/hostsidetests/appbinding/app/app4/AndroidManifest.xml
index 5df5fa8..560c4c1 100644
--- a/hostsidetests/appbinding/app/app4/AndroidManifest.xml
+++ b/hostsidetests/appbinding/app/app4/AndroidManifest.xml
@@ -31,18 +31,18 @@
             android:name=".MyService"
             android:exported="true"
             android:process=":persistent"
-            android:permission="android.permission.BIND_SMS_APP_SERVICE" >
+            android:permission="android.permission.BIND_CARRIER_MESSAGING_CLIENT_SERVICE" >
             <intent-filter>
-                <action android:name="android.telephony.action.SMS_APP_SERVICE" />
+                <action android:name="android.telephony.action.CARRIER_MESSAGING_CLIENT_SERVICE" />
             </intent-filter>
         </service>
         <service
             android:name=".MyService2"
             android:exported="true"
             android:process=":persistent"
-            android:permission="android.permission.BIND_SMS_APP_SERVICE" >
+            android:permission="android.permission.BIND_CARRIER_MESSAGING_CLIENT_SERVICE" >
             <intent-filter>
-                <action android:name="android.telephony.action.SMS_APP_SERVICE" />
+                <action android:name="android.telephony.action.CARRIER_MESSAGING_CLIENT_SERVICE" />
             </intent-filter>
         </service>
 
diff --git a/hostsidetests/appbinding/app/app6/AndroidManifest.xml b/hostsidetests/appbinding/app/app6/AndroidManifest.xml
index abea148..cf704d7 100644
--- a/hostsidetests/appbinding/app/app6/AndroidManifest.xml
+++ b/hostsidetests/appbinding/app/app6/AndroidManifest.xml
@@ -30,9 +30,9 @@
         <service
             android:name=".MyService2"
             android:exported="false"
-            android:permission="android.permission.BIND_SMS_APP_SERVICE" >
+            android:permission="android.permission.BIND_CARRIER_MESSAGING_CLIENT_SERVICE" >
             <intent-filter>
-                <action android:name="android.telephony.action.SMS_APP_SERVICE" />
+                <action android:name="android.telephony.action.CARRIER_MESSAGING_CLIENT_SERVICE" />
             </intent-filter>
         </service>
 
diff --git a/hostsidetests/appbinding/app/appb/AndroidManifest.xml b/hostsidetests/appbinding/app/appb/AndroidManifest.xml
index 3a1c5d3..e6336a6 100644
--- a/hostsidetests/appbinding/app/appb/AndroidManifest.xml
+++ b/hostsidetests/appbinding/app/appb/AndroidManifest.xml
@@ -31,9 +31,9 @@
             android:name="com.android.cts.appbinding.app.MyService"
             android:exported="true"
             android:process=":persistent"
-            android:permission="android.permission.BIND_SMS_APP_SERVICE" >
+            android:permission="android.permission.BIND_CARRIER_MESSAGING_CLIENT_SERVICE" >
             <intent-filter>
-                <action android:name="android.telephony.action.SMS_APP_SERVICE" />
+                <action android:name="android.telephony.action.CARRIER_MESSAGING_CLIENT_SERVICE" />
             </intent-filter>
         </service>
 
diff --git a/hostsidetests/appbinding/app/src/com/android/cts/appbinding/app/MyService.java b/hostsidetests/appbinding/app/src/com/android/cts/appbinding/app/MyService.java
index 5df2fa9..9a569f3 100644
--- a/hostsidetests/appbinding/app/src/com/android/cts/appbinding/app/MyService.java
+++ b/hostsidetests/appbinding/app/src/com/android/cts/appbinding/app/MyService.java
@@ -15,12 +15,12 @@
  */
 package com.android.cts.appbinding.app;
 
-import android.app.SmsAppService;
+import android.service.carrier.CarrierMessagingClientService;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 
-public class MyService extends SmsAppService {
+public class MyService extends CarrierMessagingClientService {
     @Override
     protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
 
@@ -31,6 +31,6 @@
             return;
         }
         writer.print("Package=[" + getPackageName() + "]");
-        writer.println("Class=[" + this.getClass().getName() + "]");
+        writer.println(" Class=[" + this.getClass().getName() + "]");
     }
 }
diff --git a/hostsidetests/appbinding/hostside/src/com/android/cts/appbinding/AppBindingHostTest.java b/hostsidetests/appbinding/hostside/src/com/android/cts/appbinding/AppBindingHostTest.java
index dd4c438..5c37e01 100644
--- a/hostsidetests/appbinding/hostside/src/com/android/cts/appbinding/AppBindingHostTest.java
+++ b/hostsidetests/appbinding/hostside/src/com/android/cts/appbinding/AppBindingHostTest.java
@@ -321,7 +321,7 @@
      */
     public void testSimpleNotBound3() throws Throwable {
         installAndCheckNotBound(APK_3, PACKAGE_A, USER_SYSTEM,
-                "must be protected with android.permission.BIND_SMS_APP_SERVICE");
+                "must be protected with android.permission.BIND_CARRIER_MESSAGING_CLIENT_SERVICE");
     }
 
     /**
@@ -336,7 +336,7 @@
      */
     public void testSimpleNotBound5() throws Throwable {
         installAndCheckNotBound(APK_5, PACKAGE_A, USER_SYSTEM,
-                "Service with android.telephony.action.SMS_APP_SERVICE not found");
+                "Service with android.telephony.action.CARRIER_MESSAGING_CLIENT_SERVICE not found");
     }
 
     /**
@@ -355,7 +355,7 @@
         installAndCheckBound(APK_1, PACKAGE_A, SERVICE_1, USER_SYSTEM);
         installAndCheckBound(APK_2, PACKAGE_A, SERVICE_2, USER_SYSTEM);
         installAndCheckNotBound(APK_3, PACKAGE_A, USER_SYSTEM,
-                "must be protected with android.permission.BIND_SMS_APP_SERVICE");
+                "must be protected with android.permission.BIND_CARRIER_MESSAGING_CLIENT_SERVICE");
         installAndCheckBound(APK_1, PACKAGE_A, SERVICE_1, USER_SYSTEM);
         installAndCheckNotBound(APK_4, PACKAGE_A, USER_SYSTEM, "More than one");
     }
@@ -398,7 +398,7 @@
 
             // Replace the app on the primary user with an invalid one.
             installAndCheckNotBound(APK_3, PACKAGE_A, USER_SYSTEM,
-                    "must be protected with android.permission.BIND_SMS_APP_SERVICE");
+                    "must be protected with android.permission.BIND_CARRIER_MESSAGING_CLIENT_SERVICE");
 
             // Secondary user should still have a valid connection.
             checkBound(PACKAGE_B, SERVICE_1, userId);
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/UseEmbeddedDexTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/UseEmbeddedDexTest.java
new file mode 100644
index 0000000..78f0fef
--- /dev/null
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/UseEmbeddedDexTest.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2019 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.appsecurity.cts;
+
+import android.platform.test.annotations.AppModeFull;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+@AppModeFull
+public final class UseEmbeddedDexTest extends BaseAppSecurityTest {
+
+    private static final String PACKAGE_NAME = "com.android.cts.useembeddeddex";
+    private static final String APK_CANONICAL = "CtsUseEmbeddedDexApp_Canonical.apk";
+    private static final String APK_DEX_COMPRESSED = "CtsUseEmbeddedDexApp_DexCompressed.apk";
+    private static final String APK_SPLIT_CANONICAL =
+            "CtsUseEmbeddedDexAppSplit_Canonical.apk";
+    private static final String APK_SPLIT_COMPRESSED_DEX =
+            "CtsUseEmbeddedDexAppSplit_CompressedDex.apk";
+
+    @Test
+    public void testCanonicalInstall() throws Exception {
+        new InstallMultiple().addApk(APK_CANONICAL).run();
+    }
+
+    @Test
+    public void testBadInstallWithCompressedDex() throws Exception {
+        new InstallMultiple().addApk(APK_DEX_COMPRESSED).runExpectingFailure();
+    }
+
+    @Test
+    public void testCanonicalInstallWithSplit() throws Exception {
+        new InstallMultiple().addApk(APK_CANONICAL).addApk(APK_SPLIT_CANONICAL).run();
+    }
+
+    @Test
+    public void testBadInstallWithDexCompressedSplit() throws Exception {
+        new InstallMultiple().addApk(APK_CANONICAL).addApk(APK_SPLIT_COMPRESSED_DEX)
+                .runExpectingFailure();
+    }
+
+    @Test
+    public void testCanonicalInstallWithBaseThenSplit() throws Exception {
+        new InstallMultiple().addApk(APK_CANONICAL).run();
+        new InstallMultiple().inheritFrom(PACKAGE_NAME).addApk(APK_SPLIT_CANONICAL).run();
+    }
+
+    @Test
+    public void testBadInstallWithBaseThenDexCompressedSplit() throws Exception {
+        new InstallMultiple().addApk(APK_CANONICAL).run();
+        new InstallMultiple().inheritFrom(PACKAGE_NAME).addApk(APK_SPLIT_COMPRESSED_DEX)
+                .runExpectingFailure();
+    }
+}
diff --git a/hostsidetests/appsecurity/test-apps/ClassLoaderSplitApp/Android.mk b/hostsidetests/appsecurity/test-apps/ClassLoaderSplitApp/Android.mk
deleted file mode 100644
index 1adf0f8..0000000
--- a/hostsidetests/appsecurity/test-apps/ClassLoaderSplitApp/Android.mk
+++ /dev/null
@@ -1,36 +0,0 @@
-#
-# Copyright (C) 2017 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_USE_AAPT2 := true
-LOCAL_MODULE_TAGS := tests
-LOCAL_SDK_VERSION := current
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
-LOCAL_EXPORT_PACKAGE_RESOURCES := true
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner android-support-test
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := CtsClassloaderSplitApp
-
-# Tag this module as a cts test artifact
-
-include $(BUILD_CTS_SUPPORT_PACKAGE)
-
-include $(call first-makefiles-under,$(LOCAL_PATH))
diff --git a/hostsidetests/appsecurity/test-apps/ClassLoaderSplitApp/feature_a/Android.mk b/hostsidetests/appsecurity/test-apps/ClassLoaderSplitApp/feature_a/Android.mk
deleted file mode 100644
index f37be44..0000000
--- a/hostsidetests/appsecurity/test-apps/ClassLoaderSplitApp/feature_a/Android.mk
+++ /dev/null
@@ -1,35 +0,0 @@
-#
-# Copyright (C) 2017 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_USE_AAPT2 := true
-LOCAL_MODULE_TAGS := tests
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
-LOCAL_EXPORT_PACKAGE_RESOURCES := true
-LOCAL_PACKAGE_NAME := CtsClassloaderSplitAppFeatureA
-LOCAL_SDK_VERSION := current
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-LOCAL_APK_LIBRARIES := CtsClassloaderSplitApp
-LOCAL_RES_LIBRARIES := $(LOCAL_APK_LIBRARIES)
-
-LOCAL_AAPT_FLAGS += --custom-package com.android.cts.classloadersplitapp.feature_a
-LOCAL_AAPT_FLAGS += --package-id 0x80
-
-include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/ClassLoaderSplitApp/feature_b/Android.mk b/hostsidetests/appsecurity/test-apps/ClassLoaderSplitApp/feature_b/Android.mk
deleted file mode 100644
index 3262e15..0000000
--- a/hostsidetests/appsecurity/test-apps/ClassLoaderSplitApp/feature_b/Android.mk
+++ /dev/null
@@ -1,34 +0,0 @@
-#
-# Copyright (C) 2017 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_USE_AAPT2 := true
-LOCAL_MODULE_TAGS := tests
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
-LOCAL_PACKAGE_NAME := CtsClassloaderSplitAppFeatureB
-LOCAL_SDK_VERSION := current
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-LOCAL_APK_LIBRARIES := CtsClassloaderSplitApp CtsClassloaderSplitAppFeatureA
-LOCAL_RES_LIBRARIES := $(LOCAL_APK_LIBRARIES)
-
-LOCAL_AAPT_FLAGS := --custom-package com.android.cts.classloadersplitapp.feature_b
-LOCAL_AAPT_FLAGS += --package-id 0x81
-
-include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/UseEmbeddedDexApp/Android.mk b/hostsidetests/appsecurity/test-apps/UseEmbeddedDexApp/Android.mk
new file mode 100644
index 0000000..fbd8789
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/UseEmbeddedDexApp/Android.mk
@@ -0,0 +1,120 @@
+#
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsUseEmbeddedDexApp_Canonical
+LOCAL_USE_EMBEDDED_DEX := true
+LOCAL_MANIFEST_FILE := AndroidManifest.xml
+
+LOCAL_MODULE_TAGS := tests
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_SDK_VERSION := current
+LOCAL_MIN_SDK_VERSION := 27
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_PROGUARD_ENABLED := disabled
+LOCAL_DEX_PREOPT := false
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
+
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsUseEmbeddedDexApp_DexCompressed
+# Not specifying LOCAL_USE_EMBEDDED_DEX keeps dex compressed
+LOCAL_MANIFEST_FILE := AndroidManifest.xml
+
+LOCAL_MODULE_TAGS := tests
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_SDK_VERSION := current
+LOCAL_MIN_SDK_VERSION := 28
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_PROGUARD_ENABLED := disabled
+LOCAL_DEX_PREOPT := false
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
+
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsUseEmbeddedDexApp_NotPreferred
+LOCAL_MANIFEST_FILE := AndroidManifest_use_extracted_dex.xml
+
+LOCAL_MODULE_TAGS := tests
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_SDK_VERSION := current
+LOCAL_MIN_SDK_VERSION := 28
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_PROGUARD_ENABLED := disabled
+LOCAL_DEX_PREOPT := false
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
+
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsUseEmbeddedDexAppSplit_Canonical
+LOCAL_MANIFEST_FILE := feature_split/AndroidManifest.xml
+
+# We want the dex to be uncompressed, but there is a side effect of extra
+# android:useEmbeddedDex in the manifest (which the framework will ignore
+# for split).
+LOCAL_USE_EMBEDDED_DEX := true
+
+LOCAL_MODULE_TAGS := tests
+LOCAL_SRC_FILES := $(call all-java-files-under, feature_split/src)
+LOCAL_SDK_VERSION := current
+LOCAL_MIN_SDK_VERSION := 27
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_PROGUARD_ENABLED := disabled
+LOCAL_DEX_PREOPT := false
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
+
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsUseEmbeddedDexAppSplit_CompressedDex
+LOCAL_MANIFEST_FILE := feature_split/AndroidManifest.xml
+
+LOCAL_MODULE_TAGS := tests
+LOCAL_SRC_FILES := $(call all-java-files-under, feature_split/src)
+LOCAL_SDK_VERSION := current
+LOCAL_MIN_SDK_VERSION := 27
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_PROGUARD_ENABLED := disabled
+LOCAL_DEX_PREOPT := false
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
+
+
+#include $(CLEAR_VARS)
+#
+#LOCAL_PACKAGE_NAME := CtsUseEmbeddedDexAppSplit_CompressedSo
+#LOCAL_MANIFEST_FILE := feature_split/AndroidManifest.xml
+#
+#LOCAL_MODULE_TAGS := tests
+#LOCAL_SRC_FILES := $(call all-java-files-under, feature_split/src)
+#LOCAL_PREBUILT_JNI_LIBS := dummy.so
+#LOCAL_SDK_VERSION := current
+#LOCAL_MIN_SDK_VERSION := 27
+#LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+#LOCAL_PROGUARD_ENABLED := disabled
+#LOCAL_DEX_PREOPT := false
+#
+#include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/UseEmbeddedDexApp/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/UseEmbeddedDexApp/AndroidManifest.xml
new file mode 100644
index 0000000..ad1300f
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/UseEmbeddedDexApp/AndroidManifest.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  * Copyright (C) 2019 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.useembeddeddex">
+    <uses-sdk android:minSdkVersion="27" android:targetSdkVersion="27" />
+
+    <application android:useEmbeddedDex="true">
+        <activity android:name=".DummyActivity"/>
+    </application>
+
+</manifest>
diff --git a/hostsidetests/appsecurity/test-apps/UseEmbeddedDexApp/AndroidManifest_use_extracted_dex.xml b/hostsidetests/appsecurity/test-apps/UseEmbeddedDexApp/AndroidManifest_use_extracted_dex.xml
new file mode 100644
index 0000000..73c15a3
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/UseEmbeddedDexApp/AndroidManifest_use_extracted_dex.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  * Copyright (C) 2019 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.useembeddeddex">
+    <uses-sdk android:minSdkVersion="27" android:targetSdkVersion="27" />
+
+    <application android:useEmbeddedDex="false">
+        <activity android:name=".DummyActivity"/>
+    </application>
+
+</manifest>
diff --git a/hostsidetests/appsecurity/test-apps/UseEmbeddedDexApp/dummy.so b/hostsidetests/appsecurity/test-apps/UseEmbeddedDexApp/dummy.so
new file mode 100644
index 0000000..6a4b2e2
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/UseEmbeddedDexApp/dummy.so
@@ -0,0 +1 @@
+not really an ELF artifact...
diff --git a/hostsidetests/appsecurity/test-apps/UseEmbeddedDexApp/feature_split/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/UseEmbeddedDexApp/feature_split/AndroidManifest.xml
new file mode 100644
index 0000000..3ab0452
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/UseEmbeddedDexApp/feature_split/AndroidManifest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  * Copyright (C) 2019 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.useembeddeddex"
+    android:isFeatureSplit="true"
+    split="feature_x">
+    <application>
+        <activity android:name=".feature_x.DummyActivity"/>
+    </application>
+</manifest>
diff --git a/tests/tests/debug/src/android/debug/cts/DebugTest.java b/hostsidetests/appsecurity/test-apps/UseEmbeddedDexApp/feature_split/src/com/android/cts/useembeddeddex/feature_x/DummyActivity.java
similarity index 66%
copy from tests/tests/debug/src/android/debug/cts/DebugTest.java
copy to hostsidetests/appsecurity/test-apps/UseEmbeddedDexApp/feature_split/src/com/android/cts/useembeddeddex/feature_x/DummyActivity.java
index 993f02b..6cd8004 100644
--- a/tests/tests/debug/src/android/debug/cts/DebugTest.java
+++ b/hostsidetests/appsecurity/test-apps/UseEmbeddedDexApp/feature_split/src/com/android/cts/useembeddeddex/feature_x/DummyActivity.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2019 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.
@@ -14,12 +14,9 @@
  * limitations under the License.
  */
 
-package android.debug.cts;
+package com.android.cts.apkintergrity.feature_x;
 
-import org.junit.runner.RunWith;
-import com.android.gtestrunner.GtestRunner;
-import com.android.gtestrunner.TargetLibrary;
+import android.app.Activity;
 
-@RunWith(GtestRunner.class)
-@TargetLibrary("debugtest")
-public class DebugTest {}
+/** Dummy class just to generate some dex */
+public class DummyActivity extends Activity {}
diff --git a/tests/tests/debug/src/android/debug/cts/DebugTest.java b/hostsidetests/appsecurity/test-apps/UseEmbeddedDexApp/src/com/android/cts/useembeddeddex/DummyActivity.java
similarity index 66%
copy from tests/tests/debug/src/android/debug/cts/DebugTest.java
copy to hostsidetests/appsecurity/test-apps/UseEmbeddedDexApp/src/com/android/cts/useembeddeddex/DummyActivity.java
index 993f02b..974c541 100644
--- a/tests/tests/debug/src/android/debug/cts/DebugTest.java
+++ b/hostsidetests/appsecurity/test-apps/UseEmbeddedDexApp/src/com/android/cts/useembeddeddex/DummyActivity.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2019 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.
@@ -14,12 +14,9 @@
  * limitations under the License.
  */
 
-package android.debug.cts;
+package com.android.cts.useembeddeddex;
 
-import org.junit.runner.RunWith;
-import com.android.gtestrunner.GtestRunner;
-import com.android.gtestrunner.TargetLibrary;
+import android.app.Activity;
 
-@RunWith(GtestRunner.class)
-@TargetLibrary("debugtest")
-public class DebugTest {}
+/** Dummy class just to generate some dex */
+public class DummyActivity extends Activity {}
diff --git a/hostsidetests/appsecurity/test-apps/UsesLibraryApp/Android.mk b/hostsidetests/appsecurity/test-apps/UsesLibraryApp/Android.mk
deleted file mode 100644
index df12f82..0000000
--- a/hostsidetests/appsecurity/test-apps/UsesLibraryApp/Android.mk
+++ /dev/null
@@ -1,40 +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.
-#
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-LOCAL_SDK_VERSION := current
-LOCAL_STATIC_JAVA_LIBRARIES := android-support-test compatibility-device-util ctstestrunner ub-uiautomator
-
-LOCAL_JAVA_LIBRARIES := android.test.base.stubs
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src) \
-    ../ExternalStorageApp/src/com/android/cts/externalstorageapp/CommonExternalStorageTest.java
-
-LOCAL_PACKAGE_NAME := CtsUsesLibraryApp
-
-# tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
-
-LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey2
-
-LOCAL_PROGUARD_ENABLED := disabled
-LOCAL_DEX_PREOPT := false
-
-include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/backup/AndroidTest.xml b/hostsidetests/backup/AndroidTest.xml
index 46a17be..1b38d76 100644
--- a/hostsidetests/backup/AndroidTest.xml
+++ b/hostsidetests/backup/AndroidTest.xml
@@ -18,6 +18,7 @@
     <option name="config-descriptor:metadata" key="component" value="backup" />
     <!-- Backup of instant apps is not supported. -->
     <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
         <option name="test-file-name" value="CtsFullbackupApp.apk" />
diff --git a/hostsidetests/backup/src/android/cts/backup/BaseMultiUserBackupHostSideTest.java b/hostsidetests/backup/src/android/cts/backup/BaseMultiUserBackupHostSideTest.java
index 9f75d8d..93029c1 100644
--- a/hostsidetests/backup/src/android/cts/backup/BaseMultiUserBackupHostSideTest.java
+++ b/hostsidetests/backup/src/android/cts/backup/BaseMultiUserBackupHostSideTest.java
@@ -41,7 +41,8 @@
 @AppModeFull
 public abstract class BaseMultiUserBackupHostSideTest extends BaseBackupHostSideTest {
     private static final String USER_SETUP_COMPLETE_SETTING = "user_setup_complete";
-    private static final int BROADCAST_IDLE_TIMEOUT_MIN = 2;
+    private static final long USER_STATE_TIMEOUT_MS = TimeUnit.MINUTES.toMillis(5);
+    private static final long TRANSPORT_INITIALIZATION_TIMEOUT_MS = TimeUnit.MINUTES.toMillis(2);
 
     // Key-value test package.
     static final String KEY_VALUE_APK = "CtsProfileKeyValueApp.apk";
@@ -111,15 +112,16 @@
     }
 
     /** Start the user and set necessary conditions for backup to be enabled in the user. */
-    void startUserAndInitializeForBackup(int userId) throws Exception {
+    void startUserAndInitializeForBackup(int userId)
+            throws IOException, DeviceNotAvailableException {
         // Turn on multi-user feature for this user.
         mBackupUtils.executeShellCommandSync(
                 String.format("bmgr --user %d activate %b", userId, true));
 
         mDevice.startUser(userId);
         // Wait for user to be fully started.
-        mDevice.executeShellV2Command(
-                "am wait-for-broadcast-idle", BROADCAST_IDLE_TIMEOUT_MIN, TimeUnit.MINUTES);
+        boolean isUserStarted = waitForUserState(userId, "RUNNING_UNLOCKED");
+        assertThat(isUserStarted).isTrue();
 
         mDevice.setSetting(userId, "secure", USER_SETUP_COMPLETE_SETTING, "1");
         mBackupUtils.enableBackupForUser(true, userId);
@@ -133,7 +135,24 @@
     String switchUserToLocalTransportAndAssertSuccess(int userId) throws IOException {
         // Make sure the user has the local transport.
         String localTransport = mBackupUtils.getLocalTransportName();
-        assertThat(mBackupUtils.userHasBackupTransport(localTransport, userId)).isTrue();
+
+        // TODO (b/121198010): Update dumpsys or add shell command to query status of transport
+        // initialization. Transports won't be available until they are initialized/registered.
+        boolean hasLocalTransport = false;
+        long timeout = System.currentTimeMillis() + TRANSPORT_INITIALIZATION_TIMEOUT_MS;
+        while (System.currentTimeMillis() <= timeout) {
+            if (mBackupUtils.userHasBackupTransport(localTransport, userId)) {
+                hasLocalTransport = true;
+                break;
+            }
+
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException e) {
+                // Do nothing.
+            }
+        }
+        assertThat(hasLocalTransport).isTrue();
 
         // Switch to the local transport and assert success.
         mBackupUtils.setBackupTransportForUser(localTransport, userId);
@@ -166,4 +185,27 @@
         boolean result = runDeviceTests(mDevice, packageName, className, testName, userId, null);
         assertThat(result).isTrue();
     }
+
+    /**
+     * Waits for user {@code userId} to be in the state {@code expectedState}. Returns {@code true}
+     * if the user is in the state within the timeout.
+     */
+    boolean waitForUserState(int userId, String expectedState) throws IOException {
+        long timeout = System.currentTimeMillis() + USER_STATE_TIMEOUT_MS;
+        while (System.currentTimeMillis() <= timeout) {
+            String output =
+                    mBackupUtils.executeShellCommandAndReturnOutput(
+                            String.format("am get-started-user-state %d", userId));
+            if (output.contains(expectedState)) {
+                return true;
+            }
+
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException e) {
+                // Do nothing.
+            }
+        }
+        return false;
+    }
 }
diff --git a/hostsidetests/backup/src/android/cts/backup/ProfileScheduledJobHostSideTest.java b/hostsidetests/backup/src/android/cts/backup/ProfileScheduledJobHostSideTest.java
index 8f9b0c7..627ff78 100644
--- a/hostsidetests/backup/src/android/cts/backup/ProfileScheduledJobHostSideTest.java
+++ b/hostsidetests/backup/src/android/cts/backup/ProfileScheduledJobHostSideTest.java
@@ -146,7 +146,7 @@
         int jobId = getJobIdForUser(KEY_VALUE_MIN_JOB_ID, mProfileUserId);
         assertThat(isSystemJobScheduled(jobId, KEY_VALUE_JOB_NAME)).isTrue();
 
-        mDevice.stopUser(mProfileUserId);
+        mDevice.stopUser(mProfileUserId, /* waitFlag */ true, /* forceFlag */ true);
 
         assertThat(isSystemJobScheduled(jobId, KEY_VALUE_JOB_NAME)).isFalse();
     }
@@ -196,7 +196,7 @@
         int jobId = getJobIdForUser(FULL_BACKUP_MIN_JOB_ID, mProfileUserId);
         assertThat(isSystemJobScheduled(jobId, FULL_BACKUP_JOB_NAME)).isTrue();
 
-        mDevice.stopUser(mProfileUserId);
+        mDevice.stopUser(mProfileUserId, /* waitFlag */ true, /* forceFlag */ true);
 
         assertThat(isSystemJobScheduled(jobId, FULL_BACKUP_JOB_NAME)).isFalse();
     }
diff --git a/hostsidetests/classloaders/splits/Android.bp b/hostsidetests/classloaders/splits/Android.bp
new file mode 100644
index 0000000..17f02a7
--- /dev/null
+++ b/hostsidetests/classloaders/splits/Android.bp
@@ -0,0 +1,34 @@
+// Copyright (C) 2019 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.
+
+java_test_host {
+    name: "CtsClassloaderSplitsHostTestCases",
+    defaults: [ "cts_defaults" ],
+    srcs: [ "src/**/*.java" ],
+    libs: [
+        "compatibility-host-util",
+        "cts-tradefed",
+        "tradefed",
+    ],
+    test_suites: [
+        "cts",
+        "vts",
+        "general-tests",
+    ],
+    required: [
+        "CtsClassloaderSplitApp",
+        "CtsClassloaderSplitAppFeatureA",
+        "CtsClassloaderSplitAppFeatureB",
+    ],
+}
diff --git a/hostsidetests/classloaders/splits/AndroidTest.xml b/hostsidetests/classloaders/splits/AndroidTest.xml
new file mode 100644
index 0000000..77b5bce
--- /dev/null
+++ b/hostsidetests/classloaders/splits/AndroidTest.xml
@@ -0,0 +1,23 @@
+<?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.
+-->
+<configuration description="Config for the CTS Classloader Splits host tests">
+    <option name="test-suite-tag" value="cts" />
+    <option name="config-descriptor:metadata" key="component" value="framework" />
+    <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
+        <option name="jar" value="CtsClassloaderSplitsHostTestCases.jar" />
+        <option name="runtime-hint" value="1m" />
+    </test>
+</configuration>
diff --git a/hostsidetests/classloaders/splits/TEST_MAPPING b/hostsidetests/classloaders/splits/TEST_MAPPING
new file mode 100644
index 0000000..18f00dd
--- /dev/null
+++ b/hostsidetests/classloaders/splits/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+      "name": "CtsClassloaderSplitsHostTestCases"
+    }
+  ]
+}
diff --git a/hostsidetests/classloaders/splits/apps/Android.bp b/hostsidetests/classloaders/splits/apps/Android.bp
new file mode 100644
index 0000000..ebd9318
--- /dev/null
+++ b/hostsidetests/classloaders/splits/apps/Android.bp
@@ -0,0 +1,29 @@
+// Copyright (C) 2019 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.
+
+android_test {
+    name: "CtsClassloaderSplitApp",
+    defaults: [ "cts_support_defaults" ],
+    sdk_version: "current",
+    srcs: ["src/**/*.java"],
+    static_libs: [
+        "android-support-test",
+        "ctstestrunner",
+    ],
+    test_suites: [
+        "cts",
+        "vts",
+        "general-tests",
+    ],
+}
diff --git a/hostsidetests/appsecurity/test-apps/ClassLoaderSplitApp/AndroidManifest.xml b/hostsidetests/classloaders/splits/apps/AndroidManifest.xml
similarity index 100%
rename from hostsidetests/appsecurity/test-apps/ClassLoaderSplitApp/AndroidManifest.xml
rename to hostsidetests/classloaders/splits/apps/AndroidManifest.xml
diff --git a/hostsidetests/classloaders/splits/apps/feature_a/Android.bp b/hostsidetests/classloaders/splits/apps/feature_a/Android.bp
new file mode 100644
index 0000000..0fd7091
--- /dev/null
+++ b/hostsidetests/classloaders/splits/apps/feature_a/Android.bp
@@ -0,0 +1,32 @@
+// Copyright (C) 2019 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.
+
+android_test_helper_app {
+    name: "CtsClassloaderSplitAppFeatureA",
+    defaults: [ "cts_support_defaults" ],
+    sdk_version: "current",
+    srcs: [ "src/**/*.java" ],
+    libs: [ "CtsClassloaderSplitApp" ],
+    aaptflags: [
+        "--custom-package",
+        "com.android.cts.classloadersplitapp.feature_a",
+        "--package-id",
+        "0x80",
+    ],
+    test_suites: [
+        "cts",
+        "vts",
+        "general-tests",
+    ],
+}
diff --git a/hostsidetests/appsecurity/test-apps/ClassLoaderSplitApp/feature_a/AndroidManifest.xml b/hostsidetests/classloaders/splits/apps/feature_a/AndroidManifest.xml
similarity index 100%
rename from hostsidetests/appsecurity/test-apps/ClassLoaderSplitApp/feature_a/AndroidManifest.xml
rename to hostsidetests/classloaders/splits/apps/feature_a/AndroidManifest.xml
diff --git a/hostsidetests/appsecurity/test-apps/ClassLoaderSplitApp/feature_a/src/com/android/cts/classloadersplitapp/feature_a/FeatureAActivity.java b/hostsidetests/classloaders/splits/apps/feature_a/src/com/android/cts/classloadersplitapp/feature_a/FeatureAActivity.java
similarity index 100%
rename from hostsidetests/appsecurity/test-apps/ClassLoaderSplitApp/feature_a/src/com/android/cts/classloadersplitapp/feature_a/FeatureAActivity.java
rename to hostsidetests/classloaders/splits/apps/feature_a/src/com/android/cts/classloadersplitapp/feature_a/FeatureAActivity.java
diff --git a/hostsidetests/appsecurity/test-apps/ClassLoaderSplitApp/feature_a/src/com/android/cts/classloadersplitapp/feature_a/FeatureAReceiver.java b/hostsidetests/classloaders/splits/apps/feature_a/src/com/android/cts/classloadersplitapp/feature_a/FeatureAReceiver.java
similarity index 100%
rename from hostsidetests/appsecurity/test-apps/ClassLoaderSplitApp/feature_a/src/com/android/cts/classloadersplitapp/feature_a/FeatureAReceiver.java
rename to hostsidetests/classloaders/splits/apps/feature_a/src/com/android/cts/classloadersplitapp/feature_a/FeatureAReceiver.java
diff --git a/hostsidetests/classloaders/splits/apps/feature_b/Android.bp b/hostsidetests/classloaders/splits/apps/feature_b/Android.bp
new file mode 100644
index 0000000..2643840
--- /dev/null
+++ b/hostsidetests/classloaders/splits/apps/feature_b/Android.bp
@@ -0,0 +1,35 @@
+// Copyright (C) 2019 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.
+
+android_test_helper_app {
+    name: "CtsClassloaderSplitAppFeatureB",
+    defaults: [ "cts_support_defaults" ],
+    sdk_version: "current",
+    srcs: [ "src/**/*.java" ],
+    libs: [
+        "CtsClassloaderSplitApp",
+        "CtsClassloaderSplitAppFeatureA",
+    ],
+    aaptflags: [
+        "--custom-package",
+        "com.android.cts.classloadersplitapp.feature_a",
+        "--package-id",
+        "0x81",
+    ],
+    test_suites: [
+        "cts",
+        "vts",
+        "general-tests",
+    ],
+}
diff --git a/hostsidetests/appsecurity/test-apps/ClassLoaderSplitApp/feature_b/AndroidManifest.xml b/hostsidetests/classloaders/splits/apps/feature_b/AndroidManifest.xml
similarity index 100%
rename from hostsidetests/appsecurity/test-apps/ClassLoaderSplitApp/feature_b/AndroidManifest.xml
rename to hostsidetests/classloaders/splits/apps/feature_b/AndroidManifest.xml
diff --git a/hostsidetests/appsecurity/test-apps/ClassLoaderSplitApp/feature_b/res/values-pl/values.xml b/hostsidetests/classloaders/splits/apps/feature_b/res/values-pl/values.xml
similarity index 100%
rename from hostsidetests/appsecurity/test-apps/ClassLoaderSplitApp/feature_b/res/values-pl/values.xml
rename to hostsidetests/classloaders/splits/apps/feature_b/res/values-pl/values.xml
diff --git a/hostsidetests/appsecurity/test-apps/ClassLoaderSplitApp/feature_b/res/values/values.xml b/hostsidetests/classloaders/splits/apps/feature_b/res/values/values.xml
similarity index 100%
rename from hostsidetests/appsecurity/test-apps/ClassLoaderSplitApp/feature_b/res/values/values.xml
rename to hostsidetests/classloaders/splits/apps/feature_b/res/values/values.xml
diff --git a/hostsidetests/appsecurity/test-apps/ClassLoaderSplitApp/feature_b/src/com/android/cts/classloadersplitapp/feature_b/FeatureBActivity.java b/hostsidetests/classloaders/splits/apps/feature_b/src/com/android/cts/classloadersplitapp/feature_b/FeatureBActivity.java
similarity index 100%
rename from hostsidetests/appsecurity/test-apps/ClassLoaderSplitApp/feature_b/src/com/android/cts/classloadersplitapp/feature_b/FeatureBActivity.java
rename to hostsidetests/classloaders/splits/apps/feature_b/src/com/android/cts/classloadersplitapp/feature_b/FeatureBActivity.java
diff --git a/hostsidetests/appsecurity/test-apps/ClassLoaderSplitApp/feature_b/src/com/android/cts/classloadersplitapp/feature_b/FeatureBReceiver.java b/hostsidetests/classloaders/splits/apps/feature_b/src/com/android/cts/classloadersplitapp/feature_b/FeatureBReceiver.java
similarity index 100%
rename from hostsidetests/appsecurity/test-apps/ClassLoaderSplitApp/feature_b/src/com/android/cts/classloadersplitapp/feature_b/FeatureBReceiver.java
rename to hostsidetests/classloaders/splits/apps/feature_b/src/com/android/cts/classloadersplitapp/feature_b/FeatureBReceiver.java
diff --git a/hostsidetests/appsecurity/test-apps/ClassLoaderSplitApp/src/com/android/cts/classloadersplitapp/BaseActivity.java b/hostsidetests/classloaders/splits/apps/src/com/android/cts/classloadersplitapp/BaseActivity.java
similarity index 100%
rename from hostsidetests/appsecurity/test-apps/ClassLoaderSplitApp/src/com/android/cts/classloadersplitapp/BaseActivity.java
rename to hostsidetests/classloaders/splits/apps/src/com/android/cts/classloadersplitapp/BaseActivity.java
diff --git a/hostsidetests/appsecurity/test-apps/ClassLoaderSplitApp/src/com/android/cts/classloadersplitapp/BaseReceiver.java b/hostsidetests/classloaders/splits/apps/src/com/android/cts/classloadersplitapp/BaseReceiver.java
similarity index 100%
rename from hostsidetests/appsecurity/test-apps/ClassLoaderSplitApp/src/com/android/cts/classloadersplitapp/BaseReceiver.java
rename to hostsidetests/classloaders/splits/apps/src/com/android/cts/classloadersplitapp/BaseReceiver.java
diff --git a/hostsidetests/appsecurity/test-apps/ClassLoaderSplitApp/src/com/android/cts/classloadersplitapp/SplitAppTest.java b/hostsidetests/classloaders/splits/apps/src/com/android/cts/classloadersplitapp/SplitAppTest.java
similarity index 100%
rename from hostsidetests/appsecurity/test-apps/ClassLoaderSplitApp/src/com/android/cts/classloadersplitapp/SplitAppTest.java
rename to hostsidetests/classloaders/splits/apps/src/com/android/cts/classloadersplitapp/SplitAppTest.java
diff --git a/hostsidetests/classloaders/splits/src/android/classloaders/cts/BaseInstallMultiple.java b/hostsidetests/classloaders/splits/src/android/classloaders/cts/BaseInstallMultiple.java
new file mode 100644
index 0000000..f5170e9
--- /dev/null
+++ b/hostsidetests/classloaders/splits/src/android/classloaders/cts/BaseInstallMultiple.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2017 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.classloaders.cts;
+
+import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.IAbi;
+import com.android.tradefed.util.AbiUtils;
+
+import junit.framework.TestCase;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Base class for invoking the install-multiple command via ADB. Subclass this for less typing:
+ *
+ * <code>
+ *     private class InstallMultiple extends BaseInstallMultiple&lt;InstallMultiple&gt; {
+ *         public InstallMultiple() {
+ *             super(getDevice(), null, null);
+ *         }
+ *     }
+ * </code>
+ */
+public class BaseInstallMultiple<T extends BaseInstallMultiple<?>> {
+    private final ITestDevice mDevice;
+    private final IBuildInfo mBuild;
+    private final IAbi mAbi;
+
+    private final List<String> mArgs = new ArrayList<>();
+    private final List<File> mApks = new ArrayList<>();
+    private boolean mUseNaturalAbi;
+
+    public BaseInstallMultiple(ITestDevice device, IBuildInfo buildInfo, IAbi abi) {
+        mDevice = device;
+        mBuild = buildInfo;
+        mAbi = abi;
+        addArg("-g");
+    }
+
+    T addArg(String arg) {
+        mArgs.add(arg);
+        return (T) this;
+    }
+
+    T addApk(String apk) throws FileNotFoundException {
+        CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mBuild);
+        mApks.add(buildHelper.getTestFile(apk));
+        return (T) this;
+    }
+
+    T inheritFrom(String packageName) {
+        addArg("-r");
+        addArg("-p " + packageName);
+        return (T) this;
+    }
+
+    T useNaturalAbi() {
+        mUseNaturalAbi = true;
+        return (T) this;
+    }
+
+    T allowTest() {
+        addArg("-t");
+        return (T) this;
+    }
+
+    T locationAuto() {
+        addArg("--install-location 0");
+        return (T) this;
+    }
+
+    T locationInternalOnly() {
+        addArg("--install-location 1");
+        return (T) this;
+    }
+
+    T locationPreferExternal() {
+        addArg("--install-location 2");
+        return (T) this;
+    }
+
+    T forceUuid(String uuid) {
+        addArg("--force-uuid " + uuid);
+        return (T) this;
+    }
+
+    T forUser(int userId) {
+        addArg("--user " + userId);
+        return (T) this;
+    }
+
+    void run() throws DeviceNotAvailableException {
+        run(true, null);
+    }
+
+    void runExpectingFailure() throws DeviceNotAvailableException {
+        run(false, null);
+    }
+
+    void runExpectingFailure(String failure) throws DeviceNotAvailableException {
+        run(false, failure);
+    }
+
+    private void run(boolean expectingSuccess, String failure) throws DeviceNotAvailableException {
+        final ITestDevice device = mDevice;
+
+        // Create an install session
+        final StringBuilder cmd = new StringBuilder();
+        cmd.append("pm install-create");
+        for (String arg : mArgs) {
+            cmd.append(' ').append(arg);
+        }
+        if (!mUseNaturalAbi && mAbi != null) {
+            cmd.append(' ').append(AbiUtils.createAbiFlag(mAbi.getName()));
+        }
+
+        String result = device.executeShellCommand(cmd.toString());
+        TestCase.assertTrue(result, result.startsWith("Success"));
+
+        final int start = result.lastIndexOf("[");
+        final int end = result.lastIndexOf("]");
+        int sessionId = -1;
+        try {
+            if (start != -1 && end != -1 && start < end) {
+                sessionId = Integer.parseInt(result.substring(start + 1, end));
+            }
+        } catch (NumberFormatException e) {
+        }
+        if (sessionId == -1) {
+            throw new IllegalStateException("Failed to create install session: " + result);
+        }
+
+        // Push our files into session. Ideally we'd use stdin streaming,
+        // but ddmlib doesn't support it yet.
+        for (int i = 0; i < mApks.size(); i++) {
+            final File apk = mApks.get(i);
+            final String remotePath = "/data/local/tmp/" + i + "_" + apk.getName();
+            if (!device.pushFile(apk, remotePath)) {
+                throw new IllegalStateException("Failed to push " + apk);
+            }
+
+            cmd.setLength(0);
+            cmd.append("pm install-write");
+            cmd.append(' ').append(sessionId);
+            cmd.append(' ').append(i + "_" + apk.getName());
+            cmd.append(' ').append(remotePath);
+
+            result = device.executeShellCommand(cmd.toString());
+            TestCase.assertTrue(result, result.startsWith("Success"));
+        }
+
+        // Everything staged; let's pull trigger
+        cmd.setLength(0);
+        cmd.append("pm install-commit");
+        cmd.append(' ').append(sessionId);
+
+        result = device.executeShellCommand(cmd.toString()).trim();
+        if (failure == null) {
+            if (expectingSuccess) {
+                TestCase.assertTrue(result, result.startsWith("Success"));
+            } else {
+                TestCase.assertFalse(result, result.startsWith("Success"));
+            }
+        } else {
+            TestCase.assertTrue(result, result.contains(failure));
+        }
+    }
+}
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/ClassloaderSplitsTest.java b/hostsidetests/classloaders/splits/src/android/classloaders/cts/ClassloaderSplitsTest.java
similarity index 89%
rename from hostsidetests/appsecurity/src/android/appsecurity/cts/ClassloaderSplitsTest.java
rename to hostsidetests/classloaders/splits/src/android/classloaders/cts/ClassloaderSplitsTest.java
index 4e54bc4..1460bfc 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/ClassloaderSplitsTest.java
+++ b/hostsidetests/classloaders/splits/src/android/classloaders/cts/ClassloaderSplitsTest.java
@@ -13,11 +13,12 @@
  * License for the specific language governing permissions and limitations
  * under the License.
  */
-package android.appsecurity.cts;
+package android.classloaders.cts;
 
 import android.platform.test.annotations.AppModeFull;
 import android.platform.test.annotations.AppModeInstant;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
 
 import org.junit.After;
 import org.junit.Before;
@@ -25,7 +26,7 @@
 import org.junit.runner.RunWith;
 
 @RunWith(DeviceJUnit4ClassRunner.class)
-public class ClassloaderSplitsTest extends BaseAppSecurityTest {
+public class ClassloaderSplitsTest extends BaseHostJUnit4Test {
     private static final String PKG = "com.android.cts.classloadersplitapp";
     private static final String TEST_CLASS = PKG + ".SplitAppTest";
 
@@ -47,7 +48,6 @@
 
     @Before
     public void setUp() throws Exception {
-        Utils.prepareSingleUser(getDevice());
         getDevice().uninstallPackage(PKG);
     }
 
@@ -116,4 +116,14 @@
         runDeviceTests(getDevice(), PKG, TEST_CLASS, "testBaseClassLoader");
         runDeviceTests(getDevice(), PKG, TEST_CLASS, "testAllReceivers");
     }
+
+    protected class InstallMultiple extends BaseInstallMultiple<InstallMultiple> {
+        public InstallMultiple() {
+            this(false);
+        }
+        public InstallMultiple(boolean instant) {
+            super(getDevice(), getBuild(), getAbi());
+            addArg(instant ? "--instant" : "");
+        }
+    }
 }
diff --git a/hostsidetests/classloaders/useslibrary/Android.bp b/hostsidetests/classloaders/useslibrary/Android.bp
new file mode 100644
index 0000000..603b2ec
--- /dev/null
+++ b/hostsidetests/classloaders/useslibrary/Android.bp
@@ -0,0 +1,30 @@
+// Copyright (C) 2019 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.
+
+java_test_host {
+    name: "CtsUsesLibraryHostTestCases",
+    defaults: [ "cts_defaults" ],
+    srcs: [ "src/**/*.java" ],
+    libs: [
+        "compatibility-host-util",
+        "cts-tradefed",
+        "tradefed",
+    ],
+    test_suites: [
+        "cts",
+        "vts",
+        "general-tests",
+    ],
+    required: [ "CtsUsesLibraryApp" ],
+}
diff --git a/hostsidetests/classloaders/useslibrary/AndroidTest.xml b/hostsidetests/classloaders/useslibrary/AndroidTest.xml
new file mode 100644
index 0000000..b7796d7
--- /dev/null
+++ b/hostsidetests/classloaders/useslibrary/AndroidTest.xml
@@ -0,0 +1,23 @@
+<?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.
+-->
+<configuration description="Config for the CTS UsesLibrary host tests">
+    <option name="test-suite-tag" value="cts" />
+    <option name="config-descriptor:metadata" key="component" value="framework" />
+    <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
+        <option name="jar" value="CtsUsesLibraryHostTestCases.jar" />
+        <option name="runtime-hint" value="1m" />
+    </test>
+</configuration>
diff --git a/hostsidetests/classloaders/useslibrary/TEST_MAPPING b/hostsidetests/classloaders/useslibrary/TEST_MAPPING
new file mode 100644
index 0000000..72ef61b
--- /dev/null
+++ b/hostsidetests/classloaders/useslibrary/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+      "name": "CtsUsesLibraryHostTestCases"
+    }
+  ]
+}
diff --git a/hostsidetests/classloaders/useslibrary/app/Android.bp b/hostsidetests/classloaders/useslibrary/app/Android.bp
new file mode 100644
index 0000000..faf7a22
--- /dev/null
+++ b/hostsidetests/classloaders/useslibrary/app/Android.bp
@@ -0,0 +1,32 @@
+// Copyright (C) 2019 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.
+
+android_test {
+    name: "CtsUsesLibraryApp",
+    defaults: [ "cts_support_defaults" ],
+    sdk_version: "current",
+    srcs: ["src/**/*.java"],
+    libs: [
+        "android.test.base.stubs",
+    ],
+    static_libs: [
+        "android-support-test",
+        "ctstestrunner",
+    ],
+    test_suites: [
+        "cts",
+        "vts",
+        "general-tests",
+    ],
+}
diff --git a/hostsidetests/appsecurity/test-apps/UsesLibraryApp/AndroidManifest.xml b/hostsidetests/classloaders/useslibrary/app/AndroidManifest.xml
similarity index 100%
rename from hostsidetests/appsecurity/test-apps/UsesLibraryApp/AndroidManifest.xml
rename to hostsidetests/classloaders/useslibrary/app/AndroidManifest.xml
diff --git a/hostsidetests/appsecurity/test-apps/UsesLibraryApp/src/com/android/cts/useslibrary/UsesLibraryTest.java b/hostsidetests/classloaders/useslibrary/app/src/com/android/cts/useslibrary/UsesLibraryTest.java
similarity index 95%
rename from hostsidetests/appsecurity/test-apps/UsesLibraryApp/src/com/android/cts/useslibrary/UsesLibraryTest.java
rename to hostsidetests/classloaders/useslibrary/app/src/com/android/cts/useslibrary/UsesLibraryTest.java
index 73b820d..7fa8b20 100644
--- a/hostsidetests/appsecurity/test-apps/UsesLibraryApp/src/com/android/cts/useslibrary/UsesLibraryTest.java
+++ b/hostsidetests/classloaders/useslibrary/app/src/com/android/cts/useslibrary/UsesLibraryTest.java
@@ -16,11 +16,6 @@
 
 package com.android.cts.useslibrary;
 
-import android.content.pm.PackageManager;
-import android.os.Environment;
-import android.support.test.uiautomator.UiDevice;
-import android.support.test.uiautomator.UiObject;
-import android.support.test.uiautomator.UiSelector;
 import android.test.InstrumentationTestCase;
 
 import dalvik.system.BaseDexClassLoader;
diff --git a/hostsidetests/classloaders/useslibrary/src/android/classloaders/cts/BaseInstallMultiple.java b/hostsidetests/classloaders/useslibrary/src/android/classloaders/cts/BaseInstallMultiple.java
new file mode 100644
index 0000000..f5170e9
--- /dev/null
+++ b/hostsidetests/classloaders/useslibrary/src/android/classloaders/cts/BaseInstallMultiple.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2017 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.classloaders.cts;
+
+import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.IAbi;
+import com.android.tradefed.util.AbiUtils;
+
+import junit.framework.TestCase;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Base class for invoking the install-multiple command via ADB. Subclass this for less typing:
+ *
+ * <code>
+ *     private class InstallMultiple extends BaseInstallMultiple&lt;InstallMultiple&gt; {
+ *         public InstallMultiple() {
+ *             super(getDevice(), null, null);
+ *         }
+ *     }
+ * </code>
+ */
+public class BaseInstallMultiple<T extends BaseInstallMultiple<?>> {
+    private final ITestDevice mDevice;
+    private final IBuildInfo mBuild;
+    private final IAbi mAbi;
+
+    private final List<String> mArgs = new ArrayList<>();
+    private final List<File> mApks = new ArrayList<>();
+    private boolean mUseNaturalAbi;
+
+    public BaseInstallMultiple(ITestDevice device, IBuildInfo buildInfo, IAbi abi) {
+        mDevice = device;
+        mBuild = buildInfo;
+        mAbi = abi;
+        addArg("-g");
+    }
+
+    T addArg(String arg) {
+        mArgs.add(arg);
+        return (T) this;
+    }
+
+    T addApk(String apk) throws FileNotFoundException {
+        CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mBuild);
+        mApks.add(buildHelper.getTestFile(apk));
+        return (T) this;
+    }
+
+    T inheritFrom(String packageName) {
+        addArg("-r");
+        addArg("-p " + packageName);
+        return (T) this;
+    }
+
+    T useNaturalAbi() {
+        mUseNaturalAbi = true;
+        return (T) this;
+    }
+
+    T allowTest() {
+        addArg("-t");
+        return (T) this;
+    }
+
+    T locationAuto() {
+        addArg("--install-location 0");
+        return (T) this;
+    }
+
+    T locationInternalOnly() {
+        addArg("--install-location 1");
+        return (T) this;
+    }
+
+    T locationPreferExternal() {
+        addArg("--install-location 2");
+        return (T) this;
+    }
+
+    T forceUuid(String uuid) {
+        addArg("--force-uuid " + uuid);
+        return (T) this;
+    }
+
+    T forUser(int userId) {
+        addArg("--user " + userId);
+        return (T) this;
+    }
+
+    void run() throws DeviceNotAvailableException {
+        run(true, null);
+    }
+
+    void runExpectingFailure() throws DeviceNotAvailableException {
+        run(false, null);
+    }
+
+    void runExpectingFailure(String failure) throws DeviceNotAvailableException {
+        run(false, failure);
+    }
+
+    private void run(boolean expectingSuccess, String failure) throws DeviceNotAvailableException {
+        final ITestDevice device = mDevice;
+
+        // Create an install session
+        final StringBuilder cmd = new StringBuilder();
+        cmd.append("pm install-create");
+        for (String arg : mArgs) {
+            cmd.append(' ').append(arg);
+        }
+        if (!mUseNaturalAbi && mAbi != null) {
+            cmd.append(' ').append(AbiUtils.createAbiFlag(mAbi.getName()));
+        }
+
+        String result = device.executeShellCommand(cmd.toString());
+        TestCase.assertTrue(result, result.startsWith("Success"));
+
+        final int start = result.lastIndexOf("[");
+        final int end = result.lastIndexOf("]");
+        int sessionId = -1;
+        try {
+            if (start != -1 && end != -1 && start < end) {
+                sessionId = Integer.parseInt(result.substring(start + 1, end));
+            }
+        } catch (NumberFormatException e) {
+        }
+        if (sessionId == -1) {
+            throw new IllegalStateException("Failed to create install session: " + result);
+        }
+
+        // Push our files into session. Ideally we'd use stdin streaming,
+        // but ddmlib doesn't support it yet.
+        for (int i = 0; i < mApks.size(); i++) {
+            final File apk = mApks.get(i);
+            final String remotePath = "/data/local/tmp/" + i + "_" + apk.getName();
+            if (!device.pushFile(apk, remotePath)) {
+                throw new IllegalStateException("Failed to push " + apk);
+            }
+
+            cmd.setLength(0);
+            cmd.append("pm install-write");
+            cmd.append(' ').append(sessionId);
+            cmd.append(' ').append(i + "_" + apk.getName());
+            cmd.append(' ').append(remotePath);
+
+            result = device.executeShellCommand(cmd.toString());
+            TestCase.assertTrue(result, result.startsWith("Success"));
+        }
+
+        // Everything staged; let's pull trigger
+        cmd.setLength(0);
+        cmd.append("pm install-commit");
+        cmd.append(' ').append(sessionId);
+
+        result = device.executeShellCommand(cmd.toString()).trim();
+        if (failure == null) {
+            if (expectingSuccess) {
+                TestCase.assertTrue(result, result.startsWith("Success"));
+            } else {
+                TestCase.assertFalse(result, result.startsWith("Success"));
+            }
+        } else {
+            TestCase.assertTrue(result, result.contains(failure));
+        }
+    }
+}
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/UsesLibraryHostTest.java b/hostsidetests/classloaders/useslibrary/src/android/classloaders/cts/UsesLibraryHostTest.java
similarity index 84%
rename from hostsidetests/appsecurity/src/android/appsecurity/cts/UsesLibraryHostTest.java
rename to hostsidetests/classloaders/useslibrary/src/android/classloaders/cts/UsesLibraryHostTest.java
index 41ce7a1..aecd87b 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/UsesLibraryHostTest.java
+++ b/hostsidetests/classloaders/useslibrary/src/android/classloaders/cts/UsesLibraryHostTest.java
@@ -14,12 +14,13 @@
  * limitations under the License.
  */
 
-package android.appsecurity.cts;
+package android.classloaders.cts;
 
 import android.platform.test.annotations.AppModeFull;
 import android.platform.test.annotations.AppModeInstant;
 
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
 
 import org.junit.After;
 import org.junit.Before;
@@ -32,7 +33,7 @@
  */
 @AppModeFull(reason = "TODO verify whether or not these should run in instant mode")
 @RunWith(DeviceJUnit4ClassRunner.class)
-public class UsesLibraryHostTest extends BaseAppSecurityTest {
+public class UsesLibraryHostTest extends BaseHostJUnit4Test {
     private static final String PKG = "com.android.cts.useslibrary";
 
     private static final String APK = "CtsUsesLibraryApp.apk";
@@ -79,4 +80,14 @@
         new InstallMultiple(instant).addApk(APK).run();
         Utils.runDeviceTests(getDevice(), PKG, ".UsesLibraryTest", "testDuplicateLibrary");
     }
+
+    protected class InstallMultiple extends BaseInstallMultiple<InstallMultiple> {
+        public InstallMultiple() {
+            this(false);
+        }
+        public InstallMultiple(boolean instant) {
+            super(getDevice(), getBuild(), getAbi());
+            addArg(instant ? "--instant" : "");
+        }
+    }
 }
diff --git a/hostsidetests/classloaders/useslibrary/src/android/classloaders/cts/Utils.java b/hostsidetests/classloaders/useslibrary/src/android/classloaders/cts/Utils.java
new file mode 100644
index 0000000..48497d8
--- /dev/null
+++ b/hostsidetests/classloaders/useslibrary/src/android/classloaders/cts/Utils.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.classloaders.cts;
+
+import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
+import com.android.ddmlib.testrunner.TestResult.TestStatus;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.result.CollectingTestListener;
+import com.android.tradefed.result.TestDescription;
+import com.android.tradefed.result.TestResult;
+import com.android.tradefed.result.TestRunResult;
+
+import java.util.Arrays;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+public class Utils {
+    public static final int USER_SYSTEM = 0;
+
+    public static void runDeviceTests(ITestDevice device, String packageName, String testClassName,
+            String testMethodName) throws DeviceNotAvailableException {
+        runDeviceTests(device, packageName, testClassName, testMethodName, USER_SYSTEM, null);
+    }
+
+    public static void runDeviceTests(ITestDevice device, String packageName, String testClassName,
+            String testMethodName, Map<String, String> testArgs)
+                    throws DeviceNotAvailableException {
+        runDeviceTests(device, packageName, testClassName, testMethodName, USER_SYSTEM, testArgs);
+    }
+
+    public static void runDeviceTests(ITestDevice device, String packageName, String testClassName,
+            String testMethodName, int userId) throws DeviceNotAvailableException {
+        runDeviceTests(device, packageName, testClassName, testMethodName, userId, null);
+    }
+
+    public static void runDeviceTests(ITestDevice device, String packageName, String testClassName,
+            String testMethodName, int userId, Map<String, String> testArgs)
+                    throws DeviceNotAvailableException {
+        // 60 min timeout per test by default
+        runDeviceTests(device, packageName, testClassName, testMethodName, userId, testArgs,
+                60L, TimeUnit.MINUTES);
+    }
+
+    public static void runDeviceTests(ITestDevice device, String packageName, String testClassName,
+            String testMethodName, int userId, Map<String, String> testArgs, long timeout,
+            TimeUnit unit)
+                    throws DeviceNotAvailableException {
+        if (testClassName != null && testClassName.startsWith(".")) {
+            testClassName = packageName + testClassName;
+        }
+        RemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(packageName,
+                "android.support.test.runner.AndroidJUnitRunner", device.getIDevice());
+        // timeout_msec is the timeout per test for instrumentation
+        testRunner.addInstrumentationArg("timeout_msec", Long.toString(unit.toMillis(timeout)));
+        if (testClassName != null && testMethodName != null) {
+            testRunner.setMethodName(testClassName, testMethodName);
+        } else if (testClassName != null) {
+            testRunner.setClassName(testClassName);
+        }
+
+        if (testArgs != null && testArgs.size() > 0) {
+            for (String name : testArgs.keySet()) {
+                final String value = testArgs.get(name);
+                testRunner.addInstrumentationArg(name, value);
+            }
+        }
+        final CollectingTestListener listener = new CollectingTestListener();
+        device.runInstrumentationTestsAsUser(testRunner, userId, listener);
+
+        final TestRunResult result = listener.getCurrentRunResults();
+        if (result.isRunFailure()) {
+            throw new AssertionError("Failed to successfully run device tests for "
+                    + result.getName() + ": " + result.getRunFailureMessage());
+        }
+        if (result.getNumTests() == 0) {
+            throw new AssertionError("No tests were run on the device");
+        }
+        if (result.hasFailedTests()) {
+            // build a meaningful error message
+            StringBuilder errorBuilder = new StringBuilder("on-device tests failed:\n");
+            for (Map.Entry<TestDescription, TestResult> resultEntry :
+                result.getTestResults().entrySet()) {
+                if (!resultEntry.getValue().getStatus().equals(TestStatus.PASSED)) {
+                    errorBuilder.append(resultEntry.getKey().toString());
+                    errorBuilder.append(":\n");
+                    errorBuilder.append(resultEntry.getValue().getStackTrace());
+                }
+            }
+            throw new AssertionError(errorBuilder.toString());
+        }
+    }
+
+    /**
+     * Prepare and return a single user relevant for testing.
+     */
+    public static int[] prepareSingleUser(ITestDevice device)
+            throws DeviceNotAvailableException {
+        return prepareMultipleUsers(device, 1);
+    }
+
+    /**
+     * Prepare and return two users relevant for testing.
+     */
+    public static int[] prepareMultipleUsers(ITestDevice device)
+            throws DeviceNotAvailableException {
+        return prepareMultipleUsers(device, 2);
+    }
+
+    /**
+     * Prepare and return multiple users relevant for testing.
+     */
+    public static int[] prepareMultipleUsers(ITestDevice device, int maxUsers)
+            throws DeviceNotAvailableException {
+        final int[] userIds = getAllUsers(device);
+        for (int i = 1; i < userIds.length; i++) {
+            if (i < maxUsers) {
+                device.startUser(userIds[i]);
+            } else {
+                device.stopUser(userIds[i]);
+            }
+        }
+        if (userIds.length > maxUsers) {
+            return Arrays.copyOf(userIds, maxUsers);
+        } else {
+            return userIds;
+        }
+    }
+
+    public static int[] getAllUsers(ITestDevice device)
+            throws DeviceNotAvailableException {
+        Integer primary = device.getPrimaryUserId();
+        if (primary == null) {
+            primary = USER_SYSTEM;
+        }
+        int[] users = new int[] { primary };
+        for (Integer user : device.listUsers()) {
+            if ((user != USER_SYSTEM) && (user != primary)) {
+                users = Arrays.copyOf(users, users.length + 1);
+                users[users.length - 1] = user;
+            }
+        }
+        return users;
+    }
+}
diff --git a/hostsidetests/compilation/AndroidTest.xml b/hostsidetests/compilation/AndroidTest.xml
index 9383a79..fe17ac8 100644
--- a/hostsidetests/compilation/AndroidTest.xml
+++ b/hostsidetests/compilation/AndroidTest.xml
@@ -16,7 +16,6 @@
 <configuration description="Config for CTS Compilation Test">
     <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="art" />
-    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" />
     <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
         <option name="jar" value="CtsCompilationTestCases.jar" />
         <option name="runtime-hint" value="9m45s" />
diff --git a/hostsidetests/devicepolicy/AndroidTest.xml b/hostsidetests/devicepolicy/AndroidTest.xml
index f745781..e3929cc 100644
--- a/hostsidetests/devicepolicy/AndroidTest.xml
+++ b/hostsidetests/devicepolicy/AndroidTest.xml
@@ -19,6 +19,8 @@
     <!-- Instant apps can never be device admin / profile owner / device owner so positive tests
          here are not applicable -->
     <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <!-- Not testing features backed by native code, so only need to run against one ABI -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
 
     <!-- Push the list of public APIs to device -->
     <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
diff --git a/hostsidetests/devicepolicy/app/CertInstaller/AndroidManifest.xml b/hostsidetests/devicepolicy/app/CertInstaller/AndroidManifest.xml
index 8ef107b..bda007a 100644
--- a/hostsidetests/devicepolicy/app/CertInstaller/AndroidManifest.xml
+++ b/hostsidetests/devicepolicy/app/CertInstaller/AndroidManifest.xml
@@ -19,6 +19,8 @@
 
     <uses-sdk android:minSdkVersion="22"/>
 
+    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+
     <application>
         <uses-library android:name="android.test.runner" />
 
diff --git a/hostsidetests/devicepolicy/app/CertInstaller/src/com/android/cts/certinstaller/DirectDelegatedCertInstallerTest.java b/hostsidetests/devicepolicy/app/CertInstaller/src/com/android/cts/certinstaller/DirectDelegatedCertInstallerTest.java
index ffa93b9..59d386e 100644
--- a/hostsidetests/devicepolicy/app/CertInstaller/src/com/android/cts/certinstaller/DirectDelegatedCertInstallerTest.java
+++ b/hostsidetests/devicepolicy/app/CertInstaller/src/com/android/cts/certinstaller/DirectDelegatedCertInstallerTest.java
@@ -22,11 +22,13 @@
 
 import android.app.admin.DevicePolicyManager;
 import android.content.Context;
+import android.os.Build;
 import android.security.AttestedKeyPair;
 import android.security.KeyChain;
 import android.security.KeyChainException;
 import android.security.keystore.KeyGenParameterSpec;
 import android.security.keystore.KeyProperties;
+import android.telephony.TelephonyManager;
 import android.test.InstrumentationTestCase;
 import android.util.Base64;
 import android.util.Base64InputStream;
@@ -209,6 +211,19 @@
         }
     }
 
+    public void testAccessToDeviceIdentifiers() {
+        String serialNumber = Build.getSerial();
+        assertThat(Build.getSerial()).doesNotMatch(Build.UNKNOWN);
+
+        TelephonyManager telephonyService = (TelephonyManager) getContext().getSystemService(
+                Context.TELEPHONY_SERVICE);
+        assertWithMessage("Telephony service must be available.")
+                .that(telephonyService).isNotNull();
+
+        assertWithMessage("Must be able to obtain a valid IMEI.")
+                .that(telephonyService.getImei()).isNotNull();
+    }
+
     private static boolean containsCertificate(List<byte[]> certificates, byte[] toMatch)
             throws CertificateException {
         Certificate certificateToMatch = readCertificate(toMatch);
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AlwaysOnVpnMultiStageTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AlwaysOnVpnMultiStageTest.java
index 25d7be7..e86abd7 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AlwaysOnVpnMultiStageTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AlwaysOnVpnMultiStageTest.java
@@ -25,6 +25,7 @@
 
 import com.android.cts.deviceandprofileowner.vpn.VpnTestHelper;
 
+import java.util.List;
 import java.util.concurrent.TimeUnit;
 
 /**
@@ -36,16 +37,33 @@
 
     public void testAlwaysOnSet() throws Exception {
         // Setup always-on vpn
-        VpnTestHelper.waitForVpn(mContext, VPN_PACKAGE, /* usable */ true);
+        VpnTestHelper.waitForVpn(mContext, VPN_PACKAGE,
+                /* usable */ true, /* lockdown */ true, /* whitelist */ false);
         assertTrue(VpnTestHelper.isNetworkVpn(mContext));
         VpnTestHelper.checkPing(TEST_ADDRESS);
     }
 
-    public void testAlwaysOnSetAfterReboot() throws Exception {
-        VpnTestHelper.waitForVpn(mContext, null, /* usable */ true);
+    public void testAlwaysOnSetWithWhitelist() throws Exception {
+        VpnTestHelper.waitForVpn(mContext, VPN_PACKAGE,
+                /* usable */ true, /* lockdown */ true, /* whitelist */ true);
+        assertTrue(VpnTestHelper.isNetworkVpn(mContext));
         VpnTestHelper.checkPing(TEST_ADDRESS);
     }
 
+    // Should be run after running testAlwaysOnSetWithWhitelist and rebooting.
+    public void testAlwaysOnSetAfterReboot() throws Exception {
+        VpnTestHelper.waitForVpn(mContext, null,
+                /* usable */ true, /* lockdown */ true, /* whitelist */ true);
+        VpnTestHelper.checkPing(TEST_ADDRESS);
+        final List<String> whitelist =
+                mDevicePolicyManager.getAlwaysOnVpnLockdownWhitelist(ADMIN_RECEIVER_COMPONENT);
+        assertTrue("Lockdown bit lost after reboot",
+                mDevicePolicyManager.isAlwaysOnVpnLockdownEnabled(ADMIN_RECEIVER_COMPONENT));
+        assertNotNull("whitelist is lost after reboot", whitelist);
+        assertTrue("whitelist changed after reboot",
+                whitelist.size() == 1 && mContext.getPackageName().equals(whitelist.get(0)));
+    }
+
     public void testNetworkBlocked() throws Exception {
         // After the vpn app being force-stop, expect that always-on package stays the same
         assertEquals(VPN_PACKAGE, mDevicePolicyManager.getAlwaysOnVpnPackage(
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AlwaysOnVpnTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AlwaysOnVpnTest.java
index fff701e..4b5c8de 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AlwaysOnVpnTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AlwaysOnVpnTest.java
@@ -19,11 +19,17 @@
 import static com.android.cts.deviceandprofileowner.vpn.VpnTestHelper.TEST_ADDRESS;
 import static com.android.cts.deviceandprofileowner.vpn.VpnTestHelper.VPN_PACKAGE;
 
+import android.net.VpnService;
 import android.os.Bundle;
 import android.os.UserManager;
+import android.util.Log;
 
+import com.android.compatibility.common.util.BlockingBroadcastReceiver;
 import com.android.cts.deviceandprofileowner.vpn.VpnTestHelper;
 
+import java.io.IOException;
+import java.net.Socket;
+
 /**
  * Validates that a device owner or profile owner can set an always-on VPN without user action.
  *
@@ -35,18 +41,21 @@
  * result of a misconfigured network.
  */
 public class AlwaysOnVpnTest extends BaseDeviceAdminTest {
+    private static final String TAG = "AlwaysOnVpnTest";
+
     /** @see com.android.cts.vpnfirewall.ReflectorVpnService */
-    public static final String RESTRICTION_ADDRESSES = "vpn.addresses";
-    public static final String RESTRICTION_ROUTES = "vpn.routes";
-    public static final String RESTRICTION_ALLOWED = "vpn.allowed";
-    public static final String RESTRICTION_DISALLOWED = "vpn.disallowed";
+    private static final String RESTRICTION_ALLOWED = "vpn.allowed";
+    private static final String RESTRICTION_DISALLOWED = "vpn.disallowed";
+    private static final String RESTRICTION_DONT_ESTABLISH = "vpn.dont_establish";
+    private static final String CONNECTIVITY_CHECK_HOST = "connectivitycheck.gstatic.com";
+    private static final int VPN_ON_START_TIMEOUT_MS = 5_000;
 
     private String mPackageName;
 
     @Override
     public void setUp() throws Exception {
         super.setUp();
-        // always-on is null by default
+        // Always-on is null by default.
         assertNull(mDevicePolicyManager.getAlwaysOnVpnPackage(ADMIN_RECEIVER_COMPONENT));
         mPackageName = mContext.getPackageName();
     }
@@ -58,11 +67,14 @@
                 /* restrictions */ null);
         super.tearDown();
     }
+
     public void testAlwaysOnVpn() throws Exception {
         // test always-on is null by default
         assertNull(mDevicePolicyManager.getAlwaysOnVpnPackage(ADMIN_RECEIVER_COMPONENT));
 
-        VpnTestHelper.waitForVpn(mContext, VPN_PACKAGE, /* usable */ true);
+        VpnTestHelper.waitForVpn(mContext, VPN_PACKAGE,
+                /* usable */ true, /* lockdown */ true, /* whitelist */ false);
+
         VpnTestHelper.checkPing(TEST_ADDRESS);
     }
 
@@ -83,7 +95,8 @@
         restrictions.putStringArray(RESTRICTION_ALLOWED, new String[] {mPackageName});
         mDevicePolicyManager.setApplicationRestrictions(ADMIN_RECEIVER_COMPONENT, VPN_PACKAGE,
                 restrictions);
-        VpnTestHelper.waitForVpn(mContext, VPN_PACKAGE, /* usable */ true);
+        VpnTestHelper.waitForVpn(mContext, VPN_PACKAGE,
+                /* usable */ true,  /* lockdown */ true, /* whitelist */ false);
         assertTrue(VpnTestHelper.isNetworkVpn(mContext));
     }
 
@@ -92,20 +105,103 @@
         restrictions.putStringArray(RESTRICTION_DISALLOWED, new String[] {mPackageName});
         mDevicePolicyManager.setApplicationRestrictions(ADMIN_RECEIVER_COMPONENT, VPN_PACKAGE,
                 restrictions);
-        VpnTestHelper.waitForVpn(mContext, VPN_PACKAGE, /* usable */ false);
+        VpnTestHelper.waitForVpn(mContext, VPN_PACKAGE,
+                /* usable */ false,  /* lockdown */ true, /* whitelist */ false);
         assertFalse(VpnTestHelper.isNetworkVpn(mContext));
     }
 
+    // Tests that changes to lockdown whitelist are applied correctly.
+    public void testVpnLockdownUpdateWhitelist() throws Exception {
+        assertConnectivity(true, "VPN is off");
+
+        // VPN won't start.
+        final Bundle restrictions = new Bundle();
+        restrictions.putBoolean(RESTRICTION_DONT_ESTABLISH, true);
+        mDevicePolicyManager.setApplicationRestrictions(
+                ADMIN_RECEIVER_COMPONENT, VPN_PACKAGE, restrictions);
+
+        // VPN service is started asynchronously, we need to wait for it to avoid stale service
+        // instance interfering with the next test.
+        final BlockingBroadcastReceiver receiver = VpnTestHelper.registerOnStartReceiver(mContext);
+
+        VpnTestHelper.setAlwaysOnVpn(
+                mContext, VPN_PACKAGE, /* lockdown */ false, /* whitelist */ false);
+        assertConnectivity(true, "VPN service not started, no lockdown");
+        assertNotNull(receiver.awaitForBroadcast(VPN_ON_START_TIMEOUT_MS));
+
+        VpnTestHelper.setAlwaysOnVpn(
+                mContext, VPN_PACKAGE, /* lockdown */ true, /* whitelist */ false);
+        assertConnectivity(false, "VPN in lockdown, service not started");
+        assertNotNull(receiver.awaitForBroadcast(VPN_ON_START_TIMEOUT_MS));
+
+        VpnTestHelper.setAlwaysOnVpn(
+                mContext, VPN_PACKAGE, /* lockdown */ true, /* whitelist */ true);
+        assertConnectivity(true, "VPN in lockdown, service not started, app whitelisted");
+        assertNotNull(receiver.awaitForBroadcast(VPN_ON_START_TIMEOUT_MS));
+
+        VpnTestHelper.setAlwaysOnVpn(
+                mContext, VPN_PACKAGE, /* lockdown */ true, /* whitelist */ false);
+        assertConnectivity(false, "VPN in lockdown, service not started");
+        assertNotNull(receiver.awaitForBroadcast(VPN_ON_START_TIMEOUT_MS));
+
+        receiver.unregisterQuietly();
+    }
+
+    // Tests that when VPN comes up, whitelisted app switches over to it.
+    public void testVpnLockdownWhitelistVpnComesUp() throws Exception {
+        assertConnectivity(true, "VPN is off");
+
+        // VPN won't start initially.
+        final Bundle restrictions = new Bundle();
+        restrictions.putBoolean(RESTRICTION_DONT_ESTABLISH, true);
+        mDevicePolicyManager.setApplicationRestrictions(
+                ADMIN_RECEIVER_COMPONENT, VPN_PACKAGE, restrictions);
+
+        // VPN service is started asynchronously, we need to wait for it to avoid stale service
+        // instance interfering with the next test.
+        final BlockingBroadcastReceiver receiver = VpnTestHelper.registerOnStartReceiver(mContext);
+
+        VpnTestHelper.setAlwaysOnVpn(
+                mContext, VPN_PACKAGE,  /* lockdown */ true, /* whitelist */ true);
+        assertConnectivity(true, "VPN in lockdown, service not started, app whitelisted");
+        assertNotNull(receiver.awaitForBroadcast(VPN_ON_START_TIMEOUT_MS));
+
+        // Make VPN workable again and restart.
+        mDevicePolicyManager.setApplicationRestrictions(
+                ADMIN_RECEIVER_COMPONENT, VPN_PACKAGE, null);
+        VpnTestHelper.waitForVpn(mContext, VPN_PACKAGE,
+                /* usable */ true,  /* lockdown */ true, /* whitelist */ true);
+
+        // Now we should be on VPN.
+        VpnTestHelper.checkPing(TEST_ADDRESS);
+
+        receiver.unregisterQuietly();
+    }
+
     public void testSetNonVpnAlwaysOn() throws Exception {
         // Treat this CTS DPC as an non-vpn app, since it doesn't register
         // android.net.VpnService intent filter in AndroidManifest.xml.
         try {
-            mDevicePolicyManager.setAlwaysOnVpnPackage(ADMIN_RECEIVER_COMPONENT, mPackageName,
-                    true);
+            mDevicePolicyManager.setAlwaysOnVpnPackage(
+                    ADMIN_RECEIVER_COMPONENT, mPackageName, true);
             fail("setAlwaysOnVpnPackage should not accept non-vpn package");
         } catch (UnsupportedOperationException e) {
             // success
         }
         assertNull(mDevicePolicyManager.getAlwaysOnVpnPackage(ADMIN_RECEIVER_COMPONENT));
     }
+
+    private void assertConnectivity(boolean shouldHaveConnectivity, String message) {
+        try {
+            new Socket(CONNECTIVITY_CHECK_HOST, 80);
+            if (!shouldHaveConnectivity) {
+                fail("Connectivity available while not expected: " + message);
+            }
+        } catch (IOException e) {
+            if (shouldHaveConnectivity) {
+                Log.e(TAG, "Connectivity check failed", e);
+                fail("Connectivity isn't available while expected: " + message);
+            }
+        }
+    }
 }
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/vpn/VpnTestHelper.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/vpn/VpnTestHelper.java
index 8c01884..18d3553 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/vpn/VpnTestHelper.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/vpn/VpnTestHelper.java
@@ -23,6 +23,7 @@
 
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertNull;
 import static junit.framework.Assert.assertTrue;
 import static junit.framework.Assert.fail;
 
@@ -38,12 +39,12 @@
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.NetworkInfo;
-import android.net.NetworkRequest;
 import android.os.Build.VERSION_CODES;
 import android.system.ErrnoException;
 import android.system.Os;
 import android.system.StructPollfd;
 
+import com.android.compatibility.common.util.BlockingBroadcastReceiver;
 import com.android.cts.deviceandprofileowner.BaseDeviceAdminTest;
 
 import java.io.ByteArrayOutputStream;
@@ -53,8 +54,11 @@
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
  * Helper class to test vpn status
@@ -63,11 +67,17 @@
 public class VpnTestHelper {
     public static final String VPN_PACKAGE = "com.android.cts.vpnfirewall";
     private static final String MY_PACKAGE = "com.android.cts.deviceandprofileowner";
+    // Broadcast by ReflectorVpnService when the interface is up.
     private static final String ACTION_VPN_IS_UP = VPN_PACKAGE + ".VPN_IS_UP";
+    // Broadcast by ReflectorVpnService receives onStartCommand and queried app restrictions.
+    private static final String ACTION_VPN_ON_START = VPN_PACKAGE + ".VPN_ON_START";
 
     // IP address reserved for documentation by rfc5737
     public static final String TEST_ADDRESS = "192.0.2.4";
 
+    private static final String EXTRA_ALWAYS_ON = "always-on";
+    private static final String EXTRA_LOCKDOWN = "lockdown";
+
     // HACK (TODO issue 31585407) to wait for the network to actually be usable
     private static final int NETWORK_SETTLE_GRACE_MS = 200;
 
@@ -77,11 +87,13 @@
     private static final int NETWORK_TIMEOUT_MS = 5000;
     private static final ComponentName ADMIN_RECEIVER_COMPONENT =
             BaseDeviceAdminTest.ADMIN_RECEIVER_COMPONENT;
-    private static final NetworkRequest VPN_NETWORK_REQUEST = new NetworkRequest.Builder()
-            .addTransportType(NetworkCapabilities.TRANSPORT_VPN)
-            .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
-            .removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-            .build();
+
+    public static BlockingBroadcastReceiver registerOnStartReceiver(Context context) {
+        final BlockingBroadcastReceiver receiver =
+                new BlockingBroadcastReceiver(context, ACTION_VPN_ON_START);
+        receiver.register();
+        return receiver;
+    }
 
     /**
      * Wait for a VPN app to establish VPN.
@@ -89,10 +101,13 @@
      * @param context Caller's context.
      * @param packageName {@code null} if waiting for the existing VPN to connect. Otherwise we set
      *         this package as the new always-on VPN app and wait for it to connect.
+     * @param lockdown Disallow connectivity while VPN is down.
      * @param usable Whether the resulting VPN tunnel is expected to be usable.
+     * @param whitelist whether to whitelist current package from lockdown.
      */
-    public static void waitForVpn(Context context, String packageName, boolean usable) {
-        DevicePolicyManager dpm = context.getSystemService(DevicePolicyManager.class);
+    public static void waitForVpn(Context context, String packageName, boolean usable,
+            boolean lockdown, boolean whitelist) {
+        final DevicePolicyManager dpm = context.getSystemService(DevicePolicyManager.class);
         if (packageName == null) {
             assertNotNull(dpm.getAlwaysOnVpnPackage(ADMIN_RECEIVER_COMPONENT));
         }
@@ -100,10 +115,14 @@
         ConnectivityManager cm = context.getSystemService(ConnectivityManager.class);
         final CountDownLatch vpnLatch = new CountDownLatch(1);
         final IntentFilter intentFilter = new IntentFilter(ACTION_VPN_IS_UP);
+        final AtomicBoolean isAlwaysOn = new AtomicBoolean();
+        final AtomicBoolean isLockdown = new AtomicBoolean();
         final BroadcastReceiver receiver = new BroadcastReceiver() {
                 @Override
                 public void onReceive(final Context context, final Intent intent) {
                     if (!intent.getPackage().equals(MY_PACKAGE)) return;
+                    isAlwaysOn.set(intent.getBooleanExtra(EXTRA_ALWAYS_ON, false));
+                    isLockdown.set(intent.getBooleanExtra(EXTRA_LOCKDOWN, !lockdown));
                     vpnLatch.countDown();
                     context.unregisterReceiver(this);
                 }
@@ -112,13 +131,15 @@
 
         try {
             if (packageName != null) {
-                dpm.setAlwaysOnVpnPackage(ADMIN_RECEIVER_COMPONENT, packageName, true);
-                assertEquals(packageName, dpm.getAlwaysOnVpnPackage(ADMIN_RECEIVER_COMPONENT));
+                setAlwaysOnVpn(context, packageName, lockdown, whitelist);
             }
             if (!vpnLatch.await(NETWORK_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
                 if (!isNetworkVpn(context)) {
                     fail("Took too long waiting to establish a VPN-backed connection");
                 }
+            } else {
+                assertTrue("Wrong VpnService#isAlwaysOn()", isAlwaysOn.get());
+                assertEquals("Wrong VpnService#isLockdownEnabled()", lockdown, isLockdown.get());
             }
             Thread.sleep(NETWORK_SETTLE_GRACE_MS);
         } catch (InterruptedException | PackageManager.NameNotFoundException e) {
@@ -133,6 +154,25 @@
         assertEquals(usable, vpnInfo.isConnected());
     }
 
+    public static void setAlwaysOnVpn(
+            Context context, String packageName, boolean lockdown, boolean whitelist)
+            throws PackageManager.NameNotFoundException {
+        final DevicePolicyManager dpm = context.getSystemService(DevicePolicyManager.class);
+        final List<String> lockdownWhitelist;
+        if (lockdown) {
+            lockdownWhitelist = whitelist ?
+                    Collections.singletonList(context.getPackageName()) : Collections.emptyList();
+        } else {
+            lockdownWhitelist = null;
+        }
+        dpm.setAlwaysOnVpnPackage(
+                ADMIN_RECEIVER_COMPONENT, packageName, lockdown, lockdownWhitelist);
+        assertEquals(packageName, dpm.getAlwaysOnVpnPackage(ADMIN_RECEIVER_COMPONENT));
+        assertEquals(lockdown, dpm.isAlwaysOnVpnLockdownEnabled(ADMIN_RECEIVER_COMPONENT));
+        assertEquals(lockdownWhitelist,
+                    dpm.getAlwaysOnVpnLockdownWhitelist(ADMIN_RECEIVER_COMPONENT));
+    }
+
     public static boolean isNetworkVpn(Context context) {
         ConnectivityManager connectivityManager =
                 (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
diff --git a/hostsidetests/devicepolicy/app/LauncherTests/src/com/android/cts/launchertests/LauncherAppsTests.java b/hostsidetests/devicepolicy/app/LauncherTests/src/com/android/cts/launchertests/LauncherAppsTests.java
index 73dfbc1..a94eaff 100644
--- a/hostsidetests/devicepolicy/app/LauncherTests/src/com/android/cts/launchertests/LauncherAppsTests.java
+++ b/hostsidetests/devicepolicy/app/LauncherTests/src/com/android/cts/launchertests/LauncherAppsTests.java
@@ -61,6 +61,8 @@
     public static final String PACKAGE_EXTRA = "package_extra";
     public static final String REPLY_EXTRA = "reply_extra";
 
+    private static final String MANAGED_PROFILE_PKG = "com.android.cts.managedprofile";
+
     public static final int MSG_RESULT = 0;
     public static final int MSG_CHECK_PACKAGE_ADDED = 1;
     public static final int MSG_CHECK_PACKAGE_REMOVED = 2;
@@ -213,6 +215,14 @@
         // NoLaunchableActivityApp is installed for duration of this test - make sure
         // it's present on the activity list, has the synthetic activity generated, and it's
         // enabled and exported
+        assertActivityInjected(NO_LAUNCHABLE_ACTIVITY_APP_PACKAGE);
+    }
+
+    public void testProfileOwnerLauncherActivityInjected() throws Exception {
+        assertActivityInjected(MANAGED_PROFILE_PKG);
+    }
+
+    private void assertActivityInjected(String targetPackage) {
         List<LauncherActivityInfo> activities = mLauncherApps.getActivityList(null, mUser);
         boolean noLaunchableActivityAppFound = false;
         for (LauncherActivityInfo activity : activities) {
@@ -220,7 +230,7 @@
                 continue;
             }
             ComponentName compName = activity.getComponentName();
-            if (compName.getPackageName().equals(NO_LAUNCHABLE_ACTIVITY_APP_PACKAGE)) {
+            if (compName.getPackageName().equals(targetPackage)) {
                 noLaunchableActivityAppFound = true;
                 // make sure it points to the synthetic app details activity
                 assertEquals(activity.getName(), SYNTHETIC_APP_DETAILS_ACTIVITY);
@@ -238,17 +248,25 @@
         assertTrue(noLaunchableActivityAppFound);
     }
 
-    public void testNoInjectedActivityFound() throws Exception {
+    public void testNoTestAppInjectedActivityFound() throws Exception {
         // NoLaunchableActivityApp is installed for duration of this test - make sure
         // it's NOT present on the activity list
+        assertInjectedActivityNotFound(NO_LAUNCHABLE_ACTIVITY_APP_PACKAGE);
+    }
+
+    public void testProfileOwnerInjectedActivityNotFound() throws Exception {
+        assertInjectedActivityNotFound(MANAGED_PROFILE_PKG);
+    }
+
+    private void assertInjectedActivityNotFound(String targetPackage) {
         List<LauncherActivityInfo> activities = mLauncherApps.getActivityList(null, mUser);
         for (LauncherActivityInfo activity : activities) {
             if (!activity.getUser().equals(mUser)) {
                 continue;
             }
             ComponentName compName = activity.getComponentName();
-            if (compName.getPackageName().equals(NO_LAUNCHABLE_ACTIVITY_APP_PACKAGE)) {
-                fail("Injected activity found in package: " + compName.getPackageName());
+            if (compName.getPackageName().equals(targetPackage)) {
+                fail("Injected activity found: " + compName.flattenToString());
             }
         }
     }
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/AndroidManifest.xml b/hostsidetests/devicepolicy/app/ManagedProfile/AndroidManifest.xml
index e0e3f08..05c6eb7 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/AndroidManifest.xml
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/AndroidManifest.xml
@@ -168,7 +168,7 @@
             android:name=".DummyCrossProfileViewEventActivity"
             android:exported="true">
             <intent-filter>
-                <action android:name="android.provider.calendar.action.VIEW_WORK_CALENDAR_EVENT"/>
+                <action android:name="android.provider.calendar.action.VIEW_MANAGED_PROFILE_CALENDAR_EVENT"/>
                 <category android:name="android.intent.category.DEFAULT"/>
             </intent-filter>
         </activity>
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DummyCrossProfileViewEventActivity.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DummyCrossProfileViewEventActivity.java
index 3e5490b..ae48084 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DummyCrossProfileViewEventActivity.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DummyCrossProfileViewEventActivity.java
@@ -40,9 +40,9 @@
     public void onStart() {
         super.onStart();
         // Only set the text when managed profile is getting the
-        // ACTION_VIEW_WORK_CALENDAR_EVENT intent.
+        // ACTION_VIEW_MANAGED_PROFILE_CALENDAR_EVENT intent.
         final Intent intent = getIntent();
-        if (intent.getAction() == CalendarContract.ACTION_VIEW_WORK_CALENDAR_EVENT
+        if (intent.getAction() == CalendarContract.ACTION_VIEW_MANAGED_PROFILE_CALENDAR_EVENT
                 && isManagedProfile()) {
             TextView textView = findViewById(R.id.view_event_text);
             final Bundle bundle = getIntent().getExtras();
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/WifiTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/WifiTest.java
index 3b2c7f8..617953d 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/WifiTest.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/WifiTest.java
@@ -24,6 +24,8 @@
 import android.os.SystemClock;
 import android.test.AndroidTestCase;
 
+import com.android.compatibility.common.util.SystemUtil;
+
 import java.util.List;
 import java.util.concurrent.TimeUnit;
 
@@ -61,6 +63,7 @@
         mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE);
         mWifiEnabled = mWifiManager.isWifiEnabled();
         if (!mWifiEnabled) {
+            SystemUtil.runShellCommand("svc wifi enable");
             mWifiManager.setWifiEnabled(true);
             awaitWifiEnabledState(true);
         }
@@ -69,7 +72,7 @@
     @Override
     public void tearDown() throws Exception {
         if (!mWifiEnabled) {
-            mWifiManager.setWifiEnabled(false);
+            SystemUtil.runShellCommand("svc wifi disable");
             awaitWifiEnabledState(false);
         }
         super.tearDown();
diff --git a/hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/BackupServicePoliciesTest.java b/hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/BackupServicePoliciesTest.java
new file mode 100644
index 0000000..573f041
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/BackupServicePoliciesTest.java
@@ -0,0 +1,15 @@
+package com.android.cts.profileowner;
+
+public class BackupServicePoliciesTest extends BaseProfileOwnerTest {
+  /**
+   * Test: Test enabling and disabling backup service. This test should be executed after installing
+   * a profile owner so that we check that backup service is not enabled by default.
+   */
+  public void testEnablingAndDisablingBackupService() {
+    assertFalse(mDevicePolicyManager.isBackupServiceEnabled(getWho()));
+    mDevicePolicyManager.setBackupServiceEnabled(getWho(), true);
+    assertTrue(mDevicePolicyManager.isBackupServiceEnabled(getWho()));
+    mDevicePolicyManager.setBackupServiceEnabled(getWho(), false);
+    assertFalse(mDevicePolicyManager.isBackupServiceEnabled(getWho()));
+  }
+}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
index c9c31f8..260b730 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
@@ -435,28 +435,18 @@
 
     @RequiresDevice
     public void testAlwaysOnVpnAcrossReboot() throws Exception {
-        // Note: Always-on VPN is supported on non-FBE devices as well, and the behavior should be
-        // the same. However we're only testing the FBE case here as we need to set a device
-        // password during the test. This would cause FDE devices (e.g. angler) to prompt for the
-        // password during reboot, which we can't handle easily.
-        if (!mHasFeature || !mSupportsFbe || !mHasSecureLockScreen) {
+        if (!mHasFeature) {
             return;
         }
 
-        // Set a password to encrypt the user
-        final String testPassword = "1234";
-        changeUserCredential(testPassword, null /*oldCredential*/, mUserId);
-
         try {
             installAppAsUser(VPN_APP_APK, mUserId);
-            executeDeviceTestMethod(".AlwaysOnVpnMultiStageTest", "testAlwaysOnSet");
+            executeDeviceTestMethod(".AlwaysOnVpnMultiStageTest", "testAlwaysOnSetWithWhitelist");
             rebootAndWaitUntilReady();
             // Make sure profile user initialization is complete before proceeding.
             waitForBroadcastIdle();
-            verifyUserCredential(testPassword, mUserId);
             executeDeviceTestMethod(".AlwaysOnVpnMultiStageTest", "testAlwaysOnSetAfterReboot");
         } finally {
-            changeUserCredential(null /*newCredential*/, testPassword, mUserId);
             executeDeviceTestMethod(".AlwaysOnVpnMultiStageTest", "testCleanup");
         }
     }
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
index 7428066..866bdff 100755
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
@@ -72,6 +72,9 @@
     private static final String ARG_NETWORK_LOGGING_BATCH_COUNT = "batchCount";
     private static final String TEST_UPDATE_LOCATION = "/data/local/tmp/cts/deviceowner";
 
+    private static final String LAUNCHER_TESTS_NO_LAUNCHABLE_ACTIVITY_APK =
+            "CtsNoLaunchableActivityApp.apk";
+
     /**
      * Copied from {@link
      * DevicePolicyManager.InstallUpdateCallback#UPDATE_ERROR_UPDATE_FILE_INVALID }
@@ -1082,6 +1085,29 @@
                     .build());
     }
 
+    public void testNoHiddenActivityFoundTest() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        try {
+            // Install app to primary user
+            installAppAsUser(BaseLauncherAppsTest.LAUNCHER_TESTS_APK, mPrimaryUserId);
+            installAppAsUser(BaseLauncherAppsTest.LAUNCHER_TESTS_SUPPORT_APK, mPrimaryUserId);
+            installAppAsUser(LAUNCHER_TESTS_NO_LAUNCHABLE_ACTIVITY_APK, mPrimaryUserId);
+
+            // Run test to check if launcher api shows hidden app
+            String mSerialNumber = Integer.toString(getUserSerialNumber(USER_SYSTEM));
+            runDeviceTestsAsUser(BaseLauncherAppsTest.LAUNCHER_TESTS_PKG,
+                    BaseLauncherAppsTest.LAUNCHER_TESTS_CLASS, "testNoInjectedActivityFound",
+                    mPrimaryUserId, Collections.singletonMap(BaseLauncherAppsTest.PARAM_TEST_USER,
+                            mSerialNumber));
+        } finally {
+            getDevice().uninstallPackage(LAUNCHER_TESTS_NO_LAUNCHABLE_ACTIVITY_APK);
+            getDevice().uninstallPackage(BaseLauncherAppsTest.LAUNCHER_TESTS_SUPPORT_APK);
+            getDevice().uninstallPackage(BaseLauncherAppsTest.LAUNCHER_TESTS_APK);
+        }
+    }
+
     private void executeDeviceOwnerTest(String testClassName) throws Exception {
         if (!mHasFeature) {
             return;
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/LauncherAppsProfileTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/LauncherAppsProfileTest.java
index 12624fa..ddf8361 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/LauncherAppsProfileTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/LauncherAppsProfileTest.java
@@ -109,6 +109,18 @@
                 mProfileUserId);
     }
 
+    public void testProfileOwnerAppHiddenInPrimaryProfile() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        String command = "pm disable --user " + mParentUserId + " " + MANAGED_PROFILE_PKG
+                + "/.PrimaryUserFilterSetterActivity";
+        CLog.d("Output for command " + command + ": " + getDevice().executeShellCommand(command));
+        runDeviceTestsAsUser(LAUNCHER_TESTS_PKG,
+                LAUNCHER_TESTS_CLASS, "testProfileOwnerInjectedActivityNotFound",
+                mParentUserId, Collections.singletonMap(PARAM_TEST_USER, mMainUserSerialNumber));
+    }
+
     public void testNoHiddenActivityInProfile() throws Exception {
         if (!mHasFeature) {
             return;
@@ -119,7 +131,7 @@
 
         // Run tests to check SimpleApp exists in both profile and main user.
         runDeviceTestsAsUser(LAUNCHER_TESTS_PKG,
-                LAUNCHER_TESTS_CLASS, "testNoInjectedActivityFound",
+                LAUNCHER_TESTS_CLASS, "testNoTestAppInjectedActivityFound",
                 mParentUserId, Collections.singletonMap(PARAM_TEST_USER, mProfileSerialNumber));
         runDeviceTestsAsUser(LAUNCHER_TESTS_PKG,
                 LAUNCHER_TESTS_CLASS, "testNoLaunchableActivityAppHasAppDetailsActivityInjected",
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
index 0d6225c..b83fbcd 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
@@ -110,7 +110,8 @@
 
         // We need multi user to be supported in order to create a profile of the user owner.
         mHasFeature = mHasFeature && hasDeviceFeature("android.software.managed_users");
-        mHasNfcFeature = hasDeviceFeature("android.hardware.nfc");
+        mHasNfcFeature = hasDeviceFeature("android.hardware.nfc")
+                && hasDeviceFeature("android.sofware.nfc.beam");
 
         if (mHasFeature) {
             removeTestUsers();
@@ -377,28 +378,6 @@
         }
     }
 
-    /**
-     * Verify that removing a managed profile will remove all networks owned by that profile.
-     */
-    public void testProfileWifiCleanup() throws Exception {
-        if (!mHasFeature || !hasDeviceFeature(FEATURE_WIFI)) {
-            return;
-        }
-        installAppAsUser(WIFI_CONFIG_CREATOR_APK, mProfileUserId);
-
-        runDeviceTestsAsUser(
-                MANAGED_PROFILE_PKG, ".WifiTest", "testRemoveWifiNetworkIfExists", mParentUserId);
-
-        runDeviceTestsAsUser(
-                MANAGED_PROFILE_PKG, ".WifiTest", "testAddWifiNetwork", mProfileUserId);
-
-        // Now delete the user - should undo the effect of testAddWifiNetwork.
-        removeUser(mProfileUserId);
-        runDeviceTestsAsUser(
-                MANAGED_PROFILE_PKG, ".WifiTest", "testWifiNetworkDoesNotExist",
-                mParentUserId);
-    }
-
     public void testWifiMacAddress() throws Exception {
         if (!mHasFeature || !hasDeviceFeature(FEATURE_WIFI)) {
             return;
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/PasswordComplexityTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/PasswordComplexityTest.java
index 958009f..5c105cb 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/PasswordComplexityTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/PasswordComplexityTest.java
@@ -1,5 +1,11 @@
 package com.android.cts.devicepolicy;
 
+import static com.android.cts.devicepolicy.metrics.DevicePolicyEventLogVerifier.assertMetricsLogged;
+
+import android.stats.devicepolicy.EventId;
+
+import com.android.cts.devicepolicy.metrics.DevicePolicyEventWrapper;
+
 /** Host-side tests to run the CtsPasswordComplexity device-side tests. */
 public class PasswordComplexityTest extends BaseDevicePolicyTest {
 
@@ -36,6 +42,12 @@
         if (!mHasSecureLockScreen) {
             return;
         }
-        runDeviceTestsAsUser(PKG, CLS, mPrimaryUserId);
+
+        assertMetricsLogged(
+                getDevice(),
+                () -> runDeviceTestsAsUser(PKG, CLS, mPrimaryUserId),
+                new DevicePolicyEventWrapper
+                        .Builder(EventId.GET_USER_PASSWORD_COMPLEXITY_LEVEL_VALUE)
+                        .setStrings(PKG).build());
     }
 }
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ProfileOwnerTest.java
index befb47c..0b5cdef 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ProfileOwnerTest.java
@@ -21,6 +21,7 @@
 public class ProfileOwnerTest extends BaseDevicePolicyTest {
     private static final String PROFILE_OWNER_PKG = "com.android.cts.profileowner";
     private static final String PROFILE_OWNER_APK = "CtsProfileOwnerApp.apk";
+    private static final String FEATURE_BACKUP = "android.software.backup";
 
     private static final String ADMIN_RECEIVER_TEST_CLASS =
             PROFILE_OWNER_PKG + ".BaseProfileOwnerTest$BasicAdminReceiver";
@@ -74,6 +75,15 @@
         executeProfileOwnerTest("AppUsageObserverTest");
     }
 
+    public void testBackupServiceEnabling() throws Exception {
+        final boolean hasBackupService = getDevice().hasFeature(FEATURE_BACKUP);
+        // The backup service cannot be enabled if the backup feature is not supported.
+        if (!mHasFeature || !hasBackupService) {
+            return;
+        }
+        executeProfileOwnerTest("BackupServicePoliciesTest");
+    }
+
     @Override
     protected void tearDown() throws Exception {
         if (mHasFeature) {
diff --git a/hostsidetests/dexmetadata/TEST_MAPPING b/hostsidetests/dexmetadata/TEST_MAPPING
new file mode 100644
index 0000000..f1068cc
--- /dev/null
+++ b/hostsidetests/dexmetadata/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+      "name": "CtsDexMetadataHostTestCases"
+    }
+  ]
+}
diff --git a/hostsidetests/dexmetadata/host/Android.mk b/hostsidetests/dexmetadata/host/Android.mk
index a51ddd2..cae13cd 100644
--- a/hostsidetests/dexmetadata/host/Android.mk
+++ b/hostsidetests/dexmetadata/host/Android.mk
@@ -29,6 +29,6 @@
     tradefed
 
 # tag this module as test artifact for cts
-LOCAL_COMPATIBILITY_SUITE := cts
+LOCAL_COMPATIBILITY_SUITE := cts general-tests
 
 include $(BUILD_CTS_HOST_JAVA_LIBRARY)
diff --git a/hostsidetests/dumpsys/AndroidTest.xml b/hostsidetests/dumpsys/AndroidTest.xml
index ead52be..11ab26f 100644
--- a/hostsidetests/dumpsys/AndroidTest.xml
+++ b/hostsidetests/dumpsys/AndroidTest.xml
@@ -18,6 +18,7 @@
     <option name="config-descriptor:metadata" key="component" value="framework" />
     <!-- This module tests system service dumps, which is irrelevant for Instant Apps. -->
     <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
     <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest">
         <option name="jar" value="CtsDumpsysHostTestCases.jar" />
     </test>
diff --git a/hostsidetests/edi/AndroidTest.xml b/hostsidetests/edi/AndroidTest.xml
index b0d5d9f..fdbe2cb 100644
--- a/hostsidetests/edi/AndroidTest.xml
+++ b/hostsidetests/edi/AndroidTest.xml
@@ -16,8 +16,8 @@
 <configuration description="Config for CTS EDI host test cases">
     <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="deviceinfo" />
-    <!-- Included not for instant-app but to collect the required information for the run -->
-    <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
+    <!-- Do no need to run instant mode for collecting information -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
     <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
         <option name="jar" value="CtsEdiHostTestCases.jar" />
     </test>
diff --git a/hostsidetests/jdwpsecurity/TEST_MAPPING b/hostsidetests/jdwpsecurity/TEST_MAPPING
new file mode 100644
index 0000000..2d29584
--- /dev/null
+++ b/hostsidetests/jdwpsecurity/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+       "name": "CtsJdwpSecurityHostTestCases"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/hostsidetests/jvmti/allocation-tracking/AndroidTest.xml b/hostsidetests/jvmti/allocation-tracking/AndroidTest.xml
index 21a5cc7..0760f04 100644
--- a/hostsidetests/jvmti/allocation-tracking/AndroidTest.xml
+++ b/hostsidetests/jvmti/allocation-tracking/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts" />
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/attaching/host/AndroidTest.xml b/hostsidetests/jvmti/attaching/host/AndroidTest.xml
index 710b751..5972229 100644
--- a/hostsidetests/jvmti/attaching/host/AndroidTest.xml
+++ b/hostsidetests/jvmti/attaching/host/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI Attaching test cases">
     <option name="test-suite-tag" value="cts" />
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/redefining/AndroidTest.xml b/hostsidetests/jvmti/redefining/AndroidTest.xml
index 1d04cb9..a7d8d669 100644
--- a/hostsidetests/jvmti/redefining/AndroidTest.xml
+++ b/hostsidetests/jvmti/redefining/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts" />
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-1900/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-1900/AndroidTest.xml
index c042f22..b6f221d 100644
--- a/hostsidetests/jvmti/run-tests/test-1900/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-1900/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-1901/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-1901/AndroidTest.xml
index 2ad6ce1..40e788a 100644
--- a/hostsidetests/jvmti/run-tests/test-1901/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-1901/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-1902/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-1902/AndroidTest.xml
index 9144779..00861dc 100644
--- a/hostsidetests/jvmti/run-tests/test-1902/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-1902/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-1903/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-1903/AndroidTest.xml
index 6aeb66c..45bfca2 100644
--- a/hostsidetests/jvmti/run-tests/test-1903/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-1903/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-1904/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-1904/AndroidTest.xml
index 86633dd..de81390 100644
--- a/hostsidetests/jvmti/run-tests/test-1904/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-1904/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-1906/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-1906/AndroidTest.xml
index fe51dfd..93d6f5a 100644
--- a/hostsidetests/jvmti/run-tests/test-1906/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-1906/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-1907/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-1907/AndroidTest.xml
index e3cfbb5..a3ecbe8 100644
--- a/hostsidetests/jvmti/run-tests/test-1907/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-1907/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-1908/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-1908/AndroidTest.xml
index 7a1f578..c3645b7 100644
--- a/hostsidetests/jvmti/run-tests/test-1908/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-1908/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-1909/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-1909/AndroidTest.xml
index 34d9df1..b7f4690 100644
--- a/hostsidetests/jvmti/run-tests/test-1909/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-1909/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-1910/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-1910/AndroidTest.xml
index 123c998..323662a 100644
--- a/hostsidetests/jvmti/run-tests/test-1910/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-1910/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-1911/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-1911/AndroidTest.xml
index aea50bb..98f36dd 100644
--- a/hostsidetests/jvmti/run-tests/test-1911/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-1911/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-1912/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-1912/AndroidTest.xml
index 2fe4159..b9202e1 100644
--- a/hostsidetests/jvmti/run-tests/test-1912/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-1912/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-1913/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-1913/AndroidTest.xml
index be5ad38..bb270d3 100644
--- a/hostsidetests/jvmti/run-tests/test-1913/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-1913/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-1914/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-1914/AndroidTest.xml
index 0740b38..8657601 100644
--- a/hostsidetests/jvmti/run-tests/test-1914/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-1914/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-1915/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-1915/AndroidTest.xml
index 13a3b8c..ca42ad0 100644
--- a/hostsidetests/jvmti/run-tests/test-1915/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-1915/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-1916/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-1916/AndroidTest.xml
index bd65112..55a3bbf 100644
--- a/hostsidetests/jvmti/run-tests/test-1916/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-1916/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-1917/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-1917/AndroidTest.xml
index f859f1a..f049040 100644
--- a/hostsidetests/jvmti/run-tests/test-1917/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-1917/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-1920/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-1920/AndroidTest.xml
index 56f2079..bcc276e 100644
--- a/hostsidetests/jvmti/run-tests/test-1920/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-1920/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-1921/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-1921/AndroidTest.xml
index bf57784..de35460 100644
--- a/hostsidetests/jvmti/run-tests/test-1921/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-1921/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-1922/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-1922/AndroidTest.xml
index 08a775a..7fa7d38 100644
--- a/hostsidetests/jvmti/run-tests/test-1922/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-1922/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-1923/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-1923/AndroidTest.xml
index 5f30957..d12cc61 100644
--- a/hostsidetests/jvmti/run-tests/test-1923/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-1923/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-1924/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-1924/AndroidTest.xml
index ea7fe12..a9a8245 100644
--- a/hostsidetests/jvmti/run-tests/test-1924/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-1924/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-1925/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-1925/AndroidTest.xml
index 5116d65..0c003be 100644
--- a/hostsidetests/jvmti/run-tests/test-1925/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-1925/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-1926/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-1926/AndroidTest.xml
index 23250a0..c12ae92 100644
--- a/hostsidetests/jvmti/run-tests/test-1926/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-1926/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-1927/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-1927/AndroidTest.xml
index 018eaa2..2154147 100644
--- a/hostsidetests/jvmti/run-tests/test-1927/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-1927/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-1928/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-1928/AndroidTest.xml
index 6abb462..3691021 100644
--- a/hostsidetests/jvmti/run-tests/test-1928/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-1928/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-1930/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-1930/AndroidTest.xml
index 52042c5..de9822c 100644
--- a/hostsidetests/jvmti/run-tests/test-1930/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-1930/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-1931/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-1931/AndroidTest.xml
index df176fd..1a37af6 100644
--- a/hostsidetests/jvmti/run-tests/test-1931/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-1931/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-1932/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-1932/AndroidTest.xml
index 3d88bc4..6e5f0b1c 100644
--- a/hostsidetests/jvmti/run-tests/test-1932/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-1932/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-1933/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-1933/AndroidTest.xml
index 4d87c55..90df47b 100644
--- a/hostsidetests/jvmti/run-tests/test-1933/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-1933/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-1934/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-1934/AndroidTest.xml
index c7ee6f1..fbb5a20 100644
--- a/hostsidetests/jvmti/run-tests/test-1934/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-1934/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-1936/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-1936/AndroidTest.xml
index e5ff702..8605d7e 100644
--- a/hostsidetests/jvmti/run-tests/test-1936/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-1936/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-1937/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-1937/AndroidTest.xml
index 9ea6184..c2b38b1 100644
--- a/hostsidetests/jvmti/run-tests/test-1937/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-1937/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-1939/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-1939/AndroidTest.xml
index ac510c1..62a9fe5 100644
--- a/hostsidetests/jvmti/run-tests/test-1939/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-1939/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-1941/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-1941/AndroidTest.xml
index dc68b7a..b958615 100644
--- a/hostsidetests/jvmti/run-tests/test-1941/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-1941/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-1942/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-1942/AndroidTest.xml
index 15913d3..82d03a6 100644
--- a/hostsidetests/jvmti/run-tests/test-1942/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-1942/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-1943/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-1943/AndroidTest.xml
index c03d4d9..997f914 100644
--- a/hostsidetests/jvmti/run-tests/test-1943/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-1943/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-1953/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-1953/AndroidTest.xml
index 9309740..3e4e876 100644
--- a/hostsidetests/jvmti/run-tests/test-1953/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-1953/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-1958/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-1958/AndroidTest.xml
index 313ff2b..b30faae 100644
--- a/hostsidetests/jvmti/run-tests/test-1958/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-1958/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-902/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-902/AndroidTest.xml
index 42e8698..25f2011 100644
--- a/hostsidetests/jvmti/run-tests/test-902/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-902/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts" />
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-903/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-903/AndroidTest.xml
index 4b33b2d..0d2d039 100644
--- a/hostsidetests/jvmti/run-tests/test-903/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-903/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts" />
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-904/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-904/AndroidTest.xml
index 57f6027..8a0f43e 100644
--- a/hostsidetests/jvmti/run-tests/test-904/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-904/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts" />
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-905/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-905/AndroidTest.xml
index a0e2e05..3aa6007 100644
--- a/hostsidetests/jvmti/run-tests/test-905/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-905/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts" />
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-906/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-906/AndroidTest.xml
index 38d2abe..47d077a 100644
--- a/hostsidetests/jvmti/run-tests/test-906/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-906/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts" />
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-907/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-907/AndroidTest.xml
index af587f3..b38c4c0 100644
--- a/hostsidetests/jvmti/run-tests/test-907/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-907/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts" />
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-908/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-908/AndroidTest.xml
index c2feb1a..f4713e3 100644
--- a/hostsidetests/jvmti/run-tests/test-908/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-908/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts" />
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-910/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-910/AndroidTest.xml
index 32f135f..4ea65ee 100644
--- a/hostsidetests/jvmti/run-tests/test-910/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-910/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts" />
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-911/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-911/AndroidTest.xml
index 1832662..4990071 100644
--- a/hostsidetests/jvmti/run-tests/test-911/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-911/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts" />
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-912/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-912/AndroidTest.xml
index 4ba486e..fe7c701 100644
--- a/hostsidetests/jvmti/run-tests/test-912/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-912/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts" />
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-913/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-913/AndroidTest.xml
index a24a927..3b44442 100644
--- a/hostsidetests/jvmti/run-tests/test-913/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-913/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts" />
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-914/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-914/AndroidTest.xml
index efbc392..5652db8 100644
--- a/hostsidetests/jvmti/run-tests/test-914/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-914/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts" />
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-915/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-915/AndroidTest.xml
index 02239d7..eee4d4b 100644
--- a/hostsidetests/jvmti/run-tests/test-915/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-915/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts" />
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-917/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-917/AndroidTest.xml
index 5726e10..bb4ba24 100644
--- a/hostsidetests/jvmti/run-tests/test-917/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-917/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts" />
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-918/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-918/AndroidTest.xml
index 7d9b72a..85dbdda 100644
--- a/hostsidetests/jvmti/run-tests/test-918/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-918/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts" />
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-919/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-919/AndroidTest.xml
index eb22191..d90b9e5 100644
--- a/hostsidetests/jvmti/run-tests/test-919/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-919/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts" />
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-920/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-920/AndroidTest.xml
index 9c6d09b..38eb72f 100644
--- a/hostsidetests/jvmti/run-tests/test-920/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-920/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts" />
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-922/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-922/AndroidTest.xml
index c2e21f1..4389b10 100644
--- a/hostsidetests/jvmti/run-tests/test-922/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-922/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts" />
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-923/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-923/AndroidTest.xml
index f9c586a..1ecad38 100644
--- a/hostsidetests/jvmti/run-tests/test-923/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-923/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts" />
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-924/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-924/AndroidTest.xml
index fa355f2..50f690b 100644
--- a/hostsidetests/jvmti/run-tests/test-924/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-924/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts" />
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-926/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-926/AndroidTest.xml
index a50a51d..f4552db 100644
--- a/hostsidetests/jvmti/run-tests/test-926/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-926/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts" />
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-927/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-927/AndroidTest.xml
index 5c02f07..9f5e79e 100644
--- a/hostsidetests/jvmti/run-tests/test-927/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-927/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts" />
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-928/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-928/AndroidTest.xml
index bf6f02c..9d38cf8 100644
--- a/hostsidetests/jvmti/run-tests/test-928/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-928/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts" />
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-930/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-930/AndroidTest.xml
index 2599ea5..7c3852f 100644
--- a/hostsidetests/jvmti/run-tests/test-930/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-930/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts" />
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-931/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-931/AndroidTest.xml
index 2f8a15d..d11e522 100644
--- a/hostsidetests/jvmti/run-tests/test-931/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-931/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts" />
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-932/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-932/AndroidTest.xml
index aa2b9db..5bc2b52 100644
--- a/hostsidetests/jvmti/run-tests/test-932/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-932/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts" />
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-940/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-940/AndroidTest.xml
index 2f35ce7..98709d4 100644
--- a/hostsidetests/jvmti/run-tests/test-940/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-940/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts" />
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-942/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-942/AndroidTest.xml
index bad7710..3404377 100644
--- a/hostsidetests/jvmti/run-tests/test-942/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-942/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts" />
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-944/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-944/AndroidTest.xml
index 1227f06..1949c01 100644
--- a/hostsidetests/jvmti/run-tests/test-944/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-944/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts" />
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-945/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-945/AndroidTest.xml
index dc7254a..a40edaa 100644
--- a/hostsidetests/jvmti/run-tests/test-945/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-945/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts" />
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-947/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-947/AndroidTest.xml
index cd5586e..cbb508f 100644
--- a/hostsidetests/jvmti/run-tests/test-947/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-947/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts" />
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-951/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-951/AndroidTest.xml
index 844b5a4..0d3aa78 100644
--- a/hostsidetests/jvmti/run-tests/test-951/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-951/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts" />
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-982/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-982/AndroidTest.xml
index 102db35..d946a36 100644
--- a/hostsidetests/jvmti/run-tests/test-982/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-982/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts" />
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-983/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-983/AndroidTest.xml
index 707d790..33bee46 100644
--- a/hostsidetests/jvmti/run-tests/test-983/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-983/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art"/>
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true"/>
diff --git a/hostsidetests/jvmti/run-tests/test-984/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-984/AndroidTest.xml
index 33eedb0..e97d9ad 100644
--- a/hostsidetests/jvmti/run-tests/test-984/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-984/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts" />
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-985/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-985/AndroidTest.xml
index 684833d..8554795 100644
--- a/hostsidetests/jvmti/run-tests/test-985/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-985/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts" />
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-986/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-986/AndroidTest.xml
index 170193e..016545d 100644
--- a/hostsidetests/jvmti/run-tests/test-986/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-986/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts" />
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-988/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-988/AndroidTest.xml
index edb8e2f..5db646a 100644
--- a/hostsidetests/jvmti/run-tests/test-988/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-988/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-989/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-989/AndroidTest.xml
index 46224f0..c590530 100644
--- a/hostsidetests/jvmti/run-tests/test-989/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-989/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-990/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-990/AndroidTest.xml
index 9603521..8f1e64b 100644
--- a/hostsidetests/jvmti/run-tests/test-990/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-990/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-991/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-991/AndroidTest.xml
index 771978a..94b67ae 100644
--- a/hostsidetests/jvmti/run-tests/test-991/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-991/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-992/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-992/AndroidTest.xml
index 814dff6..437521e 100644
--- a/hostsidetests/jvmti/run-tests/test-992/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-992/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-993/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-993/AndroidTest.xml
index 951a3bf..cf92806 100644
--- a/hostsidetests/jvmti/run-tests/test-993/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-993/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-994/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-994/AndroidTest.xml
index 47d61dc..a97b540 100644
--- a/hostsidetests/jvmti/run-tests/test-994/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-994/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-995/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-995/AndroidTest.xml
index 0278f01..cf3fe8a 100644
--- a/hostsidetests/jvmti/run-tests/test-995/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-995/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-996/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-996/AndroidTest.xml
index 208c34c..4b67330 100644
--- a/hostsidetests/jvmti/run-tests/test-996/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-996/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/run-tests/test-997/AndroidTest.xml b/hostsidetests/jvmti/run-tests/test-997/AndroidTest.xml
index 7c50579..5f36fc3 100644
--- a/hostsidetests/jvmti/run-tests/test-997/AndroidTest.xml
+++ b/hostsidetests/jvmti/run-tests/test-997/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts"/>
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/jvmti/tagging/AndroidTest.xml b/hostsidetests/jvmti/tagging/AndroidTest.xml
index be75c08..e4dd279 100644
--- a/hostsidetests/jvmti/tagging/AndroidTest.xml
+++ b/hostsidetests/jvmti/tagging/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS JVMTI test cases">
     <option name="test-suite-tag" value="cts" />
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/monkey/AndroidTest.xml b/hostsidetests/monkey/AndroidTest.xml
index ad1507a..88abf14 100644
--- a/hostsidetests/monkey/AndroidTest.xml
+++ b/hostsidetests/monkey/AndroidTest.xml
@@ -16,6 +16,8 @@
 <configuration description="Config for the CTS monkey host tests">
     <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="misc" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
     <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
         <option name="jar" value="CtsMonkeyTestCases.jar" />
         <option name="runtime-hint" value="5m7s" />
diff --git a/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
index ec5a877..c6e80a2 100644
--- a/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
+++ b/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
@@ -92,7 +92,8 @@
     private static final String NETWORK_STATUS_SEPARATOR = "\\|";
     private static final int SECOND_IN_MS = 1000;
     static final int NETWORK_TIMEOUT_MS = 15 * SECOND_IN_MS;
-    private static final int PROCESS_STATE_FOREGROUND_SERVICE = 3;
+    private static int PROCESS_STATE_FOREGROUND_SERVICE;
+
     private static final int PROCESS_STATE_TOP = 2;
 
     private static final String KEY_NETWORK_STATE_OBSERVER = TEST_PKG + ".observer";
@@ -131,6 +132,8 @@
     protected void setUp() throws Exception {
         super.setUp();
 
+        PROCESS_STATE_FOREGROUND_SERVICE = (Integer) ActivityManager.class
+                .getDeclaredField("PROCESS_STATE_FOREGROUND_SERVICE").get(null);
         mInstrumentation = getInstrumentation();
         mContext = mInstrumentation.getContext();
         mCm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
diff --git a/hostsidetests/net/app/src/com/android/cts/net/hostside/MyVpnService.java b/hostsidetests/net/app/src/com/android/cts/net/hostside/MyVpnService.java
index c61b7d3..7d91574 100644
--- a/hostsidetests/net/app/src/com/android/cts/net/hostside/MyVpnService.java
+++ b/hostsidetests/net/app/src/com/android/cts/net/hostside/MyVpnService.java
@@ -33,6 +33,10 @@
     private static String TAG = "MyVpnService";
     private static int MTU = 1799;
 
+    public static final String ACTION_ESTABLISHED = "com.android.cts.net.hostside.ESTABNLISHED";
+    public static final String EXTRA_ALWAYS_ON = "is-always-on";
+    public static final String EXTRA_LOCKDOWN_ENABLED = "is-lockdown-enabled";
+
     private ParcelFileDescriptor mFd = null;
     private PacketReflector mPacketReflector = null;
 
@@ -129,10 +133,19 @@
         mFd = builder.establish();
         Log.i(TAG, "Established, fd=" + (mFd == null ? "null" : mFd.getFd()));
 
+        broadcastEstablished();
+
         mPacketReflector = new PacketReflector(mFd.getFileDescriptor(), MTU);
         mPacketReflector.start();
     }
 
+    private void broadcastEstablished() {
+        final Intent bcIntent = new Intent(ACTION_ESTABLISHED);
+        bcIntent.putExtra(EXTRA_ALWAYS_ON, isAlwaysOn());
+        bcIntent.putExtra(EXTRA_LOCKDOWN_ENABLED, isLockdownEnabled());
+        sendBroadcast(bcIntent);
+    }
+
     private void stop() {
         if (mPacketReflector != null) {
             mPacketReflector.interrupt();
diff --git a/hostsidetests/net/app/src/com/android/cts/net/hostside/VpnTest.java b/hostsidetests/net/app/src/com/android/cts/net/hostside/VpnTest.java
index 75fc6f1..17e1347 100755
--- a/hostsidetests/net/app/src/com/android/cts/net/hostside/VpnTest.java
+++ b/hostsidetests/net/app/src/com/android/cts/net/hostside/VpnTest.java
@@ -36,8 +36,6 @@
 import android.os.SystemProperties;
 import android.support.test.uiautomator.UiDevice;
 import android.support.test.uiautomator.UiObject;
-import android.support.test.uiautomator.UiObjectNotFoundException;
-import android.support.test.uiautomator.UiScrollable;
 import android.support.test.uiautomator.UiSelector;
 import android.system.ErrnoException;
 import android.system.Os;
@@ -49,18 +47,12 @@
 import android.util.Log;
 
 import com.android.compatibility.common.util.BlockingBroadcastReceiver;
-import com.android.cts.net.hostside.IRemoteSocketFactory;
 
-import java.io.BufferedReader;
 import java.io.Closeable;
 import java.io.FileDescriptor;
-import java.io.FileOutputStream;
-import java.io.FileInputStream;
-import java.io.InputStreamReader;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.io.PrintWriter;
 import java.net.DatagramPacket;
 import java.net.DatagramSocket;
 import java.net.Inet6Address;
@@ -68,9 +60,9 @@
 import java.net.InetSocketAddress;
 import java.net.ServerSocket;
 import java.net.Socket;
-import java.net.SocketException;
 import java.nio.charset.StandardCharsets;
 import java.util.Random;
+import java.util.concurrent.TimeUnit;
 
 /**
  * Tests for the VpnService API.
@@ -230,6 +222,7 @@
                 .putExtra(mPackageName + ".allowedapplications", allowedApplications)
                 .putExtra(mPackageName + ".disallowedapplications", disallowedApplications)
                 .putExtra(mPackageName + ".httpProxy", proxyInfo);
+
         mActivity.startService(intent);
         synchronized (mLock) {
             if (mNetwork == null) {
@@ -573,15 +566,27 @@
             return;
         }
 
+        final BlockingBroadcastReceiver receiver = new BlockingBroadcastReceiver(
+                getInstrumentation().getTargetContext(), MyVpnService.ACTION_ESTABLISHED);
+        receiver.register();
+
         FileDescriptor fd = openSocketFdInOtherApp(TEST_HOST, 80, TIMEOUT_MS);
 
         startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"},
                  new String[] {"0.0.0.0/0", "::/0"},
                  "", "", null);
 
+        final Intent intent = receiver.awaitForBroadcast(TimeUnit.MINUTES.toMillis(1));
+        assertNotNull("Failed to receive broadcast from VPN service", intent);
+        assertFalse("Wrong VpnService#isAlwaysOn",
+                intent.getBooleanExtra(MyVpnService.EXTRA_ALWAYS_ON, true));
+        assertFalse("Wrong VpnService#isLockdownEnabled",
+                intent.getBooleanExtra(MyVpnService.EXTRA_LOCKDOWN_ENABLED, true));
+
         assertSocketClosed(fd, TEST_HOST);
 
         checkTrafficOnVpn();
+        receiver.unregisterQuietly();
     }
 
     public void testAppAllowed() throws Exception {
diff --git a/hostsidetests/numberblocking/app/src/com/android/cts/numberblocking/hostside/CallBlockingTest.java b/hostsidetests/numberblocking/app/src/com/android/cts/numberblocking/hostside/CallBlockingTest.java
index 674dab2..353471f 100644
--- a/hostsidetests/numberblocking/app/src/com/android/cts/numberblocking/hostside/CallBlockingTest.java
+++ b/hostsidetests/numberblocking/app/src/com/android/cts/numberblocking/hostside/CallBlockingTest.java
@@ -39,6 +39,7 @@
 public class CallBlockingTest extends BaseNumberBlockingClientTest {
     private static final String QUERY_CALL_THROUGH_OUR_CONNECTION_SERVICE = CallLog.Calls.NUMBER
             + " = ? AND " + CallLog.Calls.PHONE_ACCOUNT_COMPONENT_NAME + " = ?";
+    public static final long WAIT_FOR_STATE_CHANGE_TIMEOUT_MS = 10000;
 
     private static CountDownLatch callRejectionCountDownLatch;
 
@@ -58,11 +59,13 @@
                 .setSupportedUriSchemes(Arrays.asList(PhoneAccount.SCHEME_TEL))
                 .build();
         mTelecomManager.registerPhoneAccount(phoneAccount);
+        assertPhoneAccountRegistered(phoneAccountHandle, true);
     }
 
     public void testUnregisterPhoneAccount() {
-        mTelecomManager.unregisterPhoneAccount(getPhoneAccountHandle());
-        assertNull(mTelecomManager.getPhoneAccount(getPhoneAccountHandle()));
+        PhoneAccountHandle handle = getPhoneAccountHandle();
+        mTelecomManager.unregisterPhoneAccount(handle);
+        assertPhoneAccountRegistered(handle, false);
     }
 
     public void testIncomingCallFromBlockedNumberIsRejected() throws Exception {
@@ -135,4 +138,46 @@
             return connection;
         }
     }
+
+    private void assertPhoneAccountRegistered(final PhoneAccountHandle handle,
+            boolean isRegistered) {
+        waitUntilConditionIsTrueOrTimeout(
+                new Condition() {
+                    @Override
+                    public Object expected() {
+                        return true;
+                    }
+
+                    @Override
+                    public Object actual() {
+                        PhoneAccount phoneAccount = mTelecomManager.getPhoneAccount(handle);
+                        return isRegistered ? phoneAccount != null : phoneAccount == null;
+                    }
+                },
+                WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "Phone account registered for " + handle
+        );
+    }
+
+    private void waitUntilConditionIsTrueOrTimeout(Condition condition, long timeout,
+            String description) {
+        final long start = System.currentTimeMillis();
+        while (!condition.expected().equals(condition.actual())
+                && System.currentTimeMillis() - start < timeout) {
+            sleep(50);
+        }
+        assertEquals(description, condition.expected(), condition.actual());
+    }
+
+    private void sleep(long ms) {
+        try {
+            Thread.sleep(ms);
+        } catch (InterruptedException e) {
+        }
+    }
+
+    protected interface Condition {
+        Object expected();
+        Object actual();
+    }
 }
diff --git a/hostsidetests/seccomp/app/AndroidManifest.xml b/hostsidetests/seccomp/app/AndroidManifest.xml
index 538149d..5c62ab5 100644
--- a/hostsidetests/seccomp/app/AndroidManifest.xml
+++ b/hostsidetests/seccomp/app/AndroidManifest.xml
@@ -18,7 +18,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="android.seccomp.cts.app">
 
-    <application>
+    <application android:zygotePreloadName=".ZygotePreload">
         <uses-library android:name="android.test.runner" />
         <service
             android:name=".IsolatedService"
diff --git a/hostsidetests/seccomp/app/src/android/seccomp/cts/app/ZygotePreload.java b/hostsidetests/seccomp/app/src/android/seccomp/cts/app/ZygotePreload.java
index 270e558..e7f5b25 100644
--- a/hostsidetests/seccomp/app/src/android/seccomp/cts/app/ZygotePreload.java
+++ b/hostsidetests/seccomp/app/src/android/seccomp/cts/app/ZygotePreload.java
@@ -16,13 +16,14 @@
 
 package android.seccomp.cts.app;
 
+import android.content.pm.ApplicationInfo;
 import android.os.Process;
 import android.util.Log;
 
-public class ZygotePreload {
+public class ZygotePreload implements android.app.ZygotePreload {
     static final String TAG = "SeccompDeviceTest";
 
-    static boolean sResult = false;
+    static volatile boolean sResult = false;
 
     static private boolean testSetResUidGidBlocked(int rid, int eid, int sid) {
         if (!SeccompDeviceTest.testSetresuidBlocked(rid, eid, sid)) {
@@ -71,7 +72,8 @@
      *
      * This test enforces 2) is in place.
      */
-    static synchronized public void doPreload() {
+    @Override
+    synchronized public void doPreload(ApplicationInfo appInfo) {
         boolean result = true;
 
         // root uid
diff --git a/hostsidetests/security/src/android/cts/security/SELinuxHostTest.java b/hostsidetests/security/src/android/cts/security/SELinuxHostTest.java
index 3ef39dd..3463211 100644
--- a/hostsidetests/security/src/android/cts/security/SELinuxHostTest.java
+++ b/hostsidetests/security/src/android/cts/security/SELinuxHostTest.java
@@ -962,8 +962,12 @@
         Pattern p = Pattern.compile("avc: *denied.*scontext=u:(?:r|object_r):(?:" + typeRegex + "):s0.*");
         // Fail if logcat contains such a denial.
         Matcher m = p.matcher(log);
-        if (m.find())
-            fail("Found illegal SELinux denial: " + m.group());
+        StringBuilder errorString = new StringBuilder();
+        while (m.find()) {
+            errorString.append(m.group());
+            errorString.append("\n");
+        }
+        assertTrue("Found illegal SELinux denial(s): " + errorString, errorString.length() == 0);
     }
 
     /**
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2017-0479/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0479/poc.cpp
index e09fe5e..3fc6329 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2017-0479/poc.cpp
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0479/poc.cpp
@@ -16,7 +16,7 @@
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <stdlib.h>
-#include <audioflinger/AudioFlinger.h>
+#include <media/AudioSystem.h>
 #include <hardware/audio_effect.h>
 #include <media/IAudioFlinger.h>
 #include <media/IEffect.h>
diff --git a/hostsidetests/statsd/AndroidTest.xml b/hostsidetests/statsd/AndroidTest.xml
index 420ae75..a1beb7c 100644
--- a/hostsidetests/statsd/AndroidTest.xml
+++ b/hostsidetests/statsd/AndroidTest.xml
@@ -16,6 +16,7 @@
 <configuration description="Config for CTS Statsd host test cases">
     <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="statsd" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
         <option name="jar" value="CtsStatsdHostTestCases.jar" />
     </test>
diff --git a/hostsidetests/statsd/apps/statsdapp/AndroidManifest.xml b/hostsidetests/statsd/apps/statsdapp/AndroidManifest.xml
index 592f0a7..5b7d0bb 100644
--- a/hostsidetests/statsd/apps/statsdapp/AndroidManifest.xml
+++ b/hostsidetests/statsd/apps/statsdapp/AndroidManifest.xml
@@ -80,6 +80,13 @@
 
         <service android:name=".StatsdJobService"
             android:permission="android.permission.BIND_JOB_SERVICE" />
+
+        <service android:name=".DummyCallscreeningService"
+                 android:permission="android.permission.BIND_SCREENING_SERVICE">
+            <intent-filter>
+                <action android:name="android.telecom.CallScreeningService" />
+            </intent-filter>
+        </service>
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
diff --git a/tests/tests/debug/src/android/debug/cts/DebugTest.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/DummyCallscreeningService.java
similarity index 60%
copy from tests/tests/debug/src/android/debug/cts/DebugTest.java
copy to hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/DummyCallscreeningService.java
index 993f02b..3e52342 100644
--- a/tests/tests/debug/src/android/debug/cts/DebugTest.java
+++ b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/DummyCallscreeningService.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2019 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.
@@ -14,12 +14,15 @@
  * limitations under the License.
  */
 
-package android.debug.cts;
+package com.android.server.cts.device.statsd;
 
-import org.junit.runner.RunWith;
-import com.android.gtestrunner.GtestRunner;
-import com.android.gtestrunner.TargetLibrary;
+import android.annotation.NonNull;
+import android.telecom.Call;
+import android.telecom.CallScreeningService;
 
-@RunWith(GtestRunner.class)
-@TargetLibrary("debugtest")
-public class DebugTest {}
+public class DummyCallscreeningService extends CallScreeningService {
+    @Override
+    public void onScreenCall(@NonNull Call.Details callDetails) {
+
+    }
+}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java b/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
index 1a13135..410d01f 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
@@ -27,6 +27,7 @@
 import com.android.internal.os.StatsdConfigProto.GaugeMetric;
 import com.android.internal.os.StatsdConfigProto.StatsdConfig;
 import com.android.internal.os.StatsdConfigProto.TimeUnit;
+import com.android.os.AtomsProto;
 import com.android.os.AtomsProto.AppCrashOccurred;
 import com.android.os.AtomsProto.AppStartOccurred;
 import com.android.os.AtomsProto.Atom;
@@ -36,6 +37,7 @@
 import com.android.os.AtomsProto.BleScanStateChanged;
 import com.android.os.AtomsProto.CameraStateChanged;
 import com.android.os.AtomsProto.CpuActiveTime;
+import com.android.os.AtomsProto.DangerousPermissionState;
 import com.android.os.AtomsProto.DeviceCalculatedPowerBlameUid;
 import com.android.os.AtomsProto.DeviceCalculatedPowerUse;
 import com.android.os.AtomsProto.FlashlightStateChanged;
@@ -1103,4 +1105,84 @@
         assertTrue("Did not find a matching atom for statsd", foundStatsd);
         assertTrue("Did not find a matching atom for system server", foundSystemServer);
     }
+
+    public void testRoleHolder() throws Exception {
+        if (statsdDisabled()) {
+            return;
+        }
+
+        // Make device side test package a role holder
+        String callScreenAppRole = "android.app.role.CALL_SCREENING_APP";
+        getDevice().executeShellCommand(
+                "cmd role add-role-holder " + callScreenAppRole + " " + DEVICE_SIDE_TEST_PACKAGE);
+
+        // Set up what to collect
+        StatsdConfig.Builder config = getPulledConfig();
+        addGaugeAtomWithDimensions(config, Atom.ROLE_HOLDER_FIELD_NUMBER, null);
+        uploadConfig(config);
+        Thread.sleep(WAIT_TIME_SHORT);
+
+        boolean verifiedKnowRoleState = false;
+
+        // Pull a report
+        setAppBreadcrumbPredicate();
+        Thread.sleep(WAIT_TIME_SHORT);
+
+        for (Atom atom : getGaugeMetricDataList()) {
+            AtomsProto.RoleHolder roleHolder = atom.getRoleHolder();
+
+            assertNotNull(roleHolder.getPackageName());
+            assertTrue(roleHolder.getUid() >= 0);
+            assertNotNull(roleHolder.getRole());
+
+            if (roleHolder.getPackageName().equals(DEVICE_SIDE_TEST_PACKAGE)) {
+                assertEquals(getUid(), roleHolder.getUid());
+                assertEquals(DEVICE_SIDE_TEST_PACKAGE, roleHolder.getPackageName());
+                assertEquals(callScreenAppRole, roleHolder.getRole());
+
+                verifiedKnowRoleState = true;
+            }
+        }
+
+        assertTrue(verifiedKnowRoleState);
+    }
+
+    public void testDangerousPermissionState() throws Exception {
+        if (statsdDisabled()) {
+            return;
+        }
+
+        // Set up what to collect
+        StatsdConfig.Builder config = getPulledConfig();
+        addGaugeAtomWithDimensions(config, Atom.DANGEROUS_PERMISSION_STATE_FIELD_NUMBER, null);
+        uploadConfig(config);
+        Thread.sleep(WAIT_TIME_SHORT);
+
+        boolean verifiedKnowPermissionState = false;
+
+        // Pull a report
+        setAppBreadcrumbPredicate();
+        Thread.sleep(WAIT_TIME_SHORT);
+
+        for (Atom atom : getGaugeMetricDataList()) {
+            DangerousPermissionState permissionState = atom.getDangerousPermissionState();
+
+            assertNotNull(permissionState.getPermissionName());
+            assertTrue(permissionState.getUid() >= 0);
+            assertNotNull(permissionState.getPackageName());
+
+            if (permissionState.getPackageName().equals(DEVICE_SIDE_TEST_PACKAGE)) {
+                assertEquals(getUid(), permissionState.getUid());
+
+                if (permissionState.getPermissionName().equals(
+                        "android.permission.ACCESS_FINE_LOCATION")) {
+                    assertTrue(permissionState.getIsGranted());
+
+                    verifiedKnowPermissionState = true;
+                }
+            }
+        }
+
+        assertTrue(verifiedKnowPermissionState);
+    }
 }
diff --git a/hostsidetests/theme/AndroidTest.xml b/hostsidetests/theme/AndroidTest.xml
index beb9218..b03e11e 100644
--- a/hostsidetests/theme/AndroidTest.xml
+++ b/hostsidetests/theme/AndroidTest.xml
@@ -16,6 +16,8 @@
 <configuration description="Config for CTS Theme host test cases">
     <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="uitoolkit" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
         <option name="test-file-name" value="CtsThemeDeviceApp.apk" />
diff --git a/hostsidetests/theme/assets/28/360dpi.zip b/hostsidetests/theme/assets/28/360dpi.zip
index 3e1f801..40b434b 100644
--- a/hostsidetests/theme/assets/28/360dpi.zip
+++ b/hostsidetests/theme/assets/28/360dpi.zip
Binary files differ
diff --git a/hostsidetests/tzdata/AndroidTest.xml b/hostsidetests/tzdata/AndroidTest.xml
index 39fc109..09cd90f 100644
--- a/hostsidetests/tzdata/AndroidTest.xml
+++ b/hostsidetests/tzdata/AndroidTest.xml
@@ -16,6 +16,8 @@
 <configuration description="Config for CTS tzdatacheck host test cases">
     <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="libcore" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
     <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
         <option name="jar" value="CtsHostTzDataTests.jar" />
     </test>
diff --git a/tests/accessibility/AndroidTest.xml b/tests/accessibility/AndroidTest.xml
index 6e0e0a9..7783a25 100644
--- a/tests/accessibility/AndroidTest.xml
+++ b/tests/accessibility/AndroidTest.xml
@@ -17,7 +17,7 @@
     <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="framework" />
     <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
-    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
     <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
         <option name="run-command" value="cmd accessibility set-bind-instant-service-allowed true" />
         <option name="teardown-command" value="cmd accessibility set-bind-instant-service-allowed false" />
diff --git a/tests/accessibilityservice/AndroidTest.xml b/tests/accessibilityservice/AndroidTest.xml
index 7ea4c2f..eb75538 100644
--- a/tests/accessibilityservice/AndroidTest.xml
+++ b/tests/accessibilityservice/AndroidTest.xml
@@ -17,7 +17,7 @@
     <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="framework" />
     <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
-    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
     <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
         <option name="run-command" value="cmd accessibility set-bind-instant-service-allowed true" />
         <option name="teardown-command" value="cmd accessibility set-bind-instant-service-allowed false" />
diff --git a/tests/admin/AndroidTest.xml b/tests/admin/AndroidTest.xml
index 7f1a7ad..c0b10fe 100644
--- a/tests/admin/AndroidTest.xml
+++ b/tests/admin/AndroidTest.xml
@@ -16,6 +16,12 @@
 <configuration description="Config for the CTS device admin tests">
     <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="framework" />
+    <!-- Instant apps can never be device admin / profile owner / device owner so positive tests
+         here are not applicable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <!-- Not testing features backed by native code, so only need to run against one ABI -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
+
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
         <option name="install-arg" value="-t" />
diff --git a/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java b/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java
index 8bd83e2..349578f 100644
--- a/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java
+++ b/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java
@@ -844,7 +844,7 @@
             mDevicePolicyManager.setBackupServiceEnabled(mComponent, false);
             fail("did not throw expected SecurityException");
         } catch (SecurityException e) {
-            assertDeviceOwnerMessage(e.getMessage());
+            assertProfileOwnerMessage(e.getMessage());
         }
     }
 
@@ -857,6 +857,19 @@
             mDevicePolicyManager.isBackupServiceEnabled(mComponent);
             fail("did not throw expected SecurityException");
         } catch (SecurityException e) {
+            assertProfileOwnerMessage(e.getMessage());
+        }
+    }
+
+    public void testSetDefaultSmsApplication_failIfNotDeviceOwner() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testSetDefaultSmsApplication_failIfNotDeviceOwner");
+            return;
+        }
+        try {
+            mDevicePolicyManager.setDefaultSmsApplication(mComponent, "android.admin.cts");
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
             assertDeviceOwnerMessage(e.getMessage());
         }
     }
diff --git a/tests/app/app/AndroidManifest.xml b/tests/app/app/AndroidManifest.xml
index fef8625..7f66a12 100644
--- a/tests/app/app/AndroidManifest.xml
+++ b/tests/app/app/AndroidManifest.xml
@@ -52,7 +52,8 @@
                 android:multiArch="true"
                 android:name="android.app.stubs.MockApplication"
                 android:supportsRtl="true"
-                android:networkSecurityConfig="@xml/network_security_config">
+                android:networkSecurityConfig="@xml/network_security_config"
+                android:zygotePreloadName=".ZygotePreload">
         <uses-library android:name="android.test.runner" />
         <uses-library android:name="org.apache.http.legacy" android:required="false" />
 
@@ -138,6 +139,13 @@
             </intent-filter>
         </service>
 
+        <service android:name="android.app.stubs.LocalForegroundServiceLocation"
+                android:foregroundServiceType="location">
+            <intent-filter>
+                <action android:name="android.app.stubs.FOREGROUND_SERVICE_LOCATION" />
+            </intent-filter>
+        </service>
+
         <service android:name="android.app.stubs.LocalGrantedService"
              android:permission="android.app.stubs.permission.TEST_GRANTED">
             <intent-filter>
diff --git a/tests/app/app/src/android/app/stubs/ActivityCallbacksTestActivity.java b/tests/app/app/src/android/app/stubs/ActivityCallbacksTestActivity.java
index 38f0b52..fb0ccf2 100644
--- a/tests/app/app/src/android/app/stubs/ActivityCallbacksTestActivity.java
+++ b/tests/app/app/src/android/app/stubs/ActivityCallbacksTestActivity.java
@@ -55,10 +55,12 @@
     public enum Source {
         ACTIVITY,
         ACTIVITY_CALLBACK,
+        ACTIVITY_CALLBACK_CREATE_ONLY,
         APPLICATION_ACTIVITY_CALLBACK
     }
 
     private final Application.ActivityLifecycleCallbacks mActivityCallbacks;
+    private final Application.ActivityLifecycleCallbacks mActivityCallbacksCreateOnly;
 
     private ArrayList<Pair<Source, Event>> mCollectedEvents = new ArrayList<>();
 
@@ -161,6 +163,101 @@
             }
         };
         registerActivityLifecycleCallbacks(mActivityCallbacks);
+        mActivityCallbacksCreateOnly = new Application.ActivityLifecycleCallbacks() {
+
+            @Override
+            public void onActivityPreCreated(Activity activity, Bundle savedInstanceState) {
+                collectEvent(Source.ACTIVITY_CALLBACK_CREATE_ONLY, Event.ON_PRE_CREATE);
+            }
+
+            @Override
+            public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
+                collectEvent(Source.ACTIVITY_CALLBACK_CREATE_ONLY, Event.ON_CREATE);
+            }
+
+            @Override
+            public void onActivityPostCreated(Activity activity, Bundle savedInstanceState) {
+                collectEvent(Source.ACTIVITY_CALLBACK_CREATE_ONLY, Event.ON_POST_CREATE);
+                // We shouldn't get any additional callbacks after this point
+                unregisterActivityLifecycleCallbacks(this);
+            }
+
+            @Override
+            public void onActivityStarted(Activity activity) {
+                collectEvent(Source.ACTIVITY_CALLBACK_CREATE_ONLY, Event.ON_START);
+            }
+
+            @Override
+            public void onActivityPostStarted(Activity activity) {
+                collectEvent(Source.ACTIVITY_CALLBACK_CREATE_ONLY, Event.ON_POST_START);
+            }
+
+            @Override
+            public void onActivityPreResumed(Activity activity) {
+                collectEvent(Source.ACTIVITY_CALLBACK_CREATE_ONLY, Event.ON_PRE_RESUME);
+            }
+
+            @Override
+            public void onActivityResumed(Activity activity) {
+                collectEvent(Source.ACTIVITY_CALLBACK_CREATE_ONLY, Event.ON_RESUME);
+            }
+
+            @Override
+            public void onActivityPostResumed(Activity activity) {
+                collectEvent(Source.ACTIVITY_CALLBACK_CREATE_ONLY, Event.ON_POST_RESUME);
+            }
+
+            @Override
+            public void onActivityPrePaused(Activity activity) {
+                collectEvent(Source.ACTIVITY_CALLBACK_CREATE_ONLY, Event.ON_PRE_PAUSE);
+            }
+
+            @Override
+            public void onActivityPaused(Activity activity) {
+                collectEvent(Source.ACTIVITY_CALLBACK_CREATE_ONLY, Event.ON_PAUSE);
+            }
+
+            @Override
+            public void onActivityPostPaused(Activity activity) {
+                collectEvent(Source.ACTIVITY_CALLBACK_CREATE_ONLY, Event.ON_POST_PAUSE);
+            }
+
+            @Override
+            public void onActivityPreStopped(Activity activity) {
+                collectEvent(Source.ACTIVITY_CALLBACK_CREATE_ONLY, Event.ON_PRE_STOP);
+            }
+
+            @Override
+            public void onActivityStopped(Activity activity) {
+                collectEvent(Source.ACTIVITY_CALLBACK_CREATE_ONLY, Event.ON_STOP);
+            }
+
+            @Override
+            public void onActivityPostStopped(Activity activity) {
+                collectEvent(Source.ACTIVITY_CALLBACK_CREATE_ONLY, Event.ON_POST_STOP);
+            }
+
+            @Override
+            public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
+
+            }
+
+            @Override
+            public void onActivityPreDestroyed(Activity activity) {
+                collectEvent(Source.ACTIVITY_CALLBACK_CREATE_ONLY, Event.ON_PRE_DESTROY);
+            }
+
+            @Override
+            public void onActivityDestroyed(Activity activity) {
+                collectEvent(Source.ACTIVITY_CALLBACK_CREATE_ONLY, Event.ON_DESTROY);
+            }
+
+            @Override
+            public void onActivityPostDestroyed(Activity activity) {
+                collectEvent(Source.ACTIVITY_CALLBACK_CREATE_ONLY, Event.ON_POST_DESTROY);
+            }
+        };
+        registerActivityLifecycleCallbacks(mActivityCallbacksCreateOnly);
     }
 
     public void collectEvent(Source source, Event event) {
diff --git a/tests/app/app/src/android/app/stubs/CommandReceiver.java b/tests/app/app/src/android/app/stubs/CommandReceiver.java
index 26cc10f..75ed0a8 100644
--- a/tests/app/app/src/android/app/stubs/CommandReceiver.java
+++ b/tests/app/app/src/android/app/stubs/CommandReceiver.java
@@ -37,6 +37,8 @@
     public static final int COMMAND_UNBIND_SERVICE = 2;
     public static final int COMMAND_START_FOREGROUND_SERVICE = 3;
     public static final int COMMAND_STOP_FOREGROUND_SERVICE = 4;
+    public static final int COMMAND_START_FOREGROUND_SERVICE_LOCATION = 5;
+    public static final int COMMAND_STOP_FOREGROUND_SERVICE_LOCATION = 6;
 
     public static final String EXTRA_COMMAND = "android.app.stubs.extra.COMMAND";
     public static final String EXTRA_TARGET_PACKAGE = "android.app.stubs.extra.TARGET_PACKAGE";
@@ -64,10 +66,16 @@
                 doUnbindService(context, intent);
                 break;
             case COMMAND_START_FOREGROUND_SERVICE:
-                doStartForegroundService(context);
+                doStartForegroundService(context, LocalForegroundService.class);
                 break;
             case COMMAND_STOP_FOREGROUND_SERVICE:
-                doStopForegroundService(context);
+                doStopForegroundService(context, LocalForegroundService.class);
+                break;
+            case COMMAND_START_FOREGROUND_SERVICE_LOCATION:
+                doStartForegroundService(context, LocalForegroundServiceLocation.class);
+                break;
+            case COMMAND_STOP_FOREGROUND_SERVICE_LOCATION:
+                doStopForegroundService(context, LocalForegroundServiceLocation.class);
                 break;
         }
     }
@@ -94,15 +102,15 @@
         context.unbindService(sServiceMap.remove(targetPackage));
     }
 
-    private void doStartForegroundService(Context context) {
-        Intent fgsIntent = new Intent(context, LocalForegroundService.class);
+    private void doStartForegroundService(Context context, Class cls) {
+        Intent fgsIntent = new Intent(context, cls);
         int command = LocalForegroundService.COMMAND_START_FOREGROUND;
         fgsIntent.putExtras(LocalForegroundService.newCommand(new Binder(), command));
         context.startForegroundService(fgsIntent);
     }
 
-    private void doStopForegroundService(Context context) {
-        Intent fgsIntent = new Intent(context, LocalForegroundService.class);
+    private void doStopForegroundService(Context context, Class cls) {
+        Intent fgsIntent = new Intent(context, cls);
         context.stopService(fgsIntent);
     }
 
diff --git a/tests/app/app/src/android/app/stubs/LocalForegroundService.java b/tests/app/app/src/android/app/stubs/LocalForegroundService.java
index d60a1df..e7d01f8 100644
--- a/tests/app/app/src/android/app/stubs/LocalForegroundService.java
+++ b/tests/app/app/src/android/app/stubs/LocalForegroundService.java
@@ -50,11 +50,17 @@
         Log.d(TAG, "service created: " + this + " in " + android.os.Process.myPid());
     }
 
+    /** Returns the channel id for this service */
+    protected String getNotificationChannelId() {
+        return NOTIFICATION_CHANNEL_ID;
+    }
+
     @Override
     public void onStart(Intent intent, int startId) {
+        String notificationChannelId = getNotificationChannelId();
         NotificationManager notificationManager = getSystemService(NotificationManager.class);
         notificationManager.createNotificationChannel(new NotificationChannel(
-                NOTIFICATION_CHANNEL_ID, NOTIFICATION_CHANNEL_ID,
+                notificationChannelId, notificationChannelId,
                 NotificationManager.IMPORTANCE_DEFAULT));
 
         Context context = getApplicationContext();
diff --git a/tests/app/app/src/android/app/stubs/LocalForegroundServiceLocation.java b/tests/app/app/src/android/app/stubs/LocalForegroundServiceLocation.java
new file mode 100644
index 0000000..82aaf96
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/LocalForegroundServiceLocation.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.stubs;
+
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.util.Log;
+import android.app.stubs.R;
+
+import com.android.compatibility.common.util.IBinderParcelable;
+
+/**
+ * Foreground Service with location type.
+ */
+public class LocalForegroundServiceLocation extends LocalForegroundService {
+
+    private static final String TAG = "LocalForegroundServiceLocation";
+    private static final String EXTRA_COMMAND = "LocalForegroundServiceLocation.command";
+    private static final String NOTIFICATION_CHANNEL_ID = "cts/" + TAG;
+
+    /** Returns the channel id for this service */
+    @Override
+    protected String getNotificationChannelId() {
+        return NOTIFICATION_CHANNEL_ID;
+    }
+}
diff --git a/tests/app/app/src/android/app/stubs/ZygotePreload.java b/tests/app/app/src/android/app/stubs/ZygotePreload.java
index 1faef7c..5601dd0 100644
--- a/tests/app/app/src/android/app/stubs/ZygotePreload.java
+++ b/tests/app/app/src/android/app/stubs/ZygotePreload.java
@@ -16,10 +16,9 @@
 
 package android.app.stubs;
 
-import android.os.Process;
-import android.util.Log;
+import android.content.pm.ApplicationInfo;
 
-public class ZygotePreload {
+public class ZygotePreload implements android.app.ZygotePreload {
     static final String TAG = "ZygotePreload";
 
     static boolean sPreloadCalled = false;
@@ -28,7 +27,8 @@
         return sPreloadCalled;
     }
 
-    static synchronized public void doPreload() {
+    @Override
+    synchronized public void doPreload(ApplicationInfo appInfo) {
         sPreloadCalled = true;
     }
 }
diff --git a/tests/app/src/android/app/cts/ActivityCallbacksTest.java b/tests/app/src/android/app/cts/ActivityCallbacksTest.java
index ff9c401..909748f 100644
--- a/tests/app/src/android/app/cts/ActivityCallbacksTest.java
+++ b/tests/app/src/android/app/cts/ActivityCallbacksTest.java
@@ -229,11 +229,19 @@
             Event preEvent, Event event, Event postEvent) {
         expectedEvents.add(new Pair<>(Source.APPLICATION_ACTIVITY_CALLBACK, preEvent));
         expectedEvents.add(new Pair<>(Source.ACTIVITY_CALLBACK, preEvent));
+        if (preEvent == ON_PRE_CREATE) {
+            // ACTIVITY_CALLBACK_CREATE_ONLY only gets create events
+            expectedEvents.add(new Pair<>(Source.ACTIVITY_CALLBACK_CREATE_ONLY, preEvent));
+        }
         expectedEvents.add(new Pair<>(Source.ACTIVITY, preEvent));
         if (event == ON_CREATE || event == ON_START || event == ON_RESUME) {
             // Application goes first on upward lifecycle events
             expectedEvents.add(new Pair<>(Source.APPLICATION_ACTIVITY_CALLBACK, event));
             expectedEvents.add(new Pair<>(Source.ACTIVITY_CALLBACK, event));
+            if (event == ON_CREATE) {
+                // ACTIVITY_CALLBACK_CREATE_ONLY only gets create events
+                expectedEvents.add(new Pair<>(Source.ACTIVITY_CALLBACK_CREATE_ONLY, event));
+            }
         } else {
             // Application goes last on downward lifecycle events
             expectedEvents.add(new Pair<>(Source.ACTIVITY_CALLBACK, event));
@@ -241,6 +249,10 @@
         }
         expectedEvents.add(new Pair<>(Source.ACTIVITY, postEvent));
         expectedEvents.add(new Pair<>(Source.ACTIVITY_CALLBACK, postEvent));
+        if (postEvent == ON_POST_CREATE) {
+            // ACTIVITY_CALLBACK_CREATE_ONLY only gets create events
+            expectedEvents.add(new Pair<>(Source.ACTIVITY_CALLBACK_CREATE_ONLY, postEvent));
+        }
         expectedEvents.add(new Pair<>(Source.APPLICATION_ACTIVITY_CALLBACK, postEvent));
     }
 }
diff --git a/tests/app/src/android/app/cts/ActivityManagerProcessStateTest.java b/tests/app/src/android/app/cts/ActivityManagerProcessStateTest.java
index 1df5249..3cac46d 100644
--- a/tests/app/src/android/app/cts/ActivityManagerProcessStateTest.java
+++ b/tests/app/src/android/app/cts/ActivityManagerProcessStateTest.java
@@ -1569,6 +1569,56 @@
         }
     }
 
+    /**
+     * Test process states for foreground service with and without location type in the manifest.
+     * When running a foreground service with location type, the process should go to
+     * PROCESS_STATE_FOREGROUND_SERVICE_LOCATION.
+     * @throws Exception
+     */
+    public void testFgsLocation() throws Exception {
+        ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo(
+                PACKAGE_NAME_APP1, 0);
+        WatchUidRunner uid1Watcher = new WatchUidRunner(mInstrumentation, app1Info.uid,
+                WAITFOR_MSEC);
+
+        try {
+            // First start a foreground service
+            CommandReceiver.sendCommand(mContext,
+                    CommandReceiver.COMMAND_START_FOREGROUND_SERVICE,
+                    PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null);
+            uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE);
+
+            // Try to elevate to foreground service location
+            CommandReceiver.sendCommand(mContext,
+                    CommandReceiver.COMMAND_START_FOREGROUND_SERVICE_LOCATION,
+                    PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null);
+            uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE,
+                    WatchUidRunner.STATE_FG_SERVICE_LOCATION);
+
+            // Back down to foreground service
+            CommandReceiver.sendCommand(mContext,
+                    CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE_LOCATION,
+                    PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null);
+            uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE);
+
+            try {
+                uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE,
+                        WatchUidRunner.STATE_CACHED_EMPTY);
+                fail("App1 should not be demoted to cached");
+            } catch (IllegalStateException ise) {
+            }
+
+            // Remove foreground service as well
+            CommandReceiver.sendCommand(mContext,
+                    CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE,
+                    PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null);
+            uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
+
+        } finally {
+            uid1Watcher.finish();
+        }
+    }
+
     private final <T extends Activity> Activity startSubActivity(Class<T> activityClass) {
         final Instrumentation.ActivityResult result = new Instrumentation.ActivityResult(
                 0, new Intent());
diff --git a/tests/app/src/android/app/cts/ActivityManagerTest.java b/tests/app/src/android/app/cts/ActivityManagerTest.java
index 1557108..8ac3a66 100644
--- a/tests/app/src/android/app/cts/ActivityManagerTest.java
+++ b/tests/app/src/android/app/cts/ActivityManagerTest.java
@@ -42,9 +42,12 @@
 import android.test.InstrumentationTestCase;
 import android.util.Log;
 
+import com.android.compatibility.common.util.SystemUtil;
+
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.function.Predicate;
 
 public class ActivityManagerTest extends InstrumentationTestCase {
     private static final String TAG = ActivityManagerTest.class.getSimpleName();
@@ -624,6 +627,53 @@
     }
 
     /**
+     * Verify that after force-stopping a package which has a foreground task contains multiple
+     * activities, the process of the package should not be alive (restarted).
+     */
+    public void testForceStopPackageWontRestartProcess() throws Exception {
+        ActivityReceiverFilter appStartedReceiver = new ActivityReceiverFilter(
+                ACTIVITY_LAUNCHED_ACTION);
+        // Start an activity of another APK.
+        Intent intent = new Intent();
+        intent.setClassName(SIMPLE_PACKAGE_NAME, SIMPLE_PACKAGE_NAME + SIMPLE_ACTIVITY);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        mContext.startActivity(intent);
+        assertEquals(RESULT_PASS, appStartedReceiver.waitForActivity());
+
+        // Start a new activity in the same task. Here adds an action to make a different to intent
+        // filter comparison so another same activity will be created.
+        intent.setAction(Intent.ACTION_MAIN);
+        mContext.startActivity(intent);
+        assertEquals(RESULT_PASS, appStartedReceiver.waitForActivity());
+        appStartedReceiver.close();
+
+        // Wait for the first activity to stop so its ActivityRecord.haveState will be true. The
+        // condition is required to keep the activity record when its process is died.
+        Thread.sleep(WAIT_TIME);
+
+        // The package name is also the default name for the activity process.
+        final String testProcess = SIMPLE_PACKAGE_NAME;
+        Predicate<RunningAppProcessInfo> processNamePredicate =
+                runningApp -> testProcess.equals(runningApp.processName);
+
+        List<RunningAppProcessInfo> runningApps = SystemUtil.callWithShellPermissionIdentity(
+                () -> mActivityManager.getRunningAppProcesses());
+        assertTrue("Process " + testProcess + " should be found in running process list",
+                runningApps.stream().anyMatch(processNamePredicate));
+
+        runningApps = SystemUtil.callWithShellPermissionIdentity(() -> {
+            mActivityManager.forceStopPackage(SIMPLE_PACKAGE_NAME);
+            // Wait awhile (process starting may be asynchronous) to verify if the process is
+            // started again unexpectedly.
+            Thread.sleep(WAIT_TIME);
+            return mActivityManager.getRunningAppProcesses();
+        });
+
+        assertFalse("Process " + testProcess + " should not be alive after force-stop",
+                runningApps.stream().anyMatch(processNamePredicate));
+    }
+
+    /**
      * This test is to verify that devices are patched with the fix in b/119327603 for b/115384617.
      */
     public void testIsAppForegroundRemoved() throws ClassNotFoundException {
diff --git a/tests/app/src/android/app/cts/NotificationChannelTest.java b/tests/app/src/android/app/cts/NotificationChannelTest.java
index f8fe35c..cff8dcb 100644
--- a/tests/app/src/android/app/cts/NotificationChannelTest.java
+++ b/tests/app/src/android/app/cts/NotificationChannelTest.java
@@ -59,6 +59,7 @@
         assertEquals(null, channel.getGroup());
         assertTrue(channel.getLightColor() == 0);
         assertTrue(channel.canBubble());
+        assertFalse(channel.isImportanceLockedByOEM());
     }
 
     public void testWriteToParcel() {
@@ -158,14 +159,17 @@
         NotificationChannel channel =
                 new NotificationChannel("1", "one", IMPORTANCE_DEFAULT);
         channel.setAllowBubbles(true);
-        assertEquals("Only HIGH channels can have bubbles", false, channel.canBubble());
+        assertEquals(true, channel.canBubble());
 
-        channel = new NotificationChannel("1", "one", IMPORTANCE_HIGH);
+        channel = new NotificationChannel("1", "one", IMPORTANCE_DEFAULT);
         channel.setAllowBubbles(false);
         assertEquals(false, channel.canBubble());
+    }
 
-        channel = new NotificationChannel("1", "one", IMPORTANCE_HIGH);
-        channel.setAllowBubbles(true);
-        assertEquals(true, channel.canBubble());
+    public void testIsImportanceLockedByOEM() {
+        NotificationChannel channel =
+                new NotificationChannel("1", "one", IMPORTANCE_DEFAULT);
+        channel.setImportanceLockedByOEM(true);
+        assertTrue(channel.isImportanceLockedByOEM());
     }
 }
diff --git a/tests/app/src/android/app/cts/NotificationManagerTest.java b/tests/app/src/android/app/cts/NotificationManagerTest.java
index d99cb11..543e7e8 100644
--- a/tests/app/src/android/app/cts/NotificationManagerTest.java
+++ b/tests/app/src/android/app/cts/NotificationManagerTest.java
@@ -35,21 +35,32 @@
 import android.app.NotificationChannelGroup;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
+import android.app.Person;
 import android.app.UiAutomation;
 import android.app.stubs.AutomaticZenRuleActivity;
 import android.app.stubs.R;
 import android.app.stubs.TestNotificationListener;
 import android.content.ComponentName;
+import android.content.ContentProviderOperation;
 import android.content.Context;
 import android.content.Intent;
+import android.content.OperationApplicationException;
 import android.content.pm.PackageManager;
+import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.graphics.drawable.Icon;
 import android.media.AudioAttributes;
 import android.media.session.MediaSession;
 import android.net.Uri;
 import android.os.Build;
+import android.os.Bundle;
 import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.CommonDataKinds.Email;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.CommonDataKinds.StructuredName;
 import android.provider.Settings;
 import android.provider.Telephony.Threads;
 import android.service.notification.Condition;
@@ -59,6 +70,8 @@
 import android.test.AndroidTestCase;
 import android.util.Log;
 
+import com.android.compatibility.common.util.SystemUtil;
+
 import junit.framework.Assert;
 
 import java.io.FileInputStream;
@@ -141,6 +154,74 @@
         }
     }
 
+    private void insertSingleContact(String name, String phone, String email, boolean starred) {
+        final ArrayList<ContentProviderOperation> operationList =
+                new ArrayList<ContentProviderOperation>();
+        ContentProviderOperation.Builder builder =
+                ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI);
+        builder.withValue(ContactsContract.RawContacts.STARRED, starred ? 1 : 0);
+        operationList.add(builder.build());
+
+        builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
+        builder.withValueBackReference(StructuredName.RAW_CONTACT_ID, 0);
+        builder.withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
+        builder.withValue(StructuredName.DISPLAY_NAME, name);
+        operationList.add(builder.build());
+
+        if (phone != null) {
+            builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
+            builder.withValueBackReference(Phone.RAW_CONTACT_ID, 0);
+            builder.withValue(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
+            builder.withValue(Phone.TYPE, Phone.TYPE_MOBILE);
+            builder.withValue(Phone.NUMBER, phone);
+            builder.withValue(Data.IS_PRIMARY, 1);
+            operationList.add(builder.build());
+        }
+        if (email != null) {
+            builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
+            builder.withValueBackReference(Email.RAW_CONTACT_ID, 0);
+            builder.withValue(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
+            builder.withValue(Email.TYPE, Email.TYPE_HOME);
+            builder.withValue(Email.DATA, email);
+            operationList.add(builder.build());
+        }
+
+        try {
+            mContext.getContentResolver().applyBatch(ContactsContract.AUTHORITY, operationList);
+        } catch (RemoteException e) {
+            Log.e(TAG, String.format("%s: %s", e.toString(), e.getMessage()));
+        } catch (OperationApplicationException e) {
+            Log.e(TAG, String.format("%s: %s", e.toString(), e.getMessage()));
+        }
+    }
+
+    private Uri lookupContact(String phone) {
+        Cursor c = null;
+        try {
+            Uri phoneUri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI,
+                    Uri.encode(phone));
+            String[] projection = new String[] { ContactsContract.Contacts._ID,
+                    ContactsContract.Contacts.LOOKUP_KEY };
+            c = mContext.getContentResolver().query(phoneUri, projection, null, null, null);
+            if (c != null && c.getCount() > 0) {
+                c.moveToFirst();
+                int lookupIdx = c.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY);
+                int idIdx = c.getColumnIndex(ContactsContract.Contacts._ID);
+                String lookupKey = c.getString(lookupIdx);
+                long contactId = c.getLong(idIdx);
+                return ContactsContract.Contacts.getLookupUri(contactId, lookupKey);
+            }
+        } catch (Throwable t) {
+            Log.w(TAG, "Problem getting content resolver or performing contacts query.", t);
+        } finally {
+            if (c != null) {
+                c.close();
+            }
+        }
+        return null;
+    }
+
+
     private StatusBarNotification findPostedNotification(int id) {
         // notification is a bit asynchronous so it may take a few ms to appear in
         // getActiveNotifications()
@@ -884,6 +965,57 @@
         mListener.resetData();
     }
 
+    public void testCanBubble_ranking() throws Exception {
+        if (mActivityManager.isLowRamDevice() && !mPackageManager.hasSystemFeature(FEATURE_WATCH)) {
+            return;
+        }
+
+        assertEquals(1, Settings.Secure.getInt(
+                mContext.getContentResolver(), Settings.Secure.NOTIFICATION_BUBBLES));
+
+        toggleListenerAccess(TestNotificationListener.getId(),
+                InstrumentationRegistry.getInstrumentation(), true);
+        Thread.sleep(500); // wait for listener to be allowed
+
+        mListener = TestNotificationListener.getInstance();
+        assertNotNull(mListener);
+        try {
+            sendNotification(1, R.drawable.black);
+            Thread.sleep(500); // wait for notification listener to receive notification
+            NotificationListenerService.RankingMap rankingMap = mListener.mRankingMap;
+            NotificationListenerService.Ranking outRanking =
+                    new NotificationListenerService.Ranking();
+            for (String key : rankingMap.getOrderedKeys()) {
+                if (key.contains(mListener.getPackageName())) {
+                    rankingMap.getRanking(key, outRanking);
+                    // by default everything can bubble
+                    assertTrue(outRanking.canBubble());
+                }
+            }
+
+            // turn off bubbles globally
+            SystemUtil.runWithShellPermissionIdentity(() ->
+                    Settings.Secure.putInt(mContext.getContentResolver(),
+                            Settings.Secure.NOTIFICATION_BUBBLES, 0));
+
+            Thread.sleep(500); // wait for ranking update
+
+            rankingMap = mListener.mRankingMap;
+            outRanking = new NotificationListenerService.Ranking();
+            for (String key : rankingMap.getOrderedKeys()) {
+                if (key.contains(mListener.getPackageName())) {
+                    assertFalse(outRanking.canBubble());
+                }
+            }
+
+            mListener.resetData();
+        } finally {
+            SystemUtil.runWithShellPermissionIdentity(() ->
+                    Settings.Secure.putInt(mContext.getContentResolver(),
+                            Settings.Secure.NOTIFICATION_BUBBLES, 1));
+        }
+    }
+
     public void testNotify_blockedChannel() throws Exception {
         mNotificationManager.cancelAll();
 
@@ -1540,4 +1672,46 @@
         StatusBarNotification n = findPostedNotification(id);
         assertNotNull(n);
     }
+
+    public void testShouldHideSilentStatusIcons() throws Exception {
+        try {
+            mNotificationManager.shouldHideSilentStatusBarIcons();
+            fail("Non-privileged apps should not get this information");
+        } catch (SecurityException e) {
+            // pass
+        }
+
+        toggleListenerAccess(TestNotificationListener.getId(),
+                InstrumentationRegistry.getInstrumentation(), true);
+        // no exception this time
+        mNotificationManager.shouldHideSilentStatusBarIcons();
+    }
+
+    public void testMatchesCallFilter() throws Exception {
+        // allow all callers
+        toggleNotificationPolicyAccess(mContext.getPackageName(),
+                InstrumentationRegistry.getInstrumentation(), true);
+        NotificationManager.Policy currPolicy = mNotificationManager.getNotificationPolicy();
+        NotificationManager.Policy newPolicy = new NotificationManager.Policy(
+                NotificationManager.Policy.PRIORITY_CATEGORY_CALLS
+                        | NotificationManager.Policy.PRIORITY_CATEGORY_REPEAT_CALLERS,
+                NotificationManager.Policy.PRIORITY_SENDERS_ANY,
+                currPolicy.priorityMessageSenders,
+                currPolicy.suppressedVisualEffects);
+        mNotificationManager.setNotificationPolicy(newPolicy);
+
+        // add a contact
+        String ALICE = "Alice";
+        String ALICE_PHONE = "+16175551212";
+        String ALICE_EMAIL = "alice@_foo._bar";
+
+        insertSingleContact(ALICE, ALICE_PHONE, ALICE_EMAIL, false);
+
+        final Bundle peopleExtras = new Bundle();
+        ArrayList<Person> personList = new ArrayList<>();
+        personList.add(new Person.Builder().setUri(lookupContact(ALICE_PHONE).toString()).build());
+        peopleExtras.putParcelableArrayList(Notification.EXTRA_PEOPLE_LIST, personList);
+        SystemUtil.runWithShellPermissionIdentity(() ->
+                assertTrue(mNotificationManager.matchesCallFilter(peopleExtras)));
+    }
 }
diff --git a/tests/app/src/android/app/cts/SystemFeaturesTest.java b/tests/app/src/android/app/cts/SystemFeaturesTest.java
index 270fc38..3109a0e 100644
--- a/tests/app/src/android/app/cts/SystemFeaturesTest.java
+++ b/tests/app/src/android/app/cts/SystemFeaturesTest.java
@@ -44,6 +44,7 @@
 import android.test.InstrumentationTestCase;
 
 import com.android.compatibility.common.util.PropertyUtil;
+import com.android.compatibility.common.util.SystemUtil;
 
 import java.lang.reflect.Field;
 import java.util.ArrayList;
@@ -539,10 +540,12 @@
         boolean enabled = mWifiManager.isWifiEnabled();
         try {
             // assert wifimanager can toggle wifi from current sate
-            assertTrue(mWifiManager.setWifiEnabled(!enabled));
+            SystemUtil.runShellCommand("svc wifi " + (!enabled ? "enable" : "disable"));
+            Thread.sleep(5_000); // wait for the toggle to take effect.
+            assertEquals(!enabled, mWifiManager.isWifiEnabled());
 
         } finally {
-            mWifiManager.setWifiEnabled(enabled);
+            SystemUtil.runShellCommand("svc wifi " + (enabled ? "enable" : "disable"));
         }
     }
 
diff --git a/tests/app/src/android/app/cts/TestContextTest.java b/tests/app/src/android/app/cts/TestContextTest.java
new file mode 100644
index 0000000..c2a6f50
--- /dev/null
+++ b/tests/app/src/android/app/cts/TestContextTest.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.cts;
+
+import android.app.Instrumentation;
+import android.provider.Settings.Global;
+import android.test.InstrumentationTestCase;
+
+public class TestContextTest extends InstrumentationTestCase {
+    public void testTestOpPackageName() {
+        Instrumentation instrumentation = getInstrumentation();
+        assertEquals("android.app.cts", instrumentation.getContext().getPackageName());
+
+        // getOpPackageName() should return the target app's package name.
+        assertEquals("android.app.stubs", instrumentation.getContext().getOpPackageName());
+
+        instrumentation.getContext().getContentResolver().query(
+                Global.CONTENT_URI, null, null, null, null);
+    }
+}
diff --git a/tests/app/src/android/app/cts/WallpaperInfoTest.java b/tests/app/src/android/app/cts/WallpaperInfoTest.java
index 123a9cd..90a303c 100644
--- a/tests/app/src/android/app/cts/WallpaperInfoTest.java
+++ b/tests/app/src/android/app/cts/WallpaperInfoTest.java
@@ -48,7 +48,7 @@
         ResolveInfo info = result.get(0);
         WallpaperInfo wallpaperInfo = new WallpaperInfo(context, info);
         assertEquals(context.getString(R.string.wallpaper_title), wallpaperInfo.loadLabel(pm));
-        assertEquals(context.getString(R.string.wallpaper_collection),
+        assertEquals(context.getString(R.string.wallpaper_description),
             wallpaperInfo.loadDescription(pm));
         assertEquals(context.getString(R.string.wallpaper_collection),
             wallpaperInfo.loadAuthor(pm));
diff --git a/tests/app/src/android/app/cts/android/app/cts/tools/WatchUidRunner.java b/tests/app/src/android/app/cts/android/app/cts/tools/WatchUidRunner.java
index 4daf78b..09c28e7 100644
--- a/tests/app/src/android/app/cts/android/app/cts/tools/WatchUidRunner.java
+++ b/tests/app/src/android/app/cts/android/app/cts/tools/WatchUidRunner.java
@@ -52,6 +52,7 @@
     public static final String STATE_PERSISTENT_UI = "PERU";
     public static final String STATE_TOP = "TOP";
     public static final String STATE_BOUND_FG_SERVICE = "BFGS";
+    public static final String STATE_FG_SERVICE_LOCATION = "FGSL";
     public static final String STATE_FG_SERVICE = "FGS";
     public static final String STATE_TOP_SLEEPING = "TPSL";
     public static final String STATE_IMPORTANT_FG = "IMPF";
diff --git a/tests/tests/debug/Android.mk b/tests/apppredictionservice/Android.mk
similarity index 65%
rename from tests/tests/debug/Android.mk
rename to tests/apppredictionservice/Android.mk
index c715d07..c30a677 100644
--- a/tests/tests/debug/Android.mk
+++ b/tests/apppredictionservice/Android.mk
@@ -1,4 +1,4 @@
-# Copyright (C) 2017 The Android Open Source Project
+# Copyright (C) 2019 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.
@@ -12,33 +12,29 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-LOCAL_PATH := $(call my-dir)
+LOCAL_PATH:= $(call my-dir)
 
 include $(CLEAR_VARS)
 
-LOCAL_PACKAGE_NAME := CtsDebugTestCases
-
 # Don't include this package in any target.
 LOCAL_MODULE_TAGS := optional
 
-# Include both the 32 and 64 bit versions
-LOCAL_MULTILIB := both
-
 # When built, explicitly put it in the data partition.
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
-# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
-
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner nativetesthelper
-
-LOCAL_JNI_SHARED_LIBRARIES := libdebugtest
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    androidx.annotation_annotation \
+    compatibility-device-util \
+    ctstestrunner \
+    truth-prebuilt
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_SDK_VERSION := current
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
+
+LOCAL_PACKAGE_NAME := CtsAppPredictionServiceTestCases
+
+LOCAL_SDK_VERSION := test_current
 
 include $(BUILD_CTS_PACKAGE)
-
-# Include the associated library's makefile.
-include $(LOCAL_PATH)/libdebugtest/Android.mk
diff --git a/tests/apppredictionservice/AndroidManifest.xml b/tests/apppredictionservice/AndroidManifest.xml
new file mode 100644
index 0000000..7da57c06
--- /dev/null
+++ b/tests/apppredictionservice/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2019 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.apppredictionservice.cts"
+    android:targetSandboxVersion="2">
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+
+        <!-- TODO(b/111701043): Update with required permissions -->
+        <service
+            android:name=".PredictionService"
+            android:label="CtsAppPredictionService">
+            <intent-filter>
+                <!-- This constant must match AppPredictionService.SERVICE_INTERFACE -->
+                <action android:name="android.service.appprediction.AppPredictionService" />
+            </intent-filter>
+        </service>
+
+    </application>
+
+    <instrumentation
+        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:label="CTS tests for the App Prediction Framework APIs."
+        android:targetPackage="android.apppredictionservice.cts" >
+    </instrumentation>
+
+</manifest>
diff --git a/tests/apppredictionservice/AndroidTest.xml b/tests/apppredictionservice/AndroidTest.xml
new file mode 100644
index 0000000..660955c
--- /dev/null
+++ b/tests/apppredictionservice/AndroidTest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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 App Prediction CTS tests.">
+  <option name="test-suite-tag" value="cts" />
+  <option name="config-descriptor:metadata" key="component" value="framework" />
+
+  <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+    <option name="cleanup-apks" value="true" />
+    <option name="test-file-name" value="CtsAppPredictionServiceTestCases.apk" />
+  </target_preparer>
+
+  <test class="com.android.tradefed.testtype.AndroidJUnitTest">
+    <option name="package" value="android.apppredictionservice.cts" />
+    <!-- 20x default timeout of 600sec -->
+    <option name="shell-timeout" value="12000000"/>
+  </test>
+
+</configuration>
diff --git a/tests/apppredictionservice/src/android/apppredictionservice/cts/AppPredictionServiceTest.java b/tests/apppredictionservice/src/android/apppredictionservice/cts/AppPredictionServiceTest.java
new file mode 100644
index 0000000..4cf9741
--- /dev/null
+++ b/tests/apppredictionservice/src/android/apppredictionservice/cts/AppPredictionServiceTest.java
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2019 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.apppredictionservice.cts;
+
+import static android.apppredictionservice.cts.PredictionService.EXTRA_REPORTER;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.app.prediction.AppPredictionContext;
+import android.app.prediction.AppPredictionManager;
+import android.app.prediction.AppPredictor;
+import android.app.prediction.AppTarget;
+import android.app.prediction.AppTargetEvent;
+import android.app.prediction.AppTargetId;
+import android.apppredictionservice.cts.ServiceReporter.RequestVerifier;
+import android.content.Context;
+import android.os.Bundle;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.Log;
+
+import com.android.compatibility.common.util.SystemUtil;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+
+/**
+ * atest CtsAppPredictionServiceTestCases:AppPredictionServiceTest
+ */
+@RunWith(AndroidJUnit4.class)
+public class AppPredictionServiceTest {
+
+    private static final String TAG = "AppPredictionServiceTest";
+
+    private static final String APP_PREDICTION_SERVICE = "app_prediction";
+
+    private static final String TEST_UI_SURFACE = "testSysUiSurface";
+    private static final int TEST_NUM_PREDICTIONS = 10;
+    private static final String TEST_LAUNCH_LOCATION = "testCollapsedLocation";
+    private static final int TEST_ACTION = 2;
+
+    private ServiceReporter mReporter;
+    private Bundle mPredictionContextExtras;
+
+    @Before
+    public void setUp() throws Exception {
+        // Enable the prediction service
+        setService(PredictionService.SERVICE_NAME);
+        mReporter = new ServiceReporter();
+        mPredictionContextExtras = new Bundle();
+        mPredictionContextExtras.putBinder(EXTRA_REPORTER, mReporter);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        // Reset the prediction service
+        setService(null);
+        mReporter = null;
+        SystemClock.sleep(1000);
+    }
+
+    @Test
+    public void testCreateDestroySession() {
+        AppPredictionContext context =  createTestPredictionContext();
+        AppPredictor client = createTestPredictor(context);
+
+        // Wait for the service to bind and the session to be created
+        mReporter.awaitOnCreatePredictionSession();
+        mReporter.assertActiveSession(client.getSessionId());
+        assertEquals(mReporter.getPredictionContext(client.getSessionId()), context);
+
+        // Create another session, and ensure that the session ids differ
+        AppPredictionContext context2 =  createTestPredictionContext();
+        AppPredictor client2 = createTestPredictor(context2);
+
+        mReporter.awaitOnCreatePredictionSession();
+        mReporter.assertActiveSession(client2.getSessionId());
+        assertEquals(mReporter.getPredictionContext(client2.getSessionId()), context2);
+        assertNotEquals(client.getSessionId(), client2.getSessionId());
+
+        // Destroy both sessions
+        client.destroy();
+        mReporter.awaitOnDestroyPredictionSession();
+        client2.destroy();
+        mReporter.awaitOnDestroyPredictionSession();
+
+        // Ensure that the session are no longer active
+        assertFails(() -> mReporter.assertActiveSession(client.getSessionId()));
+        assertFails(() -> mReporter.assertActiveSession(client2.getSessionId()));
+
+        // Ensure that future calls to the client fail
+        assertFails(() -> client.notifyAppTargetEvent(null));
+        assertFails(() -> client.notifyLocationShown(null, null));
+        assertFails(() -> client.registerPredictionUpdates(null, null));
+        assertFails(() -> client.unregisterPredictionUpdates(null));
+        assertFails(() -> client.requestPredictionUpdate());
+        assertFails(() -> client.sortTargets(null, null, null));
+        assertFails(() -> client.destroy());
+    }
+
+    @Test
+    public void testRegisterPredictionUpdatesLifecycle() {
+        AppPredictionContext context = createTestPredictionContext();
+        AppPredictor client = createTestPredictor(context);
+
+        RequestVerifier cb = new RequestVerifier(mReporter);
+        client.registerPredictionUpdates(Executors.newSingleThreadExecutor(), cb);
+
+        // Verify some updates
+        assertTrue(cb.requestAndWaitForTargets(createPredictions(),
+                () -> client.requestPredictionUpdate()));
+        assertTrue(cb.requestAndWaitForTargets(createPredictions(),
+                () -> client.requestPredictionUpdate()));
+        assertTrue(cb.requestAndWaitForTargets(createPredictions(),
+                () -> client.requestPredictionUpdate()));
+
+        client.unregisterPredictionUpdates(cb);
+
+        // Ensure we don't get updates after the listeners are unregistered
+        assertFalse(cb.requestAndWaitForTargets(createPredictions(),
+                () -> client.requestPredictionUpdate()));
+    }
+
+    @Test
+    public void testAppTargetEvent() {
+        AppPredictionContext context = createTestPredictionContext();
+        AppPredictor client = createTestPredictor(context);
+
+        List<AppTarget> targets = createPredictions();
+        List<AppTargetEvent> events = new ArrayList<>();
+        for (AppTarget target : targets) {
+            AppTargetEvent event = new AppTargetEvent.Builder(target, TEST_ACTION)
+                    .setLaunchLocation(TEST_LAUNCH_LOCATION)
+                    .build();
+            events.add(event);
+            client.notifyAppTargetEvent(event);
+            mReporter.awaitOnAppTargetEvent();
+        }
+        assertEquals(mReporter.mEvents, events);
+    }
+
+    @Test
+    public void testNotifyLocationShown() {
+        AppPredictionContext context = createTestPredictionContext();
+        AppPredictor client = createTestPredictor(context);
+
+        List<AppTarget> targets = createPredictions();
+        List<AppTargetId> targetIds = new ArrayList<>();
+        for (AppTarget target : targets) {
+            AppTargetId id = target.getId();
+            targetIds.add(id);
+        }
+        client.notifyLocationShown(TEST_LAUNCH_LOCATION, targetIds);
+        mReporter.awaitOnLocationShown();
+        assertEquals(mReporter.mLocationsShown, TEST_LAUNCH_LOCATION);
+        assertEquals(mReporter.mLocationsShownTargets, targetIds);
+    }
+
+    @Test
+    public void testSortTargets() {
+        AppPredictionContext context = createTestPredictionContext();
+        AppPredictor client = createTestPredictor(context);
+
+        List<AppTarget> sortedTargets = createPredictions();
+        List<AppTarget> shuffledTargets = new ArrayList<>(sortedTargets);
+        Collections.shuffle(shuffledTargets);
+
+        // We call sortTargets below with the shuffled targets, ensure that the service receives the
+        // shuffled targets, and return the sorted targets to the RequestVerifier below
+        mReporter.setSortedPredictionsProvider((targets) -> {
+            assertEquals(targets, shuffledTargets);
+            return sortedTargets;
+        });
+        RequestVerifier cb = new RequestVerifier(mReporter);
+        assertTrue(cb.requestAndWaitForTargets(sortedTargets,
+                () -> client.sortTargets(shuffledTargets,
+                        Executors.newSingleThreadExecutor(), cb)));
+    }
+
+    private void assertFails(Runnable r) {
+        try {
+            r.run();
+        } catch (Exception|Error e) {
+            // Expected failure
+            return;
+        }
+        fail("Expected failure");
+    }
+
+    /** Creates a random number of targets by increasing id */
+    private List<AppTarget> createPredictions() {
+        List<AppTarget> targets = new ArrayList<>();
+        int n = (int) (Math.random() * 20);
+        for (int i = 0; i < n; i++) {
+            targets.add(new AppTarget(new AppTargetId(String.valueOf(i)), "test.pkg",
+                    "test.class." + i, UserHandle.CURRENT));
+        }
+        return targets;
+    }
+
+    private AppPredictionContext createTestPredictionContext() {
+        return new AppPredictionContext.Builder(InstrumentationRegistry.getTargetContext())
+                .setExtras(mPredictionContextExtras)
+                .setUiSurface(TEST_UI_SURFACE)
+                .setPredictedTargetCount(TEST_NUM_PREDICTIONS)
+                .build();
+    }
+
+    private AppPredictor createTestPredictor(AppPredictionContext context) {
+        Context ctx = InstrumentationRegistry.getTargetContext();
+        AppPredictionManager mgr = (AppPredictionManager) ctx.getSystemService(
+                APP_PREDICTION_SERVICE);
+        return mgr.createAppPredictionSession(context);
+    }
+
+    private void setService(String service) {
+        Log.d(TAG, "Setting app prediction service to " + service);
+        if (service != null) {
+            runShellCommand("cmd app_prediction set temporary-service 0 " + service + " 12000");
+        } else {
+            runShellCommand("cmd app_prediction set temporary-service 0");
+        }
+    }
+
+    private void runShellCommand(String command) {
+        Log.d(TAG, "runShellCommand(): " + command);
+        try {
+            SystemUtil.runShellCommand(InstrumentationRegistry.getInstrumentation(), command);
+        } catch (Exception e) {
+            throw new RuntimeException("Command '" + command + "' failed: ", e);
+        }
+    }
+}
diff --git a/tests/apppredictionservice/src/android/apppredictionservice/cts/PredictionService.java b/tests/apppredictionservice/src/android/apppredictionservice/cts/PredictionService.java
new file mode 100644
index 0000000..f65910c
--- /dev/null
+++ b/tests/apppredictionservice/src/android/apppredictionservice/cts/PredictionService.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2019 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.apppredictionservice.cts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import android.app.prediction.AppPredictionSessionId;
+import android.app.prediction.AppTargetEvent;
+import android.app.prediction.AppTargetId;
+import android.os.CancellationSignal;
+import android.app.prediction.AppPredictionContext;
+import android.service.appprediction.AppPredictionService;
+import android.app.prediction.AppTarget;
+
+import java.util.List;
+import java.util.function.Consumer;
+
+public class PredictionService extends AppPredictionService {
+
+    private static final String TAG = PredictionService.class.getSimpleName();
+
+    public static final String MY_PACKAGE = "android.apppredictionservice.cts";
+    public static final String SERVICE_NAME = MY_PACKAGE + "/."
+            + PredictionService.class.getSimpleName();
+
+    public static final String EXTRA_REPORTER = "extra_reporter";
+
+    private ServiceReporter mReporter;
+
+    @Override
+    public void onCreatePredictionSession(AppPredictionContext context,
+            AppPredictionSessionId sessionId) {
+        mReporter = (ServiceReporter) context.getExtras().getBinder(EXTRA_REPORTER);
+        mReporter.onCreatePredictionSession(context, sessionId);
+    }
+
+    @Override
+    public void onAppTargetEvent(AppPredictionSessionId sessionId, AppTargetEvent event) {
+        mReporter.onAppTargetEvent(sessionId, event);
+    }
+
+    @Override
+    public void onLocationShown(AppPredictionSessionId sessionId, String launchLocation,
+            List<AppTargetId> targetIds) {
+        mReporter.onLocationShown(sessionId, launchLocation, targetIds);
+    }
+
+    @Override
+    public void onSortAppTargets(AppPredictionSessionId sessionId, List<AppTarget> targets,
+            CancellationSignal cancellationSignal, Consumer<List<AppTarget>> callback) {
+        mReporter.onSortAppTargets(sessionId, targets, callback);
+        callback.accept(mReporter.getSortedPredictionsProvider().sortTargets(targets));
+    }
+
+    @Override
+    public void onRequestPredictionUpdate(AppPredictionSessionId sessionId) {
+        mReporter.onRequestPredictionUpdate(sessionId);
+        updatePredictions(sessionId, mReporter.getPredictionsProvider().getTargets(sessionId));
+    }
+
+    @Override
+    public void onDestroyPredictionSession(AppPredictionSessionId sessionId) {
+        mReporter.onDestroyPredictionSession(sessionId);
+    }
+
+    @Override
+    public void onStartPredictionUpdates() {
+        mReporter.onStartPredictionUpdates();
+    }
+
+    @Override
+    public void onStopPredictionUpdates() {
+        mReporter.onStopPredictionUpdates();
+    }
+}
diff --git a/tests/apppredictionservice/src/android/apppredictionservice/cts/PredictionsProvider.java b/tests/apppredictionservice/src/android/apppredictionservice/cts/PredictionsProvider.java
new file mode 100644
index 0000000..811b52e
--- /dev/null
+++ b/tests/apppredictionservice/src/android/apppredictionservice/cts/PredictionsProvider.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2019 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.apppredictionservice.cts;
+
+import android.app.prediction.AppPredictionSessionId;
+import android.app.prediction.AppTarget;
+
+import java.util.List;
+
+/**
+ * Implemented by the tests to provide predictions to be reported by the CTS prediction service to
+ * the prediction callbacks.
+ */
+public interface PredictionsProvider {
+    List<AppTarget> getTargets(AppPredictionSessionId sessionId);
+}
diff --git a/tests/apppredictionservice/src/android/apppredictionservice/cts/ServiceReporter.java b/tests/apppredictionservice/src/android/apppredictionservice/cts/ServiceReporter.java
new file mode 100644
index 0000000..0f1ff81
--- /dev/null
+++ b/tests/apppredictionservice/src/android/apppredictionservice/cts/ServiceReporter.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2019 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.apppredictionservice.cts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import android.app.prediction.AppPredictionContext;
+import android.app.prediction.AppPredictionSessionId;
+import android.app.prediction.AppPredictor;
+import android.app.prediction.AppTarget;
+import android.app.prediction.AppTargetEvent;
+import android.app.prediction.AppTargetId;
+import android.os.Binder;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
+
+/**
+ * Reports calls from the CTS prediction service back to the tests.
+ */
+public class ServiceReporter extends Binder {
+
+    public HashMap<AppPredictionSessionId, AppPredictionContext> mSessions = new HashMap<>();
+
+    public ArrayList<AppTargetEvent> mEvents = new ArrayList<>();
+    public String mLocationsShown;
+    public ArrayList<AppTargetId> mLocationsShownTargets = new ArrayList<>();
+    public int mNumRequestedUpdates = 0;
+    public boolean mPredictionUpdatesStarted = false;
+
+    private CountDownLatch mCreateSessionLatch = new CountDownLatch(1);
+    private CountDownLatch mEventLatch = new CountDownLatch(1);
+    private CountDownLatch mLocationShownLatch = new CountDownLatch(1);
+    private CountDownLatch mSortLatch = new CountDownLatch(1);
+    private CountDownLatch mStartPredictionUpdatesLatch = new CountDownLatch(1);
+    private CountDownLatch mStopPredictionUpdatesLatch = new CountDownLatch(1);
+    private CountDownLatch mPredictionUpdateLatch = new CountDownLatch(1);
+    private CountDownLatch mDestroyLatch = new CountDownLatch(1);
+
+    private PredictionsProvider mPredictionsProvider;
+    private SortedPredictionsProvider mSortedPredictionsProvider;
+
+    void setPredictionsProvider(PredictionsProvider cb) {
+        mPredictionsProvider = cb;
+    }
+
+    PredictionsProvider getPredictionsProvider() {
+        return mPredictionsProvider;
+    }
+
+    void setSortedPredictionsProvider(SortedPredictionsProvider cb) {
+        mSortedPredictionsProvider = cb;
+    }
+
+    SortedPredictionsProvider getSortedPredictionsProvider() {
+        return mSortedPredictionsProvider;
+    }
+
+    void assertActiveSession(AppPredictionSessionId sessionId) {
+        assertTrue(mSessions.containsKey(sessionId));
+    }
+
+    AppPredictionContext getPredictionContext(AppPredictionSessionId sessionId) {
+        assertTrue(mSessions.containsKey(sessionId));
+        return mSessions.get(sessionId);
+    }
+
+    void onCreatePredictionSession(AppPredictionContext context,
+            AppPredictionSessionId sessionId) {
+        assertNotNull(context);
+        assertNotNull(sessionId);
+        assertFalse(mSessions.containsKey(sessionId));
+        mSessions.put(sessionId, context);
+        mCreateSessionLatch.countDown();
+    }
+
+    boolean awaitOnCreatePredictionSession() {
+        try {
+            return await(mCreateSessionLatch);
+        } finally {
+            mCreateSessionLatch = new CountDownLatch(1);
+        }
+    }
+
+    void onAppTargetEvent(AppPredictionSessionId sessionId, AppTargetEvent event) {
+        assertTrue(mSessions.containsKey(sessionId));
+        mEvents.add(event);
+        mEventLatch.countDown();
+    }
+
+    boolean awaitOnAppTargetEvent() {
+        try {
+            return await(mEventLatch);
+        } finally {
+            mEventLatch = new CountDownLatch(1);
+        }
+    }
+
+    void onLocationShown(AppPredictionSessionId sessionId, String launchLocation,
+            List<AppTargetId> targetIds) {
+        assertTrue(mSessions.containsKey(sessionId));
+        mLocationsShown = launchLocation;
+        mLocationsShownTargets.addAll(targetIds);
+        mLocationShownLatch.countDown();
+    }
+
+    boolean awaitOnLocationShown() {
+        try {
+            return await(mLocationShownLatch);
+        } finally {
+            mLocationShownLatch = new CountDownLatch(1);
+        }
+    }
+
+    void onSortAppTargets(AppPredictionSessionId sessionId, List<AppTarget> targets,
+            Consumer<List<AppTarget>> callback) {
+        assertTrue(mSessions.containsKey(sessionId));
+        assertNotNull(targets);
+        assertNotNull(callback);
+        mSortLatch.countDown();
+    }
+
+    boolean awaitOnSortAppTargets() {
+        try {
+            return await(mSortLatch);
+        } finally {
+            mSortLatch = new CountDownLatch(1);
+        }
+    }
+
+    void onStartPredictionUpdates() {
+        mPredictionUpdatesStarted = true;
+    }
+
+    boolean awaitOnStartPredictionUpdates() {
+        try {
+            return await(mStartPredictionUpdatesLatch);
+        } finally {
+            mStartPredictionUpdatesLatch = new CountDownLatch(1);
+        }
+    }
+
+    void onStopPredictionUpdates() {
+        mPredictionUpdatesStarted = false;
+    }
+
+    boolean awaitOnStopPredictionUpdates() {
+        try {
+            return await(mStopPredictionUpdatesLatch);
+        } finally {
+            mStopPredictionUpdatesLatch = new CountDownLatch(1);
+        }
+    }
+
+    void onRequestPredictionUpdate(AppPredictionSessionId sessionId) {
+        assertTrue(mSessions.containsKey(sessionId));
+        mNumRequestedUpdates++;
+        mPredictionUpdateLatch.countDown();
+    }
+
+    boolean awaitOnRequestPredictionUpdate() {
+        try {
+            return await(mPredictionUpdateLatch);
+        } finally {
+            mPredictionUpdateLatch = new CountDownLatch(1);
+        }
+    }
+
+    void onDestroyPredictionSession(AppPredictionSessionId sessionId) {
+        assertTrue(mSessions.containsKey(sessionId));
+        mSessions.remove(sessionId);
+        mDestroyLatch.countDown();
+    }
+
+    boolean awaitOnDestroyPredictionSession() {
+        try {
+            return await(mDestroyLatch);
+        } finally {
+            mDestroyLatch = new CountDownLatch(1);
+        }
+    }
+
+    public class Event {
+        final AppTarget target;
+        final int launchLocation;
+        final int eventType;
+
+        public Event(AppTarget target, int launchLocation, int eventType) {
+            this.target = target;
+            this.launchLocation = launchLocation;
+            this.eventType = eventType;
+        }
+    }
+
+    private boolean await(CountDownLatch latch) {
+        try {
+            latch.await(500, TimeUnit.MILLISECONDS);
+            return true;
+        } catch (InterruptedException e) {
+            return false;
+        }
+    }
+
+    public static class RequestVerifier implements AppPredictor.Callback, PredictionsProvider,
+            Consumer<List<AppTarget>> {
+
+        private ServiceReporter mReporter;
+        private CountDownLatch mReceivedLatch;
+        private List<AppTarget> mTargets;
+
+        public RequestVerifier(ServiceReporter reporter) {
+            mReporter = reporter;
+            mReceivedLatch = new CountDownLatch(1);
+        }
+
+        @Override
+        public List<AppTarget> getTargets(AppPredictionSessionId sessionId) {
+            return mTargets;
+        }
+
+        @Override
+        public void onTargetsAvailable(List<AppTarget> targets) {
+            if (mTargets != null) {
+                // Verify that the targets match
+                assertEquals(targets, mTargets);
+            } else {
+                // For the case where we didn't setup the request, save the targets so we can verify
+                // them in awaitTargets()
+                mTargets = targets;
+            }
+            mReceivedLatch.countDown();
+        }
+
+        @Override
+        public void accept(List<AppTarget> appTargets) {
+            onTargetsAvailable(appTargets);
+        }
+
+        /**
+         * @param requestUpdateCb Callback called when the request is setup
+         */
+        boolean requestAndWaitForTargets(List<AppTarget> targets, Runnable requestUpdateCb) {
+            mTargets = targets;
+            mReceivedLatch = new CountDownLatch(1);
+            mReporter.setPredictionsProvider(this);
+            requestUpdateCb.run();
+            try {
+                return awaitTargets(targets);
+            } finally {
+                mReporter.setPredictionsProvider(null);
+            }
+        }
+
+        boolean awaitTargets(List<AppTarget> targets) {
+            try {
+                boolean result = mReceivedLatch.await(500, TimeUnit.MILLISECONDS);
+                assertEquals(targets, mTargets);
+                return result;
+            } catch (InterruptedException e) {
+                return false;
+            }
+        }
+    }
+}
diff --git a/tests/apppredictionservice/src/android/apppredictionservice/cts/SortedPredictionsProvider.java b/tests/apppredictionservice/src/android/apppredictionservice/cts/SortedPredictionsProvider.java
new file mode 100644
index 0000000..939506f
--- /dev/null
+++ b/tests/apppredictionservice/src/android/apppredictionservice/cts/SortedPredictionsProvider.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2019 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.apppredictionservice.cts;
+
+import android.app.prediction.AppTarget;
+
+import java.util.List;
+
+/**
+ * Implemented by the tests to sort predictions to be reported by the CTS prediction service to
+ * the prediction callbacks.
+ */
+public interface SortedPredictionsProvider {
+    List<AppTarget> sortTargets(List<AppTarget> targets);
+}
diff --git a/tests/autofillservice/AndroidTest.xml b/tests/autofillservice/AndroidTest.xml
index 4fe406f..e7413b1 100644
--- a/tests/autofillservice/AndroidTest.xml
+++ b/tests/autofillservice/AndroidTest.xml
@@ -17,6 +17,7 @@
   <option name="test-suite-tag" value="cts" />
   <option name="config-descriptor:metadata" key="component" value="autofill" />
   <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
+  <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
 
   <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
     <option name="cleanup-apks" value="true" />
diff --git a/tests/autofillservice/src/android/autofillservice/cts/AbstractAutoFillActivity.java b/tests/autofillservice/src/android/autofillservice/cts/AbstractAutoFillActivity.java
index bc7e7c1..051a6ac 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/AbstractAutoFillActivity.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/AbstractAutoFillActivity.java
@@ -29,7 +29,9 @@
 
 import androidx.annotation.NonNull;
 
+import com.android.compatibility.common.util.RetryableException;
 import com.android.compatibility.common.util.SynchronousPixelCopy;
+import com.android.compatibility.common.util.Timeout;
 
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
diff --git a/tests/autofillservice/src/android/autofillservice/cts/AutoFillServiceTestCase.java b/tests/autofillservice/src/android/autofillservice/cts/AutoFillServiceTestCase.java
index 1e1e740..6997453 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/AutoFillServiceTestCase.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/AutoFillServiceTestCase.java
@@ -18,11 +18,12 @@
 
 import static android.autofillservice.cts.Helper.getContext;
 import static android.autofillservice.cts.InstrumentedAutoFillService.SERVICE_NAME;
-import static android.autofillservice.cts.common.ShellHelper.runShellCommand;
 import static android.content.Context.CLIPBOARD_SERVICE;
+import static android.provider.Settings.Global.AUTOFILL_SMART_SUGGESTION_EMULATION_FLAGS;
+
+import static com.android.compatibility.common.util.ShellUtils.runShellCommand;
 
 import android.autofillservice.cts.InstrumentedAutoFillService.Replier;
-import android.autofillservice.cts.common.SettingsStateKeeperRule;
 import android.content.ClipboardManager;
 import android.content.Context;
 import android.content.Intent;
@@ -36,7 +37,12 @@
 import androidx.annotation.NonNull;
 
 import com.android.compatibility.common.util.RequiredFeatureRule;
+import com.android.compatibility.common.util.RetryRule;
 import com.android.compatibility.common.util.SafeCleanerRule;
+import com.android.compatibility.common.util.SettingsStateChangerRule;
+import com.android.compatibility.common.util.SettingsStateKeeperRule;
+import com.android.compatibility.common.util.SettingsUtils;
+import com.android.compatibility.common.util.TestNameUtils;
 
 import org.junit.Before;
 import org.junit.ClassRule;
@@ -156,12 +162,12 @@
                 new SettingsStateKeeperRule(sContext, Settings.Secure.AUTOFILL_SERVICE) {
             @Override
             protected void preEvaluate(Description description) {
-                JUnitHelper.setCurrentTestClass(description.getClassName());
+                TestNameUtils.setCurrentTestClass(description.getClassName());
             }
 
             @Override
             protected void postEvaluate(Description description) {
-                JUnitHelper.setCurrentTestClass(null);
+                TestNameUtils.setCurrentTestClass(null);
             }
         };
 
@@ -199,6 +205,10 @@
                 // mRetryRule should be closest to the main test as possible
                 .around(mRetryRule)
                 //
+                // Augmented Autofill should be disabled by default
+                .around(new SettingsStateChangerRule(sContext, SettingsUtils.NAMESPACE_GLOBAL,
+                        AUTOFILL_SMART_SUGGESTION_EMULATION_FLAGS,
+                        Integer.toString(getSmartSuggestionMode())))
                 //
                 // Finally, let subclasses add their own rules (like ActivityTestRule)
                 .around(getMainTestRule());
@@ -214,6 +224,10 @@
             mUiBot.reset();
         }
 
+        protected int getSmartSuggestionMode() {
+            return 0;
+        }
+
         /**
          * Gets how many times a test should be retried.
          *
diff --git a/tests/autofillservice/src/android/autofillservice/cts/AutofillLoggingTestRule.java b/tests/autofillservice/src/android/autofillservice/cts/AutofillLoggingTestRule.java
index 5c5e881..430234a 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/AutofillLoggingTestRule.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/AutofillLoggingTestRule.java
@@ -16,7 +16,7 @@
 
 package android.autofillservice.cts;
 
-import static android.autofillservice.cts.common.ShellHelper.runShellCommand;
+import static com.android.compatibility.common.util.ShellUtils.runShellCommand;
 
 import android.util.Log;
 
diff --git a/tests/autofillservice/src/android/autofillservice/cts/AutofillTestWatcher.java b/tests/autofillservice/src/android/autofillservice/cts/AutofillTestWatcher.java
index 2cca253..6879a8c 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/AutofillTestWatcher.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/AutofillTestWatcher.java
@@ -22,6 +22,8 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
+import com.android.compatibility.common.util.TestNameUtils;
+
 import org.junit.rules.TestWatcher;
 import org.junit.runner.Description;
 
@@ -47,7 +49,7 @@
         resetStaticState();
         final String testName = description.getDisplayName();
         Log.i(TAG, "Starting " + testName);
-        JUnitHelper.setCurrentTestName(testName);
+        TestNameUtils.setCurrentTestName(testName);
     }
 
     @Override
@@ -60,7 +62,7 @@
             resetStaticState();
         }
         Log.i(TAG, "Finished " + testName);
-        JUnitHelper.setCurrentTestName(null);
+        TestNameUtils.setCurrentTestName(null);
     }
 
     private void resetStaticState() {
diff --git a/tests/autofillservice/src/android/autofillservice/cts/DatasetFilteringTest.java b/tests/autofillservice/src/android/autofillservice/cts/DatasetFilteringTest.java
index 7159783..85e07ba 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/DatasetFilteringTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/DatasetFilteringTest.java
@@ -17,7 +17,8 @@
 package android.autofillservice.cts;
 
 import static android.autofillservice.cts.Helper.ID_USERNAME;
-import static android.autofillservice.cts.common.ShellHelper.sendKeyEvent;
+
+import static com.android.compatibility.common.util.ShellUtils.sendKeyEvent;
 
 import android.autofillservice.cts.CannedFillResponse.CannedDataset;
 import android.content.IntentSender;
diff --git a/tests/autofillservice/src/android/autofillservice/cts/DisableAutofillTest.java b/tests/autofillservice/src/android/autofillservice/cts/DisableAutofillTest.java
index d4d1ff4..77f5efd 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/DisableAutofillTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/DisableAutofillTest.java
@@ -26,6 +26,8 @@
 import android.service.autofill.FillResponse;
 import android.util.Log;
 
+import com.android.compatibility.common.util.RetryableException;
+
 import org.junit.Test;
 
 /**
diff --git a/tests/autofillservice/src/android/autofillservice/cts/DuplicateIdActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/DuplicateIdActivityTest.java
index 53ff280..29b4df3 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/DuplicateIdActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/DuplicateIdActivityTest.java
@@ -18,7 +18,8 @@
 
 import static android.autofillservice.cts.CannedFillResponse.NO_RESPONSE;
 import static android.autofillservice.cts.DuplicateIdActivity.DUPLICATE_ID;
-import static android.autofillservice.cts.common.ShellHelper.runShellCommand;
+
+import static com.android.compatibility.common.util.ShellUtils.runShellCommand;
 
 import static com.google.common.truth.Truth.assertThat;
 
diff --git a/tests/autofillservice/src/android/autofillservice/cts/FieldsClassificationTest.java b/tests/autofillservice/src/android/autofillservice/cts/FieldsClassificationTest.java
index 2a14468..5f81df2 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/FieldsClassificationTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/FieldsClassificationTest.java
@@ -29,7 +29,6 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import android.autofillservice.cts.Helper.FieldClassificationResult;
-import android.autofillservice.cts.common.SettingsStateChangerRule;
 import android.os.Bundle;
 import android.platform.test.annotations.AppModeFull;
 import android.service.autofill.FillEventHistory.Event;
@@ -38,6 +37,8 @@
 import android.view.autofill.AutofillManager;
 import android.widget.EditText;
 
+import com.android.compatibility.common.util.SettingsStateChangerRule;
+
 import org.junit.ClassRule;
 import org.junit.Test;
 
diff --git a/tests/autofillservice/src/android/autofillservice/cts/GridActivity.java b/tests/autofillservice/src/android/autofillservice/cts/GridActivity.java
index e1379c3..ac60ebc 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/GridActivity.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/GridActivity.java
@@ -22,6 +22,8 @@
 import android.widget.EditText;
 import android.widget.GridLayout;
 
+import com.android.compatibility.common.util.RetryableException;
+
 import java.util.ArrayList;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.LinkedBlockingQueue;
diff --git a/tests/autofillservice/src/android/autofillservice/cts/Helper.java b/tests/autofillservice/src/android/autofillservice/cts/Helper.java
index 69da062..646ea92 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/Helper.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/Helper.java
@@ -17,7 +17,6 @@
 package android.autofillservice.cts;
 
 import static android.autofillservice.cts.UiBot.PORTRAIT;
-import static android.autofillservice.cts.common.ShellHelper.runShellCommand;
 import static android.provider.Settings.Secure.AUTOFILL_SERVICE;
 import static android.provider.Settings.Secure.USER_SETUP_COMPLETE;
 import static android.service.autofill.FillEventHistory.Event.TYPE_AUTHENTICATION_SELECTED;
@@ -26,6 +25,8 @@
 import static android.service.autofill.FillEventHistory.Event.TYPE_DATASET_SELECTED;
 import static android.service.autofill.FillEventHistory.Event.TYPE_SAVE_SHOWN;
 
+import static com.android.compatibility.common.util.ShellUtils.runShellCommand;
+
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.Truth.assertWithMessage;
 
@@ -33,9 +34,6 @@
 import android.app.assist.AssistStructure;
 import android.app.assist.AssistStructure.ViewNode;
 import android.app.assist.AssistStructure.WindowNode;
-import android.autofillservice.cts.common.OneTimeSettingsListener;
-import android.autofillservice.cts.common.SettingsHelper;
-import android.autofillservice.cts.common.ShellHelper;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.PackageManager;
@@ -64,6 +62,11 @@
 import androidx.annotation.Nullable;
 
 import com.android.compatibility.common.util.BitmapUtils;
+import com.android.compatibility.common.util.OneTimeSettingsListener;
+import com.android.compatibility.common.util.SettingsUtils;
+import com.android.compatibility.common.util.ShellUtils;
+import com.android.compatibility.common.util.TestNameUtils;
+import com.android.compatibility.common.util.Timeout;
 
 import java.io.File;
 import java.io.IOException;
@@ -223,7 +226,7 @@
      * Sets whether the user completed the initial setup.
      */
     public static void setUserComplete(Context context, boolean complete) {
-        SettingsHelper.syncSet(context, USER_SETUP_COMPLETE, complete ? "1" : null);
+        SettingsUtils.syncSet(context, USER_SETUP_COMPLETE, complete ? "1" : null);
     }
 
     private static void dump(@NonNull StringBuilder builder, @NonNull ViewNode node,
@@ -899,7 +902,7 @@
             @NonNull String serviceName) {
         if (isAutofillServiceEnabled(serviceName)) return;
 
-        SettingsHelper.syncSet(context, AUTOFILL_SERVICE, serviceName);
+        SettingsUtils.syncSet(context, AUTOFILL_SERVICE, serviceName);
     }
 
     /**
@@ -907,13 +910,13 @@
      * the setting is deleted.
      */
     public static void disableAutofillService(@NonNull Context context) {
-        final String currentService = SettingsHelper.get(AUTOFILL_SERVICE);
+        final String currentService = SettingsUtils.get(AUTOFILL_SERVICE);
         if (currentService == null) {
             Log.v(TAG, "disableAutofillService(): already disabled");
             return;
         }
         Log.v(TAG, "Disabling " + currentService);
-        SettingsHelper.syncDelete(context, AUTOFILL_SERVICE);
+        SettingsUtils.syncDelete(context, AUTOFILL_SERVICE);
     }
 
     /**
@@ -928,14 +931,14 @@
      * Gets then name of the autofill service for the default user.
      */
     public static String getAutofillServiceName() {
-        return SettingsHelper.get(AUTOFILL_SERVICE);
+        return SettingsUtils.get(AUTOFILL_SERVICE);
     }
 
     /**
      * Asserts whether the given service is enabled as the autofill service for the default user.
      */
     public static void assertAutofillServiceStatus(@NonNull String serviceName, boolean enabled) {
-        final String actual = SettingsHelper.get(AUTOFILL_SERVICE);
+        final String actual = SettingsUtils.get(AUTOFILL_SERVICE);
         final String expected = enabled ? serviceName : null;
         assertWithMessage("Invalid value for secure setting %s", AUTOFILL_SERVICE)
                 .that(actual).isEqualTo(expected);
@@ -1339,7 +1342,7 @@
         final File dir = getLocalDirectory();
         if (dir == null) return null;
 
-        final String prefix = JUnitHelper.getCurrentTestName().replaceAll("\\.|\\(|\\/", "_")
+        final String prefix = TestNameUtils.getCurrentTestName().replaceAll("\\.|\\(|\\/", "_")
                 .replaceAll("\\)", "");
         final String filename = prefix + "-" + name;
 
@@ -1383,7 +1386,7 @@
      * <p>Should call {@link #disallowOverlays()} afterwards.
      */
     public static void allowOverlays() {
-        ShellHelper.setOverlayPermissions(MY_PACKAGE, true);
+        ShellUtils.setOverlayPermissions(MY_PACKAGE, true);
     }
 
     /**
@@ -1392,7 +1395,7 @@
      * <p>Should call {@link #disallowOverlays()} afterwards.
      */
     public static void disallowOverlays() {
-        ShellHelper.setOverlayPermissions(MY_PACKAGE, false);
+        ShellUtils.setOverlayPermissions(MY_PACKAGE, false);
     }
 
     private Helper() {
diff --git a/tests/autofillservice/src/android/autofillservice/cts/InstrumentedAutoFillService.java b/tests/autofillservice/src/android/autofillservice/cts/InstrumentedAutoFillService.java
index 4062817..c642885 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/InstrumentedAutoFillService.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/InstrumentedAutoFillService.java
@@ -50,6 +50,10 @@
 
 import androidx.annotation.Nullable;
 
+import com.android.compatibility.common.util.RetryableException;
+import com.android.compatibility.common.util.TestNameUtils;
+import com.android.compatibility.common.util.Timeout;
+
 import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.BlockingQueue;
@@ -187,7 +191,7 @@
             CancellationSignal cancellationSignal, FillCallback callback) {
 
         final ComponentName component = getLastActivityComponent(request.getFillContexts());
-        if (!JUnitHelper.isRunningTest()) {
+        if (!TestNameUtils.isRunningTest()) {
             Log.e(TAG, "onFillRequest(" + component + ") called after tests finished");
             return;
         }
@@ -214,7 +218,7 @@
     private void handleSaveRequest(android.service.autofill.SaveRequest request,
             SaveCallback callback) {
         final ComponentName component = getLastActivityComponent(request.getFillContexts());
-        if (!JUnitHelper.isRunningTest()) {
+        if (!TestNameUtils.isRunningTest()) {
             Log.e(TAG, "onSaveRequest(" + component + ") called after tests finished");
             return;
         }
diff --git a/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java
index 5edfb53..e39cdf9 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java
@@ -43,8 +43,6 @@
 import static android.autofillservice.cts.LoginActivity.BACKDOOR_USERNAME;
 import static android.autofillservice.cts.LoginActivity.ID_USERNAME_CONTAINER;
 import static android.autofillservice.cts.LoginActivity.getWelcomeMessage;
-import static android.autofillservice.cts.common.ShellHelper.sendKeyEvent;
-import static android.autofillservice.cts.common.ShellHelper.tap;
 import static android.content.Context.CLIPBOARD_SERVICE;
 import static android.service.autofill.FillRequest.FLAG_MANUAL_REQUEST;
 import static android.service.autofill.SaveInfo.SAVE_DATA_TYPE_ADDRESS;
@@ -58,6 +56,9 @@
 import static android.view.View.IMPORTANT_FOR_AUTOFILL_NO;
 import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
 
+import static com.android.compatibility.common.util.ShellUtils.sendKeyEvent;
+import static com.android.compatibility.common.util.ShellUtils.tap;
+
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.Truth.assertWithMessage;
 
@@ -92,6 +93,8 @@
 import android.view.autofill.AutofillManager;
 import android.widget.RemoteViews;
 
+import com.android.compatibility.common.util.RetryableException;
+
 import org.junit.Ignore;
 import org.junit.Test;
 
diff --git a/tests/autofillservice/src/android/autofillservice/cts/MultiWindowEmptyActivity.java b/tests/autofillservice/src/android/autofillservice/cts/MultiWindowEmptyActivity.java
index 5aad499..0fd0c83 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/MultiWindowEmptyActivity.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/MultiWindowEmptyActivity.java
@@ -15,6 +15,8 @@
  */
 package android.autofillservice.cts;
 
+import com.android.compatibility.common.util.RetryableException;
+
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
diff --git a/tests/autofillservice/src/android/autofillservice/cts/MultiWindowLoginActivity.java b/tests/autofillservice/src/android/autofillservice/cts/MultiWindowLoginActivity.java
index 02460050..9512591 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/MultiWindowLoginActivity.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/MultiWindowLoginActivity.java
@@ -15,6 +15,8 @@
  */
 package android.autofillservice.cts;
 
+import com.android.compatibility.common.util.RetryableException;
+
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
diff --git a/tests/autofillservice/src/android/autofillservice/cts/MultiWindowLoginActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/MultiWindowLoginActivityTest.java
index eb9d288..d8b263a 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/MultiWindowLoginActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/MultiWindowLoginActivityTest.java
@@ -18,8 +18,9 @@
 import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
 import static android.autofillservice.cts.Helper.ID_PASSWORD;
 import static android.autofillservice.cts.Helper.ID_USERNAME;
-import static android.autofillservice.cts.common.ShellHelper.runShellCommand;
-import static android.autofillservice.cts.common.ShellHelper.tap;
+
+import static com.android.compatibility.common.util.ShellUtils.runShellCommand;
+import static com.android.compatibility.common.util.ShellUtils.tap;
 
 import static com.google.common.truth.Truth.assertThat;
 
diff --git a/tests/autofillservice/src/android/autofillservice/cts/MultipleTimesTextWatcher.java b/tests/autofillservice/src/android/autofillservice/cts/MultipleTimesTextWatcher.java
index 1b93f00..a841fef 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/MultipleTimesTextWatcher.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/MultipleTimesTextWatcher.java
@@ -25,6 +25,8 @@
 import android.util.Log;
 import android.widget.EditText;
 
+import com.android.compatibility.common.util.RetryableException;
+
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
diff --git a/tests/autofillservice/src/android/autofillservice/cts/MyAutofillCallback.java b/tests/autofillservice/src/android/autofillservice/cts/MyAutofillCallback.java
index ff3eef9..65ce0e3 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/MyAutofillCallback.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/MyAutofillCallback.java
@@ -28,6 +28,9 @@
 import android.view.View;
 import android.view.autofill.AutofillManager.AutofillCallback;
 
+import com.android.compatibility.common.util.RetryableException;
+import com.android.compatibility.common.util.Timeout;
+
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.TimeUnit;
diff --git a/tests/autofillservice/src/android/autofillservice/cts/MyDrawable.java b/tests/autofillservice/src/android/autofillservice/cts/MyDrawable.java
index 940e593..46965dd 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/MyDrawable.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/MyDrawable.java
@@ -21,6 +21,8 @@
 import android.graphics.drawable.Drawable;
 import android.util.Log;
 
+import com.android.compatibility.common.util.RetryableException;
+
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
diff --git a/tests/autofillservice/src/android/autofillservice/cts/MyWebView.java b/tests/autofillservice/src/android/autofillservice/cts/MyWebView.java
index 5ccfb4a..35317f9 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/MyWebView.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/MyWebView.java
@@ -26,6 +26,8 @@
 import android.webkit.JavascriptInterface;
 import android.webkit.WebView;
 
+import com.android.compatibility.common.util.RetryableException;
+
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
diff --git a/tests/autofillservice/src/android/autofillservice/cts/SessionLifecycleTest.java b/tests/autofillservice/src/android/autofillservice/cts/SessionLifecycleTest.java
index 2e3d308..b9bd41a 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/SessionLifecycleTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/SessionLifecycleTest.java
@@ -27,10 +27,11 @@
 import static android.autofillservice.cts.OutOfProcessLoginActivity.getStoppedMarker;
 import static android.autofillservice.cts.UiBot.LANDSCAPE;
 import static android.autofillservice.cts.UiBot.PORTRAIT;
-import static android.autofillservice.cts.common.ShellHelper.runShellCommand;
 import static android.service.autofill.SaveInfo.SAVE_DATA_TYPE_PASSWORD;
 import static android.service.autofill.SaveInfo.SAVE_DATA_TYPE_USERNAME;
 
+import static com.android.compatibility.common.util.ShellUtils.runShellCommand;
+
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.Truth.assertWithMessage;
 
@@ -38,9 +39,9 @@
 import static org.junit.Assume.assumeTrue;
 
 import android.app.ActivityManager;
-import android.content.Context;
 import android.app.PendingIntent;
 import android.app.assist.AssistStructure;
+import android.content.Context;
 import android.content.Intent;
 import android.content.IntentSender;
 import android.os.Bundle;
@@ -50,6 +51,8 @@
 import android.util.Log;
 import android.view.autofill.AutofillValue;
 
+import com.android.compatibility.common.util.Timeout;
+
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
diff --git a/tests/autofillservice/src/android/autofillservice/cts/SettingsIntentTest.java b/tests/autofillservice/src/android/autofillservice/cts/SettingsIntentTest.java
index 9e471e1..1ab9069 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/SettingsIntentTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/SettingsIntentTest.java
@@ -15,7 +15,7 @@
  */
 package android.autofillservice.cts;
 
-import static android.autofillservice.cts.common.ShellHelper.runShellCommand;
+import static com.android.compatibility.common.util.ShellUtils.runShellCommand;
 
 import static com.google.common.truth.Truth.assertWithMessage;
 
diff --git a/tests/autofillservice/src/android/autofillservice/cts/Timeouts.java b/tests/autofillservice/src/android/autofillservice/cts/Timeouts.java
index 56788e7..b65b91b 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/Timeouts.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/Timeouts.java
@@ -16,6 +16,8 @@
 
 package android.autofillservice.cts;
 
+import com.android.compatibility.common.util.Timeout;
+
 /**
  * Timeouts for common tasks.
  */
diff --git a/tests/autofillservice/src/android/autofillservice/cts/UiBot.java b/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
index 85e8983..e0f4523 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
@@ -22,7 +22,6 @@
 import static android.autofillservice.cts.Timeouts.UI_DATASET_PICKER_TIMEOUT;
 import static android.autofillservice.cts.Timeouts.UI_SCREEN_ORIENTATION_TIMEOUT;
 import static android.autofillservice.cts.Timeouts.UI_TIMEOUT;
-import static android.autofillservice.cts.common.ShellHelper.runShellCommand;
 import static android.service.autofill.SaveInfo.SAVE_DATA_TYPE_ADDRESS;
 import static android.service.autofill.SaveInfo.SAVE_DATA_TYPE_CREDIT_CARD;
 import static android.service.autofill.SaveInfo.SAVE_DATA_TYPE_EMAIL_ADDRESS;
@@ -30,6 +29,8 @@
 import static android.service.autofill.SaveInfo.SAVE_DATA_TYPE_PASSWORD;
 import static android.service.autofill.SaveInfo.SAVE_DATA_TYPE_USERNAME;
 
+import static com.android.compatibility.common.util.ShellUtils.runShellCommand;
+
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.Truth.assertWithMessage;
 
@@ -57,6 +58,9 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
+import com.android.compatibility.common.util.RetryableException;
+import com.android.compatibility.common.util.Timeout;
+
 import java.io.File;
 import java.io.FileInputStream;
 import java.util.ArrayList;
diff --git a/tests/autofillservice/src/android/autofillservice/cts/UserDataTest.java b/tests/autofillservice/src/android/autofillservice/cts/UserDataTest.java
index 95845f7..e0c2894 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/UserDataTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/UserDataTest.java
@@ -26,12 +26,13 @@
 
 import static org.testng.Assert.assertThrows;
 
-import android.autofillservice.cts.common.SettingsStateChangerRule;
 import android.content.Context;
 import android.platform.test.annotations.AppModeFull;
 import android.service.autofill.UserData;
 import android.support.test.InstrumentationRegistry;
 
+import com.android.compatibility.common.util.SettingsStateChangerRule;
+
 import com.google.common.base.Strings;
 
 import org.junit.Before;
diff --git a/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerActivityCompatModeTest.java b/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerActivityCompatModeTest.java
index 5029e9e..72688f6 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerActivityCompatModeTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerActivityCompatModeTest.java
@@ -26,22 +26,24 @@
 import static android.autofillservice.cts.VirtualContainerActivity.INITIAL_URL_BAR_VALUE;
 import static android.autofillservice.cts.VirtualContainerView.ID_URL_BAR;
 import static android.autofillservice.cts.VirtualContainerView.ID_URL_BAR2;
-import static android.autofillservice.cts.common.SettingsHelper.NAMESPACE_GLOBAL;
 import static android.provider.Settings.Global.AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES;
 import static android.service.autofill.SaveInfo.SAVE_DATA_TYPE_PASSWORD;
 
+import static com.android.compatibility.common.util.SettingsUtils.NAMESPACE_GLOBAL;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import android.app.assist.AssistStructure.ViewNode;
 import android.autofillservice.cts.CannedFillResponse.CannedDataset;
 import android.autofillservice.cts.InstrumentedAutoFillService.FillRequest;
 import android.autofillservice.cts.InstrumentedAutoFillService.SaveRequest;
-import android.autofillservice.cts.common.SettingsHelper;
-import android.autofillservice.cts.common.SettingsStateChangerRule;
 import android.os.SystemClock;
 import android.platform.test.annotations.AppModeFull;
 import android.service.autofill.SaveInfo;
 
+import com.android.compatibility.common.util.SettingsStateChangerRule;
+import com.android.compatibility.common.util.SettingsUtils;
+
 import org.junit.After;
 import org.junit.ClassRule;
 import org.junit.Test;
@@ -96,7 +98,7 @@
 
     @Test
     public void testMultipleUrlBars_firstDoesNotExist() throws Exception {
-        SettingsHelper.syncSet(sContext, NAMESPACE_GLOBAL, AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES,
+        SettingsUtils.syncSet(sContext, NAMESPACE_GLOBAL, AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES,
                 SERVICE_PACKAGE + "[first_am_i,my_url_bar]");
 
         // Set service.
@@ -121,7 +123,7 @@
     @Test
     @AppModeFull // testMultipleUrlBars_firstDoesNotExist() is enough to test ephemeral apps support
     public void testMultipleUrlBars_bothExist() throws Exception {
-        SettingsHelper.syncSet(sContext, NAMESPACE_GLOBAL, AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES,
+        SettingsUtils.syncSet(sContext, NAMESPACE_GLOBAL, AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES,
                 SERVICE_PACKAGE + "[my_url_bar,my_url_bar2]");
 
         // Set service.
diff --git a/tests/autofillservice/src/android/autofillservice/cts/WebViewActivity.java b/tests/autofillservice/src/android/autofillservice/cts/WebViewActivity.java
index f738959..430a533 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/WebViewActivity.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/WebViewActivity.java
@@ -31,6 +31,8 @@
 import android.widget.EditText;
 import android.widget.LinearLayout;
 
+import com.android.compatibility.common.util.RetryableException;
+
 import java.io.IOException;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
diff --git a/tests/autofillservice/src/android/autofillservice/cts/WebViewMultiScreenLoginActivity.java b/tests/autofillservice/src/android/autofillservice/cts/WebViewMultiScreenLoginActivity.java
index 2680f14..cc4640c 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/WebViewMultiScreenLoginActivity.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/WebViewMultiScreenLoginActivity.java
@@ -27,6 +27,8 @@
 import android.webkit.WebView;
 import android.webkit.WebViewClient;
 
+import com.android.compatibility.common.util.RetryableException;
+
 import java.io.IOException;
 import java.util.HashMap;
 import java.util.Map;
diff --git a/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedAutofillAutoActivityLaunchTestCase.java b/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedAutofillAutoActivityLaunchTestCase.java
index c7e55fa..83a938d 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedAutofillAutoActivityLaunchTestCase.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedAutofillAutoActivityLaunchTestCase.java
@@ -17,30 +17,21 @@
 
 import static android.autofillservice.cts.Helper.allowOverlays;
 import static android.autofillservice.cts.Helper.disallowOverlays;
-import static android.provider.Settings.Global.AUTOFILL_SMART_SUGGESTION_EMULATION_FLAGS;
 
 import android.autofillservice.cts.AbstractAutoFillActivity;
 import android.autofillservice.cts.AutoFillServiceTestCase;
 import android.autofillservice.cts.augmented.CtsAugmentedAutofillService.AugmentedReplier;
-import android.autofillservice.cts.common.SettingsHelper;
-import android.autofillservice.cts.common.SettingsStateChangerRule;
 import android.view.autofill.AutofillManager;
 
 import org.junit.After;
 import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.BeforeClass;
-import org.junit.ClassRule;
 
 // Must be public because of the @ClassRule
 public abstract class AugmentedAutofillAutoActivityLaunchTestCase
         <A extends AbstractAutoFillActivity> extends AutoFillServiceTestCase.AutoActivityLaunch<A> {
 
-    @ClassRule
-    public static final SettingsStateChangerRule sFeatureEnabler = new SettingsStateChangerRule(
-            sContext, SettingsHelper.NAMESPACE_GLOBAL, AUTOFILL_SMART_SUGGESTION_EMULATION_FLAGS,
-            Integer.toString(AutofillManager.FLAG_SMART_SUGGESTION_SYSTEM));
-
     protected static AugmentedReplier sAugmentedReplier;
     protected AugmentedUiBot mAugmentedUiBot;
 
@@ -69,6 +60,11 @@
         AugmentedHelper.resetAugmentedService();
     }
 
+    @Override
+    protected int getSmartSuggestionMode() {
+        return AutofillManager.FLAG_SMART_SUGGESTION_SYSTEM;
+    }
+
     protected void enableAugmentedService() {
         AugmentedHelper.setAugmentedService(CtsAugmentedAutofillService.SERVICE_NAME);
     }
diff --git a/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedHelper.java b/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedHelper.java
index 626b835..4d263c1 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedHelper.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedHelper.java
@@ -16,9 +16,10 @@
 
 package android.autofillservice.cts.augmented;
 
-import static android.autofillservice.cts.common.ShellHelper.runShellCommand;
 import static android.view.autofill.AutofillManager.MAX_TEMP_AUGMENTED_SERVICE_DURATION_MS;
 
+import static com.android.compatibility.common.util.ShellUtils.runShellCommand;
+
 import static com.google.common.truth.Truth.assertWithMessage;
 
 import android.app.Activity;
diff --git a/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedLoginActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedLoginActivityTest.java
index cbf2671..a4d189f 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedLoginActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedLoginActivityTest.java
@@ -181,7 +181,7 @@
     }
 
     /*
-     * TODO(b/119638958) - add moarrrr tests:
+     * TODO(b/123542344) - add moarrrr tests:
      *
      * - Augmented service returned null
      * - Focus back and forth between username and passwod
diff --git a/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedTimeouts.java b/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedTimeouts.java
index 730b0d4..7bfdfc8 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedTimeouts.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedTimeouts.java
@@ -16,7 +16,7 @@
 
 package android.autofillservice.cts.augmented;
 
-import android.autofillservice.cts.Timeout;
+import com.android.compatibility.common.util.Timeout;
 
 /**
  * Timeouts for common tasks.
diff --git a/tests/autofillservice/src/android/autofillservice/cts/augmented/CtsAugmentedAutofillService.java b/tests/autofillservice/src/android/autofillservice/cts/augmented/CtsAugmentedAutofillService.java
index 8fb17a2..ba32f7e 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/augmented/CtsAugmentedAutofillService.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/augmented/CtsAugmentedAutofillService.java
@@ -23,8 +23,6 @@
 import static android.autofillservice.cts.augmented.CannedAugmentedFillResponse.AugmentedResponseType.TIMEOUT;
 
 import android.autofillservice.cts.Helper;
-import android.autofillservice.cts.JUnitHelper;
-import android.autofillservice.cts.RetryableException;
 import android.content.ComponentName;
 import android.content.Context;
 import android.os.CancellationSignal;
@@ -40,6 +38,9 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
+import com.android.compatibility.common.util.RetryableException;
+import com.android.compatibility.common.util.TestNameUtils;
+
 import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.BlockingQueue;
@@ -81,7 +82,7 @@
 
         final ComponentName component = request.getActivityComponent();
 
-        if (!JUnitHelper.isRunningTest()) {
+        if (!TestNameUtils.isRunningTest()) {
             Log.e(TAG, "onFillRequest(" + component + ") called after tests finished");
             return;
         }
diff --git a/tests/autofillservice/src/android/autofillservice/cts/common/README.txt b/tests/autofillservice/src/android/autofillservice/cts/common/README.txt
deleted file mode 100644
index 97d3b48..0000000
--- a/tests/autofillservice/src/android/autofillservice/cts/common/README.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-This package contains utilities that are not tied to Autofill and might eventually move to
-a common CTS package.
\ No newline at end of file
diff --git a/tests/autofillservice/src/android/autofillservice/cts/common/SettingsHelper.java b/tests/autofillservice/src/android/autofillservice/cts/common/SettingsHelper.java
deleted file mode 100644
index 59167f4..0000000
--- a/tests/autofillservice/src/android/autofillservice/cts/common/SettingsHelper.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2017 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.autofillservice.cts.common;
-
-import static android.autofillservice.cts.common.ShellHelper.runShellCommand;
-
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import android.content.Context;
-import android.provider.Settings;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-/**
- * Provides utilities to interact with the device's {@link Settings}.
- */
-public final class SettingsHelper {
-
-    public static final String NAMESPACE_SECURE = "secure";
-    public static final String NAMESPACE_GLOBAL = "global";
-
-    /**
-     * Uses a Shell command to set the given preference.
-     */
-    public static void set(@NonNull String namespace, @NonNull String key, @Nullable String value) {
-        if (value == null) {
-            delete(namespace, key);
-            return;
-        }
-        runShellCommand("settings put %s %s %s default", namespace, key, value);
-    }
-
-    public static void set(@NonNull String key, @Nullable String value) {
-        set(NAMESPACE_SECURE, key, value);
-    }
-
-    /**
-     * Uses a Shell command to set the given preference, and verifies it was correctly set.
-     */
-    public static void syncSet(@NonNull Context context, @NonNull String namespace,
-            @NonNull String key, @Nullable String value) {
-        if (value == null) {
-            syncDelete(context, namespace, key);
-            return;
-        }
-
-        final String currentValue = get(namespace, key);
-        if (value.equals(currentValue)) {
-            // Already set, ignore
-            return;
-        }
-
-        final OneTimeSettingsListener observer =
-                new OneTimeSettingsListener(context, namespace, key);
-        set(namespace, key, value);
-        observer.assertCalled();
-
-        final String newValue = get(namespace, key);
-        assertWithMessage("invalid value for '%s' settings", key).that(newValue).isEqualTo(value);
-    }
-
-    public static void syncSet(@NonNull Context context, @NonNull String key,
-            @Nullable String value) {
-        syncSet(context, NAMESPACE_SECURE, key, value);
-    }
-
-    /**
-     * Uses a Shell command to delete the given preference.
-     */
-    public static void delete(@NonNull String namespace, @NonNull String key) {
-        runShellCommand("settings delete %s %s", namespace, key);
-    }
-
-    public static void delete(@NonNull String key) {
-        delete(NAMESPACE_SECURE, key);
-    }
-
-    /**
-     * Uses a Shell command to delete the given preference, and verifies it was correctly deleted.
-     */
-    public static void syncDelete(@NonNull Context context, @NonNull String namespace,
-            @NonNull String key) {
-
-        final String currentValue = get(namespace, key);
-        if (currentValue == null) {
-            // Already set, ignore
-            return;
-        }
-
-        final OneTimeSettingsListener observer = new OneTimeSettingsListener(context, namespace,
-                key);
-        delete(namespace, key);
-        observer.assertCalled();
-
-        final String newValue = get(namespace, key);
-        assertWithMessage("invalid value for '%s' settings", key).that(newValue).isNull();
-    }
-
-    public static void syncDelete(@NonNull Context context, @NonNull String key) {
-        syncDelete(context, NAMESPACE_SECURE, key);
-    }
-
-    /**
-     * Gets the value of a given preference using Shell command.
-     */
-    @Nullable
-    public static String get(@NonNull String namespace, @NonNull String key) {
-        final String value = runShellCommand("settings get %s %s", namespace, key);
-        if (value == null || value.equals("null")) {
-            return null;
-        } else {
-            return value;
-        }
-    }
-
-    @NonNull
-    public static String get(@NonNull String key) {
-        return get(NAMESPACE_SECURE, key);
-    }
-
-    private SettingsHelper() {
-        throw new UnsupportedOperationException("contain static methods only");
-    }
-}
diff --git a/tests/backup/AndroidTest.xml b/tests/backup/AndroidTest.xml
index f9bd57d..635bfdc 100644
--- a/tests/backup/AndroidTest.xml
+++ b/tests/backup/AndroidTest.xml
@@ -19,6 +19,7 @@
     <option name="config-descriptor:metadata" key="component" value="backup" />
     <!-- Backup of instant apps is not supported. -->
     <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
         <option name="test-file-name" value="CtsFullBackupApp.apk" />
diff --git a/tests/camera/Android.mk b/tests/camera/Android.mk
index ebbd555..32b5932 100644
--- a/tests/camera/Android.mk
+++ b/tests/camera/Android.mk
@@ -82,12 +82,6 @@
 LOCAL_JNI_SHARED_LIBRARIES := \
 	libctscamera2_jni \
 	libnativehelper_compat_libc++ \
-	libdynamic_depth \
-	libimage_io \
-	libxml2 \
-	libandroidicu \
-	libbase \
-	libc++ \
 
 LOCAL_NDK_STL_VARIANT := c++_shared
 
diff --git a/tests/camera/AndroidTest.xml b/tests/camera/AndroidTest.xml
index 83cdd03..94f7ca3 100644
--- a/tests/camera/AndroidTest.xml
+++ b/tests/camera/AndroidTest.xml
@@ -17,6 +17,7 @@
     <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="camera" />
     <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
         <option name="test-file-name" value="CtsCameraTestCases.apk" />
@@ -24,7 +25,7 @@
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="android.camera.cts" />
         <option name="runtime-hint" value="12m7s" />
-        <!-- test-timeout unit is ms, value = 20 min -->
-        <option name="test-timeout" value="1200000" />
+        <!-- test-timeout unit is ms, value = 33 min -->
+        <option name="test-timeout" value="2000000" />
     </test>
 </configuration>
diff --git a/tests/camera/libctscamera2jni/Android.mk b/tests/camera/libctscamera2jni/Android.mk
index e9c301e..798674b 100644
--- a/tests/camera/libctscamera2jni/Android.mk
+++ b/tests/camera/libctscamera2jni/Android.mk
@@ -35,15 +35,18 @@
 # Flags to avoid warnings from DNG SDK
 LOCAL_CFLAGS += -Wall -Werror -Wno-unused-parameter
 LOCAL_CFLAGS += -Wno-unused-value -Wno-unused-variable
+# Flags related to dynamic depth
+LOCAL_CFLAGS += -Wno-ignored-qualifiers -DSTATIC_LIBXML=1
 
 LOCAL_STATIC_LIBRARIES := libdng_sdk_validate libjpeg_static_ndk
+# Dynamic depth libraries
+LOCAL_STATIC_LIBRARIES += libdynamic_depth_ndk libimage_io_ndk libbase_ndk libxml2_ndk
 LOCAL_SHARED_LIBRARIES := libandroid \
     libnativehelper_compat_libc++ \
     liblog \
     libcamera2ndk \
     libmediandk \
     libz \
-    libdl \
 
 # NDK build, shared C++ runtime
 LOCAL_SDK_VERSION := current
diff --git a/tests/camera/libctscamera2jni/dynamic-depth-validate-jni.cpp b/tests/camera/libctscamera2jni/dynamic-depth-validate-jni.cpp
index a1d4b83..fbc63ef 100644
--- a/tests/camera/libctscamera2jni/dynamic-depth-validate-jni.cpp
+++ b/tests/camera/libctscamera2jni/dynamic-depth-validate-jni.cpp
@@ -17,11 +17,9 @@
 #define LOG_TAG "DYNAMIC-DEPTH-JNI"
 #include <jni.h>
 #include <log/log.h>
-#include <dlfcn.h>
+#include <dynamic_depth/depth_jpeg.h>
 
-typedef int32_t (*validate_dynamic_depth_buffer) (const char *, size_t);
-static const char *kDynamicDepthLibraryName = "libdynamic_depth.so";
-static const char *kDynamicDepthValidateFunction = "ValidateAndroidDynamicDepthBuffer";
+using namespace dynamic_depth;
 
 extern "C" jboolean
 Java_android_hardware_camera2_cts_ImageReaderTest_validateDynamicDepthNative(
@@ -34,23 +32,8 @@
         return JNI_FALSE;
     }
 
-    void* depthLibHandle = dlopen(kDynamicDepthLibraryName, RTLD_NOW | RTLD_LOCAL);
-    if (depthLibHandle == nullptr) {
-        ALOGE("Failed to load dynamic depth library!");
-        return JNI_FALSE;
-    }
-
-    validate_dynamic_depth_buffer validate = reinterpret_cast<validate_dynamic_depth_buffer> (
-            dlsym(depthLibHandle, kDynamicDepthValidateFunction));
-    if (validate == nullptr) {
-        ALOGE("Failed to link to dynamic depth validate function!");
-        dlclose(depthLibHandle);
-        return JNI_FALSE;
-    }
-
-    auto ret = (validate(reinterpret_cast<const char *> (buffer), bufferLength) == 0) ?
-            JNI_TRUE : JNI_FALSE;
-    dlclose(depthLibHandle);
+    auto ret = (ValidateAndroidDynamicDepthBuffer(reinterpret_cast<const char *> (buffer),
+                bufferLength) == 0) ? JNI_TRUE : JNI_FALSE;
 
     return ret;
 }
diff --git a/tests/camera/src/android/hardware/camera2/cts/ImageReaderTest.java b/tests/camera/src/android/hardware/camera2/cts/ImageReaderTest.java
index 3ed4fdb..e275aa4 100644
--- a/tests/camera/src/android/hardware/camera2/cts/ImageReaderTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/ImageReaderTest.java
@@ -367,6 +367,32 @@
     }
 
     /**
+     * If the camera device advertises the SECURE_IAMGE_DATA capability, test
+     * ImageFormat.PRIVATE + PROTECTED usage capture by using ImageReader with the
+     * ImageReader factory method that has usage flag argument, and uses a custom usage flag.
+     */
+    public void testImageReaderPrivateWithProtectedUsageFlag() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                Log.v(TAG, "Private format and protected usage testing for camera " + id);
+                if (!mAllStaticInfo.get(id).isCapabilitySupported(
+                        CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_SECURE_IMAGE_DATA)) {
+                    Log.i(TAG, "Camera " + id +
+                            " does not support secure image data capability, skipping");
+
+                    continue;
+                }
+                openDevice(id);
+                bufferFormatTestByCamera(ImageFormat.PRIVATE, /*setUsageFlag*/ true,
+                        HardwareBuffer.USAGE_PROTECTED_CONTENT, /*repeating*/ true,
+                        /*checkSession*/ true, /*validateImageData*/ false);
+            } finally {
+                closeDevice(id);
+            }
+        }
+    }
+
+    /**
      * Test two image stream (YUV420_888 and RAW_SENSOR) capture by using ImageReader with the
      * ImageReader factory method that has usage flag argument.
      *
@@ -930,11 +956,23 @@
     }
 
     private void bufferFormatTestByCamera(int format, boolean repeating) throws Exception {
-        bufferFormatTestByCamera(format, repeating, /*checkSession*/ false);
+        bufferFormatTestByCamera(format, /*setUsageFlag*/ false,
+                HardwareBuffer.USAGE_CPU_READ_OFTEN, repeating,
+                /*checkSession*/ false, /*validateImageData*/ true);
     }
 
     private void bufferFormatTestByCamera(int format, boolean repeating, boolean checkSession)
             throws Exception {
+        bufferFormatTestByCamera(format, /*setUsageFlag*/ false,
+                HardwareBuffer.USAGE_CPU_READ_OFTEN,
+                repeating, checkSession, /*validateImageData*/true);
+    }
+
+    private void bufferFormatTestByCamera(int format, boolean setUsageFlag, long usageFlag,
+            // TODO: Consider having some sort of test configuration class passed to reduce the
+            //       proliferation of parameters ?
+            boolean repeating, boolean checkSession, boolean validateImageData)
+            throws Exception {
         Size[] availableSizes = mStaticInfo.getAvailableSizesForFormatChecked(format,
                 StaticMetadata.StreamDirection.Output);
 
@@ -948,7 +986,11 @@
 
                 // Create ImageReader.
                 mListener  = new SimpleImageListener();
-                createDefaultImageReader(sz, format, MAX_NUM_IMAGES, mListener);
+                if (setUsageFlag) {
+                    createDefaultImageReader(sz, format, MAX_NUM_IMAGES, usageFlag, mListener);
+                } else {
+                    createDefaultImageReader(sz, format, MAX_NUM_IMAGES, mListener);
+                }
 
                 if (checkSession) {
                     assertTrue("Camera capture session validation for format: " + format +
@@ -962,8 +1004,10 @@
 
                 int numFrameVerified = repeating ? NUM_FRAME_VERIFIED : 1;
 
-                // Validate images.
-                validateImage(sz, format, numFrameVerified, repeating);
+                if (validateImageData) {
+                    // Validate images.
+                    validateImage(sz, format, numFrameVerified, repeating);
+                }
 
                 // Validate capture result.
                 validateCaptureResult(format, sz, listener, numFrameVerified);
@@ -1191,7 +1235,6 @@
 
     /** Load dynamic depth validation jni on initialization */
     static {
-        System.loadLibrary("dynamic_depth");
         System.loadLibrary("ctscamera2_jni");
     }
     /**
diff --git a/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java b/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java
index 35507e9..1534e84 100644
--- a/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java
@@ -42,6 +42,8 @@
 import android.media.MediaFormat;
 import android.media.MediaRecorder;
 import android.os.Environment;
+import android.os.Handler;
+import android.os.HandlerThread;
 import android.os.SystemClock;
 import android.test.suitebuilder.annotation.LargeTest;
 import android.util.Log;
@@ -110,6 +112,8 @@
     private ImageReader mIntermediateReader;
     private ImageWriter mIntermediateWriter;
     private ImageWriterQueuer mQueuer;
+    private HandlerThread mIntermediateThread;
+    private Handler mIntermediateHandler;
 
     @Override
     public void setUp() throws Exception {
@@ -1027,7 +1031,12 @@
             stopRecording(/* useMediaRecorder */true, useIntermediateSurface);
             // Convert number of frames camera produced into the duration in unit of ms.
             float frameDurationMs = 1000.0f / profile.videoFrameRate;
-            float durationMs = resultListener.getTotalNumFrames() * frameDurationMs;
+            float durationMs = 0.f;
+            if (useIntermediateSurface) {
+                durationMs = mQueuer.getQueuedCount() * frameDurationMs;
+            } else {
+                durationMs = resultListener.getTotalNumFrames() * frameDurationMs;
+            }
 
             if (VERBOSE) {
                 Log.v(TAG, "video frame rate: " + profile.videoFrameRate +
@@ -1533,7 +1542,10 @@
                     ImageFormat.PRIVATE);
             mQueuer = new ImageWriterQueuer(mIntermediateWriter);
 
-            mIntermediateReader.setOnImageAvailableListener(mQueuer, mHandler);
+            mIntermediateThread = new HandlerThread(TAG);
+            mIntermediateThread.start();
+            mIntermediateHandler = new Handler(mIntermediateThread.getLooper());
+            mIntermediateReader.setOnImageAvailableListener(mQueuer, mIntermediateHandler);
         }
     }
 
@@ -1709,6 +1721,9 @@
         long stopRecordingTime = SystemClock.elapsedRealtime();
         if (useMediaRecorder) {
             stopCameraStreaming();
+            if (useIntermediateSurface) {
+                mIntermediateReader.setOnImageAvailableListener(null, null);
+            }
 
             mMediaRecorder.stop();
             // Can reuse the MediaRecorder object after reset.
@@ -1716,20 +1731,23 @@
         } else {
             // TODO: need implement MediaCodec path.
         }
+
+        if (useIntermediateSurface) {
+            mIntermediateReader.close();
+            mQueuer.close();
+            mIntermediateWriter.close();
+            mIntermediateSurface.release();
+            mIntermediateReader = null;
+            mIntermediateSurface = null;
+            mIntermediateWriter = null;
+            mIntermediateThread.quitSafely();
+            mIntermediateHandler = null;
+        }
+
         if (mPersistentSurface == null && mRecordingSurface != null) {
             mRecordingSurface.release();
             mRecordingSurface = null;
         }
-        if (useIntermediateSurface) {
-            mIntermediateSurface.release();
-            mIntermediateReader.close();
-            mIntermediateWriter.close();
-            mQueuer.close();
-            mIntermediateSurface = null;
-            mIntermediateReader = null;
-            mIntermediateWriter = null;
-            mQueuer = null;
-        }
         return (int) (stopRecordingTime - mRecordingStartTime);
     }
 
@@ -1808,7 +1826,9 @@
             // TODO: Don't skip this one for video snapshot on LEGACY
             assertTrue(String.format(
                     "Camera %s: Video duration doesn't match: recorded %fms, expected [%f,%f]ms.",
-                    mCamera.getId(), duration, expectedDurationMinMs, expectedDurationMaxMs),
+                    mCamera.getId(), duration,
+                    expectedDurationMinMs * (1.f - DURATION_MARGIN),
+                    expectedDurationMaxMs * (1.f + DURATION_MARGIN)),
                     duration > expectedDurationMinMs * (1.f - DURATION_MARGIN) &&
                             duration < expectedDurationMaxMs * (1.f + DURATION_MARGIN));
 
@@ -2050,16 +2070,31 @@
             try {
                 image = reader.acquireNextImage();
             } finally {
-                if (image != null && mWriter != null) {
-                    mWriter.queueInputImage(image);
+                synchronized (mLock) {
+                    if (image != null && mWriter != null) {
+                        mWriter.queueInputImage(image);
+                        mQueuedCount++;
+                    } else if (image != null) {
+                        image.close();
+                    }
                 }
             }
         }
 
-        public void close() {
-            mWriter = null;
+        public int getQueuedCount() {
+            synchronized (mLock) {
+                return mQueuedCount;
+            }
         }
 
+        public void close() {
+            synchronized (mLock) {
+                mWriter = null;
+            }
+        }
+
+        private Object      mLock = new Object();
         private ImageWriter mWriter = null;
+        private int         mQueuedCount = 0;
     }
 }
diff --git a/tests/camera/src/android/hardware/camera2/cts/SimpleObjectsTest.java b/tests/camera/src/android/hardware/camera2/cts/SimpleObjectsTest.java
new file mode 100644
index 0000000..5c1624b
--- /dev/null
+++ b/tests/camera/src/android/hardware/camera2/cts/SimpleObjectsTest.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2019 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.hardware.camera2.cts;
+
+import org.junit.Assert;
+import org.junit.runner.RunWith;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import android.app.Activity;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.ActivityInstrumentationTestCase2;
+
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.CaptureResult;
+import android.hardware.camera2.CameraCharacteristics;
+
+/**
+ * Test CaptureRequest/Result/CameraCharacteristics.Key objects.
+ */
+@RunWith(AndroidJUnit4.class)
+@SuppressWarnings("EqualsIncompatibleType")
+public class SimpleObjectsTest {
+
+    @Test
+    public void CameraKeysTest() throws Exception {
+        String keyName = "android.testing.Key";
+        String keyName2 = "android.testing.Key2";
+
+        CaptureRequest.Key<Integer> testRequestKey =
+                new CaptureRequest.Key<>(keyName, Integer.class);
+        Assert.assertEquals("Request key name not correct",
+                testRequestKey.getName(), keyName);
+
+        CaptureResult.Key<Integer> testResultKey =
+                new CaptureResult.Key<>(keyName, Integer.class);
+        Assert.assertEquals("Result key name not correct",
+                testResultKey.getName(), keyName);
+
+        CameraCharacteristics.Key<Integer> testCharacteristicsKey =
+                new CameraCharacteristics.Key<>(keyName, Integer.class);
+        Assert.assertEquals("Characteristics key name not correct",
+                testCharacteristicsKey.getName(), keyName);
+
+        CaptureRequest.Key<Integer> testRequestKey2 =
+                new CaptureRequest.Key<>(keyName, Integer.class);
+        Assert.assertEquals("Two request keys with same name/type should be equal",
+                testRequestKey, testRequestKey2);
+        CaptureRequest.Key<Byte> testRequestKey3 =
+                new CaptureRequest.Key<>(keyName, Byte.class);
+        Assert.assertTrue("Two request keys with different types should not be equal",
+                !testRequestKey.equals(testRequestKey3));
+        CaptureRequest.Key<Integer> testRequestKey4 =
+                new CaptureRequest.Key<>(keyName2, Integer.class);
+        Assert.assertTrue("Two request keys with different names should not be equal",
+                !testRequestKey.equals(testRequestKey4));
+        CaptureRequest.Key<Byte> testRequestKey5 =
+                new CaptureRequest.Key<>(keyName2, Byte.class);
+        Assert.assertTrue("Two request keys with different types and names should not be equal",
+                !testRequestKey.equals(testRequestKey5));
+
+        CaptureResult.Key<Integer> testResultKey2 =
+                new CaptureResult.Key<>(keyName, Integer.class);
+        Assert.assertEquals("Two result keys with same name/type should be equal",
+                testResultKey, testResultKey2);
+        CaptureResult.Key<Byte> testResultKey3 =
+                new CaptureResult.Key<>(keyName, Byte.class);
+        Assert.assertTrue("Two result keys with different types should not be equal",
+                !testResultKey.equals(testResultKey3));
+        CaptureResult.Key<Integer> testResultKey4 =
+                new CaptureResult.Key<>(keyName2, Integer.class);
+        Assert.assertTrue("Two result keys with different names should not be equal",
+                !testResultKey.equals(testResultKey4));
+        CaptureResult.Key<Byte> testResultKey5 =
+                new CaptureResult.Key<>(keyName2, Byte.class);
+        Assert.assertTrue("Two result keys with different types and names should not be equal",
+                !testResultKey.equals(testResultKey5));
+
+        CameraCharacteristics.Key<Integer> testCharacteristicsKey2 =
+                new CameraCharacteristics.Key<>(keyName, Integer.class);
+        Assert.assertEquals("Two characteristics keys with same name/type should be equal",
+                testCharacteristicsKey, testCharacteristicsKey2);
+        CameraCharacteristics.Key<Byte> testCharacteristicsKey3 =
+                new CameraCharacteristics.Key<>(keyName, Byte.class);
+        Assert.assertTrue("Two characteristics keys with different types should not be equal",
+                !testCharacteristicsKey.equals(testCharacteristicsKey3));
+        CameraCharacteristics.Key<Integer> testCharacteristicsKey4 =
+                new CameraCharacteristics.Key<>(keyName2, Integer.class);
+        Assert.assertTrue("Two characteristics keys with different names should not be equal",
+                !testCharacteristicsKey.equals(testCharacteristicsKey4));
+        CameraCharacteristics.Key<Byte> testCharacteristicsKey5 =
+                new CameraCharacteristics.Key<>(keyName2, Byte.class);
+        Assert.assertTrue(
+                "Two characteristics keys with different types and names should not be equal",
+                !testCharacteristicsKey.equals(testCharacteristicsKey5));
+
+    }
+
+}
diff --git a/tests/camera/src/android/hardware/cts/CameraTest.java b/tests/camera/src/android/hardware/cts/CameraTest.java
index 25722d6..2d73b37 100644
--- a/tests/camera/src/android/hardware/cts/CameraTest.java
+++ b/tests/camera/src/android/hardware/cts/CameraTest.java
@@ -1229,14 +1229,14 @@
         Camera.Parameters parameters = mCamera.getParameters();
         SurfaceHolder surfaceHolder;
         surfaceHolder = mActivityRule.getActivity().getSurfaceView().getHolder();
-        CamcorderProfile profile = CamcorderProfile.get(cameraId,
-                CamcorderProfile.QUALITY_LOW);
+        CamcorderProfile profile = null; // Used for built-in camera
         Camera.Size videoSize = null; // Used for external camera
 
         // Set the preview size.
         if (mIsExternalCamera) {
             videoSize = setupExternalCameraRecord(parameters);
         } else {
+            profile = CamcorderProfile.get(cameraId, CamcorderProfile.QUALITY_LOW);
             setPreviewSizeByProfile(parameters, profile);
         }
 
@@ -2756,13 +2756,13 @@
         Parameters parameters = mCamera.getParameters();
 
         SurfaceHolder holder = mActivityRule.getActivity().getSurfaceView().getHolder();
-        CamcorderProfile profile = CamcorderProfile.get(cameraId,
-                CamcorderProfile.QUALITY_LOW);
+        CamcorderProfile profile = null; // for built-in camera
         Camera.Size videoSize = null; // for external camera
 
         if (mIsExternalCamera) {
             videoSize = setupExternalCameraRecord(parameters);
         } else {
+            profile = CamcorderProfile.get(cameraId, CamcorderProfile.QUALITY_LOW);
             setPreviewSizeByProfile(parameters, profile);
         }
 
diff --git a/tests/contentcaptureservice/Android.mk b/tests/contentcaptureservice/Android.mk
index e6f42ac..4352e0b 100644
--- a/tests/contentcaptureservice/Android.mk
+++ b/tests/contentcaptureservice/Android.mk
@@ -36,6 +36,6 @@
 
 LOCAL_PACKAGE_NAME := CtsContentCaptureServiceTestCases
 
-LOCAL_SDK_VERSION := system_current
+LOCAL_SDK_VERSION := test_current
 
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/contentcaptureservice/AndroidTest.xml b/tests/contentcaptureservice/AndroidTest.xml
index 782a5b1..b3c8635 100644
--- a/tests/contentcaptureservice/AndroidTest.xml
+++ b/tests/contentcaptureservice/AndroidTest.xml
@@ -16,13 +16,18 @@
 <configuration description="Config for ContentCapture CTS tests.">
   <option name="test-suite-tag" value="cts" />
   <option name="config-descriptor:metadata" key="component" value="framework" />
+  <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
+  <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
 
   <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
     <option name="cleanup-apks" value="true" />
     <option name="test-file-name" value="CtsContentCaptureServiceTestCases.apk" />
   </target_preparer>
 
-  <!--  TODO(b/119638958): add preparer for instant-apps tests  -->
+  <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+    <option name="run-command" value="cmd content_capture set bind-instant-service-allowed true" />
+    <option name="teardown-command" value="cmd content_capture set bind-instant-service-allowed false" />
+  </target_preparer>
 
   <test class="com.android.tradefed.testtype.AndroidJUnitTest">
     <option name="package" value="android.contentcaptureservice.cts" />
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/AbstractContentCaptureActivity.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/AbstractContentCaptureActivity.java
index 8e248cc..f8f8092 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/AbstractContentCaptureActivity.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/AbstractContentCaptureActivity.java
@@ -15,10 +15,13 @@
  */
 package android.contentcaptureservice.cts;
 
+import static android.contentcaptureservice.cts.common.ShellHelper.runShellCommand;
+
 import android.app.Activity;
 import android.contentcaptureservice.cts.CtsContentCaptureService.Session;
 import android.os.Bundle;
 import android.util.Log;
+import android.view.View;
 import android.view.contentcapture.ContentCaptureManager;
 
 import androidx.annotation.NonNull;
@@ -34,7 +37,7 @@
  */
 abstract class AbstractContentCaptureActivity extends Activity {
 
-    protected final String mTag = getClass().getSimpleName();
+    private final String mTag = getClass().getSimpleName();
 
     private int mRealTaskId;
 
@@ -46,41 +49,46 @@
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         mRealTaskId = getTaskId();
+        Log.d(mTag, "onCreate(): taskId=" + mRealTaskId + ", decorView=" + getDecorView());
 
-        Log.i(mTag, "onCreate(): taskId= " + mRealTaskId);
         super.onCreate(savedInstanceState);
     }
 
     @Override
     protected void onStart() {
-        Log.i(mTag, "onStart()");
+        Log.d(mTag, "onStart()");
         super.onStart();
     }
 
     @Override
     protected void onResume() {
-        Log.i(mTag, "onResume()");
+        Log.d(mTag, "onResume(): decorViewId=" + getDecorView().getAutofillId());
         super.onResume();
     }
 
     @Override
     protected void onPause() {
-        Log.i(mTag, "onPause()");
+        Log.d(mTag, "onPause()");
         super.onPause();
     }
 
     @Override
     protected void onStop() {
-        Log.i(mTag, "onStop()");
+        Log.d(mTag, "onStop()");
         super.onStop();
     }
 
     @Override
     protected void onDestroy() {
-        Log.i(mTag, "onDestroy()");
+        Log.d(mTag, "onDestroy()");
         super.onDestroy();
     }
 
+    @NonNull
+    public final View getDecorView() {
+        return getWindow().getDecorView();
+    }
+
     /**
      * Asserts the events generated when this session was launched and finished,
      * without any custom / dynamic operations in between.
@@ -143,4 +151,13 @@
             throw new RuntimeException("Interrupted", e);
         }
     }
+
+    /**
+     * Dumps the {@link ContentCaptureManager} state of the activity on logcat.
+     */
+    public void dumpIt() {
+        final String dump = runShellCommand(
+                "dumpsys activity %s --contentcapture",  getComponentName().flattenToString());
+        Log.v(mTag, "dump it: " + dump);
+    }
 }
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/AbstractContentCaptureIntegrationTest.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/AbstractContentCaptureIntegrationTest.java
index b3bc15f..7e6f6f2 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/AbstractContentCaptureIntegrationTest.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/AbstractContentCaptureIntegrationTest.java
@@ -19,6 +19,7 @@
 import static android.contentcaptureservice.cts.Helper.resetService;
 import static android.contentcaptureservice.cts.Helper.setService;
 import static android.contentcaptureservice.cts.common.ShellHelper.runShellCommand;
+import static android.provider.Settings.Secure.CONTENT_CAPTURE_ENABLED;
 
 import android.app.Application;
 import android.content.Context;
@@ -37,9 +38,13 @@
 
 import com.android.compatibility.common.util.RequiredServiceRule;
 import com.android.compatibility.common.util.SafeCleanerRule;
+import com.android.compatibility.common.util.SettingsStateChangerRule;
+import com.android.compatibility.common.util.SettingsUtils;
 
 import org.junit.After;
+import org.junit.AfterClass;
 import org.junit.Before;
+import org.junit.BeforeClass;
 import org.junit.Rule;
 import org.junit.rules.RuleChain;
 import org.junit.runner.RunWith;
@@ -53,6 +58,8 @@
 
     private static final String TAG = AbstractContentCaptureIntegrationTest.class.getSimpleName();
 
+    private final String mTag = getClass().getSimpleName();
+
     protected static final Context sContext = InstrumentationRegistry.getTargetContext();
 
     protected ActivitiesWatcher mActivitiesWatcher;
@@ -61,21 +68,41 @@
 
     private final RequiredServiceRule mRequiredServiceRule =
             new RequiredServiceRule("content_capture");
-    private final ContentCaptureLoggingTestRule mLoggingRule =
-            new ContentCaptureLoggingTestRule(TAG);
 
+    private final ContentCaptureLoggingTestRule mLoggingRule = new ContentCaptureLoggingTestRule();
+
+
+    /**
+     * Watcher set on {@link #enableService()} and used to wait until it's gone after the test
+     * finishes.
+     */
+    private ServiceWatcher mServiceWatcher;
 
     protected final SafeCleanerRule mSafeCleanerRule = new SafeCleanerRule()
             .setDumper(mLoggingRule)
+            .run(() -> {
+                Log.v(mTag, "@SafeCleaner: resetDefaultService()");
+                resetService();
+
+                if (mServiceWatcher != null) {
+                    mServiceWatcher.waitOnDestroy();
+                }
+
+            })
             .add(() -> {
                 return CtsContentCaptureService.getExceptions();
             });
 
+    private final SettingsStateChangerRule mFeatureEnablerRule = new SettingsStateChangerRule(
+            sContext, CONTENT_CAPTURE_ENABLED, "true");
+
     @Rule
     public final RuleChain mLookAllTheseRules = RuleChain
             //
             // mRequiredServiceRule should be first so the test can be skipped right away
             .outerRule(mRequiredServiceRule)
+            // enable it as soon as possible, as it have to wait for the listener
+            .around(mFeatureEnablerRule)
             //
             // mLoggingRule wraps the test but doesn't interfere with it
             .around(mLoggingRule)
@@ -86,19 +113,25 @@
             // Finally, let subclasses set their ActivityTestRule
             .around(getActivityTestRule());
 
-    /**
-     * Watcher set on {@link #enableService()} and used to wait until it's gone after the test
-     * finishes.
-     */
-    private ServiceWatcher mServiceWatcher;
-
     protected AbstractContentCaptureIntegrationTest(@NonNull Class<A> activityClass) {
         mActivityClass = activityClass;
     }
 
+    @BeforeClass
+    public static void disableDefaultService() {
+        Log.v(TAG, "@BeforeClass: disableDefaultService()");
+        Helper.setDefaultServiceEnabled(false);
+    }
+
+    @AfterClass
+    public static void enableDefaultService() {
+        Log.v(TAG, "@AfterClass: enableDefaultService()");
+        Helper.setDefaultServiceEnabled(true);
+    }
+
     @Before
     public void prepareDevice() throws Exception {
-        Log.v(TAG, "@Before: prepareDevice()");
+        Log.v(mTag, "@Before: prepareDevice()");
 
         // Unlock screen.
         runShellCommand("input keyevent KEYCODE_WAKEUP");
@@ -112,13 +145,13 @@
 
     @Before
     public void clearState() {
-        Log.v(TAG, "@Before: clearState()");
+        Log.v(mTag, "@Before: clearState()");
         CtsContentCaptureService.resetStaticState();
     }
 
     @Before
     public void registerLifecycleCallback() {
-        Log.v(TAG, "@Before: Registering lifecycle callback");
+        Log.v(mTag, "@Before: Registering lifecycle callback");
         final Application app = (Application) sContext.getApplicationContext();
         mActivitiesWatcher = new ActivitiesWatcher(GENERIC_TIMEOUT_MS);
         app.registerActivityLifecycleCallbacks(mActivitiesWatcher);
@@ -126,22 +159,19 @@
 
     @After
     public void unregisterLifecycleCallback() {
-        Log.d(TAG, "@After: Unregistering lifecycle callback: " + mActivitiesWatcher);
+        Log.d(mTag, "@After: Unregistering lifecycle callback: " + mActivitiesWatcher);
         if (mActivitiesWatcher != null) {
             final Application app = (Application) sContext.getApplicationContext();
             app.unregisterActivityLifecycleCallbacks(mActivitiesWatcher);
         }
     }
 
-    // TODO(b/119638958): this method should be called from the SafeCleaner, but we'll need to
-    // add a run() method that takes an object that can throw an exception
-    @After
-    public void restoreDefaultService() throws InterruptedException {
-        Log.v(TAG, "@After: restoreDefaultService()");
-        resetService();
-
-        if (mServiceWatcher != null) {
-            mServiceWatcher.waitOnDestroy();
+    @Nullable
+    public static void setFeatureEnabled(@Nullable String enabled) {
+        if (enabled == null) {
+            SettingsUtils.syncDelete(sContext, CONTENT_CAPTURE_ENABLED);
+        } else {
+            SettingsUtils.syncSet(sContext, CONTENT_CAPTURE_ENABLED, enabled);
         }
     }
 
@@ -168,13 +198,13 @@
     protected abstract ActivityTestRule<A> getActivityTestRule();
 
     protected A launchActivity() {
-        Log.d(TAG, "Launching " + mActivityClass.getSimpleName());
+        Log.d(mTag, "Launching " + mActivityClass.getSimpleName());
 
         return getActivityTestRule().launchActivity(new Intent(sContext, mActivityClass));
     }
 
     protected A launchActivity(@Nullable Visitor<Intent> visitor) {
-        Log.d(TAG, "Launching " + mActivityClass.getSimpleName());
+        Log.d(mTag, "Launching " + mActivityClass.getSimpleName());
 
         final Intent intent = new Intent(sContext, mActivityClass);
         if (visitor != null) {
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/AbstractRootViewActivity.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/AbstractRootViewActivity.java
index f328ca0..0c6ca18 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/AbstractRootViewActivity.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/AbstractRootViewActivity.java
@@ -15,6 +15,7 @@
  */
 package android.contentcaptureservice.cts;
 
+import android.app.Activity;
 import android.contentcaptureservice.cts.common.DoubleVisitor;
 import android.os.Bundle;
 import android.util.Log;
@@ -30,18 +31,26 @@
 
     private static final String TAG = AbstractRootViewActivity.class.getSimpleName();
 
-    private static DoubleVisitor<AbstractContentCaptureActivity, LinearLayout> sRootViewVisitor;
+    private static DoubleVisitor<AbstractRootViewActivity, LinearLayout> sRootViewVisitor;
+    private static DoubleVisitor<AbstractRootViewActivity, LinearLayout> sOnAnimationVisitor;
 
     private LinearLayout mRootView;
 
     /**
-     * Applies a visitor to the root view {@code onCreate()}.
+     * Sets a visitor called when the activity is created.
      */
-    static void onRootView(
-            @NonNull DoubleVisitor<AbstractContentCaptureActivity, LinearLayout> visitor) {
+    static void onRootView(@NonNull DoubleVisitor<AbstractRootViewActivity, LinearLayout> visitor) {
         sRootViewVisitor = visitor;
     }
 
+    /**
+     * Sets a visitor to be called on {@link Activity#onEnterAnimationComplete()}.
+     */
+    static void onAnimationComplete(
+            @NonNull DoubleVisitor<AbstractRootViewActivity, LinearLayout> visitor) {
+        sOnAnimationVisitor = visitor;
+    }
+
     @Override
     protected final void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -49,14 +58,17 @@
 
         mRootView = findViewById(R.id.root_view);
 
-        Log.d(TAG, "Parents for " + getClass() + ": rootView=" + mRootView
+        Log.d(TAG, "onCreate(): parents for " + getClass() + ": rootView=" + mRootView
                 + "\ngrandParent=" + getGrandParent()
-                + "\ngrandGrandParent=" + getGrandGrandParent()
-                + "\ndecorView=" + getDecorView());
+                + "\ngrandGrandParent=" + getGrandGrandParent());
 
         if (sRootViewVisitor != null) {
             Log.d(TAG, "Applying visitor to " + this + "/" + mRootView);
-            sRootViewVisitor.visit(this, mRootView);
+            try {
+                sRootViewVisitor.visit(this, mRootView);
+            } finally {
+                sRootViewVisitor = null;
+            }
         }
     }
 
@@ -67,8 +79,21 @@
         Log.d(TAG, "AutofillIds for " + getClass() + ": "
                 + " rootView=" + getRootView().getAutofillId()
                 + ", grandParent=" + getGrandParent().getAutofillId()
-                + ", grandGrandParent=" + getGrandGrandParent().getAutofillId()
-                + ", decorView=" + getDecorView().getAutofillId());
+                + ", grandGrandParent=" + getGrandGrandParent().getAutofillId());
+    }
+
+    @Override
+    public void onEnterAnimationComplete() {
+        if (sOnAnimationVisitor != null) {
+            Log.i(TAG, "onEnterAnimationComplete(): applying visitor on " + this);
+            try {
+                sOnAnimationVisitor.visit(this, mRootView);
+            } finally {
+                sOnAnimationVisitor = null;
+            }
+        } else {
+            Log.i(TAG, "onEnterAnimationComplete(): no visitor on " + this);
+        }
     }
 
     public LinearLayout getRootView() {
@@ -87,12 +112,6 @@
         return (ViewGroup) getGrandParent().getParent();
     }
 
-    // TODO(b/122315042): remove this method when not needed anymore
-    @NonNull
-    public ViewGroup getDecorView() {
-        return (ViewGroup) getGrandGrandParent().getParent();
-    }
-
     /**
      * The real "onCreate" method that should be extended by subclasses.
      *
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/Assertions.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/Assertions.java
index f5366f6..e3792ee 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/Assertions.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/Assertions.java
@@ -17,6 +17,8 @@
 
 import static android.contentcaptureservice.cts.Helper.MY_EPOCH;
 import static android.contentcaptureservice.cts.Helper.TAG;
+import static android.view.contentcapture.ContentCaptureEvent.TYPE_INITIAL_VIEW_TREE_APPEARED;
+import static android.view.contentcapture.ContentCaptureEvent.TYPE_INITIAL_VIEW_TREE_APPEARING;
 import static android.view.contentcapture.ContentCaptureEvent.TYPE_VIEW_APPEARED;
 import static android.view.contentcapture.ContentCaptureEvent.TYPE_VIEW_DISAPPEARED;
 import static android.view.contentcapture.ContentCaptureEvent.TYPE_VIEW_TEXT_CHANGED;
@@ -27,6 +29,7 @@
 import android.contentcaptureservice.cts.CtsContentCaptureService.Session;
 import android.net.Uri;
 import android.util.Log;
+import android.view.Display;
 import android.view.View;
 import android.view.autofill.AutofillId;
 import android.view.contentcapture.ContentCaptureEvent;
@@ -53,7 +56,7 @@
         assertWithMessage("wrong activity for %s", session)
                 .that(session.context.getActivityComponent())
                 .isEqualTo(activity.getComponentName());
-        // TODO(b/119638958): merge both or replace check above by:
+        // TODO(b/123540602): merge both or replace check above by:
         //  assertMainSessionContext(session, activity);
         assertThat(session.id).isEqualTo(expectedSessionId);
     }
@@ -75,9 +78,8 @@
         assertWithMessage("wrong activity for %s", session)
                 .that(session.context.getActivityComponent())
                 .isEqualTo(activity.getComponentName());
-        // TODO(b/121260224): add this assertion when it's set
-        // assertWithMessage("context for session %s should have displayId", session)
-        //        .that(session.context.getDisplayId()).isNotEqualTo(0);
+        assertWithMessage("context for session %s should have displayId", session)
+                .that(session.context.getDisplayId()).isNotEqualTo(Display.INVALID_DISPLAY);
         assertWithMessage("wrong task id for session %s", session)
                 .that(session.context.getTaskId()).isEqualTo(activity.getRealTaskId());
         assertWithMessage("wrong flags on context for session %s", session)
@@ -96,7 +98,7 @@
         assertWithMessage("context for session %s should not have component", session)
                 .that(session.context.getActivityComponent()).isNull();
         assertWithMessage("context for session %s should not have displayId", session)
-                .that(session.context.getDisplayId()).isEqualTo(0);
+                .that(session.context.getDisplayId()).isEqualTo(Display.INVALID_DISPLAY);
         assertWithMessage("context for session %s should not have taskId", session)
                 .that(session.context.getTaskId()).isEqualTo(0);
         assertWithMessage("context for session %s should not have flags", session)
@@ -136,16 +138,28 @@
     }
 
     /**
+     * Asserts the contents of a {@link #TYPE_VIEW_APPEARED} event for a decor view.
+     *
+     * <P>The decor view is typically internal, so there isn't much we can assert, other than its
+     * autofill id.
+     */
+    public static void assertDecorViewAppeared(@NonNull List<ContentCaptureEvent> events,
+            int index, @NonNull View expectedDecorView) {
+        final ContentCaptureEvent event = assertViewAppeared(events, index);
+        assertWithMessage("wrong autofill id on %s (%s)", event, index)
+                .that(event.getViewNode().getAutofillId())
+                .isEqualTo(expectedDecorView.getAutofillId());
+    }
+
+    /**
      * Asserts the contents of a {@link #TYPE_VIEW_APPEARED} event, without checking for parent id.
      */
     public static ViewNode assertViewWithUnknownParentAppeared(
             @NonNull List<ContentCaptureEvent> events, int index, @NonNull View expectedView,
             @Nullable String expectedText) {
-        final ViewNode node = assertViewAppeared(events, index);
-        final ContentCaptureEvent event = events.get(index);
+        final ContentCaptureEvent event = assertViewAppeared(events, index);
+        final ViewNode node = event.getViewNode();
 
-        assertWithMessage("invalid time on %s (%s)", event, index).that(event.getEventTime())
-                .isAtLeast(MY_EPOCH);
         assertWithMessage("wrong class on %s (%s)", event, index).that(node.getClassName())
                 .isEqualTo(expectedView.getClass().getName());
         assertWithMessage("wrong autofill id on %s (%s)", event, index).that(node.getAutofillId())
@@ -155,21 +169,19 @@
             assertWithMessage("wrong text on %s (%s)", event, index).that(node.getText().toString())
                     .isEqualTo(expectedText);
         }
-        // TODO(b/119638958): test more fields, like resource id
+        // TODO(b/123540602): test more fields, like resource id
         return node;
     }
 
     /**
      * Asserts the contents of a {@link #TYPE_VIEW_APPEARED} event, without checking for parent id.
      */
-    public static ViewNode assertViewAppeared(@NonNull List<ContentCaptureEvent> events,
+    public static ContentCaptureEvent assertViewAppeared(@NonNull List<ContentCaptureEvent> events,
             int index) {
-        final ContentCaptureEvent event = getEvent(events, index);
-        assertWithMessage("wrong event type at index %s: %s", index, event).that(event.getType())
-                .isEqualTo(TYPE_VIEW_APPEARED);
+        final ContentCaptureEvent event = getEvent(events, index, TYPE_VIEW_APPEARED);
         final ViewNode node = event.getViewNode();
         assertThat(node).isNotNull();
-        return node;
+        return event;
     }
 
     /**
@@ -203,6 +215,38 @@
     }
 
     /**
+     * Asserts the contents of a {@link #TYPE_INITIAL_VIEW_TREE_APPEARING} event.
+     */
+    public static void assertViewHierarchyStarted(@NonNull List<ContentCaptureEvent> events,
+            int index) {
+        assertViewHierarchyEvent(events, index, /* started= */ true);
+    }
+
+    /**
+     * Asserts the contents of a {@link #TYPE_INITIAL_VIEW_TREE_APPEARED} event.
+     */
+    public static void assertViewHierarchyFinished(@NonNull List<ContentCaptureEvent> events,
+            int index) {
+        assertViewHierarchyEvent(events, index, /* started= */ false);
+    }
+
+    private static void assertViewHierarchyEvent(@NonNull List<ContentCaptureEvent> events,
+            int index, boolean started) {
+        final int expectedType = started
+                ? TYPE_INITIAL_VIEW_TREE_APPEARING
+                : TYPE_INITIAL_VIEW_TREE_APPEARED;
+        final ContentCaptureEvent event = getEvent(events, index, expectedType);
+        assertWithMessage("event %s (index %s) should not have a ViewNode", event, index)
+                .that(event.getViewNode()).isNull();
+        assertWithMessage("event %s (index %s) should not have text", event, index)
+                .that(event.getViewNode()).isNull();
+        assertWithMessage("event %s (index %s) should not have an autofillId", event, index)
+                .that(event.getId()).isNull();
+        assertWithMessage("event %s (index %s) should not have autofillIds", event, index)
+                .that(event.getIds()).isNull();
+    }
+
+    /**
      * Asserts that a session for the given activity has no events.
      */
     public static void assertNoEvents(@NonNull Session session,
@@ -223,7 +267,8 @@
      * @param minimumSize size of events received if activity stopped before views disappeared
      * @param expectedIds ids of views that might have disappeared.
      */
-    // TODO(b/122315042): remove this method if we could make it deterministic
+    // TODO(b/123540067, 122315042): remove this method if we could make it deterministic, and
+    // inline the assertions (or rename / change its logic)
     public static void assertViewsOptionallyDisappeared(@NonNull List<ContentCaptureEvent> events,
             int minimumSize, @NonNull AutofillId... expectedIds) {
         final int actualSize = events.size();
@@ -233,8 +278,19 @@
         }
         assertThat(events).hasSize(minimumSize + 1);
         final ContentCaptureEvent batchDisappearEvent = events.get(minimumSize);
-        final List<AutofillId> actualIds = batchDisappearEvent.getIds();
-        assertThat(actualIds).containsExactly((Object[]) expectedIds);
+
+        if (expectedIds.length == 1) {
+            assertWithMessage("Should have just one deleted id on %s", batchDisappearEvent)
+                    .that(batchDisappearEvent.getIds()).isNull();
+            assertWithMessage("wrong deleted id on %s", batchDisappearEvent)
+                    .that(batchDisappearEvent.getId()).isEqualTo(expectedIds[0]);
+        } else {
+            assertWithMessage("Should not have individual deleted id on %s", batchDisappearEvent)
+                    .that(batchDisappearEvent.getId()).isNull();
+            final List<AutofillId> actualIds = batchDisappearEvent.getIds();
+            assertWithMessage("wrong deleteds id on %s", batchDisappearEvent)
+                    .that(actualIds).containsExactly((Object[]) expectedIds);
+        }
     }
 
     /**
@@ -276,17 +332,11 @@
 
     private static ContentCaptureEvent assertCommonViewDisappearedProperties(
             @NonNull List<ContentCaptureEvent> events, int index) {
-        final ContentCaptureEvent event = getEvent(events, index);
-        assertWithMessage("wrong event type at index %s: %s", index, event).that(event.getType())
-                .isEqualTo(TYPE_VIEW_DISAPPEARED);
-        assertWithMessage("invalid time on %s (index %s)", event, index).that(event.getEventTime())
-            .isAtLeast(MY_EPOCH);
+        final ContentCaptureEvent event = getEvent(events, index, TYPE_VIEW_DISAPPEARED);
         assertWithMessage("event %s (index %s) should not have a ViewNode", event, index)
                 .that(event.getViewNode()).isNull();
         assertWithMessage("event %s (index %s) should not have text", event, index)
-            .that(event.getText()).isNull();
-        assertWithMessage("event %s (index %s) should not have a ViewNode", event, index)
-            .that(event.getViewNode()).isNull();
+                .that(event.getText()).isNull();
         return event;
     }
 
@@ -296,13 +346,9 @@
     public static void assertVirtualViewAppeared(@NonNull List<ContentCaptureEvent> events,
             int index, @NonNull ContentCaptureSession session, @NonNull AutofillId parentId,
             int childId, @Nullable String expectedText) {
-        final ContentCaptureEvent event = getEvent(events, index);
-        assertWithMessage("wrong event type at index %s: %s", index, event).that(event.getType())
-            .isEqualTo(TYPE_VIEW_APPEARED);
+        final ContentCaptureEvent event = getEvent(events, index, TYPE_VIEW_APPEARED);
         final ViewNode node = event.getViewNode();
         assertThat(node).isNotNull();
-        assertWithMessage("invalid time on %s (index %s)", event, index).that(event.getEventTime())
-            .isAtLeast(MY_EPOCH);
         final AutofillId expectedId = session.newAutofillId(parentId, childId);
         assertWithMessage("wrong autofill id on %s (index %s)", event, index)
             .that(node.getAutofillId()).isEqualTo(expectedId);
@@ -355,9 +401,7 @@
      */
     public static void assertViewTextChanged(@NonNull List<ContentCaptureEvent> events, int index,
             @NonNull AutofillId expectedId, @NonNull String expectedText) {
-        final ContentCaptureEvent event = getEvent(events, index);
-        assertWithMessage("wrong event at index %s: %s", index, event).that(event.getType())
-                .isEqualTo(TYPE_VIEW_TEXT_CHANGED);
+        final ContentCaptureEvent event = getEvent(events, index, TYPE_VIEW_TEXT_CHANGED);
         assertWithMessage("Wrong id on %s (%s)", event, index).that(event.getId())
                 .isEqualTo(expectedId);
         assertWithMessage("Wrong text on %s (%s)", event, index).that(event.getText().toString())
@@ -387,15 +431,51 @@
      * Gets the event at the given index, failing with the user-friendly message if necessary...
      */
     @NonNull
-    public static ContentCaptureEvent getEvent(@NonNull List<ContentCaptureEvent> events,
-            int index) {
+    private static ContentCaptureEvent getEvent(@NonNull List<ContentCaptureEvent> events,
+            int index, int expectedType) {
         assertWithMessage("events is null").that(events).isNotNull();
         final ContentCaptureEvent event = events.get(index);
         assertWithMessage("no event at index %s (size %s): %s", index, events.size(), events)
                 .that(event).isNotNull();
+        final int actualType = event.getType();
+        if (actualType != expectedType) {
+            throw new AssertionError(String.format(
+                    "wrong event type (expected %s, actual is %s) at index %s: %s",
+                    eventTypeAsString(expectedType), eventTypeAsString(actualType), index, event));
+        }
+        assertWithMessage("invalid time on %s (index %s)", event, index).that(event.getEventTime())
+                 .isAtLeast(MY_EPOCH);
         return event;
     }
 
+    /**
+     * Gets an user-friendly description of the given event type.
+     */
+    @NonNull
+    public static String eventTypeAsString(int type) {
+        final String string;
+        switch (type) {
+            case TYPE_VIEW_APPEARED:
+                string = "APPEARED";
+                break;
+            case TYPE_VIEW_DISAPPEARED:
+                string = "DISAPPEARED";
+                break;
+            case TYPE_VIEW_TEXT_CHANGED:
+                string = "TEXT_CHANGED";
+                break;
+            case TYPE_INITIAL_VIEW_TREE_APPEARING:
+                string = "HIERARCHY_STARTED";
+                break;
+            case TYPE_INITIAL_VIEW_TREE_APPEARED:
+                string = "HIERARCHY_FINISHED";
+                break;
+            default:
+                return "UNKNOWN-" + type;
+        }
+        return String.format("%s-%d", string, type);
+    }
+
     private Assertions() {
         throw new UnsupportedOperationException("contain static methods only");
     }
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/BlankActivityTest.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/BlankActivityTest.java
index 3597ae6..abb0e7e 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/BlankActivityTest.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/BlankActivityTest.java
@@ -22,13 +22,19 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import android.content.ComponentName;
 import android.contentcaptureservice.cts.CtsContentCaptureService.Session;
 import android.contentcaptureservice.cts.common.ActivitiesWatcher.ActivityWatcher;
+import android.platform.test.annotations.AppModeFull;
 import android.support.test.rule.ActivityTestRule;
 import android.util.Log;
 
 import org.junit.Test;
 
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
+
+@AppModeFull(reason = "BlankWithTitleActivityTest is enough")
 public class BlankActivityTest extends AbstractContentCaptureIntegrationTest<BlankActivity> {
 
     private static final String TAG = BlankActivityTest.class.getSimpleName();
@@ -72,14 +78,85 @@
         final BlankActivity activity = launchActivity();
         watcher.waitFor(RESUMED);
 
-        assertThat(activity.getContentCaptureManager().getServiceComponentName())
-                .isEqualTo(CONTENT_CAPTURE_SERVICE_COMPONENT_NAME);
+        try {
+            assertThat(activity.getContentCaptureManager().getServiceComponentName())
+                    .isEqualTo(CONTENT_CAPTURE_SERVICE_COMPONENT_NAME);
 
-        resetService();
-        service.waitUntilDisconnected();
+            resetService();
+            service.waitUntilDisconnected();
 
-        assertThat(activity.getContentCaptureManager().getServiceComponentName())
-                .isNotEqualTo(CONTENT_CAPTURE_SERVICE_COMPONENT_NAME);
+            assertThat(activity.getContentCaptureManager().getServiceComponentName())
+                    .isNotEqualTo(CONTENT_CAPTURE_SERVICE_COMPONENT_NAME);
+        } finally {
+            activity.finish();
+            watcher.waitFor(DESTROYED);
+        }
+    }
+
+    @Test
+    public void testGetServiceComponentName_onUiThread() throws Exception {
+        final CtsContentCaptureService service = enableService();
+        service.waitUntilConnected();
+
+        final ActivityWatcher watcher = startWatcher();
+
+        final BlankActivity activity = launchActivity();
+        watcher.waitFor(RESUMED);
+
+        final AtomicReference<ComponentName> ref = new AtomicReference<>();
+        activity.syncRunOnUiThread(
+                () -> ref.set(activity.getContentCaptureManager().getServiceComponentName()));
+
+        activity.finish();
+        watcher.waitFor(DESTROYED);
+
+        assertThat(ref.get()).isEqualTo(CONTENT_CAPTURE_SERVICE_COMPONENT_NAME);
+    }
+
+    @Test
+    public void testIsContentCaptureFeatureEnabled_onUiThread() throws Exception {
+        final CtsContentCaptureService service = enableService();
+        service.waitUntilConnected();
+
+        final ActivityWatcher watcher = startWatcher();
+
+        final BlankActivity activity = launchActivity();
+        watcher.waitFor(RESUMED);
+
+        final AtomicBoolean ref = new AtomicBoolean();
+        activity.syncRunOnUiThread(() -> ref
+                .set(activity.getContentCaptureManager().isContentCaptureFeatureEnabled()));
+
+        activity.finish();
+        watcher.waitFor(DESTROYED);
+
+        assertThat(ref.get()).isTrue();
+    }
+
+    @Test
+    public void testSetContentCaptureFeatureEnabled_onUiThread() throws Exception {
+        final CtsContentCaptureService service = enableService();
+        service.waitUntilConnected();
+
+        final ActivityWatcher watcher = startWatcher();
+
+        final BlankActivity activity = launchActivity();
+        watcher.waitFor(RESUMED);
+
+        final AtomicReference<Exception> ref = new AtomicReference<>();
+        activity.syncRunOnUiThread(() -> {
+            try {
+                activity.getContentCaptureManager().setContentCaptureFeatureEnabled(true);
+            } catch (Exception e) {
+                ref.set(e);
+            }
+        });
+
+        activity.finish();
+        watcher.waitFor(DESTROYED);
+
+        final Exception e = ref.get();
+        if (e != null) throw e;
     }
 
     @Test
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/BlankWithTitleActivity.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/BlankWithTitleActivity.java
index 256b502..88ff553 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/BlankWithTitleActivity.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/BlankWithTitleActivity.java
@@ -15,13 +15,18 @@
  */
 package android.contentcaptureservice.cts;
 
+import static android.contentcaptureservice.cts.Assertions.assertDecorViewAppeared;
 import static android.contentcaptureservice.cts.Assertions.assertRightActivity;
 import static android.contentcaptureservice.cts.Assertions.assertViewAppeared;
+import static android.contentcaptureservice.cts.Assertions.assertViewHierarchyFinished;
+import static android.contentcaptureservice.cts.Assertions.assertViewHierarchyStarted;
+import static android.contentcaptureservice.cts.Assertions.assertViewsOptionallyDisappeared;
 
 import static com.google.common.truth.Truth.assertThat;
 
 import android.contentcaptureservice.cts.CtsContentCaptureService.Session;
 import android.util.Log;
+import android.view.View;
 import android.view.contentcapture.ContentCaptureEvent;
 import android.view.contentcapture.ContentCaptureSessionId;
 import android.view.contentcapture.ViewNode;
@@ -32,19 +37,30 @@
 
 public class BlankWithTitleActivity extends AbstractContentCaptureActivity {
 
+    private static final String TAG = BlankWithTitleActivity.class.getSimpleName();
+
     @Override
     public void assertDefaultEvents(@NonNull Session session) {
         final ContentCaptureSessionId sessionId = session.id;
         assertRightActivity(session, sessionId, this);
 
-        final List<ContentCaptureEvent> events = session.getEvents();
-        Log.v(mTag, "events: " + events);
+        final View decorView = getDecorView();
 
-        final int minEvents = 1;
-        // TODO(b/119638528): somehow asset the grandparents...
+        final List<ContentCaptureEvent> events = session.getEvents();
+        Log.v(TAG, "events(" + events.size() + "): " + events);
+
+        final int minEvents = 7; // TODO(b/122315042): disappeared not always sent
         assertThat(events.size()).isAtLeast(minEvents);
 
-        final ViewNode title = assertViewAppeared(events, 0);
+        assertViewHierarchyStarted(events, 0);
+        assertDecorViewAppeared(events, 1, decorView);
+        // TODO(b/123540067): ignoring 4 intermediate parents
+        final ViewNode title = assertViewAppeared(events, 5).getViewNode();
         assertThat(title.getText()).isEqualTo("Blanka");
+        assertViewHierarchyFinished(events, 6);
+        if (false) { // TODO(b/123540067): disabled because it includes the parent
+            assertViewsOptionallyDisappeared(events, minEvents, decorView.getAutofillId(),
+                    title.getAutofillId());
+        }
     }
 }
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/BlankWithTitleActivityTest.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/BlankWithTitleActivityTest.java
index e08371c..28dc2e7 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/BlankWithTitleActivityTest.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/BlankWithTitleActivityTest.java
@@ -18,8 +18,10 @@
 import static android.contentcaptureservice.cts.common.ActivitiesWatcher.ActivityLifecycle.DESTROYED;
 import static android.contentcaptureservice.cts.common.ActivitiesWatcher.ActivityLifecycle.RESUMED;
 
+import android.content.Intent;
 import android.contentcaptureservice.cts.CtsContentCaptureService.Session;
 import android.contentcaptureservice.cts.common.ActivitiesWatcher.ActivityWatcher;
+import android.platform.test.annotations.AppModeFull;
 import android.support.test.rule.ActivityTestRule;
 import android.util.Log;
 
@@ -58,4 +60,24 @@
 
         activity.assertDefaultEvents(session);
     }
+
+    @AppModeFull(reason = "testSimpleSessionLifecycle() is enough")
+    @Test
+    public void testSimpleSessionLifecycle_noAnimation() throws Exception {
+        final CtsContentCaptureService service = enableService();
+        final ActivityWatcher watcher = startWatcher();
+
+        final BlankWithTitleActivity activity = launchActivity(
+                (intent) -> intent.addFlags(
+                        Intent.FLAG_ACTIVITY_NO_ANIMATION | Intent.FLAG_ACTIVITY_NEW_TASK));
+        watcher.waitFor(RESUMED);
+
+        activity.finish();
+        watcher.waitFor(DESTROYED);
+
+        final Session session = service.getOnlyFinishedSession();
+        Log.v(TAG, "session id: " + session.id);
+
+        activity.assertDefaultEvents(session);
+    }
 }
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/ChildlessActivityTest.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/ChildlessActivityTest.java
index 40c1420..8dbda23 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/ChildlessActivityTest.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/ChildlessActivityTest.java
@@ -18,34 +18,42 @@
 import static android.contentcaptureservice.cts.Assertions.LifecycleOrder.CREATION;
 import static android.contentcaptureservice.cts.Assertions.LifecycleOrder.DESTRUCTION;
 import static android.contentcaptureservice.cts.Assertions.assertChildSessionContext;
+import static android.contentcaptureservice.cts.Assertions.assertDecorViewAppeared;
 import static android.contentcaptureservice.cts.Assertions.assertLifecycleOrder;
 import static android.contentcaptureservice.cts.Assertions.assertMainSessionContext;
 import static android.contentcaptureservice.cts.Assertions.assertRightActivity;
 import static android.contentcaptureservice.cts.Assertions.assertViewAppeared;
 import static android.contentcaptureservice.cts.Assertions.assertViewDisappeared;
-import static android.contentcaptureservice.cts.Assertions.assertViewWithUnknownParentAppeared;
+import static android.contentcaptureservice.cts.Assertions.assertViewHierarchyFinished;
+import static android.contentcaptureservice.cts.Assertions.assertViewHierarchyStarted;
 import static android.contentcaptureservice.cts.Assertions.assertViewsDisappeared;
 import static android.contentcaptureservice.cts.Assertions.assertViewsOptionallyDisappeared;
-import static android.contentcaptureservice.cts.Helper.componentNameFor;
+import static android.contentcaptureservice.cts.Helper.newImportantView;
 import static android.contentcaptureservice.cts.common.ActivitiesWatcher.ActivityLifecycle.DESTROYED;
 import static android.contentcaptureservice.cts.common.ActivitiesWatcher.ActivityLifecycle.RESUMED;
 
 import static com.google.common.truth.Truth.assertThat;
 
-import android.content.Context;
+import static org.testng.Assert.assertThrows;
+
+import android.contentcaptureservice.cts.CtsContentCaptureService.DisconnectListener;
+import android.contentcaptureservice.cts.CtsContentCaptureService.ServiceWatcher;
 import android.contentcaptureservice.cts.CtsContentCaptureService.Session;
 import android.contentcaptureservice.cts.common.ActivitiesWatcher.ActivityWatcher;
 import android.contentcaptureservice.cts.common.ActivityLauncher;
 import android.net.Uri;
 import android.os.SystemClock;
+import android.platform.test.annotations.AppModeFull;
 import android.support.test.rule.ActivityTestRule;
 import android.util.Log;
 import android.view.View;
 import android.view.autofill.AutofillId;
 import android.view.contentcapture.ContentCaptureContext;
 import android.view.contentcapture.ContentCaptureEvent;
+import android.view.contentcapture.ContentCaptureManager;
 import android.view.contentcapture.ContentCaptureSession;
 import android.view.contentcapture.ContentCaptureSessionId;
+import android.widget.LinearLayout;
 import android.widget.TextView;
 
 import androidx.annotation.NonNull;
@@ -59,6 +67,7 @@
 import java.util.List;
 import java.util.concurrent.atomic.AtomicReference;
 
+@AppModeFull(reason = "BlankWithTitleActivityTest is enough")
 public class ChildlessActivityTest
         extends AbstractContentCaptureIntegrationTest<ChildlessActivity> {
 
@@ -99,6 +108,39 @@
         activity.assertDefaultEvents(session);
     }
 
+    @Ignore("not implemented yet, pending on b/123658889")
+    @Test
+    public void testGetContentCapture_disabledWhenNoService() throws Exception {
+
+        // TODO(b/123658889): must call a cmd that always disable the service, even if the OEM
+        // provides an implementation
+
+        final ActivityWatcher watcher = startWatcher();
+
+        final ChildlessActivity activity = launchActivity();
+        watcher.waitFor(RESUMED);
+
+        assertThat(activity.getContentCaptureManager().isContentCaptureEnabled()).isFalse();
+
+        activity.finish();
+        watcher.waitFor(DESTROYED);
+    }
+
+    @Test
+    public void testGetContentCapture_enabledWhenNoService() throws Exception {
+        enableService();
+        final ActivityWatcher watcher = startWatcher();
+
+        final ChildlessActivity activity = launchActivity();
+        watcher.waitFor(RESUMED);
+
+        assertThat(activity.getContentCaptureManager().isContentCaptureEnabled()).isTrue();
+
+        activity.finish();
+        watcher.waitFor(DESTROYED);
+
+    }
+
     @Test
     public void testLaunchAnotherActivity() throws Exception {
         final CtsContentCaptureService service = enableService();
@@ -134,44 +176,6 @@
         activity2.assertDefaultEvents(session2);
     }
 
-    @Ignore("not implemented yet, pending on b/122595322")
-    @Test
-    public void testLaunchAnotherActivity_serviceDisabledActivity() throws Exception {
-        final CtsContentCaptureService service = enableService();
-        final ActivityWatcher watcher1 = startWatcher();
-
-        // Disable activity 2
-        service.setActivityContentCaptureEnabled(componentNameFor(LoginActivity.class), false);
-
-        // Launch and finish 1st activity
-        final ChildlessActivity activity1 = launchActivity();
-        watcher1.waitFor(RESUMED);
-        activity1.finish();
-        watcher1.waitFor(DESTROYED);
-
-        // Launch and finish 2nd activity
-        final ActivityLauncher<LoginActivity> anotherActivityLauncher = new ActivityLauncher<>(
-                sContext, mActivitiesWatcher, LoginActivity.class);
-        final ActivityWatcher watcher2 = anotherActivityLauncher.getWatcher();
-        final LoginActivity activity2 = anotherActivityLauncher.launchActivity();
-        watcher2.waitFor(RESUMED);
-        activity2.finish();
-        watcher2.waitFor(DESTROYED);
-
-        // Assert the sessions
-        final List<ContentCaptureSessionId> sessionIds = service.getAllSessionIds();
-        assertThat(sessionIds).hasSize(1);
-        final ContentCaptureSessionId sessionId1 = sessionIds.get(0);
-        Log.v(TAG, "session id1: " + sessionId1);
-
-        final Session session1 = service.getFinishedSession(sessionId1);
-        activity1.assertDefaultEvents(session1);
-
-        // TODO(b/122595322): should also test events after re-enabling it
-    }
-
-    // TODO(b/122595322): same tests for disabled by package, explicity whitelisted, etc...
-
     @Test
     public void testAddAndRemoveNoImportantChild() throws Exception {
         final CtsContentCaptureService service = enableService();
@@ -207,7 +211,7 @@
         // Should be empty because the root view is not important for content capture without a
         // child that is important.
         final List<ContentCaptureEvent> events = session.getEvents();
-        Log.v(TAG, "events: " + events);
+        Log.v(TAG, "events(" + events.size() + "): " + events);
         assertThat(events).isEmpty();
     }
 
@@ -221,7 +225,7 @@
         final AtomicReference<TextView> childRef = new AtomicReference<>();
 
         ChildlessActivity.onRootView((activity, rootView) -> {
-            final TextView text = newImportantChild(activity, "Important I am");
+            final TextView text = newImportantView(activity, "Important I am");
             rootView.addView(text);
             childRef.set(text);
         });
@@ -230,8 +234,9 @@
         watcher.waitFor(RESUMED);
 
         // Remove view
+        final LinearLayout rootView = activity.getRootView();
         final TextView child = childRef.get();
-        activity.syncRunOnUiThread(() -> activity.getRootView().removeView(child));
+        activity.syncRunOnUiThread(() -> rootView.removeView(child));
 
         activity.finish();
         watcher.waitFor(DESTROYED);
@@ -243,19 +248,24 @@
         assertRightActivity(session, sessionId, activity);
 
         final List<ContentCaptureEvent> events = session.getEvents();
-        Log.v(TAG, "events: " + events);
-        // TODO(b/119638528): ideally it should be 3 so it reflects just the views defined
-        // in the layout - right now it's generating events for 2 intermediate parents
-        // (android:action_mode_bar_stub and android:content), we should try to create an
-        // activity without them
-        assertThat(events.size()).isAtLeast(5);
+        Log.v(TAG, "events(" + events.size() + "): " + events);
+
+        final AutofillId rootId = rootView.getAutofillId();
+
+        final View grandpa1 = activity.getGrandParent();
+        final View grandpa2 = activity.getGrandGrandParent();
+        final View decorView = activity.getDecorView();
 
         // Assert just the relevant events
-        final AutofillId rootId = activity.getRootView().getAutofillId();
-        assertViewAppeared(events, 0, sessionId, child, rootId);
-        assertViewWithUnknownParentAppeared(events, 1, sessionId, activity.getRootView());
-        // Ignore events 2 and 3 (intermediate parents appeared)
-        assertViewDisappeared(events, 4, child.getAutofillId());
+        assertThat(events.size()).isAtLeast(8);
+        assertViewHierarchyStarted(events, 0);
+        assertDecorViewAppeared(events, 1, decorView);
+        assertViewAppeared(events, 2, grandpa2, decorView.getAutofillId());
+        assertViewAppeared(events, 3, grandpa1, grandpa2.getAutofillId());
+        assertViewAppeared(events, 4, sessionId, rootView, grandpa1.getAutofillId());
+        assertViewAppeared(events, 5, sessionId, child, rootId);
+        assertViewHierarchyFinished(events, 6);
+        assertViewDisappeared(events, 7, child.getAutofillId());
     }
 
     @Test
@@ -266,8 +276,10 @@
         final ChildlessActivity activity = launchActivity();
         watcher.waitFor(RESUMED);
 
-        final TextView child = newImportantChild(activity, "Important I am");
-        activity.runOnUiThread(() -> activity.getRootView().addView(child));
+        // Add View
+        final LinearLayout rootView = activity.getRootView();
+        final TextView child = newImportantView(activity, "Important I am");
+        activity.runOnUiThread(() -> rootView.addView(child));
 
         activity.finish();
         watcher.waitFor(DESTROYED);
@@ -279,16 +291,18 @@
         assertRightActivity(session, sessionId, activity);
 
         final List<ContentCaptureEvent> events = session.getEvents();
-        Log.v(TAG, "events: " + events);
-        // TODO(b/119638958): ideally it should be 3 so it reflects just the views defined
-        // in the layout - right now it's generating events for 2 intermediate parents
-        // (android:action_mode_bar_stub and android:content), we should try to create an
-        // activity without them
-        assertThat(events.size()).isAtLeast(4);
+        Log.v(TAG, "events(" + events.size() + "): " + events);
+
+        final View grandpa = activity.getGrandParent();
 
         // Assert just the relevant events
-        final AutofillId rootId = activity.getRootView().getAutofillId();
-        assertViewAppeared(events, 0, sessionId, child, rootId);
+
+        // NOTE: there's no TYPE_INITIAL_VIEW_HIERARCHY_XXX events because there was no important
+        // view initially
+        assertThat(events.size()).isAtLeast(2);
+        // TODO(b/122959591): figure out the child is coming first
+        assertViewAppeared(events, 0, sessionId, child, rootView.getAutofillId());
+        assertViewAppeared(events, 1, sessionId, rootView, grandpa.getAutofillId());
     }
 
     @Test
@@ -299,7 +313,10 @@
         final ChildlessActivity activity = launchActivity();
         watcher.waitFor(RESUMED);
 
-        final ContentCaptureSession mainSession = activity.getRootView().getContentCaptureSession();
+        final LinearLayout rootView = activity.getRootView();
+        final View grandpa = activity.getGrandParent();
+
+        final ContentCaptureSession mainSession = rootView.getContentCaptureSession();
         final ContentCaptureSessionId mainSessionId = mainSession.getContentCaptureSessionId();
         Log.v(TAG, "main session id: " + mainSessionId);
 
@@ -309,9 +326,11 @@
         final ContentCaptureSessionId childSessionId = childSession.getContentCaptureSessionId();
         Log.v(TAG, "child session id: " + childSessionId);
 
-        final TextView child = newImportantChild(activity, "Important I am");
+        final TextView child = newImportantView(activity, "Important I am");
+        final AutofillId childId = child.getAutofillId();
+        Log.v(TAG, "childId: " + childId);
         child.setContentCaptureSession(childSession);
-        activity.runOnUiThread(() -> activity.getRootView().addView(child));
+        activity.runOnUiThread(() -> rootView.addView(child));
 
         activity.finish();
         watcher.waitFor(DESTROYED);
@@ -319,25 +338,26 @@
         final List<ContentCaptureSessionId> sessionIds = service.getAllSessionIds();
         assertThat(sessionIds).containsExactly(mainSessionId, childSessionId).inOrder();
 
+
         // Assert sessions
         final Session mainTestSession = service.getFinishedSession(mainSessionId);
         assertMainSessionContext(mainTestSession, activity);
         final List<ContentCaptureEvent> mainEvents = mainTestSession.getEvents();
-        // TODO(b/119638958): ideally it should have only one event for the root view ,
-        // right now it's generating events for 2 intermediate parents
-        // (android:action_mode_bar_stub and android:content), we should try to create an
-        // activity without them
-        assertThat(mainEvents.size()).isAtLeast(3);
-        assertViewWithUnknownParentAppeared(mainEvents, 0, mainSessionId, activity.getRootView());
+        Log.v(TAG, "mainEvents(" + mainEvents.size() + "): " + mainEvents);
+
+        // NOTE: there's no TYPE_INITIAL_VIEW_HIERARCHY_XXX events because there was no important
+        // view initially
+        assertThat(mainEvents.size()).isAtLeast(1);
+        assertViewAppeared(mainEvents, 0, mainSessionId, rootView, grandpa.getAutofillId());
 
         final Session childTestSession = service.getFinishedSession(childSessionId);
         assertChildSessionContext(childTestSession, "http://child");
         final List<ContentCaptureEvent> childEvents = childTestSession.getEvents();
+        Log.v(TAG, "childEvents(" + childEvents.size() + "): " + childEvents);
         final int minEvents = 1;
         assertThat(mainEvents.size()).isAtLeast(minEvents);
-        assertViewAppeared(childEvents, 0, childSessionId, child,
-                activity.getRootView().getAutofillId());
-        assertViewsOptionallyDisappeared(childEvents, minEvents, child.getAutofillId());
+        assertViewAppeared(childEvents, 0, childSessionId, child, rootView.getAutofillId());
+        assertViewsOptionallyDisappeared(childEvents, minEvents, childId);
     }
 
     /**
@@ -409,23 +429,36 @@
         // Assert main sessions info
         final Session mainTestSession = service.getFinishedSession(mainSessionId);
         assertMainSessionContext(mainTestSession, activity);
-        assertThat(mainTestSession.getEvents()).isEmpty();
 
         final Session childTestSession1 = service.getFinishedSession(childSessionId1);
         assertChildSessionContext(childTestSession1, "http://session1");
-        assertThat(childTestSession1.getEvents()).isEmpty();
 
         final Session childTestSession2 = service.getFinishedSession(childSessionId2);
         assertChildSessionContext(childTestSession2, "http://session2");
-        assertThat(childTestSession2.getEvents()).isEmpty();
 
         final Session childTestSession3 = service.getFinishedSession(childSessionId3);
         assertChildSessionContext(childTestSession3, "http://session3");
-        assertThat(childTestSession3.getEvents()).isEmpty();
 
         final Session childTestSession4 = service.getFinishedSession(childSessionId4);
         assertChildSessionContext(childTestSession4, "http://session4");
-        assertThat(childTestSession4.getEvents()).isEmpty();
+
+        // Gets all events first so they're all logged before the assertions
+        final List<ContentCaptureEvent> mainEvents = mainTestSession.getEvents();
+        final List<ContentCaptureEvent> events1 = childTestSession1.getEvents();
+        final List<ContentCaptureEvent> events2 = childTestSession2.getEvents();
+        final List<ContentCaptureEvent> events3 = childTestSession3.getEvents();
+        final List<ContentCaptureEvent> events4 = childTestSession4.getEvents();
+        Log.v(TAG, "mainEvents(" + mainEvents.size() + "): " + mainEvents);
+        Log.v(TAG, "events1(" + events1.size() + "): " + events1);
+        Log.v(TAG, "events2(" + events2.size() + "): " + events2);
+        Log.v(TAG, "events3(" + events3.size() + "): " + events3);
+        Log.v(TAG, "events4(" + events4.size() + "): " + events4);
+
+        assertThat(mainEvents).isEmpty();
+        assertThat(events1).isEmpty();
+        assertThat(events2).isEmpty();
+        assertThat(events3).isEmpty();
+        assertThat(events4).isEmpty();
 
         // Assert lifecycle methods were called in the right order
         assertLifecycleOrder(1, mainTestSession,   CREATION);
@@ -485,7 +518,7 @@
         // Assert main session
         final Session mainTestSession = service.getFinishedSession(mainSessionId);
         assertMainSessionContext(mainTestSession, activity);
-        // TODO(b/119638958): ideally it should be empty, but has intermediate parents stuff...
+        // TODO(b/123540067): ideally it should be empty, but has intermediate parents stuff...
         // assertThat(mainTestSession.getEvents()).isEmpty();
 
         // Assert child session
@@ -581,27 +614,35 @@
         // Assert main sessions info
         final Session mainTestSession = service.getFinishedSession(mainSessionId);
         assertMainSessionContext(mainTestSession, activity);
+        final List<ContentCaptureEvent> mainEvents = mainTestSession.getEvents();
+        Log.v(TAG, "main session events(" + mainEvents.size() + "): " + mainEvents);
 
+        // Gets all events first so they're all logged before the assertions
         final Session childTestSession1 = service.getFinishedSession(childSessionId1);
         assertChildSessionContext(childTestSession1, "http://session1");
         final List<ContentCaptureEvent> events1 = childTestSession1.getEvents();
-        Log.v(TAG, "events1: " + events1);
-        assertThat(events1.size()).isAtLeast(1);
-        final AutofillId rootId = activity.getRootView().getAutofillId();
-        assertViewAppeared(events1, 0, s1c1, rootId);
+        Log.v(TAG, "events1(" + events1.size() + "): " + events1);
 
         final Session childTestSession2 = service.getFinishedSession(childSessionId2);
         final List<ContentCaptureEvent> events2 = childTestSession2.getEvents();
         assertChildSessionContext(childTestSession2, "http://session2");
-        Log.v(TAG, "events2: " + events2);
+        Log.v(TAG, "events2(" + events2.size() + "): " + events2);
+        final Session childTestSession3 = service.getFinishedSession(childSessionId3);
+        assertChildSessionContext(childTestSession3, "http://session3");
+        List<ContentCaptureEvent> events3 = childTestSession3.getEvents();
+        Log.v(TAG, "events3(" + events3.size() + "): " + events3);
+
+        // TODO(b/123540067): ideally should be empty, but it has 2 grandparents
+        assertThat(mainEvents).hasSize(2);
+
+        assertThat(events1.size()).isAtLeast(1);
+        final AutofillId rootId = activity.getRootView().getAutofillId();
+        assertViewAppeared(events1, 0, s1c1, rootId);
+
         assertThat(events2.size()).isAtLeast(2);
         assertViewAppeared(events2, 0, s2c1, rootId);
         assertViewAppeared(events2, 1, s2c2, rootId);
 
-        final Session childTestSession3 = service.getFinishedSession(childSessionId3);
-        assertChildSessionContext(childTestSession3, "http://session3");
-        List<ContentCaptureEvent> events3 = childTestSession3.getEvents();
-        Log.v(TAG, "events3: " + events3);
         assertThat(events3.size()).isAtLeast(4);
         assertViewAppeared(events3, 0, s3c1, rootId);
         assertViewAppeared(events3, 1, s3c2, rootId);
@@ -848,20 +889,25 @@
         // Assert main sessions info
         final Session mainTestSession = service.getFinishedSession(mainSessionId);
         assertMainSessionContext(mainTestSession, activity);
+        final List<ContentCaptureEvent> mainEvents = mainTestSession.getEvents();
+        Log.v(TAG, "mainEvents(" + mainEvents.size() + "): " + mainEvents);
 
+        // Logs events before asserting
         final Session childTestSession1 = service.getFinishedSession(childSessionId1);
         assertChildSessionContext(childTestSession1, "http://session1");
         final List<ContentCaptureEvent> events1 = childTestSession1.getEvents();
-        Log.v(TAG, "events1: " + events1);
+        Log.v(TAG, "events1(" + events1.size() + "): " + events1);
+        final Session childTestSession2 = service.getFinishedSession(childSessionId2);
+        final List<ContentCaptureEvent> events2 = childTestSession2.getEvents();
+        assertChildSessionContext(childTestSession2, "http://session2");
+        Log.v(TAG, "events2(" + events2.size() + "): " + events2);
+
+        // Assert children
         assertThat(events1.size()).isAtLeast(2);
         final AutofillId rootId = activity.getRootView().getAutofillId();
         assertViewAppeared(events1, 0, s1c1, rootId);
         assertViewDisappeared(events1, 1, s1c1Id);
 
-        final Session childTestSession2 = service.getFinishedSession(childSessionId2);
-        final List<ContentCaptureEvent> events2 = childTestSession2.getEvents();
-        assertChildSessionContext(childTestSession2, "http://session2");
-        Log.v(TAG, "events2: " + events2);
         assertThat(events2.size()).isAtLeast(3);
         assertViewAppeared(events2, 0, s2c1, rootId);
         assertViewAppeared(events2, 1, s2c2, rootId);
@@ -876,16 +922,122 @@
      * - etc
      */
 
-    private TextView newImportantChild(@NonNull Context context, @NonNull String text) {
-        final TextView child = new TextView(context);
-        child.setText(text);
-        child.setImportantForContentCapture(View.IMPORTANT_FOR_CONTENT_CAPTURE_YES);
-        return child;
+    @Test
+    public void testIsContentCaptureFeatureEnabled_notService() throws Exception {
+        final ContentCaptureManager mgr = getContentCaptureManagerHack();
+        assertThrows(SecurityException.class,  () -> mgr.isContentCaptureFeatureEnabled());
     }
 
+    @Test
+    public void testSetContentCaptureFeatureEnabled_disabledBySettings() throws Exception {
+        setContentCaptureFeatureEnabledTest_disabled(/* bySettings= */ true);
+    }
+
+    private void setContentCaptureFeatureEnabledTest_disabled(boolean bySettings) throws Exception {
+        final ContentCaptureManager mgr = getContentCaptureManagerHack();
+
+        final CtsContentCaptureService service = enableService();
+        assertThat(mgr.isContentCaptureFeatureEnabled()).isTrue();
+        final DisconnectListener disconnectedListener = service.setOnDisconnectListener();
+
+        if (bySettings) {
+            setFeatureEnabled("false");
+        } else {
+            mgr.setContentCaptureFeatureEnabled(false);
+        }
+
+        disconnectedListener.waitForOnDisconnected();
+        assertThat(mgr.isContentCaptureFeatureEnabled()).isFalse();
+        assertThat(mgr.isContentCaptureEnabled()).isFalse();
+
+        final ActivityWatcher watcher = startWatcher();
+        final ChildlessActivity activity = launchActivity();
+
+        watcher.waitFor(RESUMED);
+        activity.finish();
+        watcher.waitFor(DESTROYED);
+
+        assertThat(service.getAllSessionIds()).isEmpty();
+    }
+
+    @Test
+    public void testSetContentCaptureFeatureEnabled_disabledThenReEnabledBySettings()
+            throws Exception {
+        setContentCaptureFeatureEnabledTest_disabledThenReEnabled(/* bySettings= */ true);
+    }
+
+    private void setContentCaptureFeatureEnabledTest_disabledThenReEnabled(boolean bySettings)
+            throws Exception {
+        final ContentCaptureManager mgr = getContentCaptureManagerHack();
+
+        final CtsContentCaptureService service1 = enableService();
+        assertThat(mgr.isContentCaptureFeatureEnabled()).isTrue();
+        final DisconnectListener disconnectedListener = service1.setOnDisconnectListener();
+
+        if (bySettings) {
+            setFeatureEnabled("false");
+        } else {
+            mgr.setContentCaptureFeatureEnabled(false);
+        }
+        disconnectedListener.waitForOnDisconnected();
+
+        assertThat(mgr.isContentCaptureFeatureEnabled()).isFalse();
+        assertThat(mgr.isContentCaptureEnabled()).isFalse();
+
+        // Launch and finish 1st activity while it's disabled
+        final ActivityWatcher watcher1 = startWatcher();
+        final ChildlessActivity activity1 = launchActivity();
+        watcher1.waitFor(RESUMED);
+        activity1.finish();
+        watcher1.waitFor(DESTROYED);
+
+        // Re-enable feature
+        final ServiceWatcher reconnectionWatcher = CtsContentCaptureService.setServiceWatcher();
+        if (bySettings) {
+            setFeatureEnabled("true");
+        } else {
+            mgr.setContentCaptureFeatureEnabled(true);
+        }
+        final CtsContentCaptureService service2 = reconnectionWatcher.waitOnCreate();
+        assertThat(mgr.isContentCaptureFeatureEnabled()).isTrue();
+
+        // Launch and finish 2nd activity while it's enabled
+        final ActivityLauncher<CustomViewActivity> launcher2 = new ActivityLauncher<>(
+                sContext, mActivitiesWatcher, CustomViewActivity.class);
+        final ActivityWatcher watcher2 = launcher2.getWatcher();
+        final CustomViewActivity activity2 = launcher2.launchActivity();
+        watcher2.waitFor(RESUMED);
+        activity2.finish();
+        watcher2.waitFor(DESTROYED);
+
+        assertThat(service1.getAllSessionIds()).isEmpty();
+        final Session session = service2.getOnlyFinishedSession();
+        activity2.assertDefaultEvents(session);
+    }
+
+    @Test
+    public void testSetContentCaptureFeatureEnabled_notService() throws Exception {
+        final ContentCaptureManager mgr = getContentCaptureManagerHack();
+        assertThrows(SecurityException.class,  () -> mgr.setContentCaptureFeatureEnabled(true));
+    }
+
+    @Test
+    public void testSetContentCaptureFeatureEnabled_disabledByApi() throws Exception {
+        setContentCaptureFeatureEnabledTest_disabled(/* bySettings= */ false);
+    }
+
+    @Test
+    public void testSetContentCaptureFeatureEnabled_disabledThenReEnabledByApi()
+            throws Exception {
+        setContentCaptureFeatureEnabledTest_disabledThenReEnabled(/* bySettings= */ false);
+    }
+
+    // TODO(b/123406031): add tests that mix feature_enabled with user_restriction_enabled (and
+    // make sure mgr.isContentCaptureFeatureEnabled() returns only the state of the 1st)
+
     private TextView addChild(@NonNull ChildlessActivity activity,
             @NonNull ContentCaptureSession session, @NonNull String text) {
-        final TextView child = newImportantChild(activity, text);
+        final TextView child = newImportantView(activity, text);
         child.setContentCaptureSession(session);
         Log.i(TAG, "adding " + child.getAutofillId() + " on session "
                 + session.getContentCaptureSessionId());
@@ -912,4 +1064,26 @@
             }
         });
     }
+
+    // TODO(b/120494182): temporary hack to get the manager, which currently is only available on
+    // Activity contexts (and would be null from sContext)
+    @NonNull
+    private ContentCaptureManager getContentCaptureManagerHack() throws InterruptedException {
+        final AtomicReference<ContentCaptureManager> ref = new AtomicReference<>();
+        LoginActivity.onRootView(
+                (activity, rootView) -> ref.set(activity.getContentCaptureManager()));
+
+        final ActivityLauncher<LoginActivity> launcher = new ActivityLauncher<>(
+                sContext, mActivitiesWatcher, LoginActivity.class);
+        final ActivityWatcher watcher = launcher.getWatcher();
+        final LoginActivity activity = launcher.launchActivity();
+        watcher.waitFor(RESUMED);
+        activity.finish();
+        watcher.waitFor(DESTROYED);
+
+        final ContentCaptureManager mgr = ref.get();
+        assertThat(mgr).isNotNull();
+
+        return mgr;
+    }
 }
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/ContentCaptureLoggingTestRule.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/ContentCaptureLoggingTestRule.java
index c5583cf..c7b831a 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/ContentCaptureLoggingTestRule.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/ContentCaptureLoggingTestRule.java
@@ -41,20 +41,15 @@
  */
 public class ContentCaptureLoggingTestRule implements TestRule, SafeCleanerRule.Dumper {
 
-    private final String mTag;
     private boolean mDumped;
 
-    public ContentCaptureLoggingTestRule(String tag) {
-        mTag = tag;
-    }
-
     @Override
     public Statement apply(Statement base, Description description) {
         return new Statement() {
 
             @Override
             public void evaluate() throws Throwable {
-                // TODO(b/119638958): set verbose logging once ContentCapture supports it
+                // TODO(b/121044306): set verbose logging once ContentCapture supports it
                 final String testName = description.getDisplayName();
                 try {
                     base.evaluate();
@@ -62,7 +57,7 @@
                     dump(testName, t);
                     throw t;
                 } finally {
-                    // TODO(b/119638958): recover logging level
+                    // TODO(b/121044306): recover logging level
                 }
             }
         };
@@ -71,7 +66,7 @@
     @Override
     public void dump(@NonNull String testName, @NonNull Throwable t) {
         if (mDumped) {
-            Log.e(mTag, "dump(" + testName + "): already dumped");
+            Log.e(TAG, "dump(" + testName + "): already dumped");
             return;
         }
         if ((t instanceof AssumptionViolatedException)) {
@@ -80,14 +75,14 @@
             Log.w(TAG, "ignoring exception: " + t);
             return;
         }
-        // TODO(b/119638958, b/120784831): should dump to a file (and integrate with tradefed)
+        // TODO(b/123540602, b/120784831): should dump to a file (and integrate with tradefed)
         // instead of outputting to log directly...
-        Log.e(mTag, "Dumping after exception on " + testName, t);
-        final String autofillDump = runShellCommand("dumpsys content_capture");
-        Log.e(mTag, "content_capture dump: \n" + autofillDump);
-        final String activityDump = runShellCommand(
-                "dumpsys activity " + MY_PACKAGE + " --contentcapture");
-        Log.e(mTag, "activity dump: \n" + activityDump);
+        Log.e(TAG, "Dumping after exception on " + testName, t);
+        final String serviceDump = runShellCommand("dumpsys content_capture");
+        Log.e(TAG, "content_capture dump: \n" + serviceDump);
+        final String activityDump = runShellCommand("dumpsys activity %s --contentcapture",
+                MY_PACKAGE);
+        Log.e(TAG, "activity dump: \n" + activityDump);
         mDumped = true;
     }
 }
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CtsContentCaptureService.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CtsContentCaptureService.java
index bbbbc0f..04213ba 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CtsContentCaptureService.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CtsContentCaptureService.java
@@ -41,7 +41,7 @@
 import java.util.List;
 import java.util.concurrent.CountDownLatch;
 
-// TODO(b/119638958): if we don't move this service to a separate package, we need to handle the
+// TODO(b/123540602): if we don't move this service to a separate package, we need to handle the
 // onXXXX methods in a separate thread
 // Either way, we need to make sure its methods are thread safe
 
@@ -54,11 +54,11 @@
     public static final ComponentName CONTENT_CAPTURE_SERVICE_COMPONENT_NAME =
             componentNameFor(CtsContentCaptureService.class);
 
+    private static int sIdCounter;
+
     private static ServiceWatcher sServiceWatcher;
 
-    // TODO(b/119638958): reuse with allSessions
-    /** Used by {@link #getOnlyFinishedSession()}. */
-    private static ContentCaptureSessionId sFirstSessionId;
+    private final int mId = ++sIdCounter;
 
     private static final ArrayList<Throwable> sExceptions = new ArrayList<>();
 
@@ -96,6 +96,12 @@
      */
     private UserDataRemovalRequest mRemovalRequest;
 
+    /**
+     * Optional listener for {@code onDisconnect()}.
+     */
+    @Nullable
+    private DisconnectListener mOnDisconnectListener;
+
     @NonNull
     public static ServiceWatcher setServiceWatcher() {
         if (sServiceWatcher != null) {
@@ -107,12 +113,11 @@
 
 
     public static void resetStaticState() {
-        sFirstSessionId = null;
         sExceptions.clear();
-        // TODO(b/119638958): should probably set sInstance to null as well, but first we would need
+        // TODO(b/123540602): should probably set sInstance to null as well, but first we would need
         // to make sure each test unbinds the service.
 
-        // TODO(b/119638958): each test should use a different service instance, but we need
+        // TODO(b/123540602): each test should use a different service instance, but we need
         // to provide onConnected() / onDisconnected() methods first and then change the infra so
         // we can wait for those
 
@@ -124,7 +129,7 @@
 
     @Override
     public void onConnected() {
-        Log.i(TAG, "onConnected(): sServiceWatcher=" + sServiceWatcher);
+        Log.i(TAG, "onConnected(id=" + mId + "): sServiceWatcher=" + sServiceWatcher);
 
         if (sServiceWatcher == null) {
             addException("onConnected() without a watcher");
@@ -147,7 +152,7 @@
 
     @Override
     public void onDisconnected() {
-        Log.i(TAG, "onDisconnected(): sServiceWatcher=" + sServiceWatcher);
+        Log.i(TAG, "onDisconnected(id=" + mId + "): sServiceWatcher=" + sServiceWatcher);
 
         if (mDisconnectedLatch.getCount() == 0) {
             addException("already disconnected: %s", mConnectedLatch);
@@ -162,6 +167,12 @@
             addException("onDisconnected(): no service on %s", sServiceWatcher);
             return;
         }
+        // Notify test case as well
+        if (mOnDisconnectListener != null) {
+            final CountDownLatch latch = mOnDisconnectListener.mLatch;
+            mOnDisconnectListener = null;
+            latch.countDown();
+        }
         sServiceWatcher.mDestroyed.countDown();
         sServiceWatcher.mService = null;
         sServiceWatcher = null;
@@ -184,12 +195,9 @@
     @Override
     public void onCreateContentCaptureSession(ContentCaptureContext context,
             ContentCaptureSessionId sessionId) {
-        Log.i(TAG, "onCreateContentCaptureSession(ctx=" + context + ", id=" + sessionId
-                + ", firstId=" + sFirstSessionId + ")");
+        Log.i(TAG, "onCreateContentCaptureSession(id=" + mId + ", ctx=" + context
+                + ", session=" + sessionId);
         mAllSessions.add(sessionId);
-        if (sFirstSessionId == null) {
-            sFirstSessionId = sessionId;
-        }
 
         safeRun(() -> {
             final Session session = mOpenSessions.get(sessionId);
@@ -204,7 +212,7 @@
 
     @Override
     public void onDestroyContentCaptureSession(ContentCaptureSessionId sessionId) {
-        Log.i(TAG, "onDestroyContentCaptureSession(" + sessionId + ")");
+        Log.i(TAG, "onDestroyContentCaptureSession(id=" + mId + ", session=" + sessionId + ")");
         safeRun(() -> {
             final Session session = getExistingSession(sessionId);
             session.finish();
@@ -222,7 +230,8 @@
     @Override
     public void onContentCaptureEvent(ContentCaptureSessionId sessionId,
             ContentCaptureEvent event) {
-        Log.i(TAG, "onContentCaptureEvent(" + sessionId + "): " + event);
+        Log.i(TAG, "onContentCaptureEventsRequest(id=" + mId + ", session=" + sessionId + "): "
+                + event);
         final ViewNode node = event.getViewNode();
         if (node != null) {
             Log.v(TAG, "onContentCaptureEvent(): parentId=" + node.getParentAutofillId());
@@ -235,7 +244,7 @@
 
     @Override
     public void onUserDataRemovalRequest(@NonNull UserDataRemovalRequest request) {
-        Log.i(TAG, "onUserDataRemovalRequest(" + request + ")");
+        Log.i(TAG, "onUserDataRemovalRequest(id=" + mId + ",req=" + request + ")");
         mRemovalRequest = request;
     }
 
@@ -271,9 +280,11 @@
      */
     @NonNull
     public Session getOnlyFinishedSession() throws InterruptedException {
-        // TODO(b/119638958): add some assertions to make sure There Can Be Only One!
-        assertWithMessage("No session yet").that(sFirstSessionId).isNotNull();
-        return getFinishedSession(sFirstSessionId);
+        final ArrayList<ContentCaptureSessionId> allSessions = mAllSessions;
+        assertWithMessage("Wrong number of sessions").that(allSessions).hasSize(1);
+        final ContentCaptureSessionId id = allSessions.get(0);
+        Log.d(TAG, "getOnlyFinishedSession(): id=" + id);
+        return getFinishedSession(id);
     }
 
     /**
@@ -284,13 +295,26 @@
         return Collections.unmodifiableList(mAllSessions);
     }
 
+    /**
+     * Sets a listener to wait until the service disconnects.
+     */
+    @NonNull
+    public DisconnectListener setOnDisconnectListener() {
+        if (mOnDisconnectListener != null) {
+            throw new IllegalStateException("already set");
+        }
+        mOnDisconnectListener = new DisconnectListener();
+        return mOnDisconnectListener;
+    }
+
     @Override
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         super.dump(fd, pw, args);
 
         pw.print("sServiceWatcher: "); pw.println(sServiceWatcher);
-        pw.print("sFirstSessionId: "); pw.println(sFirstSessionId);
         pw.print("sExceptions: "); pw.println(sExceptions);
+        pw.print("sIdCounter: "); pw.println(sIdCounter);
+        pw.print("mId: "); pw.println(mId);
         pw.print("mConnectedLatch: "); pw.println(mConnectedLatch);
         pw.print("mDisconnectedLatch: "); pw.println(mDisconnectedLatch);
         pw.print("mAllSessions: "); pw.println(mAllSessions);
@@ -318,6 +342,7 @@
 
     private void throwIllegalSessionStateException(@NonNull String fmt, @Nullable Object...args) {
         throw new IllegalStateException(String.format(fmt, args)
+                + ".\nID=" + mId
                 + ".\nAll=" + mAllSessions
                 + ".\nOpen=" + mOpenSessions
                 + ".\nLatches=" + mUnfinishedSessionLatches
@@ -372,7 +397,7 @@
             Log.d(TAG, "finish(" + id  + "): order=" + destructionOrder);
         }
 
-        // TODO(b/119638958): currently we're only interested on all events, but eventually we
+        // TODO(b/123540602): currently we're only interested on all events, but eventually we
         // should track individual requests as well to make sure they're probably batch (it will
         // require adding a Settings to tune the buffer parameters.
         public List<ContentCaptureEvent> getEvents() {
@@ -414,4 +439,22 @@
                     + " destroyed: " + (mDestroyed.getCount() == 0);
         }
     }
+
+    /**
+     * Listener used to block until the service is disconnected.
+     */
+    public class DisconnectListener {
+        private final CountDownLatch mLatch = new CountDownLatch(1);
+
+        /**
+         * Wait or die!
+         */
+        public void waitForOnDisconnected() {
+            try {
+                await(mLatch, "not disconnected");
+            } catch (Exception e) {
+                addException("DisconnectListener: onDisconnected() not called: " + e);
+            }
+        }
+    }
 }
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CustomViewActivity.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CustomViewActivity.java
index 5fb5fbf..33cd31f 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CustomViewActivity.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CustomViewActivity.java
@@ -15,8 +15,13 @@
  */
 package android.contentcaptureservice.cts;
 
+import static android.contentcaptureservice.cts.Assertions.assertDecorViewAppeared;
 import static android.contentcaptureservice.cts.Assertions.assertRightActivity;
+import static android.contentcaptureservice.cts.Assertions.assertViewAppeared;
+import static android.contentcaptureservice.cts.Assertions.assertViewHierarchyFinished;
+import static android.contentcaptureservice.cts.Assertions.assertViewHierarchyStarted;
 import static android.contentcaptureservice.cts.Assertions.assertViewWithUnknownParentAppeared;
+import static android.contentcaptureservice.cts.Assertions.assertViewsOptionallyDisappeared;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -24,6 +29,7 @@
 import android.contentcaptureservice.cts.common.DoubleVisitor;
 import android.os.Bundle;
 import android.util.Log;
+import android.view.View;
 import android.view.ViewStructure;
 import android.view.contentcapture.ContentCaptureEvent;
 
@@ -37,6 +43,14 @@
 
     private static DoubleVisitor<CustomView, ViewStructure> sCustomViewDelegate;
 
+    /**
+     * Mininum number of events generated when the activity starts.
+     *
+     * <p>Used on {@link #assertInitialViewsAppeared(Session, int)} and
+     * {@link #assertInitialViewsDisappeared(List, int)}.
+     */
+    public static final int MIN_EVENTS = 6;
+
     CustomView mCustomView;
 
     /**
@@ -63,15 +77,60 @@
     @Override
     public void assertDefaultEvents(@NonNull Session session) {
         assertRightActivity(session, session.id, this);
+        final int additionalEvents = 0;
+        final List<ContentCaptureEvent> events = assertInitialViewsAppeared(session,
+                additionalEvents);
+        Log.v(TAG, "events(" + events.size() + "): " + events);
+        assertInitialViewsDisappeared(events, additionalEvents);
+    }
+
+    /**
+     * Asserts the events generated when this activity was launched, up to the
+     * {@code TYPE_INITIAL_VIEW_HIERARCHY_FINISHED} event.
+     */
+    @NonNull
+    public List<ContentCaptureEvent> assertInitialViewsAppeared(Session session,
+            int additionalEvents) {
+        return assertJustInitialViewsAppeared(session, additionalEvents);
+    }
+
+    /**
+     * Asserts the events generated when this activity was launched, but without the
+     * {@code TYPE_INITIAL_VIEW_HIERARCHY_FINISHED} event.
+     */
+    @NonNull
+    private List<ContentCaptureEvent> assertJustInitialViewsAppeared(@NonNull Session session,
+            int additionalEvents) {
+        final View grandpa1 = (View) mCustomView.getParent();
+        final View grandpa2 = (View) grandpa1.getParent();
+        final View decorView = getDecorView();
+        Log.v(TAG, "assertJustInitialViewsAppeared(): grandpa1=" + grandpa1.getAutofillId()
+                + ", grandpa2=" + grandpa2.getAutofillId() + ", decor="
+                + decorView.getAutofillId());
 
         final List<ContentCaptureEvent> events = session.getEvents();
-        Log.v(TAG, "events: " + events);
-        // TODO(b/119638528): check right number once we get rid of grandparent
-        assertThat(events.size()).isAtLeast(1);
+        Log.v(TAG, "events(" + events.size() + "): " + events);
+        assertThat(events.size()).isAtLeast(MIN_EVENTS + additionalEvents);
 
         // Assert just the relevant events
-        assertViewWithUnknownParentAppeared(events, 0, session.id, mCustomView);
+        assertViewHierarchyStarted(events, 0);
+        assertDecorViewAppeared(events, 1, getDecorView());
+        assertViewAppeared(events, 2, grandpa2, decorView.getAutofillId());
+        assertViewAppeared(events, 3, grandpa1, grandpa2.getAutofillId());
+        assertViewWithUnknownParentAppeared(events, 4, session.id, mCustomView);
+        assertViewHierarchyFinished(events, 5);
 
-        // TODO(b/122315042): assert views disappeared
+        return events;
+    }
+
+    /**
+     * Asserts the initial views disappeared after the activity was finished.
+     */
+    // TODO(b/123540067, 122315042): fix and document or remove
+    public void assertInitialViewsDisappeared(@NonNull List<ContentCaptureEvent> events,
+            int additionalEvents) {
+        if (true) return;     // TODO(b/123540067, 122315042): not really working
+        assertViewsOptionallyDisappeared(events, MIN_EVENTS + additionalEvents,
+                getDecorView().getAutofillId(), mCustomView.getAutofillId());
     }
 }
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CustomViewActivityTest.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CustomViewActivityTest.java
index c7afd2a..0ab1425 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CustomViewActivityTest.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CustomViewActivityTest.java
@@ -15,7 +15,11 @@
  */
 package android.contentcaptureservice.cts;
 
+import static android.contentcaptureservice.cts.Assertions.assertDecorViewAppeared;
 import static android.contentcaptureservice.cts.Assertions.assertRightActivity;
+import static android.contentcaptureservice.cts.Assertions.assertViewAppeared;
+import static android.contentcaptureservice.cts.Assertions.assertViewHierarchyFinished;
+import static android.contentcaptureservice.cts.Assertions.assertViewHierarchyStarted;
 import static android.contentcaptureservice.cts.Assertions.assertViewWithUnknownParentAppeared;
 import static android.contentcaptureservice.cts.Assertions.assertVirtualViewAppeared;
 import static android.contentcaptureservice.cts.Assertions.assertVirtualViewDisappeared;
@@ -31,8 +35,10 @@
 import android.contentcaptureservice.cts.common.DoubleVisitor;
 import android.os.Handler;
 import android.os.Looper;
+import android.platform.test.annotations.AppModeFull;
 import android.support.test.rule.ActivityTestRule;
 import android.util.Log;
+import android.view.View;
 import android.view.ViewStructure;
 import android.view.autofill.AutofillId;
 import android.view.contentcapture.ContentCaptureEvent;
@@ -46,6 +52,7 @@
 import java.util.List;
 import java.util.concurrent.CountDownLatch;
 
+@AppModeFull(reason = "BlankWithTitleActivityTest is enough")
 public class CustomViewActivityTest extends
         AbstractContentCaptureIntegrationTest<CustomViewActivity> {
 
@@ -121,22 +128,36 @@
 
         assertRightActivity(session, session.id, activity);
 
+        final View grandpa1 = (View) activity.mCustomView.getParent();
+        final View grandpa2 = (View) grandpa1.getParent();
+        final View decorView = activity.getDecorView();
+        final AutofillId customViewId = activity.mCustomView.getAutofillId();
+        Log.v(TAG, "assertJustInitialViewsAppeared(): grandpa1=" + grandpa1.getAutofillId()
+                + ", grandpa2=" + grandpa2.getAutofillId() + ", decor="
+                + decorView.getAutofillId() + "customView=" + customViewId);
+
         final List<ContentCaptureEvent> events = session.getEvents();
-        Log.v(TAG, "events: " + events);
-        // TODO(b/119638528): check right number once we get rid of grandparent
-        assertThat(events.size()).isAtLeast(3);
+        Log.v(TAG, "events(" + events.size() + "): " + events);
+        final int additionalEvents = 2;
+
+        assertThat(events.size()).isAtLeast(CustomViewActivity.MIN_EVENTS + additionalEvents);
 
         // Assert just the relevant events
-        final AutofillId customViewId = activity.mCustomView.getAutofillId();
-        final ContentCaptureSession mainSession = activity.mCustomView.getContentCaptureSession();
+        assertViewHierarchyStarted(events, 0);
+        assertDecorViewAppeared(events, 1, decorView);
+        assertViewAppeared(events, 2, grandpa2, decorView.getAutofillId());
+        assertViewAppeared(events, 3, grandpa1, grandpa2.getAutofillId());
 
-        assertVirtualViewAppeared(events, 0, mainSession, customViewId, 1, "child");
-        assertVirtualViewDisappeared(events, 1, customViewId, mainSession, 1);
+        final ContentCaptureSession mainSession = activity.mCustomView.getContentCaptureSession();
+        assertVirtualViewAppeared(events, 4, mainSession, customViewId, 1, "child");
+        assertVirtualViewDisappeared(events, 5, customViewId, mainSession, 1);
 
         // This is the "wrong" part - the parent is notified last
-        assertViewWithUnknownParentAppeared(events, 2, session.id, activity.mCustomView);
+        assertViewWithUnknownParentAppeared(events, 6, session.id, activity.mCustomView);
 
-        // TODO(b/122315042): assert views disappeared
+        assertViewHierarchyFinished(events, 7);
+
+        activity.assertInitialViewsDisappeared(events, additionalEvents);
     }
 
     /**
@@ -183,21 +204,20 @@
 
         assertRightActivity(session, session.id, activity);
 
-        final List<ContentCaptureEvent> events = session.getEvents();
-        Log.v(TAG, "events: " + events);
-        // TODO(b/119638528): check right number once we get rid of grandparent
-        assertThat(events.size()).isAtLeast(6);
+        final int additionalEvents = 3;
+        final List<ContentCaptureEvent> events = activity.assertInitialViewsAppeared(session,
+                additionalEvents);
 
-        // Assert just the relevant events
         final AutofillId customViewId = activity.mCustomView.getAutofillId();
         final ContentCaptureSession mainSession = activity.mCustomView.getContentCaptureSession();
 
-        assertViewWithUnknownParentAppeared(events, 0, session.id, activity.mCustomView);
-        // TODO(b/119638528): next 2 events are the grandparents
-        assertVirtualViewAppeared(events, 3, mainSession, customViewId, 1, "child1");
-        assertVirtualViewAppeared(events, 4, mainSession, customViewId, 2, "child2");
-        assertVirtualViewsDisappeared(events, 5, customViewId, mainSession, 2, 1);
+        final int i = CustomViewActivity.MIN_EVENTS;
 
+        assertVirtualViewAppeared(events, i, mainSession, customViewId, 1, "child1");
+        assertVirtualViewAppeared(events, i + 1, mainSession, customViewId, 2, "child2");
+        assertVirtualViewsDisappeared(events, i + 2, customViewId, mainSession, 2, 1);
+
+        activity.assertInitialViewsDisappeared(events, additionalEvents);
         // TODO(b/122315042): assert views disappeared
     }
 
@@ -297,26 +317,25 @@
 
         assertRightActivity(session, session.id, activity);
 
-        final List<ContentCaptureEvent> events = session.getEvents();
-        Log.v(TAG, "events: " + events);
-        // TODO(b/119638528): check right number once we get rid of grandparents
-        assertThat(events.size()).isAtLeast(11);
+        final int additionalEvents = 7;
+        final List<ContentCaptureEvent> events = activity.assertInitialViewsAppeared(session,
+                additionalEvents);
 
-        // Assert just the relevant events
         final AutofillId customViewId = activity.mCustomView.getAutofillId();
         final ContentCaptureSession mainSession = activity.mCustomView.getContentCaptureSession();
 
-        assertViewWithUnknownParentAppeared(events, 0, session.id, activity.mCustomView);
-        // TODO(b/119638528): next 2 events are the grandparents
-        assertVirtualViewAppeared(events, 3, mainSession, customViewId, 1, "c1");
-        assertVirtualViewAppeared(events, 4, mainSession, customViewId, 11, "c1g1");
-        assertVirtualViewAppeared(events, 5, mainSession, customViewId, 12, "c1g2");
-        assertVirtualViewAppeared(events, 6, mainSession, customViewId, 2, "c2");
-        assertVirtualViewAppeared(events, 7, mainSession, customViewId, 21, "c2g1");
-        assertVirtualViewAppeared(events, 8, mainSession, customViewId, 211, "c2g1gg1");
-        assertVirtualViewAppeared(events, 9, mainSession, customViewId, 3, "c3");
-        assertVirtualViewsDisappeared(events, 10, customViewId, mainSession, 21, 2, 11, 1, 12);
+        final int i = CustomViewActivity.MIN_EVENTS;
 
+        assertVirtualViewAppeared(events, i, mainSession, customViewId, 1, "c1");
+        assertVirtualViewAppeared(events, i + 1, mainSession, customViewId, 11, "c1g1");
+        assertVirtualViewAppeared(events, i + 2, mainSession, customViewId, 12, "c1g2");
+        assertVirtualViewAppeared(events, i + 3, mainSession, customViewId, 2, "c2");
+        assertVirtualViewAppeared(events, i + 4, mainSession, customViewId, 21, "c2g1");
+        assertVirtualViewAppeared(events, i + 5, mainSession, customViewId, 211, "c2g1gg1");
+        assertVirtualViewAppeared(events, i + 6, mainSession, customViewId, 3, "c3");
+        assertVirtualViewsDisappeared(events, i + 7, customViewId, mainSession, 21, 2, 11, 1, 12);
+
+        activity.assertInitialViewsDisappeared(events, additionalEvents);
         // TODO(b/122315042): assert other views disappeared
     }
 
@@ -363,21 +382,21 @@
 
         assertRightActivity(session, session.id, activity);
 
-        final List<ContentCaptureEvent> events = session.getEvents();
-        Log.v(TAG, "events: " + events);
-        // TODO(b/119638528): check right number once we get rid of grandparent (should be 5)
-        assertThat(events.size()).isAtLeast(6);
 
-        // Assert just the relevant events
+        final int additionalEvents = 3;
+        final List<ContentCaptureEvent> events = activity.assertInitialViewsAppeared(session,
+                additionalEvents);
+
         final AutofillId customViewId = activity.mCustomView.getAutofillId();
         final ContentCaptureSession mainSession = activity.mCustomView.getContentCaptureSession();
 
-        assertViewWithUnknownParentAppeared(events, 0, session.id, activity.mCustomView);
-        // TODO(b/119638528): next 2 events are the grandparents
-        assertVirtualViewAppeared(events, 3, mainSession, customViewId, 1, "child1");
-        assertVirtualViewAppeared(events, 4, mainSession, customViewId, 2, "child2");
-        assertVirtualViewsDisappeared(events, 5, customViewId, mainSession, 2, 1);
+        final int i = CustomViewActivity.MIN_EVENTS;
 
+        assertVirtualViewAppeared(events, i, mainSession, customViewId, 1, "child1");
+        assertVirtualViewAppeared(events, i + 1, mainSession, customViewId, 2, "child2");
+        assertVirtualViewsDisappeared(events, i + 2, customViewId, mainSession, 2, 1);
+
+        activity.assertInitialViewsDisappeared(events, additionalEvents);
         // TODO(b/122315042): assert other views disappeared
     }
 
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/Helper.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/Helper.java
index 728ee82..30ba124 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/Helper.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/Helper.java
@@ -18,8 +18,11 @@
 import static android.contentcaptureservice.cts.common.ShellHelper.runShellCommand;
 
 import android.content.ComponentName;
+import android.content.Context;
 import android.os.SystemClock;
 import android.util.Log;
+import android.view.View;
+import android.widget.TextView;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
@@ -58,7 +61,7 @@
      */
     public static void setService(@NonNull String service) {
         Log.d(TAG, "Setting service to " + service);
-        // TODO(b/119638958): use @TestingAPI to get max duration constant
+        // TODO(b/123540602): use @TestingAPI to get max duration constant
         runShellCommand("cmd content_capture set temporary-service 0 " + service + " 12000");
     }
 
@@ -71,12 +74,31 @@
     }
 
     /**
+     * Enables / disables the default service.
+     */
+    public static void setDefaultServiceEnabled(boolean enabled) {
+        Log.d(TAG, "setDefaultServiceEnabled(): " + enabled);
+        runShellCommand("cmd content_capture set default-service-enabled 0 %s",
+                Boolean.toString(enabled));
+    }
+
+    /**
      * Gets the component name for a given class.
      */
     public static ComponentName componentNameFor(@NonNull Class<?> clazz) {
         return new ComponentName(MY_PACKAGE, clazz.getName());
     }
 
+    /**
+     * Creates a view that can be added to a parent and is important for content capture
+     */
+    public static TextView newImportantView(@NonNull Context context, @NonNull String text) {
+        final TextView child = new TextView(context);
+        child.setText(text);
+        child.setImportantForContentCapture(View.IMPORTANT_FOR_CONTENT_CAPTURE_YES);
+        return child;
+    }
+
     private Helper() {
         throw new UnsupportedOperationException("contain static methods only");
     }
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/LoginActivity.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/LoginActivity.java
index fc9efbd..f28f19c 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/LoginActivity.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/LoginActivity.java
@@ -15,9 +15,12 @@
  */
 package android.contentcaptureservice.cts;
 
+import static android.contentcaptureservice.cts.Assertions.assertDecorViewAppeared;
 import static android.contentcaptureservice.cts.Assertions.assertRightActivity;
 import static android.contentcaptureservice.cts.Assertions.assertSessionId;
 import static android.contentcaptureservice.cts.Assertions.assertViewAppeared;
+import static android.contentcaptureservice.cts.Assertions.assertViewHierarchyFinished;
+import static android.contentcaptureservice.cts.Assertions.assertViewHierarchyStarted;
 import static android.contentcaptureservice.cts.Assertions.assertViewsOptionallyDisappeared;
 
 import static com.google.common.truth.Truth.assertThat;
@@ -40,6 +43,14 @@
 
     private static final String TAG = LoginActivity.class.getSimpleName();
 
+    /**
+     * Mininum number of events generated when the activity starts.
+     *
+     * <p>Used on {@link #assertInitialViewsAppeared(Session, int)} and
+     * {@link #assertInitialViewsDisappeared(List, int)}.
+     */
+    public static final int MIN_EVENTS = 10;
+
     TextView mUsernameLabel;
     EditText mUsername;
     TextView mPasswordLabel;
@@ -57,6 +68,33 @@
 
     @Override
     public void assertDefaultEvents(@NonNull Session session) {
+        final int additionalEvents = 0;
+        final List<ContentCaptureEvent> events = assertInitialViewsAppeared(session,
+                additionalEvents);
+        assertInitialViewsDisappeared(events, additionalEvents);
+    }
+
+    /**
+     * Asserts the events generated when this activity was launched, up to the
+     * {@code TYPE_INITIAL_VIEW_HIERARCHY_FINISHED} event.
+     */
+    @NonNull
+    public List<ContentCaptureEvent> assertInitialViewsAppeared(@NonNull Session session,
+            int additionalEvents) {
+        final List<ContentCaptureEvent> events = assertJustInitialViewsAppeared(session,
+                additionalEvents);
+        assertViewHierarchyFinished(events, MIN_EVENTS - 1);
+
+        return events;
+    }
+
+    /**
+     * Asserts the events generated when this activity was launched, but without the
+     * {@code TYPE_INITIAL_VIEW_HIERARCHY_FINISHED} event.
+     */
+    @NonNull
+    public List<ContentCaptureEvent> assertJustInitialViewsAppeared(@NonNull Session session,
+            int additionalEvents) {
         final LoginActivity activity = this;
         final ContentCaptureSessionId sessionId = session.id;
         assertRightActivity(session, sessionId, activity);
@@ -68,39 +106,65 @@
         assertSessionId(sessionId, activity.mPasswordLabel);
 
         final List<ContentCaptureEvent> events = session.getEvents();
-        Log.v(mTag, "events: " + events);
-        // TODO(b/119638528): ideally it should be 5 so it reflects just the views defined
+        Log.v(TAG, "events(" + events.size() + "): " + events);
+        // TODO(b/123540067): ideally it should be X so it reflects just the views defined
         // in the layout - right now it's generating events for 2 intermediate parents
         // (android:action_mode_bar_stub and android:content), we should try to create an
         // activity without them
 
         final AutofillId rootId = activity.getRootView().getAutofillId();
 
-        final int minEvents = 7;
-        assertThat(events.size()).isAtLeast(minEvents);
-        assertViewAppeared(events, 0, sessionId, activity.mUsernameLabel, rootId);
-        assertViewAppeared(events, 1, sessionId, activity.mUsername, rootId);
-        assertViewAppeared(events, 2, sessionId, activity.mPasswordLabel, rootId);
-        assertViewAppeared(events, 3, sessionId, activity.mPassword, rootId);
+        assertThat(events.size()).isAtLeast(MIN_EVENTS + additionalEvents);
 
-        // TODO(b/119638528): get rid of those intermediated parents
+        // TODO(b/123540067): get rid of those intermediated parents
         final View grandpa1 = activity.getGrandParent();
         final View grandpa2 = activity.getGrandGrandParent();
         final View decorView = activity.getDecorView();
+        final View rootView = activity.getRootView();
 
-        assertViewAppeared(events, 4, sessionId, activity.getRootView(),
-                grandpa1.getAutofillId());
-        assertViewAppeared(events, 5, grandpa1, grandpa2.getAutofillId());
-        assertViewAppeared(events, 6, grandpa2, decorView.getAutofillId());
+        assertViewHierarchyStarted(events, 0);
+        assertDecorViewAppeared(events, 1, decorView);
+        assertViewAppeared(events, 2, grandpa2, decorView.getAutofillId());
+        assertViewAppeared(events, 3, grandpa1, grandpa2.getAutofillId());
+        assertViewAppeared(events, 4, sessionId, rootView, grandpa1.getAutofillId());
+        assertViewAppeared(events, 5, sessionId, activity.mUsernameLabel, rootId);
+        assertViewAppeared(events, 6, sessionId, activity.mUsername, rootId);
+        assertViewAppeared(events, 7, sessionId, activity.mPasswordLabel, rootId);
+        assertViewAppeared(events, 8, sessionId, activity.mPassword, rootId);
 
-        assertViewsOptionallyDisappeared(events, minEvents,
-                rootId,
-                grandpa1.getAutofillId(), grandpa2.getAutofillId(),
-                // decorView.getAutofillId(), // TODO(b/122315042): figure out why it's not
-                // generated
-                activity.mUsernameLabel.getAutofillId(), activity.mUsername.getAutofillId(),
-                activity.mPasswordLabel.getAutofillId(), activity.mPassword.getAutofillId()
-        );
+        return events;
+    }
+
+    /**
+     * Asserts the initial views disappeared after the activity was finished.
+     */
+    public void assertInitialViewsDisappeared(@NonNull List<ContentCaptureEvent> events,
+            int additionalEvents) {
+        final LoginActivity activity = this;
+        final AutofillId rootId = activity.getRootView().getAutofillId();
+        final View decorView = activity.getDecorView();
+        final View grandpa1 = activity.getGrandParent();
+        final View grandpa2 = activity.getGrandGrandParent();
+
+
+        // TODO(b/122315042): sometimes we get decor view disappareared events, sometimes we don't
+        // As we don't really care about those, let's fix it!
+        try {
+            assertViewsOptionallyDisappeared(events, MIN_EVENTS + additionalEvents,
+                    rootId,
+                    grandpa1.getAutofillId(), grandpa2.getAutofillId(),
+                    activity.mUsernameLabel.getAutofillId(), activity.mUsername.getAutofillId(),
+                    activity.mPasswordLabel.getAutofillId(), activity.mPassword.getAutofillId());
+        } catch (AssertionError e) {
+            Log.e(TAG, "Hack-ignoring assertion without decor view: " + e);
+            // Try again removing it...
+            assertViewsOptionallyDisappeared(events, MIN_EVENTS + additionalEvents,
+                    rootId,
+                    grandpa1.getAutofillId(), grandpa2.getAutofillId(),
+                    decorView.getAutofillId(),
+                    activity.mUsernameLabel.getAutofillId(), activity.mUsername.getAutofillId(),
+                    activity.mPasswordLabel.getAutofillId(), activity.mPassword.getAutofillId());
+        }
     }
 
     @Override
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/LoginActivityTest.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/LoginActivityTest.java
index 379f28f..926f63a 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/LoginActivityTest.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/LoginActivityTest.java
@@ -16,15 +16,18 @@
 package android.contentcaptureservice.cts;
 
 import static android.contentcaptureservice.cts.Assertions.assertChildSessionContext;
+import static android.contentcaptureservice.cts.Assertions.assertDecorViewAppeared;
 import static android.contentcaptureservice.cts.Assertions.assertMainSessionContext;
 import static android.contentcaptureservice.cts.Assertions.assertRightActivity;
 import static android.contentcaptureservice.cts.Assertions.assertRightRelationship;
 import static android.contentcaptureservice.cts.Assertions.assertSessionId;
 import static android.contentcaptureservice.cts.Assertions.assertViewAppeared;
+import static android.contentcaptureservice.cts.Assertions.assertViewHierarchyFinished;
+import static android.contentcaptureservice.cts.Assertions.assertViewHierarchyStarted;
 import static android.contentcaptureservice.cts.Assertions.assertViewTextChanged;
 import static android.contentcaptureservice.cts.Assertions.assertViewsOptionallyDisappeared;
 import static android.contentcaptureservice.cts.Helper.MY_PACKAGE;
-import static android.contentcaptureservice.cts.Helper.componentNameFor;
+import static android.contentcaptureservice.cts.Helper.newImportantView;
 import static android.contentcaptureservice.cts.common.ActivitiesWatcher.ActivityLifecycle.DESTROYED;
 import static android.contentcaptureservice.cts.common.ActivitiesWatcher.ActivityLifecycle.RESUMED;
 
@@ -32,8 +35,10 @@
 
 import android.contentcaptureservice.cts.CtsContentCaptureService.Session;
 import android.contentcaptureservice.cts.common.ActivitiesWatcher.ActivityWatcher;
+import android.contentcaptureservice.cts.common.DoubleVisitor;
 import android.net.Uri;
 import android.os.Bundle;
+import android.platform.test.annotations.AppModeFull;
 import android.support.test.rule.ActivityTestRule;
 import android.util.Log;
 import android.view.View;
@@ -44,16 +49,18 @@
 import android.view.contentcapture.ContentCaptureSession;
 import android.view.contentcapture.ContentCaptureSessionId;
 import android.view.contentcapture.UserDataRemovalRequest;
+import android.view.contentcapture.UserDataRemovalRequest.UriRequest;
+import android.widget.LinearLayout;
+import android.widget.TextView;
 
 import org.junit.After;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 
 import java.util.List;
 import java.util.concurrent.atomic.AtomicReference;
-import java.util.stream.Collectors;
 
+@AppModeFull(reason = "BlankWithTitleActivityTest is enough")
 public class LoginActivityTest extends AbstractContentCaptureIntegrationTest<LoginActivity> {
 
     private static final String TAG = LoginActivityTest.class.getSimpleName();
@@ -93,7 +100,6 @@
         activity.assertDefaultEvents(session);
     }
 
-
     @Test
     public void testSimpleLifecycle_rootViewSession() throws Exception {
         final CtsContentCaptureService service = enableService();
@@ -157,23 +163,22 @@
 
         // Check events
         final List<ContentCaptureEvent> mainEvents = mainSession.getEvents();
-        Log.v(TAG, "events for main session: " + mainEvents);
+        Log.v(TAG, "events(" + mainEvents.size() + ") for main session: " + mainEvents);
 
-        // TODO(b/119638528): ideally it should be empty - right now it's generating events for 2
-        // intermediate parents (android:action_mode_bar_stub and android:content), we should try to
-        // create an activity without them
-        final int minMainEvents = 2;
-        assertThat(mainEvents.size()).isAtLeast(minMainEvents);
         final View grandpa1 = activity.getGrandParent();
         final View grandpa2 = activity.getGrandGrandParent();
         final View decorView = activity.getDecorView();
-        assertViewAppeared(mainEvents, 0, grandpa1, grandpa2.getAutofillId());
-        assertViewAppeared(mainEvents, 1, grandpa2, decorView.getAutofillId());
-        assertViewsOptionallyDisappeared(mainEvents, minMainEvents,
-                grandpa1.getAutofillId(), grandpa2.getAutofillId()
-                // decorView.getAutofillId(), // TODO(b/122315042): figure out why it's not
-                // generated
-        );
+        final AutofillId rootId = activity.getRootView().getAutofillId();
+
+        final int minEvents = 5; // TODO(b/122315042): disappeared not always sent
+        assertThat(mainEvents.size()).isAtLeast(minEvents);
+        assertViewHierarchyStarted(mainEvents, 0);
+        assertDecorViewAppeared(mainEvents, 1, decorView);
+        assertViewAppeared(mainEvents, 2, grandpa2, decorView.getAutofillId());
+        assertViewAppeared(mainEvents, 3, grandpa1, grandpa2.getAutofillId());
+        assertViewHierarchyFinished(mainEvents, 4);
+        assertViewsOptionallyDisappeared(mainEvents, 5, decorView.getAutofillId(),
+                grandpa2.getAutofillId(), grandpa1.getAutofillId());
 
         /*
          *  Asserts child session
@@ -189,15 +194,15 @@
         // Check events
         final List<ContentCaptureEvent> childEvents = childSession.getEvents();
         Log.v(TAG, "events for child session: " + childEvents);
-        final AutofillId rootId = activity.getRootView().getAutofillId();
         final int minChildEvents = 5;
         assertThat(childEvents.size()).isAtLeast(minChildEvents);
-        assertViewAppeared(childEvents, 0, childSessionId, activity.mUsernameLabel, rootId);
-        assertViewAppeared(childEvents, 1, childSessionId, activity.mUsername, rootId);
-        assertViewAppeared(childEvents, 2, childSessionId, activity.mPasswordLabel, rootId);
-        assertViewAppeared(childEvents, 3, childSessionId, activity.mPassword, rootId);
-        assertViewAppeared(childEvents, 4, childSessionId, activity.getRootView(),
+        assertViewAppeared(childEvents, 0, childSessionId, activity.getRootView(),
                 grandpa1.getAutofillId());
+        assertViewAppeared(childEvents, 1, childSessionId, activity.mUsernameLabel, rootId);
+        assertViewAppeared(childEvents, 2, childSessionId, activity.mUsername, rootId);
+        assertViewAppeared(childEvents, 3, childSessionId, activity.mPasswordLabel, rootId);
+        assertViewAppeared(childEvents, 4, childSessionId, activity.mPassword, rootId);
+
         assertViewsOptionallyDisappeared(childEvents, minChildEvents,
                 rootId,
                 activity.mUsernameLabel.getAutofillId(), activity.mUsername.getAutofillId(),
@@ -205,29 +210,6 @@
         );
     }
 
-    @Ignore("not implemented yet, pending on b/122595322")
-    @Test
-    public void testSimpleLifecycle_serviceDisabledActivity() throws Exception {
-        final CtsContentCaptureService service = enableService();
-        final ActivityWatcher watcher = startWatcher();
-
-        // Disable activity
-        service.setActivityContentCaptureEnabled(componentNameFor(LoginActivity.class), false);
-
-        final LoginActivity activity = launchActivity();
-        watcher.waitFor(RESUMED);
-
-        activity.finish();
-        watcher.waitFor(DESTROYED);
-
-        final List<ContentCaptureSessionId> sessionIds = service.getAllSessionIds();
-        assertThat(sessionIds).isEmpty();
-
-        // TODO(b/122595322): should also test events after re-enabling it
-    }
-
-    // TODO(b/122595322): same tests for disabled by package, explicity whitelisted, etc...
-
     @Test
     public void testTextChanged() throws Exception {
         final CtsContentCaptureService service = enableService();
@@ -252,38 +234,16 @@
 
         assertRightActivity(session, sessionId, activity);
 
-        final List<ContentCaptureEvent> events = session.getEvents();
-        Log.v(TAG, "events: " + events);
+        final int additionalEvents = 2;
+        final List<ContentCaptureEvent> events = activity.assertInitialViewsAppeared(session,
+                additionalEvents);
 
-        final AutofillId rootId = activity.getRootView().getAutofillId();
+        final int i = LoginActivity.MIN_EVENTS;
 
-        final int minEvents = 9;
-        assertThat(events.size()).isAtLeast(minEvents);
+        assertViewTextChanged(events, i, activity.mUsername.getAutofillId(), "USER");
+        assertViewTextChanged(events, i + 1, activity.mPassword.getAutofillId(), "PASS");
 
-        assertViewAppeared(events, 0, activity.mUsernameLabel, rootId);
-        assertViewAppeared(events, 1, activity.mUsername, rootId, "user");
-        assertViewAppeared(events, 2, activity.mPasswordLabel, rootId);
-        assertViewAppeared(events, 3, activity.mPassword, rootId, "");
-        // TODO(b/119638528): get rid of those intermediated parents
-        final View grandpa1 = activity.getGrandParent();
-        final View grandpa2 = activity.getGrandGrandParent();
-        final View decorView = activity.getDecorView();
-
-        assertViewAppeared(events, 4, activity.getRootView(), grandpa1.getAutofillId());
-        assertViewAppeared(events, 5, grandpa1, grandpa2.getAutofillId());
-        assertViewAppeared(events, 6, grandpa2, decorView.getAutofillId());
-
-        assertViewTextChanged(events, 7, activity.mUsername.getAutofillId(), "USER");
-        assertViewTextChanged(events, 8, activity.mPassword.getAutofillId(), "PASS");
-
-        assertViewsOptionallyDisappeared(events, minEvents,
-                rootId,
-                grandpa1.getAutofillId(), grandpa2.getAutofillId(),
-                // decorView.getAutofillId(), // TODO(b/122315042): figure out why it's not
-                // generated
-                activity.mUsernameLabel.getAutofillId(), activity.mUsername.getAutofillId(),
-                activity.mPasswordLabel.getAutofillId(), activity.mPassword.getAutofillId()
-        );
+        activity.assertInitialViewsDisappeared(events, additionalEvents);
     }
 
     @Test
@@ -315,38 +275,17 @@
 
         assertRightActivity(session, sessionId, activity);
 
-        final List<ContentCaptureEvent> events = session.getEvents();
-        Log.v(TAG, "events: " + events);
+        final int additionalEvents = 3;
+        final List<ContentCaptureEvent> events = activity.assertInitialViewsAppeared(session,
+                additionalEvents);
 
-        final AutofillId rootId = activity.getRootView().getAutofillId();
+        final int i = LoginActivity.MIN_EVENTS;
 
-        final int minEvents = 10;
-        assertThat(events.size()).isAtLeast(minEvents);
+        assertViewTextChanged(events, i, activity.mUsername.getAutofillId(), "ab");
+        assertViewTextChanged(events, i + 1, activity.mPassword.getAutofillId(), "de");
+        assertViewTextChanged(events, i + 2, activity.mUsername.getAutofillId(), "abc");
 
-        assertViewAppeared(events, 0, activity.mUsernameLabel, rootId);
-        assertViewAppeared(events, 1, activity.mUsername, rootId, "");
-        assertViewAppeared(events, 2, activity.mPasswordLabel, rootId);
-        assertViewAppeared(events, 3, activity.mPassword, rootId, "");
-        // TODO(b/119638528): get rid of those intermediated parents
-        final View grandpa1 = activity.getGrandParent();
-        final View grandpa2 = activity.getGrandGrandParent();
-        final View decorView = activity.getDecorView();
-
-        assertViewAppeared(events, 4, activity.getRootView(), grandpa1.getAutofillId());
-        assertViewAppeared(events, 5, grandpa1, grandpa2.getAutofillId());
-        assertViewAppeared(events, 6, grandpa2, decorView.getAutofillId());
-
-        assertViewTextChanged(events, 7, activity.mUsername.getAutofillId(), "ab");
-        assertViewTextChanged(events, 8, activity.mPassword.getAutofillId(), "de");
-        assertViewTextChanged(events, 9, activity.mUsername.getAutofillId(), "abc");
-
-        assertViewsOptionallyDisappeared(events, minEvents,
-                rootId,
-                grandpa1.getAutofillId(),
-                grandpa2.getAutofillId(),
-                activity.mUsernameLabel.getAutofillId(), activity.mUsername.getAutofillId(),
-                activity.mPasswordLabel.getAutofillId(), activity.mPassword.getAutofillId()
-        );
+        activity.assertInitialViewsDisappeared(events, additionalEvents);
     }
 
     @Test
@@ -386,6 +325,8 @@
         final LoginActivity activity = launchActivity();
         watcher.waitFor(RESUMED);
 
+        assertThat(activity.getContentCaptureManager().isContentCaptureEnabled()).isFalse();
+
         activity.syncRunOnUiThread(() -> activity.mUsername.setText("D'OH"));
 
         activity.finish();
@@ -416,6 +357,7 @@
         final LoginActivity activity = launchActivity();
         watcher.waitFor(RESUMED);
 
+        assertThat(activity.getContentCaptureManager().isContentCaptureEnabled()).isFalse();
         activity.syncRunOnUiThread(() -> activity.mUsername.setText("D'OH"));
 
         activity.finish();
@@ -435,49 +377,6 @@
         assertThat(events).isEmpty();
     }
 
-    @Ignore("not implemented yet, pending on b/122595322")
-    @Test
-    public void testDisabledByFlagSecureAndService() throws Exception {
-        final CtsContentCaptureService service = enableService();
-        final ActivityWatcher watcher = startWatcher();
-
-        LoginActivity.onRootView((activity, rootView) -> activity.getWindow()
-                .addFlags(WindowManager.LayoutParams.FLAG_SECURE));
-
-        // Disable activity
-        service.setActivityContentCaptureEnabled(componentNameFor(LoginActivity.class), false);
-
-        final LoginActivity activity = launchActivity();
-        watcher.waitFor(RESUMED);
-
-        activity.finish();
-        watcher.waitFor(DESTROYED);
-
-        final List<ContentCaptureSessionId> sessionIds = service.getAllSessionIds();
-        assertThat(sessionIds).isEmpty();
-    }
-
-    @Ignore("not implemented yet, pending on b/122595322")
-    @Test
-    public void testDisabledByAppAndAndService() throws Exception {
-        final CtsContentCaptureService service = enableService();
-        final ActivityWatcher watcher = startWatcher();
-
-        LoginActivity.onRootView((activity, rootView) -> activity.getContentCaptureManager()
-                .setContentCaptureEnabled(false));
-
-        // Disable activity
-        service.setActivityContentCaptureEnabled(componentNameFor(LoginActivity.class), false);
-
-        final LoginActivity activity = launchActivity();
-        watcher.waitFor(RESUMED);
-
-        activity.finish();
-        watcher.waitFor(DESTROYED);
-
-        final List<ContentCaptureSessionId> sessionIds = service.getAllSessionIds();
-    }
-
     @Test
     public void testUserDataRemovalRequest_forEverything() throws Exception {
         final CtsContentCaptureService service = enableService();
@@ -505,7 +404,7 @@
         final CtsContentCaptureService service = enableService();
         final ActivityWatcher watcher = startWatcher();
 
-        Uri uri = Uri.parse("com.example");
+        final Uri uri = Uri.parse("com.example");
 
         LoginActivity.onRootView((activity, rootView) -> activity.getContentCaptureManager()
                 .removeUserData(new UserDataRemovalRequest.Builder()
@@ -521,12 +420,14 @@
         UserDataRemovalRequest request = service.getRemovalRequest();
         assertThat(request).isNotNull();
         assertThat(request.isForEverything()).isFalse();
-
-        List<UserDataRemovalRequest.UriRequest> requests = request.getUriRequests();
-        assertThat(requests.size()).isEqualTo(1);
-        assertThat(requests.stream().map((r) -> r.getUri()).collect(Collectors.toList()))
-                .containsExactly(uri).inOrder();
         assertThat(request.getPackageName()).isEqualTo(MY_PACKAGE);
+
+        final List<UserDataRemovalRequest.UriRequest> requests = request.getUriRequests();
+        assertThat(requests.size()).isEqualTo(1);
+
+        final UriRequest actualRequest = requests.get(0);
+        assertThat(actualRequest.getUri()).isEqualTo(uri);
+        assertThat(actualRequest.isRecursive()).isFalse();
     }
 
     @Test
@@ -534,13 +435,13 @@
         final CtsContentCaptureService service = enableService();
         final ActivityWatcher watcher = startWatcher();
 
-        Uri uri = Uri.parse("com.example");
-        Uri uri2 = Uri.parse("com.example2");
+        final Uri uri1 = Uri.parse("com.example");
+        final Uri uri2 = Uri.parse("com.example2");
 
         LoginActivity.onRootView((activity, rootView) -> activity.getContentCaptureManager()
                 .removeUserData(new UserDataRemovalRequest.Builder()
-                        .addUri(uri, false)
-                        .addUri(uri2, false)
+                        .addUri(uri1, false)
+                        .addUri(uri2, true)
                         .build()));
 
         final LoginActivity activity = launchActivity();
@@ -549,17 +450,132 @@
         activity.finish();
         watcher.waitFor(DESTROYED);
 
-        UserDataRemovalRequest request = service.getRemovalRequest();
+        final UserDataRemovalRequest request = service.getRemovalRequest();
         assertThat(request).isNotNull();
         assertThat(request.isForEverything()).isFalse();
-
-        List<UserDataRemovalRequest.UriRequest> requests = request.getUriRequests();
-        assertThat(requests.size()).isEqualTo(2);
-        assertThat(requests.stream().map((r) -> r.getUri()).collect(Collectors.toList()))
-                .containsExactly(uri, uri2).inOrder();
         assertThat(request.getPackageName()).isEqualTo(MY_PACKAGE);
+
+        final List<UserDataRemovalRequest.UriRequest> requests = request.getUriRequests();
+        assertThat(requests.size()).isEqualTo(2);
+
+        final UriRequest actualRequest1 = requests.get(0);
+        assertThat(actualRequest1.getUri()).isEqualTo(uri1);
+        assertThat(actualRequest1.isRecursive()).isFalse();
+
+        final UriRequest actualRequest2 = requests.get(1);
+        assertThat(actualRequest2.getUri()).isEqualTo(uri2);
+        assertThat(actualRequest2.isRecursive()).isTrue();
     }
 
+    @Test
+    public void testAddChildren_rightAway() throws Exception {
+        final CtsContentCaptureService service = enableService();
+        final ActivityWatcher watcher = startWatcher();
+        final View[] children = new View[2];
+
+        final DoubleVisitor<AbstractRootViewActivity, LinearLayout> visitor = (activity,
+                rootView) -> {
+            final TextView child1 = newImportantView(activity, "c1");
+            children[0] = child1;
+            Log.v(TAG, "Adding child1(" + child1.getAutofillId() + "): " + child1);
+            rootView.addView(child1);
+            final TextView child2 = newImportantView(activity, "c1");
+            children[1] = child2;
+            Log.v(TAG, "Adding child2(" + child2.getAutofillId() + "): " + child2);
+            rootView.addView(child2);
+        };
+        LoginActivity.onRootView(visitor);
+
+        final LoginActivity activity = launchActivity();
+        watcher.waitFor(RESUMED);
+
+        activity.finish();
+        watcher.waitFor(DESTROYED);
+
+        final Session session = service.getOnlyFinishedSession();
+        Log.v(TAG, "session id: " + session.id);
+
+        final ContentCaptureSessionId sessionId = session.id;
+        assertRightActivity(session, sessionId, activity);
+
+        final List<ContentCaptureEvent> events = activity.assertJustInitialViewsAppeared(session,
+                /* additionalEvents= */ 2);
+        final AutofillId rootId = activity.getRootView().getAutofillId();
+        int i = LoginActivity.MIN_EVENTS - 1;
+        assertViewAppeared(events, i, sessionId, children[0], rootId);
+        assertViewAppeared(events, i + 1, sessionId, children[1], rootId);
+        assertViewHierarchyFinished(events, i + 2);
+
+        activity.assertInitialViewsDisappeared(events, children.length);
+    }
+
+    @Test
+    public void testAddChildren_afterAnimation() throws Exception {
+        final CtsContentCaptureService service = enableService();
+        final ActivityWatcher watcher = startWatcher();
+        final View[] children = new View[2];
+
+        final DoubleVisitor<AbstractRootViewActivity, LinearLayout> visitor = (activity,
+                rootView) -> {
+            final TextView child1 = newImportantView(activity, "c1");
+            children[0] = child1;
+            Log.v(TAG, "Adding child1(" + child1.getAutofillId() + "): " + child1);
+            rootView.addView(child1);
+            final TextView child2 = newImportantView(activity, "c1");
+            children[1] = child2;
+            Log.v(TAG, "Adding child2(" + child2.getAutofillId() + "): " + child2);
+            rootView.addView(child2);
+        };
+        LoginActivity.onAnimationComplete(visitor);
+
+        final LoginActivity activity = launchActivity();
+        watcher.waitFor(RESUMED);
+
+        activity.finish();
+        watcher.waitFor(DESTROYED);
+
+        final Session session = service.getOnlyFinishedSession();
+        Log.v(TAG, "session id: " + session.id);
+
+        final ContentCaptureSessionId sessionId = session.id;
+        assertRightActivity(session, sessionId, activity);
+        final int additionalEvents = 2; // 2 children views
+        final List<ContentCaptureEvent> events = activity.assertJustInitialViewsAppeared(session,
+                additionalEvents);
+        final View decorView = activity.getDecorView();
+        final View grandpa1 = activity.getGrandParent();
+        final View grandpa2 = activity.getGrandGrandParent();
+        final AutofillId rootId = activity.getRootView().getAutofillId();
+        int i = LoginActivity.MIN_EVENTS - 1;
+
+        assertViewHierarchyFinished(events, i);
+        assertViewAppeared(events, i + 1, sessionId, children[0], rootId);
+        assertViewAppeared(events, i + 2, sessionId, children[1], rootId);
+
+        // TODO(b/122315042): sometimes we get decor view disappareared events, sometimes we don't
+        // As we don't really care about those, let's fix it!
+        try {
+            assertViewsOptionallyDisappeared(events, LoginActivity.MIN_EVENTS + additionalEvents,
+                    rootId,
+                    grandpa1.getAutofillId(), grandpa2.getAutofillId(),
+                    activity.mUsernameLabel.getAutofillId(), activity.mUsername.getAutofillId(),
+                    activity.mPasswordLabel.getAutofillId(), activity.mPassword.getAutofillId(),
+                    children[0].getAutofillId(), children[1].getAutofillId());
+        } catch (AssertionError e) {
+            Log.e(TAG, "Hack-ignoring assertion without decor view: " + e);
+            // Try again removing it...
+            assertViewsOptionallyDisappeared(events, LoginActivity.MIN_EVENTS + additionalEvents,
+                    rootId,
+                    grandpa1.getAutofillId(), grandpa2.getAutofillId(),
+                    decorView.getAutofillId(),
+                     activity.mUsernameLabel.getAutofillId(), activity.mUsername.getAutofillId(),
+                    activity.mPasswordLabel.getAutofillId(), activity.mPassword.getAutofillId(),
+                    children[0].getAutofillId(), children[1].getAutofillId());
+
+        }
+    }
+
+
     // TODO(b/119638528): add moar test cases for different sessions:
     // - session1 on rootView, session2 on children
     // - session1 on rootView, session2 on child1, session3 on child2
@@ -568,7 +584,7 @@
     // TODO(b/119638528): add moar test cases for different scenarios, like:
     // - dynamically adding /
     // - removing views
-    // - pausing / resuming activity
+    // - pausing / resuming activity / tapping home
     // - changing text
     // - secure flag with child sessions
     // - making sure events are flushed when activity pause / resume
diff --git a/tests/framework/base/activitymanager/AndroidManifest.xml b/tests/framework/base/activitymanager/AndroidManifest.xml
index 707e77d..e5136cc 100644
--- a/tests/framework/base/activitymanager/AndroidManifest.xml
+++ b/tests/framework/base/activitymanager/AndroidManifest.xml
@@ -24,6 +24,7 @@
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
     <uses-permission android:name="android.permission.INJECT_EVENTS" />
     <uses-permission android:name="android.permission.MANAGE_ACTIVITY_STACKS"/>
+    <uses-permission android:name="android.permission.STOP_APP_SWITCHES" />
 
     <application android:label="CtsActivityManagerDeviceTestCases">
         <uses-library android:name="android.test.runner" />
diff --git a/tests/framework/base/activitymanager/app27/AndroidManifest.xml b/tests/framework/base/activitymanager/app27/AndroidManifest.xml
index 31771a4..4c52e2b 100755
--- a/tests/framework/base/activitymanager/app27/AndroidManifest.xml
+++ b/tests/framework/base/activitymanager/app27/AndroidManifest.xml
@@ -25,6 +25,15 @@
                   android:exported="true"
         />
 
+        <activity android:name="android.server.am.TestActivity"
+                  android:exported="true"
+        />
+
+        <activity android:name="android.server.am.app27.SeparateProcessActivity"
+                  android:process="android.server.am.app27.separate_process"
+                  android:exported="true"
+        />
+
         <activity android:name="android.server.am.app27.HomeActivity"
                         android:enabled="false"
                         android:exported="true">
diff --git a/tests/framework/base/activitymanager/app27/src/android/server/am/app27/Components.java b/tests/framework/base/activitymanager/app27/src/android/server/am/app27/Components.java
index f085aa9..a7de4c2 100644
--- a/tests/framework/base/activitymanager/app27/src/android/server/am/app27/Components.java
+++ b/tests/framework/base/activitymanager/app27/src/android/server/am/app27/Components.java
@@ -24,6 +24,12 @@
     public static final ComponentName SDK_27_LAUNCHING_ACTIVITY =
             component(Components.class, "android.server.am.LaunchingActivity");
 
+    public static final ComponentName SDK_27_TEST_ACTIVITY =
+            component(Components.class, "android.server.am.TestActivity");
+
+    public static final ComponentName SDK_27_SEPARATE_PROCESS_ACTIVITY =
+            component(Components.class, "android.server.am.app27.SeparateProcessActivity");
+
     public static final ComponentName SDK_27_HOME_ACTIVITY =
             component(Components.class, "android.server.am.app27.HomeActivity");
 }
diff --git a/tests/tests/debug/src/android/debug/cts/DebugTest.java b/tests/framework/base/activitymanager/app27/src/android/server/am/app27/SeparateProcessActivity.java
similarity index 65%
copy from tests/tests/debug/src/android/debug/cts/DebugTest.java
copy to tests/framework/base/activitymanager/app27/src/android/server/am/app27/SeparateProcessActivity.java
index 993f02b..4c961f2 100644
--- a/tests/tests/debug/src/android/debug/cts/DebugTest.java
+++ b/tests/framework/base/activitymanager/app27/src/android/server/am/app27/SeparateProcessActivity.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2019 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.
@@ -14,12 +14,11 @@
  * limitations under the License.
  */
 
-package android.debug.cts;
+package android.server.am.app27;
 
-import org.junit.runner.RunWith;
-import com.android.gtestrunner.GtestRunner;
-import com.android.gtestrunner.TargetLibrary;
 
-@RunWith(GtestRunner.class)
-@TargetLibrary("debugtest")
-public class DebugTest {}
+import android.app.Activity;
+
+public class SeparateProcessActivity extends Activity {
+
+}
\ No newline at end of file
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerGetConfigTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerGetConfigTests.java
index 95370cc..a6d5b57 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerGetConfigTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerGetConfigTests.java
@@ -16,6 +16,11 @@
 
 package android.server.am;
 
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
 import android.app.ActivityManager;
 import android.app.KeyguardManager;
 import android.content.Context;
@@ -28,19 +33,20 @@
 import android.content.pm.PackageManager;
 import android.content.pm.SharedLibraryInfo;
 import android.content.res.Configuration;
-import android.graphics.Point;
 import android.hardware.display.DisplayManager;
 import android.opengl.GLES10;
 import android.os.Build;
 import android.os.LocaleList;
 import android.os.ParcelFileDescriptor;
-import android.support.test.InstrumentationRegistry;
 import android.text.TextUtils;
 import android.util.DisplayMetrics;
 import android.view.Display;
 
 import com.google.protobuf.nano.InvalidProtocolBufferNanoException;
 
+import org.junit.Before;
+import org.junit.Test;
+
 import java.io.ByteArrayOutputStream;
 import java.io.FileInputStream;
 import java.io.IOException;
@@ -58,12 +64,6 @@
 import javax.microedition.khronos.egl.EGLDisplay;
 import javax.microedition.khronos.egl.EGLSurface;
 
-import org.junit.Before;
-import org.junit.Test;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-
 public class ActivityManagerGetConfigTests {
     Context mContext;
     ActivityManager mAm;
@@ -71,16 +71,15 @@
 
     @Before
     public void setUp() throws Exception {
-        mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+        mContext = getInstrumentation().getTargetContext();
         mAm = mContext.getSystemService(ActivityManager.class);
         mPm = mContext.getPackageManager();
     }
 
     private byte[] executeShellCommand(String cmd) {
         try {
-            ParcelFileDescriptor pfd =
-                    InstrumentationRegistry.getInstrumentation().getUiAutomation()
-                            .executeShellCommand(cmd);
+            ParcelFileDescriptor pfd = getInstrumentation().getUiAutomation()
+                    .executeShellCommand(cmd);
             byte[] buf = new byte[512];
             int bytesRead;
             FileInputStream fis = new ParcelFileDescriptor.AutoCloseInputStream(pfd);
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerMultiDisplayTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerMultiDisplayTests.java
index c9b8dba..bd0b2b8 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerMultiDisplayTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerMultiDisplayTests.java
@@ -58,6 +58,9 @@
 import static android.server.am.WindowManagerState.TRANSIT_TASK_CLOSE;
 import static android.server.am.WindowManagerState.TRANSIT_TASK_OPEN;
 import static android.server.am.app27.Components.SDK_27_HOME_ACTIVITY;
+import static android.server.am.app27.Components.SDK_27_LAUNCHING_ACTIVITY;
+import static android.server.am.app27.Components.SDK_27_TEST_ACTIVITY;
+import static android.server.am.app27.Components.SDK_27_SEPARATE_PROCESS_ACTIVITY;
 import static android.server.am.lifecycle.ActivityStarterTests.StandardActivity;
 import static android.server.am.second.Components.EMBEDDING_ACTIVITY;
 import static android.server.am.second.Components.EmbeddingActivity.ACTION_EMBEDDING_TEST_ACTIVITY_START;
@@ -68,12 +71,13 @@
 import static android.server.am.second.Components.SECOND_LAUNCH_BROADCAST_RECEIVER;
 import static android.server.am.second.Components.SECOND_NO_EMBEDDING_ACTIVITY;
 import static android.server.am.third.Components.THIRD_ACTIVITY;
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
 
+import static com.android.cts.mockime.ImeEventStreamTestUtils.editorMatcher;
 import static com.android.cts.mockime.ImeEventStreamTestUtils.expectCommand;
 import static com.android.cts.mockime.ImeEventStreamTestUtils.expectEvent;
-import static com.android.cts.mockime.ImeEventStreamTestUtils.editorMatcher;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -105,7 +109,6 @@
 import android.server.am.CommandSession.SizeInfo;
 import android.server.am.TestJournalProvider.TestJournalContainer;
 import android.server.am.WindowManagerState.WindowState;
-import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.FlakyTest;
 import android.text.TextUtils;
 import android.util.SparseArray;
@@ -117,6 +120,7 @@
 
 import androidx.annotation.Nullable;
 
+import com.android.compatibility.common.util.ImeAwareEditText;
 import com.android.compatibility.common.util.SystemUtil;
 import com.android.cts.mockime.ImeEvent;
 import com.android.cts.mockime.ImeEventStream;
@@ -124,6 +128,7 @@
 import com.android.cts.mockime.MockImeSession;
 
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 
 import java.util.List;
@@ -136,12 +141,17 @@
  */
 @Presubmit
 public class ActivityManagerMultiDisplayTests extends ActivityManagerDisplayTestBase {
+
+    private Context mTargetContext;
+
     @Before
     @Override
     public void setUp() throws Exception {
         super.setUp();
 
         assumeTrue(supportsMultiDisplay());
+
+        mTargetContext = getInstrumentation().getTargetContext();
     }
 
     /**
@@ -171,8 +181,9 @@
      * Tests launching a single instance home activity on virtual display that supports system
      * decorations.
      */
-    // TODO (b/118206886): Will add it back once launcher's patch is merged into master.
-    private void testLaunchSingleHomeActivityOnDisplayWithDecorations() throws Exception {
+    @Ignore("TODO (b/118206886): Will add it back once launcher's patch is merged into master.")
+    @Test
+    public void testLaunchSingleHomeActivityOnDisplayWithDecorations() throws Exception {
         try (final HomeActivitySession session = new HomeActivitySession(SINGLE_HOME_ACTIVITY)) {
             try (final VirtualDisplaySession virtualDisplaySession = new VirtualDisplaySession()) {
                 // Create new virtual display with system decoration support.
@@ -188,8 +199,9 @@
     /**
      * Tests launching a home activity on virtual display that supports system decorations.
      */
-    // TODO (b/118206886): Will add it back once launcher's patch is merged into master.
-    private void testLaunchHomeActivityOnDisplayWithDecorations() throws Exception {
+    @Ignore("TODO (b/118206886): Will add it back once launcher's patch is merged into master.")
+    @Test
+    public void testLaunchHomeActivityOnDisplayWithDecorations() throws Exception {
         try (final HomeActivitySession homeSession = new HomeActivitySession(HOME_ACTIVITY)) {
             try (final VirtualDisplaySession virtualDisplaySession = new VirtualDisplaySession()) {
                 // Create new virtual display with system decoration support.
@@ -209,8 +221,9 @@
      * Tests home activity that target before Q won't be started on virtual display that supports
      * system decorations.
      */
-    // TODO (b/118206886): Will add it back once launcher's patch is merged into master.
-    private void testLaunchSdk27HomeActivityOnDisplayWithDecorations() throws Exception {
+    @Ignore("TODO (b/118206886): Will add it back once launcher's patch is merged into master.")
+    @Test
+    public void testLaunchSdk27HomeActivityOnDisplayWithDecorations() throws Exception {
         try (final HomeActivitySession homeSession
                      = new HomeActivitySession(SDK_27_HOME_ACTIVITY)) {
             try (final VirtualDisplaySession virtualDisplaySession = new VirtualDisplaySession()) {
@@ -707,12 +720,11 @@
             final ActivityDisplay newDisplay = virtualDisplaySession.setSimulateDisplay(true)
                     .createDisplay();
 
-            final Context targetContext = InstrumentationRegistry.getTargetContext();
             final ActivityManager activityManager =
-                    (ActivityManager) targetContext.getSystemService(Context.ACTIVITY_SERVICE);
+                    (ActivityManager) mTargetContext.getSystemService(Context.ACTIVITY_SERVICE);
             final Intent intent = new Intent(Intent.ACTION_VIEW).setComponent(TEST_ACTIVITY);
 
-            assertTrue(activityManager.isActivityStartAllowedOnDisplay(targetContext,
+            assertTrue(activityManager.isActivityStartAllowedOnDisplay(mTargetContext,
                     newDisplay.mId, intent));
         }
     }
@@ -728,14 +740,13 @@
             final ActivityDisplay newDisplay = virtualDisplaySession.setPublicDisplay(true)
                     .createDisplay();
 
-            final Context targetContext = InstrumentationRegistry.getTargetContext();
             final ActivityManager activityManager =
-                    (ActivityManager) targetContext.getSystemService(Context.ACTIVITY_SERVICE);
+                    (ActivityManager) mTargetContext.getSystemService(Context.ACTIVITY_SERVICE);
             final Intent intent = new Intent(Intent.ACTION_VIEW)
                     .setComponent(SECOND_NO_EMBEDDING_ACTIVITY);
 
             SystemUtil.runWithShellPermissionIdentity(() ->
-                    assertTrue(activityManager.isActivityStartAllowedOnDisplay(targetContext,
+                    assertTrue(activityManager.isActivityStartAllowedOnDisplay(mTargetContext,
                             newDisplay.mId, intent)), "android.permission.INTERNAL_SYSTEM_WINDOW");
         }
     }
@@ -751,14 +762,13 @@
             final ActivityDisplay newDisplay = virtualDisplaySession.setPublicDisplay(false)
                     .createDisplay();
 
-            final Context targetContext = InstrumentationRegistry.getTargetContext();
             final ActivityManager activityManager =
-                    (ActivityManager) targetContext.getSystemService(Context.ACTIVITY_SERVICE);
+                    (ActivityManager) mTargetContext.getSystemService(Context.ACTIVITY_SERVICE);
             final Intent intent = new Intent(Intent.ACTION_VIEW)
                     .setComponent(SECOND_NO_EMBEDDING_ACTIVITY);
 
             SystemUtil.runWithShellPermissionIdentity(() ->
-                    assertTrue(activityManager.isActivityStartAllowedOnDisplay(targetContext,
+                    assertTrue(activityManager.isActivityStartAllowedOnDisplay(mTargetContext,
                             newDisplay.mId, intent)), "android.permission.INTERNAL_SYSTEM_WINDOW");
         }
     }
@@ -775,12 +785,11 @@
             final ActivityDisplay newDisplay = virtualDisplaySession.setPublicDisplay(true)
                     .createDisplay();
 
-            final Context targetContext = InstrumentationRegistry.getTargetContext();
             final ActivityManager activityManager =
-                    (ActivityManager) targetContext.getSystemService(Context.ACTIVITY_SERVICE);
+                    (ActivityManager) mTargetContext.getSystemService(Context.ACTIVITY_SERVICE);
             final Intent intent = new Intent(Intent.ACTION_VIEW).setComponent(SECOND_ACTIVITY);
 
-            assertFalse(activityManager.isActivityStartAllowedOnDisplay(targetContext,
+            assertFalse(activityManager.isActivityStartAllowedOnDisplay(mTargetContext,
                     newDisplay.mId, intent));
         }
     }
@@ -796,14 +805,13 @@
             final ActivityDisplay newDisplay = virtualDisplaySession.setPublicDisplay(true)
                     .createDisplay();
 
-            final Context targetContext = InstrumentationRegistry.getTargetContext();
             final ActivityManager activityManager =
-                    (ActivityManager) targetContext.getSystemService(Context.ACTIVITY_SERVICE);
+                    (ActivityManager) mTargetContext.getSystemService(Context.ACTIVITY_SERVICE);
             final Intent intent = new Intent(Intent.ACTION_VIEW)
                     .setComponent(SECOND_NO_EMBEDDING_ACTIVITY);
 
             SystemUtil.runWithShellPermissionIdentity(() ->
-                    assertFalse(activityManager.isActivityStartAllowedOnDisplay(targetContext,
+                    assertFalse(activityManager.isActivityStartAllowedOnDisplay(mTargetContext,
                             newDisplay.mId, intent)), "android.permission.ACTIVITY_EMBEDDING");
         }
     }
@@ -819,14 +827,13 @@
             final ActivityDisplay newDisplay = virtualDisplaySession.setPublicDisplay(true)
                     .createDisplay();
 
-            final Context targetContext = InstrumentationRegistry.getTargetContext();
             final ActivityManager activityManager =
-                    (ActivityManager) targetContext.getSystemService(Context.ACTIVITY_SERVICE);
+                    (ActivityManager) mTargetContext.getSystemService(Context.ACTIVITY_SERVICE);
             final Intent intent = new Intent(Intent.ACTION_VIEW)
                     .setComponent(SECOND_ACTIVITY);
 
             SystemUtil.runWithShellPermissionIdentity(() ->
-                    assertTrue(activityManager.isActivityStartAllowedOnDisplay(targetContext,
+                    assertTrue(activityManager.isActivityStartAllowedOnDisplay(mTargetContext,
                             newDisplay.mId, intent)), "android.permission.ACTIVITY_EMBEDDING");
         }
     }
@@ -842,12 +849,11 @@
             final ActivityDisplay newDisplay = virtualDisplaySession.setPublicDisplay(false)
                     .createDisplay();
 
-            final Context targetContext = InstrumentationRegistry.getTargetContext();
             final ActivityManager activityManager =
-                    (ActivityManager) targetContext.getSystemService(Context.ACTIVITY_SERVICE);
+                    (ActivityManager) mTargetContext.getSystemService(Context.ACTIVITY_SERVICE);
             final Intent intent = new Intent(Intent.ACTION_VIEW).setComponent(SECOND_ACTIVITY);
 
-            assertFalse(activityManager.isActivityStartAllowedOnDisplay(targetContext,
+            assertFalse(activityManager.isActivityStartAllowedOnDisplay(mTargetContext,
                     newDisplay.mId, intent));
         }
     }
@@ -2216,8 +2222,7 @@
 
              // Leverage MockImeSession to ensure at least an IME exists as default.
              final MockImeSession mockImeSession = MockImeSession.create(
-                     mContext, InstrumentationRegistry.getInstrumentation().getUiAutomation(),
-                     new ImeSettings.Builder())) {
+                     mContext, getInstrumentation().getUiAutomation(), new ImeSettings.Builder())) {
 
             // Create a virtual display and launch an activity on it.
             final ActivityDisplay newDisplay = virtualDisplaySession.setPublicDisplay(true)
@@ -2267,8 +2272,7 @@
 
              // Leverage MockImeSession to ensure at least an IME exists as default.
              final MockImeSession mockImeSession = MockImeSession.create(
-                     mContext, InstrumentationRegistry.getInstrumentation().getUiAutomation(),
-                     new ImeSettings.Builder())) {
+                     mContext, getInstrumentation().getUiAutomation(), new ImeSettings.Builder())) {
 
             // Create a virtual display and launch an activity on it.
             final ActivityDisplay newDisplay = virtualDisplaySession.setPublicDisplay(true)
@@ -2306,8 +2310,7 @@
                      TestActivitySession<>();
              // Leverage MockImeSession to ensure at least an IME exists as default.
              final MockImeSession mockImeSession1 = MockImeSession.create(
-                     mContext, InstrumentationRegistry.getInstrumentation().getUiAutomation(),
-                     new ImeSettings.Builder())) {
+                     mContext, getInstrumentation().getUiAutomation(), new ImeSettings.Builder())) {
 
             // Create 2 virtual displays and launch an activity on each display.
             final List<ActivityDisplay> newDisplays = virtualDisplaySession.setPublicDisplay(true)
@@ -2454,15 +2457,14 @@
                      imeTestActivitySession = new TestActivitySession<>();
              // Leverage MockImeSession to ensure at least a test Ime exists as default.
              final MockImeSession mockImeSession = MockImeSession.create(
-                     mContext, InstrumentationRegistry.getInstrumentation().getUiAutomation(),
-                     new ImeSettings.Builder())) {
+                     mContext, getInstrumentation().getUiAutomation(), new ImeSettings.Builder())) {
 
             // Create a virtual display and pretend display does not support system decoration.
             final ActivityDisplay newDisplay = virtualDisplaySession.setPublicDisplay(true)
                     .setShowSystemDecorations(false).createDisplay();
             // Verify the virtual display should not support system decoration.
-            final DisplayManager displayManager = InstrumentationRegistry.getTargetContext()
-                    .getSystemService(DisplayManager.class);
+            final DisplayManager displayManager =
+                    mTargetContext.getSystemService(DisplayManager.class);
             final Display display = displayManager.getDisplay(newDisplay.mId);
             final boolean supportSystemDecoration =
                     display != null && display.supportsSystemDecorations();
@@ -2654,6 +2656,41 @@
         }
     }
 
+    @Test
+    public void testPreQTopProcessResumedActivity() throws Exception {
+        try (final VirtualDisplaySession virtualDisplaySession = new VirtualDisplaySession()) {
+            final ActivityDisplay newDisplay =
+                    virtualDisplaySession.setSimulateDisplay(true).createDisplay();
+
+            getLaunchActivityBuilder().setUseInstrumentation()
+                    .setTargetActivity(SDK_27_TEST_ACTIVITY).setNewTask(true)
+                    .setDisplayId(newDisplay.mId).execute();
+            waitAndAssertTopResumedActivity(SDK_27_TEST_ACTIVITY, newDisplay.mId,
+                    "Activity launched on secondary display must be resumed and focused");
+
+            getLaunchActivityBuilder().setUseInstrumentation()
+                    .setTargetActivity(SDK_27_LAUNCHING_ACTIVITY).setNewTask(true)
+                    .setDisplayId(DEFAULT_DISPLAY).execute();
+            waitAndAssertTopResumedActivity(SDK_27_LAUNCHING_ACTIVITY, DEFAULT_DISPLAY,
+                    "Activity launched on default display must be resumed and focused");
+
+            assertEquals("There must be only one resumed activity in the package.", 1,
+                    mAmWmState.getAmState().getResumedActivitiesCountInPackage(
+                            SDK_27_LAUNCHING_ACTIVITY.getPackageName()));
+
+            getLaunchActivityBuilder().setUseInstrumentation()
+                    .setTargetActivity(SDK_27_SEPARATE_PROCESS_ACTIVITY).setNewTask(true)
+                    .setDisplayId(DEFAULT_DISPLAY).execute();
+            waitAndAssertTopResumedActivity(SDK_27_SEPARATE_PROCESS_ACTIVITY, DEFAULT_DISPLAY,
+                    "Activity launched on default display must be resumed and focused");
+            assertTrue("Activity that was on secondary display must be resumed",
+                    mAmWmState.getAmState().hasActivityState(SDK_27_TEST_ACTIVITY, STATE_RESUMED));
+            assertEquals("There must be only two resumed activities in the package.", 2,
+                    mAmWmState.getAmState().getResumedActivitiesCountInPackage(
+                            SDK_27_TEST_ACTIVITY.getPackageName()));
+        }
+    }
+
     private void waitAndAssertNavBarStatesAreTheSame(List<WindowState> expected) throws Exception {
         // This is used to verify that we have nav bars shown on the same displays
         // as before the test.
@@ -2754,12 +2791,12 @@
     }
 
     public static class ImeTestActivity extends Activity {
-        EditText mEditText;
+        ImeAwareEditText mEditText;
 
         @Override
         protected void onCreate(Bundle icicle) {
             super.onCreate(icicle);
-            mEditText = new EditText(this);
+            mEditText = new ImeAwareEditText(this);
             // Set private IME option for editorMatcher to identify which TextView received
             // onStartInput event.
             mEditText.setPrivateImeOptions(
@@ -2772,7 +2809,7 @@
         }
 
         void showSoftInput() {
-            getSystemService(InputMethodManager.class).showSoftInput(mEditText, 0);
+            mEditText.scheduleShowSoftInput();
         }
     }
 
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerPinnedStackTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerPinnedStackTests.java
index 7a3b6c6..e06dd09 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerPinnedStackTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerPinnedStackTests.java
@@ -60,7 +60,9 @@
 import static android.server.am.Components.TestActivity.EXTRA_FIXED_ORIENTATION;
 import static android.server.am.Components.TestActivity.TEST_ACTIVITY_ACTION_FINISH_SELF;
 import static android.server.am.UiDeviceUtils.pressWindowButton;
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
 import static android.view.Display.DEFAULT_DISPLAY;
+
 import static org.hamcrest.Matchers.lessThan;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
@@ -87,19 +89,19 @@
 import android.server.am.WindowManagerState.WindowStack;
 import android.server.am.settings.SettingsSession;
 import android.support.test.filters.FlakyTest;
-import android.support.test.InstrumentationRegistry;
 import android.util.Log;
 import android.util.Size;
 
 import com.android.compatibility.common.util.AppOpsUtils;
 import com.android.compatibility.common.util.SystemUtil;
 
+import org.junit.Ignore;
+import org.junit.Test;
+
 import java.io.IOException;
 import java.util.List;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
-import org.junit.Ignore;
-import org.junit.Test;
 
 /**
  * Build/Install/Run:
@@ -209,7 +211,12 @@
 
         try (final RotationSession rotationSession = new RotationSession()) {
             rotationSession.set(ROTATION_0);
-
+            mAmWmState.waitForWithWmState((wmState1) -> {
+                Rect db = wmState1.getDefaultPinnedStackBounds();
+                Rect sb = wmState1.getStableBounds();
+                return (db.width() > 0 && db.height() > 0) &&
+                        (sb.contains(db));
+            }, "Waiting for valid bounds..");
             WindowManagerState wmState = mAmWmState.getWmState();
             wmState.computeState();
             Rect defaultPipBounds = wmState.getDefaultPinnedStackBounds();
@@ -218,6 +225,12 @@
             assertTrue(stableBounds.contains(defaultPipBounds));
 
             rotationSession.set(ROTATION_90);
+            mAmWmState.waitForWithWmState((wmState1) -> {
+                Rect db = wmState1.getDefaultPinnedStackBounds();
+                Rect sb = wmState1.getStableBounds();
+                return (db.width() > 0 && db.height() > 0) &&
+                        (sb.contains(db));
+            }, "Waiting for valid bounds...");
             wmState = mAmWmState.getWmState();
             wmState.computeState();
             defaultPipBounds = wmState.getDefaultPinnedStackBounds();
@@ -874,7 +887,7 @@
         public void close() throws Exception {
             // Wait for the restored setting to apply before we continue on with the next test
             final CountDownLatch waitLock = new CountDownLatch(1);
-            final Context context = InstrumentationRegistry.getTargetContext();
+            final Context context = getInstrumentation().getTargetContext();
             context.getContentResolver().registerContentObserver(mUri, false,
                     new ContentObserver(new Handler(Looper.getMainLooper())) {
                         @Override
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerSplitScreenTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerSplitScreenTests.java
index bb8c144..7fa65cf 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerSplitScreenTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerSplitScreenTests.java
@@ -37,6 +37,9 @@
 import static android.server.am.Components.TestActivity.TEST_ACTIVITY_ACTION_FINISH_SELF;
 import static android.server.am.UiDeviceUtils.pressHomeButton;
 import static android.server.am.WindowManagerState.TRANSIT_WALLPAPER_OPEN;
+import static android.server.am.app27.Components.SDK_27_LAUNCHING_ACTIVITY;
+import static android.server.am.app27.Components.SDK_27_SEPARATE_PROCESS_ACTIVITY;
+import static android.server.am.app27.Components.SDK_27_TEST_ACTIVITY;
 import static android.view.Surface.ROTATION_0;
 import static android.view.Surface.ROTATION_180;
 import static android.view.Surface.ROTATION_270;
@@ -571,6 +574,28 @@
     }
 
     @Test
+    public void testSameProcessActivityResumedPreQ() {
+        launchActivitiesInSplitScreen(
+                getLaunchActivityBuilder().setTargetActivity(SDK_27_TEST_ACTIVITY),
+                getLaunchActivityBuilder().setTargetActivity(SDK_27_LAUNCHING_ACTIVITY));
+
+        assertEquals("There must be only one resumed activity in the package.", 1,
+                mAmWmState.getAmState().getResumedActivitiesCountInPackage(
+                        SDK_27_TEST_ACTIVITY.getPackageName()));
+    }
+
+    @Test
+    public void testDifferentProcessActivityResumedPreQ() {
+        launchActivitiesInSplitScreen(
+                getLaunchActivityBuilder().setTargetActivity(SDK_27_TEST_ACTIVITY),
+                getLaunchActivityBuilder().setTargetActivity(SDK_27_SEPARATE_PROCESS_ACTIVITY));
+
+        assertEquals("There must be only two resumed activities in the package.", 2,
+                mAmWmState.getAmState().getResumedActivitiesCountInPackage(
+                        SDK_27_TEST_ACTIVITY.getPackageName()));
+    }
+
+    @Test
     public void testActivityLifeCycleOnResizeDockedStack() throws Exception {
         launchActivity(TEST_ACTIVITY);
         mAmWmState.computeState(TEST_ACTIVITY);
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityMetricsLoggerTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityMetricsLoggerTests.java
index 9ec5225..29449c8 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityMetricsLoggerTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityMetricsLoggerTests.java
@@ -30,7 +30,6 @@
 import static android.server.am.third.Components.THIRD_ACTIVITY;
 import static android.util.TimeUtils.formatDuration;
 
-import static com.android.compatibility.common.util.SystemUtil.runShellCommand;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_DELAY_MS;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_DEVICE_UPTIME_SECONDS;
@@ -63,6 +62,8 @@
 import android.support.test.metricshelper.MetricsAsserts;
 import android.util.EventLog.Event;
 
+import com.android.compatibility.common.util.SystemUtil;
+
 import org.hamcrest.collection.IsIn;
 import org.junit.Before;
 import org.junit.Test;
@@ -73,7 +74,7 @@
 import java.util.concurrent.TimeUnit;
 
 /**
- * CTS device tests for {@link com.android.server.am.ActivityMetricsLogger}.
+ * CTS device tests for {@link com.android.server.wm.ActivityMetricsLogger}.
  * Build/Install/Run:
  * atest CtsActivityManagerDeviceTestCases:ActivityMetricsLoggerTests
  */
@@ -217,15 +218,15 @@
     @Presubmit
     @FlakyTest(bugId = 122118854)
     public void testAppWarmLaunchSetsWaitResultDelayData() {
-        runShellCommand("am start -S -W " + TEST_ACTIVITY.flattenToShortString());
+        SystemUtil.runShellCommand("am start -S -W " + TEST_ACTIVITY.flattenToShortString());
 
         // Test warm launch
         pressBackButton();
         waitForDeviceIdle(1000);
         mMetricsReader.checkpoint(); // clear out old logs
 
-        final String amStartOutput =
-                runShellCommand("am start -W " + TEST_ACTIVITY.flattenToShortString());
+        final String amStartOutput = SystemUtil.runShellCommand(
+                "am start -W " + TEST_ACTIVITY.flattenToShortString());
 
         final LogMaker metricsLog = getMetricsLog(TEST_ACTIVITY, APP_TRANSITION);
         assertNotNull("log should have windows drawn delay", metricsLog);
@@ -255,15 +256,15 @@
     @Presubmit
     @FlakyTest(bugId = 122118854)
     public void testAppHotLaunchSetsWaitResultDelayData() {
-        runShellCommand("am start -S -W " + TEST_ACTIVITY.flattenToShortString());
+        SystemUtil.runShellCommand("am start -S -W " + TEST_ACTIVITY.flattenToShortString());
 
         // Test hot launch
         pressHomeButton();
         waitForDeviceIdle(1000);
         mMetricsReader.checkpoint(); // clear out old logs
 
-        final String amStartOutput =
-                runShellCommand("am start -W " + TEST_ACTIVITY.flattenToShortString());
+        final String amStartOutput = SystemUtil.runShellCommand(
+                "am start -W " + TEST_ACTIVITY.flattenToShortString());
 
         final LogMaker metricsLog = getMetricsLog(TEST_ACTIVITY, APP_TRANSITION);
         assertNotNull("log should have windows drawn delay", metricsLog);
@@ -292,8 +293,8 @@
     @Test
     @Presubmit
     public void testAppColdLaunchSetsWaitResultDelayData() {
-        final String amStartOutput =
-                runShellCommand("am start -S -W " + TEST_ACTIVITY.flattenToShortString());
+        final String amStartOutput = SystemUtil.runShellCommand(
+                "am start -S -W " + TEST_ACTIVITY.flattenToShortString());
 
         final LogMaker metricsLog = getMetricsLog(TEST_ACTIVITY, APP_TRANSITION);
         assertNotNull("log should have windows drawn delay", metricsLog);
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityViewTest.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityViewTest.java
index 139c0cd..fc07edb 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityViewTest.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityViewTest.java
@@ -19,6 +19,7 @@
 import static android.server.am.ActivityManagerState.STATE_RESUMED;
 import static android.server.am.ActivityManagerState.STATE_STOPPED;
 import static android.server.am.Components.TEST_ACTIVITY;
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
 
 import static org.junit.Assert.assertTrue;
@@ -32,7 +33,6 @@
 import android.os.Bundle;
 import android.os.SystemClock;
 import android.platform.test.annotations.Presubmit;
-import android.support.test.InstrumentationRegistry;
 import android.support.test.annotation.UiThreadTest;
 import android.support.test.filters.FlakyTest;
 import android.support.test.rule.ActivityTestRule;
@@ -62,7 +62,7 @@
 
     @Before
     public void setup() {
-        mInstrumentation = InstrumentationRegistry.getInstrumentation();
+        mInstrumentation = getInstrumentation();
         ActivityViewTestActivity activity = mActivityRule.launchActivity(null);
         mActivityView = activity.getActivityView();
         separateTestJournal();
diff --git a/tests/framework/base/activitymanager/src/android/server/am/AspectRatioTests.java b/tests/framework/base/activitymanager/src/android/server/am/AspectRatioTests.java
index a3b625c..c996ebd 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/AspectRatioTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/AspectRatioTests.java
@@ -24,18 +24,15 @@
 import android.app.Activity;
 import android.platform.test.annotations.Presubmit;
 import android.support.test.rule.ActivityTestRule;
-import android.support.test.runner.AndroidJUnit4;
 import android.view.Display;
 
 import org.junit.Rule;
 import org.junit.Test;
-import org.junit.runner.RunWith;
 
 /**
  * Build/Install/Run:
  *     atest CtsActivityManagerDeviceTestCases:AspectRatioTests
  */
-@RunWith(AndroidJUnit4.class)
 @Presubmit
 public class AspectRatioTests extends AspectRatioTestsBase {
 
diff --git a/tests/framework/base/activitymanager/src/android/server/am/AspectRatioTestsBase.java b/tests/framework/base/activitymanager/src/android/server/am/AspectRatioTestsBase.java
index eaf1276..97d344e 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/AspectRatioTestsBase.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/AspectRatioTestsBase.java
@@ -16,12 +16,13 @@
 
 package android.server.am;
 
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
+
 import static org.hamcrest.Matchers.greaterThanOrEqualTo;
 import static org.hamcrest.Matchers.lessThanOrEqualTo;
 
 import android.app.Activity;
 import android.graphics.Point;
-import android.support.test.InstrumentationRegistry;
 import android.support.test.rule.ActivityTestRule;
 import android.view.Display;
 import android.view.WindowManager;
@@ -63,7 +64,7 @@
     }
 
     static float getDefaultDisplayAspectRatio() {
-        return getAspectRatio(InstrumentationRegistry.getContext().getSystemService(
+        return getAspectRatio(getInstrumentation().getContext().getSystemService(
                 WindowManager.class).getDefaultDisplay());
     }
 
@@ -97,7 +98,7 @@
     }
 
     private static void waitForIdle() {
-        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+        getInstrumentation().waitForIdleSync();
     }
 
     static Matcher<Float> greaterThanOrEqualToInexact(float expected) {
diff --git a/tests/framework/base/activitymanager/src/android/server/am/DeprecatedTargetSdkTest.java b/tests/framework/base/activitymanager/src/android/server/am/DeprecatedTargetSdkTest.java
index b24a859..ed9bc11 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/DeprecatedTargetSdkTest.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/DeprecatedTargetSdkTest.java
@@ -19,11 +19,8 @@
 import static android.server.am.UiDeviceUtils.pressBackButton;
 import static android.server.am.deprecatedsdk.Components.MAIN_ACTIVITY;
 
-import android.support.test.runner.AndroidJUnit4;
-
 import org.junit.After;
 import org.junit.Test;
-import org.junit.runner.RunWith;
 
 /**
  * Ensure that compatibility dialog is shown when launching an application
@@ -31,10 +28,9 @@
  * <p>Build/Install/Run:
  *     atest CtsActivityManagerDeviceTestCases:DeprecatedTargetSdkTest
  */
-@RunWith(AndroidJUnit4.class)
 public class DeprecatedTargetSdkTest extends ActivityManagerTestBase {
 
-    /** @see com.android.server.am.DeprecatedTargetSdkVersionDialog */
+    /** @see com.android.server.wm.DeprecatedTargetSdkVersionDialog */
     private static final String DEPRECATED_TARGET_SDK_VERSION_DIALOG =
             "DeprecatedTargetSdkVersionDialog";
 
diff --git a/tests/framework/base/activitymanager/src/android/server/am/KeyguardLockedTests.java b/tests/framework/base/activitymanager/src/android/server/am/KeyguardLockedTests.java
index 28fe737..292f9ea 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/KeyguardLockedTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/KeyguardLockedTests.java
@@ -28,6 +28,7 @@
 import static android.server.am.Components.SHOW_WHEN_LOCKED_ATTR_IME_ACTIVITY;
 import static android.server.am.Components.TURN_SCREEN_ON_ATTR_DISMISS_KEYGUARD_ACTIVITY;
 import static android.server.am.UiDeviceUtils.pressBackButton;
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE;
 
@@ -42,14 +43,9 @@
 import android.content.ComponentName;
 import android.os.Bundle;
 import android.os.SystemClock;
-import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.InputMethodManager;
 import android.widget.EditText;
 import android.widget.LinearLayout;
 
-import android.support.test.InstrumentationRegistry;
-
-import com.android.cts.mockime.ImeEvent;
 import com.android.cts.mockime.ImeEventStream;
 import com.android.cts.mockime.ImeSettings;
 import com.android.cts.mockime.MockImeSession;
@@ -300,8 +296,7 @@
         try (final LockScreenSession lockScreenSession = new LockScreenSession();
              // Leverage MockImeSession to ensure at least an IME exists as default.
              final MockImeSession mockImeSession = MockImeSession.create(mContext,
-                     InstrumentationRegistry.getInstrumentation().getUiAutomation(),
-                     new ImeSettings.Builder())) {
+                     getInstrumentation().getUiAutomation(), new ImeSettings.Builder())) {
             lockScreenSession.setLockCredential().gotoKeyguard();
             mAmWmState.assertKeyguardShowingAndNotOccluded();
             launchActivity(SHOW_WHEN_LOCKED_ATTR_IME_ACTIVITY);
@@ -324,8 +319,7 @@
                      TestActivitySession<>();
              // Leverage MockImeSession to ensure at least an IME exists as default.
              final MockImeSession mockImeSession = MockImeSession.create(mContext,
-                     InstrumentationRegistry.getInstrumentation().getUiAutomation(),
-                     new ImeSettings.Builder())) {
+                     getInstrumentation().getUiAutomation(), new ImeSettings.Builder())) {
             lockScreenSession.setLockCredential().gotoKeyguard();
             mAmWmState.assertKeyguardShowingAndNotOccluded();
             imeTestActivitySession.launchTestActivityOnDisplaySync(ShowWhenLockedImeActivity.class,
diff --git a/tests/framework/base/activitymanager/src/android/server/am/PrereleaseSdkTest.java b/tests/framework/base/activitymanager/src/android/server/am/PrereleaseSdkTest.java
index 2eb40f8..b7703a8 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/PrereleaseSdkTest.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/PrereleaseSdkTest.java
@@ -33,7 +33,7 @@
  */
 public class PrereleaseSdkTest extends ActivityManagerTestBase {
 
-    /** @see com.android.server.am.UnsupportedCompileSdkDialog */
+    /** @see com.android.server.wm.UnsupportedCompileSdkDialog */
     private static final String UNSUPPORTED_COMPILE_SDK_DIALOG = "UnsupportedCompileSdkDialog";
 
     @Before
diff --git a/tests/framework/base/activitymanager/src/android/server/am/StartActivityTests.java b/tests/framework/base/activitymanager/src/android/server/am/StartActivityTests.java
index bcab43f..b0e85e8 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/StartActivityTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/StartActivityTests.java
@@ -22,9 +22,7 @@
 import static org.junit.Assert.assertFalse;
 
 import android.app.Activity;
-import android.content.ComponentName;
 import android.platform.test.annotations.Presubmit;
-import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.FlakyTest;
 import android.support.test.rule.ActivityTestRule;
 
diff --git a/tests/framework/base/activitymanager/src/android/server/am/VirtualDisplayHelper.java b/tests/framework/base/activitymanager/src/android/server/am/VirtualDisplayHelper.java
index b85e42a..cc9634a 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/VirtualDisplayHelper.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/VirtualDisplayHelper.java
@@ -15,12 +15,13 @@
  */
 
 package android.server.am;
-import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;
+
 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY;
 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PRESENTATION;
+import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;
 import static android.server.am.ActivityManagerTestBase.isDisplayOn;
 import static android.server.am.StateLogger.logAlways;
-import static android.support.test.InstrumentationRegistry.getContext;
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
 import static android.view.Display.DEFAULT_DISPLAY;
 
 import static org.junit.Assert.fail;
@@ -101,7 +102,8 @@
     private void createVirtualDisplay(boolean requestShowWhenLocked, int virtualDisplayFlags) {
         mReader = ImageReader.newInstance(WIDTH, HEIGHT, PixelFormat.RGBA_8888, 2);
 
-        final DisplayManager displayManager = getContext().getSystemService(DisplayManager.class);
+        final DisplayManager displayManager = getInstrumentation()
+                .getContext().getSystemService(DisplayManager.class);
 
         int flags = VIRTUAL_DISPLAY_FLAG_PRESENTATION | VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY
                 | virtualDisplayFlags;
diff --git a/tests/framework/base/activitymanager/src/android/server/am/intent/IntentGenerationTests.java b/tests/framework/base/activitymanager/src/android/server/am/intent/IntentGenerationTests.java
index c5daaaa..7aaeabb 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/intent/IntentGenerationTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/intent/IntentGenerationTests.java
@@ -16,12 +16,13 @@
 
 package android.server.am.intent;
 
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
+
 import android.content.ComponentName;
 import android.content.Context;
 import android.os.Environment;
 import android.server.am.intent.Persistence.IntentFlag;
 import android.server.am.intent.Persistence.TestCase;
-import android.support.test.InstrumentationRegistry;
 
 import org.json.JSONException;
 import org.json.JSONObject;
@@ -63,7 +64,6 @@
  * Build/Install/Run:
  * atest CtsActivityManagerDeviceTestCases:IntentGenerationTests
  */
-@Ignore
 public class IntentGenerationTests extends IntentTestBase {
     private static final Cases CASES = new Cases();
 
@@ -80,10 +80,11 @@
     /**
      * The target context we can launch the first activity from.
      */
-    private Context mTargetContext = InstrumentationRegistry.getTargetContext();
+    private Context mTargetContext = getInstrumentation().getTargetContext();
 
     //20 minute timeout.
     @Test(timeout = 1_200_000)
+    @Ignore
     public void generate() throws Exception {
         mLaunchRunner.runAndWrite(mTargetContext, "forResult", CASES.forResultCases());
         mLaunchRunner.runAndWrite(mTargetContext, "newTask", CASES.newTaskCases());
@@ -105,6 +106,7 @@
      * @throws JSONException if the file has invalid json in it.
      */
     @Test
+    @Ignore
     public void verifySingle() throws IOException, JSONException {
         String test = "forResult/test-1.json";
         TestCase testCase = readFromStorage(test);
diff --git a/tests/framework/base/activitymanager/src/android/server/am/intent/IntentTests.java b/tests/framework/base/activitymanager/src/android/server/am/intent/IntentTests.java
index e9ff1cb..826804b 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/intent/IntentTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/intent/IntentTests.java
@@ -16,21 +16,20 @@
 
 package android.server.am.intent;
 
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
+
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.res.AssetManager;
 import android.os.Environment;
-import android.server.am.UiDeviceUtils;
 import android.server.am.intent.Persistence.IntentFlag;
 import android.server.am.intent.Persistence.TestCase;
-import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.LargeTest;
 
 import com.google.common.collect.Lists;
 
 import org.json.JSONException;
 import org.json.JSONObject;
-import org.junit.After;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
@@ -69,7 +68,7 @@
      * The flag parsing table used to parse the json files.
      */
     private static final Map<String, IntentFlag> TABLE = CASES.createFlagParsingTable();
-    private static Context TARGET_CONTEXT = InstrumentationRegistry.getTargetContext();
+    private static Context TARGET_CONTEXT = getInstrumentation().getTargetContext();
 
     private static final int JSON_INDENTATION_LEVEL = 4;
 
diff --git a/tests/framework/base/activitymanager/src/android/server/am/intent/LaunchRunner.java b/tests/framework/base/activitymanager/src/android/server/am/intent/LaunchRunner.java
index 5d702db..4670594 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/intent/LaunchRunner.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/intent/LaunchRunner.java
@@ -19,6 +19,7 @@
 import static android.server.am.intent.Persistence.LaunchFromIntent.prepareSerialisation;
 import static android.server.am.intent.StateComparisonException.assertEndStatesEqual;
 import static android.server.am.intent.StateComparisonException.assertInitialStateEqual;
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
 
 import static com.google.common.collect.Iterables.getLast;
 
@@ -36,7 +37,6 @@
 import android.server.am.intent.Persistence.GenerationIntent;
 import android.server.am.intent.Persistence.LaunchFromIntent;
 import android.server.am.intent.Persistence.StateDump;
-import android.support.test.InstrumentationRegistry;
 import android.view.Display;
 
 import com.google.common.collect.Lists;
@@ -240,7 +240,7 @@
 
 
     public Activity launchFromContext(Context context, Intent intent) {
-        Instrumentation.ActivityMonitor monitor = InstrumentationRegistry.getInstrumentation()
+        Instrumentation.ActivityMonitor monitor = getInstrumentation()
                 .addMonitor((String) null, null, false);
 
         context.startActivity(intent);
@@ -251,7 +251,7 @@
     }
 
     public Activity launch(Activity activityContext, Intent intent, boolean startForResult) {
-        Instrumentation.ActivityMonitor monitor = InstrumentationRegistry.getInstrumentation()
+        Instrumentation.ActivityMonitor monitor = getInstrumentation()
                 .addMonitor((String) null, null, false);
 
         if (startForResult) {
diff --git a/tests/framework/base/activitymanager/src/android/server/am/intent/LaunchSequence.java b/tests/framework/base/activitymanager/src/android/server/am/intent/LaunchSequence.java
index 8d801e8..fa3d4e3 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/intent/LaunchSequence.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/intent/LaunchSequence.java
@@ -17,10 +17,11 @@
 package android.server.am.intent;
 
 
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
+
 import android.content.ComponentName;
 import android.server.am.intent.Persistence.LaunchFromIntent;
 import android.server.am.intent.Persistence.LaunchIntent;
-import android.support.test.InstrumentationRegistry;
 
 import com.google.common.collect.Lists;
 
@@ -158,7 +159,7 @@
         return new LaunchIntent(Lists.newArrayList(), createComponent(activity), true);
     }
 
-    String packageName = InstrumentationRegistry.getTargetContext().getPackageName();
+    String packageName = getInstrumentation().getTargetContext().getPackageName();
 
     static ComponentName createComponent(Class<? extends android.app.Activity> activity) {
         return new ComponentName(packageName, activity.getName());
diff --git a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleClientTestBase.java b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleClientTestBase.java
index 045bceb..328d27e 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleClientTestBase.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleClientTestBase.java
@@ -19,28 +19,27 @@
 import static android.server.am.Components.PipActivity.EXTRA_ENTER_PIP;
 import static android.server.am.StateLogger.log;
 import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_ACTIVITY_RESULT;
-import static android.server.am.lifecycle.LifecycleLog.ActivityCallback
-        .ON_MULTI_WINDOW_MODE_CHANGED;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_MULTI_WINDOW_MODE_CHANGED;
 import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_NEW_INTENT;
 import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_PAUSE;
 import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_POST_CREATE;
 import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_STOP;
 import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_TOP_POSITION_GAINED;
 import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_TOP_POSITION_LOST;
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
 
 import android.annotation.Nullable;
 import android.app.Activity;
 import android.app.PictureInPictureParams;
 import android.content.ComponentName;
+import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
 import android.content.res.Configuration;
 import android.os.Bundle;
 import android.os.Handler;
 import android.server.am.ActivityManagerDisplayTestBase;
-import android.server.am.ActivityManagerTestBase;
 import android.server.am.lifecycle.LifecycleLog.ActivityCallback;
-import android.support.test.InstrumentationRegistry;
 import android.support.test.rule.ActivityTestRule;
 import android.support.test.runner.lifecycle.ActivityLifecycleMonitor;
 import android.support.test.runner.lifecycle.ActivityLifecycleMonitorRegistry;
@@ -112,12 +111,16 @@
     private final ActivityLifecycleMonitor mLifecycleMonitor = ActivityLifecycleMonitorRegistry
             .getInstance();
     private static LifecycleLog mLifecycleLog;
+
+    protected Context mTargetContext;
     private LifecycleTracker mLifecycleTracker;
 
     @Before
     @Override
     public void setUp() throws Exception {
         super.setUp();
+
+        mTargetContext = getInstrumentation().getTargetContext();
         // Log transitions for all activities that belong to this app.
         mLifecycleLog = new LifecycleLog();
         mLifecycleMonitor.addLifecycleCallback(mLifecycleLog);
@@ -137,8 +140,8 @@
 
     /** Launch an activity given a class. */
     protected Activity launchActivity(Class<? extends Activity> activityClass) {
-        final Intent intent = new Intent(InstrumentationRegistry.getTargetContext(), activityClass);
-        return InstrumentationRegistry.getInstrumentation().startActivitySync(intent);
+        final Intent intent = new Intent(mTargetContext, activityClass);
+        return getInstrumentation().startActivitySync(intent);
     }
 
     /**
@@ -347,6 +350,6 @@
     }
 
     static ComponentName getComponentName(Class<? extends Activity> activity) {
-        return new ComponentName(InstrumentationRegistry.getContext(), activity);
+        return new ComponentName(getInstrumentation().getContext(), activity);
     }
 }
diff --git a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleFreeformTests.java b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleFreeformTests.java
index 3445708..044f5bc 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleFreeformTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleFreeformTests.java
@@ -23,36 +23,35 @@
 import static android.server.am.ActivityManagerState.STATE_RESUMED;
 import static android.server.am.ActivityManagerState.STATE_STOPPED;
 import static android.server.am.ComponentNameUtils.getWindowName;
+import static android.server.am.app27.Components.SDK_27_LAUNCHING_ACTIVITY;
+import static android.server.am.app27.Components.SDK_27_TEST_ACTIVITY;
 import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_RESUME;
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
 
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assume.assumeTrue;
 
 import android.app.Activity;
+import android.app.ActivityManager;
 import android.app.ActivityOptions;
 import android.content.Intent;
 import android.os.Bundle;
 import android.platform.test.annotations.Presubmit;
-import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.FlakyTest;
 import android.support.test.filters.MediumTest;
-import android.support.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
 import org.junit.Test;
-import org.junit.runner.RunWith;
 
-import java.util.ArrayList;
 import java.util.Arrays;
 
 /**
  * Build/Install/Run:
  *     atest CtsActivityManagerDeviceTestCases:ActivityLifecycleFreeformTests
  */
-@MediumTest
-@RunWith(AndroidJUnit4.class)
-@Presubmit
 @FlakyTest(bugId = 77652261)
+@MediumTest
+@Presubmit
 public class ActivityLifecycleFreeformTests extends ActivityLifecycleClientTestBase {
 
     @Before
@@ -71,10 +70,9 @@
         final Bundle bundle = launchOptions.toBundle();
 
         // Launch an activity in freeform
-        final Intent firstIntent =
-                new Intent(InstrumentationRegistry.getContext(), FirstActivity.class)
+        final Intent firstIntent = new Intent(mContext, FirstActivity.class)
                 .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK);
-        InstrumentationRegistry.getTargetContext().startActivity(firstIntent, bundle);
+        mTargetContext.startActivity(firstIntent, bundle);
 
         // Wait and assert resume
         waitAndAssertActivityState(getComponentName(FirstActivity.class), STATE_RESUMED,
@@ -95,20 +93,17 @@
         final Bundle bundle = launchOptions.toBundle();
 
         // Launch three activities in freeform
-        final Intent firstIntent =
-                new Intent(InstrumentationRegistry.getContext(), FirstActivity.class)
-                        .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK);
-        InstrumentationRegistry.getTargetContext().startActivity(firstIntent, bundle);
+        final Intent firstIntent = new Intent(mContext, FirstActivity.class)
+                .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK);
+        mTargetContext.startActivity(firstIntent, bundle);
 
-        final Intent secondIntent =
-                new Intent(InstrumentationRegistry.getContext(), SecondActivity.class)
-                        .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK);
-        InstrumentationRegistry.getTargetContext().startActivity(secondIntent, bundle);
+        final Intent secondIntent = new Intent(mContext, SecondActivity.class)
+                .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK);
+        mTargetContext.startActivity(secondIntent, bundle);
 
-        final Intent thirdIntent =
-                new Intent(InstrumentationRegistry.getContext(), ThirdActivity.class)
-                        .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK);
-        InstrumentationRegistry.getTargetContext().startActivity(thirdIntent, bundle);
+        final Intent thirdIntent = new Intent(mContext, ThirdActivity.class)
+                .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK);
+        mTargetContext.startActivity(thirdIntent, bundle);
 
         // Wait for resume
         final String message = "Activity should be resumed after launch";
@@ -137,17 +132,15 @@
         final Bundle bundle = launchOptions.toBundle();
 
         // Launch two activities in freeform in the same task
-        final Intent firstIntent =
-                new Intent(InstrumentationRegistry.getContext(), FirstActivity.class)
-                        .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK);
-        InstrumentationRegistry.getTargetContext().startActivity(firstIntent, bundle);
+        final Intent firstIntent = new Intent(mContext, FirstActivity.class)
+                .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK);
+        mTargetContext.startActivity(firstIntent, bundle);
 
         final Activity secondActivity = mSecondActivityTestRule.launchActivity(new Intent());
 
-        final Intent thirdIntent =
-                new Intent(InstrumentationRegistry.getContext(), ThirdActivity.class)
-                        .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK);
-        InstrumentationRegistry.getTargetContext().startActivity(thirdIntent, bundle);
+        final Intent thirdIntent = new Intent(mContext, ThirdActivity.class)
+                .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK);
+        mTargetContext.startActivity(thirdIntent, bundle);
 
         // Wait for valid states
         final String stopMessage = "Activity should be stopped after being covered above";
@@ -198,18 +191,16 @@
         final Bundle bundle = launchOptions.toBundle();
 
         // Launch two activities in freeform in the same task
-        final Intent firstIntent =
-                new Intent(InstrumentationRegistry.getContext(), FirstActivity.class)
-                        .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK);
-        InstrumentationRegistry.getTargetContext().startActivity(firstIntent, bundle);
+        final Intent firstIntent = new Intent(mContext, FirstActivity.class)
+                .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK);
+        mTargetContext.startActivity(firstIntent, bundle);
 
         final Activity transparentActivity = mTranslucentActivityTestRule
                 .launchActivity(new Intent());
 
-        final Intent thirdIntent =
-                new Intent(InstrumentationRegistry.getContext(), ThirdActivity.class)
-                        .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK);
-        InstrumentationRegistry.getTargetContext().startActivity(thirdIntent, bundle);
+        final Intent thirdIntent = new Intent(mContext, ThirdActivity.class)
+                .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK);
+        mTargetContext.startActivity(thirdIntent, bundle);
 
         // Wait for valid states
         final String pauseMessage = "Activity should be stopped after transparent launch above";
@@ -254,4 +245,31 @@
         LifecycleVerifier.assertEmptySequence(CallbackTrackingActivity.class, getLifecycleLog(),
                 "finishInOtherStack");
     }
+
+    @Test
+    public void testPreQTopProcessResumedActivityInFreeform() throws Exception {
+        // Resume app switches, so the activities that we are going to launch won't be deferred
+        // since Home activity was started in #setUp().
+        ActivityManager.getService().resumeAppSwitches();
+
+        final ActivityOptions launchOptions = ActivityOptions.makeBasic();
+        launchOptions.setLaunchWindowingMode(WINDOWING_MODE_FREEFORM);
+        final Bundle bundle = launchOptions.toBundle();
+
+        // Launch an activity that targeted SDK 27.
+        Intent intent = new Intent().setComponent(SDK_27_TEST_ACTIVITY)
+                .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK);
+        mTargetContext.startActivity(intent, bundle);
+        waitAndAssertActivityState(SDK_27_TEST_ACTIVITY, STATE_RESUMED,
+                "Activity must be resumed.");
+
+        // Launch another activity in the same process.
+        intent = new Intent().setComponent(SDK_27_LAUNCHING_ACTIVITY)
+                .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK);
+        mTargetContext.startActivity(intent, bundle);
+        waitAndAssertActivityState(SDK_27_TEST_ACTIVITY, STATE_PAUSED,
+                "Activity must be paused since another activity started.");
+        waitAndAssertActivityState(SDK_27_LAUNCHING_ACTIVITY, STATE_RESUMED,
+                "Activity must be resumed.");
+    }
 }
diff --git a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleKeyguardTests.java b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleKeyguardTests.java
index 76c712c..00138cf 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleKeyguardTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleKeyguardTests.java
@@ -29,10 +29,8 @@
 import android.content.Intent;
 import android.platform.test.annotations.Presubmit;
 import android.support.test.filters.MediumTest;
-import android.support.test.runner.AndroidJUnit4;
 
 import org.junit.Test;
-import org.junit.runner.RunWith;
 
 import java.util.Arrays;
 
@@ -41,7 +39,6 @@
  *     atest CtsActivityManagerDeviceTestCases:ActivityLifecycleKeyguardTests
  */
 @MediumTest
-@RunWith(AndroidJUnit4.class)
 @Presubmit
 public class ActivityLifecycleKeyguardTests extends ActivityLifecycleClientTestBase {
 
diff --git a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecyclePipTests.java b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecyclePipTests.java
index 022779b..0fbc0ca 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecyclePipTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecyclePipTests.java
@@ -36,16 +36,12 @@
 import android.content.ComponentName;
 import android.content.Intent;
 import android.platform.test.annotations.Presubmit;
-import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.FlakyTest;
 import android.support.test.filters.MediumTest;
-import android.support.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
 import org.junit.Test;
-import org.junit.runner.RunWith;
 
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
@@ -53,10 +49,9 @@
  * Build/Install/Run:
  *     atest CtsActivityManagerDeviceTestCases:ActivityLifecyclePipTests
  */
-@MediumTest
-@RunWith(AndroidJUnit4.class)
-@Presubmit
 @FlakyTest(bugId = 77652261)
+@MediumTest
+@Presubmit
 public class ActivityLifecyclePipTests extends ActivityLifecycleClientTestBase {
 
     @Before
diff --git a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleSplitScreenTests.java b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleSplitScreenTests.java
index a6c10fa..7707f1b 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleSplitScreenTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleSplitScreenTests.java
@@ -20,7 +20,6 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
 import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
-import static android.server.am.Components.PipActivity.EXTRA_ENTER_PIP;
 import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_ACTIVITY_RESULT;
 import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_CREATE;
 import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_DESTROY;
@@ -35,6 +34,7 @@
 import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_TOP_POSITION_LOST;
 import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.PRE_ON_CREATE;
 import static android.server.am.lifecycle.LifecycleVerifier.transition;
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
 
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assume.assumeTrue;
@@ -44,16 +44,12 @@
 import android.content.ComponentName;
 import android.content.Intent;
 import android.platform.test.annotations.Presubmit;
-import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.FlakyTest;
 import android.support.test.filters.MediumTest;
-import android.support.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
 import org.junit.Test;
-import org.junit.runner.RunWith;
 
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
@@ -61,10 +57,9 @@
  * Build/Install/Run:
  *     atest CtsActivityManagerDeviceTestCases:ActivityLifecycleSplitScreenTests
  */
-@MediumTest
-@RunWith(AndroidJUnit4.class)
-@Presubmit
 @FlakyTest(bugId = 77652261)
+@MediumTest
+@Presubmit
 public class ActivityLifecycleSplitScreenTests extends ActivityLifecycleClientTestBase {
 
     @Before
@@ -227,8 +222,7 @@
 
         // Launch second activity
         // Create an ActivityMonitor that catch ChildActivity and return mock ActivityResult:
-        Instrumentation.ActivityMonitor activityMonitor = InstrumentationRegistry
-                .getInstrumentation()
+        Instrumentation.ActivityMonitor activityMonitor = getInstrumentation()
                 .addMonitor(SecondActivity.class.getName(), null /* activityResult */,
                         false /* block */);
 
@@ -236,7 +230,7 @@
                 new Intent(callbackTrackingActivity, SecondActivity.class), 1 /* requestCode */);
 
         // Wait for the ActivityMonitor to be hit
-        final Activity secondActivity = InstrumentationRegistry.getInstrumentation()
+        final Activity secondActivity = getInstrumentation()
                 .waitForMonitorWithTimeout(activityMonitor, 5 * 1000);
 
         // Wait for second activity to resume
diff --git a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleTests.java b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleTests.java
index d09d554..d20f1b3 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleTests.java
@@ -16,18 +16,14 @@
 
 package android.server.am.lifecycle;
 
-import static android.app.ActivityTaskManager.INVALID_STACK_ID;
 import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
 import static android.server.am.ActivityManagerState.STATE_PAUSED;
 import static android.server.am.ActivityManagerState.STATE_STOPPED;
-import static android.server.am.Components.PipActivity.EXTRA_ENTER_PIP;
 import static android.server.am.UiDeviceUtils.pressBackButton;
 import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_ACTIVITY_RESULT;
 import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_CREATE;
 import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_DESTROY;
-import static android.server.am.lifecycle.LifecycleLog.ActivityCallback
-        .ON_MULTI_WINDOW_MODE_CHANGED;
 import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_NEW_INTENT;
 import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_PAUSE;
 import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_POST_CREATE;
@@ -38,12 +34,12 @@
 import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_TOP_POSITION_GAINED;
 import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_TOP_POSITION_LOST;
 import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.PRE_ON_CREATE;
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
 import static android.view.Surface.ROTATION_0;
 import static android.view.Surface.ROTATION_180;
 import static android.view.Surface.ROTATION_270;
 import static android.view.Surface.ROTATION_90;
 
-import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.fail;
 
 import android.app.Activity;
@@ -51,17 +47,13 @@
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
 import android.platform.test.annotations.Presubmit;
-import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.FlakyTest;
 import android.support.test.filters.MediumTest;
-import android.support.test.runner.AndroidJUnit4;
 
 import com.android.compatibility.common.util.AmUtils;
 
 import org.junit.Test;
-import org.junit.runner.RunWith;
 
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
@@ -69,10 +61,9 @@
  * Build/Install/Run:
  *     atest CtsActivityManagerDeviceTestCases:ActivityLifecycleTests
  */
-@MediumTest
-@RunWith(AndroidJUnit4.class)
-@Presubmit
 @FlakyTest(bugId = 77652261)
+@MediumTest
+@Presubmit
 public class ActivityLifecycleTests extends ActivityLifecycleClientTestBase {
 
     @Test
@@ -297,7 +288,7 @@
         waitAndAssertActivityStates(state(activity, ON_RESUME));
 
         getLifecycleLog().clear();
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(activity::recreate);
+        getInstrumentation().runOnMainSync(activity::recreate);
         waitAndAssertActivityStates(state(activity, ON_RESUME));
 
         LifecycleVerifier.assertRelaunchSequence(FirstActivity.class, getLifecycleLog(), ON_RESUME);
@@ -313,7 +304,7 @@
                 state(topTranslucentActivity, ON_RESUME));
 
         getLifecycleLog().clear();
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(pausedActivity::recreate);
+        getInstrumentation().runOnMainSync(pausedActivity::recreate);
         waitAndAssertActivityStates(state(pausedActivity, ON_PAUSE));
 
         LifecycleVerifier.assertRelaunchSequence(FirstActivity.class, getLifecycleLog(), ON_PAUSE);
@@ -328,7 +319,7 @@
                 occludedActivityState(stoppedActivity, topActivity), state(topActivity, ON_RESUME));
 
         getLifecycleLog().clear();
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(stoppedActivity::recreate);
+        getInstrumentation().runOnMainSync(stoppedActivity::recreate);
         waitAndAssertActivityStates(occludedActivityState(stoppedActivity, topActivity));
 
         LifecycleVerifier.assertRelaunchSequence(FirstActivity.class, getLifecycleLog(),
@@ -496,7 +487,7 @@
 
         // Call "recreate" and assert sequence
         getLifecycleLog().clear();
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(trackingActivity::recreate);
+        getInstrumentation().runOnMainSync(trackingActivity::recreate);
         waitAndAssertActivityStates(state(trackingActivity, ON_TOP_POSITION_GAINED));
 
         LifecycleVerifier.assertSequence(CallbackTrackingActivity.class,
@@ -523,7 +514,7 @@
 
         // Call "recreate" and assert sequence
         getLifecycleLog().clear();
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(trackingActivity::recreate);
+        getInstrumentation().runOnMainSync(trackingActivity::recreate);
         waitAndAssertActivityStates(state(trackingActivity, ON_PAUSE));
 
         LifecycleVerifier.assertSequence(CallbackTrackingActivity.class,
@@ -554,7 +545,7 @@
 
         // Call "recreate" and assert sequence
         getLifecycleLog().clear();
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(trackingActivity::recreate);
+        getInstrumentation().runOnMainSync(trackingActivity::recreate);
         waitAndAssertActivityStates(occludedActivityState(trackingActivity, secondActivity));
 
         final List<LifecycleLog.ActivityCallback> callbacks;
@@ -626,11 +617,10 @@
 
         // Launch the activity again to recreate
         getLifecycleLog().clear();
-        final Intent intent = new Intent(InstrumentationRegistry.getContext(),
-                SingleTopActivity.class);
+        final Intent intent = new Intent(mContext, SingleTopActivity.class);
         intent.putExtra(EXTRA_RECREATE, true);
         intent.addFlags(FLAG_ACTIVITY_NEW_TASK);
-        InstrumentationRegistry.getTargetContext().startActivity(intent);
+        mTargetContext.startActivity(intent);
 
         // Wait for activity to relaunch and resume
         final List<List<LifecycleLog.ActivityCallback>> expectedRelaunchSequences;
@@ -669,10 +659,9 @@
 
         // Try to launch again
         getLifecycleLog().clear();
-        final Intent intent = new Intent(InstrumentationRegistry.getContext(),
-                SingleTopActivity.class);
+        final Intent intent = new Intent(mContext, SingleTopActivity.class);
         intent.addFlags(FLAG_ACTIVITY_NEW_TASK);
-        InstrumentationRegistry.getTargetContext().startActivity(intent);
+        mTargetContext.startActivity(intent);
 
         // Wait for the activity to resume again
         waitAndAssertActivityStates(state(singleTopActivity, ON_TOP_POSITION_GAINED));
@@ -705,10 +694,9 @@
 
         // Try to launch again
         getLifecycleLog().clear();
-        final Intent intent = new Intent(InstrumentationRegistry.getContext(),
-                SingleTopActivity.class);
+        final Intent intent = new Intent(mContext, SingleTopActivity.class);
         intent.addFlags(FLAG_ACTIVITY_NEW_TASK);
-        InstrumentationRegistry.getTargetContext().startActivity(intent);
+        mTargetContext.startActivity(intent);
 
         // Wait for the activity to resume again
         waitAndAssertActivityStates(state(singleTopActivity, ON_RESUME));
@@ -747,10 +735,9 @@
 
         // Try to launch again
         getLifecycleLog().clear();
-        final Intent intent = new Intent(InstrumentationRegistry.getContext(),
-                SingleTopActivity.class);
+        final Intent intent = new Intent(mContext, SingleTopActivity.class);
         intent.addFlags(FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
-        InstrumentationRegistry.getTargetContext().startActivity(intent);
+        mTargetContext.startActivity(intent);
 
         // Wait for the activity to resume again
         // TODO(b/77974794): New intent handling sequence should always be the same.
diff --git a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleTopResumedStateTests.java b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleTopResumedStateTests.java
index 5769014..df99ae8 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleTopResumedStateTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleTopResumedStateTests.java
@@ -4,8 +4,6 @@
 import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
 import static android.server.am.ActivityManagerDisplayTestBase.ReportedDisplayMetrics.getDisplayMetrics;
-import static android.server.am.Components.ALWAYS_FOCUSABLE_PIP_ACTIVITY;
-import static android.server.am.Components.BROADCAST_RECEIVER_ACTIVITY;
 import static android.server.am.Components.PipActivity.EXTRA_ENTER_PIP;
 import static android.server.am.UiDeviceUtils.pressHomeButton;
 import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_ACTIVITY_RESULT;
@@ -23,6 +21,7 @@
 import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_TOP_POSITION_LOST;
 import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.PRE_ON_CREATE;
 import static android.server.am.lifecycle.LifecycleVerifier.transition;
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
 import static android.view.Display.DEFAULT_DISPLAY;
 
 import static org.junit.Assert.assertEquals;
@@ -30,27 +29,17 @@
 
 import android.app.Activity;
 import android.app.ActivityOptions;
-import android.content.ComponentName;
 import android.content.Intent;
-import android.content.pm.ActivityInfo;
 import android.graphics.Rect;
-import android.os.Bundle;
 import android.platform.test.annotations.Presubmit;
-import android.server.am.ActivityManagerDisplayTestBase;
-import android.server.am.ActivityManagerDisplayTestBase.VirtualDisplaySession;
 import android.server.am.ActivityManagerState;
 import android.server.am.ActivityManagerState.ActivityStack;
-import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.FlakyTest;
 import android.support.test.filters.MediumTest;
-import android.support.test.runner.AndroidJUnit4;
 import android.util.Pair;
-import android.view.Display;
 
 import org.junit.Test;
-import org.junit.runner.RunWith;
 
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
@@ -60,10 +49,9 @@
  * Build/Install/Run:
  *     atest CtsActivityManagerDeviceTestCases:ActivityLifecycleTopResumedStateTests
  */
-@MediumTest
-@RunWith(AndroidJUnit4.class)
-@Presubmit
 @FlakyTest(bugId = 117135575)
+@MediumTest
+@Presubmit
 public class ActivityLifecycleTopResumedStateTests extends ActivityLifecycleClientTestBase {
 
     @Test
@@ -286,10 +274,9 @@
 
         // Switch top between two activities
         getLifecycleLog().clear();
-        final Intent switchToFirstIntent = new Intent(InstrumentationRegistry.getContext(),
-                CallbackTrackingActivity.class);
+        final Intent switchToFirstIntent = new Intent(mContext, CallbackTrackingActivity.class);
         switchToFirstIntent.addFlags(FLAG_ACTIVITY_NEW_TASK);
-        InstrumentationRegistry.getTargetContext().startActivity(switchToFirstIntent);
+        mTargetContext.startActivity(switchToFirstIntent);
 
         waitAndAssertActivityStates(state(firstActivity, ON_TOP_POSITION_GAINED),
                 state(secondActivity, ON_TOP_POSITION_LOST));
@@ -300,10 +287,9 @@
 
         // Switch top again
         getLifecycleLog().clear();
-        final Intent switchToSecondIntent = new Intent(InstrumentationRegistry.getContext(),
-                SingleTopActivity.class);
+        final Intent switchToSecondIntent = new Intent(mContext, SingleTopActivity.class);
         switchToSecondIntent.addFlags(FLAG_ACTIVITY_NEW_TASK);
-        InstrumentationRegistry.getTargetContext().startActivity(switchToSecondIntent);
+        mTargetContext.startActivity(switchToSecondIntent);
 
         waitAndAssertActivityStates(state(firstActivity, ON_TOP_POSITION_LOST),
                 state(secondActivity, ON_TOP_POSITION_GAINED));
@@ -322,10 +308,9 @@
 
         // Launch the activity again to observe new intent
         getLifecycleLog().clear();
-        final Intent newIntent = new Intent(InstrumentationRegistry.getContext(),
-                SingleTopActivity.class);
+        final Intent newIntent = new Intent(mContext, SingleTopActivity.class);
         newIntent.addFlags(FLAG_ACTIVITY_NEW_TASK);
-        InstrumentationRegistry.getTargetContext().startActivity(newIntent);
+        mTargetContext.startActivity(newIntent);
 
         waitAndAssertActivityTransitions(SingleTopActivity.class,
                 Arrays.asList(ON_TOP_POSITION_LOST, ON_PAUSE, ON_NEW_INTENT, ON_RESUME,
@@ -345,10 +330,9 @@
 
         // Launch the single top activity again to observe new intent
         getLifecycleLog().clear();
-        final Intent newIntent = new Intent(InstrumentationRegistry.getContext(),
-                SingleTopActivity.class);
+        final Intent newIntent = new Intent(mContext, SingleTopActivity.class);
         newIntent.addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP);
-        InstrumentationRegistry.getTargetContext().startActivity(newIntent);
+        mTargetContext.startActivity(newIntent);
 
         waitAndAssertActivityStates(state(singleTopActivity, ON_TOP_POSITION_GAINED),
                 state(topActivity, ON_DESTROY));
@@ -380,10 +364,9 @@
 
         // Launch the single top activity again to observe new intent
         getLifecycleLog().clear();
-        final Intent newIntent = new Intent(InstrumentationRegistry.getContext(),
-                SingleTopActivity.class);
+        final Intent newIntent = new Intent(mContext, SingleTopActivity.class);
         newIntent.addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP);
-        InstrumentationRegistry.getTargetContext().startActivity(newIntent);
+        mTargetContext.startActivity(newIntent);
 
         waitAndAssertActivityStates(state(singleTopActivity, ON_TOP_POSITION_GAINED),
                 state(topActivity, ON_DESTROY));
@@ -478,7 +461,7 @@
         waitAndAssertActivityStates(state(activity, ON_TOP_POSITION_GAINED));
 
         getLifecycleLog().clear();
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(activity::recreate);
+        getInstrumentation().runOnMainSync(activity::recreate);
         waitAndAssertActivityStates(state(activity, ON_TOP_POSITION_GAINED));
 
         LifecycleVerifier.assertRelaunchSequence(CallbackTrackingActivity.class, getLifecycleLog(),
@@ -568,11 +551,9 @@
         // Launch activity on default display.
         final ActivityOptions launchOptions = ActivityOptions.makeBasic();
         launchOptions.setLaunchDisplayId(DEFAULT_DISPLAY);
-        final Intent defaultDisplayIntent =
-                new Intent(InstrumentationRegistry.getContext(), CallbackTrackingActivity.class);
+        final Intent defaultDisplayIntent = new Intent(mContext, CallbackTrackingActivity.class);
         defaultDisplayIntent.setFlags(FLAG_ACTIVITY_NEW_TASK);
-        InstrumentationRegistry.getTargetContext().startActivity(defaultDisplayIntent,
-                launchOptions.toBundle());
+        mTargetContext.startActivity(defaultDisplayIntent, launchOptions.toBundle());
 
         waitAndAssertTopResumedActivity(getComponentName(CallbackTrackingActivity.class),
                 DEFAULT_DISPLAY, "Activity launched on default display must be focused");
@@ -587,11 +568,9 @@
             // Launch another activity on new secondary display.
             getLifecycleLog().clear();
             launchOptions.setLaunchDisplayId(newDisplay.mId);
-            final Intent newDisplayIntent =
-                    new Intent(InstrumentationRegistry.getContext(), SingleTopActivity.class);
+            final Intent newDisplayIntent = new Intent(mContext, SingleTopActivity.class);
             newDisplayIntent.setFlags(FLAG_ACTIVITY_NEW_TASK);
-            InstrumentationRegistry.getTargetContext().startActivity(newDisplayIntent,
-                    launchOptions.toBundle());
+            mTargetContext.startActivity(newDisplayIntent, launchOptions.toBundle());
             waitAndAssertTopResumedActivity(getComponentName(SingleTopActivity.class),
                     newDisplay.mId, "Activity launched on secondary display must be focused");
 
@@ -627,11 +606,9 @@
         // Launch activity on default display.
         final ActivityOptions launchOptions = ActivityOptions.makeBasic();
         launchOptions.setLaunchDisplayId(DEFAULT_DISPLAY);
-        final Intent defaultDisplayIntent =
-                new Intent(InstrumentationRegistry.getContext(), CallbackTrackingActivity.class);
+        final Intent defaultDisplayIntent = new Intent(mContext, CallbackTrackingActivity.class);
         defaultDisplayIntent.setFlags(FLAG_ACTIVITY_NEW_TASK);
-        InstrumentationRegistry.getTargetContext().startActivity(defaultDisplayIntent,
-                launchOptions.toBundle());
+        mTargetContext.startActivity(defaultDisplayIntent, launchOptions.toBundle());
 
         waitAndAssertTopResumedActivity(getComponentName(CallbackTrackingActivity.class),
                 DEFAULT_DISPLAY, "Activity launched on default display must be focused");
@@ -644,11 +621,9 @@
             // Launch another activity on new secondary display.
             getLifecycleLog().clear();
             launchOptions.setLaunchDisplayId(newDisplay.mId);
-            final Intent newDisplayIntent =
-                    new Intent(InstrumentationRegistry.getContext(), SingleTopActivity.class);
+            final Intent newDisplayIntent = new Intent(mContext, SingleTopActivity.class);
             newDisplayIntent.setFlags(FLAG_ACTIVITY_NEW_TASK);
-            InstrumentationRegistry.getTargetContext().startActivity(newDisplayIntent,
-                    launchOptions.toBundle());
+            mTargetContext.startActivity(newDisplayIntent, launchOptions.toBundle());
             waitAndAssertTopResumedActivity(getComponentName(SingleTopActivity.class),
                     newDisplay.mId, "Activity launched on secondary display must be focused");
 
diff --git a/tests/framework/base/activitymanager/testsdk25/src/android/server/am/AspectRatioSdk25Tests.java b/tests/framework/base/activitymanager/testsdk25/src/android/server/am/AspectRatioSdk25Tests.java
index f2c2477..89313c99 100644
--- a/tests/framework/base/activitymanager/testsdk25/src/android/server/am/AspectRatioSdk25Tests.java
+++ b/tests/framework/base/activitymanager/testsdk25/src/android/server/am/AspectRatioSdk25Tests.java
@@ -17,22 +17,18 @@
 package android.server.am;
 
 import static org.junit.Assert.assertThat;
-import static org.junit.Assert.fail;
 
 import android.app.Activity;
 import android.platform.test.annotations.Presubmit;
 import android.support.test.rule.ActivityTestRule;
-import android.support.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
 import org.junit.Test;
-import org.junit.runner.RunWith;
 
 /**
  * Build: mmma -j32 cts/tests/framework/base/activitymanager
  * Run: cts/tests/framework/base/activitymanager/util/run-test CtsActivityManagerDeviceSdk25TestCases android.server.am.AspectRatioSdk25Tests
  */
-@RunWith(AndroidJUnit4.class)
 @Presubmit
 public class AspectRatioSdk25Tests extends AspectRatioTestsBase {
 
diff --git a/tests/framework/base/activitymanager/testsdk28/src/android/server/am/AspectRatioSdk28Tests.java b/tests/framework/base/activitymanager/testsdk28/src/android/server/am/AspectRatioSdk28Tests.java
index 7eaa464..377cbf5 100644
--- a/tests/framework/base/activitymanager/testsdk28/src/android/server/am/AspectRatioSdk28Tests.java
+++ b/tests/framework/base/activitymanager/testsdk28/src/android/server/am/AspectRatioSdk28Tests.java
@@ -17,23 +17,20 @@
 package android.server.am;
 
 import static android.content.pm.PackageManager.FEATURE_WATCH;
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
 
 import static org.junit.Assert.assertThat;
 
 import android.app.Activity;
 import android.platform.test.annotations.Presubmit;
-import android.support.test.InstrumentationRegistry;
 import android.support.test.rule.ActivityTestRule;
-import android.support.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
 import org.junit.Test;
-import org.junit.runner.RunWith;
 
 /**
  * Run: atest AspectRatioSdk28Tests
  */
-@RunWith(AndroidJUnit4.class)
 @Presubmit
 public class AspectRatioSdk28Tests extends AspectRatioTestsBase {
 
@@ -55,7 +52,7 @@
 
     @Test
     public void testMaxAspectRatioPreQActivity() {
-        boolean isWatch = InstrumentationRegistry.getContext().getPackageManager()
+        boolean isWatch = getInstrumentation().getContext().getPackageManager()
                 .hasSystemFeature(FEATURE_WATCH);
         float minAspectRatio = isWatch ? MIN_WATCH_DEVICE_ASPECT_RATIO : MIN_DEVICE_ASPECT_RATIO;
 
diff --git a/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerState.java b/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerState.java
index adc0ea9..96f406d 100644
--- a/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerState.java
+++ b/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerState.java
@@ -26,17 +26,16 @@
 import static android.server.am.ProtoExtractors.extract;
 import static android.server.am.StateLogger.log;
 import static android.server.am.StateLogger.logE;
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
 
 import android.content.ComponentName;
 import android.graphics.Rect;
 import android.os.ParcelFileDescriptor;
 import android.os.SystemClock;
-import android.support.test.InstrumentationRegistry;
+import android.util.SparseArray;
 
 import androidx.annotation.Nullable;
 
-import android.util.SparseArray;
-
 import com.android.server.am.nano.ActivityDisplayProto;
 import com.android.server.am.nano.ActivityManagerServiceDumpActivitiesProto;
 import com.android.server.am.nano.ActivityRecordProto;
@@ -136,9 +135,8 @@
 
     private byte[] executeShellCommand(String cmd) {
         try {
-            ParcelFileDescriptor pfd =
-                    InstrumentationRegistry.getInstrumentation().getUiAutomation()
-                            .executeShellCommand(cmd);
+            ParcelFileDescriptor pfd = getInstrumentation().getUiAutomation()
+                    .executeShellCommand(cmd);
             byte[] buf = new byte[512];
             int bytesRead;
             FileInputStream fis = new ParcelFileDescriptor.AutoCloseInputStream(pfd);
@@ -252,6 +250,21 @@
         return mResumedActivitiesInStacks.size();
     }
 
+    int getResumedActivitiesCountInPackage(String packageName) {
+        final String componentPrefix = packageName + "/";
+        int count = 0;
+        for (int i = mDisplays.size() - 1; i >= 0; --i) {
+            final ArrayList<ActivityStack> mStacks = mDisplays.get(i).getStacks();
+            for (int j = mStacks.size() - 1; j >= 0; --j) {
+                final String resumedActivity = mStacks.get(j).mResumedActivity;
+                if (resumedActivity != null && resumedActivity.startsWith(componentPrefix)) {
+                    count++;
+                }
+            }
+        }
+        return count;
+    }
+
     String getResumedActivityOnDisplay(int displayId) {
         return getDisplay(displayId).mResumedActivity;
     }
diff --git a/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java b/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java
index f429418..7ea9fb9 100644
--- a/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java
+++ b/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java
@@ -82,7 +82,7 @@
 import static android.server.am.UiDeviceUtils.pressUnlockButton;
 import static android.server.am.UiDeviceUtils.pressWakeupButton;
 import static android.server.am.UiDeviceUtils.waitForDeviceIdle;
-import static android.support.test.InstrumentationRegistry.getContext;
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.INVALID_DISPLAY;
 import static android.view.Surface.ROTATION_0;
@@ -123,7 +123,6 @@
 import android.server.am.CommandSession.SizeInfo;
 import android.server.am.TestJournalProvider.TestJournalContainer;
 import android.server.am.settings.SettingsSession;
-import android.support.test.InstrumentationRegistry;
 import android.support.test.rule.ActivityTestRule;
 import android.util.EventLog;
 import android.util.EventLog.Event;
@@ -352,7 +351,7 @@
             SystemUtil.runWithShellPermissionIdentity(() -> {
                 final Bundle bundle = ActivityOptions.makeBasic()
                         .setLaunchDisplayId(displayId).toBundle();
-                final ActivityMonitor monitor = InstrumentationRegistry.getInstrumentation()
+                final ActivityMonitor monitor = getInstrumentation()
                         .addMonitor((String) null, null, false);
                 mContext.startActivity(new Intent(mContext, activityClass)
                         .addFlags(FLAG_ACTIVITY_NEW_TASK), bundle);
@@ -374,8 +373,8 @@
         }
 
         void runOnMainSyncAndWait(Runnable runnable) {
-            InstrumentationRegistry.getInstrumentation().runOnMainSync(runnable);
-            InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+            getInstrumentation().runOnMainSync(runnable);
+            getInstrumentation().waitForIdleSync();
         }
 
         void runOnMainAndAssertWithTimeout(@NonNull BooleanSupplier condition, long timeoutMs,
@@ -409,7 +408,7 @@
 
     @Before
     public void setUp() throws Exception {
-        mContext = InstrumentationRegistry.getContext();
+        mContext = getInstrumentation().getContext();
         mAm = mContext.getSystemService(ActivityManager.class);
         mAtm = mContext.getSystemService(ActivityTaskManager.class);
 
@@ -474,8 +473,7 @@
                 x, y, 0 /* metaState */);
         event.setSource(InputDevice.SOURCE_TOUCHSCREEN);
         event.setDisplayId(displayId);
-        InstrumentationRegistry.getInstrumentation().getUiAutomation().injectInputEvent(
-                event, true /* sync */);
+        getInstrumentation().getUiAutomation().injectInputEvent(event, true /* sync */);
     }
 
     protected void removeStacksWithActivityTypes(int... activityTypes) {
@@ -494,8 +492,7 @@
     public static String executeShellCommand(String command) {
         log("Shell command: " + command);
         try {
-            return SystemUtil
-                    .runShellCommand(InstrumentationRegistry.getInstrumentation(), command);
+            return SystemUtil.runShellCommand(getInstrumentation(), command);
         } catch (IOException e) {
             //bubble it up
             logE("Error running shell command: " + command);
@@ -504,7 +501,7 @@
     }
 
     protected Bitmap takeScreenshot() {
-        return InstrumentationRegistry.getInstrumentation().getUiAutomation().takeScreenshot();
+        return getInstrumentation().getUiAutomation().takeScreenshot();
     }
 
     protected void launchActivity(final ComponentName activityName, final String... keyValuePairs) {
@@ -523,7 +520,7 @@
     }
 
     private static void waitForIdle() {
-        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+        getInstrumentation().waitForIdleSync();
     }
 
     /** Returns the set of stack ids. */
@@ -843,13 +840,13 @@
     }
 
     protected boolean hasDeviceFeature(final String requiredFeature) {
-        return InstrumentationRegistry.getContext()
-                .getPackageManager()
+        return mContext.getPackageManager()
                 .hasSystemFeature(requiredFeature);
     }
 
     protected static boolean isDisplayOn(int displayId) {
-        final DisplayManager displayManager = getContext().getSystemService(DisplayManager.class);
+        final DisplayManager displayManager = getInstrumentation()
+                .getContext().getSystemService(DisplayManager.class);
         final Display display = displayManager.getDisplay(displayId);
         return display != null && display.getState() == Display.STATE_ON;
     }
@@ -978,7 +975,7 @@
 
             waitForDeviceIdle(3000);
             SystemUtil.runWithShellPermissionIdentity(() ->
-                    InstrumentationRegistry.getInstrumentation().sendStringSync(LOCK_CREDENTIAL));
+                    getInstrumentation().sendStringSync(LOCK_CREDENTIAL));
             pressEnterButton();
             return this;
         }
@@ -998,7 +995,7 @@
             // Not all device variants lock when we go to sleep, so we need to explicitly lock the
             // device. Note that pressSleepButton() above is redundant because the action also
             // puts the device to sleep, but kept around for clarity.
-            InstrumentationRegistry.getInstrumentation().getUiAutomation().performGlobalAction(
+            getInstrumentation().getUiAutomation().performGlobalAction(
                     AccessibilityService.GLOBAL_ACTION_LOCK_SCREEN);
             for (int retry = 1; isDisplayOn(DEFAULT_DISPLAY) && retry <= 5; retry++) {
                 logAlways("***Waiting for display to turn off... retry=" + retry);
@@ -1835,7 +1832,7 @@
             b.putString(KEY_TARGET_COMPONENT, getActivityName(mTargetActivity));
             b.putBoolean(KEY_SUPPRESS_EXCEPTIONS, mSuppressExceptions);
             b.putInt(KEY_INTENT_FLAGS, mIntentFlags);
-            final Context context = InstrumentationRegistry.getContext();
+            final Context context = getInstrumentation().getContext();
             launchActivityFromExtras(context, b, mLaunchInjector);
         }
 
diff --git a/tests/framework/base/activitymanager/util/src/android/server/am/CommandSession.java b/tests/framework/base/activitymanager/util/src/android/server/am/CommandSession.java
index 62f759e..bf6d350 100644
--- a/tests/framework/base/activitymanager/util/src/android/server/am/CommandSession.java
+++ b/tests/framework/base/activitymanager/util/src/android/server/am/CommandSession.java
@@ -16,6 +16,8 @@
 
 package android.server.am;
 
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
+
 import android.app.Activity;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
@@ -34,7 +36,6 @@
 import android.os.Parcelable;
 import android.os.SystemClock;
 import android.server.am.TestJournalProvider.TestJournalClient;
-import android.support.test.InstrumentationRegistry;
 import android.util.ArrayMap;
 import android.util.DisplayMetrics;
 import android.util.Log;
@@ -360,7 +361,7 @@
         private boolean mClosed;
 
         public ActivitySessionClient() {
-            this(InstrumentationRegistry.getContext());
+            this(getInstrumentation().getContext());
         }
 
         public ActivitySessionClient(Context context) {
diff --git a/tests/framework/base/activitymanager/util/src/android/server/am/UiDeviceUtils.java b/tests/framework/base/activitymanager/util/src/android/server/am/UiDeviceUtils.java
index 3d89529..0071675 100644
--- a/tests/framework/base/activitymanager/util/src/android/server/am/UiDeviceUtils.java
+++ b/tests/framework/base/activitymanager/util/src/android/server/am/UiDeviceUtils.java
@@ -17,7 +17,7 @@
 package android.server.am;
 
 import static android.server.am.StateLogger.logE;
-import static android.support.test.InstrumentationRegistry.getContext;
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
 import static android.view.KeyEvent.KEYCODE_APP_SWITCH;
 import static android.view.KeyEvent.KEYCODE_MENU;
 import static android.view.KeyEvent.KEYCODE_SLEEP;
@@ -29,7 +29,6 @@
 import android.os.PowerManager;
 import android.os.RemoteException;
 import android.os.SystemClock;
-import android.support.test.InstrumentationRegistry;
 import android.support.test.uiautomator.UiDevice;
 import android.util.Log;
 import android.view.KeyEvent;
@@ -83,21 +82,24 @@
 
     static void pressSleepButton() {
         if (DEBUG) Log.d(TAG, "pressSleepButton");
-        final PowerManager pm = getContext().getSystemService(PowerManager.class);
+        final PowerManager pm = getInstrumentation()
+                .getContext().getSystemService(PowerManager.class);
         retryPressKeyCode(KEYCODE_SLEEP, () -> pm != null && !pm.isInteractive(),
                 "***Waiting for device sleep...");
     }
 
     public static void pressWakeupButton() {
         if (DEBUG) Log.d(TAG, "pressWakeupButton");
-        final PowerManager pm = getContext().getSystemService(PowerManager.class);
+        final PowerManager pm = getInstrumentation()
+                .getContext().getSystemService(PowerManager.class);
         retryPressKeyCode(KEYCODE_WAKEUP, () -> pm != null && pm.isInteractive(),
                 "***Waiting for device wakeup...");
     }
 
     public static void pressUnlockButton() {
         if (DEBUG) Log.d(TAG, "pressUnlockButton");
-        final KeyguardManager kgm = getContext().getSystemService(KeyguardManager.class);
+        final KeyguardManager kgm = getInstrumentation()
+                .getContext().getSystemService(KeyguardManager.class);
         retryPressKeyCode(KEYCODE_MENU, () -> kgm != null && !kgm.isKeyguardLocked(),
                 "***Waiting for device unlock...");
     }
@@ -132,6 +134,6 @@
     }
 
     private static UiDevice getDevice() {
-        return UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+        return UiDevice.getInstance(getInstrumentation());
     }
 }
diff --git a/tests/framework/base/activitymanager/util/src/android/server/am/WindowManagerState.java b/tests/framework/base/activitymanager/util/src/android/server/am/WindowManagerState.java
index 459dffb..fd943ef 100644
--- a/tests/framework/base/activitymanager/util/src/android/server/am/WindowManagerState.java
+++ b/tests/framework/base/activitymanager/util/src/android/server/am/WindowManagerState.java
@@ -22,6 +22,7 @@
 import static android.server.am.ProtoExtractors.extract;
 import static android.server.am.StateLogger.log;
 import static android.server.am.StateLogger.logE;
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
 import static android.view.Display.DEFAULT_DISPLAY;
 
 import static org.junit.Assert.assertTrue;
@@ -31,7 +32,6 @@
 import android.graphics.Rect;
 import android.os.ParcelFileDescriptor;
 import android.os.SystemClock;
-import android.support.test.InstrumentationRegistry;
 import android.view.WindowManager;
 import android.view.nano.DisplayInfoProto;
 import android.view.nano.ViewProtoEnums;
@@ -166,9 +166,8 @@
 
     private byte[] executeShellCommand(String cmd) {
         try {
-            ParcelFileDescriptor pfd =
-                    InstrumentationRegistry.getInstrumentation().getUiAutomation()
-                            .executeShellCommand(cmd);
+            ParcelFileDescriptor pfd = getInstrumentation().getUiAutomation()
+                    .executeShellCommand(cmd);
             byte[] buf = new byte[512];
             int bytesRead;
             FileInputStream fis = new ParcelFileDescriptor.AutoCloseInputStream(pfd);
diff --git a/tests/framework/base/activitymanager/util/src/android/server/am/settings/SettingsSession.java b/tests/framework/base/activitymanager/util/src/android/server/am/settings/SettingsSession.java
index 4dd800f..354b08e 100644
--- a/tests/framework/base/activitymanager/util/src/android/server/am/settings/SettingsSession.java
+++ b/tests/framework/base/activitymanager/util/src/android/server/am/settings/SettingsSession.java
@@ -1,12 +1,30 @@
+/*
+ * Copyright (C) 2017 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.server.am.settings;
 
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
+
 import android.content.ContentResolver;
 import android.net.Uri;
 import android.provider.Settings.SettingNotFoundException;
-import androidx.annotation.NonNull;
-import android.support.test.InstrumentationRegistry;
 import android.util.Log;
 
+import androidx.annotation.NonNull;
+
 import com.android.compatibility.common.util.SystemUtil;
 
 import java.util.HashMap;
@@ -146,7 +164,7 @@
     }
 
     private static ContentResolver getContentResolver() {
-        return InstrumentationRegistry.getTargetContext().getContentResolver();
+        return getInstrumentation().getTargetContext().getContentResolver();
     }
 
     private static class SessionCounters {
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/AlertWindowsAppOpsTests.java b/tests/framework/base/windowmanager/src/android/server/wm/AlertWindowsAppOpsTests.java
index 166037f..af08319 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/AlertWindowsAppOpsTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/AlertWindowsAppOpsTests.java
@@ -16,29 +16,12 @@
 
 package android.server.wm;
 
-import android.app.AppOpsManager;
-import android.os.Process;
-import android.support.test.InstrumentationRegistry;
-import android.platform.test.annotations.Presubmit;
-import android.support.test.filters.FlakyTest;
-import android.support.test.rule.ActivityTestRule;
-import android.support.test.runner.AndroidJUnit4;
-import com.android.compatibility.common.util.AppOpsUtils;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.io.IOException;
-import java.util.concurrent.TimeUnit;
-
-import static android.support.test.InstrumentationRegistry.getContext;
-
 import static android.app.AppOpsManager.MODE_ALLOWED;
 import static android.app.AppOpsManager.MODE_ERRORED;
 import static android.app.AppOpsManager.OPSTR_SYSTEM_ALERT_WINDOW;
 import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
+
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.anyBoolean;
@@ -50,14 +33,30 @@
 import static org.mockito.Mockito.timeout;
 import static org.mockito.Mockito.verify;
 
+import android.app.AppOpsManager;
+import android.os.Process;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.FlakyTest;
+import android.support.test.rule.ActivityTestRule;
+
+import com.android.compatibility.common.util.AppOpsUtils;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+
 /**
  * Test whether system alert window properly interacts with app ops.
  *
- * Build/Install/Run: atest CtsWindowManagerDeviceTestCases:AlertWindowsAppOpsTests
+ * Build/Install/Run:
+ *     atest CtsWindowManagerDeviceTestCases:AlertWindowsAppOpsTests
  */
-@Presubmit
 @FlakyTest(detail = "Can be promoted to pre-submit once confirmed stable.")
-@RunWith(AndroidJUnit4.class)
+@Presubmit
 public class AlertWindowsAppOpsTests {
     private static final long APP_OP_CHANGE_TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(2);
 
@@ -67,22 +66,23 @@
 
     @BeforeClass
     public static void grantSystemAlertWindowAccess() throws IOException {
-        AppOpsUtils.setOpMode(getContext().getPackageName(),
+        AppOpsUtils.setOpMode(getInstrumentation().getContext().getPackageName(),
                 OPSTR_SYSTEM_ALERT_WINDOW, MODE_ALLOWED);
     }
 
     @AfterClass
     public static void revokeSystemAlertWindowAccess() throws IOException {
-        AppOpsUtils.setOpMode(getContext().getPackageName(),
+        AppOpsUtils.setOpMode(getInstrumentation().getContext().getPackageName(),
                 OPSTR_SYSTEM_ALERT_WINDOW, MODE_ERRORED);
     }
 
     @Test
     public void testSystemAlertWindowAppOpsInitiallyAllowed() {
-        final String packageName = getContext().getPackageName();
+        final String packageName = getInstrumentation().getContext().getPackageName();
         final int uid = Process.myUid();
 
-        final AppOpsManager appOpsManager = getContext().getSystemService(AppOpsManager.class);
+        final AppOpsManager appOpsManager = getInstrumentation().getContext()
+                .getSystemService(AppOpsManager.class);
         final AppOpsManager.OnOpActiveChangedListener listener = mock(
                 AppOpsManager.OnOpActiveChangedListener.class);
 
@@ -97,8 +97,7 @@
 
 
         // Show a system alert window.
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(
-                activity::showSystemAlertWindow);
+        getInstrumentation().runOnMainSync(activity::showSystemAlertWindow);
 
         // The app op should start
         verify(listener, timeout(APP_OP_CHANGE_TIMEOUT_MILLIS)
@@ -114,8 +113,7 @@
         reset(listener);
 
         // Hide a system alert window.
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(
-                activity::hideSystemAlertWindow);
+        getInstrumentation().runOnMainSync(activity::hideSystemAlertWindow);
 
         // The app op should finish
         verify(listener, timeout(APP_OP_CHANGE_TIMEOUT_MILLIS)
@@ -133,8 +131,7 @@
         appOpsManager.stopWatchingActive(listener);
 
         // Show a system alert window
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(
-                activity::showSystemAlertWindow);
+        getInstrumentation().runOnMainSync(activity::showSystemAlertWindow);
 
         // No other callbacks expected
         verify(listener, timeout(APP_OP_CHANGE_TIMEOUT_MILLIS).times(0))
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/AlertWindowsImportanceTests.java b/tests/framework/base/windowmanager/src/android/server/wm/AlertWindowsImportanceTests.java
index 6657446..0c4e5d8 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/AlertWindowsImportanceTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/AlertWindowsImportanceTests.java
@@ -27,6 +27,7 @@
 import static android.content.Context.BIND_NOT_FOREGROUND;
 import static android.server.wm.alertwindowappsdk25.Components.SDK25_ALERT_WINDOW_TEST_ACTIVITY;
 import static android.server.wm.alertwindowservice.Components.ALERT_WINDOW_SERVICE;
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
 
 import static org.junit.Assert.assertEquals;
 
@@ -34,8 +35,8 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
-import android.content.res.Configuration;
 import android.content.ServiceConnection;
+import android.content.res.Configuration;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
@@ -45,8 +46,6 @@
 import android.platform.test.annotations.AppModeFull;
 import android.platform.test.annotations.Presubmit;
 import android.server.wm.alertwindowservice.AlertWindowService;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
 import android.util.Log;
 
 import com.android.compatibility.common.util.AppOpsUtils;
@@ -54,7 +53,6 @@
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
-import org.junit.runner.RunWith;
 
 import java.util.concurrent.TimeUnit;
 import java.util.function.ToIntFunction;
@@ -64,7 +62,6 @@
  *     atest CtsWindowManagerDeviceTestCases:AlertWindowsImportanceTests
  */
 @Presubmit
-@RunWith(AndroidJUnit4.class)
 public final class AlertWindowsImportanceTests {
 
     private static final String TAG = "AlertWindowsTests";
@@ -85,7 +82,7 @@
     @Before
     public void setUp() throws Exception {
         if (DEBUG) Log.e(TAG, "setUp");
-        final Context context = InstrumentationRegistry.getTargetContext();
+        final Context context = getInstrumentation().getTargetContext();
 
         mAm = context.getSystemService(ActivityManager.class);
         mAm25 = context.createPackageContext(SDK25_ALERT_WINDOW_TEST_ACTIVITY.getPackageName(), 0)
@@ -110,7 +107,7 @@
         if (mService != null) {
             mService.send(Message.obtain(null, AlertWindowService.MSG_REMOVE_ALL_ALERT_WINDOWS));
         }
-        final Context context = InstrumentationRegistry.getTargetContext();
+        final Context context = getInstrumentation().getTargetContext();
         context.unbindService(mConnection);
         mAm = null;
         mAm25 = null;
@@ -180,8 +177,7 @@
     private void assertImportance(ToIntFunction<ActivityManager> apiCaller,
             int expectedForO, int expectedForPreO) throws Exception {
         try {
-            InstrumentationRegistry.getInstrumentation().getUiAutomation()
-                    .adoptShellPermissionIdentity();
+            getInstrumentation().getUiAutomation().adoptShellPermissionIdentity();
 
             final long TIMEOUT = SystemClock.uptimeMillis() + TimeUnit.SECONDS.toMillis(30);
             int actual;
@@ -198,8 +194,7 @@
             // Check the result for pre-O apps.
             assertEquals(expectedForPreO, apiCaller.applyAsInt(mAm25));
         } finally {
-            InstrumentationRegistry.getInstrumentation().getUiAutomation()
-                    .dropShellPermissionIdentity();
+            getInstrumentation().getUiAutomation().dropShellPermissionIdentity();
         }
     }
 
@@ -258,7 +253,7 @@
     }
 
     private boolean isRunningInVR() {
-        final Context context = InstrumentationRegistry.getTargetContext();
+        final Context context = getInstrumentation().getTargetContext();
         if ((context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_TYPE_MASK)
              == Configuration.UI_MODE_TYPE_VR_HEADSET) {
             return true;
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/CrossAppDragAndDropTests.java b/tests/framework/base/windowmanager/src/android/server/wm/CrossAppDragAndDropTests.java
index 7bf57e8..4a4098e 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/CrossAppDragAndDropTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/CrossAppDragAndDropTests.java
@@ -26,6 +26,7 @@
 import static android.server.am.UiDeviceUtils.dragPointer;
 import static android.server.am.UiDeviceUtils.pressMenuButton;
 import static android.server.am.UiDeviceUtils.wakeUpDevice;
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
@@ -41,10 +42,9 @@
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.os.RemoteException;
-import android.platform.test.annotations.AppModeFull;
 import android.os.SystemClock;
+import android.platform.test.annotations.AppModeFull;
 import android.platform.test.annotations.Presubmit;
-import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.FlakyTest;
 import android.support.test.runner.lifecycle.ActivityLifecycleCallback;
 import android.support.test.runner.lifecycle.ActivityLifecycleMonitorRegistry;
@@ -62,8 +62,8 @@
 import java.util.regex.Pattern;
 
 /**
- * Build: mmma -j32 cts/tests/framework/base
- * Run: cts/tests/framework/base/activitymanager/util/run-test CtsWindowManagerDeviceTestCases android.server.wm.CrossAppDragAndDropTests
+ * Build/Install/Run:
+ *     atest CtsWindowManagerDeviceTestCases:CrossAppDragAndDropTests
  */
 @Presubmit
 @AppModeFull(reason = "Requires android.permission.MANAGE_ACTIVITY_STACKS")
@@ -191,7 +191,7 @@
         mSourceLogTag = SOURCE_LOG_TAG + mSessionId;
         mTargetLogTag = TARGET_LOG_TAG + mSessionId;
 
-        mContext = InstrumentationRegistry.getContext();
+        mContext = getInstrumentation().getContext();
         mAm = mContext.getSystemService(ActivityManager.class);
         mAtm = mContext.getSystemService(ActivityTaskManager.class);
 
@@ -287,8 +287,7 @@
 
     private String findTaskInfo(String name) {
         try {
-            InstrumentationRegistry.getInstrumentation().getUiAutomation()
-                    .adoptShellPermissionIdentity();
+            getInstrumentation().getUiAutomation().adoptShellPermissionIdentity();
 
             final String output = mAtm.listAllStacks();
             final StringBuilder builder = new StringBuilder();
@@ -313,8 +312,7 @@
             }
             return "";
         } finally {
-            InstrumentationRegistry.getInstrumentation().getUiAutomation()
-                    .dropShellPermissionIdentity();
+            getInstrumentation().getUiAutomation().dropShellPermissionIdentity();
         }
     }
 
@@ -465,15 +463,16 @@
     }
 
     private static boolean supportsDragAndDrop() {
-        return ActivityTaskManager.supportsMultiWindow(InstrumentationRegistry.getContext());
+        return ActivityTaskManager.supportsMultiWindow(getInstrumentation().getContext());
     }
 
     private static boolean supportsSplitScreenMultiWindow() {
-        return ActivityTaskManager.supportsSplitScreenMultiWindow(InstrumentationRegistry.getContext());
+        return ActivityTaskManager.supportsSplitScreenMultiWindow(
+                getInstrumentation().getContext());
     }
 
     private static boolean supportsFreeformMultiWindow() {
-        return InstrumentationRegistry.getContext()
+        return getInstrumentation().getContext()
                 .getPackageManager()
                 .hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT);
     }
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/DialogFrameTests.java b/tests/framework/base/windowmanager/src/android/server/wm/DialogFrameTests.java
index 0946221..78f3534 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/DialogFrameTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/DialogFrameTests.java
@@ -29,6 +29,7 @@
 import static android.server.wm.DialogFrameTestActivity.TEST_OVER_SIZED_DIMENSIONS;
 import static android.server.wm.DialogFrameTestActivity.TEST_OVER_SIZED_DIMENSIONS_NO_LIMITS;
 import static android.server.wm.DialogFrameTestActivity.TEST_WITH_MARGINS;
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.greaterThan;
@@ -40,7 +41,6 @@
 import android.server.am.WaitForValidActivityState;
 import android.server.am.WindowManagerState;
 import android.server.am.WindowManagerState.WindowState;
-import android.support.test.InstrumentationRegistry;
 import android.support.test.rule.ActivityTestRule;
 
 import org.junit.Ignore;
@@ -59,7 +59,7 @@
 public class DialogFrameTests extends ParentChildTestBase<DialogFrameTestActivity> {
 
     private static final ComponentName DIALOG_FRAME_TEST_ACTIVITY = new ComponentName(
-            InstrumentationRegistry.getContext(), DialogFrameTestActivity.class);
+            getInstrumentation().getContext(), DialogFrameTestActivity.class);
 
     @Rule
     public final ActivityTestRule<DialogFrameTestActivity> mDialogTestActivity =
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/DisplayCutoutTests.java b/tests/framework/base/windowmanager/src/android/server/wm/DisplayCutoutTests.java
index 2050928..ee979d1 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/DisplayCutoutTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/DisplayCutoutTests.java
@@ -19,13 +19,14 @@
 import static android.server.wm.DisplayCutoutTests.TestActivity.EXTRA_CUTOUT_MODE;
 import static android.server.wm.DisplayCutoutTests.TestDef.Which.DISPATCHED;
 import static android.server.wm.DisplayCutoutTests.TestDef.Which.ROOT;
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT;
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER;
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
 
-import static org.hamcrest.Matchers.everyItem;
 import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.everyItem;
 import static org.hamcrest.Matchers.greaterThan;
 import static org.hamcrest.Matchers.greaterThanOrEqualTo;
 import static org.hamcrest.Matchers.hasItem;
@@ -42,9 +43,7 @@
 import android.graphics.Rect;
 import android.os.Bundle;
 import android.platform.test.annotations.Presubmit;
-import android.support.test.InstrumentationRegistry;
 import android.support.test.rule.ActivityTestRule;
-import android.support.test.runner.AndroidJUnit4;
 import android.view.DisplayCutout;
 import android.view.View;
 import android.view.ViewGroup;
@@ -60,11 +59,9 @@
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ErrorCollector;
-import org.junit.runner.RunWith;
 
 import java.util.Arrays;
 import java.util.List;
-import java.util.Objects;
 import java.util.function.Predicate;
 import java.util.function.Supplier;
 import java.util.stream.Collectors;
@@ -73,7 +70,6 @@
  * Build/Install/Run:
  *     atest CtsWindowManagerDeviceTestCases:DisplayCutoutTests
  */
-@RunWith(AndroidJUnit4.class)
 @Presubmit
 public class DisplayCutoutTests {
     static final Rect ZERO_RECT = new Rect();
@@ -330,7 +326,7 @@
     }
 
     private void runOnMainSync(Runnable runnable) {
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(runnable);
+        getInstrumentation().runOnMainSync(runnable);
     }
 
     private <T extends Activity> T launchAndWait(ActivityTestRule<T> rule, int cutoutMode) {
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/LayoutTests.java b/tests/framework/base/windowmanager/src/android/server/wm/LayoutTests.java
index 98e9780..2266125 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/LayoutTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/LayoutTests.java
@@ -16,37 +16,35 @@
 
 package android.server.wm;
 
+import static android.provider.Settings.Global.WINDOW_ANIMATION_SCALE;
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
+import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
 import android.app.Instrumentation;
 import android.content.ContentResolver;
 import android.graphics.Rect;
 import android.os.SystemClock;
 import android.platform.test.annotations.Presubmit;
 import android.provider.Settings;
-import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.FlakyTest;
 import android.support.test.rule.ActivityTestRule;
-import android.support.test.runner.AndroidJUnit4;
 import android.view.KeyEvent;
 import android.view.View;
 import android.view.WindowManager.LayoutParams;
 
+import com.android.compatibility.common.util.PollingCheck;
+import com.android.compatibility.common.util.SystemUtil;
+
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static android.provider.Settings.Global.WINDOW_ANIMATION_SCALE;
-import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import com.android.compatibility.common.util.PollingCheck;
-import com.android.compatibility.common.util.SystemUtil;
 
 /**
  * Test whether WindowManager performs the correct layout after we make some changes to it.
@@ -54,9 +52,8 @@
  * Build/Install/Run:
  *     atest CtsWindowManagerDeviceTestCases:LayoutTests
  */
-@Presubmit
 @FlakyTest(detail = "Can be promoted to pre-submit once confirmed stable.")
-@RunWith(AndroidJUnit4.class)
+@Presubmit
 public class LayoutTests {
     private static final long TIMEOUT_LAYOUT = 200; // milliseconds
     private static final long TIMEOUT_RECEIVE_KEY = 100;
@@ -78,7 +75,7 @@
 
     @Before
     public void setup() {
-        mInstrumentation = InstrumentationRegistry.getInstrumentation();
+        mInstrumentation = getInstrumentation();
         mResolver = mInstrumentation.getContext().getContentResolver();
 
         SystemUtil.runWithShellPermissionIdentity(() -> {
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/LocationInWindowTests.java b/tests/framework/base/windowmanager/src/android/server/wm/LocationInWindowTests.java
index 1272237..38acddc 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/LocationInWindowTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/LocationInWindowTests.java
@@ -17,6 +17,7 @@
 package android.server.wm;
 
 import static android.server.wm.LocationOnScreenTests.TestActivity.EXTRA_LAYOUT_PARAMS;
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
 import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
 import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
@@ -31,11 +32,9 @@
 import android.graphics.Point;
 import android.os.Bundle;
 import android.platform.test.annotations.Presubmit;
-import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.FlakyTest;
 import android.support.test.filters.SmallTest;
 import android.support.test.rule.ActivityTestRule;
-import android.support.test.runner.AndroidJUnit4;
 import android.view.Gravity;
 import android.view.View;
 import android.view.ViewGroup;
@@ -50,14 +49,12 @@
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ErrorCollector;
-import org.junit.runner.RunWith;
 
 import java.util.function.Supplier;
 
-@RunWith(AndroidJUnit4.class)
+@FlakyTest(detail = "until proven non-flaky")
 @SmallTest
 @Presubmit
-@FlakyTest(detail = "until proven non-flaky")
 public class LocationInWindowTests {
 
     @Rule
@@ -157,7 +154,7 @@
     }
 
     private void runOnMainSync(Runnable runnable) {
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(runnable);
+        getInstrumentation().runOnMainSync(runnable);
     }
 
     private <T extends Activity> T launchAndWait(ActivityTestRule<T> rule,
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/LocationOnScreenTests.java b/tests/framework/base/windowmanager/src/android/server/wm/LocationOnScreenTests.java
index 15e9260..b7e463e 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/LocationOnScreenTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/LocationOnScreenTests.java
@@ -19,6 +19,7 @@
 import static android.server.wm.LocationOnScreenTests.TestActivity.EXTRA_LAYOUT_PARAMS;
 import static android.server.wm.LocationOnScreenTests.TestActivity.TEST_COLOR_1;
 import static android.server.wm.LocationOnScreenTests.TestActivity.TEST_COLOR_2;
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
 import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
 import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
@@ -37,11 +38,9 @@
 import android.graphics.Point;
 import android.os.Bundle;
 import android.platform.test.annotations.Presubmit;
-import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.FlakyTest;
 import android.support.test.filters.SmallTest;
 import android.support.test.rule.ActivityTestRule;
-import android.support.test.runner.AndroidJUnit4;
 import android.view.Gravity;
 import android.view.View;
 import android.view.ViewGroup;
@@ -58,14 +57,12 @@
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ErrorCollector;
-import org.junit.runner.RunWith;
 
 import java.util.function.Supplier;
 
-@RunWith(AndroidJUnit4.class)
+@FlakyTest(detail = "until proven non-flaky")
 @SmallTest
 @Presubmit
-@FlakyTest(detail = "until proven non-flaky")
 public class LocationOnScreenTests {
 
     @Rule
@@ -81,7 +78,7 @@
 
     @Before
     public void setUp() {
-        mContext = InstrumentationRegistry.getContext();
+        mContext = getInstrumentation().getContext();
         mLayoutParams = new LayoutParams(MATCH_PARENT, MATCH_PARENT, LayoutParams.TYPE_APPLICATION,
                 LayoutParams.FLAG_LAYOUT_IN_SCREEN | LayoutParams.FLAG_LAYOUT_INSET_DECOR,
                 PixelFormat.TRANSLUCENT);
@@ -141,7 +138,7 @@
     }
 
     private void runOnMainSync(Runnable runnable) {
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(runnable);
+        getInstrumentation().runOnMainSync(runnable);
     }
 
     private <T extends Activity> T launchAndWait(ActivityTestRule<T> rule,
@@ -153,8 +150,7 @@
     }
 
     private Point findTestColorsInScreenshot(Point guess) {
-        final Bitmap screenshot =
-                InstrumentationRegistry.getInstrumentation().getUiAutomation().takeScreenshot();
+        final Bitmap screenshot = getInstrumentation().getUiAutomation().takeScreenshot();
 
         // We have a good guess from locationOnScreen - check there first to avoid having to go over
         // the entire bitmap. Also increases robustness in the extremely unlikely case that those
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/WindowFocusTests.java b/tests/framework/base/windowmanager/src/android/server/wm/WindowFocusTests.java
index fb2f1b6..b2dfbc1 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/WindowFocusTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowFocusTests.java
@@ -23,7 +23,6 @@
 import static android.server.am.UiDeviceUtils.pressUnlockButton;
 import static android.server.am.UiDeviceUtils.pressWakeupButton;
 import static android.support.test.InstrumentationRegistry.getInstrumentation;
-import static android.support.test.InstrumentationRegistry.getTargetContext;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.INVALID_DISPLAY;
 import static android.view.KeyEvent.ACTION_DOWN;
@@ -59,7 +58,6 @@
 import android.platform.test.annotations.Presubmit;
 import android.server.am.ComponentNameUtils;
 import android.support.test.filters.FlakyTest;
-import android.support.test.runner.AndroidJUnit4;
 import android.view.Display;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
@@ -70,7 +68,6 @@
 
 import org.junit.Before;
 import org.junit.Test;
-import org.junit.runner.RunWith;
 
 import java.util.ArrayList;
 
@@ -83,7 +80,6 @@
  *     atest WindowFocusTests
  */
 @Presubmit
-@RunWith(AndroidJUnit4.class)
 public class WindowFocusTests {
 
     @Before
@@ -98,7 +94,8 @@
         final Bundle options = (displayId == DEFAULT_DISPLAY
                 ? null : ActivityOptions.makeBasic().setLaunchDisplayId(displayId).toBundle());
         final T activity = (T) getInstrumentation().startActivitySync(
-                new Intent(getTargetContext(), cls).addFlags(FLAG_ACTIVITY_NEW_TASK), options);
+                new Intent(getInstrumentation().getTargetContext(), cls)
+                        .addFlags(FLAG_ACTIVITY_NEW_TASK), options);
         activity.waitAndAssertWindowFocusState(true /* hasFocus */);
         return activity;
     }
@@ -128,7 +125,9 @@
 
     private static void tapOnCenterOfDisplay(int displayId) {
         final Point point = new Point();
-        getTargetContext().getSystemService(DisplayManager.class).getDisplay(displayId)
+        getInstrumentation().getTargetContext()
+                .getSystemService(DisplayManager.class)
+                .getDisplay(displayId)
                 .getSize(point);
         final int x = point.x / 2;
         final int y = point.y / 2;
@@ -159,15 +158,16 @@
         sendAndAssertTargetConsumedKey(primaryActivity, KEYCODE_1, DEFAULT_DISPLAY);
 
         try (VirtualDisplaySession displaySession = new VirtualDisplaySession()) {
-            final int secondaryDisplayId =
-                    displaySession.createDisplay(getTargetContext()).getDisplayId();
+            final int secondaryDisplayId = displaySession.createDisplay(
+                    getInstrumentation().getTargetContext()).getDisplayId();
             final SecondaryActivity secondaryActivity =
                     startActivity(SecondaryActivity.class, secondaryDisplayId);
             sendAndAssertTargetConsumedKey(secondaryActivity, KEYCODE_2, INVALID_DISPLAY);
             sendAndAssertTargetConsumedKey(secondaryActivity, KEYCODE_3, secondaryDisplayId);
 
-            final boolean perDisplayFocusEnabled = getTargetContext().getResources().getBoolean(
-                    com.android.internal.R.bool.config_perDisplayFocusEnabled);
+            final boolean perDisplayFocusEnabled = getInstrumentation()
+                    .getTargetContext().getResources()
+                    .getBoolean(com.android.internal.R.bool.config_perDisplayFocusEnabled);
             if (perDisplayFocusEnabled) {
                 primaryActivity.assertWindowFocusState(true /* hasFocus */);
                 sendAndAssertTargetConsumedKey(primaryActivity, KEYCODE_4, DEFAULT_DISPLAY);
@@ -206,7 +206,7 @@
      */
     @Test
     public void testMovingDisplayToTopByKeyEvent() throws InterruptedException {
-        if (getTargetContext().getResources().getBoolean(
+        if (getInstrumentation().getTargetContext().getResources().getBoolean(
                 com.android.internal.R.bool.config_perDisplayFocusEnabled)) {
             return;
         }
@@ -215,8 +215,8 @@
                 DEFAULT_DISPLAY);
 
         try (VirtualDisplaySession displaySession = new VirtualDisplaySession()) {
-            final int secondaryDisplayId =
-                    displaySession.createDisplay(getTargetContext()).getDisplayId();
+            final int secondaryDisplayId = displaySession.createDisplay(
+                    getInstrumentation().getTargetContext()).getDisplayId();
             final SecondaryActivity secondaryActivity =
                     startActivity(SecondaryActivity.class, secondaryDisplayId);
 
@@ -259,8 +259,8 @@
         primaryActivity.waitAndAssertPointerCaptureState(true /* hasCapture */);
 
         try (VirtualDisplaySession displaySession = new VirtualDisplaySession()) {
-            final int secondaryDisplayId =
-                    displaySession.createDisplay(getTargetContext()).getDisplayId();
+            final int secondaryDisplayId = displaySession.createDisplay(
+                    getInstrumentation().getTargetContext()).getDisplayId();
             final SecondaryActivity secondaryActivity =
                     startActivity(SecondaryActivity.class, secondaryDisplayId);
 
@@ -288,8 +288,8 @@
 
         final SecondaryActivity secondaryActivity;
         try (VirtualDisplaySession displaySession = new VirtualDisplaySession()) {
-            final int secondaryDisplayId =
-                    displaySession.createDisplay(getTargetContext()).getDisplayId();
+            final int secondaryDisplayId = displaySession.createDisplay(
+                    getInstrumentation().getTargetContext()).getDisplayId();
             secondaryActivity = startActivity(SecondaryActivity.class, secondaryDisplayId);
         }
         // Secondary display disconnected.
diff --git a/tests/inputmethod/AndroidTest.xml b/tests/inputmethod/AndroidTest.xml
index ce654ea..f64bd17 100644
--- a/tests/inputmethod/AndroidTest.xml
+++ b/tests/inputmethod/AndroidTest.xml
@@ -19,6 +19,7 @@
     <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="inputmethod" />
     <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
     <!--
         TODO(yukawa): come up with a proper way to take care of devices that do not support
         installable IMEs.  Ideally target_preparer should have an option to annotate required
diff --git a/tests/inputmethod/src/android/view/inputmethod/cts/NavigationBarColorTest.java b/tests/inputmethod/src/android/view/inputmethod/cts/NavigationBarColorTest.java
index 49c37dc..6b2fb62 100644
--- a/tests/inputmethod/src/android/view/inputmethod/cts/NavigationBarColorTest.java
+++ b/tests/inputmethod/src/android/view/inputmethod/cts/NavigationBarColorTest.java
@@ -48,7 +48,6 @@
 import android.view.ViewGroup;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.cts.util.EndToEndImeTestBase;
-import android.view.inputmethod.cts.util.ImeAwareEditText;
 import android.view.inputmethod.cts.util.NavigationBarInfo;
 import android.view.inputmethod.cts.util.TestActivity;
 import android.widget.LinearLayout;
@@ -57,6 +56,7 @@
 import androidx.annotation.ColorInt;
 import androidx.annotation.NonNull;
 
+import com.android.compatibility.common.util.ImeAwareEditText;
 import com.android.cts.mockime.ImeEventStream;
 import com.android.cts.mockime.ImeLayoutInfo;
 import com.android.cts.mockime.ImeSettings;
diff --git a/tests/jdwp/AndroidTest.xml b/tests/jdwp/AndroidTest.xml
index 462ed34..9b42fb9 100644
--- a/tests/jdwp/AndroidTest.xml
+++ b/tests/jdwp/AndroidTest.xml
@@ -36,6 +36,7 @@
         <option name="dalvik-arg" value="-Djpda.settings.verbose=false" />
         <option name="dalvik-arg" value="-Djpda.settings.timeout=10000" />
         <option name="dalvik-arg" value="-Djpda.settings.waitingTime=10000" />
+        <option name="dalvik-arg" value="-Djpda.settings.dumpProcess='/system/xbin/su root /system/bin/logwrapper /system/bin/debuggerd'" />
         <option name="dalvik-arg-adbconnection" value="-Djpda.settings.debuggeeAgentArgument=-agentpath:" />
         <option name="dalvik-arg-adbconnection" value="-Djpda.settings.debuggeeAgentName=libjdwp.so" />
         <option name="dalvik-arg-adbconnection" value="-Djpda.settings.debuggeeJavaPath='dalvikvm|#ABI#| -XXlib:libart.so -Xplugin:libopenjdkjvmti.so -Xcompiler-option --debuggable -Xusejit:true'" />
diff --git a/tests/netlegacy22.api/Android.mk b/tests/netlegacy22.api/Android.mk
index 5a330e5..f5b178e7 100644
--- a/tests/netlegacy22.api/Android.mk
+++ b/tests/netlegacy22.api/Android.mk
@@ -27,7 +27,7 @@
 
 LOCAL_SDK_VERSION := 22
 
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner compatibility-device-util
 
 # Tag this module as a cts test artifact
 LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
diff --git a/tests/netlegacy22.api/src/android/net/cts/legacy/api22/ConnectivityManagerLegacyTest.java b/tests/netlegacy22.api/src/android/net/cts/legacy/api22/ConnectivityManagerLegacyTest.java
index de92910..4a8a2ad 100644
--- a/tests/netlegacy22.api/src/android/net/cts/legacy/api22/ConnectivityManagerLegacyTest.java
+++ b/tests/netlegacy22.api/src/android/net/cts/legacy/api22/ConnectivityManagerLegacyTest.java
@@ -26,11 +26,12 @@
 import android.net.LinkProperties;
 import android.net.Network;
 import android.net.NetworkInfo;
-import android.net.wifi.WifiManager;
 import android.os.ConditionVariable;
 import android.test.AndroidTestCase;
 import android.util.Log;
 
+import com.android.compatibility.common.util.SystemUtil;
+
 import java.net.DatagramSocket;
 import java.net.Inet4Address;
 import java.net.InetAddress;
@@ -55,7 +56,6 @@
     private static final int MAX_NETWORK_TYPE = TYPE_VPN;
 
     private ConnectivityManager mCm;
-    private WifiManager mWifiManager;
     private PackageManager mPackageManager;
 
     private final List<Integer>mProtectedNetworks = new ArrayList<Integer>();
@@ -63,7 +63,6 @@
     protected void setUp() throws Exception {
         super.setUp();
         mCm = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
-        mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE);
         mPackageManager = getContext().getPackageManager();
 
         // Get com.android.internal.R.array.config_protectedNetworks
@@ -257,7 +256,7 @@
                     NetworkInfo.State.DISCONNECTED;
             expectNetworkBroadcast(TYPE_WIFI, desiredState, new Runnable() {
                 public void run() {
-                    mWifiManager.setWifiEnabled(enabled);
+                    SystemUtil.runShellCommand("svc wifi " + (enabled ? "enable" : "disable"));
                 }
             });
         }
diff --git a/tests/sample/AndroidTest.xml b/tests/sample/AndroidTest.xml
index c398ab05..e2a3139 100644
--- a/tests/sample/AndroidTest.xml
+++ b/tests/sample/AndroidTest.xml
@@ -17,6 +17,7 @@
     <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="misc" />
     <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
         <option name="test-file-name" value="CtsSampleDeviceTestCases.apk" />
diff --git a/tests/sensor/src/android/hardware/cts/helpers/sensorverification/MeanVerification.java b/tests/sensor/src/android/hardware/cts/helpers/sensorverification/MeanVerification.java
index 17882d7..7a48ba8 100644
--- a/tests/sensor/src/android/hardware/cts/helpers/sensorverification/MeanVerification.java
+++ b/tests/sensor/src/android/hardware/cts/helpers/sensorverification/MeanVerification.java
@@ -23,6 +23,7 @@
 import android.hardware.cts.helpers.SensorCtsHelper;
 import android.hardware.cts.helpers.SensorStats;
 import android.hardware.cts.helpers.TestSensorEnvironment;
+import android.content.pm.PackageManager;
 
 import java.util.HashMap;
 import java.util.Map;
@@ -65,13 +66,23 @@
      * @return the verification or null if the verification does not apply to the sensor.
      */
     public static MeanVerification getDefault(TestSensorEnvironment environment) {
+
+        Map<Integer, ExpectedValuesAndThresholds> currentDefaults =
+                new HashMap<Integer, ExpectedValuesAndThresholds>(DEFAULTS);
+
+        // For automotive flag, add car default tests.
+        if(environment.getContext().getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_AUTOMOTIVE)) {
+            addCarDefaultTests(currentDefaults);
+        }
+
         int sensorType = environment.getSensor().getType();
-        if (!DEFAULTS.containsKey(sensorType)) {
+        if (!currentDefaults.containsKey(sensorType)) {
             return null;
         }
-        float[] expected = DEFAULTS.get(sensorType).mExpectedValues;
-        float[] upperThresholds = DEFAULTS.get(sensorType).mUpperThresholds;
-        float[] lowerThresholds = DEFAULTS.get(sensorType).mLowerThresholds;
+        float[] expected = currentDefaults.get(sensorType).mExpectedValues;
+        float[] upperThresholds = currentDefaults.get(sensorType).mUpperThresholds;
+        float[] lowerThresholds = currentDefaults.get(sensorType).mLowerThresholds;
         return new MeanVerification(expected, upperThresholds, lowerThresholds);
     }
 
@@ -186,6 +197,20 @@
                                                         Float.MAX_VALUE}));
     }
 
+    @SuppressWarnings("deprecation")
+    private static void addCarDefaultTests(Map<Integer, ExpectedValuesAndThresholds> defaults) {
+        // Sensors that are being tested for mean verification for the car.
+        // Accelerometer axes should be aligned to car axes: X right, Y forward, Z up.
+        // Refer for car axes: https://source.android.com/devices/sensors/sensor-types
+        // Verifying Z axis is Gravity, X and Y is zero as car is expected to be stationary.
+        // Tolerance set to 1.95 as used in CTS Verifier tests.
+        defaults.put(Sensor.TYPE_ACCELEROMETER,
+                new ExpectedValuesAndThresholds(
+                        new float[]{0.0f, 0.0f, SensorManager.STANDARD_GRAVITY},
+                        new float[]{1.95f, 1.95f, 1.95f} /* m / s^2 */,
+                        new float[]{1.95f, 1.95f, 1.95f} /* m / s^2 */));
+    }
+
     private static final class ExpectedValuesAndThresholds {
         private float[] mExpectedValues;
         private float[] mUpperThresholds;
diff --git a/tests/signature/api-check/Android.mk b/tests/signature/api-check/Android.mk
index bb2c28c..ef1df59 100644
--- a/tests/signature/api-check/Android.mk
+++ b/tests/signature/api-check/Android.mk
@@ -31,8 +31,7 @@
 LOCAL_STATIC_JAVA_LIBRARIES := \
     cts-signature-common \
     repackaged.android.test.base \
-    repackaged.android.test.runner \
-    compatibility-device-util
+    repackaged.android.test.runner
 
 include $(BUILD_STATIC_JAVA_LIBRARY)
 
@@ -40,7 +39,7 @@
 # ===================================
 
 include $(CLEAR_VARS)
-LOCAL_MODULE := cts-hiddenapi-flags
+LOCAL_MODULE := cts-hiddenapi_flags-csv
 LOCAL_MODULE_STEM := hiddenapi_flags.csv
 LOCAL_MODULE_CLASS := ETC
 LOCAL_MODULE_PATH = $(TARGET_OUT_DATA_ETC)
diff --git a/tests/signature/api-check/build_signature_apk.mk b/tests/signature/api-check/build_signature_apk.mk
index a5ebcf8..b883d6a 100644
--- a/tests/signature/api-check/build_signature_apk.mk
+++ b/tests/signature/api-check/build_signature_apk.mk
@@ -36,9 +36,45 @@
 LOCAL_ADDITIONAL_DEPENDENCIES += \
     $(addprefix $(COMPATIBILITY_TESTCASES_OUT_cts)/,$(LOCAL_SIGNATURE_API_FILES))
 
+# Add dependencies needed to build/run the test with atest.
+#
+# This is a temporary workaround as described in b/123393637. It adds the dependencies that
+# atest requires for each of the modules specified in the LOCAL_SIGNATURE_API_FILES. The
+# mapping from module name to the dependency is slightly complicated due to inconsistencies
+# in the mapping for the different file types, i.e. .api, .csv and .zip. Those
+# inconsistencies will be resolved by build improvement work mentioned in b/123393637.
+#
+# Converts:
+#     current.api -> $(TARGET_OUT_TESTCASES)/cts-current-api/current.api
+#     hiddenapi_flags.csv -> $(TARGET_OUT_TESTCASES)/cts-hiddenapi_flags-csv/hiddenapi_flags.csv
+#     system-all.api.zip -> $(TARGET_OUT_TESTCASES)/cts-system-all.api/system-all.api.zip
+
+# Construct module name directory from file name, matches behavior in the
+# build_xml_api_file function in ../api/Android.mk plus some extra rules for handling slight
+# inconsistencies with that behavior for the ..all.zip files used by some signature tests.
+#   Replace . with -
+#   Prefix every entry with cts-
+#   Replace -all-api-zip with -all.api to handle ...all.zip files
+#
+cts_signature_module_deps := $(LOCAL_SIGNATURE_API_FILES)
+cts_signature_module_deps := $(subst .,-,$(cts_signature_module_deps))
+cts_signature_module_deps := $(addprefix cts-,$(cts_signature_module_deps))
+cts_signature_module_deps := $(subst -all-api-zip,-all.api,$(cts_signature_module_deps))
+
+ifndef ENABLE_DEFAULT_TEST_LOCATION
+# Construct path to dependency.
+#   Join module name directory and file name and prefix with TARGET_OUT_TESTCASES
+LOCAL_ADDITIONAL_DEPENDENCIES += \
+    $(addprefix $(TARGET_OUT_TESTCASES)/,\
+        $(join $(cts_signature_module_deps),$(addprefix /,$(LOCAL_SIGNATURE_API_FILES))))
+else
+LOCAL_REQUIRED_MODULES := $(cts_signature_module_deps)
+endif
+
 LOCAL_DEX_PREOPT := false
 LOCAL_PROGUARD_ENABLED := disabled
 
 include $(BUILD_CTS_PACKAGE)
 
 LOCAL_SIGNATURE_API_FILES :=
+cts_signature_module_deps :=
diff --git a/tests/signature/api-check/shared-libs-api/Android.mk b/tests/signature/api-check/shared-libs-api/Android.mk
index 789241e..149455c 100644
--- a/tests/signature/api-check/shared-libs-api/Android.mk
+++ b/tests/signature/api-check/shared-libs-api/Android.mk
@@ -37,12 +37,31 @@
 
 include $(CLEAR_VARS)
 
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_MODULE := cts-api-signature-multilib-test
+
+LOCAL_SDK_VERSION := test_current
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+        cts-api-signature-test \
+        compatibility-device-util
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+
+include $(CLEAR_VARS)
+
 LOCAL_PACKAGE_NAME := CtsSharedLibsApiSignatureTestCases
 
 LOCAL_SIGNATURE_API_FILES := \
     shared-libs-all.api.zip \
     $(all_shared_libs_files)
 
+LOCAL_STATIC_JAVA_LIBRARIES := cts-api-signature-multilib-test
+
 include $(LOCAL_PATH)/../build_signature_apk.mk
 
 LOCAL_JAVA_SDK_LIBRARIES :=
diff --git a/tests/signature/api-check/shared-libs-api/AndroidTest.xml b/tests/signature/api-check/shared-libs-api/AndroidTest.xml
index 79657cc..2b30da4 100644
--- a/tests/signature/api-check/shared-libs-api/AndroidTest.xml
+++ b/tests/signature/api-check/shared-libs-api/AndroidTest.xml
@@ -30,9 +30,8 @@
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="android.signature.cts.api.shared_libs" />
         <option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
-        <option name="class" value="android.signature.cts.api.SignatureTest" />
+        <option name="class" value="android.signature.cts.api.SignatureMultiLibsTest" />
         <option name="instrumentation-arg" key="expected-api-files" value="shared-libs-all.api.zip" />
-        <option name="instrumentation-arg" key="check-library-names" value="true" />
         <option name="runtime-hint" value="30s" />
     </test>
 </configuration>
diff --git a/tests/signature/api-check/shared-libs-api/src/android/signature/cts/api/SignatureMultiLibsTest.java b/tests/signature/api-check/shared-libs-api/src/android/signature/cts/api/SignatureMultiLibsTest.java
new file mode 100644
index 0000000..e6c011f
--- /dev/null
+++ b/tests/signature/api-check/shared-libs-api/src/android/signature/cts/api/SignatureMultiLibsTest.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2011 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.signature.cts.api;
+
+import android.signature.cts.ApiComplianceChecker;
+import android.signature.cts.ApiDocumentParser;
+import android.signature.cts.JDiffClassDescription;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.stream.Stream;
+import java.util.zip.ZipFile;
+import org.xmlpull.v1.XmlPullParserException;
+
+import static android.signature.cts.CurrentApi.API_FILE_DIRECTORY;
+import static com.android.compatibility.common.util.SystemUtil.runShellCommand;
+
+/**
+ * Performs the signature multi-libs check via a JUnit test.
+ */
+public class SignatureMultiLibsTest extends SignatureTest {
+
+    private static final String TAG = SignatureMultiLibsTest.class.getSimpleName();
+
+    /**
+     * Tests that the device's API matches the expected set defined in xml.
+     * <p/>
+     * Will check the entire API, and then report the complete list of failures
+     */
+    public void testSignature() {
+        runWithTestResultObserver(mResultObserver -> {
+
+            ApiComplianceChecker complianceChecker =
+                    new ApiComplianceChecker(mResultObserver, classProvider);
+
+            ApiDocumentParser apiDocumentParser = new ApiDocumentParser(TAG);
+
+            parseApiFilesAsStream(apiDocumentParser, expectedApiFiles)
+                    .forEach(complianceChecker::checkSignatureCompliance);
+
+            // After done parsing all expected API files, perform any deferred checks.
+            complianceChecker.checkDeferred();
+        });
+    }
+
+    private Stream<String> getLibraries() {
+        try {
+            String result = runShellCommand(getInstrumentation(), "cmd package list libraries");
+            return Arrays.stream(result.split("\n")).map(line -> line.split(":")[1]);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private boolean checkLibrary (String name) {
+        String libraryName = name.substring(name.lastIndexOf('/') + 1).split("-")[0];
+        if (getLibraries().filter(lib -> lib.equals(libraryName)).findAny().isPresent()) {
+            return true;
+        }
+        return false;
+    }
+
+    protected Stream<InputStream> readFile(File file) {
+        try {
+            if (file.getName().endsWith(".zip")) {
+                ZipFile zip = new ZipFile(file);
+                return zip.stream().filter(entry -> checkLibrary(entry.getName())).map(entry -> {
+                    try {
+                        return zip.getInputStream(entry);
+                    } catch (IOException e) {
+                        throw new RuntimeException(e);
+                    }});
+            } else {
+                return Stream.of(new FileInputStream(file));
+            }
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    protected Stream<JDiffClassDescription> parseApiFilesAsStream(
+            ApiDocumentParser apiDocumentParser, String[] apiFiles)
+            throws XmlPullParserException, IOException {
+        return Stream.of(apiFiles)
+                .map(name -> new File(API_FILE_DIRECTORY + "/" + name))
+                .flatMap(file -> readFile(file))
+                .flatMap(stream -> {
+                    try {
+                        return apiDocumentParser.parseAsStream(stream)
+                              .filter(AbstractApiTest::isAccessibleClass);
+                    } catch (IOException | XmlPullParserException e) {
+                        throw new RuntimeException(e);
+                    }
+                });
+    }
+}
diff --git a/tests/signature/api-check/src/java/android/signature/cts/api/AbstractApiTest.java b/tests/signature/api-check/src/java/android/signature/cts/api/AbstractApiTest.java
index 796ae50..e781188 100644
--- a/tests/signature/api-check/src/java/android/signature/cts/api/AbstractApiTest.java
+++ b/tests/signature/api-check/src/java/android/signature/cts/api/AbstractApiTest.java
@@ -27,7 +27,6 @@
 import java.io.InputStream;
 import java.io.PrintWriter;
 import java.io.StringWriter;
-import java.util.Arrays;
 import java.util.HashSet;
 import java.util.Set;
 import java.util.stream.Stream;
@@ -37,7 +36,6 @@
 import repackaged.android.test.InstrumentationTestRunner;
 
 import static android.signature.cts.CurrentApi.API_FILE_DIRECTORY;
-import static com.android.compatibility.common.util.SystemUtil.runShellCommand;
 
 /**
  */
@@ -64,7 +62,6 @@
     }
 
     private TestResultObserver mResultObserver;
-    private boolean checkLibraryNames;
 
     ClassProvider classProvider;
 
@@ -93,7 +90,7 @@
 
     }
 
-    private static boolean isAccessibleClass(JDiffClassDescription classDescription) {
+    protected static boolean isAccessibleClass(JDiffClassDescription classDescription) {
         // Ignore classes that are known to be inaccessible.
         return !KNOWN_INACCESSIBLE_CLASSES.contains(classDescription.getAbsoluteClassName());
     }
@@ -102,10 +99,6 @@
         void run(TestResultObserver observer) throws Exception;
     }
 
-    protected void setCheckLibraryNames() {
-        checkLibraryNames = true;
-    }
-
     void runWithTestResultObserver(RunnableWithTestResultObserver runnable) {
         try {
             runnable.run(mResultObserver);
@@ -137,32 +130,11 @@
         return argument.split(",");
     }
 
-    private Stream<String> getLibraries() {
-        try {
-            String result = runShellCommand(getInstrumentation(), "cmd package list libraries");
-            return Arrays.stream(result.split("\n")).map(line -> line.split(":")[1]);
-        } catch (IOException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    private boolean checkLibrary (String name) {
-        if (!checkLibraryNames) {
-            return true;
-        }
-
-        String libraryName = name.substring(name.lastIndexOf('/') + 1).split("-")[0];
-        if (getLibraries().filter(lib -> lib.equals(libraryName)).findAny().isPresent()) {
-            return true;
-        }
-        return false;
-    }
-
     protected Stream<InputStream> readFile(File file) {
         try {
             if (file.getName().endsWith(".zip")) {
                 ZipFile zip = new ZipFile(file);
-                return zip.stream().filter(entry -> checkLibrary(entry.getName())).map(entry -> {
+                return zip.stream().map(entry -> {
                     try {
                         return zip.getInputStream(entry);
                     } catch (IOException e) {
diff --git a/tests/signature/api-check/src/java/android/signature/cts/api/SignatureTest.java b/tests/signature/api-check/src/java/android/signature/cts/api/SignatureTest.java
index 7b02e54..7861df7 100644
--- a/tests/signature/api-check/src/java/android/signature/cts/api/SignatureTest.java
+++ b/tests/signature/api-check/src/java/android/signature/cts/api/SignatureTest.java
@@ -47,11 +47,6 @@
         expectedApiFiles = getCommaSeparatedList(instrumentationArgs, "expected-api-files");
         baseApiFiles = getCommaSeparatedList(instrumentationArgs, "base-api-files");
         unexpectedApiFiles = getCommaSeparatedList(instrumentationArgs, "unexpected-api-files");
-        String checkLibraryNames = instrumentationArgs.getString("check-library-names");
-
-        if (Boolean.valueOf(checkLibraryNames)) {
-            setCheckLibraryNames();
-        }
     }
 
     /**
diff --git a/tests/signature/runSignatureTests.sh b/tests/signature/runSignatureTests.sh
index 046300f..a97dd64 100755
--- a/tests/signature/runSignatureTests.sh
+++ b/tests/signature/runSignatureTests.sh
@@ -40,15 +40,4 @@
     PACKAGES=${1+"$@"}
 fi
 
-cd $ANDROID_BUILD_TOP
-make -j32 $PACKAGES
-
-TMPFILE=$(mktemp)
-trap "echo Removing temporary directory; rm -f $TMPFILE" EXIT
-
-for p in $PACKAGES
-do
-    echo cts -a arm64-v8a -m "$p" >> $TMPFILE
-done
-
-cts-tradefed run cmdfileAndExit $TMPFILE
+atest ${PACKAGES}
diff --git a/tests/signature/src/android/signature/cts/AbstractApiChecker.java b/tests/signature/src/android/signature/cts/AbstractApiChecker.java
index 546b921..66e7d6c 100644
--- a/tests/signature/src/android/signature/cts/AbstractApiChecker.java
+++ b/tests/signature/src/android/signature/cts/AbstractApiChecker.java
@@ -230,7 +230,7 @@
                 if (m == null) {
                     resultObserver.notifyFailure(FailureType.MISSING_METHOD,
                             method.toReadableString(classDescription.getAbsoluteClassName()),
-                            "No method with correct signature found:" +
+                            "No method with correct signature found, looking for:" +
                                     method.toSignatureString());
                 } else {
                     checkMethod(classDescription, runtimeClass, method, m);
diff --git a/tests/signature/src/android/signature/cts/ApiComplianceChecker.java b/tests/signature/src/android/signature/cts/ApiComplianceChecker.java
index 6bb9806..54242e3 100644
--- a/tests/signature/src/android/signature/cts/ApiComplianceChecker.java
+++ b/tests/signature/src/android/signature/cts/ApiComplianceChecker.java
@@ -29,6 +29,23 @@
  */
 public class ApiComplianceChecker extends AbstractApiChecker {
 
+    /**
+     * A set of method signatures whose abstract modifier should be ignored.
+     *
+     * <p>If a class is not intended to be created or extended by application developers and all
+     * instances are created and supplied by Android itself then the abstract modifier has no
+     * impact on runtime compatibility.
+     */
+    private static final Set<String> IGNORE_METHOD_ABSTRACT_MODIFIER_WHITE_LIST = new HashSet<>();
+    static {
+        // This method was previously abstract and is now not abstract. As the
+        // CtsSystemApiSignatureTestCases package tests both the old and new specifications, with
+        // and without the abstract modifier this needs to ignore the abstract modifier.
+        IGNORE_METHOD_ABSTRACT_MODIFIER_WHITE_LIST.add(
+                "public int android.service.euicc.EuiccService.onDownloadSubscription("
+                        + "int,android.telephony.euicc.DownloadableSubscription,boolean,boolean)");
+    }
+
     /** Indicates that the class is an annotation. */
     private static final int CLASS_MODIFIER_ANNOTATION = 0x00002000;
 
@@ -131,6 +148,13 @@
         }
         if (classDescription.isEnumType() && runtimeClass.isEnum()) {
             reflectionModifiers &= ~CLASS_MODIFIER_ENUM;
+
+            // Most enums are marked as final, however enums that have one or more constants that
+            // override a method from the class cannot be marked as final because those constants
+            // are represented as a subclass. As enum classes cannot be extended (except for its own
+            // constants) there is no benefit in checking final modifier so just ignore them.
+            reflectionModifiers &= ~Modifier.FINAL;
+            apiModifiers &= ~Modifier.FINAL;
         }
 
         if ((reflectionModifiers == apiModifiers)
@@ -480,7 +504,7 @@
         }
 
         String reason;
-        if ((reason = areMethodsModifiedCompatible(
+        if ((reason = areMethodsModifierCompatible(
                 classDescription, methodDescription, method)) != null) {
             resultObserver.notifyFailure(FailureType.MISMATCH_METHOD,
                     methodDescription.toReadableString(classDescription.getAbsoluteClassName()),
@@ -493,14 +517,14 @@
      * Checks to ensure that the modifiers value for two methods are compatible.
      *
      * Allowable differences are:
-     *   - the native modified is ignored
+     *   - the native modifier is ignored
      *
      * @param classDescription a description of a class in an API.
      * @param apiMethod the method read from the api file.
      * @param reflectedMethod the method found via reflection.
      * @return null if the method modifiers are compatible otherwise the reason why not.
      */
-    private static String areMethodsModifiedCompatible(
+    private static String areMethodsModifierCompatible(
             JDiffClassDescription classDescription,
             JDiffClassDescription.JDiffMethod apiMethod,
             Method reflectedMethod) {
@@ -517,11 +541,17 @@
             apiModifiers &= ~Modifier.FINAL;
         }
 
+        String genericString = reflectedMethod.toGenericString();
+        if (IGNORE_METHOD_ABSTRACT_MODIFIER_WHITE_LIST.contains(genericString)) {
+            reflectionModifiers &= ~Modifier.ABSTRACT;
+            apiModifiers &= ~Modifier.ABSTRACT;
+        }
+
         if (reflectionModifiers == apiModifiers) {
             return null;
         } else {
-            return String.format("modifier mismatch - description (%s), method (%s)",
-                    Modifier.toString(apiModifiers), Modifier.toString(reflectionModifiers));
+            return String.format("modifier mismatch - description (%s), method (%s), for %s",
+                Modifier.toString(apiModifiers), Modifier.toString(reflectionModifiers), genericString);
         }
     }
 
diff --git a/tests/signature/src/android/signature/cts/ReflectionHelper.java b/tests/signature/src/android/signature/cts/ReflectionHelper.java
index 790692d..134d7fe 100644
--- a/tests/signature/src/android/signature/cts/ReflectionHelper.java
+++ b/tests/signature/src/android/signature/cts/ReflectionHelper.java
@@ -150,7 +150,8 @@
                 int i = 0;
                 int j = startParamOffset;
                 while (i < jdiffParamList.size()) {
-                    if (!compareParam(jdiffParamList.get(i), params[j])) {
+                    if (!compareParam(jdiffParamList.get(i), params[j],
+                            DefaultTypeComparator.INSTANCE)) {
                         isFound = false;
                         break;
                     }
@@ -171,9 +172,11 @@
      *
      * @param jdiffParam param parsed from the API xml file.
      * @param reflectionParamType param gotten from the Java reflection.
+     * @param typeComparator compares two types to determine if they are equal.
      * @return True if the two params match, otherwise return false.
      */
-    private static boolean compareParam(String jdiffParam, Type reflectionParamType) {
+    private static boolean compareParam(String jdiffParam, Type reflectionParamType,
+            TypeComparator typeComparator) {
         if (jdiffParam == null) {
             return false;
         }
@@ -181,7 +184,7 @@
         String reflectionParam = typeToString(reflectionParamType);
         // Most things aren't varargs, so just do a simple compare
         // first.
-        if (jdiffParam.equals(reflectionParam)) {
+        if (typeComparator.compare(jdiffParam, reflectionParam)) {
             return true;
         }
 
@@ -192,7 +195,7 @@
         if (jdiffParamEndOffset != -1 && reflectionParamEndOffset != -1) {
             jdiffParam = jdiffParam.substring(0, jdiffParamEndOffset);
             reflectionParam = reflectionParam.substring(0, reflectionParamEndOffset);
-            return jdiffParam.equals(reflectionParam);
+            return typeComparator.compare(jdiffParam, reflectionParam);
         }
 
         return false;
@@ -205,15 +208,23 @@
      * @param method description of the method to find
      * @return the reflected method, or null if not found.
      */
-    @SuppressWarnings("unchecked")
     static Method findMatchingMethod(Class<?> runtimeClass,
             JDiffClassDescription.JDiffMethod method) {
-        Method[] methods = runtimeClass.getDeclaredMethods();
 
-        for (Method m : methods) {
-            if (matches(method, m)) {
-                return m;
+        // Search through the class to find the methods just in case the method was actually
+        // declared in a superclass which is not part of the API and so was made to appear as if
+        // it was declared in each of the hidden class' subclasses. Cannot use getMethods() as that
+        // will only return public methods and the API includes protected methods.
+        while (runtimeClass != null) {
+            Method[] methods = runtimeClass.getDeclaredMethods();
+
+            for (Method m : methods) {
+                if (matches(method, m)) {
+                    return m;
+                }
             }
+
+            runtimeClass = runtimeClass.getSuperclass();
         }
 
         return null;
@@ -232,13 +243,20 @@
         if (!jDiffMethod.mName.equals(reflectedMethod.getName())) {
             return false;
         }
+
+        // If the method is a bridge then use a special comparator for comparing types as
+        // bridge methods created for generic methods may not have generic signatures.
+        // See b/123558763 for more information.
+        TypeComparator typeComparator = reflectedMethod.isBridge()
+                ? BridgeTypeComparator.INSTANCE : DefaultTypeComparator.INSTANCE;
+
         String jdiffReturnType = jDiffMethod.mReturnType;
         String reflectionReturnType = typeToString(reflectedMethod.getGenericReturnType());
         List<String> jdiffParamList = jDiffMethod.mParamList;
 
         // Next, compare the return types of the two methods.  If
         // they aren't equal, the methods can't match.
-        if (!jdiffReturnType.equals(reflectionReturnType)) {
+        if (!typeComparator.compare(jdiffReturnType, reflectionReturnType)) {
             return false;
         }
 
@@ -254,7 +272,7 @@
 
         // Compare method parameters piecewise and return true if they all match.
         for (int i = 0; i < jdiffParamList.size(); i++) {
-            piecewiseParamsMatch &= compareParam(jdiffParamList.get(i), params[i]);
+            piecewiseParamsMatch &= compareParam(jdiffParamList.get(i), params[i], typeComparator);
         }
         if (piecewiseParamsMatch) {
             return true;
@@ -506,4 +524,49 @@
             return null;
         }
     }
+
+    /**
+     * Compare the string representation of types for equality.
+     */
+    interface TypeComparator {
+        boolean compare(String apiType, String reflectedType);
+    }
+
+    /**
+     * Compare the types using their default signature, i.e. generic for generic methods, otherwise
+     * basic types.
+     */
+    static class DefaultTypeComparator implements TypeComparator {
+        static final TypeComparator INSTANCE = new DefaultTypeComparator();
+        @Override
+        public boolean compare(String apiType, String reflectedType) {
+            return apiType.equals(reflectedType);
+        }
+    }
+
+    /**
+     * Comparator for the types of bridge methods.
+     *
+     * <p>Bridge methods may not have generic signatures so compare as for
+     * {@link DefaultTypeComparator}, but if they do not match and the api type is
+     * generic then fall back to comparing their raw types.
+     */
+    static class BridgeTypeComparator implements TypeComparator {
+        static final TypeComparator INSTANCE = new BridgeTypeComparator();
+        @Override
+        public boolean compare(String apiType, String reflectedType) {
+            if (DefaultTypeComparator.INSTANCE.compare(apiType, reflectedType)) {
+                return true;
+            }
+
+            // If the method is a bridge method and the return types are generic then compare the
+            // non generic types as bridge methods do not have generic types.
+            int index = apiType.indexOf('<');
+            if (index != -1) {
+                String rawReturnType = apiType.substring(0, index);
+                return rawReturnType.equals(reflectedType);
+            }
+            return false;
+        }
+    }
 }
diff --git a/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java b/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java
index 99fbff7..23d555e 100644
--- a/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java
+++ b/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java
@@ -18,6 +18,7 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.junit.Assume.assumeTrue;
@@ -971,6 +972,8 @@
         final Context context = InstrumentationRegistry.getInstrumentation().getContext();
         context.startService(new Intent(context, TestService.class));
         mUiDevice.wait(Until.hasObject(By.clazz(TestService.class)), TIMEOUT);
+        final long sleepTime = 500;
+        SystemClock.sleep(sleepTime);
         context.stopService(new Intent(context, TestService.class));
         mUiDevice.wait(Until.gone(By.clazz(TestService.class)), TIMEOUT);
         final long endTime = System.currentTimeMillis();
@@ -1000,6 +1003,19 @@
         assertEquals(numStarts, 1);
         assertEquals(numStops, 1);
         assertLessThan(startIdx, stopIdx);
+
+        final Map<String, UsageStats> map = mUsageStatsManager.queryAndAggregateUsageStats(
+            startTime, endTime);
+        final UsageStats stats = map.get(mTargetPackage);
+        assertNotNull(stats);
+        final long lastTimeUsed = stats.getLastTimeForegroundServiceUsed();
+        // lastTimeUsed should be falling between startTime and endTime.
+        assertLessThan(startTime, lastTimeUsed);
+        assertLessThan(lastTimeUsed, endTime);
+        final long totalTimeUsed = stats.getTotalTimeForegroundServiceUsed();
+        // because we slept for 500 milliseconds earlier, we know the totalTimeUsed must be more
+        // more than 500 milliseconds.
+        assertLessThan(sleepTime, totalTimeUsed);
     }
 
     @AppModeFull // No usage events access in instant apps
@@ -1050,6 +1066,8 @@
             SystemClock.sleep(500);
         }
 
+        mUiDevice.pressHome();
+
         setUsageSourceSetting(Integer.toString(mUsageStatsManager.USAGE_SOURCE_CURRENT_ACTIVITY));
         launchSubActivity(TaskRootActivity.class);
         // Usage should be attributed to the test app package
diff --git a/tests/tests/binder_ndk/AndroidTest.xml b/tests/tests/binder_ndk/AndroidTest.xml
index c627392..bcdb45e 100644
--- a/tests/tests/binder_ndk/AndroidTest.xml
+++ b/tests/tests/binder_ndk/AndroidTest.xml
@@ -16,6 +16,8 @@
 <configuration description="Config for CTS NDK Binder test cases">
     <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="devtools" />
+    <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="not-shardable" value="true" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/tests/tests/bionic/Android.build.copy.libs.mk b/tests/tests/bionic/Android.build.copy.libs.mk
index f346b8a..0d4b701 100644
--- a/tests/tests/bionic/Android.build.copy.libs.mk
+++ b/tests/tests/bionic/Android.build.copy.libs.mk
@@ -1,10 +1,12 @@
 LOCAL_PATH := $(call my-dir)
 
 cts_bionic_tests_dir := lib32
+lib_or_lib64 := lib
 
 ifeq (true,$(TARGET_IS_64_BIT))
   ifeq (,$(cts_bionic_tests_2nd_arch_prefix))
     cts_bionic_tests_dir := lib64
+    lib_or_lib64 := lib64
   endif
 endif
 
@@ -16,6 +18,7 @@
   dt_runpath_b_c_x/libtest_dt_runpath_b.so \
   dt_runpath_b_c_x/libtest_dt_runpath_c.so \
   dt_runpath_b_c_x/libtest_dt_runpath_x.so \
+  dt_runpath_y/$(lib_or_lib64)/libtest_dt_runpath_y.so \
   elftls_dlopen_ie_error_helper/elftls_dlopen_ie_error_helper \
   exec_linker_helper/exec_linker_helper \
   exec_linker_helper_lib.so \
@@ -39,7 +42,6 @@
   libdlext_test_runpath_zip/libdlext_test_runpath_zip_zipaligned.zip \
   libdlext_test_zip/libdlext_test_zip.so \
   libdlext_test_zip/libdlext_test_zip_zipaligned.zip \
-  libelf-tls-library.so \
   libsysv-hash-table-library.so \
   libtest_atexit.so \
   libtest_check_order_dlsym.so \
@@ -75,6 +77,10 @@
   libtest_dlsym_from_this_grandchild.so \
   libtest_dlsym_weak_func.so \
   libtest_dt_runpath_d.so \
+  libtest_elftls_dynamic.so \
+  libtest_elftls_dynamic_filler_1.so \
+  libtest_elftls_dynamic_filler_2.so \
+  libtest_elftls_dynamic_filler_3.so \
   libtest_elftls_shared_var.so \
   libtest_elftls_shared_var_ie.so \
   libtest_elftls_tprel.so \
@@ -162,9 +168,28 @@
     $(my_bionic_testlibs_src_dir)/$(lib):$(my_bionic_testlibs_out_dir)/$(lib))
 endif
 
+# Special casing for libtest_dt_runpath_y.so. Since we use the standard ARM CTS
+# to test ARM-on-x86 devices where ${LIB} is expanded to lib/arm, the lib
+# is installed to ./lib/arm as well as ./lib to make sure that the lib can be
+# found on any device.
+archname := $(TARGET_ARCH)
+ifneq (,$(cts_bionic_tests_2nd_arch_prefix))
+  archname := $(TARGET_2ND_ARCH)
+endif
+
+src := $(my_bionic_testlibs_src_dir)/dt_runpath_y/$(lib_or_lib64)/libtest_dt_runpath_y.so
+dst := $(my_bionic_testlibs_out_dir)/dt_runpath_y/$(lib_or_lib64)/$(archname)/libtest_dt_runpath_y.so
+
+LOCAL_COMPATIBILITY_SUPPORT_FILES += $(src):$(dst)
+
 my_bionic_testlib_files :=
 my_bionic_testlib_files_non_mips :=
 my_bionic_testlibs_src_dir :=
 my_bionic_testlibs_out_dir :=
 cts_bionic_tests_dir :=
 cts_bionic_tests_2nd_arch_prefix :=
+lib_or_lib64 :=
+archname :=
+src :=
+dst :=
+
diff --git a/tests/tests/car/src/android/car/cts/CarPackageManagerTest.java b/tests/tests/car/src/android/car/cts/CarPackageManagerTest.java
index ec79572..ffbaaa5 100644
--- a/tests/tests/car/src/android/car/cts/CarPackageManagerTest.java
+++ b/tests/tests/car/src/android/car/cts/CarPackageManagerTest.java
@@ -37,7 +37,6 @@
 import java.util.List;
 
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
diff --git a/tests/tests/car/src/android/car/cts/CarSensorManagerTest.java b/tests/tests/car/src/android/car/cts/CarSensorManagerTest.java
index 3b9d8eb..c7cce6d 100644
--- a/tests/tests/car/src/android/car/cts/CarSensorManagerTest.java
+++ b/tests/tests/car/src/android/car/cts/CarSensorManagerTest.java
@@ -33,7 +33,6 @@
 import java.util.stream.IntStream;
 
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -55,7 +54,6 @@
 
     @CddTest(requirement="2.5.1")
     @Test
-    @Ignore // Enable when b/120125891 is fixed
     public void testRequiredSensorsForDrivingState() throws Exception {
         boolean foundSpeed = false;
         boolean foundGear = false;
diff --git a/tests/tests/content/AndroidManifest.xml b/tests/tests/content/AndroidManifest.xml
index 79f0cb0..1f1d62e 100644
--- a/tests/tests/content/AndroidManifest.xml
+++ b/tests/tests/content/AndroidManifest.xml
@@ -218,6 +218,15 @@
             </intent-filter>
         </receiver>
 
+        <activity android:name="android.content.pm.cts.LauncherMockActivity"
+                  android:enabled="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.HOME" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+
         <!-- Used for PackageManager test, don't delete this MockContentProvider provider -->
         <provider android:name="android.content.cts.MockContentProvider" android:authorities="ctstest"
             android:multiprocess="false" />
diff --git a/tests/tests/content/res/layout/source_style_layout.xml b/tests/tests/content/res/layout/source_style_layout.xml
new file mode 100644
index 0000000..f861155
--- /dev/null
+++ b/tests/tests/content/res/layout/source_style_layout.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2019 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
+  -->
+
+<View xmlns:android="http://schemas.android.com/apk/res/android"
+      xmlns:app="http://schemas.android.com/apk/res-auto"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              style="@style/StyleA"
+              app:type1="true"/>
\ No newline at end of file
diff --git a/tests/tests/content/res/values/styles.xml b/tests/tests/content/res/values/styles.xml
index 7da5c5e..bc583f1 100644
--- a/tests/tests/content/res/values/styles.xml
+++ b/tests/tests/content/res/values/styles.xml
@@ -41,6 +41,7 @@
 
     <style name="StyleA" parent="StyleB">
         <item name="type1">true</item>
+        <item name="type17">@color/testcolor_orientation</item>
     </style>
     <style name="StyleB" parent="StyleC">
         <item name="type1">false</item>
diff --git a/tests/tests/content/src/android/content/pm/cts/LauncherAppsTest.java b/tests/tests/content/src/android/content/pm/cts/LauncherAppsTest.java
new file mode 100644
index 0000000..77250f8
--- /dev/null
+++ b/tests/tests/content/src/android/content/pm/cts/LauncherAppsTest.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2019 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.content.pm.cts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import android.app.PendingIntent;
+import android.app.usage.UsageStatsManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.LauncherApps;
+import android.os.Process;
+import android.os.UserHandle;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.compatibility.common.util.SystemUtil;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(AndroidJUnit4.class)
+public class LauncherAppsTest {
+
+    private Context mContext;
+    private LauncherApps mLauncherApps;
+    private UsageStatsManager mUsageStatsManager;
+    private ComponentName mDefaultHome;
+    private ComponentName mTestHome;
+
+    private static final String PACKAGE_NAME = "android.content.cts";
+    private static final String FULL_CLASS_NAME = "android.content.pm.cts.LauncherMockActivity";
+
+    private static final int DEFAULT_OBSERVER_ID = 0;
+    private static final String SETTINGS_PACKAGE = "com.android.settings";
+    private static final String[] SETTINGS_PACKAGE_GROUP = new String[] {SETTINGS_PACKAGE};
+    private static final int DEFAULT_TIME_LIMIT = 1;
+    private static final UserHandle USER_HANDLE = Process.myUserHandle();
+
+    @Before
+    public void setUp() throws Exception {
+        mContext = InstrumentationRegistry.getTargetContext();
+        mLauncherApps = (LauncherApps) mContext.getSystemService(Context.LAUNCHER_APPS_SERVICE);
+        mUsageStatsManager = (UsageStatsManager) mContext.getSystemService(
+                Context.USAGE_STATS_SERVICE);
+
+        mDefaultHome = mContext.getPackageManager().getHomeActivities(new ArrayList<>());
+        mTestHome = new ComponentName(PACKAGE_NAME, FULL_CLASS_NAME);
+        setHomeActivity(mTestHome);
+    }
+
+    @Test
+    public void testGetAppUsageLimit_isNull() {
+        final LauncherApps.AppUsageLimit limit = mLauncherApps.getAppUsageLimit(
+                SETTINGS_PACKAGE, USER_HANDLE);
+        assertNull(limit); // An observer was never registered
+    }
+
+    @Test
+    public void testGetAppUsageLimit_isNotNull() {
+        registerDefaultObserver();
+        final LauncherApps.AppUsageLimit limit = mLauncherApps.getAppUsageLimit(
+                SETTINGS_PACKAGE, USER_HANDLE);
+        assertNotNull(limit);
+    }
+
+    @Test
+    public void testGetAppUsageLimit_isNullOnUnregister() {
+        registerDefaultObserver();
+        unregisterObserver(DEFAULT_OBSERVER_ID);
+        final LauncherApps.AppUsageLimit limit = mLauncherApps.getAppUsageLimit(
+                SETTINGS_PACKAGE, USER_HANDLE);
+        assertNull("An unregistered observer was returned.", limit);
+    }
+
+    @Test
+    public void testGetAppUsageLimit_getTotalUsageLimit() {
+        registerDefaultObserver();
+        final LauncherApps.AppUsageLimit limit = mLauncherApps.getAppUsageLimit(
+                SETTINGS_PACKAGE, USER_HANDLE);
+        assertEquals("Total usage limit not equal to the limit registered.",
+                TimeUnit.MINUTES.toMillis(DEFAULT_TIME_LIMIT), limit.getTotalUsageLimit());
+    }
+
+    @Test
+    public void testGetAppUsageLimit_getTotalUsageRemaining() {
+        registerDefaultObserver();
+        final LauncherApps.AppUsageLimit limit = mLauncherApps.getAppUsageLimit(
+                SETTINGS_PACKAGE, USER_HANDLE);
+        assertEquals("Usage remaining not equal to the total limit with no usage.",
+                limit.getTotalUsageLimit(), limit.getUsageRemaining());
+    }
+
+    @Test
+    public void testGetAppUsageLimit_smallestLimitReturned() {
+        registerDefaultObserver();
+        registerObserver(1, 5);
+        final LauncherApps.AppUsageLimit limit = mLauncherApps.getAppUsageLimit(
+                SETTINGS_PACKAGE, USER_HANDLE);
+        try {
+            assertEquals("Smallest usage limit not returned when multiple limits exist.",
+                    TimeUnit.MINUTES.toMillis(DEFAULT_TIME_LIMIT), limit.getTotalUsageLimit());
+        } finally {
+            unregisterObserver(1);
+        }
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        unregisterObserver(DEFAULT_OBSERVER_ID);
+        if (mDefaultHome != null) {
+            setHomeActivity(mDefaultHome);
+        }
+    }
+
+    private void registerDefaultObserver() {
+        registerObserver(DEFAULT_OBSERVER_ID, DEFAULT_TIME_LIMIT);
+    }
+
+    private void registerObserver(int observerId, long timeLimitInMinutes) {
+        SystemUtil.runWithShellPermissionIdentity(() ->
+                mUsageStatsManager.registerAppUsageLimitObserver(
+                        observerId, SETTINGS_PACKAGE_GROUP, timeLimitInMinutes, TimeUnit.MINUTES,
+                        PendingIntent.getActivity(mContext, -1, new Intent(), 0)));
+    }
+
+    private void unregisterObserver(int observerId) {
+        SystemUtil.runWithShellPermissionIdentity(() ->
+                mUsageStatsManager.unregisterAppUsageLimitObserver(observerId));
+    }
+
+    private void setHomeActivity(ComponentName component) throws Exception {
+        SystemUtil.runShellCommand("cmd package set-home-activity --user "
+                + USER_HANDLE.getIdentifier() + " " + component.flattenToString());
+    }
+}
diff --git a/tests/tests/debug/src/android/debug/cts/DebugTest.java b/tests/tests/content/src/android/content/pm/cts/LauncherMockActivity.java
similarity index 66%
rename from tests/tests/debug/src/android/debug/cts/DebugTest.java
rename to tests/tests/content/src/android/content/pm/cts/LauncherMockActivity.java
index 993f02b..16077f2 100644
--- a/tests/tests/debug/src/android/debug/cts/DebugTest.java
+++ b/tests/tests/content/src/android/content/pm/cts/LauncherMockActivity.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2019 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.
@@ -14,12 +14,9 @@
  * limitations under the License.
  */
 
-package android.debug.cts;
+package android.content.pm.cts;
 
-import org.junit.runner.RunWith;
-import com.android.gtestrunner.GtestRunner;
-import com.android.gtestrunner.TargetLibrary;
+import android.app.Activity;
 
-@RunWith(GtestRunner.class)
-@TargetLibrary("debugtest")
-public class DebugTest {}
+public class LauncherMockActivity extends Activity {
+}
diff --git a/tests/tests/content/src/android/content/res/cts/TypedArrayTest.java b/tests/tests/content/src/android/content/res/cts/TypedArrayTest.java
index 38a6a5b..d98bda8 100644
--- a/tests/tests/content/src/android/content/res/cts/TypedArrayTest.java
+++ b/tests/tests/content/src/android/content/res/cts/TypedArrayTest.java
@@ -28,8 +28,10 @@
 import android.test.AndroidTestCase;
 import android.util.AttributeSet;
 import android.util.TypedValue;
+import android.util.Xml;
 import android.view.ContextThemeWrapper;
 
+import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
 import java.io.IOException;
@@ -72,19 +74,41 @@
         mTypedArray.recycle();
     }
 
-    public void testSourceStyleResourceId() {
+    public void testSourceResourceIdFromStyle() {
         final TypedArray t = getContext().getTheme().obtainStyledAttributes(
                 R.style.StyleA, R.styleable.style1);
 
-        assertEquals(R.style.StyleA, t.getSourceStyleResourceId(R.styleable.style1_type1, 0));
-        assertEquals(R.style.StyleB, t.getSourceStyleResourceId(R.styleable.style1_type2, 0));
-        assertEquals(R.style.StyleC, t.getSourceStyleResourceId(R.styleable.style1_type3, 0));
-        assertEquals(R.style.StyleB, t.getSourceStyleResourceId(R.styleable.style1_type4, 0));
-        assertEquals(0, t.getSourceStyleResourceId(R.styleable.style1_type5, 0));
+        assertEquals(R.style.StyleA, t.getSourceResourceId(R.styleable.style1_type1, 0));
+        assertEquals(R.style.StyleB, t.getSourceResourceId(R.styleable.style1_type2, 0));
+        assertEquals(R.style.StyleC, t.getSourceResourceId(R.styleable.style1_type3, 0));
+        assertEquals(R.style.StyleB, t.getSourceResourceId(R.styleable.style1_type4, 0));
+        assertEquals(0, t.getSourceResourceId(R.styleable.style1_type5, 0));
+        assertEquals(R.style.StyleA, t.getSourceResourceId(R.styleable.style1_type17, 0));
 
         t.recycle();
     }
 
+    public void testSourceResourceIdFromLayout() throws Exception {
+        XmlResourceParser parser =
+                getContext().getResources().getLayout(R.layout.source_style_layout);
+
+        final AttributeSet attrs = Xml.asAttributeSet(parser);
+
+        // Look for the root node.
+        assertEquals(XmlPullParser.START_DOCUMENT, parser.next());
+        assertEquals(XmlPullParser.START_TAG, parser.next());
+
+        final TypedArray t = getContext().getTheme().obtainStyledAttributes(
+                attrs, R.styleable.style1, 0, 0);
+        assertEquals(R.layout.source_style_layout,
+                t.getSourceResourceId(R.styleable.style1_type1, 0));
+        assertEquals(R.style.StyleB, t.getSourceResourceId(R.styleable.style1_type2, 0));
+        assertEquals(R.style.StyleC, t.getSourceResourceId(R.styleable.style1_type3, 0));
+        assertEquals(R.style.StyleB, t.getSourceResourceId(R.styleable.style1_type4, 0));
+        assertEquals(0, t.getSourceResourceId(R.styleable.style1_type5, 0));
+        assertEquals(R.style.StyleA, t.getSourceResourceId(R.styleable.style1_type17, 0));
+    }
+
     public void testGetType() {
         final TypedArray t = getContext().getTheme().obtainStyledAttributes(
                 R.style.Whatever, R.styleable.style1);
diff --git a/tests/tests/debug/AndroidManifest.xml b/tests/tests/debug/AndroidManifest.xml
deleted file mode 100644
index 091e778..0000000
--- a/tests/tests/debug/AndroidManifest.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 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.debug.cts">
-
-    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
-    <application android:debuggable="true">
-        <uses-library android:name="android.test.runner" />
-    </application>
-
-    <!-- This is a self-instrumenting test package. -->
-    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="android.debug.cts"
-                     android:label="CTS tests of native debugging API">
-    </instrumentation>
-
-</manifest>
-
diff --git a/tests/tests/debug/AndroidTest.xml b/tests/tests/debug/AndroidTest.xml
deleted file mode 100644
index c6d6de3..0000000
--- a/tests/tests/debug/AndroidTest.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 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 Debug test cases">
-    <option name="test-suite-tag" value="cts" />
-    <option name="config-descriptor:metadata" key="component" value="devtools" />
-    <option name="not-shardable" value="true" />
-    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
-        <option name="cleanup-apks" value="true" />
-        <option name="test-file-name" value="CtsDebugTestCases.apk" />
-    </target_preparer>
-    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
-        <option name="package" value="android.debug.cts" />
-        <option name="runtime-hint" value="0m5s" />
-    </test>
-</configuration>
diff --git a/tests/tests/debug/libdebugtest/Android.mk b/tests/tests/debug/libdebugtest/Android.mk
deleted file mode 100644
index d3db70f..0000000
--- a/tests/tests/debug/libdebugtest/Android.mk
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright (C) 2017 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.
-
-#
-# This is the shared library included by the JNI test app.
-#
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libdebugtest
-
-LOCAL_CFLAGS := -Wall -Werror
-
-# Don't include this package in any configuration by default.
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SRC_FILES := \
-	android_debug_cts.cpp
-
-LOCAL_SHARED_LIBRARIES := liblog
-LOCAL_WHOLE_STATIC_LIBRARIES := libnativetesthelper_jni
-
-LOCAL_SDK_VERSION := 23
-LOCAL_NDK_STL_VARIANT := c++_static
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/tests/tests/debug/libdebugtest/android_debug_cts.cpp b/tests/tests/debug/libdebugtest/android_debug_cts.cpp
deleted file mode 100644
index 3aa4318..0000000
--- a/tests/tests/debug/libdebugtest/android_debug_cts.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <jni.h>
-#include <gtest/gtest.h>
-#include <android/log.h>
-
-#include <errno.h>
-#include <sys/ptrace.h>
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-#include <functional>
-#include <vector>
-
-#define LOG_TAG "Cts-DebugTest"
-
-// Used by child processes only
-#define assert_or_exit(x)                                                                         \
-    do {                                                                                          \
-        if(x) break;                                                                              \
-        __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "Assertion " #x " failed. errno(%d): %s", \
-                errno, strerror(errno));                                                          \
-        _exit(1);                                                                                 \
-    } while (0)
-
-static void parent(pid_t child) {
-    int status;
-    int wpid = waitpid(child, &status, 0);
-    ASSERT_EQ(child, wpid);
-    ASSERT_TRUE(WIFEXITED(status));
-    ASSERT_EQ(0, WEXITSTATUS(status));
-}
-
-static void run_test(const std::function<void(pid_t)> &test) {
-    pid_t pid = fork();
-    ASSERT_NE(-1, pid) << "fork() failed with " << strerror(errno);
-    if (pid != 0) {
-        parent(pid);
-    } else {
-        // child
-        test(getppid());
-        _exit(0);
-    }
-}
-
-static void ptraceAttach(pid_t parent) {
-    assert_or_exit(ptrace(PTRACE_ATTACH, parent, nullptr, nullptr) == 0);
-    int status;
-    assert_or_exit(waitpid(parent, &status, __WALL) == parent);
-    assert_or_exit(WIFSTOPPED(status));
-    assert_or_exit(WSTOPSIG(status) == SIGSTOP);
-
-    assert_or_exit(ptrace(PTRACE_DETACH, parent, nullptr, nullptr) == 0);
-}
-
-TEST(DebugTest, ptraceAttach) {
-    run_test(ptraceAttach);
-}
-
-static void processVmReadv(pid_t parent, const std::vector<long *> &addresses) {
-    long destination;
-    iovec local = { &destination, sizeof destination };
-
-    for (long *address : addresses) {
-        // Since we are forked, the address will be valid in the remote process as well.
-        iovec remote = { address, sizeof *address };
-        __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "%s About to read %p\n", __func__,
-                            address);
-        assert_or_exit(process_vm_readv(parent, &local, 1, &remote, 1, 0) == sizeof destination);
-
-        // Compare the data with the contents of our memory.
-        assert_or_exit(destination == *address);
-    }
-}
-
-static long global_variable = 0x47474747;
-// public static native boolean processVmReadv();
-TEST(DebugTest, processVmReadv) {
-    long stack_variable = 0x42424242;
-    // This runs the test with a selection of different kinds of addresses and
-    // makes sure the child process (simulating a debugger) can read them.
-    run_test([&](pid_t parent) {
-        processVmReadv(parent, std::vector<long *>{
-                                   &global_variable, &stack_variable,
-                                   reinterpret_cast<long *>(&processVmReadv)});
-    });
-}
-
-// public static native boolean processVmReadvNullptr();
-TEST(DebugTest, processVmReadvNullptr) {
-    // Make sure reading unallocated memory behaves reasonably.
-    run_test([](pid_t parent) {
-        long destination;
-        iovec local = {&destination, sizeof destination};
-        iovec remote = {nullptr, sizeof(long)};
-
-        assert_or_exit(process_vm_readv(parent, &local, 1, &remote, 1, 0) == -1);
-        assert_or_exit(errno == EFAULT);
-    });
-}
diff --git a/tests/tests/dynamic_linker/AndroidTest.xml b/tests/tests/dynamic_linker/AndroidTest.xml
index a043e15..e4fa4cb 100644
--- a/tests/tests/dynamic_linker/AndroidTest.xml
+++ b/tests/tests/dynamic_linker/AndroidTest.xml
@@ -16,6 +16,8 @@
 <configuration description="Config for CTS dynamic linker test cases">
     <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="bionic" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
         <option name="test-file-name" value="CtsDynamicLinkerTestCases27.apk" />
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_arcto_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_arcto_golden.png
index 9ba7c00..d1ef33b 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_arcto_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_arcto_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_clip_path_1_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_clip_path_1_golden.png
index 6cafa84..2663f3c 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_clip_path_1_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_clip_path_1_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_create_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_create_golden.png
index b0b6eb5..535b435 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_create_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_create_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_delete_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_delete_golden.png
index 9f60a31..75805c6 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_delete_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_delete_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_filltype_evenodd_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_filltype_evenodd_golden.png
index 3d14630..5765d1d 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_filltype_evenodd_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_filltype_evenodd_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_filltype_nonzero_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_filltype_nonzero_golden.png
index 87ffcc1..587ca1e 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_filltype_nonzero_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_filltype_nonzero_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_1_clamp_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_1_clamp_golden.png
index 859df7e..e3be1d1 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_1_clamp_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_1_clamp_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_1_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_1_golden.png
index 78ef42b..ce18075 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_1_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_1_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_2_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_2_golden.png
index 29aee85..f991189 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_2_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_2_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_2_repeat_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_2_repeat_golden.png
index 1c13c30..f2798b4 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_2_repeat_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_2_repeat_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_3_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_3_golden.png
index f2cb106..aee71ec 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_3_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_3_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_3_mirror_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_3_mirror_golden.png
index 34e0571..a879e3c 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_3_mirror_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_3_mirror_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_group_clip_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_group_clip_golden.png
index c9702c9..f227465 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_group_clip_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_group_clip_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_heart_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_heart_golden.png
index b0af7d4..051689a 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_heart_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_heart_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_implicit_lineto_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_implicit_lineto_golden.png
index 9d74952..b18a6bf 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_implicit_lineto_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_implicit_lineto_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_random_path_1_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_random_path_1_golden.png
index e779718..90442f0 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_random_path_1_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_random_path_1_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_random_path_2_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_random_path_2_golden.png
index 7ba7191..c9d8e1f 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_random_path_2_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_random_path_2_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_render_order_1_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_render_order_1_golden.png
index 2fca8eb..7b2f066 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_render_order_1_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_render_order_1_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_render_order_2_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_render_order_2_golden.png
index f317901..96b2fc9 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_render_order_2_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_render_order_2_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_repeated_a_1_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_repeated_a_1_golden.png
index 37a0d21..b78975c 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_repeated_a_1_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_repeated_a_1_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_repeated_a_2_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_repeated_a_2_golden.png
index b011284..26d6846 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_repeated_a_2_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_repeated_a_2_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_repeated_cq_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_repeated_cq_golden.png
index 9e92c8a..74f5ed7 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_repeated_cq_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_repeated_cq_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_repeated_st_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_repeated_st_golden.png
index 0262e57..d08870a 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_repeated_st_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_repeated_st_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_scale_1_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_scale_1_golden.png
index 1520397..4b02211 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_scale_1_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_scale_1_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_scale_2_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_scale_2_golden.png
index 727bb48..ac67731 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_scale_2_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_scale_2_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_scale_3_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_scale_3_golden.png
index d68ab90..49639cb 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_scale_3_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_scale_3_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_schedule_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_schedule_golden.png
index 2830840..b5163e9 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_schedule_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_schedule_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_settings_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_settings_golden.png
index b5d25be..39f26aa 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_settings_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_settings_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_state_list_2_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_state_list_2_golden.png
index 923347d..e090273 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_state_list_2_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_state_list_2_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_state_list_2_pressed_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_state_list_2_pressed_golden.png
index 74c30fa..fddd4ec 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_state_list_2_pressed_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_state_list_2_pressed_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_state_list_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_state_list_golden.png
index 923347d..e090273 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_state_list_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_state_list_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_state_list_pressed_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_state_list_pressed_golden.png
index 74c30fa..fddd4ec 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_state_list_pressed_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_state_list_pressed_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_stroke_1_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_stroke_1_golden.png
index c202ffc..f016ee5 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_stroke_1_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_stroke_1_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_stroke_2_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_stroke_2_golden.png
index ed31e47..c09c1d9 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_stroke_2_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_stroke_2_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_stroke_3_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_stroke_3_golden.png
index a32de90..d9884a6 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_stroke_3_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_stroke_3_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_transformation_1_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_transformation_1_golden.png
index 26cbe2a..f819839 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_transformation_1_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_transformation_1_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_transformation_2_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_transformation_2_golden.png
index 9aeeeef..03b82e3 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_transformation_2_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_transformation_2_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_transformation_3_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_transformation_3_golden.png
index 468a1c3..352798b 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_transformation_3_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_transformation_3_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_transformation_4_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_transformation_4_golden.png
index e4bc055..d91fa66 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_transformation_4_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_transformation_4_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_transformation_5_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_transformation_5_golden.png
index bb185f2..530bb51 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_transformation_5_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_transformation_5_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_transformation_6_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_transformation_6_golden.png
index 02901b6..ec2ad7e 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_transformation_6_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_transformation_6_golden.png
Binary files differ
diff --git a/tests/tests/graphics/src/android/graphics/cts/BitmapTest.java b/tests/tests/graphics/src/android/graphics/cts/BitmapTest.java
index 59d3e56..f4cdf7a 100644
--- a/tests/tests/graphics/src/android/graphics/cts/BitmapTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/BitmapTest.java
@@ -57,6 +57,8 @@
 import java.nio.CharBuffer;
 import java.nio.IntBuffer;
 import java.nio.ShortBuffer;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
@@ -78,6 +80,22 @@
     private Bitmap mBitmap;
     private BitmapFactory.Options mOptions;
 
+    public static List<ColorSpace> getRgbColorSpaces() {
+        List<ColorSpace> rgbColorSpaces;
+        rgbColorSpaces = new ArrayList<ColorSpace>();
+        for (ColorSpace.Named e : ColorSpace.Named.values()) {
+            ColorSpace cs = ColorSpace.get(e);
+            if (cs.getModel() != ColorSpace.Model.RGB) {
+                continue;
+            }
+            if (((ColorSpace.Rgb) cs).getTransferParameters() == null) {
+                continue;
+            }
+            rgbColorSpaces.add(cs);
+        }
+        return rgbColorSpaces;
+    }
+
     @Before
     public void setup() {
         mRes = InstrumentationRegistry.getTargetContext().getResources();
@@ -612,6 +630,102 @@
         assertEquals(0xffff0000, mBitmap.getPixel(50, 50));
     }
 
+    @Test(expected = IllegalArgumentException.class)
+    public void testGetColorOOB() {
+        mBitmap = Bitmap.createBitmap(100, 100, Config.ARGB_8888);
+        mBitmap.getColor(-1, 0);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testGetColorOOB2() {
+        mBitmap = Bitmap.createBitmap(100, 100, Config.ARGB_8888);
+        mBitmap.getColor(5, -10);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testGetColorOOB3() {
+        mBitmap = Bitmap.createBitmap(100, 100, Config.ARGB_8888);
+        mBitmap.getColor(100, 10);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testGetColorOOB4() {
+        mBitmap = Bitmap.createBitmap(100, 100, Config.ARGB_8888);
+        mBitmap.getColor(99, 1000);
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void testGetColorRecycled() {
+        mBitmap = Bitmap.createBitmap(100, 100, Config.ARGB_8888);
+        mBitmap.recycle();
+        mBitmap.getColor(0, 0);
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void testGetColorHardware() {
+        BitmapFactory.Options options = new BitmapFactory.Options();
+        options.inPreferredConfig = Bitmap.Config.HARDWARE;
+        mBitmap = BitmapFactory.decodeResource(mRes, R.drawable.start, options);
+        mBitmap.getColor(50, 50);
+
+    }
+
+    private static float clamp(float f) {
+        return clamp(f, 0.0f, 1.0f);
+    }
+
+    private static float clamp(float f, float min, float max) {
+        return Math.min(Math.max(f, min), max);
+    }
+
+    @Test
+    public void testGetColor() {
+        final ColorSpace sRGB = ColorSpace.get(ColorSpace.Named.SRGB);
+        List<ColorSpace> rgbColorSpaces = getRgbColorSpaces();
+        for (Config config : new Config[] { Config.ARGB_8888, Config.RGBA_F16, Config.RGB_565 }) {
+            for (ColorSpace bitmapColorSpace : rgbColorSpaces) {
+                mBitmap = Bitmap.createBitmap(1, 1, config, /*hasAlpha*/ false,
+                        bitmapColorSpace);
+                bitmapColorSpace = mBitmap.getColorSpace();
+                for (ColorSpace eraseColorSpace : rgbColorSpaces) {
+                    for (long wideGamutLong : new long[] {
+                            Color.pack(1.0f, 0.0f, 0.0f, 1.0f, eraseColorSpace),
+                            Color.pack(0.0f, 1.0f, 0.0f, 1.0f, eraseColorSpace),
+                            Color.pack(0.0f, 0.0f, 1.0f, 1.0f, eraseColorSpace)}) {
+                        mBitmap.eraseColor(wideGamutLong);
+
+                        Color result = mBitmap.getColor(0, 0);
+                        if (mBitmap.getColorSpace().equals(sRGB)) {
+                            assertEquals(mBitmap.getPixel(0, 0), result.toArgb());
+                        }
+                        if (eraseColorSpace.equals(bitmapColorSpace)) {
+                            final Color wideGamutColor = Color.valueOf(wideGamutLong);
+                            ColorUtils.verifyColor("Erasing to Bitmap's ColorSpace "
+                                    + bitmapColorSpace, wideGamutColor, result, .0f);
+
+                        } else {
+                            Color convertedColor = Color.valueOf(
+                                    Color.convert(wideGamutLong, bitmapColorSpace));
+                            if (mBitmap.getConfig() != Config.RGBA_F16) {
+                                // It's possible that we have to clip to fit into the Config.
+                                convertedColor = Color.valueOf(
+                                        clamp(convertedColor.red()),
+                                        clamp(convertedColor.green()),
+                                        clamp(convertedColor.blue()),
+                                        convertedColor.alpha(),
+                                        bitmapColorSpace);
+                            }
+                            ColorUtils.verifyColor("Bitmap(Config: " + mBitmap.getConfig()
+                                    + ", ColorSpace: " + bitmapColorSpace
+                                    + ") erasing to " + Color.valueOf(wideGamutLong),
+                                    convertedColor, result, .03f);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
     private static class ARGB {
         public float alpha;
         public float red;
@@ -627,7 +741,7 @@
 
     @Test
     public void testEraseColorLong() {
-        // normal case
+        List<ColorSpace> rgbColorSpaces = getRgbColorSpaces();
         for (Config config : new Config[]{Config.ARGB_8888, Config.RGB_565, Config.RGBA_F16}) {
             mBitmap = Bitmap.createBitmap(100, 100, config);
             // pack SRGB colors into ColorLongs.
@@ -655,14 +769,7 @@
                     continue;
                 }
                 int srgbColor = Color.argb(color.alpha, color.red, color.green, color.blue);
-                for (ColorSpace.Named e : ColorSpace.Named.values()) {
-                    ColorSpace cs = ColorSpace.get(e);
-                    if (cs.getModel() != ColorSpace.Model.RGB) {
-                        continue;
-                    }
-                    if (((ColorSpace.Rgb) cs).getTransferParameters() == null) {
-                        continue;
-                    }
+                for (ColorSpace cs : rgbColorSpaces) {
                     long longColor = Color.convert(srgbColor, cs);
                     mBitmap.eraseColor(longColor);
                     // These tolerances were chosen by trial and error. It is expected that
diff --git a/tests/tests/graphics/src/android/graphics/cts/CanvasTest.java b/tests/tests/graphics/src/android/graphics/cts/CanvasTest.java
new file mode 100644
index 0000000..2c45d6e
--- /dev/null
+++ b/tests/tests/graphics/src/android/graphics/cts/CanvasTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2019 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.cts;
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.ColorSpace;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class CanvasTest {
+    Canvas mCanvas;
+
+    @Before
+    public void setup() {
+        Bitmap bm = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
+        mCanvas = new Canvas(bm);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testDrawColorXYZ() {
+        mCanvas.drawColor(Color.convert(Color.BLUE, ColorSpace.get(ColorSpace.Named.CIE_XYZ)));
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testDrawColorLAB() {
+        mCanvas.drawColor(Color.convert(Color.BLUE, ColorSpace.get(ColorSpace.Named.CIE_LAB)));
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testDrawColorUnknown() {
+        mCanvas.drawColor(-1L);
+    }
+}
diff --git a/tests/tests/graphics/src/android/graphics/cts/Color_ColorLongTest.java b/tests/tests/graphics/src/android/graphics/cts/Color_ColorLongTest.java
index a2c0cd6..a5ccec2 100644
--- a/tests/tests/graphics/src/android/graphics/cts/Color_ColorLongTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/Color_ColorLongTest.java
@@ -15,14 +15,6 @@
  */
 package android.graphics.cts;
 
-import android.graphics.Color;
-import android.graphics.ColorSpace;
-import android.graphics.ColorSpace.Named;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
 import static android.graphics.Color.alpha;
 import static android.graphics.Color.blue;
 import static android.graphics.Color.colorSpace;
@@ -33,6 +25,7 @@
 import static android.graphics.Color.red;
 import static android.graphics.Color.toArgb;
 import static android.graphics.Color.valueOf;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
@@ -40,6 +33,15 @@
 import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 
+import android.graphics.Color;
+import android.graphics.ColorSpace;
+import android.graphics.ColorSpace.Named;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class Color_ColorLongTest {
@@ -419,4 +421,11 @@
         assertEquals(0.4597f, green(color), 0.01f);
         assertEquals(0.0000f, blue(color), 0.01f);
     }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testConvertFailureUnnamedColorSpace() {
+        float[] primaries = new float[]{ .7f, .6f, .5f, .4f, .3f, .2f };
+        ColorSpace cs = new ColorSpace.Rgb("mock", primaries, ColorSpace.ILLUMINANT_A, .7);
+        Color.convert(Color.BLUE, cs);
+    }
 }
diff --git a/tests/tests/graphics/src/android/graphics/cts/EGL15Test.java b/tests/tests/graphics/src/android/graphics/cts/EGL15Test.java
new file mode 100644
index 0000000..04d2d35
--- /dev/null
+++ b/tests/tests/graphics/src/android/graphics/cts/EGL15Test.java
@@ -0,0 +1,327 @@
+/*
+ * Copyright 2017 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.cts;
+
+import static org.junit.Assert.assertEquals;
+//import static android.opengl.EGL14.*;
+//import static android.opengl.EGL15.*;
+
+import android.opengl.EGL14;
+import android.opengl.EGL15;
+import android.opengl.EGLConfig;
+import android.opengl.EGLContext;
+import android.opengl.EGLDisplay;
+import android.opengl.EGLImage;
+import android.opengl.EGLSurface;
+import android.opengl.EGLSync;
+import android.opengl.GLES20;
+import android.support.test.filters.SmallTest;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.BlockJUnit4ClassRunner;
+
+
+@SmallTest
+@RunWith(BlockJUnit4ClassRunner.class)
+public class EGL15Test {
+
+    static {
+        System.loadLibrary("ctsgraphics_jni");
+    }
+
+    private static final String TAG = EGL15Test.class.getSimpleName();
+    private static final boolean DEBUG = false;
+
+    private EGLDisplay mEglDisplay = EGL15.EGL_NO_DISPLAY;
+    private EGLConfig mEglConfig = null;
+    private EGLSurface mEglPbuffer = EGL15.EGL_NO_SURFACE;
+    private EGLContext mEglContext = EGL15.EGL_NO_CONTEXT;
+    private int mEglVersion = 0;
+
+    @Before
+    public void setup() throws Throwable {
+        int error;
+
+        mEglDisplay = EGL15.eglGetPlatformDisplay(EGL15.EGL_PLATFORM_ANDROID_KHR,
+                EGL14.EGL_DEFAULT_DISPLAY,
+                new long[] {
+                    EGL14.EGL_NONE },
+                0);
+        if (mEglDisplay == EGL15.EGL_NO_DISPLAY) {
+            throw new RuntimeException("no EGL display");
+        }
+        error = EGL14.eglGetError();
+        if (error != EGL14.EGL_SUCCESS) {
+            throw new RuntimeException("eglGetPlatformDisplay failed");
+        }
+
+        int[] major = new int[1];
+        int[] minor = new int[1];
+        if (!EGL14.eglInitialize(mEglDisplay, major, 0, minor, 0)) {
+            throw new RuntimeException("error in eglInitialize");
+        }
+        error = EGL14.eglGetError();
+        if (error != EGL14.EGL_SUCCESS) {
+            throw new RuntimeException("eglInitialize failed");
+        }
+        mEglVersion = major[0] * 10 + minor[0];
+
+        // If we could rely on having EGL_KHR_surfaceless_context and EGL_KHR_context_no_config, we
+        // wouldn't have to create a config or pbuffer at all.
+
+        int[] numConfigs = new int[1];
+        EGLConfig[] configs = new EGLConfig[1];
+        if (!EGL14.eglChooseConfig(mEglDisplay,
+                new int[] {
+                    EGL14.EGL_RENDERABLE_TYPE, EGL14.EGL_OPENGL_ES2_BIT,
+                    EGL14.EGL_SURFACE_TYPE, EGL14.EGL_PBUFFER_BIT,
+                    EGL14.EGL_NONE},
+                0, configs, 0, 1, numConfigs, 0)) {
+            throw new RuntimeException("eglChooseConfig failed");
+        }
+        error = EGL14.eglGetError();
+        if (error != EGL14.EGL_SUCCESS) {
+            throw new RuntimeException("eglChooseConfig failed");
+        }
+
+        mEglConfig = configs[0];
+
+        mEglPbuffer = EGL14.eglCreatePbufferSurface(mEglDisplay, mEglConfig,
+                new int[] {EGL14.EGL_WIDTH, 1, EGL14.EGL_HEIGHT, 1, EGL14.EGL_NONE}, 0);
+        if (mEglPbuffer == EGL15.EGL_NO_SURFACE) {
+            throw new RuntimeException("eglCreatePbufferSurface failed");
+        }
+        error = EGL14.eglGetError();
+        if (error != EGL14.EGL_SUCCESS) {
+            throw new RuntimeException("eglCreatePbufferSurface failed");
+        }
+
+
+        mEglContext = EGL14.eglCreateContext(mEglDisplay, mEglConfig, EGL14.EGL_NO_CONTEXT,
+                new int[] {EGL14.EGL_CONTEXT_CLIENT_VERSION, 2, EGL14.EGL_NONE}, 0);
+        if (mEglContext == EGL15.EGL_NO_CONTEXT) {
+            throw new RuntimeException("eglCreateContext failed");
+        }
+        error = EGL14.eglGetError();
+        if (error != EGL14.EGL_SUCCESS) {
+            throw new RuntimeException("eglCreateContext failed");
+        }
+
+
+        if (!EGL14.eglMakeCurrent(mEglDisplay, mEglPbuffer, mEglPbuffer, mEglContext)) {
+            throw new RuntimeException("eglMakeCurrent failed");
+        }
+        error = EGL14.eglGetError();
+        if (error != EGL14.EGL_SUCCESS) {
+            throw new RuntimeException("eglMakeCurrent failed");
+        }
+    }
+
+    @After
+    public void teardown() throws Throwable {
+        EGL14.eglTerminate(mEglDisplay);
+    }
+
+    @Test
+    public void testEGL15SyncFence() {
+        if (mEglVersion < 15) {
+            return;
+        }
+        EGLSync sync = EGL15.eglCreateSync(mEglDisplay, EGL15.EGL_SYNC_FENCE,
+                new long[] {
+                    EGL14.EGL_NONE },
+                0);
+        if (sync == EGL15.EGL_NO_SYNC) {
+            throw new RuntimeException("eglCreateSync failed");
+        }
+        int error = EGL14.eglGetError();
+        if (error != EGL14.EGL_SUCCESS) {
+            throw new RuntimeException("eglCreateSync failed");
+        }
+
+        GLES20.glFlush();
+        error = GLES20.glGetError();
+        if (error != GLES20.GL_NO_ERROR) {
+            throw new RuntimeException("glFlush failed");
+        }
+
+        int status = EGL15.eglClientWaitSync(mEglDisplay, sync, 0, EGL15.EGL_FOREVER);
+        if (status != EGL15.EGL_CONDITION_SATISFIED) {
+            throw new RuntimeException("eglClientWaitSync failed");
+        }
+        error = EGL14.eglGetError();
+        if (error != EGL14.EGL_SUCCESS) {
+            throw new RuntimeException("eglClientWaitSync failed");
+        }
+
+        if (!EGL15.eglDestroySync(mEglDisplay, sync)) {
+            throw new RuntimeException("eglDestroySync failed");
+        }
+        error = EGL14.eglGetError();
+        if (error != EGL14.EGL_SUCCESS) {
+            throw new RuntimeException("eglDestroySync failed");
+        }
+    }
+
+    @Test
+    public void testEGL15GetSyncType() {
+        if (mEglVersion < 15) {
+            return;
+        }
+        EGLSync sync = EGL15.eglCreateSync(mEglDisplay, EGL15.EGL_SYNC_FENCE,
+                new long[] {
+                    EGL14.EGL_NONE },
+                0);
+        if (sync == EGL15.EGL_NO_SYNC) {
+            throw new RuntimeException("eglCreateSync failed");
+        }
+        int error = EGL14.eglGetError();
+        if (error != EGL14.EGL_SUCCESS) {
+            throw new RuntimeException("eglCreateSync failed");
+        }
+
+        long[] type = new long[1];
+        boolean success = EGL15.eglGetSyncAttrib(mEglDisplay, sync, EGL15.EGL_SYNC_TYPE, type, 0);
+        if (!success) {
+            throw new RuntimeException("eglGetSyncAttrib failed (returned false)");
+        }
+        error = EGL14.eglGetError();
+        if (error != EGL14.EGL_SUCCESS) {
+            throw new RuntimeException("eglGetSyncAttrib failed");
+        }
+        assertEquals(type[0], EGL15.EGL_SYNC_FENCE);
+
+        if (!EGL15.eglDestroySync(mEglDisplay, sync)) {
+            throw new RuntimeException("eglDestroySync failed");
+        }
+        error = EGL14.eglGetError();
+        if (error != EGL14.EGL_SUCCESS) {
+            throw new RuntimeException("eglDestroySync failed");
+        }
+    }
+
+    @Test
+    public void testEGL15WaitSync() {
+        if (mEglVersion < 15) {
+            return;
+        }
+        EGLSync sync = EGL15.eglCreateSync(mEglDisplay, EGL15.EGL_SYNC_FENCE,
+                new long[] {
+                    EGL14.EGL_NONE },
+                0);
+        if (sync == EGL15.EGL_NO_SYNC) {
+            throw new RuntimeException("eglCreateSync failed");
+        }
+        int error = EGL14.eglGetError();
+        if (error != EGL14.EGL_SUCCESS) {
+            throw new RuntimeException("eglCreateSync failed");
+        }
+
+        boolean success = EGL15.eglWaitSync(mEglDisplay, sync, 0);
+        if (!success) {
+            throw new RuntimeException("eglWaitSync failed (returned false)");
+        }
+        error = EGL14.eglGetError();
+        if (error != EGL14.EGL_SUCCESS) {
+            throw new RuntimeException("eglWaitSync failed");
+        }
+
+        if (!EGL15.eglDestroySync(mEglDisplay, sync)) {
+            throw new RuntimeException("eglDestroySync failed");
+        }
+        error = EGL14.eglGetError();
+        if (error != EGL14.EGL_SUCCESS) {
+            throw new RuntimeException("eglDestroySync failed");
+        }
+    }
+
+    @Test
+    public void testEGL15CreateImage() {
+        if (mEglVersion < 15) {
+            return;
+        }
+
+        int error;
+        int srcTex = 1;
+        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, srcTex);
+        error = GLES20.glGetError();
+        if (error != GLES20.GL_NO_ERROR) {
+            throw new RuntimeException("glBindTexture failed");
+        }
+
+        GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, 64, 64, 0,
+                            GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null);
+        error = GLES20.glGetError();
+        if (error != GLES20.GL_NO_ERROR) {
+            throw new RuntimeException("glTexImage2D failed");
+        }
+
+        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER,
+                               GLES20.GL_LINEAR);
+        error = GLES20.glGetError();
+        if (error != GLES20.GL_NO_ERROR) {
+            throw new RuntimeException("glTexParameteri failed");
+        }
+
+        long[] attribs = new long[] {
+                EGL15.EGL_GL_TEXTURE_LEVEL, 0,
+                EGL14.EGL_NONE };
+        EGLImage image = EGL15.eglCreateImage(mEglDisplay, mEglContext,
+                EGL15.EGL_GL_TEXTURE_2D, srcTex, attribs, 0);
+        if (image == EGL15.EGL_NO_IMAGE) {
+            throw new RuntimeException("eglCreateImage failed, got EGL_NO_IMAGE");
+        }
+        error = EGL14.eglGetError();
+        if (error != EGL14.EGL_SUCCESS) {
+            throw new RuntimeException("eglCreateImage failed");
+        }
+
+        boolean success = EGL15.eglDestroyImage(mEglDisplay, image);
+        if (!success) {
+            throw new RuntimeException("eglDestroyImage failed (returned false)");
+        }
+        error = EGL14.eglGetError();
+        if (error != EGL14.EGL_SUCCESS) {
+            throw new RuntimeException("eglDestroyImage failed");
+        }
+    }
+
+    @Test
+    public void testEGL15CreatePlatformPixmap() {
+        if (mEglVersion < 15) {
+            return;
+        }
+
+        long[] attribs = new long[] { EGL14.EGL_NONE };
+        boolean unsupported = false;
+        try {
+            EGLSurface surface = EGL15.eglCreatePlatformPixmapSurface(mEglDisplay,
+                    mEglConfig, null, attribs, 0);
+        } catch (UnsupportedOperationException e) {
+            unsupported = true;
+        }
+        if (!unsupported) {
+            throw new RuntimeException("eglCreatePlatformPixmapSurface is not supported on Android,"
+                    + " why did call not report that!");
+        }
+    }
+}
+
+// Note: Need to add tests for eglCreatePlatformWindowSurface
diff --git a/tests/tests/graphics/src/android/graphics/cts/LinearGradientTest.java b/tests/tests/graphics/src/android/graphics/cts/LinearGradientTest.java
index 185e6a1..d5f7f2e 100644
--- a/tests/tests/graphics/src/android/graphics/cts/LinearGradientTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/LinearGradientTest.java
@@ -23,6 +23,7 @@
 import android.graphics.Bitmap.Config;
 import android.graphics.Canvas;
 import android.graphics.Color;
+import android.graphics.ColorSpace;
 import android.graphics.LinearGradient;
 import android.graphics.Matrix;
 import android.graphics.Paint;
@@ -35,6 +36,8 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.function.Function;
+
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class LinearGradientTest {
@@ -46,7 +49,7 @@
         float[] position = { 0.0f, 1.0f / 3.0f, 2.0f / 3.0f };
 
         lg = new LinearGradient(0, 0, 0, 40, color, position, TileMode.CLAMP);
-        b = drawLinearGradient(lg);
+        b = drawLinearGradient(lg, Config.ARGB_8888);
 
         // The pixels in same gradient line should be equivalent
         assertEquals(b.getPixel(10, 10), b.getPixel(20, 10));
@@ -62,7 +65,7 @@
         assertTrue(Color.red(b.getPixel(10, 20)) < Color.red(b.getPixel(10, 25)));
 
         lg = new LinearGradient(0, 0, 0, 40, Color.RED, Color.BLUE, TileMode.CLAMP);
-        b = drawLinearGradient(lg);
+        b = drawLinearGradient(lg, Config.ARGB_8888);
 
         // The pixels in same gradient line should be equivalent
         assertEquals(b.getPixel(10, 10), b.getPixel(20, 10));
@@ -73,10 +76,67 @@
         assertTrue(Color.blue(b.getPixel(10, 15)) < Color.blue(b.getPixel(10, 30)));
     }
 
-    private Bitmap drawLinearGradient(LinearGradient lg) {
+    @Test
+    public void testLinearGradientLong() {
+        ColorSpace p3 = ColorSpace.get(ColorSpace.Named.DISPLAY_P3);
+        long red = Color.pack(1, 0, 0, 1, p3);
+        long green = Color.pack(0, 1, 0, 1, p3);
+        long blue = Color.pack(0, 0, 1, 1, p3);
+        long[] colors = new long[] { blue, green, red };
+        float[] positions = null;
+
+        LinearGradient lg = new LinearGradient(0, 0, 0, 40, colors, positions, TileMode.CLAMP);
+        Bitmap b = drawLinearGradient(lg, Config.RGBA_F16);
+        final ColorSpace bitmapColorSpace = b.getColorSpace();
+        Function<Long, Color> convert = (l) -> {
+            return Color.valueOf(Color.convert(l, bitmapColorSpace));
+        };
+
+        ColorUtils.verifyColor("Top-most color should be mostly blue!",
+                convert.apply(blue), b.getColor(0, 0), 0.09f);
+
+        ColorUtils.verifyColor("Middle color should be mostly green!",
+                convert.apply(green), b.getColor(0, 20), 0.09f);
+
+        ColorUtils.verifyColor("Bottom-most color should be mostly red!",
+                convert.apply(red), b.getColor(0, 39), 0.08f);
+
+        ColorUtils.verifyColor("The pixels in same gradient line should be equivalent!",
+                b.getColor(10, 10), b.getColor(20, 10), 0f);
+        // BLUE -> GREEN, B sub-value decreasing while G sub-value increasing
+        assertTrue(b.getColor(10, 0).blue() > b.getColor(10, 5).blue());
+        assertTrue(b.getColor(10, 5).blue() > b.getColor(10, 10).blue());
+        assertTrue(b.getColor(10, 0).green() < b.getColor(10, 5).green());
+        assertTrue(b.getColor(10, 5).green() < b.getColor(10, 10).green());
+        // GREEN -> RED, G sub-value decreasing while R sub-value increasing
+        assertTrue(b.getColor(10, 20).green() > b.getColor(10, 30).green());
+        assertTrue(b.getColor(10, 30).green() > b.getColor(10, 35).green());
+        assertTrue(b.getColor(10, 20).red() < b.getColor(10, 30).red());
+        assertTrue(b.getColor(10, 30).red() < b.getColor(10, 35).red());
+
+        lg = new LinearGradient(0, 0, 0, 40, red, blue, TileMode.CLAMP);
+        b = drawLinearGradient(lg, Config.RGBA_F16);
+
+        ColorUtils.verifyColor("Top-most color should be mostly red!",
+                convert.apply(red), b.getColor(0, 0), .03f);
+
+        ColorUtils.verifyColor("Bottom-most color should be mostly blue!",
+                convert.apply(blue), b.getColor(0, 39), 0.016f);
+
+
+        ColorUtils.verifyColor("The pixels in same gradient line should be equivalent!",
+                b.getColor(10, 10), b.getColor(20, 10), 0f);
+        // RED -> BLUE, R sub-value decreasing while B sub-value increasing
+        assertTrue(b.getColor(10, 0).red() > b.getColor(10, 15).red());
+        assertTrue(b.getColor(10, 15).red() > b.getColor(10, 30).red());
+        assertTrue(b.getColor(10, 0).blue() < b.getColor(10, 15).blue());
+        assertTrue(b.getColor(10, 15).blue() < b.getColor(10, 30).blue());
+    }
+
+    private Bitmap drawLinearGradient(LinearGradient lg, Config c) {
         Paint paint = new Paint();
         paint.setShader(lg);
-        Bitmap b = Bitmap.createBitmap(40, 40, Config.ARGB_8888);
+        Bitmap b = Bitmap.createBitmap(40, 40, c);
         b.eraseColor(Color.BLACK);
         Canvas canvas = new Canvas(b);
         canvas.drawPaint(paint);
@@ -90,9 +150,84 @@
         Matrix m = new Matrix();
         m.setScale(0, 0);
         gradient.setLocalMatrix(m);
-        Bitmap bitmap = drawLinearGradient(gradient);
+        Bitmap bitmap = drawLinearGradient(gradient, Config.ARGB_8888);
 
         ColorUtils.verifyColor(Color.BLACK, bitmap.getPixel(0, 0), 1);
         ColorUtils.verifyColor(Color.BLACK, bitmap.getPixel(20, 20), 1);
     }
+
+    @Test(expected = NullPointerException.class)
+    public void testNullColorInts() {
+        int[] colors = null;
+        new LinearGradient(0.5f, 0, 1.5f, 0, colors, null, TileMode.CLAMP);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testNullColorLongs() {
+        long[] colors = null;
+        new LinearGradient(0.5f, 0, 1.5f, 0, colors, null, TileMode.CLAMP);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testNoColorInts() {
+        new LinearGradient(0.5f, 0, 1.5f, 0, new int[0], null, TileMode.CLAMP);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testNoColorLongs() {
+        new LinearGradient(0.5f, 0, 1.5f, 0, new long[0], null, TileMode.CLAMP);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testOneColorInts() {
+        new LinearGradient(0.5f, 0, 1.5f, 0, new int[1], null, TileMode.CLAMP);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testOneColorLongs() {
+        new LinearGradient(0.5f, 0, 1.5f, 0, new long[1], null, TileMode.CLAMP);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testMismatchColorLongs() {
+        long[] colors = new long[2];
+        colors[0] = Color.pack(Color.BLUE);
+        colors[1] = Color.pack(.5f, .5f, .5f, 1.0f, ColorSpace.get(ColorSpace.Named.DISPLAY_P3));
+        new LinearGradient(0.5f, 0, 1.5f, 0, colors, null, TileMode.CLAMP);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testMismatchColorLongs2() {
+        long color0 = Color.pack(Color.BLUE);
+        long color1 = Color.pack(.5f, .5f, .5f, 1.0f, ColorSpace.get(ColorSpace.Named.DISPLAY_P3));
+        new LinearGradient(0.5f, 0, 1.5f, 0, color0, color1, TileMode.CLAMP);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testMismatchPositionsInts() {
+        new LinearGradient(0.5f, 0, 1.5f, 0, new int[2], new float[3], TileMode.CLAMP);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testMismatchPositionsLongs() {
+        new LinearGradient(0.5f, 0, 1.5f, 0, new long[2], new float[3], TileMode.CLAMP);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testInvalidColorLongs() {
+        long[] colors = new long[2];
+        colors[0] = -1L;
+        colors[0] = -2L;
+        new LinearGradient(0.5f, 0, 1.5f, 0, colors, null, TileMode.CLAMP);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testInvalidColorLong() {
+        new LinearGradient(0.5f, 0, 1.5f, 0, -1L, Color.pack(Color.RED), TileMode.CLAMP);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testInvalidColorLong2() {
+        new LinearGradient(0.5f, 0, 1.5f, 0, Color.pack(Color.RED), -1L, TileMode.CLAMP);
+    }
 }
diff --git a/tests/tests/graphics/src/android/graphics/cts/RadialGradientTest.java b/tests/tests/graphics/src/android/graphics/cts/RadialGradientTest.java
index d133bb9..c53e938 100644
--- a/tests/tests/graphics/src/android/graphics/cts/RadialGradientTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/RadialGradientTest.java
@@ -16,12 +16,16 @@
 
 package android.graphics.cts;
 
+import static org.junit.Assert.assertTrue;
+
 import android.graphics.Bitmap;
 import android.graphics.Bitmap.Config;
 import android.graphics.Canvas;
 import android.graphics.Color;
+import android.graphics.ColorSpace;
 import android.graphics.Matrix;
 import android.graphics.Paint;
+import android.graphics.Point;
 import android.graphics.RadialGradient;
 import android.graphics.Shader.TileMode;
 import android.support.test.filters.SmallTest;
@@ -32,6 +36,8 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.function.Function;
+
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class RadialGradientTest {
@@ -57,4 +63,171 @@
         ColorUtils.verifyColor(Color.BLACK, bitmap.getPixel(1, 0), 1);
         ColorUtils.verifyColor(Color.BLACK, bitmap.getPixel(2, 0), 1);
     }
+
+    @Test
+    public void testColorLong() {
+        ColorSpace p3 = ColorSpace.get(ColorSpace.Named.DISPLAY_P3);
+        long red = Color.pack(1, 0, 0, 1, p3);
+        long blue = Color.pack(0, 0, 1, 1, p3);
+        RadialGradient gradient = new RadialGradient(50, 50, 25, red, blue, TileMode.CLAMP);
+
+        Bitmap bitmap = Bitmap.createBitmap(100, 100, Config.RGBA_F16);
+        bitmap.eraseColor(Color.TRANSPARENT);
+        Canvas canvas = new Canvas(bitmap);
+
+        Paint paint = new Paint();
+        paint.setShader(gradient);
+        canvas.drawPaint(paint);
+
+        final ColorSpace bitmapColorSpace = bitmap.getColorSpace();
+        Function<Long, Color> convert = (l) -> {
+            return Color.valueOf(Color.convert(l, bitmapColorSpace));
+        };
+
+        final Color centerColor = bitmap.getColor(50, 50);
+        ColorUtils.verifyColor("Center color should be red!", convert.apply(red),
+                centerColor, 0.034f);
+        Color blueColor = convert.apply(blue);
+        for (Point p : new Point[] { new Point(0, 0), new Point(50, 0), new Point(99, 0),
+                new Point(0, 50), new Point(0, 99), new Point(99, 0), new Point(99, 50),
+                new Point(99, 99) }) {
+            ColorUtils.verifyColor("Edge point " + p + " should be blue", blueColor,
+                    bitmap.getColor(p.x, p.y), .001f);
+        }
+
+        final double[] negativeOneAndOne = new double[] { -1, 1 };
+        Color lastColor = centerColor;
+        Point lastPoint = new Point(0, 0);
+        // On several different radii, verify that colors trend from red to blue.
+        for (double radius = 4; radius < 25; radius += 4) {
+            // These correspond to the first point we check at a given radius.
+            Color currentColor = null;
+            Point currentPoint = null;
+            for (double angle = 0; angle <= Math.PI / 2.0; angle += Math.PI / 8.0) {
+                double dx = Math.cos(angle) * radius;
+                double dy = Math.sin(angle) * radius;
+                for (double nx : negativeOneAndOne) {
+                    for (double ny : negativeOneAndOne) {
+                        int x = 50 + (int) (nx * dx);
+                        int y = 50 + (int) (ny * dy);
+                        Color c = bitmap.getColor(x, y);
+                        if (currentColor == null) {
+                            currentColor = c;
+                            currentPoint = new Point(x, y);
+                            assertTrue("Outer " + currentPoint + " (" + currentColor
+                                    + ") should be less red than inner " + lastPoint
+                                    + " (" + lastColor + ")", currentColor.red() < lastColor.red());
+                            assertTrue("Outer " + currentPoint + " (" + currentColor
+                                    + ") should be more blue than inner " + lastPoint
+                                    + " (" + lastColor + ")",
+                                    currentColor.blue() > lastColor.blue());
+                        } else {
+                            ColorUtils.verifyColor("Point(" + x + ", " + y + ") should match "
+                                    + currentPoint, currentColor, c, .08f);
+                        }
+                    }
+                }
+            }
+
+            lastColor = currentColor;
+            lastPoint = currentPoint;
+        }
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testNullColorInts() {
+        int[] colors = null;
+        new RadialGradient(0.5f, 0.5f, 1, colors, null, TileMode.CLAMP);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testNullColorLongs() {
+        long[] colors = null;
+        new RadialGradient(0.5f, 0.5f, 1, colors, null, TileMode.CLAMP);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testNoColorInts() {
+        new RadialGradient(0.5f, 0.5f, 1, new int[0], null, TileMode.CLAMP);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testNoColorLongs() {
+        new RadialGradient(0.5f, 0.5f, 1, new long[0], null, TileMode.CLAMP);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testOneColorInts() {
+        new RadialGradient(0.5f, 0.5f, 1, new int[1], null, TileMode.CLAMP);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testOneColorLongs() {
+        new RadialGradient(0.5f, 0.5f, 1, new long[1], null, TileMode.CLAMP);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testMismatchColorLongs() {
+        long[] colors = new long[2];
+        colors[0] = Color.pack(Color.BLUE);
+        colors[1] = Color.pack(.5f, .5f, .5f, 1.0f, ColorSpace.get(ColorSpace.Named.DISPLAY_P3));
+        new RadialGradient(0.5f, 0.5f, 1, colors, null, TileMode.CLAMP);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testMismatchColorLongs2() {
+        long color0 = Color.pack(Color.BLUE);
+        long color1 = Color.pack(.5f, .5f, .5f, 1.0f, ColorSpace.get(ColorSpace.Named.DISPLAY_P3));
+        new RadialGradient(0.5f, 0.5f, 1, color0, color1, TileMode.CLAMP);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testMismatchPositionsInts() {
+        new RadialGradient(0.5f, 0.5f, 1, new int[2], new float[3], TileMode.CLAMP);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testMismatchPositionsLongs() {
+        new RadialGradient(0.5f, 0.5f, 1, new long[2], new float[3], TileMode.CLAMP);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testInvalidColorLongs() {
+        long[] colors = new long[2];
+        colors[0] = -1L;
+        colors[0] = -2L;
+        new RadialGradient(0.5f, 0.5f, 1, colors, null, TileMode.CLAMP);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testInvalidColorLong() {
+        new RadialGradient(0.5f, 0.5f, 1, -1L, Color.pack(Color.RED), TileMode.CLAMP);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testInvalidColorLong2() {
+        new RadialGradient(0.5f, 0.5f, 1, Color.pack(Color.RED), -1L, TileMode.CLAMP);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testZeroRadius() {
+        new RadialGradient(0.5f, 0.5f, 0, Color.RED, Color.BLUE, TileMode.CLAMP);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testZeroRadiusArray() {
+        new RadialGradient(0.5f, 0.5f, 0, new int[] {Color.RED, Color.BLUE}, null, TileMode.CLAMP);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testZeroRadiusLong() {
+        new RadialGradient(0.5f, 0.5f, 0, Color.pack(Color.RED), Color.pack(Color.BLUE),
+                TileMode.CLAMP);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testZeroRadiusLongArray() {
+        new RadialGradient(0.5f, 0.5f, 0, new long[]{Color.pack(Color.RED), Color.pack(Color.BLUE)},
+                null, TileMode.CLAMP);
+    }
 }
diff --git a/tests/tests/graphics/src/android/graphics/cts/SweepGradientTest.java b/tests/tests/graphics/src/android/graphics/cts/SweepGradientTest.java
index cb7ec0a..2a67b97 100644
--- a/tests/tests/graphics/src/android/graphics/cts/SweepGradientTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/SweepGradientTest.java
@@ -17,11 +17,13 @@
 package android.graphics.cts;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 import android.graphics.Bitmap;
 import android.graphics.Bitmap.Config;
 import android.graphics.Canvas;
 import android.graphics.Color;
+import android.graphics.ColorSpace;
 import android.graphics.Matrix;
 import android.graphics.Paint;
 import android.graphics.Rect;
@@ -37,6 +39,8 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.function.Function;
+
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class SweepGradientTest {
@@ -166,4 +170,149 @@
         ColorUtils.verifyColor(Color.BLACK, bitmap.getPixel(0, 0), 1);
         ColorUtils.verifyColor(Color.BLACK, bitmap.getPixel(1, 0), 1);
     }
+
+    @Test(expected = NullPointerException.class)
+    public void testNullColorInts() {
+        int[] colors = null;
+        new SweepGradient(1, 0.5f, colors, null);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testNullColorLongs() {
+        long[] colors = null;
+        new SweepGradient(1, 0.5f, colors, null);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testNoColorInts() {
+        new SweepGradient(1, 0.5f, new int[0], null);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testNoColorLongs() {
+        new SweepGradient(1, 0.5f, new long[0], null);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testOneColorInts() {
+        new SweepGradient(1, 0.5f, new int[1], null);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testOneColorLongs() {
+        new SweepGradient(1, 0.5f, new long[1], null);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testMismatchColorLongs() {
+        long[] colors = new long[2];
+        colors[0] = Color.pack(Color.BLUE);
+        colors[1] = Color.pack(.5f, .5f, .5f, 1.0f, ColorSpace.get(ColorSpace.Named.DISPLAY_P3));
+        new SweepGradient(1, 0.5f, colors, null);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testMismatchColorLongs2() {
+        long color0 = Color.pack(Color.BLUE);
+        long color1 = Color.pack(.5f, .5f, .5f, 1.0f, ColorSpace.get(ColorSpace.Named.DISPLAY_P3));
+        new SweepGradient(1, 0.5f, color0, color1);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testMismatchPositionsInts() {
+        new SweepGradient(1, 0.5f, new int[2], new float[3]);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testMismatchPositionsLongs() {
+        new SweepGradient(1, 0.5f, new long[2], new float[3]);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testInvalidColorLongs() {
+        long[] colors = new long[2];
+        colors[0] = -1L;
+        colors[0] = -2L;
+        new SweepGradient(1, 0.5f, colors, null);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testInvalidColorLong() {
+        new SweepGradient(1, 0.5f, -1L, Color.pack(Color.RED));
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testInvalidColorLong2() {
+        new SweepGradient(1, 0.5f, Color.pack(Color.RED), -1L);
+    }
+
+    private String toString(double angle) {
+        double factor = angle * Math.PI;
+        return String.format("%.2f", angle) + "(pi)";
+    }
+
+    @Test
+    public void testColorLong() {
+        ColorSpace p3 = ColorSpace.get(ColorSpace.Named.DISPLAY_P3);
+        long red = Color.pack(1, 0, 0, 1, p3);
+        long blue = Color.pack(0, 0, 1, 1, p3);
+        SweepGradient gradient = new SweepGradient(50, 50, red, blue);
+
+        Bitmap bitmap = Bitmap.createBitmap(100, 100, Config.RGBA_F16);
+        bitmap.eraseColor(Color.TRANSPARENT);
+        Canvas canvas = new Canvas(bitmap);
+
+        Paint paint = new Paint();
+        paint.setShader(gradient);
+        canvas.drawPaint(paint);
+
+        final ColorSpace bitmapColorSpace = bitmap.getColorSpace();
+        Function<Long, Color> convert = (l) -> {
+            return Color.valueOf(Color.convert(l, bitmapColorSpace));
+        };
+
+        Color lastColor = null;
+        double lastAngle = 0;
+        for (double angle = Math.PI / 8.0; angle < Math.PI * 2.0; angle += Math.PI / 8.0) {
+            // currentColor is the Color at this angle.
+            Color currentColor = null;
+            double lastRadius = 0;
+            for (double radius = 4; radius < 25; radius += 4) {
+                double dx = Math.cos(angle) * radius;
+                double dy = Math.sin(angle) * radius;
+                int x = 50 + (int) (dx);
+                int y = 50 + (int) (dy);
+                Color c = bitmap.getColor(x, y);
+                if (currentColor == null) {
+                    // Checking the first radius at this angle.
+                    currentColor = c;
+                    if (lastColor == null) {
+                        // This should be pretty close to the initial color.
+                        ColorUtils.verifyColor("First color (at angle " + toString(angle)
+                                + " and radius " + radius  + " should be mostly red",
+                                convert.apply(red), c, .08f);
+                        lastColor = currentColor;
+                        lastAngle = angle;
+                    } else {
+                        assertTrue("Angle " + toString(angle)
+                                + " should be less red than prior angle "
+                                + toString(lastAngle), c.red() < lastColor.red());
+                        assertTrue("Angle " + toString(angle)
+                                + " should be more blue than prior angle "
+                                + toString(lastAngle), c.blue() > lastColor.blue());
+                    }
+                } else {
+                    // Already have a Color at this angle. This one should match.
+                    ColorUtils.verifyColor("Radius " + radius + " at angle " + toString(angle)
+                            + " should match same angle with radius " + lastRadius, currentColor,
+                            c, .05f);
+                }
+                lastRadius = radius;
+            }
+
+            lastColor = currentColor;
+            lastAngle = angle;
+        }
+    }
+
 }
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableTest.java
index 4fd64b8..891647d 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableTest.java
@@ -58,6 +58,7 @@
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
+import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
@@ -158,6 +159,47 @@
         assertTrue(imageFile.delete());
     }
 
+    @Test
+    public void testCreateFromIncomplete() throws IOException {
+        // Create a truncated image file.
+        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
+        byte[] buffer = new byte[1024];
+        try (InputStream source = mResources.openRawResource(R.raw.testimage)) {
+            for (int len = source.read(buffer); len >= 0; len = source.read(buffer)) {
+                bytes.write(buffer, 0, len);
+            }
+        }
+
+        File imageFile = new File(mContext.getFilesDir(), "tempimage.jpg");
+        assertTrue(imageFile.createNewFile());
+        assertTrue(imageFile.exists());
+        try (OutputStream target = new FileOutputStream(imageFile)) {
+            byte[] byteArray = bytes.toByteArray();
+            target.write(byteArray, 0, byteArray.length / 2);
+        }
+
+        // Now test various Drawable APIs that should succeed.
+        final String path = imageFile.getPath();
+        Uri u = Uri.parse(path);
+        assertNotNull(Drawable.createFromPath(u.toString()));
+
+        try (FileInputStream input = new FileInputStream(imageFile)) {
+            assertNotNull(Drawable.createFromStream(input, ""));
+        }
+
+        try (FileInputStream input = new FileInputStream(imageFile)) {
+            assertNotNull(Drawable.createFromResourceStream(mResources, new TypedValue(),
+                        input, ""));
+        }
+
+        try (FileInputStream input = new FileInputStream(imageFile)) {
+            assertNotNull(Drawable.createFromResourceStream(mResources, new TypedValue(),
+                        input, "", new BitmapFactory.Options()));
+        }
+
+        assertTrue(imageFile.delete());
+    }
+
     private void writeSampleImage(File imagefile) throws IOException {
         try (InputStream source = mResources.openRawResource(R.raw.testimage);
              OutputStream target = new FileOutputStream(imagefile)) {
diff --git a/tests/tests/hardware/src/android/hardware/fingerprint/cts/FingerprintFeatureCompatTest.java b/tests/tests/hardware/src/android/hardware/fingerprint/cts/FingerprintFeatureCompatTest.java
deleted file mode 100644
index ecd5a02..0000000
--- a/tests/tests/hardware/src/android/hardware/fingerprint/cts/FingerprintFeatureCompatTest.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2018 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.hardware.fingerprint.cts;
-
-import android.content.pm.PackageManager;
-import android.platform.test.annotations.Presubmit;
-import android.test.AndroidTestCase;
-
-public class FingerprintFeatureCompatTest extends AndroidTestCase {
-
-    @Presubmit
-    public void test_bothFeaturesDeclared() {
-        /**
-         * Android biometric features are now all under the "android.hardware.biometrics" namespace.
-         * For backwards compatibility, both {@link PackageManager.FEATURE_FINGERPRINT} and
-         * {@link android.content.pm.PackageManager.FEATURE_FINGERPRINT_PRE_29} must be declared
-         * by any device supporting fingerprint.
-         */
-        final PackageManager pm = getContext().getPackageManager();
-        final boolean hasNewFeature = pm.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT);
-        final boolean hasOldFeature =
-                pm.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT_PRE_29);
-
-        if (hasNewFeature || hasOldFeature) {
-            assertTrue(hasNewFeature && hasOldFeature);
-        }
-    }
-}
diff --git a/tests/tests/jni/AndroidTest.xml b/tests/tests/jni/AndroidTest.xml
index e4ab2dd..1c2d529 100644
--- a/tests/tests/jni/AndroidTest.xml
+++ b/tests/tests/jni/AndroidTest.xml
@@ -16,6 +16,8 @@
 <configuration description="Config for CTS JNI test cases">
     <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="art" />
+    <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
         <option name="test-file-name" value="CtsJniTestCases.apk" />
diff --git a/tests/tests/jni/libjnitest/android_jni_cts_LinkerNamespacesTest.cpp b/tests/tests/jni/libjnitest/android_jni_cts_LinkerNamespacesTest.cpp
index 643fd75..c00ae3b 100644
--- a/tests/tests/jni/libjnitest/android_jni_cts_LinkerNamespacesTest.cpp
+++ b/tests/tests/jni/libjnitest/android_jni_cts_LinkerNamespacesTest.cpp
@@ -185,6 +185,15 @@
   return true;
 }
 
+static bool is_bootstrap_bionic(const std::string& dir, const std::string& name) {
+  if (dir == kSystemLibraryPath + "/bootstrap") {
+    if (name == "libc.so" || name == "libdl.so" || name == "libm.so") {
+      return true;
+    }
+  }
+  return false;
+}
+
 static bool check_path(JNIEnv* env,
                        jclass clazz,
                        const std::string& library_path,
@@ -211,6 +220,11 @@
       if (strcmp(".", dp->d_name) == 0 || strcmp("..", dp->d_name) == 0) {
         continue;
       }
+      // TODO(b/123183824) remove this by disallowing bootstrap Bionic to
+      // app processes
+      if (is_bootstrap_bionic(dir, dp->d_name)) {
+        continue;
+      }
 
       std::string path = dir + "/" + dp->d_name;
       if (is_directory(path.c_str())) {
diff --git a/tests/tests/jvmti/attaching/AndroidTest.xml b/tests/tests/jvmti/attaching/AndroidTest.xml
index 0e927a3..8948004 100644
--- a/tests/tests/jvmti/attaching/AndroidTest.xml
+++ b/tests/tests/jvmti/attaching/AndroidTest.xml
@@ -18,6 +18,9 @@
 
 <configuration description="Config for CTS jvmti attaching test cases">
     <option name="test-suite-tag" value="cts" />
+    <!-- Requires debuggable -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/tests/tests/jvmti/attaching/TEST_MAPPING b/tests/tests/jvmti/attaching/TEST_MAPPING
new file mode 100644
index 0000000..ea21aa4
--- /dev/null
+++ b/tests/tests/jvmti/attaching/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+      "name": "CtsJvmtiAttachingTestCases"
+    }
+  ]
+}
diff --git a/tests/tests/location/src/android/location/cts/GnssMeasurementTest.java b/tests/tests/location/src/android/location/cts/GnssMeasurementTest.java
index c7d28c9..437948f 100644
--- a/tests/tests/location/src/android/location/cts/GnssMeasurementTest.java
+++ b/tests/tests/location/src/android/location/cts/GnssMeasurementTest.java
@@ -40,6 +40,7 @@
         measurement.setCarrierPhase(6.0);
         measurement.setCarrierPhaseUncertainty(7.0);
         measurement.setCn0DbHz(8.0);
+        measurement.setCodeType(GnssMeasurement.CODE_TYPE_C);
         measurement.setConstellationType(GnssStatus.CONSTELLATION_GALILEO);
         measurement.setMultipathIndicator(GnssMeasurement.MULTIPATH_INDICATOR_DETECTED);
         measurement.setPseudorangeRateMetersPerSecond(9.0);
@@ -64,6 +65,7 @@
         assertEquals(GnssStatus.CONSTELLATION_GALILEO, measurement.getConstellationType());
         assertEquals(GnssMeasurement.MULTIPATH_INDICATOR_DETECTED,
                 measurement.getMultipathIndicator());
+        assertEquals(GnssMeasurement.CODE_TYPE_C, measurement.getCodeType());
         assertEquals(9.0, measurement.getPseudorangeRateMetersPerSecond());
         assertEquals(10.0, measurement.getPseudorangeRateUncertaintyMetersPerSecond());
         assertEquals(11, measurement.getReceivedSvTimeNanos());
diff --git a/tests/tests/location/src/android/location/cts/GnssTestCase.java b/tests/tests/location/src/android/location/cts/GnssTestCase.java
index a128c95..62c38c8 100644
--- a/tests/tests/location/src/android/location/cts/GnssTestCase.java
+++ b/tests/tests/location/src/android/location/cts/GnssTestCase.java
@@ -19,6 +19,7 @@
 import android.os.SystemProperties;
 import android.test.AndroidTestCase;
 import android.util.Log;
+import android.content.pm.PackageManager;
 
 /**
  * Base Test Case class for all Gnss Tests.
@@ -37,7 +38,8 @@
     // On devices using newer hardware, GNSS measurement support is required.
     protected boolean isMeasurementTestStrict() {
         // Enforce strict measurement test on devices with first API level at least P.
-        if (SystemProperties.getInt("ro.product.first_api_level", 0) >= Build.VERSION_CODES.P) {
+        if (SystemProperties.getInt("ro.product.first_api_level", 0) >= Build.VERSION_CODES.P &&
+            !getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH)) {
             return true;
         }
 
diff --git a/tests/tests/media/Android.mk b/tests/tests/media/Android.mk
index dc77eed..11d687d 100644
--- a/tests/tests/media/Android.mk
+++ b/tests/tests/media/Android.mk
@@ -85,8 +85,7 @@
 LOCAL_JAVA_LIBRARIES += \
     org.apache.http.legacy \
     android.test.base.stubs \
-    android.test.runner.stubs \
-    updatable-media # TODO(b/112766913): replace with stub to prevent private API use.
+    android.test.runner.stubs
 
 # Tag this module as a cts test artifact
 LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
diff --git a/tests/tests/media/res/raw/lg_g4_iso_800.jpg b/tests/tests/media/res/raw/lg_g4_iso_800.jpg
new file mode 100644
index 0000000..d264196
--- /dev/null
+++ b/tests/tests/media/res/raw/lg_g4_iso_800.jpg
Binary files differ
diff --git a/tests/tests/media/res/values/exifinterface.xml b/tests/tests/media/res/values/exifinterface.xml
index 3ab9364..f4f648d 100644
--- a/tests/tests/media/res/values/exifinterface.xml
+++ b/tests/tests/media/res/values/exifinterface.xml
@@ -17,7 +17,7 @@
 <resources>
     <array name="exifbyteorderii_jpg">
         <item>true</item>
-        <item>3500</item>
+        <item>3112</item>
         <item>6265</item>
         <item>512</item>
         <item>288</item>
@@ -49,6 +49,9 @@
         <item>50</item>
         <item>6</item>
         <item>0</item>
+        <item>false</item>
+        <item />
+        <item />
     </array>
     <array name="exifbyteordermm_jpg">
         <item>false</item>
@@ -58,7 +61,7 @@
         <item>0</item>
         <item>false</item>
         <item>true</item>
-        <item>572</item>
+        <item>675</item>
         <item>24</item>
         <item>0.0</item>
         <item>0.0</item>
@@ -84,6 +87,9 @@
         <item>146</item>
         <item>0</item>
         <item>0</item>
+        <item>false</item>
+        <item />
+        <item />
     </array>
     <array name="lg_g4_iso_800_dng">
         <item>true</item>
@@ -119,16 +125,57 @@
         <item>800</item>
         <item>1</item>
         <item>0</item>
+        <item>true</item>
+        <item>826</item>
+        <item>10067</item>
+    </array>
+    <array name="lg_g4_iso_800_jpg">
+        <item>false</item>
+        <item />
+        <item />
+        <item />
+        <item />
+        <item />
+        <item>true</item>
+        <item>1662</item>
+        <item>24</item>
+        <item>53.834507</item>
+        <item>10.69585</item>
+        <item>0.0</item>
+        <item>LGE</item>
+        <item>LG-H815</item>
+        <item>1.800</item>
+        <item>2015:11:12 16:46:18</item>
+        <item>0.0040</item>
+        <item>0.0</item>
+        <item>442/100</item>
+        <item />
+        <item />
+        <item>1970:01:17</item>
+        <item>53/1,50/1,423/100</item>
+        <item>N</item>
+        <item>10/1,41/1,4506/100</item>
+        <item>E</item>
+        <item />
+        <item>18:08:10</item>
+        <item>337</item>
+        <item>600</item>
+        <item>800</item>
+        <item>1</item>
+        <item>0</item>
+        <item>true</item>
+        <item>1809</item>
+        <item>13197</item>
     </array>
     <array name="volantis_jpg">
         <item>false</item>
         <item />
         <item />
-        <item>0</item>
-        <item>0</item>
-        <item>false</item>
+        <item />
+        <item />
+        <item />
         <item>true</item>
-        <item>3143</item>
+        <item>3081</item>
         <item>24</item>
         <item>37.423</item>
         <item>-122.162</item>
@@ -154,6 +201,9 @@
         <item>175</item>
         <item>1</item>
         <item>0</item>
+        <item>false</item>
+        <item />
+        <item />
     </array>
     <array name="sony_rx_100_arw">
         <item>true</item>
@@ -189,6 +239,9 @@
         <item>125</item>
         <item>8</item>
         <item>0</item>
+        <item>false</item>
+        <item />
+        <item />
     </array>
     <array name="canon_g7x_cr2">
         <item>true</item>
@@ -224,6 +277,9 @@
         <item>12800</item>
         <item>8</item>
         <item>1</item>
+        <item>true</item>
+        <item>14336</item>
+        <item>8192</item>
     </array>
     <array name="fuji_x20_raf">
         <item>true</item>
@@ -259,6 +315,9 @@
         <item>100</item>
         <item>1</item>
         <item>0</item>
+        <item>false</item>
+        <item />
+        <item />
     </array>
     <array name="nikon_1aw1_nef">
         <item>true</item>
@@ -294,6 +353,9 @@
         <item>200</item>
         <item>8</item>
         <item>0</item>
+        <item>true</item>
+        <item>472</item>
+        <item>2048</item>
     </array>
     <array name="nikon_p330_nrw">
         <item>true</item>
@@ -329,6 +391,9 @@
         <item>3200</item>
         <item>8</item>
         <item>0</item>
+        <item>false</item>
+        <item />
+        <item />
     </array>
     <array name="pentax_k5_pef">
         <item>true</item>
@@ -364,6 +429,9 @@
         <item>100</item>
         <item>1</item>
         <item>0</item>
+        <item>false</item>
+        <item />
+        <item />
     </array>
     <array name="olympus_e_pl3_orf">
         <item>true</item>
@@ -399,6 +467,9 @@
         <item>200</item>
         <item>1</item>
         <item>0</item>
+        <item>false</item>
+        <item />
+        <item />
     </array>
     <array name="panasonic_gm5_rw2">
         <item>true</item>
@@ -434,6 +505,9 @@
         <item>200</item>
         <item>8</item>
         <item>1</item>
+        <item>false</item>
+        <item />
+        <item />
     </array>
     <array name="samsung_nx3000_srw">
         <item>true</item>
@@ -469,5 +543,8 @@
         <item>100</item>
         <item>8</item>
         <item>0</item>
+        <item>false</item>
+        <item />
+        <item />
     </array>
 </resources>
diff --git a/tests/tests/media/src/android/media/cts/AudioSystemTest.java b/tests/tests/media/src/android/media/cts/AudioSystemTest.java
new file mode 100644
index 0000000..7aa915a
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/AudioSystemTest.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2019 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.media.cts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.media.AudioSystem;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Ensures proper support of internal @TestApi functionality for AudioSystem.
+ * This is a framework consistency test of important internal APIs.
+ * Java applications should use the client facing AudioManager APIs for Audio management.
+ */
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class AudioSystemTest {
+
+    /**
+     * Tests AudioSystem.setMasterBalance and AudioSystem.getMasterBalance
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testBalance() throws Exception {
+        final float DELTA = 0.f; // float values must be exact
+
+        // original balance must be valid
+        final float originalBalance = AudioSystem.getMasterBalance();
+        assertTrue("original balance must be within -1.f to 1.f " + originalBalance,
+                originalBalance <= 1.f && originalBalance >= -1.f);
+
+        try {
+            // can we set with valid values?
+            final float[] GOOD_BALANCE_VALUES = {-1.f, -0.5f, 0.f, 0.5f, 1.f};
+            for (final float b : GOOD_BALANCE_VALUES) {
+                assertEquals("set must return NO_ERROR", 0, AudioSystem.setMasterBalance(b));
+                assertEquals("get must return set value " + b,
+                        b, AudioSystem.getMasterBalance(), DELTA);
+            }
+
+            // can we restore?
+            AudioSystem.setMasterBalance(originalBalance);
+            assertEquals("get must return set value",
+                    originalBalance, AudioSystem.getMasterBalance(), DELTA);
+
+            // do we reject invalid values?
+            final float[] BAD_BALANCE_VALUES = {-2.f, 2.f, // out of bounds
+                    Float.POSITIVE_INFINITY, Float.NaN, Float.NEGATIVE_INFINITY, // special values
+            };
+            for (final float b : BAD_BALANCE_VALUES) {
+                assertTrue("set returns error on invalid value",
+                        0 != AudioSystem.setMasterBalance(b));
+                assertEquals("get reads old value on invalid set",
+                        originalBalance, AudioSystem.getMasterBalance(), DELTA);
+            }
+            // we are at original balance here.
+
+        } finally {
+            // always attempt to restore original balance if we got it successfully.
+            AudioSystem.setMasterBalance(originalBalance);
+        }
+    }
+}
diff --git a/tests/tests/media/src/android/media/cts/EncoderTest.java b/tests/tests/media/src/android/media/cts/EncoderTest.java
index 7f08662..2319113 100644
--- a/tests/tests/media/src/android/media/cts/EncoderTest.java
+++ b/tests/tests/media/src/android/media/cts/EncoderTest.java
@@ -107,6 +107,24 @@
         testEncoderWithFormats(MediaFormat.MIMETYPE_AUDIO_AMR_WB, formats);
     }
 
+    public void testOpusEncoders() {
+        LinkedList<MediaFormat> formats = new LinkedList<MediaFormat>();
+
+        final int kBitRates[] =
+            { 6600, 8850, 12650, 14250, 15850, 18250, 19850, 23050, 23850 };
+
+        for (int j = 0; j < kBitRates.length; ++j) {
+            MediaFormat format  = new MediaFormat();
+            format.setString(MediaFormat.KEY_MIME, MediaFormat.MIMETYPE_AUDIO_OPUS);
+            format.setInteger(MediaFormat.KEY_SAMPLE_RATE, 16000);
+            format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
+            format.setInteger(MediaFormat.KEY_BIT_RATE, kBitRates[j]);
+            formats.push(format);
+        }
+
+        testEncoderWithFormats(MediaFormat.MIMETYPE_AUDIO_OPUS, formats);
+    }
+
     public void testAACEncoders() {
         LinkedList<MediaFormat> formats = new LinkedList<MediaFormat>();
 
diff --git a/tests/tests/media/src/android/media/cts/ExifInterfaceTest.java b/tests/tests/media/src/android/media/cts/ExifInterfaceTest.java
index 39bb458..5bcfaa7 100644
--- a/tests/tests/media/src/android/media/cts/ExifInterfaceTest.java
+++ b/tests/tests/media/src/android/media/cts/ExifInterfaceTest.java
@@ -18,16 +18,17 @@
 
 import android.content.res.TypedArray;
 import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
 import android.media.ExifInterface;
 import android.os.Environment;
 import android.os.FileUtils;
 import android.platform.test.annotations.AppModeFull;
-import android.test.AndroidTestCase;
-import android.util.Log;
 import android.system.ErrnoException;
 import android.system.Os;
 import android.system.OsConstants;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+import libcore.io.IoUtils;
 
 import java.io.BufferedInputStream;
 import java.io.ByteArrayInputStream;
@@ -35,14 +36,10 @@
 import java.io.FileDescriptor;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
-import java.io.FileNotFoundException;
-import java.io.InputStream;
 import java.io.IOException;
-import java.lang.reflect.Type;
-import java.util.Arrays;
-
-import libcore.io.IoUtils;
-import libcore.io.Streams;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.charset.StandardCharsets;
 
 @AppModeFull(reason = "Instant apps cannot access the SD card")
 public class ExifInterfaceTest extends AndroidTestCase {
@@ -59,6 +56,7 @@
     private static final String EXIF_BYTE_ORDER_II_JPEG = "image_exif_byte_order_ii.jpg";
     private static final String EXIF_BYTE_ORDER_MM_JPEG = "image_exif_byte_order_mm.jpg";
     private static final String LG_G4_ISO_800_DNG = "lg_g4_iso_800.dng";
+    private static final String LG_G4_ISO_800_JPG = "lg_g4_iso_800.jpg";
     private static final String SONY_RX_100_ARW = "sony_rx_100.arw";
     private static final String CANON_G7X_CR2 = "canon_g7x.cr2";
     private static final String FUJI_X20_RAF = "fuji_x20.raf";
@@ -134,6 +132,11 @@
         public final int orientation;
         public final int whiteBalance;
 
+        // XMP information.
+        public final boolean hasXmp;
+        public final int xmpOffset;
+        public final int xmpLength;
+
         private static String getString(TypedArray typedArray, int index) {
             String stringValue = typedArray.getString(index);
             if (stringValue == null || stringValue.equals("")) {
@@ -184,6 +187,11 @@
             orientation = typedArray.getInt(index++, 0);
             whiteBalance = typedArray.getInt(index++, 0);
 
+            // Reads XMP information.
+            hasXmp = typedArray.getBoolean(index++, false);
+            xmpOffset = typedArray.getInt(index++, 0);
+            xmpLength = typedArray.getInt(index++, 0);
+
             typedArray.recycle();
         }
     }
@@ -253,16 +261,19 @@
     }
 
     private void compareWithExpectedValue(ExifInterface exifInterface,
-            ExpectedValue expectedValue, String verboseTag) {
+            ExpectedValue expectedValue, String verboseTag, boolean assertRanges) {
         if (VERBOSE) {
             printExifTagsAndValues(verboseTag, exifInterface);
         }
         // Checks a thumbnail image.
         assertEquals(expectedValue.hasThumbnail, exifInterface.hasThumbnail());
         if (expectedValue.hasThumbnail) {
-            final long[] thumbnailRange = exifInterface.getThumbnailRange();
-            assertEquals(expectedValue.thumbnailOffset, thumbnailRange[0]);
-            assertEquals(expectedValue.thumbnailLength, thumbnailRange[1]);
+            assertNotNull(exifInterface.getThumbnailRange());
+            if (assertRanges) {
+                final long[] thumbnailRange = exifInterface.getThumbnailRange();
+                assertEquals(expectedValue.thumbnailOffset, thumbnailRange[0]);
+                assertEquals(expectedValue.thumbnailLength, thumbnailRange[1]);
+            }
             byte[] thumbnailBytes = exifInterface.getThumbnailBytes();
             assertNotNull(thumbnailBytes);
             Bitmap thumbnailBitmap = exifInterface.getThumbnailBitmap();
@@ -272,6 +283,7 @@
             assertEquals(expectedValue.isThumbnailCompressed,
                     exifInterface.isThumbnailCompressed());
         } else {
+            assertNull(exifInterface.getThumbnailRange());
             assertNull(exifInterface.getThumbnail());
         }
 
@@ -279,15 +291,19 @@
         float[] latLong = new float[2];
         assertEquals(expectedValue.hasLatLong, exifInterface.getLatLong(latLong));
         if (expectedValue.hasLatLong) {
-            final long[] latitudeRange = exifInterface
-                    .getAttributeRange(ExifInterface.TAG_GPS_LATITUDE);
-            assertEquals(expectedValue.latitudeOffset, latitudeRange[0]);
-            assertEquals(expectedValue.latitudeLength, latitudeRange[1]);
+            assertNotNull(exifInterface.getAttributeRange(ExifInterface.TAG_GPS_LATITUDE));
+            if (assertRanges) {
+                final long[] latitudeRange = exifInterface
+                        .getAttributeRange(ExifInterface.TAG_GPS_LATITUDE);
+                assertEquals(expectedValue.latitudeOffset, latitudeRange[0]);
+                assertEquals(expectedValue.latitudeLength, latitudeRange[1]);
+            }
             assertEquals(expectedValue.latitude, latLong[0], DIFFERENCE_TOLERANCE);
             assertEquals(expectedValue.longitude, latLong[1], DIFFERENCE_TOLERANCE);
             assertTrue(exifInterface.hasAttribute(ExifInterface.TAG_GPS_LATITUDE));
             assertTrue(exifInterface.hasAttribute(ExifInterface.TAG_GPS_LONGITUDE));
         } else {
+            assertNull(exifInterface.getAttributeRange(ExifInterface.TAG_GPS_LATITUDE));
             assertFalse(exifInterface.hasAttribute(ExifInterface.TAG_GPS_LATITUDE));
             assertFalse(exifInterface.hasAttribute(ExifInterface.TAG_GPS_LONGITUDE));
         }
@@ -320,6 +336,26 @@
         assertStringTag(exifInterface, ExifInterface.TAG_ISO_SPEED_RATINGS, expectedValue.iso);
         assertIntTag(exifInterface, ExifInterface.TAG_ORIENTATION, expectedValue.orientation);
         assertIntTag(exifInterface, ExifInterface.TAG_WHITE_BALANCE, expectedValue.whiteBalance);
+
+        if (expectedValue.hasXmp) {
+            assertNotNull(exifInterface.getAttributeRange(ExifInterface.TAG_XMP));
+            if (assertRanges) {
+                final long[] xmpRange = exifInterface.getAttributeRange(ExifInterface.TAG_XMP);
+                assertEquals(expectedValue.xmpOffset, xmpRange[0]);
+                assertEquals(expectedValue.xmpLength, xmpRange[1]);
+            }
+            final String xmp = new String(exifInterface.getAttributeBytes(ExifInterface.TAG_XMP),
+                    StandardCharsets.UTF_8);
+            // We're only interested in confirming that we were able to extract
+            // valid XMP data, which must always include this XML tag; a full
+            // XMP parser is beyond the scope of ExifInterface. See XMP
+            // Specification Part 1, Section C.2.2 for additional details.
+            if (!xmp.contains("<rdf:RDF")) {
+                fail("Invalid XMP: " + xmp);
+            }
+        } else {
+            assertNull(exifInterface.getAttributeRange(ExifInterface.TAG_XMP));
+        }
     }
 
     private void testExifInterfaceCommon(String fileName, ExpectedValue expectedValue)
@@ -330,18 +366,18 @@
         // Creates via path.
         ExifInterface exifInterface = new ExifInterface(imageFile.getAbsolutePath());
         assertNotNull(exifInterface);
-        compareWithExpectedValue(exifInterface, expectedValue, verboseTag);
+        compareWithExpectedValue(exifInterface, expectedValue, verboseTag, true);
 
         // Creates via file.
         exifInterface = new ExifInterface(imageFile);
-        compareWithExpectedValue(exifInterface, expectedValue, verboseTag);
+        compareWithExpectedValue(exifInterface, expectedValue, verboseTag, true);
 
         InputStream in = null;
         // Creates via InputStream.
         try {
             in = new BufferedInputStream(new FileInputStream(imageFile.getAbsolutePath()));
             exifInterface = new ExifInterface(in);
-            compareWithExpectedValue(exifInterface, expectedValue, verboseTag);
+            compareWithExpectedValue(exifInterface, expectedValue, verboseTag, true);
         } finally {
             IoUtils.closeQuietly(in);
         }
@@ -351,7 +387,7 @@
         try {
             fd = Os.open(imageFile.getAbsolutePath(), OsConstants.O_RDONLY, 0600);
             exifInterface = new ExifInterface(fd);
-            compareWithExpectedValue(exifInterface, expectedValue, verboseTag);
+            compareWithExpectedValue(exifInterface, expectedValue, verboseTag, true);
         } catch (ErrnoException e) {
             throw e.rethrowAsIOException();
         } finally {
@@ -367,7 +403,7 @@
         ExifInterface exifInterface = new ExifInterface(imageFile.getAbsolutePath());
         exifInterface.saveAttributes();
         exifInterface = new ExifInterface(imageFile.getAbsolutePath());
-        compareWithExpectedValue(exifInterface, expectedValue, verboseTag);
+        compareWithExpectedValue(exifInterface, expectedValue, verboseTag, false);
 
         // Test for modifying one attribute.
         String backupValue = exifInterface.getAttribute(ExifInterface.TAG_MAKE);
@@ -379,7 +415,7 @@
         exifInterface.setAttribute(ExifInterface.TAG_MAKE, backupValue);
         exifInterface.saveAttributes();
         exifInterface = new ExifInterface(imageFile.getAbsolutePath());
-        compareWithExpectedValue(exifInterface, expectedValue, verboseTag);
+        compareWithExpectedValue(exifInterface, expectedValue, verboseTag, false);
     }
 
     private void testSaveAttributes_withFileDescriptor(String fileName, ExpectedValue expectedValue)
@@ -394,7 +430,7 @@
             exifInterface.saveAttributes();
             Os.lseek(fd, 0, OsConstants.SEEK_SET);
             exifInterface = new ExifInterface(fd);
-            compareWithExpectedValue(exifInterface, expectedValue, verboseTag);
+            compareWithExpectedValue(exifInterface, expectedValue, verboseTag, false);
 
             // Test for modifying one attribute.
             String backupValue = exifInterface.getAttribute(ExifInterface.TAG_MAKE);
@@ -408,7 +444,7 @@
             exifInterface.saveAttributes();
             Os.lseek(fd, 0, OsConstants.SEEK_SET);
             exifInterface = new ExifInterface(fd);
-            compareWithExpectedValue(exifInterface, expectedValue, verboseTag);
+            compareWithExpectedValue(exifInterface, expectedValue, verboseTag, false);
         } catch (ErrnoException e) {
             throw e.rethrowAsIOException();
         } finally {
@@ -455,6 +491,12 @@
         testExifInterfaceForRaw(LG_G4_ISO_800_DNG, R.array.lg_g4_iso_800_dng);
     }
 
+    public void testReadExifDataFromLgG4Iso800Jpg() throws Throwable {
+        stageFile(R.raw.lg_g4_iso_800, new File(Environment.getExternalStorageDirectory(),
+                EXTERNAL_BASE_DIRECTORY + LG_G4_ISO_800_JPG));
+        testExifInterfaceForJpeg(LG_G4_ISO_800_JPG, R.array.lg_g4_iso_800_jpg);
+    }
+
     public void testDoNotFailOnCorruptedImage() throws Throwable {
         // To keep the compatibility with old versions of ExifInterface, even on a corrupted image,
         // it shouldn't raise any exceptions except an IOException when unable to open a file.
@@ -537,4 +579,11 @@
         assertEquals(dateTimeOriginalValue, exif.getAttribute(ExifInterface.TAG_DATETIME));
         imageFile.delete();
     }
+
+    private void stageFile(int resId, File file) throws IOException {
+        try (InputStream source = getContext().getResources().openRawResource(resId);
+                OutputStream target = new FileOutputStream(file)) {
+            FileUtils.copy(source, target);
+        }
+    }
 }
diff --git a/tests/tests/media/src/android/media/cts/MediaCasTest.java b/tests/tests/media/src/android/media/cts/MediaCasTest.java
index 97cdcdd..e13f945 100644
--- a/tests/tests/media/src/android/media/cts/MediaCasTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaCasTest.java
@@ -180,6 +180,13 @@
                                 + "event=" + event + ", arg=" + arg
                                 + ", data=" + Arrays.toString(data));
                     }
+                    @Override
+                    public void onSessionEvent(MediaCas MediaCas, MediaCas.Session session,
+                            int event, int arg, byte[] data) {
+                        Log.d(TAG, "Received MediaCas Session event: "
+                                + "event=" + event + ", arg=" + arg
+                                + ", data=" + Arrays.toString(data));
+                    }
                 }, null);
             } finally {
                 if (mediaCas != null) {
@@ -280,11 +287,13 @@
             thread.start();
             Handler handler = new Handler(thread.getLooper());
             testEventEcho(mediaCas, 1, 2, null /* data */, handler);
+            testSessionEventEcho(mediaCas, session, 1, 2, null /* data */, handler);
             thread.interrupt();
 
             String eventDataString = "event data string";
             byte[] eventData = eventDataString.getBytes();
             testEventEcho(mediaCas, 3, 4, eventData, null /* handler */);
+            testSessionEventEcho(mediaCas, session, 3, 4, eventData, null /* handler */);
 
             String emm = "clear key emm";
             byte[] emmData = emm.getBytes();
@@ -485,6 +494,7 @@
     private class TestEventListener implements MediaCas.EventListener {
         private final CountDownLatch mLatch = new CountDownLatch(1);
         private final MediaCas mMediaCas;
+        private final MediaCas.Session mSession;
         private final int mEvent;
         private final int mArg;
         private final byte[] mData;
@@ -495,6 +505,16 @@
             mEvent = event;
             mArg = arg;
             mData = data;
+            mSession = null;
+        }
+
+        TestEventListener(MediaCas mediaCas, MediaCas.Session session, int event,
+                int arg, byte[] data) {
+            mMediaCas = mediaCas;
+            mSession = session;
+            mEvent = event;
+            mArg = arg;
+            mData = data;
         }
 
         boolean waitForResult() {
@@ -519,7 +539,21 @@
             }
             mLatch.countDown();
         }
-    }
+
+        @Override
+        public void onSessionEvent(MediaCas mediaCas, MediaCas.Session session,
+            int event, int arg, byte[] data) {
+            Log.d(TAG, "Received MediaCas session event: event=" + event
+                    + ", arg=" + arg + ", data=" + Arrays.toString(data));
+            if (mediaCas == mMediaCas && mSession.equals(session) && event == mEvent
+                    && arg == mArg && (Arrays.equals(data, mData) ||
+                            data == null && mData.length == 0 ||
+                            mData == null && data.length == 0)) {
+                mIsIdential = true;
+            }
+            mLatch.countDown();
+        }
+     }
 
     // helper to send an event and wait for echo
     private void testEventEcho(MediaCas mediaCas, int event,
@@ -530,6 +564,15 @@
         assertTrue("Didn't receive event callback for " + event, listener.waitForResult());
     }
 
+    // helper to send an event and wait for echo
+    private void testSessionEventEcho(MediaCas mediaCas, MediaCas.Session session, int event,
+            int arg, byte[] data, Handler handler) throws Exception {
+        TestEventListener listener = new TestEventListener(mediaCas, session, event, arg, data);
+        mediaCas.setEventListener(listener, handler);
+        session.sendSessionEvent(event, arg, data);
+        assertTrue("Didn't receive event callback for " + event, listener.waitForResult());
+    }
+
     // helper to descramble from the sample input (sInputBufferStr) and get output buffer
     private ByteBuffer descrambleTestInputBuffer(
             MediaDescrambler descrambler) throws Exception {
diff --git a/tests/tests/media/src/android/media/cts/MediaCodecClearKeyPlayer.java b/tests/tests/media/src/android/media/cts/MediaCodecClearKeyPlayer.java
index 5b2ad2f..6aaafe5 100644
--- a/tests/tests/media/src/android/media/cts/MediaCodecClearKeyPlayer.java
+++ b/tests/tests/media/src/android/media/cts/MediaCodecClearKeyPlayer.java
@@ -115,6 +115,9 @@
             "  \"track_types\": [ ]                              " +
             "}                                                   " ;
 
+    // ClearKey private data (0-bytes of length 4)
+    private static final byte[] sCasPrivateInfo = hexStringToByteArray("00000000");
+
     /**
      * Convert a hex string into byte array.
      */
@@ -309,6 +312,9 @@
                     MediaFormat.MIMETYPE_AUDIO_SCRAMBLED.equals(mime)) {
                 MediaExtractor.CasInfo casInfo = extractor.getCasInfo(trackId);
                 if (casInfo != null) {
+                    if (!Arrays.equals(sCasPrivateInfo, casInfo.getPrivateData())) {
+                        throw new Error("Cas private data mismatch");
+                    }
                     mMediaCas = new MediaCas(casInfo.getSystemId());
                     mMediaCas.provision(sProvisionStr);
                     extractor.setMediaCas(mMediaCas);
diff --git a/tests/tests/media/src/android/media/cts/MediaCodecTest.java b/tests/tests/media/src/android/media/cts/MediaCodecTest.java
index ec0c8f0..10603b9 100644
--- a/tests/tests/media/src/android/media/cts/MediaCodecTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaCodecTest.java
@@ -16,10 +16,13 @@
 
 package android.media.cts;
 
+import static org.testng.Assert.assertThrows;
+
 import android.media.cts.R;
 import android.content.res.AssetFileDescriptor;
 import android.content.res.Resources;
 import android.media.AudioFormat;
+import android.media.AudioPresentation;
 import android.media.MediaCodec;
 import android.media.MediaCodec.BufferInfo;
 import android.media.MediaCodec.CodecException;
@@ -2379,4 +2382,18 @@
             }
         }
     }
+
+    public void testSetAudioPresentation() throws Exception {
+        MediaFormat format = MediaFormat.createAudioFormat(
+                MediaFormat.MIMETYPE_AUDIO_MPEG, 44100 /* sampleRate */, 2 /* channelCount */);
+        String mimeType = format.getString(MediaFormat.KEY_MIME);
+        MediaCodec codec = createCodecByType(
+                format.getString(MediaFormat.KEY_MIME), false /* isEncoder */);
+        assertNotNull(codec);
+        assertThrows(NullPointerException.class, () -> {
+            codec.setAudioPresentation(null);
+        });
+        codec.setAudioPresentation(
+                (new AudioPresentation.Builder(42 /* presentationId */)).build());
+    }
 }
diff --git a/tests/tests/media/src/android/media/cts/MediaDrmClearkeyTest.java b/tests/tests/media/src/android/media/cts/MediaDrmClearkeyTest.java
index 16f8863..80581a1 100644
--- a/tests/tests/media/src/android/media/cts/MediaDrmClearkeyTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaDrmClearkeyTest.java
@@ -651,7 +651,7 @@
             getKeys(drm, "cenc", mSessionId, mDrmInitData, MediaDrm.KEY_TYPE_OFFLINE,
                     new byte[][] { CLEAR_KEY_CENC });
 
-            if (drm.getOfflineLicenseState(mKeySetId) != MediaDrm.OFFLINE_LICENSE_USABLE) {
+            if (drm.getOfflineLicenseState(mKeySetId) != MediaDrm.OFFLINE_LICENSE_STATE_USABLE) {
                 throw new Error("Offline license state is not usable");
             }
 
diff --git a/tests/tests/media/src/android/media/cts/MediaFormatTest.java b/tests/tests/media/src/android/media/cts/MediaFormatTest.java
new file mode 100644
index 0000000..c5b3ed4
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/MediaFormatTest.java
@@ -0,0 +1,588 @@
+/*
+ * Copyright (C) 2018 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.media.cts;
+
+import android.media.MediaFormat;
+import android.test.AndroidTestCase;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+public class MediaFormatTest extends AndroidTestCase {
+    private static ByteBuffer defaultByteBuffer = ByteBuffer.allocateDirect(16);
+
+    private void assertGetByteBuffersThrowClassCastException(
+            MediaFormat format, String key, String type) {
+        try {
+            ByteBuffer value = format.getByteBuffer(key);
+            throw new AssertionError("read " + type + " as ByteBuffer " + value);
+        } catch (ClassCastException e) {
+        }
+
+        try {
+            ByteBuffer value = format.getByteBuffer(key, defaultByteBuffer);
+            throw new AssertionError("read " + type + " with default as ByteBuffer " + value);
+        } catch (ClassCastException e) {
+        }
+    }
+
+    private void assertGetFloatsThrowClassCastException(
+            MediaFormat format, String key, String type) {
+        try {
+            float value = format.getFloat(key);
+            throw new AssertionError("read " + type + " as float " + value);
+        } catch (ClassCastException e) {
+        }
+
+        try {
+            float value = format.getFloat(key, 321.f);
+            throw new AssertionError("read " + type + " with default as float " + value);
+        } catch (ClassCastException e) {
+        }
+    }
+
+    private void assertGetIntegersThrowClassCastException(
+            MediaFormat format, String key, String type) {
+        try {
+            int value = format.getInteger(key);
+            throw new AssertionError("read " + type + " as int " + value);
+        } catch (ClassCastException e) {
+        }
+
+        try {
+            int value = format.getInteger(key, 123);
+            throw new AssertionError("read " + type + " with default as int " + value);
+        } catch (ClassCastException e) {
+        }
+    }
+
+    private void assertGetLongsThrowClassCastException(
+            MediaFormat format, String key, String type) {
+        try {
+            long value = format.getLong(key);
+            throw new AssertionError("read " + type + " as long " + value);
+        } catch (ClassCastException e) {
+        }
+
+        try {
+            long value = format.getLong(key, 321L);
+            throw new AssertionError("read " + type + " with default as long " + value);
+        } catch (ClassCastException e) {
+        }
+    }
+
+    private void assertGetNumbersThrowClassCastException(
+            MediaFormat format, String key, String type) {
+        try {
+            Number value = format.getNumber(key);
+            throw new AssertionError("read " + type + " as Number " + value);
+        } catch (ClassCastException e) {
+        }
+
+        try {
+            Number value = format.getNumber(key, 321.f);
+            throw new AssertionError("read " + type + " with default as Number " + value);
+        } catch (ClassCastException e) {
+        }
+    }
+
+    private void assertGetStringsThrowClassCastException(
+            MediaFormat format, String key, String type) {
+        try {
+            String value = format.getString(key);
+            throw new AssertionError("read " + type + " as string " + value);
+        } catch (ClassCastException e) {
+        }
+
+        try {
+            String value = format.getString(key, "321");
+            throw new AssertionError("read " + type + " with default as string " + value);
+        } catch (ClassCastException e) {
+        }
+    }
+
+    public void testIntegerValue() throws Exception {
+        MediaFormat format = new MediaFormat();
+        format.setInteger("int", 123);
+
+        assertEquals(123, format.getInteger("int"));
+
+        // We should be able to read int values as numbers.
+        assertEquals(123, format.getNumber("int").intValue());
+        assertEquals(123, format.getNumber("int", 321).intValue());
+
+        // We should not be able to get an integer value as any other type. Instead,
+        // we should receive a ClassCastException
+        assertGetByteBuffersThrowClassCastException(format, "int", "int");
+        assertGetFloatsThrowClassCastException(format, "int", "int");
+        assertGetLongsThrowClassCastException(format, "int", "int");
+        assertGetStringsThrowClassCastException(format, "int", "int");
+
+        // We should not have a feature enabled for an integer value
+        try {
+            boolean value = format.getFeatureEnabled("int");
+            throw new AssertionError("read int as feature " + value);
+        } catch (IllegalArgumentException e) {
+        }
+
+        testSingleKeyRemoval(format, "int", MediaFormat.TYPE_INTEGER);
+    }
+
+    public void testLongValue() throws Exception {
+        MediaFormat format = new MediaFormat();
+        format.setLong("long", 9876543210L);
+
+        assertEquals(9876543210L, format.getLong("long"));
+
+        // We should be able to read long values as numbers.
+        assertEquals(9876543210L, format.getNumber("long").longValue());
+        assertEquals(9876543210L, format.getNumber("long", 9012345678L).longValue());
+
+        // We should not be able to get a long value as any other type. Instead,
+        // we should receive a ClassCastException
+        assertGetByteBuffersThrowClassCastException(format, "long", "long");
+        assertGetFloatsThrowClassCastException(format, "long", "long");
+        assertGetIntegersThrowClassCastException(format, "long", "long");
+        assertGetStringsThrowClassCastException(format, "long", "long");
+
+        // We should not have a feature enabled for a long value
+        try {
+            boolean value = format.getFeatureEnabled("long");
+            throw new AssertionError("read long as feature " + value);
+        } catch (IllegalArgumentException e) {
+        }
+
+        testSingleKeyRemoval(format, "long", MediaFormat.TYPE_LONG);
+    }
+
+    public void testFloatValue() throws Exception {
+        MediaFormat format = new MediaFormat();
+        format.setFloat("float", 3.14f);
+
+        assertEquals(3.14f, format.getFloat("float"));
+
+        // We should be able to read float values as numbers.
+        assertEquals(3.14f, format.getNumber("float").floatValue());
+        assertEquals(3.14f, format.getNumber("float", 2.81f).floatValue());
+
+        // We should not be able to get a float value as any other type. Instead,
+        // we should receive a ClassCastException
+        assertGetByteBuffersThrowClassCastException(format, "float", "float");
+        assertGetIntegersThrowClassCastException(format, "float", "float");
+        assertGetLongsThrowClassCastException(format, "float", "float");
+        assertGetStringsThrowClassCastException(format, "float", "float");
+
+        // We should not have a feature enabled for a float value
+        try {
+            boolean value = format.getFeatureEnabled("float");
+            throw new AssertionError("read float as feature " + value);
+        } catch (IllegalArgumentException e) {
+        }
+
+        testSingleKeyRemoval(format, "float", MediaFormat.TYPE_FLOAT);
+    }
+
+    public void testStringValue() throws Exception {
+        MediaFormat format = new MediaFormat();
+        format.setString("string", "value");
+
+        assertEquals("value", format.getString("string"));
+
+        // We should not be able to get a string value as any other type. Instead,
+        // we should receive a ClassCastException
+        assertGetByteBuffersThrowClassCastException(format, "string", "string");
+        assertGetFloatsThrowClassCastException(format, "string", "string");
+        assertGetIntegersThrowClassCastException(format, "string", "string");
+        assertGetLongsThrowClassCastException(format, "string", "string");
+        assertGetNumbersThrowClassCastException(format, "string", "string");
+
+        // We should not have a feature enabled for an integer value
+        try {
+            boolean value = format.getFeatureEnabled("string");
+            throw new AssertionError("read string as feature " + value);
+        } catch (IllegalArgumentException e) {
+        }
+
+        testSingleKeyRemoval(format, "string", MediaFormat.TYPE_STRING);
+    }
+
+    public void testByteBufferValue() throws Exception {
+        MediaFormat format = new MediaFormat();
+        ByteBuffer buffer = ByteBuffer.allocateDirect(123);
+        format.setByteBuffer("buffer", buffer);
+
+        assertEquals(buffer, format.getByteBuffer("buffer"));
+
+        // We should not be able to get a string value as any other type. Instead,
+        // we should receive a ClassCastException
+        assertGetFloatsThrowClassCastException(format, "buffer", "ByteBuffer");
+        assertGetIntegersThrowClassCastException(format, "buffer", "ByteBuffer");
+        assertGetLongsThrowClassCastException(format, "buffer", "ByteBuffer");
+        assertGetNumbersThrowClassCastException(format, "buffer", "ByteBuffer");
+        assertGetStringsThrowClassCastException(format, "buffer", "ByteBuffer");
+
+        // We should not have a feature enabled for an integer value
+        try {
+            boolean value = format.getFeatureEnabled("buffer");
+            throw new AssertionError("read ByteBuffer as feature " + value);
+        } catch (IllegalArgumentException e) {
+        }
+
+        testSingleKeyRemoval(format, "buffer", MediaFormat.TYPE_BYTE_BUFFER);
+    }
+
+    public void testNullStringValue() throws Exception {
+        MediaFormat format = new MediaFormat();
+        format.setString("null", null);
+        testNullOrMissingValue(format, "null");
+        testSingleKeyRemoval(format, "null", MediaFormat.TYPE_NULL);
+    }
+
+    public void testNullByteBufferValue() throws Exception {
+        MediaFormat format = new MediaFormat();
+        format.setByteBuffer("null", null);
+        testNullOrMissingValue(format, "null");
+        testSingleKeyRemoval(format, "null", MediaFormat.TYPE_NULL);
+    }
+
+    public void testMissingValue() throws Exception {
+        MediaFormat format = new MediaFormat();
+        // null values should be handled the same as missing values
+        assertEquals(MediaFormat.TYPE_NULL, format.getValueTypeForKey("missing"));
+        testNullOrMissingValue(format, "missing");
+    }
+
+    private void testSingleKeyRemoval(
+            MediaFormat format, String key, @MediaFormat.Type int type) {
+        assertEquals(type, format.getValueTypeForKey(key));
+        assertTrue(format.containsKey(key));
+
+        Set<String> keySet = format.getKeys();
+        assertEquals(1, keySet.size());
+        assertTrue(keySet.contains(key));
+
+        format.removeKey(key);
+        assertFalse(format.containsKey(key));
+
+        // test that keySet is connected to the format
+        assertFalse(keySet.contains(key));
+        assertEquals(0, keySet.size());
+    }
+
+    private static Set<String> asSet(String ... values) {
+        return new HashSet<>(Arrays.asList(values));
+    }
+
+    private void assertStringSetEquals(Set<String> set, String ... expected_members) {
+        Set<String> expected = new HashSet<>(Arrays.asList(expected_members));
+        assertEquals(expected, set);
+    }
+
+    public void testKeySetContainsAndRemove() {
+        MediaFormat format = new MediaFormat();
+        format.setInteger("int", 123);
+        format.setLong("long", 9876543210L);
+        format.setFloat("float", 321.f);
+        format.setFeatureEnabled("int", true);
+        format.setFeatureEnabled("long", false);
+        format.setFeatureEnabled("float", true);
+        format.setFeatureEnabled("string", false);
+
+        Set<String> keySet = format.getKeys();
+        // test size and contains
+        assertEquals(3, keySet.size());
+        assertTrue(keySet.contains("int"));
+        assertTrue(keySet.contains("long"));
+        assertTrue(keySet.contains("float"));
+        assertFalse(keySet.contains("string"));
+        assertStringSetEquals(keySet, "int", "long", "float");
+
+        // test adding an element
+        format.setString("string", "value");
+
+        // test that key set reflects format change in size and contains
+        assertEquals(4, keySet.size());
+        assertTrue(keySet.contains("int"));
+        assertTrue(keySet.contains("long"));
+        assertTrue(keySet.contains("float"));
+        assertTrue(keySet.contains("string"));
+
+        // test iterator
+        {
+            Set<String> toFind = asSet("int", "long", "float", "string");
+            Iterator<String> it = keySet.iterator();
+            while (it.hasNext()) {
+                String k = it.next();
+                assertTrue(toFind.remove(k));
+            }
+            assertEquals(0, toFind.size());
+        }
+
+        // remove via format
+        format.removeKey("float");
+
+        // test that key set reflects format change in size and contains
+        assertEquals(3, keySet.size());
+        assertTrue(keySet.contains("int"));
+        assertTrue(keySet.contains("long"));
+        assertFalse(keySet.contains("float"));
+        assertTrue(keySet.contains("string"));
+
+        // re-test iterator after removal
+        {
+            Set<String> toFind = asSet("int", "long", "string");
+            for (String k : keySet) {
+                assertTrue(toFind.remove(k));
+            }
+            assertEquals(0, toFind.size());
+        }
+
+        // test remove
+        keySet.remove("long");
+        assertEquals(2, keySet.size());
+        assertTrue(keySet.contains("int"));
+        assertFalse(keySet.contains("long"));
+        assertFalse(keySet.contains("float"));
+        assertTrue(keySet.contains("string"));
+        assertTrue(format.containsKey("int"));
+        assertFalse(format.containsKey("long"));
+        assertFalse(format.containsKey("float"));
+        assertTrue(format.containsKey("string"));
+
+        // test iterator by its interface as well as its remove
+        {
+            Set<String> toFind = asSet("int", "string");
+            Iterator<String> it = keySet.iterator();
+            while (it.hasNext()) {
+                String k = it.next();
+                assertTrue(toFind.remove(k));
+                if (k.equals("int")) {
+                    it.remove();
+                }
+            }
+            assertEquals(0, toFind.size());
+        }
+
+        // test that removing via iterator also removes from format
+        assertEquals(1, keySet.size());
+        assertFalse(keySet.contains("int"));
+        assertFalse(keySet.contains("long"));
+        assertFalse(keySet.contains("float"));
+        assertTrue(keySet.contains("string"));
+        assertFalse(format.containsKey("int"));
+        assertFalse(format.containsKey("long"));
+        assertFalse(format.containsKey("float"));
+        assertTrue(format.containsKey("string"));
+
+        // verify that features are still present
+        assertTrue(format.getFeatureEnabled("int"));
+        assertFalse(format.getFeatureEnabled("long"));
+        assertTrue(format.getFeatureEnabled("float"));
+        assertFalse(format.getFeatureEnabled("string"));
+    }
+
+    public void testFeatureKeySetContainsAndRemove() {
+        MediaFormat format = new MediaFormat();
+        format.setInteger("int", 123);
+        format.setLong("long", 9876543210L);
+        format.setFloat("float", 321.f);
+        format.setString("string", "value");
+        format.setFeatureEnabled("int", true);
+        format.setFeatureEnabled("long", false);
+        format.setFeatureEnabled("float", true);
+
+        Set<String> featureSet = format.getFeatures();
+        // test size and contains
+        assertEquals(3, featureSet.size());
+        assertTrue(featureSet.contains("int"));
+        assertTrue(featureSet.contains("long"));
+        assertTrue(featureSet.contains("float"));
+        assertFalse(featureSet.contains("string"));
+        assertStringSetEquals(featureSet, "int", "long", "float");
+
+        // test adding an element
+        format.setFeatureEnabled("string", false);
+
+        // test that key set reflects format change in size and contains
+        assertEquals(4, featureSet.size());
+        assertTrue(featureSet.contains("int"));
+        assertTrue(featureSet.contains("long"));
+        assertTrue(featureSet.contains("float"));
+        assertTrue(featureSet.contains("string"));
+
+        // test iterator
+        {
+            Set<String> toFind = asSet("int", "long", "float", "string");
+            Iterator<String> it = featureSet.iterator();
+            while (it.hasNext()) {
+                String k = it.next();
+                assertTrue(toFind.remove(k));
+            }
+            assertEquals(0, toFind.size());
+        }
+
+        // test that features cannot be removed via format as keys, even though for backward
+        // compatibility, they can be accessed as integers and can be found via containsKey
+        format.removeKey("feature-float");
+        assertEquals(4, featureSet.size());
+        assertTrue(featureSet.contains("float"));
+
+        format.removeFeature("float");
+
+        // TODO: deprecate this usage
+        assertEquals(1, format.getInteger("feature-int"));
+        assertEquals(0, format.getInteger("feature-long"));
+        assertTrue(format.containsKey("feature-int"));
+
+        // Along these lines also verify that this is not true for the getKeys() set
+        assertFalse(format.getKeys().contains("feature-int"));
+
+        // Also verify that getKeys() cannot be used to remove a feature
+        assertFalse(format.getKeys().remove("feature-int"));
+
+        // test that key set reflects format change in size and contains
+        assertEquals(3, featureSet.size());
+        assertTrue(featureSet.contains("int"));
+        assertTrue(featureSet.contains("long"));
+        assertFalse(featureSet.contains("float"));
+        assertTrue(featureSet.contains("string"));
+
+        // re-test iterator after removal
+        {
+            Set<String> toFind = asSet("int", "long", "string");
+            for (String k : featureSet) {
+                assertTrue(toFind.remove(k));
+            }
+            assertEquals(0, toFind.size());
+        }
+
+        // test remove via set
+        featureSet.remove("long");
+        assertEquals(2, featureSet.size());
+        assertTrue(featureSet.contains("int"));
+        assertFalse(featureSet.contains("long"));
+        assertFalse(featureSet.contains("float"));
+        assertTrue(featureSet.contains("string"));
+
+        assertTrue(format.containsFeature("int"));
+        assertFalse(format.containsFeature("long"));
+        assertFalse(format.containsFeature("float"));
+        assertTrue(format.containsFeature("string"));
+
+        assertTrue(format.getFeatureEnabled("int"));
+        try {
+            format.getFeatureEnabled("long");
+            fail("should not contain feature long");
+        } catch (IllegalArgumentException e) {}
+        try {
+            format.getFeatureEnabled("float");
+            fail("should not contain feature float");
+        } catch (IllegalArgumentException e) {}
+        assertFalse(format.getFeatureEnabled("string"));
+
+        // test iterator by its interface as well as its remove
+        {
+            Set<String> toFind = asSet("int", "string");
+            Iterator<String> it = featureSet.iterator();
+            while (it.hasNext()) {
+                String k = it.next();
+                assertTrue(toFind.remove(k));
+                if (k.equals("int")) {
+                    it.remove();
+                }
+            }
+            assertEquals(0, toFind.size());
+        }
+
+        // test that removing via iterator also removes from format
+        assertEquals(1, featureSet.size());
+        assertFalse(featureSet.contains("int"));
+        assertFalse(featureSet.contains("long"));
+        assertFalse(featureSet.contains("float"));
+        assertTrue(featureSet.contains("string"));
+
+        assertFalse(format.containsFeature("int"));
+        assertFalse(format.containsFeature("long"));
+        assertFalse(format.containsFeature("float"));
+        assertTrue(format.containsFeature("string"));
+
+        try {
+            format.getFeatureEnabled("int");
+            fail("should not contain feature int");
+        } catch (IllegalArgumentException e) {}
+        try {
+            format.getFeatureEnabled("long");
+            fail("should not contain feature long");
+        } catch (IllegalArgumentException e) {}
+        try {
+            format.getFeatureEnabled("float");
+            fail("should not contain feature float");
+        } catch (IllegalArgumentException e) {}
+        assertFalse(format.getFeatureEnabled("string"));
+
+        // verify that keys are still present
+        assertEquals(123, format.getInteger("int"));
+        assertEquals(9876543210L, format.getLong("long"));
+        assertEquals(321.f, format.getFloat("float"));
+        assertEquals("value", format.getString("string"));
+    }
+
+    private void testNullOrMissingValue(MediaFormat format, String key) throws Exception {
+        // We should not be able to get a string value as any primitive type. Instead,
+        // we should receive a NullPointerException
+        try {
+            int value = format.getInteger(key);
+            throw new AssertionError("read " + key + " as int " + value);
+        } catch (NullPointerException e) {
+        }
+
+        try {
+            long value = format.getLong(key);
+            throw new AssertionError("read " + key + " as long " + value);
+        } catch (NullPointerException e) {
+        }
+
+        try {
+            float value = format.getFloat(key);
+            throw new AssertionError("read " + key + " as float " + value);
+        } catch (NullPointerException e) {
+        }
+
+        // We should get null for all object types (ByteBuffer, Number, String)
+        assertNull(format.getNumber(key));
+        assertNull(format.getString(key));
+        assertNull(format.getByteBuffer(key));
+
+        // We should get the default value for all getters with default
+        assertEquals(123, format.getInteger(key, 123));
+        assertEquals(321L, format.getLong(key, 321L));
+        assertEquals(321.f, format.getFloat(key, 321.f));
+        assertEquals(321.f, format.getNumber(key, 321.f));
+        assertEquals("value", format.getString(key, "value"));
+        assertEquals(defaultByteBuffer, format.getByteBuffer(key, defaultByteBuffer));
+
+        // We should not have a feature enabled for a null value
+        try {
+            boolean value = format.getFeatureEnabled(key);
+            throw new AssertionError("read " + key + " as feature " + value);
+        } catch (IllegalArgumentException e) {
+        }
+    }
+}
diff --git a/tests/tests/media/src/android/media/cts/MediaItem2Test.java b/tests/tests/media/src/android/media/cts/MediaItem2Test.java
index efb6f98..cdb15a6 100644
--- a/tests/tests/media/src/android/media/cts/MediaItem2Test.java
+++ b/tests/tests/media/src/android/media/cts/MediaItem2Test.java
@@ -17,10 +17,12 @@
 package android.media.cts;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.fail;
 
 import android.media.MediaItem2;
 import android.media.MediaMetadata;
+import android.os.Parcel;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 
@@ -107,6 +109,40 @@
         assertEquals(meta2, item.getMetadata());
     }
 
+    @Test
+    public void testDescribeContents() {
+        MediaItem2 item = new MediaItem2.Builder().setStartPosition(0).setEndPosition(10).build();
+        assertEquals(0, item.describeContents());
+    }
+
+    @Test
+    public void testWriteToParcel() {
+        long testStartPosition = 100;
+        long testEndPosition = 200;
+        final String testId = "testId";
+        final long testDuration = 12345;
+
+        MediaItem2 item = new MediaItem2.Builder()
+                .setStartPosition(testStartPosition)
+                .setEndPosition(testEndPosition)
+                .setMetadata(createMetadata(testId, testDuration))
+                .build();
+
+        Parcel parcel = Parcel.obtain();
+        item.writeToParcel(parcel, 0 /* flags */);
+        parcel.setDataPosition(0);
+        MediaItem2 itemOut = MediaItem2.CREATOR.createFromParcel(parcel);
+
+        assertEquals(testStartPosition, itemOut.getStartPosition());
+        assertEquals(testEndPosition, itemOut.getEndPosition());
+        MediaMetadata metadataOut = item.getMetadata();
+        assertNotNull(metadataOut);
+        assertEquals(testId, metadataOut.getString(MediaMetadata.METADATA_KEY_MEDIA_ID));
+        assertEquals(testDuration, metadataOut.getLong(MediaMetadata.METADATA_KEY_DURATION));
+
+        parcel.recycle();
+    }
+
     private MediaMetadata createMetadata(String id, long duration) {
         MediaMetadata.Builder builder = new MediaMetadata.Builder();
         builder.putString(MediaMetadata.METADATA_KEY_MEDIA_ID, id);
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayer2DrmTest.java b/tests/tests/media/src/android/media/cts/MediaPlayer2DrmTest.java
index a5461e7..de1b747 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayer2DrmTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayer2DrmTest.java
@@ -129,6 +129,14 @@
     }
 
     @LargeTest
+    public void testCAR_CLEARKEY_AUDIO_DOWNLOADED_V4_OFFLINE_KEY() throws Exception {
+        download(CENC_AUDIO_URL,
+                CENC_AUDIO_URL_DOWNLOADED,
+                RES_AUDIO,
+                ModularDrmTestType.V4_SYNC_OFFLINE_KEY);
+    }
+
+    @LargeTest
     public void testCAR_CLEARKEY_AUDIO_DOWNLOADED_V5_ASYNC_CALLBACKS() throws Exception {
         download(CENC_AUDIO_URL,
                 CENC_AUDIO_URL_DOWNLOADED,
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayer2DrmTestBase.java b/tests/tests/media/src/android/media/cts/MediaPlayer2DrmTestBase.java
index c27b314..66b38f2 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayer2DrmTestBase.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayer2DrmTestBase.java
@@ -28,7 +28,6 @@
 import android.media.MediaPlayer2;
 import android.media.MediaPlayer2.DrmInfo;
 import android.media.MediaPlayer2.DrmPreparationInfo;
-import android.media.VideoSize;
 import android.media.MediaDrm.KeyRequest;
 import android.media.cts.TestUtils.Monitor;
 import android.net.Uri;
@@ -36,6 +35,7 @@
 import android.test.ActivityInstrumentationTestCase2;
 import android.util.Base64;
 import android.util.Log;
+import android.util.Size;
 import android.view.SurfaceHolder;
 
 import org.json.JSONArray;
@@ -45,7 +45,9 @@
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.charset.Charset;
+import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.UUID;
@@ -67,6 +69,7 @@
     protected Monitor mOnPreparedCalled = new Monitor();
     protected Monitor mOnVideoSizeChangedCalled = new Monitor();
     protected Monitor mOnPlaybackCompleted = new Monitor();
+    protected Monitor mOnPlaylistCompleted = new Monitor();
     protected Monitor mOnDrmInfoCalled = new Monitor();
     protected Monitor mOnDrmPreparedCalled = new Monitor();
     protected int mCallStatus = MediaPlayer2.CALL_STATUS_NO_ERROR;
@@ -78,7 +81,41 @@
     protected MediaStubActivity mActivity;
 
     protected ExecutorService mExecutor;
-    protected MediaPlayer2.EventCallback mECb = null;
+    protected MediaPlayer2.EventCallback mECb = new MediaPlayer2.EventCallback() {
+        @Override
+        public void onVideoSizeChanged(MediaPlayer2 mp, DataSourceDesc dsd, Size size) {
+            Log.v(TAG, "VideoSizeChanged" + " w:" + size.getWidth()
+                    + " h:" + size.getHeight());
+            mOnVideoSizeChangedCalled.signal();
+        }
+
+        @Override
+        public void onError(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
+            fail("Media player had error " + what + " playing video");
+        }
+
+        @Override
+        public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
+            if (what == MediaPlayer2.MEDIA_INFO_PREPARED) {
+                mOnPreparedCalled.signal();
+            } else if (what == MediaPlayer2.MEDIA_INFO_DATA_SOURCE_END) {
+                Log.v(TAG, "playLoadedVideo: MEDIA_INFO_DATA_SOURCE_END");
+                mOnPlaybackCompleted.signal();
+            } else if (what == MediaPlayer2.MEDIA_INFO_DATA_SOURCE_LIST_END) {
+                Log.v(TAG, "playLoadedVideo: MEDIA_INFO_DATA_SOURCE_LIST_END");
+                mOnPlaylistCompleted.signal();
+            }
+        }
+
+        @Override
+        public void onCallCompleted(MediaPlayer2 mp, DataSourceDesc dsd,
+                int what, int status) {
+            if (what == MediaPlayer2.CALL_COMPLETED_SET_DATA_SOURCE) {
+                mCallStatus = status;
+                mSetDataSourceCallCompleted.signal();
+            }
+        }
+    };
 
     public MediaPlayer2DrmTestBase() {
         super(MediaStubActivity.class);
@@ -245,38 +282,6 @@
         mAudioOnly = (width == 0);
 
         mCallStatus = MediaPlayer2.CALL_STATUS_NO_ERROR;
-        mECb = new MediaPlayer2.EventCallback() {
-                @Override
-                public void onVideoSizeChanged(MediaPlayer2 mp, DataSourceDesc dsd, VideoSize size) {
-                    Log.v(TAG, "VideoSizeChanged" + " w:" + size.getWidth()
-                            + " h:" + size.getHeight());
-                    mOnVideoSizeChangedCalled.signal();
-                }
-
-                @Override
-                public void onError(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
-                    fail("Media player had error " + what + " playing video");
-                }
-
-                @Override
-                public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
-                    if (what == MediaPlayer2.MEDIA_INFO_PREPARED) {
-                        mOnPreparedCalled.signal();
-                    } else if (what == MediaPlayer2.MEDIA_INFO_DATA_SOURCE_END) {
-                        Log.v(TAG, "playLoadedVideo: onInfo_PlaybackComplete");
-                        mOnPlaybackCompleted.signal();
-                    }
-                }
-
-                @Override
-                public void onCallCompleted(MediaPlayer2 mp, DataSourceDesc dsd,
-                        int what, int status) {
-                    if (what == MediaPlayer2.CALL_COMPLETED_SET_DATA_SOURCE) {
-                        mCallStatus = status;
-                        mSetDataSourceCallCompleted.signal();
-                    }
-                }
-            };
 
         mPlayer.registerEventCallback(mExecutor, mECb);
         Log.v(TAG, "playLoadedVideo: setDataSource()");
@@ -540,104 +545,140 @@
         }
     }
 
-    private void preparePlayerAndDrm_V5_asyncDrmSetupCallbacks(DataSourceDesc dsd)
-            throws InterruptedException {
-        final AtomicBoolean drmCallbackError = new AtomicBoolean(false);
+    private final class CtsDrmEventCallback extends MediaPlayer2.DrmEventCallback {
+        final String DRM_EVENT_CB_TAG = CtsDrmEventCallback.class.getSimpleName();
+        final AtomicBoolean mDrmCallbackError;
+        final List<DataSourceDesc> mDsds;
+        final int mKeyType;
+        byte[] mOfflineKeySetId;
 
-        mPlayer.setDrmEventCallback(mExecutor, new MediaPlayer2.DrmEventCallback() {
-            @Override
-            public DrmPreparationInfo onDrmInfo(MediaPlayer2 mp, DataSourceDesc dsd2,
-                    DrmInfo drmInfo) {
-                Log.v(TAG, "preparePlayerAndDrm_V5: onDrmInfo" + drmInfo);
+        CtsDrmEventCallback(AtomicBoolean drmCallbackError, List<DataSourceDesc> dsds,
+                int keyType) {
+            mDrmCallbackError = drmCallbackError;
+            mDsds = new ArrayList<DataSourceDesc>(dsds);
+            mKeyType = keyType;
+        }
 
-                // DRM preparation
-                UUID drmScheme = CLEARKEY_SCHEME_UUID;
-                List<UUID> supportedSchemes = drmInfo.getSupportedSchemes();
-                if (dsd != dsd2 || supportedSchemes.isEmpty()) {
-                    String msg = dsd != dsd2 ? "dsd mismatch" : "No supportedSchemes";
-                    Log.e(TAG, "preparePlayerAndDrm_V5: onDrmInfo " + msg);
-                    drmCallbackError.set(true);
-                    return null;
-                }
+        @Override
+        public DrmPreparationInfo onDrmInfo(MediaPlayer2 mp, DataSourceDesc dsd,
+                DrmInfo drmInfo) {
+            Log.v(DRM_EVENT_CB_TAG, "onDrmInfo" + drmInfo);
 
-                // setting up with the first supported UUID
-                // instead of supportedSchemes[0] in GTS
-                DrmPreparationInfo.Builder drmBuilder = new DrmPreparationInfo.Builder();
-                drmBuilder.setUuid(drmScheme);
-                drmBuilder.setMimeType("cenc");
-                drmBuilder.setKeyType(MediaDrm.KEY_TYPE_STREAMING);
+            // DRM preparation
+            List<UUID> supportedSchemes = drmInfo.getSupportedSchemes();
+            final DataSourceDesc curDsd = mDsds.get(0);
+            if (curDsd != dsd || supportedSchemes.isEmpty()) {
+                String msg = curDsd != dsd ? "dsd mismatch" : "No supportedSchemes";
+                Log.e(DRM_EVENT_CB_TAG, "onDrmInfo " + msg);
+                mDrmCallbackError.set(true);
+                return null;
+            }
 
-                byte[] psshData = drmInfo.getPssh().get(drmScheme);
-                byte[] initData;
-                // diverging from GTS
-                if (psshData == null) {
-                    initData = mClearKeyPssh;
-                    Log.d(TAG, "preparePlayerAndDrm_V5: CLEARKEY scheme not found in PSSH."
-                            + " Using default data.");
-                } else {
-                    // Can skip conversion if ClearKey adds support for BMFF initData b/64863112
-                    initData = makeCencPSSH(drmScheme, psshData);
-                }
-                drmBuilder.setInitData(initData);
-                Log.d(TAG, "preparePlayerAndDrm_V5: initData[" + drmScheme + "]: "
-                        + Arrays.toString(initData));
-
-                Log.v(TAG, "preparePlayerAndDrm_V5: onDrmInfo done!");
+            // setting up with the first supported UUID
+            // instead of supportedSchemes[0] in GTS
+            DrmPreparationInfo.Builder drmBuilder = new DrmPreparationInfo.Builder();
+            UUID drmScheme = CLEARKEY_SCHEME_UUID;
+            drmBuilder.setUuid(drmScheme);
+            if (mOfflineKeySetId != null && mOfflineKeySetId.length > 0) {
+                drmBuilder.setKeySetId(mOfflineKeySetId);
                 return drmBuilder.build();
             }
 
-            @Override
-            public void onDrmConfig(MediaPlayer2 mp, DataSourceDesc dsd2, MediaDrm drmObj) {
-                if (dsd != dsd2) {
-                    Log.e(TAG, "preparePlayerAndDrm_V5: onDrmConfig dsd mismatch");
-                    drmCallbackError.set(true);
-                    return;
-                }
+            drmBuilder.setMimeType("cenc");
+            drmBuilder.setKeyType(mKeyType);
 
-                String widevineSecurityLevel3 = "L3";
+            byte[] psshData = drmInfo.getPssh().get(drmScheme);
+            byte[] initData;
+            // diverging from GTS
+            if (psshData == null) {
+                initData = mClearKeyPssh;
+                Log.d(DRM_EVENT_CB_TAG,
+                        "CLEARKEY scheme not found in PSSH. Using default data.");
+            } else {
+                // Can skip conversion if ClearKey adds support for BMFF initData b/64863112
+                initData = makeCencPSSH(drmScheme, psshData);
+            }
+            drmBuilder.setInitData(initData);
+            Log.d(DRM_EVENT_CB_TAG,
+                    "initData[" + drmScheme + "]: " + Arrays.toString(initData));
+
+            Log.v(DRM_EVENT_CB_TAG, "onDrmInfo done!");
+            return drmBuilder.build();
+        }
+
+        @Override
+        public void onDrmConfig(MediaPlayer2 mp, DataSourceDesc dsd2, MediaDrm drmObj) {
+
+            final DataSourceDesc curDsd = mDsds.get(0);
+            if (curDsd != dsd2) {
+                Log.e(DRM_EVENT_CB_TAG, "onDrmConfig dsd mismatch");
+                mDrmCallbackError.set(true);
+                return;
+            }
+
+            try {
                 String securityLevelProperty = "securityLevel";
-
-                try {
-                    String level = drmObj.getPropertyString(securityLevelProperty);
-                    Log.v(TAG, "preparePlayerAndDrm_V5: getDrmPropertyString: "
-                            + securityLevelProperty + " -> " + level);
-                    drmObj.setPropertyString(securityLevelProperty, widevineSecurityLevel3);
-                    level = drmObj.getPropertyString(securityLevelProperty);
-                    Log.v(TAG, "preparePlayerAndDrm_V5: getDrmPropertyString: "
-                            + securityLevelProperty + " -> " + level);
-                } catch (Exception e) {
-                    Log.v(TAG, "preparePlayerAndDrm_V5: onDrmConfig EXCEPTION " + e);
-                }
+                String widevineSecurityLevel3 = "L3";
+                String level = drmObj.getPropertyString(securityLevelProperty);
+                Log.v(DRM_EVENT_CB_TAG, "getDrmPropertyString: "
+                        + securityLevelProperty + " -> " + level);
+                drmObj.setPropertyString(securityLevelProperty, widevineSecurityLevel3);
+                level = drmObj.getPropertyString(securityLevelProperty);
+                Log.v(DRM_EVENT_CB_TAG, "getDrmPropertyString: "
+                        + securityLevelProperty + " -> " + level);
+            } catch (Exception e) {
+                Log.v(DRM_EVENT_CB_TAG, "onDrmConfig EXCEPTION " + e);
             }
 
-            @Override
-            public byte[] onDrmKeyRequest(MediaPlayer2 mp, DataSourceDesc dsd, KeyRequest req) {
-                byte[][] clearKeys = new byte[][] { CLEAR_KEY_CENC };
-                byte[] response = createKeysResponse(req, clearKeys);
-                return response;
+        }
+
+        @Override
+        public byte[] onDrmKeyRequest(MediaPlayer2 mp, DataSourceDesc dsd, KeyRequest req) {
+            byte[][] clearKeys = new byte[][] { CLEAR_KEY_CENC };
+            byte[] response = createKeysResponse(req, clearKeys, mKeyType);
+            return response;
+        }
+
+        @Override
+        public void onDrmPrepared(MediaPlayer2 mp, DataSourceDesc dsd, int status,
+                byte[] keySetId) {
+
+            Log.v(DRM_EVENT_CB_TAG, "onDrmPrepared status: " + status);
+            String errMsg = null;
+            final DataSourceDesc curDsd = mDsds.remove(0);
+            if (curDsd != dsd) {
+                errMsg = "dsd mismatch";
             }
 
-            @Override
-            public void onDrmPrepared(MediaPlayer2 mp, DataSourceDesc dsd2, int status,
-                    byte[] keySetId) {
-                Log.v(TAG, "preparePlayerAndDrm_V5: onDrmPrepared status: " + status);
-                String errMsg = null;
-                if (dsd != dsd2) {
-                    errMsg = "dsd mismatch";
-                }
-                if (status != MediaPlayer2.PREPARE_DRM_STATUS_SUCCESS) {
-                    errMsg = "drm prepare failed";
-                }
-                if (keySetId != null && keySetId.length > 0) {
-                    errMsg = "unexpected keySetId";
-                }
-                if (errMsg != null) {
-                    drmCallbackError.set(true);
-                    Log.e(TAG, "preparePlayerAndDrm_V5: onDrmPrepared " + errMsg);
-                }
+            if (status != MediaPlayer2.PREPARE_DRM_STATUS_SUCCESS) {
+                errMsg = "drm prepare failed";
             }
-        });
 
+            final boolean hasKeySetId = keySetId != null && keySetId.length > 0;
+            final boolean isOffline = mKeyType == MediaDrm.KEY_TYPE_OFFLINE;
+            mOfflineKeySetId = keySetId;
+            if (hasKeySetId && !isOffline) {
+                errMsg = "unexpected keySetId";
+            }
+            if (!hasKeySetId && isOffline) {
+                errMsg = "expecting keySetId";
+            }
+
+            if (errMsg != null) {
+                mDrmCallbackError.set(true);
+                Log.e(DRM_EVENT_CB_TAG, "onDrmPrepared " + errMsg);
+            }
+
+        }
+    }
+
+    private void preparePlayerAndDrm_V5_asyncDrmSetupCallbacks(DataSourceDesc dsd)
+            throws InterruptedException {
+
+        final AtomicBoolean drmCallbackError = new AtomicBoolean(false);
+        List<DataSourceDesc> dsds = Collections.singletonList(dsd);
+        mPlayer.setDrmEventCallback(mExecutor,
+                new CtsDrmEventCallback(drmCallbackError, dsds, MediaDrm.KEY_TYPE_STREAMING));
         Log.v(TAG, "preparePlayerAndDrm_V5: calling prepare()");
         mPlayer.prepare();
 
@@ -648,103 +689,59 @@
         if (drmCallbackError.get()) {
             fail("preparePlayerAndDrm_V5: setupDrm");
         }
+
     }
 
     private void playLoadedModularDrmVideo_V4_offlineKey(final Uri file, final Integer width,
             final Integer height, int playTime) throws Exception {
         final float volume = 0.5f;
 
-        mAudioOnly = (width == 0);
+        mAudioOnly = (width == 0) || (height == 0);
+        mCallStatus = MediaPlayer2.CALL_STATUS_NO_ERROR;
 
         SurfaceHolder surfaceHolder = mActivity.getSurfaceHolder();
-        Log.v(TAG, "playLoadedModularDrmVideo_V4_offlineKey: setSurface " + surfaceHolder);
+        Log.v(TAG, "V4_offlineKey: setSurface " + surfaceHolder);
         mPlayer.setSurface(surfaceHolder.getSurface());
         surfaceHolder.setKeepScreenOn(true);
 
-        mCallStatus = MediaPlayer2.CALL_STATUS_NO_ERROR;
-        DrmInfo drmInfo = null;
+        final AtomicBoolean drmCallbackError = new AtomicBoolean(false);
+        UriDataSourceDesc.Builder dsdBuilder = new UriDataSourceDesc.Builder();
+        DataSourceDesc dsd = dsdBuilder.setDataSource(mContext, file).build();
+        DataSourceDesc dsd2 = dsdBuilder.build();
+        List<DataSourceDesc> dsds = Arrays.asList(dsd, dsd2);
 
-        for (int round = 0; round < 2; round++) {
-            boolean keyRequestRound = (round == 0);
-            boolean restoreRound = (round == 1);
-            Log.v(TAG, "playLoadedVideo: round " + round);
+        Log.v(TAG, "V4_offlineKey: set(Next)DataSource()");
+        mPlayer.registerEventCallback(mExecutor, mECb);
+        mPlayer.setDataSource(dsd);
+        mPlayer.setNextDataSource(dsd2);
+        mPlayer.setDrmEventCallback(mExecutor,
+                new CtsDrmEventCallback(drmCallbackError, dsds, MediaDrm.KEY_TYPE_OFFLINE));
 
-            UriDataSourceDesc.Builder dsdBuilder = new UriDataSourceDesc.Builder();
-            DataSourceDesc dsd = dsdBuilder.setDataSource(mContext, file).build();
-            try {
-                mPlayer.registerEventCallback(mExecutor, mECb);
+        Log.v(TAG, "V4_offlineKey: prepare()");
+        mPlayer.prepare();
+        mOnPreparedCalled.waitForSignal();
 
-                Log.v(TAG, "playLoadedVideo: setDataSource()");
-                mPlayer.setDataSource(dsd);
+        Log.v(TAG, "V4_offlineKey: play()");
+        mPlayer.play();
+        if (!mAudioOnly) {
+            mOnVideoSizeChangedCalled.waitForSignal();
+        }
+        mPlayer.setPlayerVolume(volume);
 
-                Log.v(TAG, "playLoadedVideo: prepare()");
-                mPlayer.prepare();
-                mOnPreparedCalled.waitForSignal();
+        // wait for completion
+        if (playTime == 0) {
+            Log.v(TAG, "V4_offlineKey: waiting for playback completion");
+            mOnPlaybackCompleted.waitForCountedSignals(dsds.size());
+            mOnPlaylistCompleted.waitForSignal();
+        } else {
+            Log.v(TAG, "V4_offlineKey: waiting while playing for " + playTime);
+            mOnPlaybackCompleted.waitForSignal(playTime);
+            mPlayer.skipToNext();
+            mOnPlaylistCompleted.waitForSignal(playTime);
+        }
 
-                // but preparing the DRM every time with proper key request type
-                drmInfo = mPlayer.getDrmInfo(dsd);
-                if (drmInfo != null) {
-                    if (keyRequestRound) {
-                        // asking for offline keys
-                        setupDrm(dsd, drmInfo, true /* prepareDrm */,
-                                 true /* synchronousNetworking */, MediaDrm.KEY_TYPE_OFFLINE);
-                    } else if (restoreRound) {
-                        setupDrmRestore(dsd, drmInfo, true /* prepareDrm */);
-                    } else {
-                        fail("preparePlayer: unexpected round " + round);
-                    }
-                    Log.v(TAG, "preparePlayer: setupDrm done!");
-                }
-
-            } catch (IOException e) {
-                e.printStackTrace();
-                throw new PrepareFailedException();
-            }
-
-            Log.v(TAG, "playLoadedVideo: play()");
-            mPlayer.play();
-            if (!mAudioOnly) {
-                mOnVideoSizeChangedCalled.waitForSignal();
-            }
-            mPlayer.setPlayerVolume(volume);
-
-            // waiting to complete
-            if (playTime == 0) {
-                Log.v(TAG, "playLoadedVideo: waiting for playback completion");
-                mOnPlaybackCompleted.waitForSignal();
-            } else {
-                Log.v(TAG, "playLoadedVideo: waiting while playing for " + playTime);
-                mOnPlaybackCompleted.waitForSignal(playTime);
-            }
-
-            try {
-                if (drmInfo != null) {
-                    if (restoreRound) {
-                        // releasing the offline key
-                        setupDrm(dsd, null /* drmInfo */, false /* prepareDrm */,
-                                 true /* synchronousNetworking */, MediaDrm.KEY_TYPE_RELEASE);
-                        Log.v(TAG, "playLoadedVideo: released offline keys");
-                    }
-
-                    Log.v(TAG, "playLoadedVideo: releaseDrm");
-                    mPlayer.releaseDrm(dsd);
-                }
-            } catch (Exception e) {
-                e.printStackTrace();
-                throw new PrepareFailedException();
-            }
-
-            if (keyRequestRound) {
-                mOnPreparedCalled.reset();
-                mOnVideoSizeChangedCalled.reset();
-                mOnPlaybackCompleted.reset();
-                final int sleepBetweenRounds = 1000;
-                Thread.sleep(sleepBetweenRounds);
-
-                Log.v(TAG, "playLoadedVideo: reset");
-                mPlayer.reset();
-            }
-        }  // for
+        mPlayer.close();
+        // TODO: release the offline key
     }
 
     // Converts a BMFF PSSH initData to a raw cenc initData
@@ -870,7 +867,7 @@
 
             // diverging from GTS
             byte[][] clearKeys = new byte[][] { CLEAR_KEY_CENC };
-            byte[] response = createKeysResponse(request, clearKeys);
+            byte[] response = createKeysResponse(request, clearKeys, keyType);
 
             // null is returned when the response is for a streaming or release request.
             byte[] keySetId = mPlayer.provideDrmKeyResponse(
@@ -1001,22 +998,29 @@
      *
      * @return JSON Web Key string.
      */
-    private String createJsonWebKeySet(Vector<String> keyIds, Vector<String> keys) {
+    private String createJsonWebKeySet(Vector<String> keyIds, Vector<String> keys, int keyType) {
         String jwkSet = "{\"keys\":[";
         for (int i = 0; i < keyIds.size(); ++i) {
             String id = new String(keyIds.get(i).getBytes(Charset.forName("UTF-8")));
             String key = new String(keys.get(i).getBytes(Charset.forName("UTF-8")));
 
-            jwkSet += "{\"kty\":\"oct\",\"kid\":\"" + id + "\",\"k\":\"" + key + "\"}";
+            jwkSet += "{\"kty\":\"oct\",\"kid\":\"" + id +
+                    "\",\"k\":\"" + key + "\"}";
         }
-        jwkSet += "]}";
+        jwkSet += "], \"type\":";
+        if (keyType == MediaDrm.KEY_TYPE_OFFLINE || keyType == MediaDrm.KEY_TYPE_RELEASE) {
+            jwkSet += "\"persistent-license\" }";
+        } else {
+            jwkSet += "\"temporary\" }";
+        }
         return jwkSet;
     }
 
     /**
      * Retrieves clear key ids from KeyRequest and creates the response in place.
      */
-    private byte[] createKeysResponse(MediaDrm.KeyRequest keyRequest, byte[][] clearKeys) {
+    private byte[] createKeysResponse(MediaDrm.KeyRequest keyRequest, byte[][] clearKeys,
+            int keyType) {
 
         Vector<String> keyIds = new Vector<String>();
         if (0 == getKeyIds(keyRequest.getData(), keyIds)) {
@@ -1025,20 +1029,20 @@
         }
 
         if (clearKeys.length != keyIds.size()) {
-            Log.e(TAG, "Mismatch number of key ids and keys: ids="
-                    + keyIds.size() + ", keys=" + clearKeys.length);
+            Log.e(TAG, "Mismatch number of key ids and keys: ids=" + keyIds.size() + ", keys="
+                    + clearKeys.length);
             return null;
         }
 
         // Base64 encodes clearkeys. Keys are known to the application.
         Vector<String> keys = new Vector<String>();
         for (int i = 0; i < clearKeys.length; ++i) {
-            String clearKey = Base64.encodeToString(clearKeys[i],
-                    Base64.NO_PADDING | Base64.NO_WRAP);
+            String clearKey =
+                    Base64.encodeToString(clearKeys[i], Base64.NO_PADDING | Base64.NO_WRAP);
             keys.add(clearKey);
         }
 
-        String jwkSet = createJsonWebKeySet(keyIds, keys);
+        String jwkSet = createJsonWebKeySet(keyIds, keys, keyType);
         byte[] jsonResponse = jwkSet.getBytes(Charset.forName("UTF-8"));
 
         return jsonResponse;
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayer2Test.java b/tests/tests/media/src/android/media/cts/MediaPlayer2Test.java
index 3c780ca..da4d28c 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayer2Test.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayer2Test.java
@@ -41,7 +41,6 @@
 import android.media.SubtitleData;
 import android.media.SyncParams;
 import android.media.TimedText;
-import android.media.VideoSize;
 import android.media.audiofx.AudioEffect;
 import android.media.audiofx.Visualizer;
 import android.media.cts.TestUtils.Monitor;
@@ -59,6 +58,7 @@
 import android.platform.test.annotations.RequiresDevice;
 import android.util.Log;
 import android.util.Pair;
+import android.util.Size;
 import android.webkit.cts.CtsTestServer;
 
 import com.android.compatibility.common.util.MediaUtils;
@@ -2138,7 +2138,7 @@
         mOnCompletionCalled.reset();
         MediaPlayer2.EventCallback ecb = new MediaPlayer2.EventCallback() {
             @Override
-            public void onVideoSizeChanged(MediaPlayer2 mp, DataSourceDesc dsd, VideoSize size) {
+            public void onVideoSizeChanged(MediaPlayer2 mp, DataSourceDesc dsd, Size size) {
                 mOnVideoSizeChangedCalled.signal();
             }
 
@@ -2474,7 +2474,7 @@
         Monitor mOnVideoSizeChangedCalled = new Monitor();
         MediaPlayer2.EventCallback ecb = new MediaPlayer2.EventCallback() {
             @Override
-            public void onVideoSizeChanged(MediaPlayer2 mp, DataSourceDesc dsd, VideoSize size) {
+            public void onVideoSizeChanged(MediaPlayer2 mp, DataSourceDesc dsd, Size size) {
                 if (size.getWidth() > 0 && size.getHeight() > 0) {
                     mOnVideoSizeChangedCalled.signal();
                 }
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayer2TestBase.java b/tests/tests/media/src/android/media/cts/MediaPlayer2TestBase.java
index 6f88364..cc44db6 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayer2TestBase.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayer2TestBase.java
@@ -29,13 +29,13 @@
 import android.media.SubtitleData;
 import android.media.TimedMetaData;
 import android.media.TimedText;
-import android.media.VideoSize;
 import android.media.cts.TestUtils.Monitor;
 import android.net.Uri;
 import android.os.ParcelFileDescriptor;
 import android.os.PersistableBundle;
 import android.test.ActivityInstrumentationTestCase2;
 import android.view.SurfaceHolder;
+import android.util.Size;
 
 import com.android.compatibility.common.util.MediaUtils;
 
@@ -250,7 +250,7 @@
             List<MediaPlayer2.EventCallback> ecbs) {
         mp.registerEventCallback(mExecutor, new MediaPlayer2.EventCallback() {
             @Override
-            public void onVideoSizeChanged(MediaPlayer2 mp, DataSourceDesc dsd, VideoSize size) {
+            public void onVideoSizeChanged(MediaPlayer2 mp, DataSourceDesc dsd, Size size) {
                 synchronized (cbLock) {
                     for (MediaPlayer2.EventCallback ecb : ecbs) {
                         ecb.onVideoSizeChanged(mp, dsd, size);
@@ -259,15 +259,6 @@
             }
 
             @Override
-            public void onTimedText(MediaPlayer2 mp, DataSourceDesc dsd, TimedText text) {
-                synchronized (cbLock) {
-                    for (MediaPlayer2.EventCallback ecb : ecbs) {
-                        ecb.onTimedText(mp, dsd, text);
-                    }
-                }
-            }
-
-            @Override
             public void onTimedMetaDataAvailable(MediaPlayer2 mp, DataSourceDesc dsd,
                     TimedMetaData data) {
                 synchronized (cbLock) {
@@ -462,7 +453,7 @@
         synchronized (mEventCbLock) {
             mEventCallbacks.add(new MediaPlayer2.EventCallback() {
                 @Override
-                public void onVideoSizeChanged(MediaPlayer2 mp, DataSourceDesc dsd, VideoSize size) {
+                public void onVideoSizeChanged(MediaPlayer2 mp, DataSourceDesc dsd, Size size) {
                     if (size.getWidth() == 0 && size.getHeight() == 0) {
                         // A size of 0x0 can be sent initially one time when using NuPlayer.
                         assertFalse(mOnVideoSizeChangedCalled.isSignalled());
diff --git a/tests/tests/media/src/android/media/cts/MediaSession2Test.java b/tests/tests/media/src/android/media/cts/MediaSession2Test.java
index 9738f65..bfcc2d3 100644
--- a/tests/tests/media/src/android/media/cts/MediaSession2Test.java
+++ b/tests/tests/media/src/android/media/cts/MediaSession2Test.java
@@ -21,15 +21,19 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
+import android.app.PendingIntent;
 import android.content.Context;
+import android.content.Intent;
 import android.media.MediaController2;
 import android.media.MediaSession2;
 import android.media.Session2Command;
 import android.media.Session2CommandGroup;
 import android.media.Session2Token;
+import android.media.session.MediaSessionManager;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.HandlerThread;
+import android.os.Parcel;
 import android.os.Process;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
@@ -120,6 +124,19 @@
     }
 
     @Test
+    public void testBuilder_setSessionActivity() {
+        Intent intent = new Intent(Intent.ACTION_MAIN);
+        PendingIntent pendingIntent = PendingIntent.getActivity(
+                mContext, 0 /* requestCode */, intent, 0 /* flags */);
+        try (MediaSession2 session = new MediaSession2.Builder(mContext)
+                .setSessionActivity(pendingIntent)
+                .build()) {
+            // Note: The pendingIntent is set but is never used inside of MediaSession2.
+            // TODO: If getter is created, put assertEquals() here.
+        }
+    }
+
+    @Test
     public void testBuilder_createSessionWithoutId() {
         try (MediaSession2 session = new MediaSession2.Builder(mContext).build()) {
             assertEquals("", session.getSessionId());
@@ -148,6 +165,83 @@
             assertEquals(mContext.getPackageName(), token.getPackageName());
             assertNull(token.getServiceName());
             assertEquals(Session2Token.TYPE_SESSION, token.getType());
+            assertEquals(0, token.describeContents());
+        }
+    }
+
+    @Test
+    public void testSession2Token_writeToParcel() {
+        try (MediaSession2 session = new MediaSession2.Builder(mContext).build()) {
+            Session2Token token = session.getSessionToken();
+
+            Parcel parcel = Parcel.obtain();
+            token.writeToParcel(parcel, 0 /* flags */);
+            parcel.setDataPosition(0);
+            Session2Token tokenOut = Session2Token.CREATOR.createFromParcel(parcel);
+
+            assertEquals(Process.myUid(), tokenOut.getUid());
+            assertEquals(mContext.getPackageName(), tokenOut.getPackageName());
+            assertNull(tokenOut.getServiceName());
+            assertEquals(Session2Token.TYPE_SESSION, tokenOut.getType());
+
+            parcel.recycle();
+        }
+    }
+
+    @Test
+    public void testBroadcastSessionCommand() throws Exception {
+        Session2Callback sessionCallback = new Session2Callback();
+
+        String commandStr = "test_command";
+        Session2Command command = new Session2Command(commandStr, null);
+
+        int resultCode = 100;
+        Session2Command.Result commandResult = new Session2Command.Result(resultCode, null);
+
+        try (MediaSession2 session = new MediaSession2.Builder(mContext)
+                .setSessionCallback(sHandlerExecutor, sessionCallback)
+                .build()) {
+
+            // 1. Create two controllers with each latch.
+            final CountDownLatch latch1 = new CountDownLatch(1);
+            Controller2Callback callback1 = new Controller2Callback() {
+                @Override
+                public Session2Command.Result onSessionCommand(MediaController2 controller,
+                        Session2Command command, Bundle args) {
+                    if (commandStr.equals(command.getCustomCommand())
+                            && command.getExtras() == null) {
+                        latch1.countDown();
+                    }
+                    return commandResult;
+                }
+            };
+            MediaController2 controller1 = new MediaController2(
+                    mContext, session.getSessionToken(), sHandlerExecutor, callback1);
+
+            final CountDownLatch latch2 = new CountDownLatch(1);
+            Controller2Callback callback2 = new Controller2Callback() {
+                @Override
+                public Session2Command.Result onSessionCommand(MediaController2 controller,
+                        Session2Command command, Bundle args) {
+                    if (commandStr.equals(command.getCustomCommand())
+                            && command.getExtras() == null) {
+                        latch2.countDown();
+                    }
+                    return commandResult;
+                }
+            };
+            MediaController2 controller2 = new MediaController2(
+                    mContext, session.getSessionToken(), sHandlerExecutor, callback2);
+
+            // 2. Wait until all the controllers are connected.
+            assertTrue(callback1.awaitOnConnected(WAIT_TIME_MS));
+            assertTrue(callback2.awaitOnConnected(WAIT_TIME_MS));
+
+            // 3. Call MediaSession2#broadcastSessionCommand() and check both controller's
+            // onSessionCommand is called.
+            session.broadcastSessionCommand(command, null);
+            assertTrue(latch1.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
+            assertTrue(latch2.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
         }
     }
 
@@ -166,6 +260,13 @@
             assertEquals(session, sessionCallback.mSession);
             MediaSession2.ControllerInfo controllerInfo = sessionCallback.mController;
 
+            // Check whether the controllerInfo is the right one.
+            assertEquals(mContext.getPackageName(), controllerInfo.getPackageName());
+            MediaSessionManager.RemoteUserInfo remoteUserInfo = controllerInfo.getRemoteUserInfo();
+            assertEquals(Process.myPid(), remoteUserInfo.getPid());
+            assertEquals(Process.myUid(), remoteUserInfo.getUid());
+            assertEquals(mContext.getPackageName(), remoteUserInfo.getPackageName());
+
             // Test onDisconnect
             controller.close();
             assertTrue(controllerCallback.awaitOnDisconnected(WAIT_TIME_MS));
@@ -279,6 +380,7 @@
                 .setSessionCallback(sHandlerExecutor, sessionCallback)
                 .build()) {
             session.setPlaybackActive(testInitialPlaybackActive);
+            assertEquals(testInitialPlaybackActive, session.isPlaybackActive());
 
             Controller2Callback controllerCallback = new Controller2Callback();
             MediaController2 controller = new MediaController2(mContext, session.getSessionToken(),
@@ -291,6 +393,7 @@
 
             // Change playback active change and wait for changes
             session.setPlaybackActive(testPlaybackActive);
+            assertEquals(testPlaybackActive, session.isPlaybackActive());
             assertTrue(controllerCallback.awaitOnPlaybackActiveChanged(WAIT_TIME_MS));
 
             assertEquals(testPlaybackActive, controllerCallback.getNotifiedPlaybackActive());
diff --git a/tests/tests/media/src/android/media/cts/MediaSessionManagerTest.java b/tests/tests/media/src/android/media/cts/MediaSessionManagerTest.java
index 88d8264..024d74f 100644
--- a/tests/tests/media/src/android/media/cts/MediaSessionManagerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaSessionManagerTest.java
@@ -274,15 +274,29 @@
         }
     }
 
-    public void testGetSession2Tokens() {
+    public void testGetSession2Tokens() throws Exception {
         final Context context = getInstrumentation().getTargetContext();
         Handler handler = createHandler();
+        Executor handlerExecutor = (runnable) -> {
+            if (handler != null) {
+                handler.post(() -> {
+                    runnable.run();
+                });
+            }
+        };
 
-        MediaSession2.SessionCallback sessionCallback = new MediaSession2.SessionCallback() {};
+        Session2TokenListener listener = new Session2TokenListener();
+        mSessionManager.addOnSession2TokensChangedListener(listener, handler);
+
+        Session2Callback sessionCallback = new Session2Callback();
         try (MediaSession2 session = new MediaSession2.Builder(context)
-                .setSessionCallback(new HandlerExecutor(handler.getLooper()), sessionCallback)
+                .setSessionCallback(handlerExecutor, sessionCallback)
                 .build()) {
+            assertTrue(sessionCallback.mCountDownLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+            assertTrue(listener.mCountDownLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+
             Session2Token currentToken = session.getSessionToken();
+            assertTrue(listContainsToken(listener.mTokens, currentToken));
             assertTrue(listContainsToken(mSessionManager.getSession2Tokens(), currentToken));
         }
     }
@@ -290,13 +304,20 @@
     public void testAddAndRemoveSession2TokensListener() throws Exception {
         final Context context = getInstrumentation().getTargetContext();
         Handler handler = createHandler();
+        Executor handlerExecutor = (runnable) -> {
+            if (handler != null) {
+                handler.post(() -> {
+                    runnable.run();
+                });
+            }
+        };
 
         Session2TokenListener listener1 = new Session2TokenListener();
         mSessionManager.addOnSession2TokensChangedListener(listener1, handler);
 
-        MediaSession2.SessionCallback sessionCallback = new MediaSession2.SessionCallback() {};
+        Session2Callback sessionCallback = new Session2Callback();
         try (MediaSession2 session = new MediaSession2.Builder(context)
-                .setSessionCallback(new HandlerExecutor(handler.getLooper()), sessionCallback)
+                .setSessionCallback(handlerExecutor, sessionCallback)
                 .build()) {
             assertTrue(listener1.mCountDownLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
             Session2Token currentToken = session.getSessionToken();
@@ -314,43 +335,6 @@
         }
     }
 
-    public void testNotifySession2Created_withDestroyedToken_shouldThrowIAE() {
-        final Context context = getInstrumentation().getTargetContext();
-
-        MediaSession2 session = new MediaSession2.Builder(context)
-                .setSessionCallback(new HandlerExecutor(createHandler().getLooper()),
-                        new MediaSession2.SessionCallback() {})
-                .build();
-        session.close();
-        Session2Token destroyedToken = session.getSessionToken();
-
-        try {
-            mSessionManager.notifySession2Created(destroyedToken);
-            fail("notifySession2Created should throw IAE");
-        } catch (IllegalArgumentException ex) {
-            // Expected.
-        }
-    }
-
-    public void testNotifySession2Destroyed_withLiveToken_shouldThrowIAE() {
-        final Context context = getInstrumentation().getTargetContext();
-
-        MediaSession2 session = new MediaSession2.Builder(context)
-                .setSessionCallback(new HandlerExecutor(createHandler().getLooper()),
-                        new MediaSession2.SessionCallback() {})
-                .build();
-        Session2Token liveToken = session.getSessionToken();
-
-        try {
-            mSessionManager.notifySession2Destroyed(liveToken);
-            fail("notifySession2Destroyed should throw IAE");
-        } catch (IllegalArgumentException ex) {
-            // Expected.
-        } finally {
-            session.close();
-        }
-    }
-
     private boolean listContainsToken(List<Session2Token> tokens, Session2Token token) {
         for (int i = 0; i < tokens.size(); i++) {
             if (tokens.get(i).equals(token)) {
@@ -437,6 +421,21 @@
         }
     }
 
+    private class Session2Callback extends MediaSession2.SessionCallback {
+        private CountDownLatch mCountDownLatch;
+
+        private Session2Callback() {
+            mCountDownLatch = new CountDownLatch(1);
+        }
+
+        @Override
+        public Session2CommandGroup onConnect(MediaSession2 session,
+                MediaSession2.ControllerInfo controller) {
+            mCountDownLatch.countDown();
+            return new Session2CommandGroup.Builder().build();
+        }
+    }
+
     private class Session2TokenListener implements
             MediaSessionManager.OnSession2TokensChangedListener {
         private CountDownLatch mCountDownLatch;
diff --git a/tests/tests/multiuser/AndroidTest.xml b/tests/tests/multiuser/AndroidTest.xml
index 595fcd5..8edf9d6 100644
--- a/tests/tests/multiuser/AndroidTest.xml
+++ b/tests/tests/multiuser/AndroidTest.xml
@@ -18,6 +18,7 @@
     <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="framework" />
     <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
         <option name="test-file-name" value="CtsMultiUserTestCases.apk" />
diff --git a/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java
index 0337119..4297a73 100644
--- a/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java
+++ b/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java
@@ -872,8 +872,8 @@
      * Verify that the {@link android.Manifest.permission#NETWORK_SETTINGS} permission is
      * never held by any package.
      * <p>
-     * Only Settings, SysUi and shell apps should <em>ever</em> attempt to acquire this
-     * permission, since it would give those apps extremely broad access to connectivity
+     * Only Settings, SysUi, NetworkStack and shell apps should <em>ever</em> attempt to acquire
+     * this permission, since it would give those apps extremely broad access to connectivity
      * functionality.  The permission is intended to be granted to only those apps with direct user
      * access and no others.
      */
@@ -886,6 +886,7 @@
         allowedUIDs.add(Process.SYSTEM_UID);
         allowedUIDs.add(Process.SHELL_UID);
         allowedUIDs.add(Process.PHONE_UID);
+        allowedUIDs.add(Process.NETWORK_STACK_UID);
 
         // only quick settings is allowed to bind to the BIND_QUICK_SETTINGS_TILE permission, using
         // this fact to determined allowed package name for sysui
diff --git a/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java b/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
index 7661585..dd7ad38 100644
--- a/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
@@ -321,6 +321,33 @@
         assertFileOwnedByGroup(f, "net_bw_stats");
     }
 
+    private static List<String> procNetFiles = Arrays.asList("anycast6", "arp", "arp_tables_matches",
+            "arp_tables_names", "arp_tables_targets", "dev", "dev_mcast", "fib_trie", "fib_triestat",
+            "hci", "icmp", "icmp6", "if_inet6", "igmp", "igmp6", "ip6_flowlabel",
+            "ip6_tables_matches", "ip6_tables_names", "ip6_tables_targets", "ip_tables_matches",
+            "ip_tables_names", "ip_tables_targets", "ipv6_route", "l2cap", "mcfilter", "mcfilter6",
+            "netlink", "netstat", "nf_conntrack", "nf_conntrack_expect", "packet", "pfkey", "pnp",
+            "pppoe", "pppol2tp", "protocols", "psched", "ptype", "raw", "raw6", "route", "rt6_stats",
+            "rt_cache", "sco", "snmp", "snmp6", "sockstat", "sockstat6", "softnet_stat", "tcp",
+            "tcp6", "udp", "udp6", "udplite", "udplite6", "unix", "wireless", "xfrm_stat");
+
+    private static void procNetSane(String path) {
+        File f = new File(path);
+        assertFalse(f.canRead());
+        assertFalse(f.canWrite());
+        assertFalse(f.canExecute());
+        assertFileOwnedBy(f, "root");
+        assertFileOwnedByGroup(f, "root");
+    }
+
+    @MediumTest
+    @Test
+    public void testProcNetSane() throws Exception {
+        for (String file : procNetFiles) {
+            procNetSane("/proc/net/" + file);
+        }
+    }
+
     private static int readInt(File f) throws FileNotFoundException {
         try (Scanner s = new Scanner(f)) {
             return s.nextInt();
diff --git a/tests/tests/permission/src/android/permission/cts/LocationAccessCheckTest.java b/tests/tests/permission/src/android/permission/cts/LocationAccessCheckTest.java
index bdd909b..50e695e 100644
--- a/tests/tests/permission/src/android/permission/cts/LocationAccessCheckTest.java
+++ b/tests/tests/permission/src/android/permission/cts/LocationAccessCheckTest.java
@@ -22,6 +22,7 @@
 import static android.content.Context.BIND_AUTO_CREATE;
 import static android.content.Intent.ACTION_BOOT_COMPLETED;
 import static android.location.Criteria.ACCURACY_FINE;
+import static android.provider.Settings.RESET_MODE_PACKAGE_DEFAULTS;
 import static android.provider.Settings.Secure.LOCATION_ACCESS_CHECK_DELAY_MILLIS;
 import static android.provider.Settings.Secure.LOCATION_ACCESS_CHECK_INTERVAL_MILLIS;
 
@@ -52,6 +53,8 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.ParcelFileDescriptor;
+import android.provider.DeviceConfig;
+import android.provider.DeviceConfig.Privacy;
 import android.provider.Settings;
 import android.service.notification.NotificationListenerService;
 import android.service.notification.StatusBarNotification;
@@ -65,6 +68,7 @@
 import com.android.server.job.nano.JobSchedulerServiceDumpProto;
 import com.android.server.job.nano.JobSchedulerServiceDumpProto.RegisteredJob;
 
+import org.junit.After;
 import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.BeforeClass;
@@ -341,6 +345,15 @@
     }
 
     /**
+     * Enable location access check
+     */
+    @Before
+    public void enableLocationAccessCheck() {
+        runWithShellPermissionIdentity(() -> DeviceConfig.setProperty(Privacy.NAMESPACE,
+                Privacy.PROPERTY_LOCATION_ACCESS_CHECK_ENABLED, "true", false));
+    }
+
+    /**
      * Make sure fine location can be accessed at all.
      */
     @Before
@@ -448,6 +461,15 @@
         resetPermissionController();
     }
 
+    /**
+     * Reset location access check
+     */
+    @After
+    public void resetPrivacyConfig() {
+        runWithShellPermissionIdentity(
+                () -> DeviceConfig.resetToDefaults(RESET_MODE_PACKAGE_DEFAULTS, Privacy.NAMESPACE));
+    }
+
     @Test
     public void notificationIsShown() throws Throwable {
         accessLocation();
diff --git a/tests/tests/permission/src/android/permission/cts/ShellPermissionTest.java b/tests/tests/permission/src/android/permission/cts/ShellPermissionTest.java
new file mode 100644
index 0000000..cf49f50
--- /dev/null
+++ b/tests/tests/permission/src/android/permission/cts/ShellPermissionTest.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2019 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.permission.cts;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+
+import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.UsesPermissionInfo;
+import android.os.Process;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.Log;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Tests that shell has acceptable permissions.
+ */
+@RunWith(AndroidJUnit4.class)
+public class ShellPermissionTest {
+    private static final String LOG_TAG = ShellPermissionTest.class.getSimpleName();
+
+    /** Permissions that shell is NOT permitted to have. */
+    private static final String[] BLACKLISTED_PERMISSIONS = {
+            "android.permission.MANAGE_USERS",
+    };
+
+    private static final Context sContext = InstrumentationRegistry.getTargetContext();
+
+    /**
+     * Verify that the shell uid does not have any of the permissions listed in
+     *   {@link #BLACKLISTED_PERMISSIONS}.
+     */
+    @Test
+    public void testBlacklistedPermissions() throws Exception {
+        final Set<String> blacklist = new HashSet<>(Arrays.asList(BLACKLISTED_PERMISSIONS));
+
+        final PackageManager pm = sContext.getPackageManager();
+        final String[] pkgs = pm.getPackagesForUid(Process.SHELL_UID);
+        assertNotNull("No SHELL packages were found", pkgs);
+        assertNotEquals("SHELL package list had 0 size", 0, pkgs.length);
+        String pkg = pkgs[0];
+
+        final PackageInfo packageInfo = pm.getPackageInfo(pkg, PackageManager.GET_PERMISSIONS);
+        assertNotNull("No permissions found for " + pkg, packageInfo.usesPermissions);
+
+        for (UsesPermissionInfo permInfo : packageInfo.usesPermissions) {
+            final String permission = permInfo.getPermission();
+            Log.d(LOG_TAG, "SHELL as " + pkg + " uses permission " + permission);
+            assertFalse("SHELL as " + pkg + " contains the illegal permission " + permission,
+                    blacklist.contains(permission));
+        }
+    }
+}
diff --git a/tests/tests/permission2/res/raw/android_manifest.xml b/tests/tests/permission2/res/raw/android_manifest.xml
index 17bc81d..836214c 100644
--- a/tests/tests/permission2/res/raw/android_manifest.xml
+++ b/tests/tests/permission2/res/raw/android_manifest.xml
@@ -1865,6 +1865,10 @@
     <permission android:name="android.permission.HARDWARE_TEST"
         android:protectionLevel="signature" />
 
+    <!-- @hide Allows an application to manage DynamicAndroid image -->
+    <permission android:name="android.permission.MANAGE_DYNAMIC_ANDROID"
+        android:protectionLevel="signature" />
+
     <!-- @SystemApi Allows access to Broadcast Radio
          @hide This is not a third-party API (intended for system apps).-->
     <permission android:name="android.permission.ACCESS_BROADCAST_RADIO"
@@ -2796,6 +2800,20 @@
     <permission android:name="android.permission.SIGNAL_PERSISTENT_PROCESSES"
         android:protectionLevel="signature|privileged|development" />
 
+    <!-- @hide @SystemApi @TestApi
+         Allow an application to approve incident and bug reports to be
+         shared off-device.  There can be only one application installed on the
+         device with this permission, and since this is a privileged permission, it
+         must be in priv-app.
+        <p>Not for use by third-party applications. -->
+    <permission android:name="android.permission.APPROVE_INCIDENT_REPORTS"
+        android:protectionLevel="signature|incidentReportApprover" />
+
+    <!-- @hide Allow an application to approve an incident or bug report approval from
+        the system. -->
+    <permission android:name="android.permission.REQUEST_INCIDENT_REPORT_APPROVAL"
+        android:protectionLevel="signature|privileged" />
+
     <!-- ==================================== -->
     <!-- Private permissions                  -->
     <!-- ==================================== -->
@@ -4314,7 +4332,7 @@
     <!-- @SystemApi Allows an application to manage the app predictions service.
          @hide  <p>Not for use by third-party applications.</p> -->
     <permission android:name="android.permission.MANAGE_APP_PREDICTIONS"
-         android:protectionLevel="signature" />
+         android:protectionLevel="signature|appPredictor" />
 
     <!-- Allows an app to set the theme overlay in /vendor/overlay
          being used.
@@ -4390,11 +4408,11 @@
         {@link android.provider.Telephony.Intents#ACTION_DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL}
         broadcast -->
     <permission android:name="android.permission.MONITOR_DEFAULT_SMS_PACKAGE"
-        android:protectionLevel="signature" />
+        android:protectionLevel="signature|privileged" />
 
-    <!-- A subclass of {@link android.app.SmsAppService} must be protected with this permission. -->
-    <permission android:name="android.permission.BIND_SMS_APP_SERVICE"
-        android:protectionLevel="signature" />
+    <!-- A subclass of {@link android.service.carrier.CarrierMessagingClientService} must be protected with this permission. -->
+    <permission android:name="android.permission.BIND_CARRIER_MESSAGING_CLIENT_SERVICE"
+                android:protectionLevel="signature" />
 
     <!-- @hide Permission that allows background clipboard access.
          <p>Not for use by third-party applications. -->
diff --git a/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java b/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java
index b0ba8fa..96ab8dc 100644
--- a/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java
+++ b/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java
@@ -321,9 +321,15 @@
                 case "configurator": {
                     protectionLevel |= PermissionInfo.PROTECTION_FLAG_CONFIGURATOR;
                 } break;
+                case "incidentReportApprover": {
+                    protectionLevel |= PermissionInfo.PROTECTION_FLAG_INCIDENT_REPORT_APPROVER;
+                } break;
                 case "documenter": {
                     protectionLevel |= PermissionInfo.PROTECTION_FLAG_DOCUMENTER;
                 } break;
+                case "appPredictor": {
+                    protectionLevel |= PermissionInfo.PROTECTION_FLAG_APP_PREDICTOR;
+                } break;
                 case "instant": {
                     protectionLevel |= PermissionInfo.PROTECTION_FLAG_INSTANT;
                 } break;
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStoreTest.java b/tests/tests/provider/src/android/provider/cts/MediaStoreTest.java
index 6104f61..4f0850a 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStoreTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStoreTest.java
@@ -152,7 +152,7 @@
         final File file = new File(ProviderTestUtils.stageDir(mVolumeName),
                 "cts" + System.nanoTime() + ".jpg");
         ProviderTestUtils.stageFile(R.raw.volantis, file);
-        inside = ProviderTestUtils.scanFile(file);
+        inside = ProviderTestUtils.scanFile(file, true);
         outside = ProviderTestUtils.stageMedia(R.raw.volantis, mExternalImages);
 
         {
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_DownloadsTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_DownloadsTest.java
index f9a3372..de1b40a 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_DownloadsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_DownloadsTest.java
@@ -21,7 +21,6 @@
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.fail;
 
 import android.content.ContentResolver;
 import android.content.ContentUris;
@@ -29,7 +28,6 @@
 import android.content.Context;
 import android.database.ContentObserver;
 import android.database.Cursor;
-import android.media.MediaScannerConnection;
 import android.net.Uri;
 import android.os.Environment;
 import android.os.FileUtils;
@@ -59,7 +57,6 @@
 @RunWith(AndroidJUnit4.class)
 public class MediaStore_DownloadsTest {
     private static final String TAG = MediaStore_DownloadsTest.class.getSimpleName();
-    private static final long SCAN_TIMEOUT_MILLIS = 4000;
     private static final long NOTIFY_TIMEOUT_MILLIS = 4000;
 
     private Context mContext;
@@ -173,14 +170,14 @@
         final ContentValues updateValues = new ContentValues();
         updateValues.put(MediaStore.Files.FileColumns.MEDIA_TYPE,
                 MediaStore.Files.FileColumns.MEDIA_TYPE_AUDIO);
-        updateValues.put(Downloads.MIME_TYPE, "audio/3gp");
+        updateValues.put(Downloads.MIME_TYPE, "audio/3gpp");
         assertEquals(1, mContentResolver.update(publishUri, updateValues, null, null));
 
         try (Cursor cursor = mContentResolver.query(publishUri,
                 null, null, null, null)) {
             assertEquals(1, cursor.getCount());
             cursor.moveToNext();
-            assertEquals("audio/3gp",
+            assertEquals("audio/3gpp",
                     cursor.getString(cursor.getColumnIndex(Downloads.MIME_TYPE)));
             assertEquals(downloadUri.toString(),
                     cursor.getString(cursor.getColumnIndex(Downloads.DOWNLOAD_URI)));
@@ -293,7 +290,7 @@
     }
 
     private void verifyScannedDownload(File file) throws Exception {
-        final Uri mediaStoreUri = scanFile(file);
+        final Uri mediaStoreUri = ProviderTestUtils.scanFile(file, false);
         Log.e(TAG, "Scanned file " + file.getAbsolutePath() + ": " + mediaStoreUri);
         mAddedUris.add(mediaStoreUri);
         assertArrayEquals("File hashes should match for " + file + " and " + mediaStoreUri,
@@ -306,22 +303,4 @@
                 null, MediaStore.Downloads._ID + "=" + id, null, null);
         assertEquals(1, cursor.getCount());
     }
-
-    private Uri scanFile(File file) throws Exception {
-        final CountDownLatch latch = new CountDownLatch(1);
-        final Uri[] mediaStoreUris = new Uri[1];
-        MediaScannerConnection.scanFile(mContext,
-                new String[] {file.getAbsolutePath()},
-                null /* mimeType */,
-                (String path, Uri uri) -> {
-                    mediaStoreUris[0] = uri;
-                    latch.countDown();
-                });
-
-        if (!latch.await(SCAN_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)) {
-            fail("Timed out waiting for scanFile: " + file.getAbsolutePath());
-        }
-        assertNotNull("Failed to scan " + file.getAbsolutePath(), mediaStoreUris[0]);
-        return mediaStoreUris[0];
-    }
 }
diff --git a/tests/tests/provider/src/android/provider/cts/ProviderTestUtils.java b/tests/tests/provider/src/android/provider/cts/ProviderTestUtils.java
index 038291a..c5c43f4 100644
--- a/tests/tests/provider/src/android/provider/cts/ProviderTestUtils.java
+++ b/tests/tests/provider/src/android/provider/cts/ProviderTestUtils.java
@@ -225,14 +225,14 @@
         }
     }
 
-    static Uri scanFile(File file) throws Exception {
+    static Uri scanFile(File file, boolean originatedFromShell) throws Exception {
         final ContentResolver resolver = InstrumentationRegistry.getTargetContext()
                 .getContentResolver();
         try (ContentProviderClient cpc = resolver
                 .acquireContentProviderClient(MediaStore.AUTHORITY)) {
             final Bundle in = new Bundle();
             in.putParcelable(Intent.EXTRA_STREAM, Uri.fromFile(file));
-            in.putBoolean(Intent.EXTRA_LOCAL_ONLY, true);
+            in.putBoolean(MediaStore.EXTRA_ORIGINATED_FROM_SHELL, originatedFromShell);
             final Bundle out = cpc.call(MediaStore.AUTHORITY, MediaStore.SCAN_FILE_CALL, null, in);
             return out.getParcelable(Intent.EXTRA_STREAM);
         }
diff --git a/tests/tests/role/CtsRoleTestApp/AndroidManifest.xml b/tests/tests/role/CtsRoleTestApp/AndroidManifest.xml
index 370e111..03f9513 100644
--- a/tests/tests/role/CtsRoleTestApp/AndroidManifest.xml
+++ b/tests/tests/role/CtsRoleTestApp/AndroidManifest.xml
@@ -30,9 +30,11 @@
         <activity android:name=".DialerDialActivity">
             <intent-filter>
                 <action android:name="android.intent.action.DIAL" />
+                <category android:name="android.intent.category.DEFAULT"/>
             </intent-filter>
             <intent-filter>
                 <action android:name="android.intent.action.DIAL" />
+                <category android:name="android.intent.category.DEFAULT"/>
                 <data android:scheme="tel" />
             </intent-filter>
         </activity>
diff --git a/tests/tests/role/src/android/app/role/cts/RoleManagerTest.java b/tests/tests/role/src/android/app/role/cts/RoleManagerTest.java
index 9613c15..13caf39 100644
--- a/tests/tests/role/src/android/app/role/cts/RoleManagerTest.java
+++ b/tests/tests/role/src/android/app/role/cts/RoleManagerTest.java
@@ -206,7 +206,7 @@
         boolean[] successful = new boolean[1];
         CountDownLatch latch = new CountDownLatch(1);
         runWithShellPermissionIdentity(() -> sRoleManager.addRoleHolderAsUser(roleName,
-                packageName, user, executor, new RoleManagerCallback() {
+                packageName, 0, user, executor, new RoleManagerCallback() {
                     @Override
                     public void onSuccess() {
                         successful[0] = true;
@@ -229,7 +229,7 @@
         boolean[] successful = new boolean[1];
         CountDownLatch latch = new CountDownLatch(1);
         runWithShellPermissionIdentity(() -> sRoleManager.removeRoleHolderAsUser(roleName,
-                packageName, user, executor, new RoleManagerCallback() {
+                packageName, 0, user, executor, new RoleManagerCallback() {
                     @Override
                     public void onSuccess() {
                         successful[0] = true;
diff --git a/tests/tests/secure_element/access_control/AccessControlApp1/Android.mk b/tests/tests/secure_element/access_control/AccessControlApp1/Android.mk
index c9b40f4..9e7905c 100644
--- a/tests/tests/secure_element/access_control/AccessControlApp1/Android.mk
+++ b/tests/tests/secure_element/access_control/AccessControlApp1/Android.mk
@@ -32,7 +32,7 @@
 LOCAL_JAVA_LIBRARIES += android.test.runner
 LOCAL_JAVA_LIBRARIES += android.test.base
 # Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts-instant
 
 include $(BUILD_CTS_PACKAGE)
 
@@ -47,7 +47,7 @@
 LOCAL_BUILT_MODULE_STEM := package.apk
 # Make sure the build system doesn't try to resign the APK
 LOCAL_CERTIFICATE := PRESIGNED
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts-instant
 
 LOCAL_REPLACE_PREBUILT_APK_INSTALLED := $(LOCAL_PATH)/apk/signed-CtsSecureElementAccessControlTestCases1.apk
 
diff --git a/tests/tests/secure_element/access_control/AccessControlApp1/AndroidManifest.xml b/tests/tests/secure_element/access_control/AccessControlApp1/AndroidManifest.xml
index 87a7aa5..cf9e3e5 100644
--- a/tests/tests/secure_element/access_control/AccessControlApp1/AndroidManifest.xml
+++ b/tests/tests/secure_element/access_control/AccessControlApp1/AndroidManifest.xml
@@ -15,7 +15,8 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.omapi.accesscontrol1.cts">
+          package="android.omapi.accesscontrol1.cts"
+          android:targetSandboxVersion="2">
 
     <application>
         <uses-library android:name="android.test.runner"/>
diff --git a/tests/tests/secure_element/access_control/AccessControlApp1/AndroidTest.xml b/tests/tests/secure_element/access_control/AccessControlApp1/AndroidTest.xml
index 2330951..bff9d91 100644
--- a/tests/tests/secure_element/access_control/AccessControlApp1/AndroidTest.xml
+++ b/tests/tests/secure_element/access_control/AccessControlApp1/AndroidTest.xml
@@ -17,6 +17,8 @@
     <option name="test-suite-tag" value="cts"/>
     <option name="config-descriptor:metadata" key="component" value="systems"/>
     <option name="config-descriptor:metadata" key="token" value="SECURE_ELEMENT_SIM_CARD" />
+    <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
     <option name="not-shardable" value="true" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true"/>
diff --git a/tests/tests/secure_element/access_control/AccessControlApp1/apk/signed-CtsSecureElementAccessControlTestCases1.apk b/tests/tests/secure_element/access_control/AccessControlApp1/apk/signed-CtsSecureElementAccessControlTestCases1.apk
index 9f87b5a..28cb203 100644
--- a/tests/tests/secure_element/access_control/AccessControlApp1/apk/signed-CtsSecureElementAccessControlTestCases1.apk
+++ b/tests/tests/secure_element/access_control/AccessControlApp1/apk/signed-CtsSecureElementAccessControlTestCases1.apk
Binary files differ
diff --git a/tests/tests/secure_element/access_control/AccessControlApp2/Android.mk b/tests/tests/secure_element/access_control/AccessControlApp2/Android.mk
index eff645d..c46cc7a 100644
--- a/tests/tests/secure_element/access_control/AccessControlApp2/Android.mk
+++ b/tests/tests/secure_element/access_control/AccessControlApp2/Android.mk
@@ -32,7 +32,7 @@
 LOCAL_JAVA_LIBRARIES += android.test.runner
 LOCAL_JAVA_LIBRARIES += android.test.base
 # Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts-instant
 
 include $(BUILD_CTS_PACKAGE)
 
@@ -47,7 +47,7 @@
 LOCAL_BUILT_MODULE_STEM := package.apk
 # Make sure the build system doesn't try to resign the APK
 LOCAL_CERTIFICATE := PRESIGNED
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts-instant
 
 LOCAL_REPLACE_PREBUILT_APK_INSTALLED := $(LOCAL_PATH)/apk/signed-CtsSecureElementAccessControlTestCases2.apk
 
diff --git a/tests/tests/secure_element/access_control/AccessControlApp2/AndroidManifest.xml b/tests/tests/secure_element/access_control/AccessControlApp2/AndroidManifest.xml
index e92a577..1f1dc28 100644
--- a/tests/tests/secure_element/access_control/AccessControlApp2/AndroidManifest.xml
+++ b/tests/tests/secure_element/access_control/AccessControlApp2/AndroidManifest.xml
@@ -15,7 +15,8 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.omapi.accesscontrol2.cts">
+          package="android.omapi.accesscontrol2.cts"
+          android:targetSandboxVersion="2">
 
     <application>
         <uses-library android:name="android.test.runner"/>
diff --git a/tests/tests/secure_element/access_control/AccessControlApp2/AndroidTest.xml b/tests/tests/secure_element/access_control/AccessControlApp2/AndroidTest.xml
index dc67959..e6433f7 100644
--- a/tests/tests/secure_element/access_control/AccessControlApp2/AndroidTest.xml
+++ b/tests/tests/secure_element/access_control/AccessControlApp2/AndroidTest.xml
@@ -17,6 +17,8 @@
     <option name="test-suite-tag" value="cts"/>
     <option name="config-descriptor:metadata" key="component" value="systems"/>
     <option name="config-descriptor:metadata" key="token" value="SECURE_ELEMENT_SIM_CARD" />
+    <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
     <option name="not-shardable" value="true" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true"/>
diff --git a/tests/tests/secure_element/access_control/AccessControlApp2/apk/signed-CtsSecureElementAccessControlTestCases2.apk b/tests/tests/secure_element/access_control/AccessControlApp2/apk/signed-CtsSecureElementAccessControlTestCases2.apk
index 2557025..1769767 100644
--- a/tests/tests/secure_element/access_control/AccessControlApp2/apk/signed-CtsSecureElementAccessControlTestCases2.apk
+++ b/tests/tests/secure_element/access_control/AccessControlApp2/apk/signed-CtsSecureElementAccessControlTestCases2.apk
Binary files differ
diff --git a/tests/tests/secure_element/access_control/AccessControlApp3/Android.mk b/tests/tests/secure_element/access_control/AccessControlApp3/Android.mk
index 29e38f3..557d828 100644
--- a/tests/tests/secure_element/access_control/AccessControlApp3/Android.mk
+++ b/tests/tests/secure_element/access_control/AccessControlApp3/Android.mk
@@ -32,7 +32,7 @@
 LOCAL_JAVA_LIBRARIES += android.test.runner
 LOCAL_JAVA_LIBRARIES += android.test.base
 # Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts-instant
 
 include $(BUILD_CTS_PACKAGE)
 
@@ -47,7 +47,7 @@
 LOCAL_BUILT_MODULE_STEM := package.apk
 # Make sure the build system doesn't try to resign the APK
 LOCAL_CERTIFICATE := PRESIGNED
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts-instant
 
 LOCAL_REPLACE_PREBUILT_APK_INSTALLED := $(LOCAL_PATH)/apk/signed-CtsSecureElementAccessControlTestCases3.apk
 
diff --git a/tests/tests/secure_element/access_control/AccessControlApp3/AndroidManifest.xml b/tests/tests/secure_element/access_control/AccessControlApp3/AndroidManifest.xml
index dd6375c..b1c1e38 100644
--- a/tests/tests/secure_element/access_control/AccessControlApp3/AndroidManifest.xml
+++ b/tests/tests/secure_element/access_control/AccessControlApp3/AndroidManifest.xml
@@ -15,7 +15,8 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.omapi.accesscontrol3.cts">
+          package="android.omapi.accesscontrol3.cts"
+          android:targetSandboxVersion="2">
 
     <application>
         <uses-library android:name="android.test.runner"/>
diff --git a/tests/tests/secure_element/access_control/AccessControlApp3/AndroidTest.xml b/tests/tests/secure_element/access_control/AccessControlApp3/AndroidTest.xml
index ba27779..4cab33d 100644
--- a/tests/tests/secure_element/access_control/AccessControlApp3/AndroidTest.xml
+++ b/tests/tests/secure_element/access_control/AccessControlApp3/AndroidTest.xml
@@ -17,6 +17,8 @@
     <option name="test-suite-tag" value="cts"/>
     <option name="config-descriptor:metadata" key="component" value="systems"/>
     <option name="config-descriptor:metadata" key="token" value="SECURE_ELEMENT_SIM_CARD" />
+    <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
     <option name="not-shardable" value="true" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true"/>
diff --git a/tests/tests/secure_element/access_control/AccessControlApp3/apk/signed-CtsSecureElementAccessControlTestCases3.apk b/tests/tests/secure_element/access_control/AccessControlApp3/apk/signed-CtsSecureElementAccessControlTestCases3.apk
index 20e4a4c..ab07811 100644
--- a/tests/tests/secure_element/access_control/AccessControlApp3/apk/signed-CtsSecureElementAccessControlTestCases3.apk
+++ b/tests/tests/secure_element/access_control/AccessControlApp3/apk/signed-CtsSecureElementAccessControlTestCases3.apk
Binary files differ
diff --git a/tests/tests/secure_element/omapi/Android.mk b/tests/tests/secure_element/omapi/Android.mk
index 4378136..6187d16 100644
--- a/tests/tests/secure_element/omapi/Android.mk
+++ b/tests/tests/secure_element/omapi/Android.mk
@@ -35,6 +35,6 @@
 LOCAL_JAVA_LIBRARIES += android.test.base
 
 # Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts-instant
 
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/secure_element/omapi/AndroidManifest.xml b/tests/tests/secure_element/omapi/AndroidManifest.xml
index ce5ccc9..5e449b8 100644
--- a/tests/tests/secure_element/omapi/AndroidManifest.xml
+++ b/tests/tests/secure_element/omapi/AndroidManifest.xml
@@ -15,7 +15,8 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.omapi.cts">
+          package="android.omapi.cts"
+          android:targetSandboxVersion="2">
 
     <application>
         <uses-library android:name="android.test.runner"/>
diff --git a/tests/tests/secure_element/omapi/AndroidTest.xml b/tests/tests/secure_element/omapi/AndroidTest.xml
index 50e1b5f..0f18f70 100644
--- a/tests/tests/secure_element/omapi/AndroidTest.xml
+++ b/tests/tests/secure_element/omapi/AndroidTest.xml
@@ -17,6 +17,8 @@
     <option name="test-suite-tag" value="cts"/>
     <option name="config-descriptor:metadata" key="component" value="systems"/>
     <option name="config-descriptor:metadata" key="token" value="SECURE_ELEMENT_SIM_CARD" />
+    <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
     <option name="not-shardable" value="true" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true"/>
diff --git a/tests/tests/security/src/android/security/cts/MotionEventTest.java b/tests/tests/security/src/android/security/cts/MotionEventTest.java
index d36e420..cc8bb51 100644
--- a/tests/tests/security/src/android/security/cts/MotionEventTest.java
+++ b/tests/tests/security/src/android/security/cts/MotionEventTest.java
@@ -84,16 +84,17 @@
     public void testActionOutsideDoesNotContainedObscuredInformation() throws Throwable {
         enableAppOps();
         final OnTouchListener listener = new OnTouchListener();
+        final WindowManager wm = mActivity.getSystemService(WindowManager.class);
+        WindowManager.LayoutParams wmlp = new WindowManager.LayoutParams(
+                WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
+                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
+                        WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH |
+                        WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
+
         FutureTask<View> addViewTask = new FutureTask<>(() -> {
-            final WindowManager wm = mActivity.getSystemService(WindowManager.class);
             final Point size = new Point();
             wm.getDefaultDisplay().getSize(size);
 
-            WindowManager.LayoutParams wmlp = new WindowManager.LayoutParams(
-                    WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
-                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
-                    WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH |
-                    WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
             wmlp.width = size.x / 4;
             wmlp.height = size.y / 4;
             wmlp.gravity = Gravity.TOP | Gravity.LEFT;
@@ -127,6 +128,14 @@
         WidgetTestUtils.runOnMainAndLayoutSync(mActivityRule, view, null /*runnable*/,
                 true /*forceLayout*/);
 
+	// This ensures the window is visible, where the code above ensures
+        // the view is on screen.
+        mActivityRule.runOnUiThread(() -> {
+            // This will force WindowManager to relayout, ensuring the
+	    // transaction to show the window are sent to the graphics code.
+            wm.updateViewLayout(view, wmlp);
+        });
+
         FutureTask<Point> clickLocationTask = new FutureTask<>(() -> {
             final int[] viewLocation = new int[2];
             view.getLocationOnScreen(viewLocation);
diff --git a/tests/tests/simpleperf/AndroidTest.xml b/tests/tests/simpleperf/AndroidTest.xml
index d4f462d..ad94b98 100644
--- a/tests/tests/simpleperf/AndroidTest.xml
+++ b/tests/tests/simpleperf/AndroidTest.xml
@@ -27,7 +27,12 @@
     </target_preparer>
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
-        <option name="test-file-name" value="CtsSimpleperfDebugApp.apk" />
+        <option name="test-file-name" value="CtsSimpleperfDebuggableApp.apk" />
+        <option name="test-file-name" value="CtsSimpleperfProfileableApp.apk" />
+    </target_preparer>
+    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+        <option name="run-command" value="am start com.android.simpleperf.debuggable/.MainActivity" />
+        <option name="run-command" value="am start com.android.simpleperf.profileable/.MainActivity" />
     </target_preparer>
     <test class="com.android.tradefed.testtype.GTest" >
         <option name="native-test-device-path" value="/data/local/tmp" />
diff --git a/tests/tests/simpleperf/CtsSimpleperfDebugApp/com/android/simpleperf/EmptyTest.java b/tests/tests/simpleperf/CtsSimpleperfDebugApp/com/android/simpleperf/EmptyTest.java
deleted file mode 100644
index b4bee68..0000000
--- a/tests/tests/simpleperf/CtsSimpleperfDebugApp/com/android/simpleperf/EmptyTest.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.simpleperf;
-
-import android.test.AndroidTestCase;
-import android.util.Log;
-
-// This file is just to ensure that we have some code in the apk.
-public class EmptyTest extends AndroidTestCase {
-  private static final String TAG = "EmptyTest";
-
-  public void testEmpty() {
-    Log.i(TAG, "testEmpty()");
-  }
-}
diff --git a/tests/tests/simpleperf/CtsSimpleperfDebugApp/Android.mk b/tests/tests/simpleperf/CtsSimpleperfDebuggableApp/Android.mk
similarity index 87%
rename from tests/tests/simpleperf/CtsSimpleperfDebugApp/Android.mk
rename to tests/tests/simpleperf/CtsSimpleperfDebuggableApp/Android.mk
index 4f097a4..9b7821d 100644
--- a/tests/tests/simpleperf/CtsSimpleperfDebugApp/Android.mk
+++ b/tests/tests/simpleperf/CtsSimpleperfDebuggableApp/Android.mk
@@ -20,15 +20,11 @@
 
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
-
-LOCAL_JAVA_LIBRARIES := android.test.base.stubs
-
 LOCAL_SRC_FILES := $(call all-java-files-under, .)
 
 LOCAL_MANIFEST_FILE := AndroidManifest.xml
 
-LOCAL_PACKAGE_NAME := CtsSimpleperfDebugApp
+LOCAL_PACKAGE_NAME := CtsSimpleperfDebuggableApp
 
 LOCAL_SDK_VERSION := current
 
diff --git a/tests/tests/simpleperf/CtsSimpleperfDebugApp/AndroidManifest.xml b/tests/tests/simpleperf/CtsSimpleperfDebuggableApp/AndroidManifest.xml
similarity index 66%
rename from tests/tests/simpleperf/CtsSimpleperfDebugApp/AndroidManifest.xml
rename to tests/tests/simpleperf/CtsSimpleperfDebuggableApp/AndroidManifest.xml
index b3509c8..348c7b4 100644
--- a/tests/tests/simpleperf/CtsSimpleperfDebugApp/AndroidManifest.xml
+++ b/tests/tests/simpleperf/CtsSimpleperfDebuggableApp/AndroidManifest.xml
@@ -15,12 +15,16 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="com.android.simpleperf">
+        package="com.android.simpleperf.debuggable">
 
     <application android:debuggable="true">
-        <uses-library android:name="android.test.runner" />
+        <activity
+            android:label="simpleperf"
+            android:name="com.android.simpleperf.debuggable.MainActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
     </application>
-    <instrumentation
-        android:targetPackage="com.android.simpleperf"
-        android:name="android.support.test.runner.AndroidJUnitRunner" />
 </manifest>
\ No newline at end of file
diff --git a/tests/tests/simpleperf/CtsSimpleperfDebuggableApp/com/android/simpleperf/debuggable/MainActivity.java b/tests/tests/simpleperf/CtsSimpleperfDebuggableApp/com/android/simpleperf/debuggable/MainActivity.java
new file mode 100644
index 0000000..c1a48a9
--- /dev/null
+++ b/tests/tests/simpleperf/CtsSimpleperfDebuggableApp/com/android/simpleperf/debuggable/MainActivity.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.simpleperf.debuggable;
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.widget.TextView;
+
+public class MainActivity extends Activity {
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        TextView view = new TextView(this);
+        view.setText("MainActivity");
+        setContentView(view);
+
+        createBusyThread();
+    }
+
+    void createBusyThread() {
+        new Thread(new Runnable() {
+            volatile int counter = 0;
+
+            @Override
+            public void run() {
+                while (true) {
+                    for (int i = 0; i < 100000; i++) {
+                        counter++;
+                    }
+                    try {
+                        Thread.sleep(1);
+                    } catch (InterruptedException e) {
+                    }
+                }
+            }
+        }, "BusyThread").start();
+    }
+}
diff --git a/tests/tests/simpleperf/CtsSimpleperfDebugApp/Android.mk b/tests/tests/simpleperf/CtsSimpleperfProfileableApp/Android.mk
similarity index 87%
copy from tests/tests/simpleperf/CtsSimpleperfDebugApp/Android.mk
copy to tests/tests/simpleperf/CtsSimpleperfProfileableApp/Android.mk
index 4f097a4..6105f9d 100644
--- a/tests/tests/simpleperf/CtsSimpleperfDebugApp/Android.mk
+++ b/tests/tests/simpleperf/CtsSimpleperfProfileableApp/Android.mk
@@ -20,18 +20,16 @@
 
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
-
-LOCAL_JAVA_LIBRARIES := android.test.base.stubs
-
 LOCAL_SRC_FILES := $(call all-java-files-under, .)
 
 LOCAL_MANIFEST_FILE := AndroidManifest.xml
 
-LOCAL_PACKAGE_NAME := CtsSimpleperfDebugApp
+LOCAL_PACKAGE_NAME := CtsSimpleperfProfileableApp
 
 LOCAL_SDK_VERSION := current
 
+LOCAL_AAPT_FLAGS += --warn-manifest-validation
+
 LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
 
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/simpleperf/CtsSimpleperfDebugApp/AndroidManifest.xml b/tests/tests/simpleperf/CtsSimpleperfProfileableApp/AndroidManifest.xml
similarity index 61%
copy from tests/tests/simpleperf/CtsSimpleperfDebugApp/AndroidManifest.xml
copy to tests/tests/simpleperf/CtsSimpleperfProfileableApp/AndroidManifest.xml
index b3509c8..d87d10e 100644
--- a/tests/tests/simpleperf/CtsSimpleperfDebugApp/AndroidManifest.xml
+++ b/tests/tests/simpleperf/CtsSimpleperfProfileableApp/AndroidManifest.xml
@@ -15,12 +15,17 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="com.android.simpleperf">
+        package="com.android.simpleperf.profileable">
 
-    <application android:debuggable="true">
-        <uses-library android:name="android.test.runner" />
+    <application>
+        <profileable android:shell="true" />
+        <activity
+            android:label="simpleperf"
+            android:name="com.android.simpleperf.profileable.MainActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
     </application>
-    <instrumentation
-        android:targetPackage="com.android.simpleperf"
-        android:name="android.support.test.runner.AndroidJUnitRunner" />
-</manifest>
\ No newline at end of file
+</manifest>
diff --git a/tests/tests/simpleperf/CtsSimpleperfProfileableApp/com/android/simpleperf/profileable/MainActivity.java b/tests/tests/simpleperf/CtsSimpleperfProfileableApp/com/android/simpleperf/profileable/MainActivity.java
new file mode 100644
index 0000000..9db511b
--- /dev/null
+++ b/tests/tests/simpleperf/CtsSimpleperfProfileableApp/com/android/simpleperf/profileable/MainActivity.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.simpleperf.profileable;
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.widget.TextView;
+
+public class MainActivity extends Activity {
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        TextView view = new TextView(this);
+        view.setText("MainActivity");
+        setContentView(view);
+
+        createBusyThread();
+    }
+
+    void createBusyThread() {
+        new Thread(new Runnable() {
+            volatile int counter = 0;
+
+            @Override
+            public void run() {
+                while (true) {
+                    for (int i = 0; i < 100000; i++) {
+                        counter++;
+                    }
+                    try {
+                        Thread.sleep(1);
+                    } catch (InterruptedException e) {
+                    }
+                }
+            }
+        }, "BusyThread").start();
+    }
+}
diff --git a/tests/tests/telecom/src/android/telecom/cts/CallRedirectionServiceTest.java b/tests/tests/telecom/src/android/telecom/cts/CallRedirectionServiceTest.java
index d3e0958..ef7a9ec 100644
--- a/tests/tests/telecom/src/android/telecom/cts/CallRedirectionServiceTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/CallRedirectionServiceTest.java
@@ -180,7 +180,7 @@
         LinkedBlockingQueue<Boolean> queue = new LinkedBlockingQueue(1);
 
         runWithShellPermissionIdentity(() -> mRoleManager.addRoleHolderAsUser(roleName,
-                packageName, user, executor, new RoleManagerCallback() {
+                packageName, 0, user, executor, new RoleManagerCallback() {
                     @Override
                     public void onSuccess() {
                         try {
@@ -209,7 +209,7 @@
         LinkedBlockingQueue<Boolean> queue = new LinkedBlockingQueue(1);
 
         runWithShellPermissionIdentity(() -> mRoleManager.removeRoleHolderAsUser(roleName,
-                packageName, user, executor, new RoleManagerCallback() {
+                packageName, 0, user, executor, new RoleManagerCallback() {
                     @Override
                     public void onSuccess() {
                         try {
diff --git a/tests/tests/telecom/src/android/telecom/cts/CtsRoleManagerAdapter.java b/tests/tests/telecom/src/android/telecom/cts/CtsRoleManagerAdapter.java
index 27a7010..3abf52f 100644
--- a/tests/tests/telecom/src/android/telecom/cts/CtsRoleManagerAdapter.java
+++ b/tests/tests/telecom/src/android/telecom/cts/CtsRoleManagerAdapter.java
@@ -163,7 +163,7 @@
         Executor executor = mContext.getMainExecutor();
         LinkedBlockingQueue<String> q = new LinkedBlockingQueue<>(1);
         runWithShellPermissionIdentity(() -> {
-            mRoleManager.addRoleHolderAsUser(roleName, packageName, user, executor,
+            mRoleManager.addRoleHolderAsUser(roleName, packageName, 0, user, executor,
                     new RoleManagerCallback() {
                         @Override
                         public void onSuccess() {
@@ -186,7 +186,7 @@
         Executor executor = mContext.getMainExecutor();
         LinkedBlockingQueue<String> q = new LinkedBlockingQueue<>(1);
         runWithShellPermissionIdentity(() -> {
-            mRoleManager.removeRoleHolderAsUser(roleName, packageName, user, executor,
+            mRoleManager.removeRoleHolderAsUser(roleName, packageName, 0, user, executor,
                     new RoleManagerCallback() {
                         @Override
                         public void onSuccess() {
diff --git a/tests/tests/telecom/src/android/telecom/cts/ThirdPartyCallScreeningServiceTest.java b/tests/tests/telecom/src/android/telecom/cts/ThirdPartyCallScreeningServiceTest.java
index 7d1bae2..83f3995 100644
--- a/tests/tests/telecom/src/android/telecom/cts/ThirdPartyCallScreeningServiceTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/ThirdPartyCallScreeningServiceTest.java
@@ -454,7 +454,7 @@
         LinkedBlockingQueue<Boolean> queue = new LinkedBlockingQueue(1);
 
         runWithShellPermissionIdentity(() -> mRoleManager.addRoleHolderAsUser(roleName,
-                packageName, user, executor, new RoleManagerCallback() {
+                packageName, 0, user, executor, new RoleManagerCallback() {
                     @Override
                     public void onSuccess() {
                         try {
@@ -483,7 +483,7 @@
         LinkedBlockingQueue<Boolean> queue = new LinkedBlockingQueue(1);
 
         runWithShellPermissionIdentity(() -> mRoleManager.removeRoleHolderAsUser(roleName,
-                packageName, user, executor, new RoleManagerCallback() {
+                packageName, 0, user, executor, new RoleManagerCallback() {
                     @Override
                     public void onSuccess() {
                         try {
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/CarrierConfigManagerTest.java b/tests/tests/telephony/current/src/android/telephony/cts/CarrierConfigManagerTest.java
index 6a0819c..a5731d2 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/CarrierConfigManagerTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/CarrierConfigManagerTest.java
@@ -69,7 +69,12 @@
     }
 
     private boolean isSimCardPresent() {
-        return mTelephonyManager.getSimState() != TelephonyManager.SIM_STATE_ABSENT;
+        return mTelephonyManager.getPhoneType() != TelephonyManager.PHONE_TYPE_NONE &&
+                mTelephonyManager.getSimState() != TelephonyManager.SIM_STATE_ABSENT;
+    }
+
+    private boolean isSimCardAbsent() {
+        return mTelephonyManager.getSimState() == TelephonyManager.SIM_STATE_ABSENT;
     }
 
     private void checkConfig(PersistableBundle config) {
@@ -78,7 +83,7 @@
             return;
         }
         assertNotNull("CarrierConfigManager should not return null config", config);
-        if (!isSimCardPresent()) {
+        if (isSimCardAbsent()) {
             // Static default in CarrierConfigManager will be returned when no sim card present.
             assertEquals("Config doesn't match static default.",
                     config.getBoolean(CarrierConfigManager.KEY_ADDITIONAL_CALL_SETTING_BOOL), true);
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/PhoneStateListenerTest.java b/tests/tests/telephony/current/src/android/telephony/cts/PhoneStateListenerTest.java
index b0d8f18..ada3d81 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/PhoneStateListenerTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/PhoneStateListenerTest.java
@@ -26,6 +26,7 @@
 import android.telephony.SignalStrength;
 import android.telephony.TelephonyManager;
 import android.net.ConnectivityManager;
+import android.telephony.ims.ImsReasonInfo;
 import android.test.AndroidTestCase;
 import android.util.Log;
 
@@ -54,6 +55,7 @@
     private boolean mOnSignalStrengthChangedCalled;
     private boolean mOnPreciseCallStateChangedCalled;
     private boolean mOnCallDisconnectCauseChangedCalled;
+    private boolean mOnImsCallDisconnectCauseChangedCalled;
     private boolean mOnPreciseDataConnectionStateChanged;
     private boolean mOnRadioPowerStateChangedCalled;
     private boolean mVoiceActivationStateChangedCalled;
@@ -375,6 +377,48 @@
         assertThat(mOnCallDisconnectCauseChangedCalled).isTrue();
     }
 
+    /*
+     * The tests below rely on the framework to immediately call the installed listener upon
+     * registration. There is no simple way to emulate state changes for testing the listeners.
+     */
+    public void testOnImsCallDisconnectCauseChanged() throws Throwable {
+        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+            return;
+        }
+
+        TestThread t = new TestThread(new Runnable() {
+            public void run() {
+                Looper.prepare();
+
+                mListener = new PhoneStateListener() {
+                    @Override
+                    public void onImsCallDisconnectCauseChanged(ImsReasonInfo imsReason) {
+                        synchronized (mLock) {
+                            mOnImsCallDisconnectCauseChangedCalled = true;
+                            mLock.notify();
+                        }
+                    }
+                };
+                ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
+                        (tm) -> tm.listen(mListener,
+                                PhoneStateListener.LISTEN_IMS_CALL_DISCONNECT_CAUSES));
+                Looper.loop();
+            }
+        });
+
+        assertThat(mOnImsCallDisconnectCauseChangedCalled).isFalse();
+        t.start();
+
+        synchronized (mLock) {
+            if (!mOnImsCallDisconnectCauseChangedCalled){
+                mLock.wait(WAIT_TIME);
+            }
+        }
+        t.checkException();
+        assertThat(mOnImsCallDisconnectCauseChangedCalled).isTrue();
+    }
+
     public void testOnPhoneStateListenerExecutorWithSrvccChanged() throws Throwable {
         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
             Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java b/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java
index f358d8c..bb5857e 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java
@@ -394,6 +394,17 @@
     }
 
     @Test
+    public void testMccMncString() {
+        if (!isSupported()) return;
+
+        SubscriptionInfo info = mSm.getActiveSubscriptionInfo(mSubId);
+        String mcc = info.getMccString();
+        String mnc = info.getMncString();
+        assertTrue(mcc == null || mcc.length() <= 3);
+        assertTrue(mnc == null || mnc.length() <= 3);
+    }
+
+    @Test
     public void testSettingSubscriptionMeteredNess() throws Exception {
         if (!isSupported()) return;
 
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java b/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java
index b964292..7081b8b 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java
@@ -54,6 +54,7 @@
 import com.android.compatibility.common.util.TestThread;
 
 import org.junit.After;
+import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -1015,10 +1016,26 @@
         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
             return;
         }
-        boolean isEmergencyNumber = mTelephonyManager.isCurrentPotentialEmergencyNumber("911");
+        // use shell permission to run system api
+        boolean isEmergencyNumber =
+                ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
+                        (tm) -> tm.isCurrentPotentialEmergencyNumber("911"));
         // TODO enhance it later
     }
 
+    /**
+     * Tests {@link TelephonyManager#getSupportedRadioAccessFamily()}
+     */
+    @Test
+    public void testGetRadioAccessFamily() {
+        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+            return;
+        }
+        long raf = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
+                (tm) -> tm.getSupportedRadioAccessFamily());
+        assertThat(raf).isNotEqualTo(TelephonyManager.NETWORK_TYPE_BITMASK_UNKNOWN);
+    }
+
     public static void waitForMs(long ms) {
         try {
             Thread.sleep(ms);
diff --git a/tests/tests/telephony4/src/android/telephony4/cts/SimRestrictedApisTest.java b/tests/tests/telephony4/src/android/telephony4/cts/SimRestrictedApisTest.java
index c1189a2..4732193 100644
--- a/tests/tests/telephony4/src/android/telephony4/cts/SimRestrictedApisTest.java
+++ b/tests/tests/telephony4/src/android/telephony4/cts/SimRestrictedApisTest.java
@@ -89,7 +89,8 @@
     public void testIccOpenLogicalChannel() {
         try {
             if (isSimCardPresent()) {
-                mTelephonyManager.iccOpenLogicalChannel("");
+                mTelephonyManager.iccCloseLogicalChannel(
+                        mTelephonyManager.iccOpenLogicalChannel("").getChannel());
                 fail("Expected SecurityException. App doesn't have carrier privileges.");
             }
         } catch (SecurityException expected) {
diff --git a/tests/tests/text/src/android/text/cts/StaticLayoutLineBreakingTest.java b/tests/tests/text/src/android/text/cts/StaticLayoutLineBreakingTest.java
index 932b1fc..d7e59cc 100644
--- a/tests/tests/text/src/android/text/cts/StaticLayoutLineBreakingTest.java
+++ b/tests/tests/text/src/android/text/cts/StaticLayoutLineBreakingTest.java
@@ -18,7 +18,7 @@
 
 import static org.junit.Assert.assertEquals;
 
-import android.content.Context;;
+import android.content.Context;
 import android.graphics.Typeface;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
diff --git a/tests/tests/theme/AndroidTest.xml b/tests/tests/theme/AndroidTest.xml
index 95a7a88..fa00709 100644
--- a/tests/tests/theme/AndroidTest.xml
+++ b/tests/tests/theme/AndroidTest.xml
@@ -16,6 +16,8 @@
 <configuration description="Config for CTS Theme test cases">
     <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="uitoolkit" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
         <option name="test-file-name" value="CtsThemeDeviceTestCases.apk" />
diff --git a/tests/tests/tools/processors/view_inspector/Android.bp b/tests/tests/tools/processors/view_inspector/Android.bp
index bcebde1..d4a89cd 100644
--- a/tests/tests/tools/processors/view_inspector/Android.bp
+++ b/tests/tests/tools/processors/view_inspector/Android.bp
@@ -30,5 +30,6 @@
         "cts",
         "vts",
         "general-tests",
+        "cts_instant",
     ]
 }
diff --git a/tests/tests/tools/processors/view_inspector/AndroidManifest.xml b/tests/tests/tools/processors/view_inspector/AndroidManifest.xml
index e6574d7..15ed5fe 100644
--- a/tests/tests/tools/processors/view_inspector/AndroidManifest.xml
+++ b/tests/tests/tools/processors/view_inspector/AndroidManifest.xml
@@ -17,9 +17,9 @@
 
 <manifest
     xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.processor.view.inspector.cts">
+    package="android.processor.view.inspector.cts"
+    android:targetSandboxVersion="2">
 
-    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <application>
         <uses-library android:name="android.test.runner" />
     </application>
diff --git a/tests/tests/tools/processors/view_inspector/AndroidTest.xml b/tests/tests/tools/processors/view_inspector/AndroidTest.xml
index dab96b2..8745e65 100644
--- a/tests/tests/tools/processors/view_inspector/AndroidTest.xml
+++ b/tests/tests/tools/processors/view_inspector/AndroidTest.xml
@@ -17,6 +17,8 @@
 
     <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="uitoolkit" />
+    <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
 
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/tests/tests/transition/AndroidTest.xml b/tests/tests/transition/AndroidTest.xml
index e75e8de..cac2338 100644
--- a/tests/tests/transition/AndroidTest.xml
+++ b/tests/tests/transition/AndroidTest.xml
@@ -16,6 +16,9 @@
 <configuration description="Config for CTS Transition test cases">
     <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="uitoolkit" />
+    <!-- There is no difference between instant apps and installed apps with
+         respect to transition tests, so don't run these in instant apps. -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
         <option name="test-file-name" value="CtsTransitionTestCases.apk" />
diff --git a/tests/tests/transition/src/android/transition/cts/ActivityTransitionTest.java b/tests/tests/transition/src/android/transition/cts/ActivityTransitionTest.java
index 3dd5135..5be8d47 100644
--- a/tests/tests/transition/src/android/transition/cts/ActivityTransitionTest.java
+++ b/tests/tests/transition/src/android/transition/cts/ActivityTransitionTest.java
@@ -315,6 +315,7 @@
         mActivityRule.runOnUiThread(() -> {
             mActivity.getWindow().setExitTransition(new Fade());
             Intent intent = new Intent(mActivity, TargetActivity.class);
+            intent.putExtra(TargetActivity.EXTRA_USE_ANIMATOR, true);
             ActivityOptions activityOptions =
                     ActivityOptions.makeSceneTransitionAnimation(mActivity);
             mActivity.startActivity(intent, activityOptions.toBundle());
@@ -379,7 +380,7 @@
 
         TargetActivity targetActivity = waitForTargetActivity();
 
-        assertTrue(targetActivity.transitionComplete.await(1, TimeUnit.SECONDS));
+        assertTrue(targetActivity.transitionComplete.await(5, TimeUnit.SECONDS));
         assertEquals(View.VISIBLE, targetActivity.startVisibility);
         assertEquals(View.VISIBLE, targetActivity.endVisibility);
 
@@ -392,11 +393,11 @@
             targetActivity.finishAfterTransition();
         });
 
-        assertTrue(targetActivity.transitionComplete.await(1, TimeUnit.SECONDS));
+        assertTrue(targetActivity.transitionComplete.await(5, TimeUnit.SECONDS));
         assertEquals(View.VISIBLE, targetActivity.startVisibility);
         assertEquals(View.VISIBLE, targetActivity.endVisibility);
 
-        assertTrue(targetActivity.transitionComplete.await(1, TimeUnit.SECONDS));
+        assertTrue(targetActivity.transitionComplete.await(5, TimeUnit.SECONDS));
         verify(mReenterListener, within(5000)).onTransitionStart(any());
         verify(mReenterListener, within(5000)).onTransitionEnd(any());
     }
diff --git a/tests/tests/transition/src/android/transition/cts/ChangeBoundsTest.java b/tests/tests/transition/src/android/transition/cts/ChangeBoundsTest.java
index 71bb9f1..cabe7bf 100644
--- a/tests/tests/transition/src/android/transition/cts/ChangeBoundsTest.java
+++ b/tests/tests/transition/src/android/transition/cts/ChangeBoundsTest.java
@@ -71,7 +71,7 @@
     private void resetChangeBoundsTransition() {
         mListener = mock(Transition.TransitionListener.class);
         mChangeBounds = new MyChangeBounds();
-        mChangeBounds.setDuration(500);
+        mChangeBounds.setDuration(1000);
         mChangeBounds.addListener(mListener);
         mChangeBounds.setInterpolator(new LinearInterpolator());
         mTransition = mChangeBounds;
diff --git a/tests/tests/transition/src/android/transition/cts/ExplodeTest.java b/tests/tests/transition/src/android/transition/cts/ExplodeTest.java
index c1248a5..70da07f 100644
--- a/tests/tests/transition/src/android/transition/cts/ExplodeTest.java
+++ b/tests/tests/transition/src/android/transition/cts/ExplodeTest.java
@@ -51,7 +51,7 @@
 
     private void resetTransition() {
         mExplode = new Explode();
-        mExplode.setDuration(500);
+        mExplode.setDuration(1000);
         mTransition = mExplode;
         resetListener();
     }
diff --git a/tests/tests/transition/src/android/transition/cts/SlideEdgeTest.java b/tests/tests/transition/src/android/transition/cts/SlideEdgeTest.java
index 63db5ef..dc4be47 100644
--- a/tests/tests/transition/src/android/transition/cts/SlideEdgeTest.java
+++ b/tests/tests/transition/src/android/transition/cts/SlideEdgeTest.java
@@ -72,7 +72,7 @@
         for (int i = 0; i < sSlideEdgeArray.length; i++) {
             final int slideEdge = (Integer) (sSlideEdgeArray[i][0]);
             final Slide slide = new Slide(slideEdge);
-            slide.setDuration(500);
+            slide.setDuration(1000);
             final Transition.TransitionListener listener =
                     mock(Transition.TransitionListener.class);
             slide.addListener(listener);
@@ -107,7 +107,7 @@
                         });
             });
             verify(listener, within(1000)).onTransitionStart(any());
-            verify(listener, within(1000)).onTransitionEnd(any());
+            verify(listener, within(2000)).onTransitionEnd(any());
 
             verifyMovement(redPoints, slideEdge, false);
             verifyMovement(greenPoints, slideEdge, false);
@@ -128,7 +128,7 @@
         for (int i = 0; i < sSlideEdgeArray.length; i++) {
             final int slideEdge = (Integer) (sSlideEdgeArray[i][0]);
             final Slide slide = new Slide(slideEdge);
-            slide.setDuration(500);
+            slide.setDuration(1000);
             final Transition.TransitionListener listener =
                     mock(Transition.TransitionListener.class);
             slide.addListener(listener);
@@ -172,7 +172,7 @@
                         });
             });
             verify(listener, within(1000)).onTransitionStart(any());
-            verify(listener, within(1000)).onTransitionEnd(any());
+            verify(listener, within(2000)).onTransitionEnd(any());
 
             verifyMovement(redPoints, slideEdge, true);
             verifyMovement(greenPoints, slideEdge, true);
diff --git a/tests/tests/transition/src/android/transition/cts/TargetActivity.java b/tests/tests/transition/src/android/transition/cts/TargetActivity.java
index a547979..b4065dd 100644
--- a/tests/tests/transition/src/android/transition/cts/TargetActivity.java
+++ b/tests/tests/transition/src/android/transition/cts/TargetActivity.java
@@ -76,7 +76,9 @@
 
         if (useAnimator) {
             enterTransition = new TrackingVisibilityWithAnimator();
+            enterTransition.setDuration(2000);
             returnTransition = new TrackingVisibilityWithAnimator();
+            returnTransition.setDuration(2000);
         }
 
         if (excludeId != 0) {
diff --git a/tests/tests/transition/src/android/transition/cts/TransitionManagerTest.java b/tests/tests/transition/src/android/transition/cts/TransitionManagerTest.java
index e401e88..bf8c7f7 100644
--- a/tests/tests/transition/src/android/transition/cts/TransitionManagerTest.java
+++ b/tests/tests/transition/src/android/transition/cts/TransitionManagerTest.java
@@ -16,7 +16,6 @@
 package android.transition.cts;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Matchers.any;
@@ -77,6 +76,8 @@
         enterScene(R.layout.scene1);
         final CountDownLatch startLatch = new CountDownLatch(1);
         final Scene scene6 = loadScene(R.layout.scene6);
+
+        final CountDownLatch moveLatch = watchForRedSquareMoving();
         mActivityRule.runOnUiThread(() -> {
             mSceneRoot.getViewTreeObserver().addOnPreDrawListener(
                     new ViewTreeObserver.OnPreDrawListener() {
@@ -91,37 +92,56 @@
             scene6.enter();
         });
         assertTrue(startLatch.await(500, TimeUnit.MILLISECONDS));
-        ensureRedSquareIsMoving();
+        assertTrue(moveLatch.await(1000, TimeUnit.MILLISECONDS));
         endTransition();
     }
 
-    private void ensureRedSquareIsMoving() throws InterruptedException {
-        final View view = mActivity.findViewById(R.id.redSquare);
-        assertNotNull(view);
-        // We should see a ChangeBounds on redSquare
-        final Rect position = new Rect(view.getLeft(), view.getTop(), view.getRight(),
-                view.getBottom());
-
+    private CountDownLatch watchForRedSquareMoving() throws Throwable {
         final CountDownLatch latch = new CountDownLatch(1);
-        final Rect[] nextArr = new Rect[1];
-        view.postOnAnimation(new Runnable() {
-            // Wait at most 10 frames for the position to change
-            int mFramesToChange = 10;
 
-            @Override
-            public void run() {
-                nextArr[0] = new Rect(view.getLeft(), view.getTop(), view.getRight(),
-                        view.getBottom());
-                mFramesToChange--;
-                if (nextArr[0].equals(position) && mFramesToChange > 0) {
-                    view.postOnAnimation(this);
-                } else {
-                    latch.countDown();
-                }
-            }
+        mActivityRule.runOnUiThread(() -> {
+            final View decor = mActivity.getWindow().getDecorView();
+            final View viewBeforeTransition = mActivity.findViewById(R.id.redSquare);
+            decor.getViewTreeObserver().addOnPreDrawListener(
+                    new ViewTreeObserver.OnPreDrawListener() {
+                        // Wait at most 20 frames for the position to change
+                        int mFramesToChange = 20;
+                        Rect mLastPosition = null;
+                        View mView = null;
+                        int mPositionChanges = 0;
+
+                        @Override
+                        public boolean onPreDraw() {
+                            final View view = mActivity.findViewById(R.id.redSquare);
+                            if (mView == null && view != viewBeforeTransition) {
+                                // Capture the new red square View. It will be in the end
+                                // position now, so don't capture its position.
+                                mView = view;
+                                return true;
+                            }
+                            Rect nextPosition = new Rect(view.getLeft(), view.getTop(),
+                                    view.getRight(), view.getBottom());
+                            if (mLastPosition == null) {
+                                // This is the start position
+                                mLastPosition = nextPosition;
+                                return true;
+                            }
+                            mFramesToChange--;
+                            if (!nextPosition.equals(mLastPosition)) {
+                                mPositionChanges++;
+                                mLastPosition = nextPosition;
+                                if (mPositionChanges > 2) {
+                                    latch.countDown();
+                                }
+                            }
+                            if (mFramesToChange <= 0 || mPositionChanges > 2) {
+                                decor.getViewTreeObserver().removeOnPreDrawListener(this);
+                            }
+                            return true;
+                        }
+                    });
         });
-        assertTrue(latch.await(500, TimeUnit.MILLISECONDS));
-        assertNotEquals(position, nextArr[0]);
+        return latch;
     }
 
     @Test
@@ -149,6 +169,7 @@
         enterScene(R.layout.scene1);
         final CountDownLatch startLatch = new CountDownLatch(1);
         final Scene scene6 = loadScene(R.layout.scene6);
+        final CountDownLatch moveLatch = watchForRedSquareMoving();
         mActivityRule.runOnUiThread(() -> {
             mSceneRoot.getViewTreeObserver().addOnPreDrawListener(
                     new ViewTreeObserver.OnPreDrawListener() {
@@ -162,7 +183,7 @@
             TransitionManager.go(scene6);
         });
         assertTrue(startLatch.await(500, TimeUnit.MILLISECONDS));
-        ensureRedSquareIsMoving();
+        assertTrue(moveLatch.await(1000, TimeUnit.MILLISECONDS));
         endTransition();
     }
 
diff --git a/tests/tests/transition/src/android/transition/cts/TransitionTest.java b/tests/tests/transition/src/android/transition/cts/TransitionTest.java
index ca6d7dd..d200299 100644
--- a/tests/tests/transition/src/android/transition/cts/TransitionTest.java
+++ b/tests/tests/transition/src/android/transition/cts/TransitionTest.java
@@ -70,6 +70,14 @@
 @MediumTest
 @RunWith(AndroidJUnit4.class)
 public class TransitionTest extends BaseTransitionTest {
+    @Override
+    public void setup() {
+        super.setup();
+        // We want to be able to catch the transition in the middle of running, so
+        // it should be long enough that devices can catch it without trouble.
+        mTransition.setDuration(1000);
+    }
+
     @Test
     public void testAddListener() throws Throwable {
         startTransition(R.layout.scene1);
@@ -103,13 +111,14 @@
 
     @Test
     public void testRemoveListener() throws Throwable {
+        TransitionListener listener = mock(TransitionListener.class);
+        mTransition.addListener(listener);
         startTransition(R.layout.scene1);
         waitForStart();
 
-        mActivityRule.runOnUiThread(() -> mTransition.removeListener(mListener));
-
-        SystemClock.sleep(250);
-        verify(mListener, never()).onTransitionEnd(any());
+        mActivityRule.runOnUiThread(() -> mTransition.removeListener(listener));
+        waitForEnd(2000);
+        mActivityRule.runOnUiThread(() -> verify(listener, never()).onTransitionEnd(any()));
     }
 
     @Test
@@ -360,7 +369,7 @@
         View redSquare1 = layout1.findViewById(R.id.redSquare);
         mTransition.excludeTarget(redSquare1, true);
         startTransition(R.layout.scene7);
-        waitForEnd(600);
+        waitForEnd(2000);
 
         mTransition.excludeTarget(redSquare1, false); // remove it
         resetListener();
@@ -422,21 +431,22 @@
 
     @Test
     public void testDuration() throws Throwable {
-        assertEquals(-1, mTransition.getDuration());
+        Transition transition = new AutoTransition();
+        assertEquals(-1, transition.getDuration());
         enterScene(R.layout.scene1);
-        mTransition.setDuration(500);
-        assertEquals(500, mTransition.getDuration());
+        mTransition.setDuration(1000);
+        assertEquals(1000, mTransition.getDuration());
         DurationListener durationListener = new DurationListener();
         mTransition.addListener(durationListener);
         startTransition(R.layout.scene3);
         waitForEnd(5000);
         // We can't be certain that the onTransitionStart() and onTransitionEnd()
-        // are going to be called exactly 500ms apart. There could be more of a
+        // are going to be called exactly 1000ms apart. There could be more of a
         // delay at the beginning than the end. So, we give it some room at the
         // minimum. It can also take a lot longer on the larger side because of
         // slow devices.
         assertThat(durationListener.getDuration(),
-                allOf(greaterThanOrEqualTo(400L), lessThan(900L)));
+                allOf(greaterThanOrEqualTo(500L), lessThan(2000L)));
     }
 
     @Test
@@ -468,7 +478,7 @@
         assertFalse(transition.animators.isEmpty());
         Animator animator = transition.animators.get(redSquare);
         Animator.AnimatorListener listener = transition.listeners.get(redSquare);
-        verify(listener, within(100)).onAnimationStart(any(), eq(false));
+        verify(listener, within(1000)).onAnimationStart(any(), eq(false));
         assertSame(interpolator, animator.getInterpolator());
         endTransition();
     }
@@ -525,7 +535,7 @@
         Animator redSquareAnimator = transition.animators.get(redSquare);
         Animator greenSquareAnimator = transition.animators.get(greenSquare);
         Animator.AnimatorListener listener = transition.listeners.get(redSquare);
-        verify(listener, within(100)).onAnimationStart(any(), eq(false));
+        verify(listener, within(1000)).onAnimationStart(any(), eq(false));
         assertEquals(0, redSquareAnimator.getStartDelay());
         assertEquals(diffTop, greenSquareAnimator.getStartDelay());
         endTransition();
@@ -557,7 +567,7 @@
         Animator animator = transition.animators.get(redSquare);
         assertFalse(animator.isRunning());
         Animator.AnimatorListener listener = transition.listeners.get(redSquare);
-        verify(listener, within(250)).onAnimationStart(any(), eq(false));
+        verify(listener, within(1000)).onAnimationStart(any(), eq(false));
         endTransition();
     }
 
@@ -569,8 +579,8 @@
         mTransition.setDuration(10);
         resetListener();
         startTransition(R.layout.scene2);
-        assertTrue(transition.onDisappearCalled.await(500, TimeUnit.MILLISECONDS));
-        assertTrue(transition.onAppearCalled.await(500, TimeUnit.MILLISECONDS));
+        assertTrue(transition.onDisappearCalled.await(2000, TimeUnit.MILLISECONDS));
+        assertTrue(transition.onAppearCalled.await(2000, TimeUnit.MILLISECONDS));
         // The transition has all the asserts in it, so we can just end it now.
         endTransition();
     }
@@ -583,7 +593,7 @@
         startTransition(R.layout.scene8);
 
         // scene 8 swaps the ids, but not the names. No transition should happen.
-        waitForEnd(1000);
+        waitForEnd(2000);
 
         // now change the match order to prefer the id
         mTransition.setMatchOrder(new int[] {Transition.MATCH_ID, Transition.MATCH_NAME});
@@ -591,7 +601,7 @@
         resetListener();
         startTransition(R.layout.scene1);
         verify(mListener, never()).onTransitionEnd(any()); // it is running as expected
-        waitForEnd(1000);
+        waitForEnd(2000);
     }
 
     @Test
@@ -602,7 +612,7 @@
         mTransition = transition;
         resetListener();
         startTransition(R.layout.scene2);
-        assertTrue(transition.latch.await(500, TimeUnit.MILLISECONDS));
+        assertTrue(transition.latch.await(2000, TimeUnit.MILLISECONDS));
         endTransition();
 
         // Now make the transition only make changes to unimportant properties.
@@ -610,7 +620,7 @@
         mTransition = transition;
         resetListener();
         startTransition(R.layout.scene1);
-        verify(mListener, within(500)).onTransitionEnd(any());
+        verify(mListener, within(2000)).onTransitionEnd(any());
         // createAnimator shouldn't have been called.
         assertEquals(1, transition.latch.getCount());
 
diff --git a/tests/tests/uiautomation/AndroidTest.xml b/tests/tests/uiautomation/AndroidTest.xml
index 8d7637b..f5cf748 100644
--- a/tests/tests/uiautomation/AndroidTest.xml
+++ b/tests/tests/uiautomation/AndroidTest.xml
@@ -17,7 +17,7 @@
     <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="framework" />
     <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
-    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
         <option name="test-file-name" value="CtsUiAutomationTestCases.apk" />
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/bitmapverifiers/SamplePointWideGamutVerifier.java b/tests/tests/uirendering/src/android/uirendering/cts/bitmapverifiers/SamplePointWideGamutVerifier.java
index d2cb027..5cd019a 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/bitmapverifiers/SamplePointWideGamutVerifier.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/bitmapverifiers/SamplePointWideGamutVerifier.java
@@ -19,14 +19,10 @@
 import android.graphics.Bitmap;
 import android.graphics.Color;
 import android.graphics.Point;
-import android.util.Half;
 import android.util.Log;
 
 import org.junit.Assert;
 
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
 public class SamplePointWideGamutVerifier extends BitmapVerifier {
     private static final String TAG = "SamplePointWideGamut";
 
@@ -45,53 +41,22 @@
         Assert.assertTrue("You cannot use this verifier with an bitmap whose ColorSpace is not "
                  + "wide gamut: " + bitmap.getColorSpace(), bitmap.getColorSpace().isWideGamut());
 
-        ByteBuffer dst = ByteBuffer.allocateDirect(bitmap.getAllocationByteCount());
-        bitmap.copyPixelsToBuffer(dst);
-        dst.rewind();
-        dst.order(ByteOrder.LITTLE_ENDIAN);
-
-        int width = bitmap.getWidth();
-        int height = bitmap.getHeight();
-        int stride = bitmap.getRowBytes();
-
         boolean success = true;
         for (int i = 0; i < mPoints.length; i++) {
             Point p = mPoints[i];
-            Color c = mColors[i];
+            Color expected = mColors[i];
 
-            float r, g, b, a;
-
-            if (bitmap.getConfig() == Bitmap.Config.RGBA_F16) {
-                int index = p.y * stride + (p.x << 3);
-                r = Half.toFloat(dst.getShort(index));
-                g = Half.toFloat(dst.getShort(index + 2));
-                b = Half.toFloat(dst.getShort(index + 4));
-                a = Half.toFloat(dst.getShort(index + 6));
-            } else if (bitmap.getConfig() == Bitmap.Config.ARGB_8888) {
-                int index = p.y * stride + (p.x << 2);
-                r = dst.get(index + 0) / 255.0f;
-                g = dst.get(index + 1) / 255.0f;
-                b = dst.get(index + 2) / 255.0f;
-                a = dst.get(index + 3) / 255.0f;
-            } else {
-                Assert.fail("This verifier does not support the provided bitmap config: "
-                        + bitmap.getConfig());
-                return false;
-            }
-
-            Color bitmapColor = Color.valueOf(r, g, b, a, bitmap.getColorSpace());
-            Color convertedBitmapColor = bitmapColor.convert(c.getColorSpace());
+            Color actual = bitmap.getColor(p.x, p.y).convert(expected.getColorSpace());
 
             boolean localSuccess = true;
-            if (!floatCompare(c.red(),   convertedBitmapColor.red(),   mEps)) localSuccess = false;
-            if (!floatCompare(c.green(), convertedBitmapColor.green(), mEps)) localSuccess = false;
-            if (!floatCompare(c.blue(),  convertedBitmapColor.blue(),  mEps)) localSuccess = false;
-            if (!floatCompare(c.alpha(), convertedBitmapColor.alpha(), mEps)) localSuccess = false;
+            if (!floatCompare(expected.red(),   actual.red(),   mEps)) localSuccess = false;
+            if (!floatCompare(expected.green(), actual.green(), mEps)) localSuccess = false;
+            if (!floatCompare(expected.blue(),  actual.blue(),  mEps)) localSuccess = false;
+            if (!floatCompare(expected.alpha(), actual.alpha(), mEps)) localSuccess = false;
 
             if (!localSuccess) {
                 success = false;
-                Log.w(TAG, "Expected " + c.toString() + " at " + p.x + "x" + p.y
-                        + ", got " + convertedBitmapColor.toString());
+                Log.w(TAG, "Expected " + expected + " at " + p + ", got " + actual);
             }
         }
         return success;
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/BlendModeColorFilterTest.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/BlendModeColorFilterTest.java
index fe0292c..3b08c64 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/BlendModeColorFilterTest.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/BlendModeColorFilterTest.java
@@ -15,6 +15,8 @@
  */
 package android.uirendering.cts.testclasses;
 
+import static org.junit.Assert.assertEquals;
+
 import android.graphics.Bitmap;
 import android.graphics.BlendMode;
 import android.graphics.BlendModeColorFilter;
@@ -103,4 +105,16 @@
         testBlendModeColorFilter(Color.GREEN, BlendMode.SCREEN,
                 new int[]{Color.RED, Color.CYAN, Color.CYAN});
     }
+
+    @Test
+    public void testBlendModeColorFilterGetMode() {
+        BlendModeColorFilter filter = new BlendModeColorFilter(Color.CYAN, BlendMode.SOFT_LIGHT);
+        assertEquals(BlendMode.SOFT_LIGHT, filter.getMode());
+    }
+
+    @Test
+    public void testBlendModeColorFilterGetColor() {
+        BlendModeColorFilter filter = new BlendModeColorFilter(Color.MAGENTA, BlendMode.HARD_LIGHT);
+        assertEquals(Color.MAGENTA, filter.getColor());
+    }
 }
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ExactCanvasTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ExactCanvasTests.java
index f2185b4..8d16d5e 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ExactCanvasTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ExactCanvasTests.java
@@ -19,6 +19,7 @@
 import android.graphics.BlendMode;
 import android.graphics.Canvas;
 import android.graphics.Color;
+import android.graphics.ColorSpace;
 import android.graphics.Paint;
 import android.graphics.Path;
 import android.graphics.Picture;
@@ -281,4 +282,20 @@
                 })
                 .runWithComparer(mExactComparer);
     }
+
+    @Test
+    public void testColorLongs() {
+        createTest()
+                .addCanvasClient((canvas, width, height) -> {
+                    canvas.drawColor(Color.pack(0.5f, 0.3f, 0.1f, 1.0f,
+                                ColorSpace.get(ColorSpace.Named.DISPLAY_P3)));
+                    canvas.drawColor(Color.pack(0.2f, 0.2f, 0.2f, 1.0f,
+                                ColorSpace.get(ColorSpace.Named.DISPLAY_P3)), BlendMode.PLUS);
+                    Paint p = new Paint();
+                    p.setColor(Color.pack(0.7f, 0.9f, 0.4f, 1.0f,
+                                ColorSpace.get(ColorSpace.Named.DISPLAY_P3)));
+                    canvas.drawRect(20, 20, 70, 70, p);
+                })
+                .runWithComparer(mExactComparer);
+    }
 }
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/RenderNodeTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/RenderNodeTests.java
index 0077115..afd9a64 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/RenderNodeTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/RenderNodeTests.java
@@ -350,4 +350,17 @@
             assertTrue(usedIds.add(new RenderNode(null).getUniqueId()));
         }
     }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testInvalidCameraDistance() {
+        final RenderNode renderNode = new RenderNode(null);
+        renderNode.setCameraDistance(-1f);
+    }
+
+    @Test
+    public void testCameraDistanceSetGet() {
+        final RenderNode renderNode = new RenderNode(null);
+        renderNode.setCameraDistance(100f);
+        assertEquals(100f, renderNode.getCameraDistance(), 0.0f);
+    }
 }
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/WideColorGamutTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/WideColorGamutTests.java
index 9f46e36..57446b0 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/WideColorGamutTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/WideColorGamutTests.java
@@ -18,6 +18,7 @@
 
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
+import android.graphics.BlendMode;
 import android.graphics.Color;
 import android.graphics.ColorSpace;
 import android.graphics.Point;
@@ -30,6 +31,7 @@
 import android.uirendering.cts.testclasses.view.BitmapView;
 import android.uirendering.cts.testinfrastructure.ActivityTestBase;
 import android.view.View;
+
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
@@ -129,4 +131,33 @@
                 }, true)
                 .runWithVerifier(getVerifier(POINTS, COLORS, 1e-2f));
     }
+
+    @Test
+    public void testCanvasDrawColorLong() {
+        final Color greenP3 = Color.valueOf(0, 1.0f, 0, 1.0f, DISPLAY_P3);
+        createTest()
+                .addCanvasClient((canvas, width, height) -> {
+                    canvas.drawColor(greenP3.pack());
+                })
+                .runWithVerifier(getVerifier(
+                            new Point[] { new Point(0, 0), new Point(50, 50) },
+                            new Color[] { greenP3, greenP3 },
+                            0));
+    }
+
+    @Test
+    public void testCanvasDrawColorLongBlendMode() {
+        final Color greenP3 = Color.valueOf(0, 1.0f, 0, 1.0f, DISPLAY_P3);
+        final Color redP3 = Color.valueOf(1.0f, 0, 0, 1.0f, DISPLAY_P3);
+        final Color expected = Color.valueOf(1.0f, 1.0f, 0, 1.0f, DISPLAY_P3);
+        createTest()
+                .addCanvasClient((canvas, width, height) -> {
+                    canvas.drawColor(greenP3.pack());
+                    canvas.drawColor(redP3.pack(), BlendMode.PLUS);
+                })
+                .runWithVerifier(getVerifier(
+                            new Point[] { new Point(0, 0), new Point(50, 50) },
+                            new Color[] { expected, expected },
+                            0));
+    }
 }
diff --git a/tests/tests/view/AndroidManifest.xml b/tests/tests/view/AndroidManifest.xml
index 68d14a7..dabbc1a 100644
--- a/tests/tests/view/AndroidManifest.xml
+++ b/tests/tests/view/AndroidManifest.xml
@@ -359,6 +359,12 @@
                 <action android:name="android.intent.action.MAIN" />
             </intent-filter>
         </activity>
+
+        <activity android:name="android.view.cts.ViewSourceLayoutTestActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+            </intent-filter>
+        </activity>
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
diff --git a/tests/tests/view/res/layout/focus_finder_layout.xml b/tests/tests/view/res/layout/focus_finder_layout.xml
index 8f4dffb..1dea684 100644
--- a/tests/tests/view/res/layout/focus_finder_layout.xml
+++ b/tests/tests/view/res/layout/focus_finder_layout.xml
@@ -22,8 +22,7 @@
             android:layout_alignParentTop="true">
         <TableRow>
             <android.view.cts.TestButton android:id="@+id/top_left_button"
-                    android:layout_width="20dp"
-                    android:layout_marginRight="40dp"
+                    android:layout_width="60dp"
                     android:layout_height="match_parent"
                     android:text="TL" />
             <android.view.cts.TestButton android:id="@+id/top_right_button"
diff --git a/tests/tests/view/res/layout/view_source_layout_test_include_layout.xml b/tests/tests/view/res/layout/view_source_layout_test_include_layout.xml
new file mode 100644
index 0000000..9421131
--- /dev/null
+++ b/tests/tests/view/res/layout/view_source_layout_test_include_layout.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2019 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
+  -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent">
+    <View
+        android:id="@+id/view2"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent" />
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/tests/view/res/layout/view_source_layout_test_layout.xml b/tests/tests/view/res/layout/view_source_layout_test_layout.xml
new file mode 100644
index 0000000..049a4de
--- /dev/null
+++ b/tests/tests/view/res/layout/view_source_layout_test_layout.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2019 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
+  -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:id="@+id/view_root"
+              android:orientation="vertical"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent">
+    <View
+        android:id="@+id/view1"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent" />
+
+    <include layout="@layout/view_source_layout_test_include_layout" />
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/tests/view/src/android/view/cts/ASurfaceControlTest.java b/tests/tests/view/src/android/view/cts/ASurfaceControlTest.java
index eb9f513..7bc8155 100644
--- a/tests/tests/view/src/android/view/cts/ASurfaceControlTest.java
+++ b/tests/tests/view/src/android/view/cts/ASurfaceControlTest.java
@@ -21,6 +21,8 @@
 import android.animation.ObjectAnimator;
 import android.animation.PropertyValuesHolder;
 import android.animation.ValueAnimator;
+import android.graphics.Canvas;
+import android.graphics.Color;
 import android.support.test.rule.ActivityTestRule;
 import android.support.test.runner.AndroidJUnit4;
 import android.support.test.uiautomator.UiObjectNotFoundException;
@@ -93,7 +95,11 @@
         private Set<Long> mBuffers = new HashSet<Long>();
 
         @Override
-        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}
+        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
+            Canvas canvas = holder.lockCanvas();
+            canvas.drawColor(Color.YELLOW);
+            holder.unlockCanvasAndPost(canvas);
+        }
 
         @Override
         public void surfaceDestroyed(SurfaceHolder holder) {
@@ -255,6 +261,18 @@
             reparent(surfaceControl, newParentSurfaceControl, surfaceTransaction);
             applyAndDeleteSurfaceTransaction(surfaceTransaction);
         }
+
+        public void setColor(long surfaceControl, long surfaceTransaction, float red, float green,
+                float blue, float alpha) {
+            nSurfaceTransaction_setColor(surfaceControl, surfaceTransaction, red, green, blue,
+                    alpha);
+        }
+
+        public void setColor(long surfaceControl, float red, float green, float blue, float alpha) {
+            long surfaceTransaction = createSurfaceTransaction();
+            setColor(surfaceControl, surfaceTransaction, red, green, blue, alpha);
+            applyAndDeleteSurfaceTransaction(surfaceTransaction);
+        }
     }
 
     ///////////////////////////////////////////////////////////////////////////
@@ -335,7 +353,7 @@
                         long surfaceControl = createFromWindow(holder.getSurface());
                     }
                 },
-                new PixelChecker(PixelColor.BLACK) { //10000
+                new PixelChecker(PixelColor.YELLOW) { //10000
                     @Override
                     public boolean checkPixels(int pixelCount, int width, int height) {
                         return pixelCount > 9000 && pixelCount < 11000;
@@ -353,7 +371,7 @@
                         long childSurfaceControl = create(parentSurfaceControl);
                     }
                 },
-                new PixelChecker(PixelColor.BLACK) { //10000
+                new PixelChecker(PixelColor.YELLOW) { //10000
                     @Override
                     public boolean checkPixels(int pixelCount, int width, int height) {
                         return pixelCount > 9000 && pixelCount < 11000;
@@ -458,7 +476,7 @@
                         setVisibility(surfaceControl, false);
                     }
                 },
-                new PixelChecker(PixelColor.BLACK) { //10000
+                new PixelChecker(PixelColor.YELLOW) { //10000
                     @Override
                     public boolean checkPixels(int pixelCount, int width, int height) {
                         return pixelCount > 9000 && pixelCount < 11000;
@@ -508,7 +526,7 @@
                 // we don't know what variation the GPU/DPU/blitter might have. Although
                 // we don't know what shade of red might be present, we can at least check
                 // that the optimization doesn't cause the framework to drop the buffer entirely.
-                new PixelChecker(PixelColor.BLACK) {
+                new PixelChecker(PixelColor.YELLOW) {
                     @Override
                     public boolean checkPixels(int pixelCount, int width, int height) {
                         return pixelCount == 0;
@@ -706,7 +724,7 @@
 
                         setQuadrantBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH,
                                 DEFAULT_LAYOUT_HEIGHT, PixelColor.RED, PixelColor.BLUE,
-                                PixelColor.BLACK, PixelColor.GREEN);
+                                PixelColor.MAGENTA, PixelColor.GREEN);
                         setGeometry(surfaceControl, 0, 0, 100, 100, 0, 0, 640, 480, 0);
                     }
                 };
@@ -725,7 +743,7 @@
                     }
                 });
         verifyTest(callback,
-                new PixelChecker(PixelColor.BLACK) { //2500
+                new PixelChecker(PixelColor.MAGENTA) { //2500
                     @Override
                     public boolean checkPixels(int pixelCount, int width, int height) {
                         return pixelCount > 2250 && pixelCount < 2750;
@@ -749,7 +767,7 @@
 
                         setQuadrantBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH,
                                 DEFAULT_LAYOUT_HEIGHT, PixelColor.RED, PixelColor.BLUE,
-                                PixelColor.BLACK, PixelColor.GREEN);
+                                PixelColor.MAGENTA, PixelColor.GREEN);
                         setGeometry(surfaceControl, 10, 10, 90, 90, 0, 0, 640, 480, 0);
                     }
                 };
@@ -768,7 +786,7 @@
                     }
                 });
         verifyTest(callback,
-                new PixelChecker(PixelColor.BLACK) { //2500
+                new PixelChecker(PixelColor.MAGENTA) { //2500
                     @Override
                     public boolean checkPixels(int pixelCount, int width, int height) {
                         return pixelCount > 2250 && pixelCount < 2750;
@@ -793,11 +811,11 @@
 
                         setQuadrantBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH,
                                 DEFAULT_LAYOUT_HEIGHT, PixelColor.RED, PixelColor.BLUE,
-                                PixelColor.BLACK, PixelColor.GREEN);
+                                PixelColor.MAGENTA, PixelColor.GREEN);
                         setGeometry(surfaceControl, 60, 10, 90, 90, 0, 0, 640, 480, 0);
                     }
                 },
-                new PixelChecker(PixelColor.BLACK) { //5000
+                new PixelChecker(PixelColor.MAGENTA) { //5000
                     @Override
                     public boolean checkPixels(int pixelCount, int width, int height) {
                         return pixelCount > 4500 && pixelCount < 5500;
@@ -814,7 +832,7 @@
 
                         setQuadrantBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH,
                                 DEFAULT_LAYOUT_HEIGHT, PixelColor.RED, PixelColor.BLUE,
-                                PixelColor.BLACK, PixelColor.GREEN);
+                                PixelColor.MAGENTA, PixelColor.GREEN);
                         setGeometry(surfaceControl, -50, -50, 150, 150, 0, 0, 640, 480, 0);
                     }
                 };
@@ -833,7 +851,7 @@
                     }
                 });
         verifyTest(callback,
-                new PixelChecker(PixelColor.BLACK) { //2500
+                new PixelChecker(PixelColor.MAGENTA) { //2500
                     @Override
                     public boolean checkPixels(int pixelCount, int width, int height) {
                         return pixelCount > 2250 && pixelCount < 2750;
@@ -858,7 +876,7 @@
 
                         setQuadrantBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH,
                                 DEFAULT_LAYOUT_HEIGHT, PixelColor.RED, PixelColor.BLUE,
-                                PixelColor.BLACK, PixelColor.GREEN);
+                                PixelColor.MAGENTA, PixelColor.GREEN);
                         setGeometry(surfaceControl, -50, -50, 50, 50, 0, 0, 640, 480, 0);
                     }
                 },
@@ -880,7 +898,7 @@
 
                         setQuadrantBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH,
                                 DEFAULT_LAYOUT_HEIGHT, PixelColor.RED, PixelColor.BLUE,
-                                PixelColor.BLACK, PixelColor.GREEN);
+                                PixelColor.MAGENTA, PixelColor.GREEN);
                         setGeometry(surfaceControl, 60, 10, 90, 90, 0, 0, 640, 480,
                                     /*NATIVE_WINDOW_TRANSFORM_FLIP_H*/ 1);
                     }
@@ -903,7 +921,7 @@
 
                         setQuadrantBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH,
                                 DEFAULT_LAYOUT_HEIGHT, PixelColor.RED, PixelColor.BLUE,
-                                PixelColor.BLACK, PixelColor.GREEN);
+                                PixelColor.MAGENTA, PixelColor.GREEN);
                         setGeometry(surfaceControl, 60, 10, 90, 90, 0, 0, 640, 480,
                                     /*NATIVE_WINDOW_TRANSFORM_ROT_180*/ 3);
                     }
@@ -952,13 +970,13 @@
                         setSolidBuffer(surfaceControl1, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
                                 PixelColor.RED);
                         setSolidBuffer(surfaceControl2, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
-                                PixelColor.BLACK);
+                                PixelColor.MAGENTA);
 
                         setZOrder(surfaceControl1, 1);
                         setZOrder(surfaceControl2, 0);
                     }
                 },
-                new PixelChecker(PixelColor.BLACK) {
+                new PixelChecker(PixelColor.YELLOW) {
                     @Override
                     public boolean checkPixels(int pixelCount, int width, int height) {
                         return pixelCount == 0;
@@ -977,7 +995,7 @@
                         setSolidBuffer(surfaceControl1, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
                                 PixelColor.RED);
                         setSolidBuffer(surfaceControl2, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
-                                PixelColor.BLACK);
+                                PixelColor.MAGENTA);
 
                         setZOrder(surfaceControl1, 1);
                         setZOrder(surfaceControl2, 5);
@@ -1002,13 +1020,13 @@
                         setSolidBuffer(surfaceControl1, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
                                 PixelColor.RED);
                         setSolidBuffer(surfaceControl2, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
-                                PixelColor.BLACK);
+                                PixelColor.MAGENTA);
 
                         setZOrder(surfaceControl1, 1);
                         setZOrder(surfaceControl2, -15);
                     }
                 },
-                new PixelChecker(PixelColor.BLACK) {
+                new PixelChecker(PixelColor.YELLOW) {
                     @Override
                     public boolean checkPixels(int pixelCount, int width, int height) {
                         return pixelCount == 0;
@@ -1027,7 +1045,7 @@
                         setSolidBuffer(surfaceControl1, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
                                 PixelColor.RED);
                         setSolidBuffer(surfaceControl2, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
-                                PixelColor.BLACK);
+                                PixelColor.MAGENTA);
 
                         setZOrder(surfaceControl1, 1);
                         setZOrder(surfaceControl2, Integer.MAX_VALUE);
@@ -1052,13 +1070,13 @@
                         setSolidBuffer(surfaceControl1, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
                                 PixelColor.RED);
                         setSolidBuffer(surfaceControl2, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
-                                PixelColor.BLACK);
+                                PixelColor.MAGENTA);
 
                         setZOrder(surfaceControl1, 1);
                         setZOrder(surfaceControl2, Integer.MIN_VALUE);
                     }
                 },
-                new PixelChecker(PixelColor.BLACK) {
+                new PixelChecker(PixelColor.YELLOW) {
                     @Override
                     public boolean checkPixels(int pixelCount, int width, int height) {
                         return pixelCount == 0;
@@ -1229,7 +1247,7 @@
                     }
                 };
         verifyTest(callback,
-                new PixelChecker(PixelColor.BLACK) {
+                new PixelChecker(PixelColor.YELLOW) {
                     @Override
                     public boolean checkPixels(int pixelCount, int width, int height) {
                         return pixelCount == 0;
@@ -1257,7 +1275,7 @@
                         setBufferAlpha(surfaceControl, 0.0);
                     }
                 },
-                new PixelChecker(PixelColor.BLACK) { //10000
+                new PixelChecker(PixelColor.YELLOW) { //10000
                     @Override
                     public boolean checkPixels(int pixelCount, int width, int height) {
                         return pixelCount > 9000 && pixelCount < 11000;
@@ -1307,7 +1325,7 @@
                         reparent(childSurfaceControl, 0);
                     }
                 },
-                new PixelChecker(PixelColor.BLACK) { //10000
+                new PixelChecker(PixelColor.YELLOW) { //10000
                     @Override
                     public boolean checkPixels(int pixelCount, int width, int height) {
                         return pixelCount > 9000 && pixelCount < 11000;
@@ -1315,6 +1333,214 @@
                 });
     }
 
+    @Test
+    public void testSurfaceTransaction_setColor() throws Throwable {
+        verifyTest(
+                new BasicSurfaceHolderCallback() {
+                @Override
+                public void surfaceCreated(SurfaceHolder holder) {
+                    long surfaceControl = createFromWindow(holder.getSurface());
+
+                    setColor(surfaceControl, 0, 1.0f, 0, 1.0f);
+                }
+            },
+                new PixelChecker(PixelColor.GREEN) { // 10000
+                @Override
+                public boolean checkPixels(int pixelCount, int width, int height) {
+                    return pixelCount > 9000 && pixelCount < 11000;
+                }
+            });
+    }
+
+    @Test
+    public void testSurfaceTransaction_noColorNoBuffer() throws Throwable {
+        verifyTest(
+                new BasicSurfaceHolderCallback() {
+                @Override
+                public void surfaceCreated(SurfaceHolder holder) {
+                    long parentSurfaceControl = createFromWindow(holder.getSurface());
+                    long childSurfaceControl = create(parentSurfaceControl);
+
+                    setColor(parentSurfaceControl, 0, 1.0f, 0, 1.0f);
+                }
+            },
+                new PixelChecker(PixelColor.GREEN) { // 10000
+                @Override
+                public boolean checkPixels(int pixelCount, int width, int height) {
+                    return pixelCount > 9000 && pixelCount < 11000;
+                }
+            });
+    }
+
+    @Test
+    public void testSurfaceTransaction_setColorAlpha() throws Throwable {
+        verifyTest(
+                new BasicSurfaceHolderCallback() {
+                @Override
+                public void surfaceCreated(SurfaceHolder holder) {
+                    long parentSurfaceControl = createFromWindow(holder.getSurface());
+                    setColor(parentSurfaceControl, 0, 0, 1.0f, 0);
+                }
+            },
+                new PixelChecker(PixelColor.YELLOW) { // 10000
+                @Override
+                public boolean checkPixels(int pixelCount, int width, int height) {
+                    return pixelCount > 9000 && pixelCount < 11000;
+                }
+            });
+    }
+
+    @Test
+    public void testSurfaceTransaction_setColorAndBuffer() throws Throwable {
+        verifyTest(
+                new BasicSurfaceHolderCallback() {
+                @Override
+                public void surfaceCreated(SurfaceHolder holder) {
+                    long surfaceControl = createFromWindow(holder.getSurface());
+
+                    setSolidBuffer(
+                            surfaceControl, DEFAULT_LAYOUT_WIDTH,
+                            DEFAULT_LAYOUT_HEIGHT, PixelColor.RED);
+                    setColor(surfaceControl, 0, 1.0f, 0, 1.0f);
+                }
+            },
+                new PixelChecker(PixelColor.RED) { // 10000
+                @Override
+                public boolean checkPixels(int pixelCount, int width, int height) {
+                    return pixelCount > 9000 && pixelCount < 11000;
+                }
+            });
+    }
+
+    @Test
+    public void testSurfaceTransaction_setColorAndBuffer_bufferAlpha_0_5() throws Throwable {
+        verifyTest(
+                new BasicSurfaceHolderCallback() {
+                @Override
+                public void surfaceCreated(SurfaceHolder holder) {
+                    long surfaceControl = createFromWindow(holder.getSurface());
+
+                    setSolidBuffer(
+                            surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+                            PixelColor.RED);
+                    setBufferAlpha(surfaceControl, 0.5);
+                    setColor(surfaceControl, 0, 0, 1.0f, 1.0f);
+                }
+            },
+                new PixelChecker(PixelColor.RED) {
+                @Override
+                public boolean checkPixels(int pixelCount, int width, int height) {
+                    return pixelCount == 0;
+                }
+            });
+    }
+
+    @Test
+    public void testSurfaceTransaction_setBufferNoColor_bufferAlpha_0() throws Throwable {
+        verifyTest(
+                new BasicSurfaceHolderCallback() {
+                @Override
+                public void surfaceCreated(SurfaceHolder holder) {
+                    long surfaceControlA = createFromWindow(holder.getSurface());
+                    long surfaceControlB = createFromWindow(holder.getSurface());
+
+                    setColor(surfaceControlA, 1.0f, 0, 0, 1.0f);
+                    setSolidBuffer(surfaceControlB, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+                            PixelColor.TRANSPARENT);
+
+                    setZOrder(surfaceControlA, 1);
+                    setZOrder(surfaceControlB, 2);
+                }
+            },
+                new PixelChecker(PixelColor.RED) { // 10000
+                @Override
+                public boolean checkPixels(int pixelCount, int width, int height) {
+                    return pixelCount > 9000 && pixelCount < 11000;
+                }
+            });
+    }
+
+    @Test
+    public void testSurfaceTransaction_setColorAndBuffer_hide() throws Throwable {
+        verifyTest(
+                new BasicSurfaceHolderCallback() {
+                @Override
+                public void surfaceCreated(SurfaceHolder holder) {
+                    long parentSurfaceControl = createFromWindow(holder.getSurface());
+                    long childSurfaceControl = create(parentSurfaceControl);
+
+                    setColor(parentSurfaceControl, 0, 1.0f, 0, 1.0f);
+
+                    setSolidBuffer(
+                            childSurfaceControl, DEFAULT_LAYOUT_WIDTH,
+                            DEFAULT_LAYOUT_HEIGHT, PixelColor.RED);
+                    setColor(childSurfaceControl, 0, 0, 1.0f, 1.0f);
+                    setVisibility(childSurfaceControl, false);
+                }
+            },
+                new PixelChecker(PixelColor.GREEN) { // 10000
+                @Override
+                public boolean checkPixels(int pixelCount, int width, int height) {
+                    return pixelCount > 9000 && pixelCount < 11000;
+                }
+            });
+    }
+
+    @Test
+    public void testSurfaceTransaction_zOrderMultipleSurfaces() throws Throwable {
+        verifyTest(
+                new BasicSurfaceHolderCallback() {
+                @Override
+                public void surfaceCreated(SurfaceHolder holder) {
+                    long surfaceControlA = createFromWindow(holder.getSurface());
+                    long surfaceControlB = createFromWindow(holder.getSurface());
+
+                    // blue color layer of A is above the green buffer and red color layer
+                    // of B
+                    setColor(surfaceControlA, 0, 0, 1.0f, 1.0f);
+                    setSolidBuffer(
+                            surfaceControlB, DEFAULT_LAYOUT_WIDTH,
+                            DEFAULT_LAYOUT_HEIGHT, PixelColor.GREEN);
+                    setColor(surfaceControlB, 1.0f, 0, 0, 1.0f);
+                    setZOrder(surfaceControlA, 5);
+                    setZOrder(surfaceControlB, 4);
+                }
+            },
+                new PixelChecker(PixelColor.BLUE) { // 10000
+                @Override
+                public boolean checkPixels(int pixelCount, int width, int height) {
+                    return pixelCount > 9000 && pixelCount < 11000;
+                }
+            });
+    }
+
+    @Test
+    public void testSurfaceTransaction_zOrderMultipleSurfacesWithParent() throws Throwable {
+        verifyTest(
+                new BasicSurfaceHolderCallback() {
+                @Override
+                public void surfaceCreated(SurfaceHolder holder) {
+                    long parentSurfaceControl = createFromWindow(holder.getSurface());
+                    long surfaceControlA = create(parentSurfaceControl);
+                    long surfaceControlB = create(parentSurfaceControl);
+
+                    setColor(surfaceControlA, 0, 1.0f, 0, 1.0f);
+                    setSolidBuffer(
+                            surfaceControlA, DEFAULT_LAYOUT_WIDTH,
+                            DEFAULT_LAYOUT_HEIGHT, PixelColor.GREEN);
+                    setColor(surfaceControlB, 1.0f, 0, 0, 1.0f);
+                    setZOrder(surfaceControlA, 3);
+                    setZOrder(surfaceControlB, 4);
+                }
+            },
+                new PixelChecker(PixelColor.RED) { // 10000
+                @Override
+                public boolean checkPixels(int pixelCount, int width, int height) {
+                    return pixelCount > 9000 && pixelCount < 11000;
+                }
+            });
+    }
+
     ///////////////////////////////////////////////////////////////////////////
     // Native function prototypes
     ///////////////////////////////////////////////////////////////////////////
diff --git a/tests/tests/view/src/android/view/cts/ChoreographerTest.java b/tests/tests/view/src/android/view/cts/ChoreographerTest.java
index a232b51..2adbc13 100644
--- a/tests/tests/view/src/android/view/cts/ChoreographerTest.java
+++ b/tests/tests/view/src/android/view/cts/ChoreographerTest.java
@@ -81,15 +81,15 @@
                     Choreographer.CALLBACK_ANIMATION, removedCallback, null);
 
             // We expect the remaining callbacks to have been invoked once.
-            verify(addedCallback1, timeout(NOMINAL_VSYNC_PERIOD * 10).times(1)).run();
-            verify(addedCallback2, timeout(NOMINAL_VSYNC_PERIOD * 10).times(1)).run();
+            verify(addedCallback1, timeout(NOMINAL_VSYNC_PERIOD * 30).times(1)).run();
+            verify(addedCallback2, timeout(NOMINAL_VSYNC_PERIOD * 30).times(1)).run();
             verifyZeroInteractions(removedCallback);
 
             // If we post a callback again, then it should be invoked again.
             mChoreographer.postCallback(
                     Choreographer.CALLBACK_ANIMATION, addedCallback1, null);
 
-            verify(addedCallback1, timeout(NOMINAL_VSYNC_PERIOD * 10).times(2)).run();
+            verify(addedCallback1, timeout(NOMINAL_VSYNC_PERIOD * 30).times(2)).run();
             verify(addedCallback2, times(1)).run();
             verifyZeroInteractions(removedCallback);
 
@@ -100,7 +100,7 @@
                     Choreographer.CALLBACK_ANIMATION, removedCallback, TOKEN);
             mChoreographer.removeCallbacks(
                     Choreographer.CALLBACK_ANIMATION, null, TOKEN);
-            verify(addedCallback1, timeout(NOMINAL_VSYNC_PERIOD * 10).times(3)).run();
+            verify(addedCallback1, timeout(NOMINAL_VSYNC_PERIOD * 30).times(3)).run();
             verifyZeroInteractions(removedCallback);
 
             // If the action and token matches, then the callback should be removed.
@@ -111,7 +111,7 @@
                     Choreographer.CALLBACK_ANIMATION, removedCallback, TOKEN);
             mChoreographer.removeCallbacks(
                     Choreographer.CALLBACK_ANIMATION, removedCallback, TOKEN);
-            verify(addedCallback1, timeout(NOMINAL_VSYNC_PERIOD * 10).times(4)).run();
+            verify(addedCallback1, timeout(NOMINAL_VSYNC_PERIOD * 30).times(4)).run();
             verifyZeroInteractions(removedCallback);
         } finally {
             mChoreographer.removeCallbacks(
diff --git a/tests/tests/view/src/android/view/cts/FocusFinderTest.java b/tests/tests/view/src/android/view/cts/FocusFinderTest.java
index 2505111..465b218 100644
--- a/tests/tests/view/src/android/view/cts/FocusFinderTest.java
+++ b/tests/tests/view/src/android/view/cts/FocusFinderTest.java
@@ -121,13 +121,14 @@
          * |   |   |
          * +---+---+
          */
-        Rect rect = new Rect();
-        mTopLeft.getDrawingRect(rect);
-        rect.offset(mTopLeft.getWidth() / 2, 0);
-        rect.inset(mTopLeft.getWidth() / 4, mTopLeft.getHeight() / 4);
+        int buttonHalfWidth = mTopLeft.getWidth() / 2;
+        Rect topRect = new Rect(mTopLeft.getLeft() + buttonHalfWidth,
+                mTopLeft.getTop(),
+                mTopLeft.getRight() + buttonHalfWidth,
+                mTopLeft.getBottom());
 
-        verifytNextFocusFromRect(rect, View.FOCUS_LEFT, mTopLeft);
-        verifytNextFocusFromRect(rect, View.FOCUS_RIGHT, mTopRight);
+        verifytNextFocusFromRect(topRect, View.FOCUS_LEFT, mTopLeft);
+        verifytNextFocusFromRect(topRect, View.FOCUS_RIGHT, mTopRight);
 
         /*
          * Create a small rectangle on the border between the top left and bottom left buttons.
@@ -138,12 +139,14 @@
          * |   |   |
          * +---+---+
          */
-        mTopLeft.getDrawingRect(rect);
-        rect.offset(0, mTopRight.getHeight() / 2);
-        rect.inset(mTopLeft.getWidth() / 4, mTopLeft.getHeight() / 4);
+        int buttonHalfHeight = mTopLeft.getHeight() / 2;
+        Rect leftRect = new Rect(mTopLeft.getLeft(),
+                 mTopLeft.getTop() + buttonHalfHeight,
+                 mTopLeft.getRight(),
+                 mTopLeft.getBottom() + buttonHalfHeight);
 
-        verifytNextFocusFromRect(rect, View.FOCUS_UP, mTopLeft);
-        verifytNextFocusFromRect(rect, View.FOCUS_DOWN, mBottomLeft);
+        verifytNextFocusFromRect(leftRect, View.FOCUS_UP, mTopLeft);
+        verifytNextFocusFromRect(leftRect, View.FOCUS_DOWN, mBottomLeft);
     }
 
     private void verifytNextFocusFromRect(Rect rect, int direction, View expectedNextFocus) {
diff --git a/tests/tests/view/src/android/view/cts/MotionEventTest.java b/tests/tests/view/src/android/view/cts/MotionEventTest.java
index f9b2e4f..f1397fc 100644
--- a/tests/tests/view/src/android/view/cts/MotionEventTest.java
+++ b/tests/tests/view/src/android/view/cts/MotionEventTest.java
@@ -45,6 +45,9 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.LinkedHashSet;
+import java.util.Set;
+
 /**
  * Test {@link MotionEvent}.
  */
@@ -911,4 +914,24 @@
         assertFalse(mMotionEventDynamic.isButtonPressed(MotionEvent.BUTTON_BACK));
         assertTrue(mMotionEventDynamic.isButtonPressed(MotionEvent.BUTTON_FORWARD));
     }
+
+    @Test
+    public void testClassificationConstantsAreUnique() {
+        Set<Integer> values = new LinkedHashSet<>();
+        values.add(MotionEvent.CLASSIFICATION_NONE);
+        values.add(MotionEvent.CLASSIFICATION_AMBIGUOUS_GESTURE);
+        values.add(MotionEvent.CLASSIFICATION_DEEP_PRESS);
+        assertEquals(3, values.size());
+    }
+
+    /**
+     * The motion events 1 and 2 were created using one of the obtain methods.
+     * As a result, they should not have any classification.
+     * Only events generated by the framework are allowed to have classification other than NONE.
+     */
+    @Test
+    public void testGetClassification() {
+        assertEquals(MotionEvent.CLASSIFICATION_NONE, mMotionEvent1.getClassification());
+        assertEquals(MotionEvent.CLASSIFICATION_NONE, mMotionEvent2.getClassification());
+    }
 }
diff --git a/tests/tests/view/src/android/view/cts/PrecompiledLayoutTest.java b/tests/tests/view/src/android/view/cts/PrecompiledLayoutTest.java
new file mode 100644
index 0000000..ca81292
--- /dev/null
+++ b/tests/tests/view/src/android/view/cts/PrecompiledLayoutTest.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2019 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.view.cts;
+
+import android.content.Context;
+import android.os.SystemProperties;
+import android.support.test.InstrumentationRegistry;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class PrecompiledLayoutTest {
+    private LayoutInflater mInflater;
+
+    @Before
+    public void setup() {
+        Context context = InstrumentationRegistry.getTargetContext();
+        mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+    }
+
+    /**
+     * Check whether two layouts are equivalent. We do this by making sure the
+     * classes match, that they have the same ID, and that ViewGroups have the
+     * same children.
+     */
+    private void assertEquivalentLayouts(View lhs, View rhs) {
+        // Make sure both are null or both are not null.
+        Assert.assertEquals(lhs == null, rhs == null);
+        if (lhs == null) {
+            // If the two objects are null, then they are the same.
+            return;
+        }
+
+        // The two views should have the same class and ID
+        Assert.assertSame(lhs.getClass(), rhs.getClass());
+        Assert.assertEquals(lhs.getId(), rhs.getId());
+
+        // If these are ViewGroups, make sure the children are also equivalent.
+        if (lhs instanceof ViewGroup) {
+            ViewGroup lhsGroup = (ViewGroup) lhs;
+            ViewGroup rhsGroup = (ViewGroup) rhs;
+
+            Assert.assertEquals(lhsGroup.getChildCount(), rhsGroup.getChildCount());
+
+            for (int i = 0; i < lhsGroup.getChildCount(); i++) {
+                assertEquivalentLayouts(lhsGroup.getChildAt(i), rhsGroup.getChildAt(i));
+            }
+        }
+    }
+
+    private void compareInflation(int resourceId) {
+        // Inflate without layout precompilation.
+        mInflater.setPrecompiledLayoutsEnabledForTesting(false);
+        View interpreted = mInflater.inflate(resourceId, null);
+
+        // Inflate with layout precompilation
+        mInflater.setPrecompiledLayoutsEnabledForTesting(true);
+        View precompiled = mInflater.inflate(resourceId, null);
+
+        assertEquivalentLayouts(interpreted, precompiled);
+    }
+
+    // The following tests make sure that we get equivalent layouts when
+    // inflated with and without precompilation.
+
+    @Test
+    public void equivalentInflaterLayout() {
+        compareInflation(R.layout.inflater_layout);
+    }
+
+    @Test
+    public void equivalentInflaterOverrideThemeLayout() {
+        compareInflation(R.layout.inflater_override_theme_layout);
+    }
+
+    @Test
+    public void equivalentInflaterLayoutTags() {
+        compareInflation(R.layout.inflater_layout_tags);
+    }
+}
diff --git a/tests/tests/view/src/android/view/cts/SurfaceControlTest.java b/tests/tests/view/src/android/view/cts/SurfaceControlTest.java
index e02b286..f61ead2 100644
--- a/tests/tests/view/src/android/view/cts/SurfaceControlTest.java
+++ b/tests/tests/view/src/android/view/cts/SurfaceControlTest.java
@@ -79,7 +79,7 @@
     @Test
     public void testLifecycle() {
         final SurfaceControl.Builder b = new SurfaceControl.Builder();
-        final SurfaceControl sc = b.build();
+        final SurfaceControl sc = b.setName("CTS").build();
 
         assertTrue("Failed to build SurfaceControl", sc != null);
         assertTrue(sc.isValid());
@@ -90,6 +90,7 @@
     private SurfaceControl buildDefaultSurface(SurfaceControl parent) {
         return new SurfaceControl.Builder()
             .setBufferSize(DEFAULT_BUFFER_WIDTH, DEFAULT_BUFFER_HEIGHT)
+            .setName("CTS surface")
             .setParent(parent)
             .build();
 
diff --git a/tests/tests/view/src/android/view/cts/ViewConfigurationTest.java b/tests/tests/view/src/android/view/cts/ViewConfigurationTest.java
index 2c88b25..aa9dcf1 100644
--- a/tests/tests/view/src/android/view/cts/ViewConfigurationTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewConfigurationTest.java
@@ -17,6 +17,7 @@
 package android.view.cts;
 
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
@@ -83,4 +84,19 @@
         vc.getScaledWindowTouchSlop();
         vc.hasPermanentMenuKey();
     }
+
+    /**
+     * The purpose of the ambiguous gesture multiplier is to potentially increase the touch slop
+     * and the long press timeout to allow the gesture classifier an additional window to
+     * make the classification. Therefore, this multiplier should be always greater or equal to 1.
+     */
+    @Test
+    public void testGetAmbiguousGestureMultiplier() {
+        final float staticMultiplier = ViewConfiguration.getAmbiguousGestureMultiplier();
+        assertTrue(staticMultiplier >= 1);
+
+        ViewConfiguration vc = ViewConfiguration.get(InstrumentationRegistry.getTargetContext());
+        final float instanceMultiplier = vc.getAmbiguousGestureMultiplier();
+        assertTrue(instanceMultiplier >= 1);
+    }
 }
diff --git a/tests/tests/view/src/android/view/cts/ViewSourceLayoutTest.java b/tests/tests/view/src/android/view/cts/ViewSourceLayoutTest.java
new file mode 100644
index 0000000..3a6aa4c
--- /dev/null
+++ b/tests/tests/view/src/android/view/cts/ViewSourceLayoutTest.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2019 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.view.cts;
+
+import static org.junit.Assert.assertEquals;
+
+import android.content.res.Resources;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.View;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class ViewSourceLayoutTest {
+    @Rule
+    public ActivityTestRule<ViewSourceLayoutTestActivity> mActivityRule =
+            new ActivityTestRule<>(ViewSourceLayoutTestActivity.class);
+
+    @Test
+    public void testGetSourceLayout() {
+        ViewSourceLayoutTestActivity activity = mActivityRule.getActivity();
+        View rootView = activity.findViewById(R.id.view_root);
+        assertEquals(R.layout.view_source_layout_test_layout, rootView.getSourceLayoutResId());
+
+        View view1 = activity.findViewById(R.id.view1);
+        assertEquals(R.layout.view_source_layout_test_layout, view1.getSourceLayoutResId());
+
+        View view2 = activity.findViewById(R.id.view2);
+        assertEquals(R.layout.view_source_layout_test_include_layout, view2.getSourceLayoutResId());
+
+        View view3 = new View(activity);
+        assertEquals(Resources.ID_NULL, view3.getSourceLayoutResId());
+    }
+}
diff --git a/tests/tests/debug/src/android/debug/cts/DebugTest.java b/tests/tests/view/src/android/view/cts/ViewSourceLayoutTestActivity.java
similarity index 60%
copy from tests/tests/debug/src/android/debug/cts/DebugTest.java
copy to tests/tests/view/src/android/view/cts/ViewSourceLayoutTestActivity.java
index 993f02b..efb6f02 100644
--- a/tests/tests/debug/src/android/debug/cts/DebugTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewSourceLayoutTestActivity.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2019 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.
@@ -14,12 +14,16 @@
  * limitations under the License.
  */
 
-package android.debug.cts;
+package android.view.cts;
 
-import org.junit.runner.RunWith;
-import com.android.gtestrunner.GtestRunner;
-import com.android.gtestrunner.TargetLibrary;
+import android.app.Activity;
+import android.os.Bundle;
 
-@RunWith(GtestRunner.class)
-@TargetLibrary("debugtest")
-public class DebugTest {}
+public class ViewSourceLayoutTestActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle bundle) {
+        super.onCreate(bundle);
+        setContentView(R.layout.view_source_layout_test_layout);
+    }
+}
diff --git a/tests/tests/view/src/android/view/cts/ViewTest.java b/tests/tests/view/src/android/view/cts/ViewTest.java
index 3168c60..7af6529 100644
--- a/tests/tests/view/src/android/view/cts/ViewTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewTest.java
@@ -4855,6 +4855,30 @@
         }
     }
 
+    @Test
+    public void testSetTransitionVisibility() {
+        MockView view = new MockView(mContext);
+        view.setVisibility(View.GONE);
+        view.setParent(mMockParent);
+        mMockParent.reset();
+
+        // setTransitionVisibility shouldn't trigger requestLayout() on the parent
+        view.setTransitionVisibility(View.VISIBLE);
+
+        assertEquals(View.VISIBLE, view.getVisibility());
+        assertFalse(mMockParent.hasRequestLayout());
+
+        // Reset state
+        view.setVisibility(View.GONE);
+        mMockParent.reset();
+
+        // setVisibility should trigger requestLayout() on the parent
+        view.setVisibility(View.VISIBLE);
+
+        assertEquals(View.VISIBLE, view.getVisibility());
+        assertTrue(mMockParent.hasRequestLayout());
+    }
+
     private static class MockDrawable extends Drawable {
         private boolean mCalledSetTint = false;
 
diff --git a/tests/tests/view/src/android/view/cts/surfacevalidator/PixelColor.java b/tests/tests/view/src/android/view/cts/surfacevalidator/PixelColor.java
index a7395bb..c4d4b95 100644
--- a/tests/tests/view/src/android/view/cts/surfacevalidator/PixelColor.java
+++ b/tests/tests/view/src/android/view/cts/surfacevalidator/PixelColor.java
@@ -20,8 +20,12 @@
     public static final int RED = 0xFF0000FF;
     public static final int GREEN = 0xFF00FF00;
     public static final int BLUE = 0xFFFF0000;
+    public static final int YELLOW = 0xFF00FFFF;
+    public static final int MAGENTA = 0xFFFF00FF;
 
     public static final int TRANSPARENT_RED = 0x7F0000FF;
+    public static final int TRANSPARENT_BLUE = 0x7FFF0000;
+    public static final int TRANSPARENT = 0x00000000;
 
     // Default to black
     public short mMinAlpha;
diff --git a/tests/tests/view/src/android/view/inspector/cts/GeneratedInspectionCompanionProviderTest.java b/tests/tests/view/src/android/view/inspector/cts/GeneratedInspectionCompanionProviderTest.java
new file mode 100644
index 0000000..a9bbd08
--- /dev/null
+++ b/tests/tests/view/src/android/view/inspector/cts/GeneratedInspectionCompanionProviderTest.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2019 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.view.inspector.cts;
+
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.View;
+import android.view.inspector.GeneratedInspectionCompanionProvider;
+import android.view.inspector.InspectionCompanion;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests for {@link GeneratedInspectionCompanionProvider}
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class GeneratedInspectionCompanionProviderTest {
+    private GeneratedInspectionCompanionProvider mProvider;
+
+    @Before
+    public void setup() {
+        mProvider = new GeneratedInspectionCompanionProvider();
+    }
+
+    @Test
+    public void testViewWorks() {
+        InspectionCompanion<View> companion = mProvider.provide(View.class);
+        assertNotNull(companion);
+        assertEquals("android.view.View$$InspectionCompanion", companion.getClass().getName());
+    }
+}
diff --git a/tests/tests/view/src/android/view/textclassifier/cts/ConversationActionsTest.java b/tests/tests/view/src/android/view/textclassifier/cts/ConversationActionsTest.java
index 8e34571..484644f 100644
--- a/tests/tests/view/src/android/view/textclassifier/cts/ConversationActionsTest.java
+++ b/tests/tests/view/src/android/view/textclassifier/cts/ConversationActionsTest.java
@@ -313,7 +313,7 @@
         assertThat(request.getConversation().get(0).getText().toString()).isEqualTo(TEXT);
         assertThat(request.getConversation().get(0).getAuthor()).isEqualTo(PERSON);
         assertThat(request.getHints()).isEmpty();
-        assertThat(request.getMaxSuggestions()).isEqualTo(0);
+        assertThat(request.getMaxSuggestions()).isEqualTo(-1);
         assertThat(request.getTypeConfig()).isNotNull();
         assertThat(request.getConversationId()).isNull();
     }
diff --git a/tests/tests/voicesettings/AndroidTest.xml b/tests/tests/voicesettings/AndroidTest.xml
index 5b97823..7bdb094 100644
--- a/tests/tests/voicesettings/AndroidTest.xml
+++ b/tests/tests/voicesettings/AndroidTest.xml
@@ -16,6 +16,8 @@
 <configuration description="Config for CTS Voice Settings test cases">
     <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="framework" />
+    <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
     <option name="not-shardable" value="true" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
@@ -27,7 +29,9 @@
 
         <!-- Close the "turn on battery saver?" dialog, and wait for the broadcast queue to drain. -->
         <option name="teardown-command" value="am broadcast --receiver-foreground -a android.intent.action.CLOSE_SYSTEM_DIALOGS" />
+        <!-- TODO(b/123958025): disabled because it hangs most of the time
         <option name="teardown-command" value="am wait-for-broadcast-idle" />
+        -->
     </target_preparer>
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="android.voicesettings.cts" />
diff --git a/tests/tests/voicesettings/src/android/voicesettings/cts/AirplaneModeTest.java b/tests/tests/voicesettings/src/android/voicesettings/cts/AirplaneModeTest.java
index db6bbb9..2ef1999 100644
--- a/tests/tests/voicesettings/src/android/voicesettings/cts/AirplaneModeTest.java
+++ b/tests/tests/voicesettings/src/android/voicesettings/cts/AirplaneModeTest.java
@@ -40,6 +40,7 @@
         super.setUp();
         mContext = getInstrumentation().getTargetContext();
         mHasFeature = mContext.getPackageManager().hasSystemFeature(FEATURE_VOICE_RECOGNIZERS);
+        Log.v(TAG, "setUp(): mHasFeature=" + mHasFeature);
     }
 
     public AirplaneModeTest() {
@@ -84,6 +85,7 @@
             }
             runTest(BroadcastUtils.TestcaseType.AIRPLANE_MODE_ON, AIRPLANE_MODE_IS_ON);
         }
+        Log.i(TAG, "All done!");
     }
 
     private boolean runTest(BroadcastUtils.TestcaseType test, int expectedMode) throws Exception {
diff --git a/tests/tests/webkit/src/android/webkit/cts/CookieTest.java b/tests/tests/webkit/src/android/webkit/cts/CookieTest.java
index 887b891..11a4482 100644
--- a/tests/tests/webkit/src/android/webkit/cts/CookieTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/CookieTest.java
@@ -68,11 +68,11 @@
         // basic
         mCookieManager.setCookie(url, "a=b");
         String cookie = mCookieManager.getCookie(url);
-        assertTrue(cookie.equals("a=b"));
+        assertEquals("a=b", cookie);
 
         // no cross domain cookie
         cookie = mCookieManager.getCookie("http://bar.com");
-        assertTrue(cookie == null);
+        assertNull(cookie);
 
         // more than one cookie
         mCookieManager.setCookie(url, "c=d; domain=.foo.com");
@@ -82,7 +82,7 @@
 
         // host cookie should not be accessible from a sub-domain.
         cookie = mCookieManager.getCookie("http://bar.www.foo.com");
-        assertTrue(cookie.equals("c=d"));
+        assertEquals("c=d", cookie);
 
         // test setting a domain= that doesn't start w/ a dot, should
         // treat it as a domain cookie, as if there was a pre-pended dot.
@@ -97,7 +97,7 @@
         assertTrue(cookie.contains("e=f"));
 
         cookie = mCookieManager.getCookie("http://foo.com");
-        assertTrue(cookie.equals("c=d"));
+        assertEquals("c=d", cookie);
     }
 
     public void testSubDomain() {
@@ -127,7 +127,7 @@
         assertTrue(cookie.contains("c=3"));
         assertTrue(cookie.contains("d=4"));
         cookie = mCookieManager.getCookie(url_d);
-        assertTrue(cookie.equals("d=4"));
+        assertEquals("d=4", cookie);
 
         // check that the same cookie can exist on different sub-domains.
         mCookieManager.setCookie(url_bcd, "x=bcd; domain=.b.c.d.com");
@@ -152,35 +152,35 @@
 
         mCookieManager.setCookie(url, "a=1; domain=.yo.foo.bar.com");
         String cookie = mCookieManager.getCookie(url);
-        assertTrue(cookie == null);
+        assertNull(cookie);
 
         mCookieManager.setCookie(url, "b=2; domain=.foo.com");
         cookie = mCookieManager.getCookie(url);
-        assertTrue(cookie == null);
+        assertNull(cookie);
 
         mCookieManager.setCookie(url, "c=3; domain=.bar.foo.com");
         cookie = mCookieManager.getCookie(url);
-        assertTrue(cookie == null);
+        assertNull(cookie);
 
         mCookieManager.setCookie(url, "d=4; domain=.foo.bar.com.net");
         cookie = mCookieManager.getCookie(url);
-        assertTrue(cookie == null);
+        assertNull(cookie);
 
         mCookieManager.setCookie(url, "e=5; domain=.ar.com");
         cookie = mCookieManager.getCookie(url);
-        assertTrue(cookie == null);
+        assertNull(cookie);
 
         mCookieManager.setCookie(url, "f=6; domain=.com");
         cookie = mCookieManager.getCookie(url);
-        assertTrue(cookie == null);
+        assertNull(cookie);
 
         mCookieManager.setCookie(url, "g=7; domain=.co.uk");
         cookie = mCookieManager.getCookie(url);
-        assertTrue(cookie == null);
+        assertNull(cookie);
 
         mCookieManager.setCookie(url, "h=8; domain=.foo.bar.com.com");
         cookie = mCookieManager.getCookie(url);
-        assertTrue(cookie == null);
+        assertNull(cookie);
     }
 
     public void testPath() {
@@ -191,28 +191,28 @@
 
         mCookieManager.setCookie(url, "a=b; path=/wee");
         String cookie = mCookieManager.getCookie(url + "/wee");
-        assertTrue(cookie.equals("a=b"));
+        assertEquals("a=b", cookie);
         cookie = mCookieManager.getCookie(url + "/wee/");
-        assertTrue(cookie.equals("a=b"));
+        assertEquals("a=b", cookie);
         cookie = mCookieManager.getCookie(url + "/wee/hee");
-        assertTrue(cookie.equals("a=b"));
+        assertEquals("a=b", cookie);
         cookie = mCookieManager.getCookie(url + "/wee/hee/more");
-        assertTrue(cookie.equals("a=b"));
+        assertEquals("a=b", cookie);
         cookie = mCookieManager.getCookie(url + "/weehee");
-        assertTrue(cookie == null);
+        assertNull(cookie);
         cookie = mCookieManager.getCookie(url);
-        assertTrue(cookie == null);
+        assertNull(cookie);
 
         mCookieManager.setCookie(url, "a=c; path=");
         cookie = mCookieManager.getCookie(url + "/wee");
         // order of contents matters in this case, per spec
-        assertTrue(cookie.equals("a=b; a=c"));
+        assertEquals("a=b; a=c", cookie);
         cookie = mCookieManager.getCookie(url);
-        assertTrue(cookie.equals("a=c"));
+        assertEquals("a=c", cookie);
 
         mCookieManager.setCookie(url, "a=d");
         cookie = mCookieManager.getCookie(url + "/wee");
-        assertTrue(cookie.equals("a=b; a=d"));
+        assertEquals("a=b; a=d", cookie);
     }
 
     public void testEmptyValue() {
@@ -223,14 +223,14 @@
 
         mCookieManager.setCookie(url, "bar=");
         String cookie = mCookieManager.getCookie(url);
-        assertTrue(cookie.equals("bar="));
+        assertEquals("bar=", cookie);
 
         mCookieManager.setCookie(url, "foobar=;");
         cookie = mCookieManager.getCookie(url);
-        assertTrue(cookie.equals("bar=; foobar="));
+        assertEquals("bar=; foobar=", cookie);
 
         mCookieManager.setCookie(url, "baz=; path=/wee");
         cookie = mCookieManager.getCookie(url + "/wee");
-        assertTrue(cookie.equals("baz=; bar=; foobar="));
+        assertEquals("baz=; bar=; foobar=", cookie);
     }
 }
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java
index 1146e25..8f08dc7 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java
@@ -307,7 +307,7 @@
         mOnUiThread.setWebViewClient(webViewClient);
         mWebServer = new CtsTestServer(getActivity());
 
-        assertEquals(null, webViewClient.hasOnReceivedResourceError());
+        assertNull(webViewClient.hasOnReceivedResourceError());
         String url = mWebServer.getAssetUrl(TestHtmlConstants.BAD_IMAGE_PAGE_URL);
         mOnUiThread.loadUrlAndWaitForCompletion(url);
         assertTrue(webViewClient.hasOnReceivedResourceError() != null);
@@ -323,7 +323,7 @@
         mOnUiThread.setWebViewClient(webViewClient);
         mWebServer = new CtsTestServer(getActivity());
 
-        assertEquals(null, webViewClient.hasOnReceivedHttpError());
+        assertNull(webViewClient.hasOnReceivedHttpError());
         String url = mWebServer.getAssetUrl(TestHtmlConstants.NON_EXISTENT_PAGE_URL);
         mOnUiThread.loadUrlAndWaitForCompletion(url);
         assertTrue(webViewClient.hasOnReceivedHttpError() != null);
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewSslTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewSslTest.java
index 7fd8fc8..5006641 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewSslTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewSslTest.java
@@ -756,20 +756,20 @@
         mOnUiThread.setWebViewClient(webViewClient);
         clearClientCertPreferences();
         mOnUiThread.loadUrlAndWaitForCompletion(url);
-        assertTrue(TestHtmlConstants.HELLO_WORLD_TITLE.equals(mOnUiThread.getTitle()));
+        assertEquals(TestHtmlConstants.HELLO_WORLD_TITLE, mOnUiThread.getTitle());
 
         // Test that the user's response for this server is kept in cache. Load a different
         // page from the same server and make sure we don't receive a client cert request callback.
         int callCount = webViewClient.getClientCertRequestCount();
         url = mWebServer.getAssetUrl(TestHtmlConstants.HTML_URL1);
         mOnUiThread.loadUrlAndWaitForCompletion(url);
-        assertTrue(TestHtmlConstants.HTML_URL1_TITLE.equals(mOnUiThread.getTitle()));
+        assertEquals(TestHtmlConstants.HTML_URL1_TITLE, mOnUiThread.getTitle());
         assertEquals(callCount, webViewClient.getClientCertRequestCount());
 
         // Now clear the cache and reload the page. We should receive a new callback.
         clearClientCertPreferences();
         mOnUiThread.loadUrlAndWaitForCompletion(url);
-        assertTrue(TestHtmlConstants.HTML_URL1_TITLE.equals(mOnUiThread.getTitle()));
+        assertEquals(TestHtmlConstants.HTML_URL1_TITLE, mOnUiThread.getTitle());
         assertEquals(callCount + 1, webViewClient.getClientCertRequestCount());
     }
 
@@ -786,20 +786,20 @@
         mOnUiThread.setWebViewClient(webViewClient);
         clearClientCertPreferences();
         mOnUiThread.loadUrlAndWaitForCompletion(url);
-        assertTrue(TestHtmlConstants.HELLO_WORLD_TITLE.equals(mOnUiThread.getTitle()));
+        assertEquals(TestHtmlConstants.HELLO_WORLD_TITLE, mOnUiThread.getTitle());
 
         // Test that the user's response for this server is kept in cache. Load a different
         // page from the same server and make sure we don't receive a client cert request callback.
         int callCount = webViewClient.getClientCertRequestCount();
         url = mWebServer.getAssetUrl(TestHtmlConstants.HTML_URL1);
         mOnUiThread.loadUrlAndWaitForCompletion(url);
-        assertTrue(TestHtmlConstants.HTML_URL1_TITLE.equals(mOnUiThread.getTitle()));
+        assertEquals(TestHtmlConstants.HTML_URL1_TITLE, mOnUiThread.getTitle());
         assertEquals(callCount, webViewClient.getClientCertRequestCount());
 
         // Now clear the cache and reload the page. We should receive a new callback.
         clearClientCertPreferences();
         mOnUiThread.loadUrlAndWaitForCompletion(url);
-        assertTrue(TestHtmlConstants.HTML_URL1_TITLE.equals(mOnUiThread.getTitle()));
+        assertEquals(TestHtmlConstants.HTML_URL1_TITLE, mOnUiThread.getTitle());
         assertEquals(callCount + 1, webViewClient.getClientCertRequestCount());
     }
 
@@ -831,7 +831,7 @@
         webViewClient.setAction(ClientCertWebViewClient.PROCEED);
         url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
         mOnUiThread.loadUrlAndWaitForCompletion(url);
-        assertTrue(TestHtmlConstants.HELLO_WORLD_TITLE.equals(mOnUiThread.getTitle()));
+        assertEquals(TestHtmlConstants.HELLO_WORLD_TITLE, mOnUiThread.getTitle());
     }
 
     public void testCancelClientCertRequest() throws Throwable {
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
index 2f95f82..bbaac70 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
@@ -1133,7 +1133,7 @@
             result = mWebView.getHttpAuthUsernamePassword(host, realm);
             assertNotNull(result);
             assertEquals(userName, result[0]);
-            assertEquals(null, result[1]);
+            assertNull(result[1]);
 
             mWebView.setHttpAuthUsernamePassword(host, realm, null, null);
             result = mWebView.getHttpAuthUsernamePassword(host, realm);
@@ -1201,7 +1201,7 @@
             result = webViewDb.getHttpAuthUsernamePassword(host, realm);
             assertNotNull(result);
             assertEquals(userName, result[0]);
-            assertEquals(null, result[1]);
+            assertNull(result[1]);
 
             webViewDb.setHttpAuthUsernamePassword(host, realm, null, null);
             result = webViewDb.getHttpAuthUsernamePassword(host, realm);
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebView_WebViewTransportTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewTransportTest.java
similarity index 94%
rename from tests/tests/webkit/src/android/webkit/cts/WebView_WebViewTransportTest.java
rename to tests/tests/webkit/src/android/webkit/cts/WebViewTransportTest.java
index b4e4d04..b35f7bc 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebView_WebViewTransportTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewTransportTest.java
@@ -23,10 +23,10 @@
 
 import com.android.compatibility.common.util.NullWebViewUtils;
 
-public class WebView_WebViewTransportTest
+public class WebViewTransportTest
         extends ActivityInstrumentationTestCase2<WebViewCtsActivity> {
 
-    public WebView_WebViewTransportTest() {
+    public WebViewTransportTest() {
         super("android.webkit.cts", WebViewCtsActivity.class);
     }
 
diff --git a/tests/tests/widget/src/android/widget/cts/AbsListViewTest.java b/tests/tests/widget/src/android/widget/cts/AbsListViewTest.java
index 7bbc08a..49b0f64 100644
--- a/tests/tests/widget/src/android/widget/cts/AbsListViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/AbsListViewTest.java
@@ -763,7 +763,7 @@
         mActivityRule.runOnUiThread(() -> mListView.setItemChecked(0, false));
         assertFalse(mListView.isLayoutRequested());
     }
-
+    private boolean checkResult = false;
     @MediumTest
     @Test
     public void testSetItemChecked_multipleModeDifferentValue() throws Throwable {
@@ -773,8 +773,15 @@
         mActivityRule.runOnUiThread(() -> mListView.setItemChecked(0, false));
         mInstrumentation.waitForIdleSync();
         assertFalse(mListView.isLayoutRequested());
-        mActivityRule.runOnUiThread(() -> mListView.setItemChecked(0, true));
-        assertTrue(mListView.isLayoutRequested());
+        checkResult = false;
+        mActivityRule.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mListView.setItemChecked(0, true);
+                checkResult = mListView.isLayoutRequested();
+            }
+        });
+        assertTrue(checkResult);
     }
 
     @MediumTest
@@ -786,8 +793,15 @@
         mActivityRule.runOnUiThread(() -> mListView.setItemChecked(0, false));
         mInstrumentation.waitForIdleSync();
         assertFalse(mListView.isLayoutRequested());
-        mActivityRule.runOnUiThread(() -> mListView.setItemChecked(0, true));
-        assertTrue(mListView.isLayoutRequested());
+        checkResult = false;
+        mActivityRule.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mListView.setItemChecked(0, true);
+                checkResult = mListView.isLayoutRequested();
+            }
+        });
+        assertTrue(checkResult);
     }
 
     @LargeTest
diff --git a/tests/tests/widget/src/android/widget/cts/MagnifierTest.java b/tests/tests/widget/src/android/widget/cts/MagnifierTest.java
index 786a3fb..3a20640 100644
--- a/tests/tests/widget/src/android/widget/cts/MagnifierTest.java
+++ b/tests/tests/widget/src/android/widget/cts/MagnifierTest.java
@@ -73,6 +73,7 @@
 public class MagnifierTest {
     private static final String TIME_LIMIT_EXCEEDED =
             "Completing the magnifier operation took too long";
+    private static final float PIXEL_COMPARISON_DELTA = 1f;
 
     private Activity mActivity;
     private LinearLayout mLayout;
@@ -303,19 +304,19 @@
         final Point sourcePosition = mMagnifier.getSourcePosition();
         assertNotNull(sourcePosition);
         assertEquals(xCenter + mViewLocationInSurface[0],
-                sourcePosition.x + mMagnifier.getSourceWidth() / 2f, 0.01f);
+                sourcePosition.x + mMagnifier.getSourceWidth() / 2f, PIXEL_COMPARISON_DELTA);
         assertEquals(yCenter + mViewLocationInSurface[1],
-                sourcePosition.y + mMagnifier.getSourceHeight() / 2f, 0.01f);
+                sourcePosition.y + mMagnifier.getSourceHeight() / 2f, PIXEL_COMPARISON_DELTA);
 
         // Check the coordinates of the magnifier.
         final Point magnifierPosition = mMagnifier.getPosition();
         assertNotNull(magnifierPosition);
         assertEquals(sourcePosition.x + mMagnifier.getDefaultHorizontalSourceToMagnifierOffset()
                         - mMagnifier.getWidth() / 2f + mMagnifier.getSourceWidth() / 2f,
-                magnifierPosition.x, 0.01f);
+                magnifierPosition.x, PIXEL_COMPARISON_DELTA);
         assertEquals(sourcePosition.y + mMagnifier.getDefaultVerticalSourceToMagnifierOffset()
                         - mMagnifier.getHeight() / 2f + mMagnifier.getSourceHeight() / 2f,
-                magnifierPosition.y, 0.01f);
+                magnifierPosition.y, PIXEL_COMPARISON_DELTA);
     }
 
     @Test
@@ -339,10 +340,10 @@
         assertNotNull(magnifierPosition);
         assertEquals(
                 mViewLocationInSurface[0] + xMagnifier - mMagnifier.getWidth() / 2,
-                magnifierPosition.x, 0.01f);
+                magnifierPosition.x, PIXEL_COMPARISON_DELTA);
         assertEquals(
                 mViewLocationInSurface[1] + yMagnifier - mMagnifier.getHeight() / 2,
-                magnifierPosition.y, 0.01f);
+                magnifierPosition.y, PIXEL_COMPARISON_DELTA);
     }
 
     //***** Tests for #dismiss() *****//
@@ -423,8 +424,10 @@
         final Rect surfaceInsets = mLayout.getViewRootImpl().mWindowAttributes.surfaceInsets;
         final Point magnifierCoords = mMagnifier.getPosition();
         assertNotNull(magnifierCoords);
-        assertEquals(systemInsets.left + surfaceInsets.left, magnifierCoords.x);
-        assertEquals(systemInsets.top + surfaceInsets.top, magnifierCoords.y);
+        assertEquals(systemInsets.left + surfaceInsets.left, magnifierCoords.x,
+                PIXEL_COMPARISON_DELTA);
+        assertEquals(systemInsets.top + surfaceInsets.top, magnifierCoords.y,
+                PIXEL_COMPARISON_DELTA);
     }
 
     @Test
@@ -444,10 +447,10 @@
         assertNotNull(magnifierCoords);
         assertEquals(mLayout.getViewRootImpl().getWidth()
                         - systemInsets.right - mMagnifier.getWidth() + surfaceInsets.left,
-                magnifierCoords.x);
+                magnifierCoords.x, PIXEL_COMPARISON_DELTA);
         assertEquals(mLayout.getViewRootImpl().getHeight()
                         - systemInsets.bottom - mMagnifier.getHeight() + surfaceInsets.top,
-                magnifierCoords.y);
+                magnifierCoords.y, PIXEL_COMPARISON_DELTA);
     }
 
     @Test
@@ -466,8 +469,10 @@
         final int[] magnifiedViewPosition = new int[2];
         mLayout.getLocationInSurface(magnifiedViewPosition);
         assertNotNull(magnifierCoords);
-        assertEquals(magnifiedViewPosition[0] - 3 * mMagnifier.getWidth() / 2, magnifierCoords.x);
-        assertEquals(magnifiedViewPosition[1] - 3 * mMagnifier.getHeight() / 2, magnifierCoords.y);
+        assertEquals(magnifiedViewPosition[0] - 3 * mMagnifier.getWidth() / 2, magnifierCoords.x,
+                PIXEL_COMPARISON_DELTA);
+        assertEquals(magnifiedViewPosition[1] - 3 * mMagnifier.getHeight() / 2, magnifierCoords.y,
+                PIXEL_COMPARISON_DELTA);
     }
 
     @Test
@@ -490,11 +495,9 @@
         mLayout.getLocationInSurface(magnifiedViewPosition);
         assertNotNull(magnifierCoords);
         assertEquals(magnifiedViewPosition[0] + mLayout.getViewRootImpl().getWidth()
-                        + mMagnifier.getWidth() / 2,
-                magnifierCoords.x);
+                        + mMagnifier.getWidth() / 2, magnifierCoords.x, PIXEL_COMPARISON_DELTA);
         assertEquals(magnifiedViewPosition[1] + mLayout.getViewRootImpl().getHeight()
-                        + mMagnifier.getHeight() / 2,
-                magnifierCoords.y);
+                        + mMagnifier.getHeight() / 2, magnifierCoords.y, PIXEL_COMPARISON_DELTA);
     }
 
     @Test
@@ -515,9 +518,9 @@
         final Point sourceCoords = mMagnifier.getSourcePosition();
         assertNotNull(magnifierCoords);
         assertEquals(sourceCoords.x + mMagnifier.getSourceWidth() / 2f + horizontalOffset,
-                magnifierCoords.x + mMagnifier.getWidth() / 2f, 0.01f);
+                magnifierCoords.x + mMagnifier.getWidth() / 2f, PIXEL_COMPARISON_DELTA);
         assertEquals(sourceCoords.y + mMagnifier.getSourceHeight() / 2f + verticalOffset,
-                magnifierCoords.y + mMagnifier.getHeight() / 2f, 0.01f);
+                magnifierCoords.y + mMagnifier.getHeight() / 2f, PIXEL_COMPARISON_DELTA);
     }
 
     @Test
@@ -589,14 +592,14 @@
         showMagnifier(view.getWidth() / 4, 0);
         Point sourcePosition = mMagnifier.getSourcePosition();
         assertNotNull(sourcePosition);
-        assertEquals(containerPosition[0], sourcePosition.x);
+        assertEquals(containerPosition[0], sourcePosition.x, PIXEL_COMPARISON_DELTA);
 
         // Try to copy from an x to the right of the currently visible region.
         showMagnifier(3 * view.getWidth() / 4, 0);
         sourcePosition = mMagnifier.getSourcePosition();
         assertNotNull(sourcePosition);
-        assertEquals(containerPosition[0] + container.getWidth() - mMagnifier.getSourceWidth() + 1,
-                sourcePosition.x);
+        assertEquals(containerPosition[0] + container.getWidth() - mMagnifier.getSourceWidth(),
+                sourcePosition.x, PIXEL_COMPARISON_DELTA);
     }
 
     @Test
@@ -631,52 +634,14 @@
         showMagnifier(0, view.getHeight() / 4);
         Point sourcePosition = mMagnifier.getSourcePosition();
         assertNotNull(sourcePosition);
-        assertEquals(containerPosition[1], sourcePosition.y);
+        assertEquals(containerPosition[1], sourcePosition.y, PIXEL_COMPARISON_DELTA);
 
         // Try to copy from an x below the currently visible region.
         showMagnifier(0, 3 * view.getHeight() / 4);
         sourcePosition = mMagnifier.getSourcePosition();
         assertNotNull(sourcePosition);
         assertEquals(containerPosition[1] + container.getHeight() - mMagnifier.getSourceHeight(),
-                sourcePosition.y);
-    }
-
-    @Test
-    public void testSourcePosition_respectsMaxInViewBounds() throws Throwable {
-        WidgetTestUtils.runOnMainAndLayoutSync(mActivityRule, () -> {
-            mActivity.setContentView(R.layout.magnifier_activity_centered_view_layout);
-        }, false /*forceLayout*/);
-        final View view = mActivity.findViewById(R.id.magnifier_centered_view);
-        final Magnifier.Builder builder = new Magnifier.Builder(view)
-                .setSize(100, 100)
-                .setInitialZoom(10f) /* 10x10 source size */
-                .setSourceBounds(
-                        Magnifier.SOURCE_BOUND_MAX_IN_VIEW,
-                        Magnifier.SOURCE_BOUND_MAX_IN_VIEW,
-                        Magnifier.SOURCE_BOUND_MAX_IN_VIEW,
-                        Magnifier.SOURCE_BOUND_MAX_IN_VIEW
-                );
-
-        runOnUiThreadAndWaitForCompletion(() -> mMagnifier = builder.build());
-
-        final int[] viewPosition = new int[2];
-        view.getLocationInSurface(viewPosition);
-
-        // Copy content centered on relative position (0, 0) and expect the top left
-        // corner of the source to have been pulled to coincide with (0, 0) of the view.
-        showMagnifier(0, 0);
-        Point sourcePosition = mMagnifier.getSourcePosition();
-        assertNotNull(sourcePosition);
-        assertEquals(viewPosition[0], sourcePosition.x);
-        assertEquals(viewPosition[1], sourcePosition.y);
-
-        showMagnifier(view.getWidth(), view.getHeight());
-        sourcePosition = mMagnifier.getSourcePosition();
-        assertNotNull(sourcePosition);
-        assertEquals(viewPosition[0] + view.getWidth() - mMagnifier.getSourceWidth(),
-                sourcePosition.x);
-        assertEquals(viewPosition[1] + view.getHeight() - mMagnifier.getSourceHeight(),
-                sourcePosition.y);
+                sourcePosition.y, PIXEL_COMPARISON_DELTA);
     }
 
     @Test
@@ -705,8 +670,10 @@
         showMagnifier(0, 0);
         Point sourcePosition = mMagnifier.getSourcePosition();
         assertNotNull(sourcePosition);
-        assertEquals(viewPosition[0] - mMagnifier.getSourceWidth() / 2, sourcePosition.x);
-        assertEquals(viewPosition[1] - mMagnifier.getSourceHeight() / 2, sourcePosition.y);
+        assertEquals(viewPosition[0] - mMagnifier.getSourceWidth() / 2, sourcePosition.x,
+                PIXEL_COMPARISON_DELTA);
+        assertEquals(viewPosition[1] - mMagnifier.getSourceHeight() / 2, sourcePosition.y,
+                PIXEL_COMPARISON_DELTA);
 
         // Copy content centered on the bottom right corner of the view and expect the top left
         // corner of the source NOT to have been pulled inside the view.
@@ -714,17 +681,17 @@
         sourcePosition = mMagnifier.getSourcePosition();
         assertNotNull(sourcePosition);
         assertEquals(viewPosition[0] + view.getWidth() - mMagnifier.getSourceWidth() / 2,
-                sourcePosition.x);
+                sourcePosition.x, PIXEL_COMPARISON_DELTA);
         assertEquals(viewPosition[1] + view.getHeight() - mMagnifier.getSourceHeight() / 2,
-                sourcePosition.y);
+                sourcePosition.y, PIXEL_COMPARISON_DELTA);
 
         // Copy content centered on the top left corner of the main app surface and expect the top
         // left corner of the source to have been pulled to the top left corner of the surface.
         showMagnifier(-viewPosition[0], -viewPosition[1]);
         sourcePosition = mMagnifier.getSourcePosition();
         assertNotNull(sourcePosition);
-        assertEquals(0, sourcePosition.x);
-        assertEquals(0, sourcePosition.y);
+        assertEquals(0, sourcePosition.x, PIXEL_COMPARISON_DELTA);
+        assertEquals(0, sourcePosition.y, PIXEL_COMPARISON_DELTA);
 
         // Copy content centered on the bottom right corner of the main app surface and expect the
         // source to have been pulled inside the surface at its bottom right.
@@ -737,8 +704,10 @@
                 surfaceHeight - viewPosition[1] + view.getHeight());
         sourcePosition = mMagnifier.getSourcePosition();
         assertNotNull(sourcePosition);
-        assertEquals(surfaceWidth - mMagnifier.getSourceWidth(), sourcePosition.x);
-        assertEquals(surfaceHeight - mMagnifier.getSourceHeight(), sourcePosition.y);
+        assertEquals(surfaceWidth - mMagnifier.getSourceWidth(), sourcePosition.x,
+                PIXEL_COMPARISON_DELTA);
+        assertEquals(surfaceHeight - mMagnifier.getSourceHeight(), sourcePosition.y,
+                PIXEL_COMPARISON_DELTA);
     }
 
     @Test
@@ -765,8 +734,8 @@
         showMagnifier(0, 0);
         Point sourcePosition = mMagnifier.getSourcePosition();
         assertNotNull(sourcePosition);
-        assertEquals(0, sourcePosition.x);
-        assertEquals(0, sourcePosition.y);
+        assertEquals(0, sourcePosition.x, PIXEL_COMPARISON_DELTA);
+        assertEquals(0, sourcePosition.y, PIXEL_COMPARISON_DELTA);
 
         // Copy content centered on the bottom right corner of the view and expect the top left
         // corner of the source to have been pulled inside the surface view.
@@ -780,8 +749,10 @@
         showMagnifier(view.getWidth() / 2, view.getHeight() / 2);
         sourcePosition = mMagnifier.getSourcePosition();
         assertNotNull(sourcePosition);
-        assertEquals(view.getWidth() / 2 - mMagnifier.getSourceWidth() / 2, sourcePosition.x);
-        assertEquals(view.getHeight() / 2 - mMagnifier.getSourceHeight() / 2, sourcePosition.y);
+        assertEquals(view.getWidth() / 2 - mMagnifier.getSourceWidth() / 2, sourcePosition.x,
+                PIXEL_COMPARISON_DELTA);
+        assertEquals(view.getHeight() / 2 - mMagnifier.getSourceHeight() / 2, sourcePosition.y,
+                PIXEL_COMPARISON_DELTA);
     }
 
     @Test
@@ -796,10 +767,10 @@
                         2 * view.getHeight() + systemInsets.bottom)
                 .setInitialZoom(1f) /* source double the size of the view + right/bottom insets */
                 .setSourceBounds(/* invalid bounds */
-                        Magnifier.SOURCE_BOUND_MAX_IN_VIEW,
-                        Magnifier.SOURCE_BOUND_MAX_IN_VIEW,
-                        Magnifier.SOURCE_BOUND_MAX_IN_VIEW,
-                        Magnifier.SOURCE_BOUND_MAX_IN_VIEW
+                        Magnifier.SOURCE_BOUND_MAX_VISIBLE,
+                        Magnifier.SOURCE_BOUND_MAX_VISIBLE,
+                        Magnifier.SOURCE_BOUND_MAX_VISIBLE,
+                        Magnifier.SOURCE_BOUND_MAX_VISIBLE
                 );
 
         runOnUiThreadAndWaitForCompletion(() -> mMagnifier = builder.build());
@@ -811,8 +782,8 @@
         // for this source size, when the view is centered.
         showMagnifier(0, 0);
         Point sourcePosition = mMagnifier.getSourcePosition();
-        assertEquals(viewPosition[0], sourcePosition.x);
-        assertEquals(viewPosition[1], sourcePosition.y);
+        assertEquals(viewPosition[0], sourcePosition.x, PIXEL_COMPARISON_DELTA);
+        assertEquals(viewPosition[1], sourcePosition.y, PIXEL_COMPARISON_DELTA);
 
         // Move the magnified view to the top left of the screen, and make sure that
         // the top and left bounds are still respected.
@@ -826,8 +797,8 @@
 
         showMagnifier(0, 0);
         sourcePosition = mMagnifier.getSourcePosition();
-        assertEquals(viewPosition[0], sourcePosition.x);
-        assertEquals(viewPosition[1], sourcePosition.y);
+        assertEquals(viewPosition[0], sourcePosition.x, PIXEL_COMPARISON_DELTA);
+        assertEquals(viewPosition[1], sourcePosition.y, PIXEL_COMPARISON_DELTA);
 
         // Move the magnified view to the bottom right of the layout, and expect the top and left
         // bounds to have been shifted such that the source sits inside the surface.
@@ -841,8 +812,8 @@
 
         showMagnifier(0, 0);
         sourcePosition = mMagnifier.getSourcePosition();
-        assertEquals(viewPosition[0] - view.getWidth(), sourcePosition.x);
-        assertEquals(viewPosition[1] - view.getHeight(), sourcePosition.y);
+        assertEquals(viewPosition[0] - view.getWidth(), sourcePosition.x, PIXEL_COMPARISON_DELTA);
+        assertEquals(viewPosition[1] - view.getHeight(), sourcePosition.y, PIXEL_COMPARISON_DELTA);
     }
 
     //***** Tests for zoom change *****//
diff --git a/tests/tests/widget/src/android/widget/cts/PopupMenuTest.java b/tests/tests/widget/src/android/widget/cts/PopupMenuTest.java
index e76382e..0456667 100644
--- a/tests/tests/widget/src/android/widget/cts/PopupMenuTest.java
+++ b/tests/tests/widget/src/android/widget/cts/PopupMenuTest.java
@@ -29,6 +29,9 @@
 import android.app.Activity;
 import android.app.Instrumentation;
 import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.annotation.UiThreadTest;
 import android.support.test.filters.MediumTest;
@@ -339,6 +342,42 @@
         teardown();
     }
 
+    @Test
+    public void testForceShowIcon_enabled() throws Throwable {
+        testForceShowIcon(true);
+    }
+
+    @Test
+    public void testForceShowIcon_disabled() throws Throwable {
+        testForceShowIcon(false);
+    }
+
+    private void testForceShowIcon(boolean forceShowIcon) throws Throwable {
+        mBuilder = new Builder().withForceShowIcon(forceShowIcon);
+        WidgetTestUtils.runOnMainAndLayoutSync(mActivityRule, mBuilder::configure, true);
+        final TestColorDrawable drawable = new TestColorDrawable(Color.BLUE);
+        mPopupMenu.getMenu().getItem(0).setIcon(drawable);
+        WidgetTestUtils.runOnMainAndDrawSync(
+                mActivityRule,
+                mActivity.findViewById(R.id.anchor_middle_left),
+                mBuilder::show
+        );
+        assertEquals(forceShowIcon, drawable.mWasDrawn);
+    }
+
+    private class TestColorDrawable extends ColorDrawable {
+        boolean mWasDrawn = false;
+        TestColorDrawable(final int color) {
+            super(color);
+        }
+
+        @Override
+        public void draw(Canvas canvas) {
+            super.draw(canvas);
+            mWasDrawn = true;
+        }
+    }
+
     /**
      * Inner helper class to configure an instance of {@link PopupMenu} for the specific test.
      * The main reason for its existence is that once a popup menu is shown with the show() method,
@@ -367,6 +406,8 @@
 
         private boolean mGroupDividerEnabled = false;
 
+        private boolean mForceShowIcon = false;
+
         public Builder withMenuItemClickListener() {
             mHasMenuItemClickListener = true;
             return this;
@@ -409,7 +450,12 @@
             return this;
         }
 
-        private void configure() {
+        public Builder withForceShowIcon(boolean forceShowIcon) {
+            mForceShowIcon = forceShowIcon;
+            return this;
+        }
+
+        public void configure() {
             mAnchor = mActivity.findViewById(mAnchorId);
             if (!mUseCustomGravity && !mUseCustomPopupResource) {
                 mPopupMenu = new PopupMenu(mActivity, mAnchor);
@@ -443,10 +489,14 @@
             if (mGroupDividerEnabled) {
                 mPopupMenu.getMenu().setGroupDividerEnabled(true);
             }
+
+            mPopupMenu.setForceShowIcon(mForceShowIcon);
         }
 
         public void show() {
-            configure();
+            if (mPopupMenu == null) {
+                configure();
+            }
             // Show the popup menu
             mPopupMenu.show();
         }
diff --git a/tests/tests/widget/src/android/widget/cts/ProgressBarTest.java b/tests/tests/widget/src/android/widget/cts/ProgressBarTest.java
index 5a68273..1904710 100644
--- a/tests/tests/widget/src/android/widget/cts/ProgressBarTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ProgressBarTest.java
@@ -559,6 +559,38 @@
         assertEquals(oldSecondaryProgress, mProgressBarHorizontal.getSecondaryProgress());
     }
 
+    @UiThreadTest
+    @Test
+    public void testGetAndSetMinWidth() {
+        final int minWidth = 20;
+        mProgressBar.setMinWidth(minWidth);
+        assertEquals(minWidth, mProgressBar.getMinWidth());
+    }
+
+    @UiThreadTest
+    @Test
+    public void testGetAndSetMaxWidth() {
+        final int maxWidth = 20;
+        mProgressBar.setMaxWidth(maxWidth);
+        assertEquals(maxWidth, mProgressBar.getMaxWidth());
+    }
+
+    @UiThreadTest
+    @Test
+    public void testGetAndSetMinHeight() {
+        final int minHeight = 20;
+        mProgressBar.setMinHeight(minHeight);
+        assertEquals(minHeight, mProgressBar.getMinHeight());
+    }
+
+    @UiThreadTest
+    @Test
+    public void testGetAndSetMaxHeight() {
+        final int maxHeight = 20;
+        mProgressBar.setMaxHeight(maxHeight);
+        assertEquals(maxHeight, mProgressBar.getMaxHeight());
+    }
+
     /*
      * Mock class for ProgressBar to test protected methods
      */
diff --git a/tests/tests/widget/src/android/widget/cts/ScrollViewTest.java b/tests/tests/widget/src/android/widget/cts/ScrollViewTest.java
index 3abb023..bae62ed 100644
--- a/tests/tests/widget/src/android/widget/cts/ScrollViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ScrollViewTest.java
@@ -800,6 +800,22 @@
         assertTrue(myScrollView.getBottomFadingEdgeStrength() >= 0.0f);
     }
 
+    @Test
+    public void testScrollDescendant() throws Throwable {
+        assertEquals(0, mScrollViewCustom.getScrollX());
+        assertEquals(0, mScrollViewCustom.getScrollY());
+
+        View lastChild = mScrollViewCustom.findViewById(R.id.last_child);
+        int lastChildTop = (ITEM_COUNT - 1) * mItemHeight;
+
+        mActivityRule.runOnUiThread(() -> mScrollViewCustom.scrollToDescendant(lastChild));
+        // smoothScrollBy doesn't scroll in X
+        pollingCheckSmoothScrolling(0, 0, 0, lastChildTop);
+
+        assertEquals(0, mScrollViewCustom.getScrollX());
+        assertEquals(lastChildTop, mScrollViewCustom.getScrollY());
+    }
+
     private boolean isInRange(int current, int from, int to) {
         if (from < to) {
             return current >= from && current <= to;
diff --git a/tests/tests/wrap/TEST_MAPPING b/tests/tests/wrap/TEST_MAPPING
new file mode 100644
index 0000000..25b3a66
--- /dev/null
+++ b/tests/tests/wrap/TEST_MAPPING
@@ -0,0 +1,16 @@
+{
+  "presubmit": [
+    {
+      "name": "CtsWrapNoWrapTestCases"
+    },
+    {
+      "name": "CtsWrapWrapNoDebugTestCases"
+    },
+    {
+      "name": "CtsWrapWrapDebugTestCases"
+    },
+    {
+      "name": "CtsWrapWrapDebugMallocDebugTestCases"
+    }
+  ]
+}
diff --git a/tests/tests/wrap/nowrap/AndroidManifest.xml b/tests/tests/wrap/nowrap/AndroidManifest.xml
index 6145390..dfb73bb 100644
--- a/tests/tests/wrap/nowrap/AndroidManifest.xml
+++ b/tests/tests/wrap/nowrap/AndroidManifest.xml
@@ -18,7 +18,8 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="android.wrap.nowrap.cts">
 
-    <application android:debuggable="true">
+    <!-- Ensure that wrap.sh is extracted. -->
+    <application android:debuggable="true" android:extractNativeLibs="true">
         <uses-library android:name="android.test.runner" />
         <meta-data android:name="android.wrap.cts.expext_env" android:value="false" />
         <activity android:name="android.wrap.WrapActivity" >
diff --git a/tests/tests/wrap/wrap_debug/AndroidManifest.xml b/tests/tests/wrap/wrap_debug/AndroidManifest.xml
index f371108..620984e 100644
--- a/tests/tests/wrap/wrap_debug/AndroidManifest.xml
+++ b/tests/tests/wrap/wrap_debug/AndroidManifest.xml
@@ -18,7 +18,8 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="android.wrap.wrap_debug.cts">
 
-    <application android:debuggable="true">
+    <!-- Ensure that wrap.sh is extracted. -->
+    <application android:debuggable="true" android:extractNativeLibs="true">
         <uses-library android:name="android.test.runner" />
         <meta-data android:name="android.wrap.cts.expext_env" android:value="true" />
         <activity android:name="android.wrap.WrapActivity" >
diff --git a/tests/tests/wrap/wrap_debug_malloc_debug/AndroidManifest.xml b/tests/tests/wrap/wrap_debug_malloc_debug/AndroidManifest.xml
index a359f17..5e18526 100644
--- a/tests/tests/wrap/wrap_debug_malloc_debug/AndroidManifest.xml
+++ b/tests/tests/wrap/wrap_debug_malloc_debug/AndroidManifest.xml
@@ -18,7 +18,8 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="android.wrap.wrap_debug_malloc_debug.cts">
 
-    <application android:debuggable="true">
+    <!-- Ensure that wrap.sh is extracted. -->
+    <application android:debuggable="true" android:extractNativeLibs="true">
         <uses-library android:name="android.test.runner" />
         <meta-data android:name="android.wrap.cts.expext_env" android:value="true" />
         <activity android:name="android.wrap.WrapActivity" >
diff --git a/tests/tests/wrap/wrap_nodebug/AndroidManifest.xml b/tests/tests/wrap/wrap_nodebug/AndroidManifest.xml
index 127e6a8..4a29546 100644
--- a/tests/tests/wrap/wrap_nodebug/AndroidManifest.xml
+++ b/tests/tests/wrap/wrap_nodebug/AndroidManifest.xml
@@ -18,7 +18,8 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="android.wrap.wrap_nodebug.cts">
 
-    <application>
+    <!-- Ensure that wrap.sh is extracted. -->
+    <application android:extractNativeLibs="true">
         <uses-library android:name="android.test.runner" />
         <meta-data android:name="android.wrap.cts.expext_env" android:value="false" />
         <activity android:name="android.wrap.WrapActivity" >
diff --git a/tools/vm-tests-tf/AndroidTest.xml b/tools/vm-tests-tf/AndroidTest.xml
index aaafbcf..227a340 100644
--- a/tools/vm-tests-tf/AndroidTest.xml
+++ b/tools/vm-tests-tf/AndroidTest.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Config for CTS VM test cases">
     <option name="test-suite-tag" value="cts" />
+    <!-- Jar test -->
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="component" value="art" />
     <target_preparer class="android.core.vm.targetprep.VmTestPreparer" />
     <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >