Snap for 8857176 from 594dfb3dc7876ac581cd510d4292cff64e6bfe1c to mainline-go-resolv-release

Change-Id: Icdda83ff0f22c62777d1cb00f6bcf53bfed55c7b
diff --git a/apps/CameraITS/tests/scene2_a/test_auto_flash.py b/apps/CameraITS/tests/scene2_a/test_auto_flash.py
index b20da2d..c00cd5c 100644
--- a/apps/CameraITS/tests/scene2_a/test_auto_flash.py
+++ b/apps/CameraITS/tests/scene2_a/test_auto_flash.py
@@ -107,10 +107,10 @@
       test_name = os.path.join(self.log_path, _TEST_NAME)
 
       # check SKIP conditions
-      first_api_level = its_session_utils.get_first_api_level(self.dut.serial)
+      vendor_api_level = its_session_utils.get_vendor_api_level(self.dut.serial)
       camera_properties_utils.skip_unless(
           camera_properties_utils.flash(props) and
-          first_api_level >= its_session_utils.ANDROID13_API_LEVEL)
+          vendor_api_level >= its_session_utils.ANDROID13_API_LEVEL)
 
       # establish connection with lighting controller
       arduino_serial_port = lighting_control_utils.lighting_control(
diff --git a/apps/CameraITS/tests/scene4/test_preview_stabilization_fov.py b/apps/CameraITS/tests/scene4/test_preview_stabilization_fov.py
index 1f5b7c0..2781f18 100644
--- a/apps/CameraITS/tests/scene4/test_preview_stabilization_fov.py
+++ b/apps/CameraITS/tests/scene4/test_preview_stabilization_fov.py
@@ -35,9 +35,9 @@
 _ROUNDESS_DELTA_THRESHOLD = 0.05
 
 _MAX_CENTER_THRESHOLD_PERCENT = 0.075
-_MAX_DIMENSION_SIZE = (1920, 1440)  # max mandatory preview stream resolution
+_MAX_AREA = 1920 * 1440  # max mandatory preview stream resolution
 _MIN_CENTER_THRESHOLD_PERCENT = 0.02
-_MIN_DIMENSION_SIZE = (176, 144)  # assume QCIF to be min preview size
+_MIN_AREA = 176 * 144  # assume QCIF to be min preview size
 
 
 def _collect_data(cam, video_size, stabilize):
@@ -93,23 +93,19 @@
     threshold value ratio between which the circle centers can differ
   """
 
-  max_diagonal = _point_distance(0, 0,
-                                 _MAX_DIMENSION_SIZE[0], _MAX_DIMENSION_SIZE[1])
-  min_diagonal = _point_distance(0, 0,
-                                 _MIN_DIMENSION_SIZE[0], _MIN_DIMENSION_SIZE[1])
+  img_area = image_size[0] * image_size[1]
 
-  img_diagonal = _point_distance(0, 0, image_size[0], image_size[1])
+  normalized_area = ((img_area - _MIN_AREA) /
+                         (_MAX_AREA - _MIN_AREA))
 
-  normalized_diagonal = ((img_diagonal - min_diagonal) /
-                         (max_diagonal - min_diagonal))
-
-  if normalized_diagonal > 1 or normalized_diagonal < 0:
-    raise AssertionError(f'normalized diagonal > 1 or < 0!'
-                         f' img_diag: {img_diagonal}, '
-                         f' normalized_diagonal: {normalized_diagonal}')
+  if normalized_area > 1 or normalized_area < 0:
+    raise AssertionError(f'normalized area > 1 or < 0! '
+                         f'image_size[0]: {image_size[0]}, '
+                         f'image_size[1]: {image_size[1]}, '
+                         f'normalized_area: {normalized_area}')
 
   # Threshold should be larger for images with smaller resolution
-  normalized_threshold_percent = ((1 - normalized_diagonal) *
+  normalized_threshold_percent = ((1 - normalized_area) *
                                   (_MAX_CENTER_THRESHOLD_PERCENT -
                                    _MIN_CENTER_THRESHOLD_PERCENT))
 
@@ -144,7 +140,7 @@
 
       # Load scene.
       its_session_utils.load_scene(cam, props, self.scene,
-                                   self.tablet, chart_distance=0)
+                                   self.tablet, self.chart_distance)
 
       # Check skip condition
       first_api_level = its_session_utils.get_first_api_level(self.dut.serial)
@@ -253,7 +249,8 @@
                              f'{_ROUNDESS_DELTA_THRESHOLD}, '
                              f'actual ratio difference: {roundness_diff}. ')
 
-        # Distance between centers
+        # Distance between centers, x_offset and y_offset are relative to the
+        # radius of the circle, so they're normalized. Not pixel values.
         unstab_center = (ustab_circle['x_offset'], ustab_circle['y_offset'])
         logging.debug('unstabilized center: %s', unstab_center)
         stab_center = (stab_circle['x_offset'], stab_circle['y_offset'])
diff --git a/apps/CameraITS/tests/scene4/test_video_aspect_ratio_and_crop.py b/apps/CameraITS/tests/scene4/test_video_aspect_ratio_and_crop.py
index 6eaca19..bb71367 100644
--- a/apps/CameraITS/tests/scene4/test_video_aspect_ratio_and_crop.py
+++ b/apps/CameraITS/tests/scene4/test_video_aspect_ratio_and_crop.py
@@ -137,13 +137,13 @@
       logging.debug('physical available focal lengths: %s', str(fls_physical))
 
       # Check SKIP conditions.
-      first_api_level = its_session_utils.get_first_api_level(self.dut.serial)
+      vendor_api_level = its_session_utils.get_vendor_api_level(self.dut.serial)
       camera_properties_utils.skip_unless(
-          first_api_level >= its_session_utils.ANDROID13_API_LEVEL)
+          vendor_api_level >= its_session_utils.ANDROID13_API_LEVEL)
 
       # Load scene.
       its_session_utils.load_scene(cam, props, self.scene,
-                                   self.tablet, chart_distance=0)
+                                   self.tablet, self.chart_distance)
 
       # Determine camera capabilities.
       supported_video_qualities = cam.get_supported_video_qualities(
diff --git a/apps/CameraITS/tests/sensor_fusion/test_video_stabilization.py b/apps/CameraITS/tests/sensor_fusion/test_video_stabilization.py
index 0be38b5..195d567 100644
--- a/apps/CameraITS/tests/sensor_fusion/test_video_stabilization.py
+++ b/apps/CameraITS/tests/sensor_fusion/test_video_stabilization.py
@@ -129,7 +129,7 @@
   in gyroscope movement. Test is a PASS if rotation is reduced in video.
   """
 
-  def test_video_stability(self):
+  def test_video_stabilization(self):
     rot_rig = {}
     log_path = self.log_path
 
@@ -139,12 +139,12 @@
         hidden_physical_id=self.hidden_physical_id) as cam:
       props = cam.get_camera_properties()
       props = cam.override_with_hidden_physical_camera_props(props)
-      first_api_level = its_session_utils.get_first_api_level(self.dut.serial)
+      vendor_api_level = its_session_utils.get_vendor_api_level(self.dut.serial)
       supported_stabilization_modes = props[
           'android.control.availableVideoStabilizationModes']
 
       camera_properties_utils.skip_unless(
-          first_api_level >= its_session_utils.ANDROID13_API_LEVEL and
+          vendor_api_level >= its_session_utils.ANDROID13_API_LEVEL and
           _VIDEO_STABILIZATION_MODE in supported_stabilization_modes)
 
       # Raise error if not FRONT or REAR facing camera
diff --git a/apps/CameraITS/utils/its_session_utils.py b/apps/CameraITS/utils/its_session_utils.py
index e91565e..c2065ba 100644
--- a/apps/CameraITS/utils/its_session_utils.py
+++ b/apps/CameraITS/utils/its_session_utils.py
@@ -1612,6 +1612,18 @@
   return first_api_level
 
 
+def get_vendor_api_level(device_id):
+  """Return the int value for the vendor API level of the device."""
+  cmd = 'adb -s %s shell getprop ro.vendor.api_level' % device_id
+  try:
+    vendor_api_level = int(subprocess.check_output(cmd.split()).rstrip())
+    logging.debug('First vendor API level: %d', vendor_api_level)
+  except (subprocess.CalledProcessError, ValueError):
+    logging.error('No vendor_api_level. Setting to build version.')
+    vendor_api_level = get_build_sdk_version(device_id)
+  return vendor_api_level
+
+
 class ItsSessionUtilsTests(unittest.TestCase):
   """Run a suite of unit tests on this module."""
 
diff --git a/apps/CtsVerifier/Android.bp b/apps/CtsVerifier/Android.bp
index b4485d1..024e038 100644
--- a/apps/CtsVerifier/Android.bp
+++ b/apps/CtsVerifier/Android.bp
@@ -91,6 +91,7 @@
         "CtsForceStopHelper-constants",
         "ctsmediautil",
         "DpmWrapper",
+        "MediaPerformanceClassCommon",
     ],
 
     libs: ["telephony-common"] + ["android.test.runner.stubs"] + ["android.test.base.stubs"] + ["android.test.mock.stubs"] + ["android.car-test-stubs"] + ["voip-common"] + ["truth-prebuilt"],
@@ -114,7 +115,7 @@
 
     compile_multilib: "both",
 
-    manifest: "AndroidManifest-verifierConfig.xml",
+    additional_manifests: ["AndroidManifest-verifierConfig.xml"],
 
     jni_libs: [
         "libctsverifier_jni",
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index 5a257de..db1ca21 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -248,6 +248,7 @@
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.cts.intent.category.MANUAL_TEST" />
             </intent-filter>
+            <meta-data android:name="CddTest" android:value="3.8.17/C-1-1,C-2-1" />
             <meta-data android:name="test_category" android:value="@string/test_category_features" />
             <meta-data android:name="test_excluded_features"
                        android:value="android.hardware.type.watch:android.software.leanback:android.hardware.type.automotive" />
@@ -3901,174 +3902,6 @@
                        android:value="single_display_mode" />
         </activity>
 
-        <!--            CTS Verifier Presence Test Top Screen -->
-        <activity
-            android:name=".presence.PresenceTestActivity"
-            android:configChanges="keyboardHidden|orientation|screenSize"
-            android:exported="true"
-            android:label="@string/presence_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_networking" />
-            <meta-data android:name="display_mode"
-                       android:value="single_display_mode" />
-        </activity>
-
-        <!--
-             CTS Verifier Uwb Precision Test Screen
-                 test category : uwb
-                 test parent : PresenceTestActivity
-        -->
-        <activity
-            android:name=".presence.UwbPrecisionActivity"
-            android:configChanges="keyboardHidden|orientation|screenSize"
-            android:exported="true"
-            android:label="@string/uwb_precision" >
-            <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/uwb" />
-            <meta-data
-                android:name="test_parent"
-                android:value="com.android.cts.verifier.presence.PresenceTestActivity" />
-            <meta-data android:name="display_mode"
-                       android:value="single_display_mode" />
-            <meta-data android:name="CddTest"
-                       android:value="7.4.9/C-1-1" />
-        </activity>
-
-        <!--
-             CTS Verifier Uwb Short Range Test Screen
-                 test category : uwb
-                 test parent : PresenceTestActivity
-        -->
-        <activity
-            android:name=".presence.UwbShortRangeActivity"
-            android:configChanges="keyboardHidden|orientation|screenSize"
-            android:exported="true"
-            android:label="@string/uwb_short_range" >
-            <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/uwb" />
-            <meta-data
-                android:name="test_parent"
-                android:value="com.android.cts.verifier.presence.PresenceTestActivity" />
-            <meta-data
-                android:name="display_mode"
-                android:value="single_display_mode" />
-            <meta-data
-                android:name="CddTest"
-                android:value="7.4.9/C-1-2" />
-        </activity>
-
-        <!--
-            CTS Verifier BLE RSSI Precision Test Screen
-                test category : BLE
-                test parent : PresenceTestActivity
-        -->
-        <activity
-            android:name=".presence.BleRssiPrecisionActivity"
-            android:exported="true"
-            android:label="@string/ble_rssi_precision_name">
-            <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/ble" />
-            <meta-data
-                android:name="test_parent"
-                android:value="com.android.cts.verifier.presence.PresenceTestActivity" />
-            <meta-data
-                android:name="test_required_features"
-                android:value="android.hardware.bluetooth_le" />
-            <meta-data
-                android:name="display_mode"
-                android:value="single_display_mode" />
-            <meta-data
-                android:name="CddText"
-                android:value="7.4.3/C-7-1" />
-        </activity>
-
-        <!--
-            CTS Verifier BLE Rx/Tx Calibration Test Screen
-                test category : BLE
-                test parent : PresenceTestActivity
-        -->
-        <activity
-            android:name=".presence.BleRxTxCalibrationActivity"
-            android:exported="true"
-            android:label="@string/ble_rx_tx_calibration_name">
-            <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/ble" />
-            <meta-data
-                android:name="test_parent"
-                android:value="com.android.cts.verifier.presence.PresenceTestActivity" />
-            <meta-data
-                android:name="test_required_features"
-                android:value="android.hardware.bluetooth_le" />
-            <meta-data
-                android:name="display_mode"
-                android:value="single_display_mode" />
-            <meta-data
-                android:name="CddText"
-                android:value="7.4.3/C-7-2" />
-        </activity>
-
-        <!-- CTS Verifier Nan Precision and Bias Test Screen
-                 test category : wifi_nan
-                 test parent : PresenceTestActivity
-        -->
-        <activity
-            android:name=".presence.NanPrecisionTestActivity"
-            android:configChanges="keyboardHidden|orientation|screenSize"
-            android:exported="true"
-            android:label="@string/nan_precision" >
-            <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/wifi_nan" />
-            <meta-data
-                android:name="test_parent"
-                android:value="com.android.cts.verifier.presence.PresenceTestActivity" />
-            <meta-data android:name="display_mode"
-                       android:value="single_display_mode" />
-            <meta-data android:name="CddTest"
-                       android:value="7.4.2.5/H-1-1|7.4.2.5/H-1-2" />
-        </activity>
-
         <activity-alias
             android:name=".CtsVerifierActivity"
             android:label="@string/app_name"
@@ -6159,6 +5992,7 @@
                 <category android:name="android.cts.intent.category.MANUAL_TEST" />
             </intent-filter>
             <meta-data android:name="test_category" android:value="@string/test_category_logcat" />
+            <meta-data android:name="test_excluded_features" android:value="android.hardware.type.automotive" />
         </activity>
 
         <activity android:name=".displaycutout.DisplayCutoutTestActivity"
diff --git a/apps/CtsVerifier/res/layout/ble_rssi_precision.xml b/apps/CtsVerifier/res/layout/ble_rssi_precision.xml
deleted file mode 100644
index 5f01e1f..0000000
--- a/apps/CtsVerifier/res/layout/ble_rssi_precision.xml
+++ /dev/null
@@ -1,60 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2022 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"
-    xmlns:tools="http://schemas.android.com/tools"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical"
-    style="@style/RootLayoutPadding"
-    tools:ignore="Autofill">
-
-    <ScrollView
-        android:layout_width="fill_parent"
-        android:layout_height="wrap_content">
-
-        <LinearLayout
-            android:orientation="vertical"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content">
-
-            <TextView
-                android:text="@string/ble_rssi_precision_test_instructions"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:scrollbars="vertical" />
-
-            <EditText
-                android:id="@+id/report_rssi_range"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:hint="@string/report_ble_rssi_range"
-                android:inputType="number" />
-
-            <EditText
-                android:id="@+id/report_reference_device"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:hint="@string/report_reference_device"
-                android:inputType="text" />
-
-            <include
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                layout="@layout/pass_fail_buttons" />
-        </LinearLayout>
-    </ScrollView>
-</RelativeLayout>
diff --git a/apps/CtsVerifier/res/layout/ble_rx_tx_calibration.xml b/apps/CtsVerifier/res/layout/ble_rx_tx_calibration.xml
deleted file mode 100644
index 3ca955b..0000000
--- a/apps/CtsVerifier/res/layout/ble_rx_tx_calibration.xml
+++ /dev/null
@@ -1,66 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
-  ~ Copyright (C) 2022 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"
-    xmlns:tools="http://schemas.android.com/tools"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical"
-    style="@style/RootLayoutPadding"
-    tools:ignore="Autofill">
-
-    <ScrollView
-        android:layout_width="fill_parent"
-        android:layout_height="wrap_content">
-
-        <LinearLayout
-            android:orientation="vertical"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content">
-
-            <TextView
-                android:text="@string/ble_rx_tx_calibration_test_instructions"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:scrollbars="vertical" />
-
-            <EditText
-                android:id="@+id/report_channels_rssi_range"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:hint="@string/report_channels_ble_rssi_range"
-                android:inputType="number" />
-
-            <EditText
-                android:id="@+id/report_cores_rssi_range"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:hint="@string/report_cores_ble_rssi_range"
-                android:inputType="number" />
-
-            <EditText
-                android:id="@+id/report_reference_device"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:hint="@string/report_reference_device"
-                android:inputType="text" />
-
-            <include
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                layout="@layout/pass_fail_buttons" />
-        </LinearLayout>
-    </ScrollView>
-</RelativeLayout>
diff --git a/apps/CtsVerifier/res/layout/clipboard_preview.xml b/apps/CtsVerifier/res/layout/clipboard_preview.xml
index 85f38c8..efec118 100644
--- a/apps/CtsVerifier/res/layout/clipboard_preview.xml
+++ b/apps/CtsVerifier/res/layout/clipboard_preview.xml
@@ -31,86 +31,6 @@
         android:layout_marginBottom="100dp"
         android:layout_marginTop="30dp"
         android:text="@string/clipboard_preview_test_copy_button"/>
-
-    <TableLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content">
-        <TableRow
-            android:layout_width="match_parent"
-            android:layout_height="50dp">
-            <View android:layout_weight="3"
-                  android:layout_height="50dp"/>
-            <Button android:layout_weight="1"
-                    android:id="@+id/clipboard_preview_test_b1"
-                    android:layout_width="50dp"
-                    android:layout_height="50dp"
-                    android:text="1"/>
-            <Button android:layout_weight="1"
-                    android:id="@+id/clipboard_preview_test_b2"
-                    android:layout_width="50dp"
-                    android:layout_height="50dp"
-                    android:text="2"/>
-            <Button android:layout_weight="1"
-                    android:id="@+id/clipboard_preview_test_b3"
-                    android:layout_width="50dp"
-                    android:layout_height="50dp"
-                    android:text="3"/>
-            <View android:layout_weight="3"
-                  android:layout_height="50dp"/>
-        </TableRow>
-        <TableRow
-            android:layout_width="match_parent"
-            android:layout_height="50dp">
-            <View android:layout_weight="3"
-                  android:layout_height="50dp"/>
-            <Button android:layout_weight="1"
-                    android:id="@+id/clipboard_preview_test_b4"
-                    android:layout_width="50dp"
-                    android:layout_height="50dp"
-                    android:text="4"/>
-            <Button android:layout_weight="1"
-                    android:id="@+id/clipboard_preview_test_b5"
-                    android:layout_width="50dp"
-                    android:layout_height="50dp"
-                    android:text="5"/>
-            <Button android:layout_weight="1"
-                    android:id="@+id/clipboard_preview_test_b6"
-                    android:layout_width="50dp"
-                    android:layout_height="50dp"
-                    android:text="6"/>
-            <View android:layout_weight="3"
-                  android:layout_height="50dp"/>
-        </TableRow>
-        <TableRow
-            android:layout_width="match_parent"
-            android:layout_height="50dp">
-            <View android:layout_weight="3"
-                  android:layout_height="match_parent"/>
-            <Button android:layout_weight="1"
-                    android:id="@+id/clipboard_preview_test_b7"
-                    android:layout_width="50dp"
-                    android:layout_height="match_parent"
-                    android:text="7"/>
-            <Button android:layout_weight="1"
-                    android:id="@+id/clipboard_preview_test_b8"
-                    android:layout_width="50dp"
-                    android:layout_height="match_parent"
-                    android:text="8"/>
-            <Button android:layout_weight="1"
-                    android:id="@+id/clipboard_preview_test_b9"
-                    android:layout_width="50dp"
-                    android:layout_height="match_parent"
-                    android:text="9"/>
-            <View android:layout_weight="3"
-                  android:layout_height="50dp"/>
-        </TableRow>
-    </TableLayout>
-    <Button
-        android:id="@+id/clipboard_preview_test_b0"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center"
-        android:text="0"/>
     <include
         android:id="@+id/clipboard_preview_test_pass_fail"
         android:layout_width="match_parent"
diff --git a/apps/CtsVerifier/res/layout/nan_precision.xml b/apps/CtsVerifier/res/layout/nan_precision.xml
deleted file mode 100644
index c81a9c4..0000000
--- a/apps/CtsVerifier/res/layout/nan_precision.xml
+++ /dev/null
@@ -1,92 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2022 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="match_parent"
-                android:layout_height="match_parent"
-                android:orientation="vertical"
-                style="@style/RootLayoutPadding">
-    <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
-                android:layout_width="fill_parent"
-                android:layout_height="wrap_content">
-        <LinearLayout android:orientation="vertical"
-                      android:layout_width="match_parent"
-                      android:layout_height="wrap_content">
-            <TextView android:text="@string/nan_precision_instruction"
-                      android:id="@+id/nan_precision_instruction"
-                      android:layout_width="wrap_content"
-                      android:layout_height="wrap_content"
-                      android:scrollbars="vertical"/>
-            <LinearLayout android:orientation="vertical"
-                          android:layout_width="match_parent"
-                          android:layout_height="wrap_content">
-                <EditText android:id="@+id/nan_bandwidth"
-                          android:layout_width="wrap_content"
-                          android:layout_height="wrap_content"
-                          android:inputType="number"
-                          android:hint="@string/report_nan_bandwidth_mhz"/>
-                <EditText android:id="@+id/distance_range_10cm_gt_68p"
-                          android:layout_width="wrap_content"
-                          android:layout_height="wrap_content"
-                          android:inputType="numberDecimal"
-                          android:hint="@string/report_distance_range_10cm_gt_68p"/>
-                <EditText android:id="@+id/distance_range_1m_gt_68p"
-                          android:layout_width="wrap_content"
-                          android:layout_height="wrap_content"
-                          android:inputType="numberDecimal"
-                          android:hint="@string/report_distance_range_1m_gt_68p"/>
-                <EditText android:id="@+id/distance_range_3m_gt_68p"
-                          android:layout_width="wrap_content"
-                          android:layout_height="wrap_content"
-                          android:inputType="numberDecimal"
-                          android:hint="@string/report_distance_range_3m_gt_68p"/>
-                <EditText android:id="@+id/distance_range_5m_gt_68p"
-                          android:layout_width="wrap_content"
-                          android:layout_height="wrap_content"
-                          android:inputType="numberDecimal"
-                          android:hint="@string/report_distance_range_5m_gt_68p"/>
-                <EditText android:id="@+id/distance_range_10cm_gt_90p"
-                          android:layout_width="wrap_content"
-                          android:layout_height="wrap_content"
-                          android:inputType="numberDecimal"
-                          android:hint="@string/report_distance_range_10cm_gt_90p"/>
-                <EditText android:id="@+id/distance_range_1m_gt_90p"
-                          android:layout_width="wrap_content"
-                          android:layout_height="wrap_content"
-                          android:inputType="numberDecimal"
-                          android:hint="@string/report_distance_range_1m_gt_90p"/>
-                <EditText android:id="@+id/distance_range_3m_gt_90p"
-                          android:layout_width="wrap_content"
-                          android:layout_height="wrap_content"
-                          android:inputType="numberDecimal"
-                          android:hint="@string/report_distance_range_3m_gt_90p"/>
-                <EditText android:id="@+id/distance_range_5m_gt_90p"
-                          android:layout_width="wrap_content"
-                          android:layout_height="wrap_content"
-                          android:inputType="numberDecimal"
-                          android:hint="@string/report_distance_range_5m_gt_90p"/>
-                <EditText android:id="@+id/reference_device"
-                          android:layout_width="wrap_content"
-                          android:layout_height="wrap_content"
-                          android:hint="@string/report_reference_device"/>
-            </LinearLayout>
-
-            <include android:layout_width="match_parent"
-                     android:layout_height="wrap_content"
-                     layout="@layout/pass_fail_buttons"/>
-        </LinearLayout>
-    </ScrollView>
-</RelativeLayout>
diff --git a/apps/CtsVerifier/res/layout/uwb_precision.xml b/apps/CtsVerifier/res/layout/uwb_precision.xml
deleted file mode 100644
index 14e996d..0000000
--- a/apps/CtsVerifier/res/layout/uwb_precision.xml
+++ /dev/null
@@ -1,51 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2022 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="match_parent"
-                android:layout_height="match_parent"
-                android:orientation="vertical"
-                style="@style/RootLayoutPadding">
-    <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
-                android:layout_width="fill_parent"
-                android:layout_height="wrap_content">
-        <LinearLayout android:orientation="vertical"
-                      android:layout_width="match_parent"
-                      android:layout_height="wrap_content">
-            <TextView android:text="@string/uwb_precision_instruction"
-                      android:id="@+id/uwb_precision_instruction"
-                      android:layout_width="wrap_content"
-                      android:layout_height="wrap_content"
-                      android:scrollbars="vertical"/>
-            <LinearLayout android:orientation="vertical"
-                          android:layout_width="match_parent"
-                          android:layout_height="wrap_content">
-                <EditText android:id="@+id/distance_range_cm"
-                          android:layout_width="wrap_content"
-                          android:layout_height="wrap_content"
-                          android:inputType="numberDecimal"
-                          android:hint="@string/report_distance_range_cm"/>
-                <EditText android:id="@+id/reference_device"
-                          android:layout_width="wrap_content"
-                          android:layout_height="wrap_content"
-                          android:hint="@string/report_reference_device"/>
-            </LinearLayout>
-
-            <include android:layout_width="match_parent"
-                     android:layout_height="wrap_content"
-                     layout="@layout/pass_fail_buttons"/>
-        </LinearLayout>
-    </ScrollView>
-</RelativeLayout>
diff --git a/apps/CtsVerifier/res/layout/uwb_short_range.xml b/apps/CtsVerifier/res/layout/uwb_short_range.xml
deleted file mode 100644
index 9afc6e5..0000000
--- a/apps/CtsVerifier/res/layout/uwb_short_range.xml
+++ /dev/null
@@ -1,51 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2022 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="match_parent"
-        android:layout_height="match_parent"
-        android:orientation="vertical"
-        style="@style/RootLayoutPadding">
-    <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
-            android:layout_width="fill_parent"
-            android:layout_height="wrap_content">
-        <LinearLayout android:orientation="vertical"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content">
-            <TextView android:text="@string/uwb_short_range_instruction"
-                    android:id="@+id/uwb_short_range_instruction"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:scrollbars="vertical"/>
-            <LinearLayout android:orientation="vertical"
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content">
-                <EditText android:id="@+id/distance_median_meters"
-                        android:layout_width="wrap_content"
-                          android:inputType="numberDecimal"
-                        android:layout_height="wrap_content"
-                        android:hint="@string/report_distance_median_meters"/>
-                <EditText android:id="@+id/reference_device"
-                          android:layout_width="wrap_content"
-                          android:layout_height="wrap_content"
-                          android:hint="@string/report_reference_device"/>
-            </LinearLayout>
-
-            <include android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    layout="@layout/pass_fail_buttons"/>
-        </LinearLayout>
-    </ScrollView>
-</RelativeLayout>
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index 4862965..0f32b34 100644
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -32,6 +32,16 @@
     <string name="finish_button_text">Finish</string>
     <string name="fail_and_next_button_text">Fail and Next</string>
 
+    <!-- Strings for CtsReportLog warning -->
+    <string name="reportlog_warning_title">CTS-Verifier Report Log</string>
+    <string name="reportlog_warning_body">Can\'t create folder for CTS-Verifier Report Logs.
+        \n\nPlease enable Report Log creation by exiting CTS Verifier and running the following commands:
+        \n\n<code>adb shell appops set com.android.cts.verifier android:read_device_identifiers allow</code>
+        \n\n<code>adb shell appops set com.android.cts.verifier MANAGE_EXTERNAL_STORAGE 0</code>
+        \n\nTest instructions are found in the \"Using CTS Verifier\" document found at
+        <a href="https://source.android.com/compatibility/cts/verifier">https://source.android.com/compatibility/cts/verifier</a>
+    </string>
+
     <!-- Strings for TestListActivity -->
     <string name="test_category_audio">Audio</string>
     <string name="test_category_camera">Camera</string>
@@ -301,9 +311,11 @@
     </string>
     <string name="clipboard_preview_test_instructions">
         Press the \'Copy\' button to copy the secret code to the clipboard.
-        \n\nUse the clipboard preview UI, or the clipboard editor component to view the secret code.
-        \n\nEnter the secret code using the buttons below.
+        \n\n If nothing happens, press Fail.
+        \n\n If you see the word "FAIL" appear on screen, press Fail.
+        \n\n If you see a confirmation that content has been copied to the clipboard, press Pass.
     </string>
+    <string name="clipboard_preview_test_secret">FAIL</string>
     <string name="clipboard_preview_test_copy_button">Copy</string>
 
 
@@ -778,7 +790,7 @@
     <!-- BLE Advertising Set test strings -->
     <string name="ble_advertising_set_test_name">Bluetooth LE Advertising Set Test</string>
     <string name="ble_advertising_set_test_info">Bluetooth LE Advertising Set tests AdvertisingSet and AdvertisingSetCallback APIs.</string>
-    <string name="ble_advertising_set_test_instruction">Press the \"Set Up\" button first, then start the test by pressing the \"Start Test\" button. UI thread may freeze for a few seconds while enabling/disabling bluetooth adapter.</string>
+    <string name="ble_advertising_set_test_instruction">Press the \"Start Test\" button. UI thread may freeze for a few seconds while enabling/disabling bluetooth adapter.</string>
     <string name="ble_advertising_set_start_test">Start Test</string>
     <string name="ble_advertising_set_running_test">Running Test...</string>
     <string name="ble_advertising_set_finished_test">Finished Test</string>
@@ -5480,6 +5492,7 @@
     <string name="audio_general_test_not_run">Test Not Run</string>
     <string name="audio_general_testnotcompleted">Test not completed.</string>
 
+    <string name="audio_general_reportlogtest">[Can\'t Write ReportLog]</string>
 
     <!-- Audio Loopback Latency Test -->
     <string name="audio_loopback_latency_test">Audio Loopback Latency Test</string>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/CtsVerifierReportLog.java b/apps/CtsVerifier/src/com/android/cts/verifier/CtsVerifierReportLog.java
index b013bb7..a93e3b5 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/CtsVerifierReportLog.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/CtsVerifierReportLog.java
@@ -74,6 +74,10 @@
         }
     }
 
+    public boolean isOpen() {
+        return mStore != null;
+    }
+
     /**
      * Closes report file. Static functions that do not have access to instrumentation can
      * use this to close report logs. Summary, if present, is not reported to instrumentation, hence
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/PassFailButtons.java b/apps/CtsVerifier/src/com/android/cts/verifier/PassFailButtons.java
index 0294ff7..7b993ee 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/PassFailButtons.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/PassFailButtons.java
@@ -32,7 +32,6 @@
 import android.os.Bundle;
 import android.os.PowerManager;
 import android.os.PowerManager.WakeLock;
-import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.MenuItem;
 import android.view.View;
@@ -146,6 +145,8 @@
         private final CtsVerifierReportLog mReportLog;
         private final TestResultHistoryCollection mHistoryCollection;
 
+        protected boolean mRequireReportLogToPass;
+
         public Activity() {
             this.mReportLog = new CtsVerifierReportLog(getReportFileName(), getReportSectionName());
             this.mHistoryCollection = new TestResultHistoryCollection();
@@ -159,6 +160,10 @@
                         .newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "PassFailButtons");
                 mWakeLock.acquire();
             }
+
+            if (!this.mReportLog.isOpen()) {
+                showReportLogWarningDialog(this);
+            }
         }
 
         @Override
@@ -212,6 +217,14 @@
         }
 
         /**
+         * A mechanism to block tests from passing if no ReportLog data has been collected.
+         * @return true if the ReportLog is open OR if the test does not require that.
+         */
+        public boolean isReportLogOkToPass() {
+            return !mRequireReportLogToPass || mReportLog.isOpen();
+        }
+
+        /**
          * @return The name of the file to store the (suite of) ReportLog information.
          */
         @Override
@@ -527,6 +540,12 @@
         activity.showDialog(INFO_DIALOG_ID, args);
     }
 
+    protected static void showReportLogWarningDialog(final android.app.Activity activity) {
+        showInfoDialog(activity,
+                R.string.reportlog_warning_title, R.string.reportlog_warning_body, -1);
+    }
+
+
     protected static Dialog createDialog(final android.app.Activity activity, int id, Bundle args) {
         switch (id) {
             case INFO_DIALOG_ID:
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AnalogHeadsetAudioActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AnalogHeadsetAudioActivity.java
index 528d914..83b32de 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AnalogHeadsetAudioActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AnalogHeadsetAudioActivity.java
@@ -182,12 +182,15 @@
             mResultsTxt.setText(getResources().getString(R.string.analog_headset_pass_noheadset));
             return true;
         } else {
-            boolean pass = mPlugIntentReceived &&
-                    mHeadsetDeviceInfo != null &&
-                    mPlaybackSuccess &&
-                    (mHasHeadsetHook || mHasPlayPause) && mHasVolUp && mHasVolDown;
+            boolean pass = isReportLogOkToPass()
+                    && mPlugIntentReceived
+                    && mHeadsetDeviceInfo != null
+                    && mPlaybackSuccess
+                    && (mHasHeadsetHook || mHasPlayPause) && mHasVolUp && mHasVolDown;
             if (pass) {
                 mResultsTxt.setText(getResources().getString(R.string.analog_headset_pass));
+            } else if (!isReportLogOkToPass()) {
+                mResultsTxt.setText(getResources().getString(R.string.audio_general_reportlogtest));
             }
             return pass;
         }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioAEC.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioAEC.java
index 48795ef..3c1b8a1 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioAEC.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioAEC.java
@@ -542,8 +542,10 @@
             Log.v(TAG, "Test EndedOk. " + testId + " str:"+str);
             showView(mProgress, false);
             mResultTest.setText("test completed. " + str);
-            if (mTestAECPassed) {
-                getPassButton().setEnabled(true);;
+            if (!isReportLogOkToPass()) {
+                mResultTest.setText(getResources().getString(R.string.audio_general_reportlogtest));
+            } else if (mTestAECPassed) {
+                getPassButton().setEnabled(true);
             }
         }
 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioLoopbackLatencyActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioLoopbackLatencyActivity.java
index a6bd4ad..79d3e3b 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioLoopbackLatencyActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioLoopbackLatencyActivity.java
@@ -294,6 +294,8 @@
         getPassButton().setEnabled(false);
         setInfoResources(R.string.audio_loopback_latency_test, R.string.audio_loopback_info, -1);
 
+        mRequireReportLogToPass = true;
+
         mClaimsOutput = AudioSystemFlags.claimsOutput(this);
         mClaimsInput = AudioSystemFlags.claimsInput(this);
         mClaimsProAudio = AudioSystemFlags.claimsProAudio(this);
@@ -683,7 +685,8 @@
         mResultsText[mTestRoute].setText(testSpec.getResultString());
 
         LoopbackLatencyRequirements requirements = new LoopbackLatencyRequirements();
-        boolean pass = requirements.evaluate(mClaimsProAudio,
+        boolean pass = isReportLogOkToPass()
+                && requirements.evaluate(mClaimsProAudio,
                 Build.VERSION.MEDIA_PERFORMANCE_CLASS,
                 mTestSpecs[TESTROUTE_DEVICE].isMeasurementValid()
                         ? mTestSpecs[TESTROUTE_DEVICE].mMeanLatencyMS : 0.0,
@@ -694,8 +697,12 @@
 
         getPassButton().setEnabled(pass);
 
-        String resultText = requirements.getResultsString();
-        mTestStatusText.setText(resultText);
+        StringBuilder sb = new StringBuilder();
+        if (!isReportLogOkToPass()) {
+            sb.append(getResources().getString(R.string.audio_general_reportlogtest) + "\n");
+        }
+        sb.append(requirements.getResultsString());
+        mTestStatusText.setText(sb.toString());
 
         showWait(false);
         enableStartButtons(true);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioTap2ToneActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioTap2ToneActivity.java
index 215d26f..8ff2358 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioTap2ToneActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioTap2ToneActivity.java
@@ -154,6 +154,8 @@
         String yesString = getResources().getString(R.string.audio_general_yes);
         String noString = getResources().getString(R.string.audio_general_no);
 
+        mRequireReportLogToPass = true;
+
         boolean claimsProAudio = AudioSystemFlags.claimsProAudio(this);
         boolean claimsLowLatencyAudio = AudioSystemFlags.claimsLowLatencyAudio(this);
 
@@ -311,11 +313,14 @@
         }
 
         double averageLatency = mLatencyAve[mActiveTestAPI];
-        boolean pass = averageLatency != 0 && averageLatency <= mMaxRequiredLatency;
+        boolean pass = isReportLogOkToPass()
+                && averageLatency != 0 && averageLatency <= mMaxRequiredLatency;
 
         if (pass) {
             mSpecView.setText("Average: " + averageLatency + " ms <= "
                     + mMaxRequiredLatency + " ms -- PASS");
+        } else if (!isReportLogOkToPass()) {
+            mSpecView.setText(getResources().getString(R.string.audio_general_reportlogtest));
         } else {
             mSpecView.setText("Average: " + averageLatency + " ms > "
                     + mMaxRequiredLatency + " ms -- FAIL");
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/ProAudioActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/ProAudioActivity.java
index 126d15f..e93d2b3 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/ProAudioActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/ProAudioActivity.java
@@ -158,11 +158,9 @@
         boolean usbOK = mClaimsUSBHostMode && mClaimsUSBPeripheralMode;
         boolean hdmiOK = !mClaimsHDMI || isHDMIValid();
 
-        boolean hasPassed = !mClaimsProAudio ||
-                (mClaimsLowLatencyAudio &&
-                mClaimsMIDI &&
-                usbOK &&
-                hdmiOK);
+        boolean hasPassed = isReportLogOkToPass()
+                && !mClaimsProAudio
+                || (mClaimsLowLatencyAudio && mClaimsMIDI && usbOK && hdmiOK);
 
         getPassButton().setEnabled(hasPassed);
         return hasPassed;
@@ -172,7 +170,9 @@
         boolean hasPassed = calculatePass();
 
         Resources strings = getResources();
-        if (hasPassed) {
+        if (!isReportLogOkToPass()) {
+            mTestStatusLbl.setText(getResources().getString(R.string.audio_general_reportlogtest));
+        } else  if (hasPassed) {
             mTestStatusLbl.setText(strings.getString(R.string.audio_proaudio_pass));
         } else if (!mClaimsMIDI) {
             mTestStatusLbl.setText(strings.getString(R.string.audio_proaudio_midinotreported));
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/USBAudioPeripheralNotificationsTest.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/USBAudioPeripheralNotificationsTest.java
index bc23048..6270a5a 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/USBAudioPeripheralNotificationsTest.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/USBAudioPeripheralNotificationsTest.java
@@ -20,23 +20,17 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-
 import android.media.AudioDeviceCallback;
 import android.media.AudioDeviceInfo;
 import android.media.AudioManager;
-
 import android.os.Bundle;
 import android.os.Handler;
-
 import android.util.Log;
-
 import android.widget.TextView;
 
 import com.android.compatibility.common.util.CddTest;
-import com.android.compatibility.common.util.ReportLog;
 import com.android.compatibility.common.util.ResultType;
 import com.android.compatibility.common.util.ResultUnit;
-
 import com.android.cts.verifier.PassFailButtons;
 import com.android.cts.verifier.R;  // needed to access resource in CTSVerifier project namespace.
 
@@ -173,9 +167,10 @@
     // Test Status
     //
     private boolean calculatePass() {
-        return mUsbHeadsetInReceived && mUsbHeadsetOutReceived &&
-                mUsbDeviceInReceived && mUsbDeviceOutReceived &&
-                mPlugIntentReceived;
+        return isReportLogOkToPass()
+                && mUsbHeadsetInReceived && mUsbHeadsetOutReceived
+                && mUsbDeviceInReceived && mUsbDeviceOutReceived
+                && mPlugIntentReceived;
     }
 
     //
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleAdvertisingSetTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleAdvertisingSetTestActivity.java
index 07a70c6..164992b 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleAdvertisingSetTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleAdvertisingSetTestActivity.java
@@ -99,11 +99,6 @@
                 R.string.ble_advertising_set_test_info, -1);
         getPassButton().setEnabled(false);
 
-        mBluetoothManager = getSystemService(BluetoothManager.class);
-        mBluetoothAdapter = mBluetoothManager.getAdapter();
-        mAdvertiser = mBluetoothAdapter.getBluetoothLeAdvertiser();
-        mCallback = new TestAdvertisingSetCallback();
-
         mTestAdapter = new TestAdapter(this, setupTestList());
         ListView listView = findViewById(R.id.ble_advertising_set_tests);
         listView.setAdapter(mTestAdapter);
@@ -133,9 +128,7 @@
                             testEnableAndDisableAdvertising();
                             testSetAdvertisingData();
                             testSetAdvertisingParameters();
-                            if (mBluetoothAdapter.isLePeriodicAdvertisingSupported()) {
-                                testPeriodicAdvertising();
-                            }
+                            testPeriodicAdvertising();
                             testSetScanResponseData();
                             stopAdvertisingSet();
                         } catch (InterruptedException e) {
@@ -167,6 +160,11 @@
         });
 
         mAllTestsPassed = 0;
+
+        mBluetoothManager = getSystemService(BluetoothManager.class);
+        mBluetoothAdapter = mBluetoothManager.getAdapter();
+        mAdvertiser = mBluetoothAdapter.getBluetoothLeAdvertiser();
+        mCallback = new TestAdvertisingSetCallback();
     }
 
     private void startAdvertisingSet() throws InterruptedException {
@@ -323,11 +321,9 @@
         testList.add(R.string.ble_advertising_set_enable_disable);
         testList.add(R.string.ble_advertising_set_advertising_data);
         testList.add(R.string.ble_advertising_set_advertising_params);
-        if (mBluetoothAdapter.isLePeriodicAdvertisingSupported()) {
-            testList.add(R.string.ble_advertising_set_periodic_advertising_data);
-            testList.add(R.string.ble_advertising_set_periodic_advertising_enabled_disabled);
-            testList.add(R.string.ble_advertising_set_periodic_advertising_params);
-        }
+        testList.add(R.string.ble_advertising_set_periodic_advertising_data);
+        testList.add(R.string.ble_advertising_set_periodic_advertising_enabled_disabled);
+        testList.add(R.string.ble_advertising_set_periodic_advertising_params);
         testList.add(R.string.ble_advertising_set_scan_response_data);
         testList.add(R.string.ble_advertising_set_stop);
         return testList;
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java
index 861c6f6..212f988 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java
@@ -1847,6 +1847,8 @@
         // s1440p which is the max supported stream size in a combination, when preview
         // stabilization is on.
         Size maxPreviewSize = new Size(1920, 1440);
+        // QCIF, we test only sizes >= this.
+        Size minPreviewSize = new Size(176, 144);
         Size[] outputSizes = configMap.getOutputSizes(ImageFormat.YUV_420_888);
         if (outputSizes == null) {
             mSocketRunnableObj.sendResponse("supportedPreviewSizes", "");
@@ -1857,6 +1859,8 @@
                 .distinct()
                 .filter(s -> s.getWidth() * s.getHeight()
                         <= maxPreviewSize.getWidth() * maxPreviewSize.getHeight())
+                .filter(s -> s.getWidth() * s.getHeight()
+                        >= minPreviewSize.getWidth() * minPreviewSize.getHeight())
                 .sorted(Comparator.comparingInt(s -> s.getWidth() * s.getHeight()))
                 .map(Size::toString)
                 .collect(Collectors.joining(";"));
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsTestActivity.java
index d83464b..692538a 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsTestActivity.java
@@ -21,9 +21,8 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.res.Configuration;
-import android.hardware.camera2.CameraCharacteristics;
 import android.hardware.camera2.CameraManager;
-import android.os.Build;
+import android.mediapc.cts.common.PerformanceClassEvaluator;
 import android.os.Bundle;
 import android.text.method.ScrollingMovementMethod;
 import android.util.Log;
@@ -31,6 +30,11 @@
 import android.widget.TextView;
 import android.widget.Toast;
 
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Comparator;
@@ -39,17 +43,11 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
-import java.util.Map;
 import java.util.Set;
 import java.util.TreeSet;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import java.io.BufferedReader;
-import java.io.FileReader;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-
 import com.android.compatibility.common.util.ResultType;
 import com.android.compatibility.common.util.ResultUnit;
 import com.android.cts.verifier.ArrayTestListAdapter;
@@ -59,6 +57,7 @@
 
 import org.json.JSONArray;
 import org.json.JSONObject;
+import org.junit.rules.TestName;
 
 /**
  * Test for Camera features that require that the camera be aimed at a specific test scene.
@@ -81,12 +80,6 @@
             Arrays.asList(new String[] {RESULT_PASS, RESULT_FAIL, RESULT_NOT_EXECUTED}));
     private static final int MAX_SUMMARY_LEN = 200;
 
-    private static final int MPC12_CAMERA_LAUNCH_THRESHOLD = 600; // ms
-    private static final int MPC12_JPEG_CAPTURE_THRESHOLD = 1000; // ms
-
-    private static final String MPC_TESTS_REPORT_LOG_NAME = "MediaPerformanceClassLogs";
-    private static final String MPC_TESTS_REPORT_LOG_SECTION = "CameraIts";
-
     private static final Pattern MPC12_CAMERA_LAUNCH_PATTERN =
             Pattern.compile("camera_launch_time_ms:(\\d+(\\.\\d+)?)");
     private static final Pattern MPC12_JPEG_CAPTURE_PATTERN =
@@ -95,8 +88,12 @@
     private final ResultReceiver mResultsReceiver = new ResultReceiver();
     private boolean mReceiverRegistered = false;
 
+    public final TestName mTestName = new TestName();
+
     // Initialized in onCreate
     List<String> mToBeTestedCameraIds = null;
+    String mPrimaryRearCameraId = null;
+    String mPrimaryFrontCameraId = null;
 
     // Scenes
     private static final ArrayList<String> mSceneIds = new ArrayList<String> () {{
@@ -132,8 +129,15 @@
     private final HashMap<ResultKey, String> mSummaryMap = new HashMap<>();
     // All primary cameras for which MPC level test has run
     private Set<ResultKey> mExecutedMpcTests = null;
-    // Map primary camera id to MPC level
-    private final HashMap<String, Integer> mMpcLevelMap = new HashMap<>();
+    private static final String MPC_LAUNCH_REQ_NUM = "2.2.7.2/7.5/H-1-6";
+    private static final String MPC_JPEG_CAPTURE_REQ_NUM = "2.2.7.2/7.5/H-1-5";
+    // Performance class evaluator used for writing test result
+    PerformanceClassEvaluator mPce = new PerformanceClassEvaluator(mTestName);
+    PerformanceClassEvaluator.CameraLatencyRequirement mJpegLatencyReq =
+            mPce.addR7_5__H_1_5();
+    PerformanceClassEvaluator.CameraLatencyRequirement mLaunchLatencyReq =
+            mPce.addR7_5__H_1_6();
+
 
     final class ResultKey {
         public final String cameraId;
@@ -266,10 +270,7 @@
                         JSONArray metrics = sceneResult.getJSONArray("mpc_metrics");
                         for (int i = 0; i < metrics.length(); i++) {
                             String mpcResult = metrics.getString(i);
-                            if (!matchMpcResult(cameraId, mpcResult, MPC12_CAMERA_LAUNCH_PATTERN,
-                                    "2.2.7.2/7.5/H-1-6", MPC12_CAMERA_LAUNCH_THRESHOLD) &&
-                                    !matchMpcResult(cameraId, mpcResult, MPC12_JPEG_CAPTURE_PATTERN,
-                                    "2.2.7.2/7.5/H-1-5", MPC12_JPEG_CAPTURE_THRESHOLD)) {
+                            if (!matchMpcResult(cameraId, mpcResult)) {
                                 Log.e(TAG, "Error parsing MPC result string:" + mpcResult);
                                 return;
                             }
@@ -294,17 +295,6 @@
                             summary.toString(), 1.0, ResultType.NEUTRAL, ResultUnit.NONE);
                 }
 
-                //  Save MPC info once both front primary and rear primary data are collected.
-                if (mExecutedMpcTests.size() == 4) {
-                    ItsTestActivity.this.getReportLog().addValue(
-                            "Version", "0.0.1", ResultType.NEUTRAL, ResultUnit.NONE);
-                    for (Map.Entry<String, Integer> entry : mMpcLevelMap.entrySet()) {
-                        ItsTestActivity.this.getReportLog().addValue(entry.getKey(),
-                                entry.getValue(), ResultType.NEUTRAL, ResultUnit.NONE);
-                    }
-                    ItsTestActivity.this.getReportLog().submit();
-                }
-
                 // Display current progress
                 StringBuilder progress = new StringBuilder();
                 for (ResultKey k : mAllScenes) {
@@ -367,28 +357,44 @@
             }
         }
 
-        private boolean matchMpcResult(String cameraId, String mpcResult, Pattern pattern,
-                String reqNum, float threshold) {
-            Matcher matcher = pattern.matcher(mpcResult);
-            boolean match = matcher.matches();
-            final int LATEST_MPC_LEVEL = Build.VERSION_CODES.TIRAMISU;
+        private boolean matchMpcResult(String cameraId, String mpcResult) {
+            Matcher launchMatcher = MPC12_CAMERA_LAUNCH_PATTERN.matcher(mpcResult);
+            boolean launchMatches = launchMatcher.matches();
 
-            if (match) {
-                // Store test result
-                ItsTestActivity.this.getReportLog().addValue("Cam" + cameraId,
-                        mpcResult, ResultType.NEUTRAL, ResultUnit.NONE);
+            Matcher jpegMatcher = MPC12_JPEG_CAPTURE_PATTERN.matcher(mpcResult);
+            boolean jpegMatches = jpegMatcher.matches();
 
-                float latency = Float.parseFloat(matcher.group(1));
-                int mpcLevel = latency < threshold ? LATEST_MPC_LEVEL : 0;
-                mExecutedMpcTests.add(new ResultKey(cameraId, reqNum));
-
-                if (mMpcLevelMap.containsKey(reqNum)) {
-                    mpcLevel = Math.min(mpcLevel, mMpcLevelMap.get(reqNum));
-                }
-                mMpcLevelMap.put(reqNum, mpcLevel);
+            if (!launchMatches && !jpegMatches) {
+                return false;
+            }
+            if (!cameraId.equals(mPrimaryRearCameraId) &&
+                    !cameraId.equals(mPrimaryFrontCameraId)) {
+                return false;
             }
 
-            return match;
+            if (launchMatches) {
+                float latency = Float.parseFloat(launchMatcher.group(1));
+                if (cameraId.equals(mPrimaryRearCameraId)) {
+                    mLaunchLatencyReq.setRearCameraLatency(latency);
+                } else {
+                    mLaunchLatencyReq.setFrontCameraLatency(latency);
+                }
+                mExecutedMpcTests.add(new ResultKey(cameraId, MPC_LAUNCH_REQ_NUM));
+            } else {
+                float latency = Float.parseFloat(jpegMatcher.group(1));
+                if (cameraId.equals(mPrimaryRearCameraId)) {
+                    mJpegLatencyReq.setRearCameraLatency(latency);
+                } else {
+                    mJpegLatencyReq.setFrontCameraLatency(latency);
+                }
+                mExecutedMpcTests.add(new ResultKey(cameraId, MPC_JPEG_CAPTURE_REQ_NUM));
+            }
+
+            // Save MPC info once both front primary and rear primary data are collected.
+            if (mExecutedMpcTests.size() == 4) {
+                mPce.submit();
+            }
+            return true;
         }
     }
 
@@ -397,8 +403,11 @@
         // Hide the test if all camera devices are legacy
         CameraManager manager = (CameraManager) this.getSystemService(Context.CAMERA_SERVICE);
         try {
-            ItsUtils.ItsCameraIdList cameraIdList = ItsUtils.getItsCompatibleCameraIds(manager);
+            ItsUtils.ItsCameraIdList cameraIdList =
+                    ItsUtils.getItsCompatibleCameraIds(manager);
             mToBeTestedCameraIds = cameraIdList.mCameraIdCombos;
+            mPrimaryRearCameraId = cameraIdList.mPrimaryRearCameraId;
+            mPrimaryFrontCameraId = cameraIdList.mPrimaryFrontCameraId;
         } catch (ItsException e) {
             Toast.makeText(ItsTestActivity.this,
                     "Received error from camera service while checking device capabilities: "
@@ -499,14 +508,4 @@
         setInfoResources(R.string.camera_its_test, R.string.camera_its_test_info, -1);
         setPassFailButtonClickListeners();
     }
-
-    @Override
-    public String getReportFileName() {
-        return MPC_TESTS_REPORT_LOG_NAME;
-    }
-
-    @Override
-    public String getReportSectionName() {
-        return MPC_TESTS_REPORT_LOG_SECTION;
-    }
 }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsUtils.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsUtils.java
index c648e8e..734b4a2 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsUtils.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsUtils.java
@@ -16,28 +16,24 @@
 
 package com.android.cts.verifier.camera.its;
 
-import android.content.Context;
 import android.graphics.ImageFormat;
 import android.graphics.Rect;
 import android.hardware.camera2.CameraAccessException;
 import android.hardware.camera2.CameraDevice;
 import android.hardware.camera2.CameraCharacteristics;
 import android.hardware.camera2.CameraManager;
+import android.hardware.camera2.CameraMetadata;
 import android.hardware.camera2.CaptureRequest;
-import android.hardware.camera2.CaptureResult;
 import android.hardware.camera2.params.MeteringRectangle;
 import android.hardware.camera2.params.StreamConfigurationMap;
 import android.media.Image;
 import android.media.Image.Plane;
-import android.net.Uri;
-import android.os.Environment;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.util.Log;
 import android.util.Size;
 
 import com.android.ex.camera2.blocking.BlockingCameraManager;
-import com.android.ex.camera2.blocking.BlockingCameraManager.BlockingOpenException;
 import com.android.ex.camera2.blocking.BlockingStateCallback;
 
 import org.json.JSONArray;
@@ -322,6 +318,9 @@
         // Camera Id combos (ids from CameraIdList, and hidden physical camera Ids
         // in the form of [logical camera id]:[hidden physical camera id]
         public List<String> mCameraIdCombos;
+        // Primary rear and front camera Ids (as defined in MPC)
+        public String mPrimaryRearCameraId;
+        public String mPrimaryFrontCameraId;
     }
 
     public static ItsCameraIdList getItsCompatibleCameraIds(CameraManager manager)
@@ -345,6 +344,18 @@
                         CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE;
                 final int LOGICAL_MULTI_CAMERA =
                         CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA;
+
+                final Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);
+                if (facing != null) {
+                    if (facing == CameraMetadata.LENS_FACING_BACK
+                            && outList.mPrimaryRearCameraId == null) {
+                        outList.mPrimaryRearCameraId = id;
+                    } else if (facing == CameraMetadata.LENS_FACING_FRONT
+                            && outList.mPrimaryFrontCameraId == null) {
+                        outList.mPrimaryFrontCameraId = id;
+                    }
+                }
+
                 for (int capability : actualCapabilities) {
                     if (capability == BACKWARD_COMPAT) {
                         haveBC = true;
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/clipboard/ClipboardPreviewTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/clipboard/ClipboardPreviewTestActivity.java
index 3587e6f..63b8904 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/clipboard/ClipboardPreviewTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/clipboard/ClipboardPreviewTestActivity.java
@@ -18,49 +18,22 @@
 
 
 import android.content.ClipData;
+import android.content.ClipDescription;
 import android.content.ClipboardManager;
-import android.graphics.Color;
 import android.os.Bundle;
+import android.os.PersistableBundle;
 import android.view.View;
 import android.widget.Button;
 
 import com.android.cts.verifier.PassFailButtons;
 import com.android.cts.verifier.R;
 
-import java.util.concurrent.ThreadLocalRandom;
-
 
 /**
- * A CTS Verifier test case for validating the user-visible clipboard preview.
- *
- * This test assumes bluetooth is turned on and the device is already paired with a second device.
- * Note: the second device need not be an Android device; it could be a laptop or desktop.
+ * A CTS Verifier test case for validating the user-visible clipboard confirmation.
  */
 public class ClipboardPreviewTestActivity extends PassFailButtons.Activity {
 
-    /**
-     * The content of the test file being transferred.
-     */
-    private static final String TEST_STRING = "Sample Test String";
-    /**
-     * The name of the test file being transferred.
-     */
-    private final int[] mSecretCode = new int[4];
-    private final int[] mSecretGuess = new int[4];
-    private final int[] mButtons = {
-            R.id.clipboard_preview_test_b0,
-            R.id.clipboard_preview_test_b1,
-            R.id.clipboard_preview_test_b2,
-            R.id.clipboard_preview_test_b3,
-            R.id.clipboard_preview_test_b4,
-            R.id.clipboard_preview_test_b5,
-            R.id.clipboard_preview_test_b6,
-            R.id.clipboard_preview_test_b7,
-            R.id.clipboard_preview_test_b8,
-            R.id.clipboard_preview_test_b9
-    };
-    private int mGuessIndex = 0;
-
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -74,87 +47,29 @@
         copyButton.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
-                generateAndCopySecret();
+                setClipboardData();
             }
         });
-        disableKeypad();
+        disablePassFail();
     }
 
-    private void generateAndCopySecret() {
-        String s = "";
-        resetState();
-        for (int i = 0; i < mSecretCode.length; ++i) {
-            mSecretCode[i] = ThreadLocalRandom.current().nextInt(0, 10);
-            s += mSecretCode[i];
-        }
+    private void setClipboardData() {
         ClipboardManager cm = this.getSystemService(ClipboardManager.class);
-        cm.setPrimaryClip(ClipData.newPlainText("Secret", s));
-        enableKeypad();
+
+        ClipData cd = ClipData.newPlainText("",
+                getString(R.string.clipboard_preview_test_secret));
+        PersistableBundle pb = new PersistableBundle(1);
+        pb.putBoolean(ClipDescription.EXTRA_IS_SENSITIVE, true);
+        cd.getDescription().setExtras(pb);
+        cm.setPrimaryClip(cd);
+        enablePassFail();
     }
 
-    private void enableKeypad() {
-        for (int i = 0; i < mButtons.length; ++i) {
-            Button numButton = findViewById(mButtons[i]);
-            numButton.setBackgroundColor(Color.GREEN);
-            int finalI = i;
-            numButton.setOnClickListener(new View.OnClickListener() {
-                @Override
-                public void onClick(View v) {
-                    buttonClicked(finalI);
-                }
-            });
-        }
-    }
-
-    private void disableKeypad() {
-        for (int i = 0; i < mButtons.length; ++i) {
-            Button numButton = findViewById(mButtons[i]);
-            numButton.setOnClickListener(null);
-            numButton.setBackgroundColor(Color.LTGRAY);
-        }
-    }
-
-    private void resetState() {
-        for (int i = 0; i < mSecretGuess.length; ++i) {
-            mSecretGuess[i] = -1;
-        }
-        mGuessIndex = 0;
-        View v = findViewById(R.id.clipboard_preview_test_pass_fail);
+    private void disablePassFail() {
         findViewById(R.id.clipboard_preview_test_pass_fail).setVisibility(View.INVISIBLE);
-        findViewById(R.id.fail_button).setVisibility(View.VISIBLE);
-        findViewById(R.id.pass_button).setVisibility(View.VISIBLE);
     }
 
-    private void buttonClicked(int i) {
-        if (mGuessIndex < mSecretGuess.length) {
-            mSecretGuess[mGuessIndex] = i;
-            ++mGuessIndex;
-        }
-        checkSolution();
-    }
-
-    private void checkSolution() {
-        boolean testPassed = true;
-        if (mGuessIndex == mSecretGuess.length) {
-            for (int i = 0; i < mSecretGuess.length && i < mSecretCode.length; ++i) {
-                if (mSecretGuess[i] != mSecretCode[i]) {
-                    testPassed = false;
-                }
-            }
-            markPassed(testPassed);
-            disableKeypad();
-        }
-    }
-
-    private void markPassed(boolean passed) {
+    private void enablePassFail() {
         findViewById(R.id.clipboard_preview_test_pass_fail).setVisibility(View.VISIBLE);
-        if (passed) {
-            findViewById(R.id.fail_button).setVisibility(View.INVISIBLE);
-        } else {
-            findViewById(R.id.pass_button).setVisibility(View.INVISIBLE);
-        }
-
     }
-
-
 }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/companion/CompanionDeviceServiceTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/companion/CompanionDeviceServiceTestActivity.java
index b8b9602..97ec07a 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/companion/CompanionDeviceServiceTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/companion/CompanionDeviceServiceTestActivity.java
@@ -118,7 +118,7 @@
 
     /** Stop observing to associated device and then disassociate. */
     private void disassociate(AssociationInfo association) {
-        String deviceAddress = association.getDeviceMacAddressAsString();
+        String deviceAddress = association.getDeviceMacAddress().toString();
         mCompanionDeviceManager.stopObservingDevicePresence(deviceAddress);
         mCompanionDeviceManager.disassociate(association.getId());
         Log.d(LOG_TAG, "Disassociated with device: " + deviceAddress);
@@ -142,11 +142,14 @@
             AssociationInfo association =
                     data.getParcelableExtra(CompanionDeviceManager.EXTRA_ASSOCIATION,
                     AssociationInfo.class);
-            String deviceAddress = association.getDeviceMacAddressAsString();
 
             // This test is for bluetooth devices, which should all have a MAC address.
-            if (deviceAddress == null) fail("The device was present but its address was null.");
+            if (association == null || association.getDeviceMacAddress() == null) {
+                fail("The device was present but its address was null.");
+                return;
+            }
 
+            String deviceAddress = association.getDeviceMacAddress().toString();
             mCompanionDeviceManager.startObservingDevicePresence(deviceAddress);
             mCurrentAssociation = getAssociation(association.getId());
             Log.d(LOG_TAG, "Associated with device: " + deviceAddress);
@@ -285,7 +288,9 @@
         @Override
         boolean verify() {
             // Check that it is associated and being observed.
-            return mCurrentAssociation != null && mCurrentAssociation.isNotifyOnDeviceNearby();
+            // Bypass inaccessible AssociationInfo#isNotifyOnDeviceNearby() with toString()
+            return mCurrentAssociation != null
+                    && mCurrentAssociation.toString().contains("mNotifyOnDeviceNearby=true");
         }
     }
 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/companion/DevicePresenceListener.java b/apps/CtsVerifier/src/com/android/cts/verifier/companion/DevicePresenceListener.java
index 37760d5..11829c3 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/companion/DevicePresenceListener.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/companion/DevicePresenceListener.java
@@ -45,7 +45,7 @@
     @Override
     public void onDeviceAppeared(AssociationInfo association) {
         NEARBY_DEVICES.add(association.getId());
-        String message = "Device appeared: " + association.getDeviceMacAddressAsString();
+        String message = "Device appeared: " + association.getDeviceMacAddress();
         Log.d(LOG_TAG, message);
         Toast.makeText(this, message, Toast.LENGTH_LONG).show();
     }
@@ -53,7 +53,7 @@
     @Override
     public void onDeviceDisappeared(AssociationInfo association) {
         NEARBY_DEVICES.remove(association.getId());
-        String message = "Device disappeared: " + association.getDeviceMacAddressAsString();
+        String message = "Device disappeared: " + association.getDeviceMacAddress();
         Log.d(LOG_TAG, message);
         Toast.makeText(this, message, Toast.LENGTH_LONG).show();
     }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/presence/BleRssiPrecisionActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/presence/BleRssiPrecisionActivity.java
deleted file mode 100644
index 1548910..0000000
--- a/apps/CtsVerifier/src/com/android/cts/verifier/presence/BleRssiPrecisionActivity.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.verifier.presence;
-
-import android.app.AlertDialog;
-import android.bluetooth.BluetoothAdapter;
-import android.content.pm.PackageManager;
-import android.os.Bundle;
-import android.text.Editable;
-import android.util.Log;
-import android.widget.EditText;
-
-import com.android.compatibility.common.util.ResultType;
-import com.android.compatibility.common.util.ResultUnit;
-import com.android.cts.verifier.PassFailButtons;
-import com.android.cts.verifier.R;
-
-/** Tests the precision of the device's RSSI measurement wtfdelet */
-public class BleRssiPrecisionActivity extends PassFailButtons.Activity {
-    private static final String TAG = BleRssiPrecisionActivity.class.getName();
-
-    // Report log schema
-    private static final String KEY_RSSI_RANGE_DBM = "rssi_range_dbm";
-    private static final String KEY_REFERENCE_DEVICE = "reference_device";
-
-    // Thresholds
-    private static final int MAX_RSSI_RANGE_DBM = 18;
-
-    private EditText reportRssiRangeEditText;
-    private EditText reportReferenceDeviceEditText;
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.ble_rssi_precision);
-        setPassFailButtonClickListeners();
-        getPassButton().setEnabled(false);
-
-        reportRssiRangeEditText = findViewById(R.id.report_rssi_range);
-        reportReferenceDeviceEditText = findViewById(R.id.report_reference_device);
-
-        DeviceFeatureChecker.checkFeatureSupported(this, getPassButton(),
-                PackageManager.FEATURE_BLUETOOTH_LE);
-
-        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
-
-        if (!adapter.isEnabled()) {
-            new AlertDialog.Builder(this)
-                    .setTitle(R.string.ble_bluetooth_disable_title)
-                    .setMessage(R.string.ble_bluetooth_disable_message)
-                    .setOnCancelListener(dialog -> finish())
-                    .create().show();
-        }
-
-        reportRssiRangeEditText.addTextChangedListener(
-                InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs()));
-        reportReferenceDeviceEditText.addTextChangedListener(
-                InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs()));
-    }
-
-    private void checkTestInputs() {
-        getPassButton().setEnabled(checkDistanceRangeInput() && checkReferenceDeviceInput());
-    }
-
-    private boolean checkDistanceRangeInput() {
-        String rssiRangeInput = reportRssiRangeEditText.getText().toString();
-
-        if (!rssiRangeInput.isEmpty()) {
-            int rssiRange = Integer.parseInt(rssiRangeInput);
-            // RSSI range must be inputted and within acceptable range before test can be passed
-            return rssiRange <= MAX_RSSI_RANGE_DBM;
-        }
-        return false;
-    }
-
-    private boolean checkReferenceDeviceInput() {
-        // Reference device must be inputted before test can be passed
-        return !reportReferenceDeviceEditText.getText().toString().isEmpty();
-    }
-
-    @Override
-    public void recordTestResults() {
-        String rssiRange = reportRssiRangeEditText.getText().toString();
-        String referenceDevice = reportReferenceDeviceEditText.getText().toString();
-
-        if (!rssiRange.isEmpty()) {
-            Log.i(TAG, "BLE RSSI Range (dBm): " + rssiRange);
-            getReportLog().addValue(KEY_RSSI_RANGE_DBM, Integer.parseInt(rssiRange),
-                    ResultType.NEUTRAL, ResultUnit.NONE);
-        }
-
-        if (!referenceDevice.isEmpty()) {
-            Log.i(TAG, "BLE Reference Device: " + referenceDevice);
-            getReportLog().addValue(KEY_REFERENCE_DEVICE, referenceDevice,
-                    ResultType.NEUTRAL, ResultUnit.NONE);
-        }
-        getReportLog().submit();
-    }
-}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/presence/BleRxTxCalibrationActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/presence/BleRxTxCalibrationActivity.java
deleted file mode 100644
index 2de7edf..0000000
--- a/apps/CtsVerifier/src/com/android/cts/verifier/presence/BleRxTxCalibrationActivity.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.verifier.presence;
-
-import android.app.AlertDialog;
-import android.bluetooth.BluetoothAdapter;
-import android.content.pm.PackageManager;
-import android.os.Bundle;
-import android.text.Editable;
-import android.util.Log;
-import android.widget.EditText;
-
-import com.android.compatibility.common.util.ResultType;
-import com.android.compatibility.common.util.ResultUnit;
-import com.android.cts.verifier.PassFailButtons;
-import com.android.cts.verifier.R;
-
-/**
- * Tests that the device's Rx/Tx calibration results in a median range (cm) within the specified
- * bounds
- */
-public class BleRxTxCalibrationActivity extends PassFailButtons.Activity {
-    private static final String TAG = BleRxTxCalibrationActivity.class.getName();
-
-    // Report log schema
-    private static final String KEY_CHANNEL_RSSI_RANGE = "channel_rssi_range";
-    private static final String KEY_CORE_RSSI_RANGE = "core_rssi_range";
-    private static final String KEY_REFERENCE_DEVICE = "reference_device";
-
-    // Thresholds
-    private static final int MAX_RSSI_RANGE = 6;
-
-    private EditText reportChannelsRssiRangeEditText;
-    private EditText reportCoresRssiRangeEditText;
-    private EditText reportReferenceDeviceEditText;
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.ble_rx_tx_calibration);
-        setPassFailButtonClickListeners();
-        getPassButton().setEnabled(false);
-
-        reportChannelsRssiRangeEditText = findViewById(R.id.report_channels_rssi_range);
-        reportCoresRssiRangeEditText = findViewById(R.id.report_cores_rssi_range);
-        reportReferenceDeviceEditText = findViewById(R.id.report_reference_device);
-
-        DeviceFeatureChecker.checkFeatureSupported(this, getPassButton(),
-                PackageManager.FEATURE_BLUETOOTH_LE);
-
-        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
-
-        if (!adapter.isEnabled()) {
-            new AlertDialog.Builder(this)
-                    .setTitle(R.string.ble_bluetooth_disable_title)
-                    .setMessage(R.string.ble_bluetooth_disable_message)
-                    .setOnCancelListener(dialog -> finish())
-                    .create().show();
-        }
-
-        reportChannelsRssiRangeEditText.addTextChangedListener(
-                InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs()));
-        reportCoresRssiRangeEditText.addTextChangedListener(
-                InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs()));
-        reportReferenceDeviceEditText.addTextChangedListener(
-                InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs()));
-    }
-
-    private void checkTestInputs() {
-        getPassButton().setEnabled(
-                checkChannelRssiInput() && checkCoreRssiInput() && checkReferenceDeviceInput());
-    }
-
-    private boolean checkChannelRssiInput() {
-        String channelsRssiRangeInput = reportChannelsRssiRangeEditText.getText().toString();
-        if (!channelsRssiRangeInput.isEmpty()) {
-            int channelsRssiRange = Integer.parseInt(channelsRssiRangeInput);
-            // RSSI range must be inputted and within acceptable range before test can be passed
-            return channelsRssiRange <= MAX_RSSI_RANGE;
-        }
-        return false;
-    }
-
-    private boolean checkCoreRssiInput() {
-        String coresRssiRangeInput = reportCoresRssiRangeEditText.getText().toString();
-        if (!coresRssiRangeInput.isEmpty()) {
-            int coresRssiRange = Integer.parseInt(coresRssiRangeInput);
-            // RSSI range must be inputted and within acceptable range before test can be passed
-            return coresRssiRange <= MAX_RSSI_RANGE;
-        }
-        // This field is optional, so return true even if the user has not inputted anything
-        return true;
-    }
-
-    private boolean checkReferenceDeviceInput() {
-        // Reference device must be inputted before test can be passed
-        return !reportReferenceDeviceEditText.getText().toString().isEmpty();
-    }
-
-    @Override
-    public void recordTestResults() {
-        String channelRssiRange = reportChannelsRssiRangeEditText.getText().toString();
-        String coreRssiRange = reportCoresRssiRangeEditText.getText().toString();
-        String referenceDevice = reportReferenceDeviceEditText.getText().toString();
-
-        if (!channelRssiRange.isEmpty()) {
-            Log.i(TAG, "BLE RSSI Range Across Channels (dBm): " + channelRssiRange);
-            getReportLog().addValue(KEY_CHANNEL_RSSI_RANGE, Integer.parseInt(channelRssiRange),
-                    ResultType.NEUTRAL, ResultUnit.NONE);
-        }
-
-        if (!coreRssiRange.isEmpty()) {
-            Log.i(TAG, "BLE RSSI Range Across Cores (dBm): " + coreRssiRange);
-            getReportLog().addValue(KEY_CORE_RSSI_RANGE, Integer.parseInt(coreRssiRange),
-                    ResultType.NEUTRAL, ResultUnit.NONE);
-        }
-
-        if (!referenceDevice.isEmpty()) {
-            Log.i(TAG, "BLE Reference Device: " + referenceDevice);
-            getReportLog().addValue(KEY_REFERENCE_DEVICE, referenceDevice,
-                    ResultType.NEUTRAL, ResultUnit.NONE);
-        }
-
-        getReportLog().submit();
-    }
-}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/presence/DeviceFeatureChecker.java b/apps/CtsVerifier/src/com/android/cts/verifier/presence/DeviceFeatureChecker.java
deleted file mode 100644
index 256fe3a..0000000
--- a/apps/CtsVerifier/src/com/android/cts/verifier/presence/DeviceFeatureChecker.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2022 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.presence;
-import android.app.Activity;
-import android.content.Context;
-import android.util.Log;
-import android.view.View;
-import android.widget.Toast;
-
-/**
- * Checks if a device supports a hardware feature needed for a test, and passes the test
- * automatically otherwise.
- */
-public class DeviceFeatureChecker {
-
-    /** Checks if a feature is supported.
-     *
-     * @param feature must be a string defined in PackageManager
-     */
-    public static void checkFeatureSupported(Context context, View passButton, String feature) {
-        if (!context.getPackageManager().hasSystemFeature(feature)) {
-            String message = String.format("Device does not support %s, automatically passing test",
-                    feature);
-            Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
-            Log.e(context.getClass().getName(), message);
-            passButton.performClick();
-            Activity activity = (Activity) (context);
-            activity.finish();
-        }
-    }
-}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/presence/InputTextHandler.java b/apps/CtsVerifier/src/com/android/cts/verifier/presence/InputTextHandler.java
deleted file mode 100644
index 2de68a5..0000000
--- a/apps/CtsVerifier/src/com/android/cts/verifier/presence/InputTextHandler.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2022 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.presence;
-
-import android.text.Editable;
-import android.text.TextWatcher;
-
-/**
- * Handles editable text inputted into test activities.
- */
-public class InputTextHandler {
-
-    /** Callback that is executed when text is changed. Takes modified text as input. */
-    public interface OnTextChanged {
-        void run(Editable s);
-    }
-
-    /**
-     * Generic text changed handler that will execute the provided callback when text is modified.
-     *
-     * @param callback called when text is changed, and passed the modified text
-     */
-    public static TextWatcher getOnTextChangedHandler(OnTextChanged callback) {
-        return new TextWatcher() {
-            @Override
-            public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
-
-            @Override
-            public void onTextChanged(CharSequence s, int start, int before, int count) {}
-
-            @Override
-            public void afterTextChanged(Editable s) {
-                callback.run(s);
-            }
-        };
-    }
-}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/presence/NanPrecisionTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/presence/NanPrecisionTestActivity.java
deleted file mode 100644
index 458d192..0000000
--- a/apps/CtsVerifier/src/com/android/cts/verifier/presence/NanPrecisionTestActivity.java
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- * Copyright (C) 2022 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.presence;
-
-import android.content.pm.PackageManager;
-import android.os.Bundle;
-import android.text.Editable;
-import android.util.Log;
-import android.widget.EditText;
-
-import com.android.compatibility.common.util.ResultType;
-import com.android.compatibility.common.util.ResultUnit;
-import com.android.cts.verifier.PassFailButtons;
-import com.android.cts.verifier.R;
-
-import com.google.common.collect.ImmutableMap;
-
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Activity for testing that NAN measurements are within the acceptable ranges
- */
-public class NanPrecisionTestActivity extends PassFailButtons.Activity {
-    private static final String TAG = NanPrecisionTestActivity.class.getName();
-
-    // Report log schema
-    private static final String KEY_BANDWIDTH = "nan_bandwidth";
-    private static final String KEY_MEASUREMENT_RANGE_10CM_AT_68P = "measurement_range_10cm_68p";
-    private static final String KEY_MEASUREMENT_RANGE_1M_AT_68P = "measurement_range_1m_68p";
-    private static final String KEY_MEASUREMENT_RANGE_3M_AT_68p = "measurement_range_3m_68p";
-    private static final String KEY_MEASUREMENT_RANGE_5M_AT_68p = "measurement_range_5m_68p";
-    private static final String KEY_MEASUREMENT_RANGE_10CM_AT_90P = "measurement_range_10cm_90p";
-    private static final String KEY_MEASUREMENT_RANGE_1M_AT_90P = "measurement_range_1m_90p";
-    private static final String KEY_MEASUREMENT_RANGE_3M_AT_90p = "measurement_range_3m_90p";
-    private static final String KEY_MEASUREMENT_RANGE_5M_AT_90p = "measurement_range_5m_90p";
-    private static final String KEY_REFERENCE_DEVICE = "reference_device";
-
-    // Thresholds
-    private static final int MAX_DISTANCE_RANGE_METERS_160MHZ = 2;
-    private static final int MAX_DISTANCE_RANGE_METERS_80MHZ = 4;
-    private static final int MAX_DISTANCE_RANGE_METERS_40MHZ = 8;
-    private static final int MAX_DISTANCE_RANGE_METERS_20MHZ = 16;
-
-    // Maps NAN bandwidths to acceptable range thresholds
-    private static final ImmutableMap<Integer, Integer> BANDWIDTH_TO_THRESHOLD_MAP =
-            ImmutableMap.of(160, MAX_DISTANCE_RANGE_METERS_160MHZ, 80,
-                    MAX_DISTANCE_RANGE_METERS_80MHZ, 40, MAX_DISTANCE_RANGE_METERS_40MHZ, 20,
-                    MAX_DISTANCE_RANGE_METERS_20MHZ);
-
-    private EditText mBandwidthMhz;
-    private EditText mMeasurementRange10cmGt68p;
-    private EditText mMeasurementRange1mGt68p;
-    private EditText mMeasurementRange3mGt68p;
-    private EditText mMeasurementRange5mGt68p;
-    private EditText mMeasurementRange10cmGt90p;
-    private EditText mMeasurementRange1mGt90p;
-    private EditText mMeasurementRange3mGt90p;
-    private EditText mMeasurementRange5mGt90p;
-    private EditText mReferenceDeviceInput;
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.nan_precision);
-        setPassFailButtonClickListeners();
-        getPassButton().setEnabled(false);
-
-        mBandwidthMhz = (EditText) findViewById(R.id.nan_bandwidth);
-        mMeasurementRange10cmGt68p = (EditText) findViewById(R.id.distance_range_10cm_gt_68p);
-        mMeasurementRange1mGt68p = (EditText) findViewById(R.id.distance_range_1m_gt_68p);
-        mMeasurementRange3mGt68p = (EditText) findViewById(R.id.distance_range_3m_gt_68p);
-        mMeasurementRange5mGt68p = (EditText) findViewById(R.id.distance_range_5m_gt_68p);
-        mMeasurementRange10cmGt90p = (EditText) findViewById(R.id.distance_range_10cm_gt_90p);
-        mMeasurementRange1mGt90p = (EditText) findViewById(R.id.distance_range_1m_gt_90p);
-        mMeasurementRange3mGt90p = (EditText) findViewById(R.id.distance_range_3m_gt_90p);
-        mMeasurementRange5mGt90p = (EditText) findViewById(R.id.distance_range_5m_gt_90p);
-        mReferenceDeviceInput = (EditText) findViewById(R.id.reference_device);
-
-        DeviceFeatureChecker.checkFeatureSupported(this, getPassButton(),
-                PackageManager.FEATURE_WIFI_AWARE);
-
-        mBandwidthMhz.addTextChangedListener(
-                InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs()));
-        mMeasurementRange10cmGt68p.addTextChangedListener(
-                InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs()));
-        mMeasurementRange1mGt68p.addTextChangedListener(
-                InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs()));
-        mMeasurementRange3mGt68p.addTextChangedListener(
-                InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs()));
-        mMeasurementRange5mGt68p.addTextChangedListener(
-                InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs()));
-        mMeasurementRange10cmGt90p.addTextChangedListener(
-                InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs()));
-        mMeasurementRange1mGt90p.addTextChangedListener(
-                InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs()));
-        mMeasurementRange3mGt90p.addTextChangedListener(
-                InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs()));
-        mMeasurementRange5mGt90p.addTextChangedListener(
-                InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs()));
-        mReferenceDeviceInput.addTextChangedListener(
-                InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs()));
-    }
-
-    private void checkTestInputs() {
-        getPassButton().setEnabled(checkMeasurementRange68thPercentileInput()
-                && checkMeasurementRange90thPercentileInput()
-                && checkReferenceDeviceInput());
-    }
-
-    private boolean checkMeasurementRange68thPercentileInput() {
-        return checkRequiredMeasurementRangeInput(mMeasurementRange10cmGt68p,
-                mMeasurementRange1mGt68p, mMeasurementRange3mGt68p, mMeasurementRange5mGt68p);
-    }
-
-    private boolean checkMeasurementRange90thPercentileInput() {
-        String measurementRangeInput10cmGt90p = mMeasurementRange10cmGt90p.getText().toString();
-        String measurementRangeInput1mGt90p = mMeasurementRange1mGt90p.getText().toString();
-        String measurementRangeInput3mGt90p = mMeasurementRange3mGt90p.getText().toString();
-        String measurementRangeInput5mGt90p = mMeasurementRange5mGt90p.getText().toString();
-        List<String> optionalMeasurementRangeList = Arrays.asList(measurementRangeInput10cmGt90p,
-                measurementRangeInput1mGt90p,
-                measurementRangeInput3mGt90p, measurementRangeInput5mGt90p);
-
-        boolean inputted = false;
-        for (String input : optionalMeasurementRangeList) {
-            if (!input.isEmpty()) {
-                inputted = true;
-                break;
-            }
-        }
-        // If one of the ranges is inputted for one of the distances, then it becomes required
-        // that the ranges are inputted for all the distances and for tests to pass, must be
-        // acceptable values
-        return !inputted || checkRequiredMeasurementRangeInput(mMeasurementRange10cmGt90p,
-                mMeasurementRange1mGt90p, mMeasurementRange3mGt90p, mMeasurementRange5mGt90p);
-    }
-
-    private boolean checkRequiredMeasurementRangeInput(EditText rangeInput10cm,
-            EditText rangeInput1m, EditText rangeInput3m, EditText rangeInput5m) {
-        String bandwidthInputMhz = mBandwidthMhz.getText().toString();
-        String measurementRangeInput10cmGt = rangeInput10cm.getText().toString();
-        String measurementRangeInput1mGt = rangeInput1m.getText().toString();
-        String measurementRangeInput3mGt = rangeInput3m.getText().toString();
-        String measurementRangeInput5mGt = rangeInput5m.getText().toString();
-        List<String> requiredMeasurementRangeList = Arrays.asList(measurementRangeInput10cmGt,
-                measurementRangeInput1mGt,
-                measurementRangeInput3mGt, measurementRangeInput5mGt);
-
-        for (String input : requiredMeasurementRangeList) {
-            if (bandwidthInputMhz.isEmpty() || input.isEmpty()) {
-                // Distance range must be inputted for all fields so fail early otherwise
-                return false;
-            }
-            if (!BANDWIDTH_TO_THRESHOLD_MAP.containsKey(Integer.parseInt(bandwidthInputMhz))) {
-                // bandwidth must be one of the expected thresholds
-                return false;
-            }
-            double distanceRange = Double.parseDouble(input);
-            int bandwidth = Integer.parseInt(bandwidthInputMhz);
-            if (distanceRange > BANDWIDTH_TO_THRESHOLD_MAP.get(bandwidth)) {
-                // All inputs must be in acceptable range so fail early otherwise
-                return false;
-            }
-        }
-        return true;
-    }
-
-    private boolean checkReferenceDeviceInput() {
-        // Reference device used must be inputted before test can be passed.
-        return !mReferenceDeviceInput.getText().toString().isEmpty();
-    }
-
-    @Override
-    public void recordTestResults() {
-        String nanBandwidthMhz = mBandwidthMhz.getText().toString();
-        String measurementRange10cmGt68p = mMeasurementRange10cmGt68p.getText().toString();
-        String measurementRange1mGt68p = mMeasurementRange1mGt68p.getText().toString();
-        String measurementRange3mGt68p = mMeasurementRange3mGt68p.getText().toString();
-        String measurementRange5mGt68p = mMeasurementRange5mGt68p.getText().toString();
-        String measurementRange10cmGt90p = mMeasurementRange10cmGt90p.getText().toString();
-        String measurementRange1mGt90p = mMeasurementRange1mGt90p.getText().toString();
-        String measurementRange3mGt90p = mMeasurementRange3mGt90p.getText().toString();
-        String measurementRange5mGt90p = mMeasurementRange5mGt90p.getText().toString();
-        String referenceDevice = mReferenceDeviceInput.getText().toString();
-
-        if (!nanBandwidthMhz.isEmpty()) {
-            Log.i(TAG, "NAN Bandwidth at which data was collected: " + nanBandwidthMhz);
-            getReportLog().addValue(KEY_BANDWIDTH,
-                    Integer.parseInt(nanBandwidthMhz),
-                    ResultType.NEUTRAL, ResultUnit.NONE);
-        }
-
-        if (!measurementRange10cmGt68p.isEmpty()) {
-            Log.i(TAG, "NAN Measurement Range at 10cm: " + measurementRange10cmGt68p);
-            getReportLog().addValue(KEY_MEASUREMENT_RANGE_10CM_AT_68P,
-                    Double.parseDouble(measurementRange10cmGt68p),
-                    ResultType.NEUTRAL, ResultUnit.NONE);
-        }
-
-        if (!measurementRange1mGt68p.isEmpty()) {
-            Log.i(TAG, "NAN Measurement Range at 1m: " + measurementRange1mGt68p);
-            getReportLog().addValue(KEY_MEASUREMENT_RANGE_1M_AT_68P,
-                    Double.parseDouble(measurementRange1mGt68p),
-                    ResultType.NEUTRAL, ResultUnit.NONE);
-        }
-
-        if (!measurementRange3mGt68p.isEmpty()) {
-            Log.i(TAG, "NAN Measurement Range at 3m: " + measurementRange3mGt68p);
-            getReportLog().addValue(KEY_MEASUREMENT_RANGE_3M_AT_68p,
-                    Double.parseDouble(measurementRange3mGt68p),
-                    ResultType.NEUTRAL, ResultUnit.NONE);
-        }
-
-        if (!measurementRange5mGt68p.isEmpty()) {
-            Log.i(TAG, "NAN Measurement Range at 5m: " + measurementRange5mGt68p);
-            getReportLog().addValue(KEY_MEASUREMENT_RANGE_5M_AT_68p,
-                    Double.parseDouble(measurementRange5mGt68p),
-                    ResultType.NEUTRAL, ResultUnit.NONE);
-        }
-
-        if (!measurementRange10cmGt90p.isEmpty()) {
-            Log.i(TAG, "NAN Measurement Range at 10cm: " + measurementRange10cmGt68p);
-            getReportLog().addValue(KEY_MEASUREMENT_RANGE_10CM_AT_90P,
-                    Double.parseDouble(measurementRange10cmGt90p),
-                    ResultType.NEUTRAL, ResultUnit.NONE);
-        }
-
-        if (!measurementRange1mGt90p.isEmpty()) {
-            Log.i(TAG, "NAN Measurement Range at 1m: " + measurementRange1mGt90p);
-            getReportLog().addValue(KEY_MEASUREMENT_RANGE_1M_AT_90P,
-                    Double.parseDouble(measurementRange1mGt90p),
-                    ResultType.NEUTRAL, ResultUnit.NONE);
-        }
-
-        if (!measurementRange3mGt90p.isEmpty()) {
-            Log.i(TAG, "NAN Measurement Range at 3m: " + measurementRange3mGt90p);
-            getReportLog().addValue(KEY_MEASUREMENT_RANGE_3M_AT_90p,
-                    Double.parseDouble(measurementRange3mGt90p),
-                    ResultType.NEUTRAL, ResultUnit.NONE);
-        }
-
-        if (!measurementRange5mGt90p.isEmpty()) {
-            Log.i(TAG, "NAN Measurement Range at 5m: " + measurementRange5mGt90p);
-            getReportLog().addValue(KEY_MEASUREMENT_RANGE_5M_AT_90p,
-                    Double.parseDouble(measurementRange5mGt90p),
-                    ResultType.NEUTRAL, ResultUnit.NONE);
-        }
-
-        if (!referenceDevice.isEmpty()) {
-            Log.i(TAG, "NAN Reference Device: " + referenceDevice);
-            getReportLog().addValue(KEY_REFERENCE_DEVICE, referenceDevice,
-                    ResultType.NEUTRAL, ResultUnit.NONE);
-        }
-        getReportLog().submit();
-    }
-}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/presence/OWNERS b/apps/CtsVerifier/src/com/android/cts/verifier/presence/OWNERS
deleted file mode 100644
index e874499..0000000
--- a/apps/CtsVerifier/src/com/android/cts/verifier/presence/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-# Bug component: 1106357
-asalo@google.com
-jbabs@google.com
-christinatao@google.com
\ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/presence/PresenceTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/presence/PresenceTestActivity.java
deleted file mode 100644
index 6776693..0000000
--- a/apps/CtsVerifier/src/com/android/cts/verifier/presence/PresenceTestActivity.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2022 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.presence;
-
-import android.content.pm.PackageManager;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.SystemProperties;
-
-import com.android.cts.verifier.ManifestTestListAdapter;
-import com.android.cts.verifier.PassFailButtons;
-import com.android.cts.verifier.R;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class PresenceTestActivity extends PassFailButtons.TestListActivity {
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.pass_fail_list);
-        setPassFailButtonClickListeners();
-
-        List<String> disabledTest = new ArrayList<String>();
-        boolean isTv = getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK);
-        if (isTv) {
-            setInfoResources(R.string.presence_test, R.string.presence_test_tv_info, -1);
-            int firstSdk = SystemProperties.getInt("ro.product.first_api_level", 0);
-            if (firstSdk < Build.VERSION_CODES.TIRAMISU) {
-                disabledTest.add("com.android.cts.verifier.presence.UwbPrecisionActivity");
-                disabledTest.add("com.android.cts.verifier.presence.UwbShortRangeActivity");
-                disabledTest.add("com.android.cts.verifier.presence.BleRssiPrecisionActivity");
-                disabledTest.add("com.android.cts.verifier.presence.BleRxTxCalibrationActivity");
-                disabledTest.add("com.android.cts.verifier.presence.BleRxOffsetActivity");
-                disabledTest.add("com.android.cts.verifier.presence.BleTxOffsetActivity");
-                disabledTest.add("com.android.cts.verifier.presence.NanPrecisionTestActivity");
-            }
-        } else {
-            setInfoResources(R.string.presence_test, R.string.presence_test_info, -1);
-        }
-
-        setTestListAdapter(new ManifestTestListAdapter(this, PresenceTestActivity.class.getName(),
-                disabledTest.toArray(new String[disabledTest.size()])));
-    }
-}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/presence/UwbPrecisionActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/presence/UwbPrecisionActivity.java
deleted file mode 100644
index 5d1ff86..0000000
--- a/apps/CtsVerifier/src/com/android/cts/verifier/presence/UwbPrecisionActivity.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2022 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.presence;
-
-import android.content.pm.PackageManager;
-import android.os.Bundle;
-import android.text.Editable;
-import android.util.Log;
-import android.widget.EditText;
-
-import com.android.compatibility.common.util.ResultType;
-import com.android.compatibility.common.util.ResultUnit;
-import com.android.cts.verifier.PassFailButtons;
-import com.android.cts.verifier.R;
-
-/**
- * Activity for testing that UWB distance and angle of arrival measurements are within the right
- * range.
- */
-public class UwbPrecisionActivity extends PassFailButtons.Activity {
-    private static final String TAG = UwbPrecisionActivity.class.getName();
-    // Report log schema
-    private static final String KEY_DISTANCE_RANGE_CM = "distance_range_cm";
-    private static final String KEY_REFERENCE_DEVICE = "reference_device";
-    // Thresholds
-    private static final int MAX_DISTANCE_RANGE_CM = 30;
-
-    private EditText mDistanceRangeInput;
-    private EditText mReferenceDeviceInput;
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.uwb_precision);
-        setPassFailButtonClickListeners();
-        getPassButton().setEnabled(false);
-
-        mDistanceRangeInput = (EditText) findViewById(R.id.distance_range_cm);
-        mReferenceDeviceInput = (EditText) findViewById(R.id.reference_device);
-
-        DeviceFeatureChecker.checkFeatureSupported(this, getPassButton(),
-                PackageManager.FEATURE_UWB);
-
-        mDistanceRangeInput.addTextChangedListener(
-                InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs()));
-        mReferenceDeviceInput.addTextChangedListener(
-                InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs()));
-    }
-
-    private void checkTestInputs() {
-        getPassButton().setEnabled(
-                checkDistanceRangeInput() && checkReferenceDeviceInput());
-    }
-
-    private boolean checkDistanceRangeInput() {
-        String distanceRangeInput = mDistanceRangeInput.getText().toString();
-        if (!distanceRangeInput.isEmpty()) {
-            double distanceRange = Double.parseDouble(distanceRangeInput);
-            // Distance range must be inputted and within acceptable range before test can be
-            // passed.
-            return distanceRange <= MAX_DISTANCE_RANGE_CM;
-        }
-        return false;
-    }
-
-    private boolean checkReferenceDeviceInput() {
-        // Reference device must be inputted before test can be passed.
-        return !mReferenceDeviceInput.getText().toString().isEmpty();
-    }
-
-    @Override
-    public void recordTestResults() {
-        String distanceRange = mDistanceRangeInput.getText().toString();
-        String referenceDevice = mReferenceDeviceInput.getText().toString();
-        if (!distanceRange.isEmpty()) {
-            Log.i(TAG, "UWB Distance Range: " + distanceRange);
-            getReportLog().addValue(KEY_DISTANCE_RANGE_CM, Double.parseDouble(distanceRange),
-                    ResultType.NEUTRAL, ResultUnit.NONE);
-        }
-        if (!referenceDevice.isEmpty()) {
-            Log.i(TAG, "UWB Reference Device: " + referenceDevice);
-            getReportLog().addValue(KEY_REFERENCE_DEVICE, referenceDevice,
-                    ResultType.NEUTRAL, ResultUnit.NONE);
-        }
-        getReportLog().submit();
-    }
-}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/presence/UwbShortRangeActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/presence/UwbShortRangeActivity.java
deleted file mode 100644
index 7f14800..0000000
--- a/apps/CtsVerifier/src/com/android/cts/verifier/presence/UwbShortRangeActivity.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2022 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.presence;
-
-import android.content.pm.PackageManager;
-import android.os.Bundle;
-import android.text.Editable;
-import android.util.Log;
-import android.widget.EditText;
-
-import com.android.compatibility.common.util.ResultType;
-import com.android.compatibility.common.util.ResultUnit;
-import com.android.cts.verifier.PassFailButtons;
-import com.android.cts.verifier.R;
-
-/**
- * Activity for testing that UWB distance measurements are within the acceptable median.
- */
-public class UwbShortRangeActivity extends PassFailButtons.Activity {
-    private static final String TAG = UwbShortRangeActivity.class.getName();
-    // Report log schema
-    private static final String KEY_DISTANCE_MEDIAN_CM = "distance_median_cm";
-    private static final String KEY_REFERENCE_DEVICE = "reference_device";
-    // Median Thresholds
-    private static final double MIN_MEDIAN = 0.75;
-    private static final double MAX_MEDIAN = 1.25;
-    private EditText mMedianInput;
-    private EditText mReferenceDeviceInput;
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.uwb_short_range);
-        setPassFailButtonClickListeners();
-        getPassButton().setEnabled(false);
-
-        mMedianInput = (EditText) findViewById(R.id.distance_median_meters);
-        mReferenceDeviceInput = (EditText) findViewById(R.id.reference_device);
-
-        DeviceFeatureChecker.checkFeatureSupported(this, getPassButton(),
-                PackageManager.FEATURE_UWB);
-
-        mMedianInput.addTextChangedListener(
-                InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs()));
-        mReferenceDeviceInput.addTextChangedListener(
-                InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs()));
-    }
-
-    private void checkTestInputs() {
-        getPassButton().setEnabled(checkMedianInput() && checkReferenceDeviceInput());
-    }
-
-    private boolean checkMedianInput() {
-        String medianInput = mMedianInput.getText().toString();
-        if (!medianInput.isEmpty()) {
-            double median = Double.parseDouble(medianInput);
-            return median >= MIN_MEDIAN && median <= MAX_MEDIAN;
-        }
-        return false;
-    }
-
-    private boolean checkReferenceDeviceInput() {
-        return !mReferenceDeviceInput.getText().toString().isEmpty();
-    }
-
-    @Override
-    public void recordTestResults() {
-        String medianInput = mMedianInput.getText().toString();
-        String referenceDeviceInput = mReferenceDeviceInput.getText().toString();
-        if (!medianInput.isEmpty()) {
-            Log.i(TAG, "UWB Distance Median: " + medianInput);
-            getReportLog().addValue(KEY_DISTANCE_MEDIAN_CM, Double.parseDouble(medianInput),
-                    ResultType.NEUTRAL, ResultUnit.NONE);
-        }
-        if (!referenceDeviceInput.isEmpty()) {
-            Log.i(TAG, "UWB Reference Device: " + referenceDeviceInput);
-            getReportLog().addValue(KEY_REFERENCE_DEVICE, referenceDeviceInput, ResultType.NEUTRAL,
-                    ResultUnit.NONE);
-        }
-        getReportLog().submit();
-    }
-}
diff --git a/hostsidetests/scopedstorage/device/src/android/scopedstorage/cts/device/ScopedStorageDeviceTest.java b/hostsidetests/scopedstorage/device/src/android/scopedstorage/cts/device/ScopedStorageDeviceTest.java
index 099a0ab..35cb549 100644
--- a/hostsidetests/scopedstorage/device/src/android/scopedstorage/cts/device/ScopedStorageDeviceTest.java
+++ b/hostsidetests/scopedstorage/device/src/android/scopedstorage/cts/device/ScopedStorageDeviceTest.java
@@ -1772,6 +1772,37 @@
     }
 
     /**
+     * Test that renaming file paths to an external directory such as Android/* and Android/* /*
+     * except Android/media/* /* is not allowed.
+     */
+    @Test
+    public void testRenameFileToAppSpecificDir() throws Exception {
+        final File testFile = new File(getExternalMediaDir(), IMAGE_FILE_NAME);
+        final File testFileNew = new File(getExternalMediaDir(), NONMEDIA_FILE_NAME);
+
+        try {
+            // Create a file in app's external media directory
+            if (!testFile.exists()) {
+                assertThat(testFile.createNewFile()).isTrue();
+            }
+
+            final String androidDirPath = getExternalStorageDir().getPath() + "/Android";
+
+            // Verify that we can't rename a file to Android/ or Android/data or
+            // Android/media directory
+            assertCantRenameFile(testFile, new File(androidDirPath, IMAGE_FILE_NAME));
+            assertCantRenameFile(testFile, new File(androidDirPath + "/data", IMAGE_FILE_NAME));
+            assertCantRenameFile(testFile, new File(androidDirPath + "/media", IMAGE_FILE_NAME));
+
+            // Verify that we can rename a file to app specific media directory.
+            assertCanRenameFile(testFile, testFileNew);
+        } finally {
+            testFile.delete();
+            testFileNew.delete();
+        }
+    }
+
+    /**
      * Test that renaming directories is allowed and aligns to default directory restrictions.
      */
     @Test
diff --git a/hostsidetests/security/src/android/security/cts/SELinuxHostTest.java b/hostsidetests/security/src/android/security/cts/SELinuxHostTest.java
index 573035c..13ade8b 100644
--- a/hostsidetests/security/src/android/security/cts/SELinuxHostTest.java
+++ b/hostsidetests/security/src/android/security/cts/SELinuxHostTest.java
@@ -1367,7 +1367,7 @@
     @CddTest(requirement="9.7")
     @Test
     public void testDrmServerDomain() throws DeviceNotAvailableException {
-        assertDomainN("u:r:drmserver:s0", "/system/bin/drmserver", "/system/bin/drmserver64");
+        assertDomainHasExecutable("u:r:drmserver:s0", "/system/bin/drmserver", "/system/bin/drmserver64");
     }
 
     /* Installd is always running */
diff --git a/hostsidetests/securitybulletin/Android.bp b/hostsidetests/securitybulletin/Android.bp
index 30b6161..2524227 100644
--- a/hostsidetests/securitybulletin/Android.bp
+++ b/hostsidetests/securitybulletin/Android.bp
@@ -43,6 +43,7 @@
 
 cc_defaults {
     name: "cts_hostsidetests_securitybulletin_defaults",
+    auto_gen_config: false,
     compile_multilib: "both",
     multilib: {
         lib32: {
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0954.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0954.java
index 12287b0..95c90d4 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0954.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0954.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -16,43 +16,39 @@
 
 package android.security.cts;
 
-import android.platform.test.annotations.AppModeFull;
+import static org.junit.Assume.assumeNoException;
+
 import android.platform.test.annotations.AsbSecurityTest;
 
+import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
 
-import org.junit.Assert;
-import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 @RunWith(DeviceJUnit4ClassRunner.class)
 public class CVE_2021_0954 extends StsExtraBusinessLogicHostTestBase {
-    private static final String TEST_PKG = "android.security.cts.cve_2021_0954";
-    private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
-    private static final String TEST_APP = "CVE-2021-0954.apk";
-    private ITestDevice device;
+    private static final String TEST_PKG = "android.security.cts.CVE_2021_0954";
 
-    @Before
-    public void setUp() throws Exception {
-        device = getDevice();
-        uninstallPackage(device, TEST_PKG);
-
-        /* Wake up the screen */
-        AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP", device);
-        AdbUtils.runCommandLine("input keyevent KEYCODE_MENU", device);
-        AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device);
-    }
-
-    @AppModeFull
     @AsbSecurityTest(cveBugId = 143559931)
     @Test
     public void testPocCVE_2021_0954() throws Exception {
-        installPackage(TEST_APP);
-        AdbUtils.runCommandLine("pm grant " + TEST_PKG + " android.permission.SYSTEM_ALERT_WINDOW",
-                device);
-        runDeviceTests(TEST_PKG, TEST_CLASS, "testVulnerableActivityPresence");
+        try {
+            ITestDevice device = getDevice();
+            uninstallPackage(device, TEST_PKG);
+
+            /* Wake up the screen */
+            AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP", device);
+            AdbUtils.runCommandLine("input keyevent KEYCODE_MENU", device);
+            AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device);
+
+            installPackage("CVE-2021-0954.apk");
+            AdbUtils.runCommandLine(
+                    "pm grant " + TEST_PKG + " android.permission.SYSTEM_ALERT_WINDOW", device);
+            runDeviceTests(TEST_PKG, TEST_PKG + "." + "DeviceTest", "testOverlayButtonPresence");
+        } catch (Exception e) {
+            assumeNoException(e);
+        }
     }
 }
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20353.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20353.java
new file mode 100644
index 0000000..e661b4f
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20353.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts;
+
+import static org.junit.Assume.assumeNoException;
+
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2022_20353 extends StsExtraBusinessLogicHostTestBase {
+
+    @AsbSecurityTest(cveBugId = 221041256)
+    @Test
+    public void testPocCVE_2022_20353() {
+        try {
+            final String testPkg = "android.security.cts.CVE_2022_20353";
+            ITestDevice device = getDevice();
+
+            AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP", device);
+            AdbUtils.runCommandLine("input keyevent KEYCODE_MENU", device);
+            AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device);
+
+            // to generate NOTICE.html if not already present
+            AdbUtils.runCommandLine("am start -a android.settings.LICENSE", device);
+
+            installPackage("CVE-2022-20353.apk");
+
+            runDeviceTests(testPkg, testPkg + ".DeviceTest", "testDefaultRingtonePreference");
+        } catch (Exception e) {
+            assumeNoException(e);
+        }
+    }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/Android.bp
index aa9f71f..59350cf 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/Android.bp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -18,10 +18,10 @@
 android_test_helper_app {
     name: "CVE-2021-0954",
     defaults: ["cts_support_defaults"],
-    srcs: ["src/**/*.java"],
+    srcs: [
+        "src/**/*.java"
+    ],
     test_suites: [
-        "cts",
-        "vts10",
         "sts",
     ],
     static_libs: [
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/AndroidManifest.xml
index a7e0218..75299c4 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/AndroidManifest.xml
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/AndroidManifest.xml
@@ -1,5 +1,5 @@
 <!--
-  Copyright 2021 The Android Open Source Project
+  Copyright 2022 The Android Open Source Project
 
   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
@@ -13,25 +13,19 @@
   See the License for the specific language governing permissions and
   limitations under the License.
   -->
+
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:tools="http://schemas.android.com/tools"
-    package="android.security.cts.cve_2021_0954"
+    package="android.security.cts.CVE_2021_0954"
     android:versionCode="1"
     android:versionName="1.0">
-
     <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
-
-    <application
-        android:allowBackup="true"
-        android:label="CVE_2021_0954"
-        android:supportsRtl="true">
-        <uses-library android:name="android.test.runner" />
+    <application>
         <service android:name=".PocService"
             android:enabled="true"
-            android:exported="false" />
+            android:exported="true" />
     </application>
-
    <instrumentation
         android:name="androidx.test.runner.AndroidJUnitRunner"
-        android:targetPackage="android.security.cts.cve_2021_0954" />
+        android:targetPackage="android.security.cts.CVE_2021_0954" />
 </manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/res/values/integers.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/res/values/integers.xml
new file mode 100644
index 0000000..363df00
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/res/values/integers.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2022 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>
+    <integer name="assumptionFailure">-1</integer>
+    <integer name="noAssumptionFailure">0</integer>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/res/values/strings.xml
new file mode 100644
index 0000000..7c4d959
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/res/values/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2022 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>
+    <string name="canNotDrawOverlaysMsg">The application cannot draw overlays</string>
+    <string name="defaultSemaphoreMsg">Could not get message key in shared preferences</string>
+    <string name="cmdDumpsysActivity">dumpsys activity %1$s</string>
+    <string name="empty"></string>
+    <string name="overlayErrorMessage">Device is vulnerable to b/143559931 hence any app with
+    "SYSTEM_ALERT_WINDOW can overlay the %1$s screen</string>
+    <string name="mResumedTrue">mResumed=true</string>
+    <string name="messageKey">message</string>
+    <string name="overlayButtonText">OverlayButton</string>
+    <string name="overlayUiScreenError">Overlay UI did not appear on the screen</string>
+    <string name="resultKey">result</string>
+    <string name="sharedPreferences">CVE_2021_0954_prefs</string>
+    <string name="timedOutPocActivity">Timed out waiting on a result from PocActivity</string>
+    <string name="vulClass">com.android.internal.app.ResolverActivity</string>
+    <string name="vulClassAuto">com.android.car.activityresolver.CarResolverActivity</string>
+    <string name="vulPkg">android</string>
+    <string name="vulPkgAuto">com.android.car.activityresolver</string>
+    <string name="vulActivityNotRunningError">The %1$s is not currently running on the device
+    </string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/src/android/security/cts/CVE_2021_0954/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/src/android/security/cts/CVE_2021_0954/DeviceTest.java
index f986906..9a94ef9 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/src/android/security/cts/CVE_2021_0954/DeviceTest.java
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/src/android/security/cts/CVE_2021_0954/DeviceTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2022 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,17 +14,20 @@
  * limitations under the License.
  */
 
-package android.security.cts.cve_2021_0954;
+package android.security.cts.CVE_2021_0954;
 
 import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assume.assumeNoException;
 
-import android.content.ActivityNotFoundException;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeTrue;
+
 import android.content.Context;
 import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.content.pm.PackageManager;
 import android.provider.Settings;
 
 import androidx.test.runner.AndroidJUnit4;
@@ -32,90 +35,107 @@
 import androidx.test.uiautomator.UiDevice;
 import androidx.test.uiautomator.Until;
 
-import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import java.io.IOException;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
 import java.util.regex.Pattern;
 
 @RunWith(AndroidJUnit4.class)
 public class DeviceTest {
-    private static final String TEST_PKG = "android.security.cts.cve_2021_0954";
-    private static final String TEST_VULNERABLE_PKG = "android";
-    private static final String TEST_VULNERABLE_ACTIVITY =
-            "com.android.internal.app.ResolverActivity";
-    private static final int LAUNCH_TIMEOUT_MS = 20000;
-    private static final String vulnerableActivityName = "ResolverActivity";
-    private UiDevice mDevice;
-    String activityDump = "";
+    private Context mContext = getApplicationContext();
+    private static final int TIMEOUT_MS = 10000;
 
-    private void startOverlayService() {
-        Context context = getApplicationContext();
-        assertNotNull(context);
-        Intent intent = new Intent(context, PocService.class);
-        assertNotNull(intent);
-
-        if (Settings.canDrawOverlays(getApplicationContext())) {
-            context.startService(intent);
-        } else {
-            try {
-                context.startService(intent);
-            } catch (Exception e) {
-                throw new RuntimeException("Unable to start the overlay service", e);
-            }
-        }
+    private boolean hasFeature(String feature) {
+        return mContext.getPackageManager().hasSystemFeature(feature);
     }
 
-    public void startVulnerableActivity() {
-        Context context = getApplicationContext();
-        Intent intent = new Intent();
-        intent.setClassName(TEST_VULNERABLE_PKG, TEST_VULNERABLE_ACTIVITY);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        try {
-            context.startActivity(intent);
-        } catch (ActivityNotFoundException e) {
-            assumeNoException("Activity not found on device", e);
-        }
+    private boolean isAuto() {
+        return hasFeature(PackageManager.FEATURE_AUTOMOTIVE);
     }
 
-    @Before
-    public void setUp() throws Exception {
-        mDevice = UiDevice.getInstance(getInstrumentation());
+    String getStringRes(int key) {
+        return mContext.getResources().getString(key);
+    }
 
-        /* Start the vulnerable activity */
-        startVulnerableActivity();
-        if (!mDevice.wait(Until.hasObject(By.res("android:id/contentPanel")
-                .clazz("android.widget.ScrollView").pkg("android")), LAUNCH_TIMEOUT_MS)) {
-            return;
-        }
+    String getStringResWithArg(int key, String arg) {
+        return mContext.getResources().getString(key, arg);
+    }
 
-        /* Start the overlay service */
-        startOverlayService();
+    int getIntegerRes(int key) {
+        return mContext.getResources().getInteger(key);
     }
 
     @Test
-    public void testVulnerableActivityPresence() {
-        Pattern overlayTextPattern = Pattern.compile("OverlayButton", Pattern.CASE_INSENSITIVE);
-        if (!mDevice.wait(Until.hasObject(By.text(overlayTextPattern)), LAUNCH_TIMEOUT_MS)) {
-            return;
-        }
-
-        /*
-         * Check if the currently running activity is the vulnerable activity, if not abort the test
-         */
+    public void testOverlayButtonPresence() {
         try {
-            activityDump = mDevice.executeShellCommand("dumpsys activity");
-        } catch (IOException e) {
-            throw new RuntimeException("Could not execute dumpsys activity command");
+            UiDevice device = UiDevice.getInstance(getInstrumentation());
+
+            /* Start the overlay service */
+            assumeTrue(getStringRes(R.string.canNotDrawOverlaysMsg),
+                    Settings.canDrawOverlays(mContext));
+            Intent intent = new Intent(mContext, PocService.class);
+            mContext.startService(intent);
+
+            /* Wait for a result from overlay service */
+            SharedPreferences sharedPrefs = mContext.getSharedPreferences(
+                    getStringRes(R.string.sharedPreferences), Context.MODE_PRIVATE);
+            final Semaphore preferenceChanged = new Semaphore(0);
+            OnSharedPreferenceChangeListener listener = new OnSharedPreferenceChangeListener() {
+                @Override
+                public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
+                        String key) {
+                    if (key.equals(getStringRes(R.string.resultKey))) {
+                        preferenceChanged.release();
+                    }
+                }
+            };
+            sharedPrefs.registerOnSharedPreferenceChangeListener(listener);
+            assumeTrue(preferenceChanged.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+            int result = sharedPrefs.getInt(getStringRes(R.string.resultKey),
+                    getIntegerRes(R.integer.assumptionFailure));
+            String message = sharedPrefs.getString(getStringRes(R.string.messageKey),
+                    getStringRes(R.string.defaultSemaphoreMsg));
+            assumeTrue(message, result != getIntegerRes(R.integer.assumptionFailure));
+
+            /* Wait for the UI of overlay window to appear */
+            Pattern overlayTextPattern = Pattern.compile(
+                    mContext.getString(R.string.overlayButtonText), Pattern.CASE_INSENSITIVE);
+            assumeTrue(mContext.getString(R.string.overlayUiScreenError),
+                    device.wait(Until.hasObject(By.text(overlayTextPattern)), TIMEOUT_MS));
+
+            /* Start the vulnerable activity */
+            intent = new Intent();
+            String vulActivity = getStringRes(R.string.vulClass);
+            String vulPkg = getStringRes(R.string.vulPkg);
+            if (isAuto()) {
+                vulActivity = getStringRes(R.string.vulClassAuto);
+                vulPkg = getStringRes(R.string.vulPkgAuto);
+            }
+            intent.setClassName(vulPkg, vulActivity);
+            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            mContext.startActivity(intent);
+
+            /* Wait until the object of overlay window is gone */
+            boolean overlayDisallowed =
+                    device.wait(Until.gone(By.pkg(mContext.getPackageName())), TIMEOUT_MS);
+
+            /*
+             * Check if the currently running activity is the vulnerable activity, if not abort the
+             * test
+             */
+            String activityDump = device.executeShellCommand(
+                    getStringResWithArg(R.string.cmdDumpsysActivity, vulActivity));
+            Pattern activityPattern = Pattern.compile(getStringRes(R.string.mResumedTrue));
+            assumeTrue(getStringRes(R.string.vulActivityNotRunningError),
+                    activityPattern.matcher(activityDump).find());
+
+            /* Failing the test as fix is not present */
+            assertTrue(getStringResWithArg(R.string.overlayErrorMessage, vulActivity),
+                    overlayDisallowed);
+        } catch (Exception e) {
+            assumeNoException(e);
         }
-        Pattern activityPattern =
-                Pattern.compile("mResumedActivity.*" + vulnerableActivityName + ".*\n");
-        if (!activityPattern.matcher(activityDump).find()) {
-            return;
-        }
-        String message = "Device is vulnerable to b/143559931 hence any app with "
-                + "SYSTEM_ALERT_WINDOW can overlay the ResolverActivity screen";
-        assertNull(message, mDevice.findObject(By.text(overlayTextPattern)));
     }
 }
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/src/android/security/cts/CVE_2021_0954/PocService.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/src/android/security/cts/CVE_2021_0954/PocService.java
index 82b78a2..79270ba 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/src/android/security/cts/CVE_2021_0954/PocService.java
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/src/android/security/cts/CVE_2021_0954/PocService.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2022 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,47 +14,65 @@
  * limitations under the License.
  */
 
-package android.security.cts.cve_2021_0954;
+package android.security.cts.CVE_2021_0954;
 
 import android.app.Service;
+import android.content.Context;
 import android.content.Intent;
+import android.content.SharedPreferences;
 import android.content.res.Resources;
 import android.graphics.PixelFormat;
-import android.os.Handler;
 import android.os.IBinder;
-import android.provider.Settings;
 import android.view.Gravity;
 import android.view.WindowManager;
 import android.view.WindowManager.LayoutParams;
 import android.widget.Button;
 
 public class PocService extends Service {
-    public static Button mButton;
-    private WindowManager mWindowManager;
-    private WindowManager.LayoutParams mLayoutParams;
+    Button mButton;
+    WindowManager mWindowManager;
 
-    private static int getScreenWidth() {
+    private int getScreenWidth() {
         return Resources.getSystem().getDisplayMetrics().widthPixels;
     }
 
-    private static int getScreenHeight() {
+    private int getScreenHeight() {
         return Resources.getSystem().getDisplayMetrics().heightPixels;
     }
 
+    String getStringRes(int key) {
+        return getResources().getString(key);
+    }
+
+    int getIntegerRes(int key) {
+        return getResources().getInteger(key);
+    }
+
     @Override
     public void onCreate() {
-        super.onCreate();
-        mWindowManager = getSystemService(WindowManager.class);
-        mLayoutParams = new WindowManager.LayoutParams();
-        mLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
-        mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
-                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
-        mLayoutParams.format = PixelFormat.OPAQUE;
-        mLayoutParams.gravity = Gravity.LEFT | Gravity.TOP;
-        mLayoutParams.width = getScreenWidth();
-        mLayoutParams.height = getScreenHeight();
-        mLayoutParams.x = getScreenWidth() / 2;
-        mLayoutParams.y = getScreenHeight() / 2;
+        try {
+            super.onCreate();
+            mWindowManager = getSystemService(WindowManager.class);
+            LayoutParams layoutParams = new LayoutParams();
+            layoutParams.type = LayoutParams.TYPE_APPLICATION_OVERLAY;
+            layoutParams.flags =
+                    LayoutParams.FLAG_NOT_TOUCH_MODAL | LayoutParams.FLAG_NOT_FOCUSABLE;
+            layoutParams.format = PixelFormat.OPAQUE;
+            layoutParams.gravity = Gravity.LEFT | Gravity.TOP;
+            layoutParams.width = getScreenWidth();
+            layoutParams.height = getScreenHeight();
+            layoutParams.x = getScreenWidth() / 2;
+            layoutParams.y = getScreenHeight() / 2;
+
+            /* Show the floating window */
+            mButton = new Button(this);
+            mButton.setText(getString(R.string.overlayButtonText));
+            mWindowManager.addView(mButton, layoutParams);
+        } catch (Exception e) {
+            sendTestResult(getIntegerRes(R.integer.assumptionFailure), e.getMessage());
+            return;
+        }
+        sendTestResult(getIntegerRes(R.integer.noAssumptionFailure), getStringRes(R.string.empty));
     }
 
     @Override
@@ -63,31 +81,27 @@
     }
 
     @Override
-    public int onStartCommand(Intent intent, int flags, int startId) {
-        showFloatingWindow();
-        return super.onStartCommand(intent, flags, startId);
-    }
-
-    @Override
     public void onDestroy() {
-        if (mWindowManager != null && mButton != null) {
-            mWindowManager.removeView(mButton);
+        try {
+            if (mWindowManager != null && mButton != null) {
+                mWindowManager.removeView(mButton);
+            }
+            super.onDestroy();
+        } catch (Exception e) {
+            sendTestResult(getIntegerRes(R.integer.assumptionFailure), e.getMessage());
         }
-        super.onDestroy();
     }
 
-    private void showFloatingWindow() {
-        if (Settings.canDrawOverlays(this)) {
-            mButton = new Button(getApplicationContext());
-            mButton.setText("OverlayButton");
-            mWindowManager.addView(mButton, mLayoutParams);
-            new Handler().postDelayed(new Runnable() {
-                @Override
-                public void run() {
-                    onDestroy();
-                }
-            }, 60000); // one minute
-            mButton.setTag(mButton.getVisibility());
+    private void sendTestResult(int result, String message) {
+        try {
+            SharedPreferences sh = getSharedPreferences(getStringRes(R.string.sharedPreferences),
+                    Context.MODE_PRIVATE);
+            SharedPreferences.Editor edit = sh.edit();
+            edit.putInt(getStringRes(R.string.resultKey), result);
+            edit.putString(getStringRes(R.string.messageKey), message);
+            edit.commit();
+        } catch (Exception e) {
+            // ignore the exception
         }
     }
 }
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/Android.bp
new file mode 100644
index 0000000..37d35eb
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/Android.bp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 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 {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_test_helper_app {
+    name: "CVE-2022-20353",
+    defaults: [
+        "cts_support_defaults",
+    ],
+    srcs: [
+        "src/**/*.java",
+    ],
+    test_suites: [
+        "sts",
+    ],
+    static_libs: [
+        "androidx.test.core",
+        "androidx.test.rules",
+        "androidx.test.uiautomator_uiautomator",
+    ],
+    sdk_version: "current",
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/AndroidManifest.xml
new file mode 100644
index 0000000..d4129ac
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/AndroidManifest.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2022 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.security.cts.CVE_2022_20353">
+    <application
+        android:label="@string/appName"
+        android:supportsRtl="true">
+        <activity
+            android:name=".PocActivity"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="android.intent.action.RINGTONE_PICKER" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+    </application>
+    <instrumentation
+        android:name="androidx.test.runner.AndroidJUnitRunner"
+        android:targetPackage="android.security.cts.CVE_2022_20353" />
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/res/values/integers.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/res/values/integers.xml
new file mode 100644
index 0000000..3207c29
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/res/values/integers.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2022 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>
+    <integer name="assumptionFailure">-1</integer>
+    <integer name="success">0</integer>
+    <integer name="timeoutMs">20000</integer>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/res/values/strings.xml
new file mode 100644
index 0000000..27e87f6
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/res/values/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2022 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>
+    <string name="alwaysButtonId">android:id/button_always</string>
+    <string name="appName">CVE-2022-20353</string>
+    <string name="defaultSemaphoreMsg">Could not get message key in shared preferences</string>
+    <string name="failureMessage">
+    Device is vulnerable to b/221041256!! Privilege escalation possible in
+    com.android.settings.DefaultRingtonePreference
+    </string>
+    <string name="fileName">NOTICE.html</string>
+    <string name="getRingtoneCmd">settings get system ringtone</string>
+    <string name="messageKey">message</string>
+    <string name="noticeUri">
+    content://com.android.settings.files/my_cache/NOTICE.html
+    </string>
+    <string name="resType">string</string>
+    <string name="resultKey">result</string>
+    <string name="setRingtoneCmd">settings put system ringtone</string>
+    <string name="sharedPreferences">sharedPreferences</string>
+    <string name="textResId">ringtone_title</string>
+    <string name="uiObjectNotFoundMsg">Unable to find UiObject with %1$s text/id</string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/src/android/security/cts/CVE_2022_20353/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/src/android/security/cts/CVE_2022_20353/DeviceTest.java
new file mode 100644
index 0000000..af1f978
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/src/android/security/cts/CVE_2022_20353/DeviceTest.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts.CVE_2022_20353;
+
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeTrue;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.content.res.Resources;
+import android.provider.Settings;
+
+import androidx.test.runner.AndroidJUnit4;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.BySelector;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.UiScrollable;
+import androidx.test.uiautomator.UiSelector;
+import androidx.test.uiautomator.Until;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+    Resources mResources;
+    UiDevice mDevice;
+    Context mContext;
+
+    // Wait for UiObject to appear and click on the UiObject if it is visible
+    private boolean clickUiObject(BySelector selector) {
+        boolean objectFound =
+                mDevice.wait(Until.hasObject(selector), mResources.getInteger(R.integer.timeoutMs));
+        if (objectFound) {
+            mDevice.findObject(selector).click();
+        }
+        return objectFound;
+    }
+
+    @Test
+    public void testDefaultRingtonePreference() {
+        String defaultRingtone = null;
+        try {
+            mDevice = UiDevice.getInstance(getInstrumentation());
+            mContext = getInstrumentation().getContext();
+            mResources = mContext.getResources();
+            defaultRingtone =
+                    mDevice.executeShellCommand(mContext.getString(R.string.getRingtoneCmd));
+
+            Intent intent = new Intent(Settings.ACTION_SOUND_SETTINGS);
+            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            mContext.startActivity(intent);
+
+            String settingsPackageName =
+                    intent.resolveActivity(mContext.getPackageManager()).getPackageName();
+            Context settingsContext = mContext.createPackageContext(settingsPackageName,
+                    Context.CONTEXT_IGNORE_SECURITY);
+            Resources res = settingsContext.getPackageManager()
+                    .getResourcesForApplication(settingsPackageName);
+            String text = settingsContext
+                    .getString(res.getIdentifier(mContext.getString(R.string.textResId),
+                            mContext.getString(R.string.resType), settingsPackageName));
+            // scroll until text 'Phone ringtone' is visible
+            UiScrollable uiScrollable = new UiScrollable(new UiSelector().scrollable(true));
+            uiScrollable.scrollTextIntoView(text);
+            // click on 'Phone ringtone'
+            BySelector selector = By.text(text);
+            assumeTrue(mContext.getString(R.string.uiObjectNotFoundMsg, text),
+                    clickUiObject(selector));
+            // select CTS PoC app
+            text = mContext.getString(R.string.appName);
+            selector = By.text(text);
+            assumeTrue(mContext.getString(R.string.uiObjectNotFoundMsg, text),
+                    clickUiObject(selector));
+            // select 'Always'
+            String resId = mContext.getString(R.string.alwaysButtonId);
+            selector = By.res(resId);
+            assumeTrue(mContext.getString(R.string.uiObjectNotFoundMsg, resId),
+                    clickUiObject(selector));
+
+            SharedPreferences sharedPrefs = mContext.getSharedPreferences(
+                    mContext.getString(R.string.sharedPreferences), Context.MODE_APPEND);
+            Semaphore preferenceChanged = new Semaphore(0);
+            OnSharedPreferenceChangeListener sharedPrefListener =
+                    new OnSharedPreferenceChangeListener() {
+                        @Override
+                        public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
+                                String key) {
+                            if (key.equals(mContext.getString(R.string.resultKey))) {
+                                preferenceChanged.release();
+                            }
+                        }
+                    };
+            sharedPrefs.registerOnSharedPreferenceChangeListener(sharedPrefListener);
+            // wait for PocActivity to complete
+            assumeTrue(preferenceChanged.tryAcquire(mResources.getInteger(R.integer.timeoutMs),
+                    TimeUnit.MILLISECONDS));
+            int result = sharedPrefs.getInt(mContext.getString(R.string.resultKey),
+                    mResources.getInteger(R.integer.assumptionFailure));
+            String message = sharedPrefs.getString(mContext.getString(R.string.messageKey),
+                    mContext.getString(R.string.defaultSemaphoreMsg));
+            assumeTrue(message, result != mResources.getInteger(R.integer.assumptionFailure));
+
+            String ringtoneUri = "";
+            boolean isVulnerable = false;
+            long startTime = System.currentTimeMillis();
+            while ((System.currentTimeMillis() - startTime) < mResources
+                    .getInteger(R.integer.timeoutMs)) {
+                ringtoneUri =
+                        mDevice.executeShellCommand(mContext.getString(R.string.getRingtoneCmd));
+                if (ringtoneUri.contains(mContext.getString(R.string.fileName))) {
+                    isVulnerable = true;
+                    break;
+                }
+            }
+            assertFalse(mContext.getString(R.string.failureMessage), isVulnerable);
+        } catch (Exception e) {
+            assumeNoException(e);
+        } finally {
+            try {
+                // reset ringtone to default (other than 'null') present before test
+                mDevice.executeShellCommand(
+                        mContext.getString(R.string.setRingtoneCmd) + " " + defaultRingtone);
+                mDevice.pressHome();
+            } catch (Exception e) {
+                // ignore exception here
+            }
+        }
+    }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/src/android/security/cts/CVE_2022_20353/PocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/src/android/security/cts/CVE_2022_20353/PocActivity.java
new file mode 100644
index 0000000..977e647
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/src/android/security/cts/CVE_2022_20353/PocActivity.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts.CVE_2022_20353;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.media.RingtoneManager;
+import android.net.Uri;
+import android.os.Bundle;
+
+/* PocActivity is required in this test since it is required that CTS PoC app is selected when */
+/* choosing an app for setting default ringtone. RingtonePicker appears due to actions done in */
+/* DeviceTest.                                                                                 */
+public class PocActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        try {
+            super.onCreate(savedInstanceState);
+            Intent intent = new Intent();
+            /* set NOTICE.html file uri as EXTRA_RINGTONE_PICKED_URI which sets NOTICE.html as */
+            /* default ringtone if vulnerability is present                                    */
+            intent.putExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI,
+                    Uri.parse(getString(R.string.noticeUri)));
+            setResult(Activity.RESULT_OK, intent);
+            finish();
+            sendTestResult(getResources().getInteger(R.integer.success), "");
+        } catch (Exception e) {
+            sendTestResult(getResources().getInteger(R.integer.assumptionFailure), e.getMessage());
+        }
+    }
+
+    void sendTestResult(int result, String message) {
+        try {
+            SharedPreferences sh = getSharedPreferences(getString(R.string.sharedPreferences),
+                    Context.MODE_PRIVATE);
+            SharedPreferences.Editor edit = sh.edit();
+            edit.putInt(getString(R.string.resultKey), result);
+            edit.putString(getString(R.string.messageKey), message);
+            edit.commit();
+        } catch (Exception e) {
+            // ignore exception here
+        }
+    }
+
+}
diff --git a/hostsidetests/statsdatom/src/android/cts/statsdatom/lib/ConfigUtils.java b/hostsidetests/statsdatom/src/android/cts/statsdatom/lib/ConfigUtils.java
index be665ba..7f29d44 100644
--- a/hostsidetests/statsdatom/src/android/cts/statsdatom/lib/ConfigUtils.java
+++ b/hostsidetests/statsdatom/src/android/cts/statsdatom/lib/ConfigUtils.java
@@ -69,10 +69,6 @@
                 .addAllowedLogSource("AID_SYSTEM")
                 .addAllowedLogSource("AID_BLUETOOTH")
                 .addAllowedLogSource("com.android.bluetooth")
-                // TODO(b/236681553): Remove this.
-                .addAllowedLogSource("com.android.bluetooth.services")
-                // TODO(b/236681553): Remove this.
-                .addAllowedLogSource("com.google.android.bluetooth.services")
                 .addAllowedLogSource("AID_LMKD")
                 .addAllowedLogSource("AID_MEDIA")
                 .addAllowedLogSource("AID_RADIO")
diff --git a/tests/camera/Android.bp b/tests/camera/Android.bp
index aae58c6..c2334fc 100644
--- a/tests/camera/Android.bp
+++ b/tests/camera/Android.bp
@@ -65,6 +65,7 @@
         "truth-prebuilt",
         "androidx.heifwriter_heifwriter",
         "androidx.test.rules",
+        "MediaPerformanceClassCommon",
     ],
     jni_libs: [
         "libctscamera2_jni",
diff --git a/tests/camera/api31test/src/android/camera/cts/api31test/SPerfClassTest.java b/tests/camera/api31test/src/android/camera/cts/api31test/SPerfClassTest.java
index feb5567..772e7a5 100644
--- a/tests/camera/api31test/src/android/camera/cts/api31test/SPerfClassTest.java
+++ b/tests/camera/api31test/src/android/camera/cts/api31test/SPerfClassTest.java
@@ -36,6 +36,7 @@
 import android.hardware.camera2.TotalCaptureResult;
 import android.media.Image;
 import android.media.ImageReader;
+import android.os.Build;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.test.AndroidTestCase;
@@ -210,8 +211,9 @@
      * Version.MEDIA_PERFORMANCE_CLASS
      */
     public void testSPerfClassJpegSizes() throws Exception {
-        boolean isSPerfClass = CameraTestUtils.isSPerfClass();
-        if (!isSPerfClass) {
+        final boolean isAtLeastSPerfClass =
+                (Build.VERSION.MEDIA_PERFORMANCE_CLASS >= Build.VERSION_CODES.S);
+        if (!isAtLeastSPerfClass) {
             return;
         }
 
diff --git a/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java b/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
index 6af7758..d7dd63d 100644
--- a/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
@@ -55,6 +55,10 @@
 import android.hardware.camera2.params.RecommendedStreamConfigurationMap;
 import android.hardware.camera2.params.StreamConfigurationMap;
 import android.hardware.cts.helpers.CameraUtils;
+import android.mediapc.cts.common.Requirement;
+import android.mediapc.cts.common.RequiredMeasurement;
+import android.mediapc.cts.common.RequirementConstants;
+import android.mediapc.cts.common.PerformanceClassEvaluator;
 import android.media.CamcorderProfile;
 import android.media.ImageReader;
 import android.os.Build;
@@ -74,15 +78,11 @@
 
 import androidx.test.rule.ActivityTestRule;
 
-import androidx.test.InstrumentationRegistry;
-
 import com.android.compatibility.common.util.CddTest;
-import com.android.compatibility.common.util.DeviceReportLog;
-import com.android.compatibility.common.util.ResultType;
-import com.android.compatibility.common.util.ResultUnit;
 
 import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.TestName;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
 
@@ -92,12 +92,10 @@
 import java.util.List;
 import java.util.Objects;
 import java.util.Set;
+import java.util.function.BiPredicate;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import static android.hardware.camera2.cts.CameraTestUtils.MPC_REPORT_LOG_NAME;
-import static android.hardware.camera2.cts.CameraTestUtils.MPC_STREAM_NAME;
-
 /**
  * Extended tests for static camera characteristics.
  */
@@ -113,6 +111,9 @@
      */
     private static final int MIN_ALLOWABLE_WHITELEVEL = 32; // must have sensor bit depth > 5
 
+    @Rule
+    public final TestName mTestName = new TestName();
+
     private List<CameraCharacteristics> mCharacteristics;
 
     private static final Size FULLHD = new Size(1920, 1080);
@@ -131,10 +132,6 @@
     private static final long PREVIEW_RUN_MS = 500;
     private static final long FRAME_DURATION_30FPS_NSEC = (long) 1e9 / 30;
 
-    private static final long MIN_BACK_SENSOR_PERF_CLASS_RESOLUTION = 12000000;
-    private static final long MIN_FRONT_SENSOR_S_PERF_CLASS_RESOLUTION = 5000000;
-    private static final long MIN_FRONT_SENSOR_R_PERF_CLASS_RESOLUTION = 4000000;
-
     private static final long MIN_UHR_SENSOR_RESOLUTION = 24000000;
     /*
      * HW Levels short hand
@@ -2857,28 +2854,70 @@
     }
 
     /**
-     * Update performance class level based on condition
-     *
-     * @param condition whether the condition is met for passLevel
-     * @param passLevel the highest performance class level when condition is true
-     * @param failLevel the performance class when condition is false
+     * Camera hardware level requirement for Media Performance Class
      */
-    private int updatePerfClassLevel(boolean condition, int passLevel, int failLevel) {
-        return condition ? passLevel : failLevel;
-    }
+    public static class PrimaryCameraHwLevelReq extends Requirement {
+        private static final String TAG = PrimaryCameraHwLevelReq.class.getSimpleName();
 
-    /**
-     * Update perf class level based on meetSPerfClass and meetRPerfClass.
-     */
-    private int updatePerfClassLevelRS(boolean meetSPerfClass, boolean meetRPerfClass,
-            int perfClassLevel) {
-        if (!meetRPerfClass) {
-            return CameraTestUtils.PERFORMANCE_CLASS_NOT_MET;
-        } else if (!meetSPerfClass &&
-                perfClassLevel > CameraTestUtils.PERFORMANCE_CLASS_R) {
-            return Math.min(CameraTestUtils.PERFORMANCE_CLASS_R, perfClassLevel);
+        /**
+         * Creates a >= predicate for camera hardware level
+         */
+        private static BiPredicate<Integer, Integer> camHwLevelGte() {
+            return new BiPredicate<Integer, Integer>() {
+                @Override
+                public boolean test(Integer actual, Integer expected) {
+                    return StaticMetadata.hardwareLevelPredicate(actual, expected);
+                }
+
+                @Override
+                public String toString() {
+                    return "Camera Hardware Level Greater than or equal to";
+                }
+            };
         }
-        return perfClassLevel;
+        private static final BiPredicate<Integer, Integer> CAM_HW_LEVEL_GTE = camHwLevelGte();
+        private PrimaryCameraHwLevelReq(String id, RequiredMeasurement<?> ... reqs) {
+            super(id, reqs);
+        }
+
+        public void setPrimaryRearCameraHwlLevel(Integer hwLevel) {
+            this.setMeasuredValue(RequirementConstants.REAR_CAMERA_HWL_LEVEL, hwLevel);
+        }
+
+        public void setPrimaryFrontCameraHwlLevel(Integer hwLevel) {
+            this.setMeasuredValue(RequirementConstants.FRONT_CAMERA_HWL_LEVEL, hwLevel);
+        }
+
+        /**
+         * [2.2.7.2/7.5/H-1-3] MUST support android.info.supportedHardwareLevel property as FULL or
+         * better for back primary and LIMITED or better for front primary camera.
+         */
+        public static PrimaryCameraHwLevelReq createPrimaryCameraHwLevelReq() {
+            RequiredMeasurement<Integer> rearCameraHwlLevel = RequiredMeasurement
+                .<Integer>builder()
+                .setId(RequirementConstants.REAR_CAMERA_HWL_LEVEL)
+                .setPredicate(CAM_HW_LEVEL_GTE)
+                .addRequiredValue(Build.VERSION_CODES.R,
+                        CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL)
+                .addRequiredValue(Build.VERSION_CODES.S,
+                        CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL)
+                .addRequiredValue(Build.VERSION_CODES.TIRAMISU,
+                        CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL)
+                .build();
+            RequiredMeasurement<Integer> frontCameraHwlLevel = RequiredMeasurement
+                .<Integer>builder()
+                .setId(RequirementConstants.FRONT_CAMERA_HWL_LEVEL)
+                .setPredicate(CAM_HW_LEVEL_GTE)
+                .addRequiredValue(Build.VERSION_CODES.R,
+                        CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED)
+                .addRequiredValue(Build.VERSION_CODES.S,
+                        CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL)
+                .addRequiredValue(Build.VERSION_CODES.TIRAMISU,
+                        CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL)
+                .build();
+            return new PrimaryCameraHwLevelReq(RequirementConstants.R7_5__H_1_3,
+                    rearCameraHwlLevel, frontCameraHwlLevel);
+        }
     }
 
     /**
@@ -2893,30 +2932,31 @@
             // ids.
             return;
         }
-        boolean assertRPerfClass = CameraTestUtils.isRPerfClass();
-        boolean assertSPerfClass = CameraTestUtils.isSPerfClass();
-        boolean assertTPerfClass = CameraTestUtils.isTPerfClass();
-        boolean assertPerfClass = (assertRPerfClass || assertSPerfClass || assertTPerfClass);
+        PerformanceClassEvaluator pce = new PerformanceClassEvaluator(this.mTestName);
+        PerformanceClassEvaluator.PrimaryCameraRequirement primaryRearReq =
+                pce.addPrimaryRearCameraReq();
+        PerformanceClassEvaluator.PrimaryCameraRequirement primaryFrontReq =
+                pce.addPrimaryFrontCameraReq();
+        PrimaryCameraHwLevelReq hwLevelReq = pce.addRequirement(
+                PrimaryCameraHwLevelReq.createPrimaryCameraHwLevelReq());
+        PerformanceClassEvaluator.CameraTimestampSourceRequirement timestampSourceReq =
+                pce.addR7_5__H_1_4();
+        PerformanceClassEvaluator.CameraRawRequirement rearRawReq =
+                pce.addR7_5__H_1_8();
+        PerformanceClassEvaluator.Camera240FpsRequirement hfrReq =
+                pce.addR7_5__H_1_9();
+        PerformanceClassEvaluator.UltraWideZoomRatioRequirement ultrawideZoomRatioReq =
+                pce.addR7_5__H_1_10();
+        PerformanceClassEvaluator.ConcurrentRearFrontRequirement concurrentRearFrontReq =
+                pce.addR7_5__H_1_11();
+        PerformanceClassEvaluator.PreviewStabilizationRequirement previewStabilizationReq =
+                pce.addR7_5__H_1_12();
+        PerformanceClassEvaluator.LogicalMultiCameraRequirement logicalMultiCameraReq =
+                pce.addR7_5__H_1_13();
+        PerformanceClassEvaluator.StreamUseCaseRequirement streamUseCaseReq =
+                pce.addR7_5__H_1_14();
 
-        // R & S Performance Class
-        int perfClassLevelH11 = CameraTestUtils.PERFORMANCE_CLASS_CURRENT;
-        int perfClassLevelH12 = CameraTestUtils.PERFORMANCE_CLASS_CURRENT;
-        int perfClassLevelH13 = CameraTestUtils.PERFORMANCE_CLASS_CURRENT;
-        int perfClassLevelH14 = CameraTestUtils.PERFORMANCE_CLASS_CURRENT;
-        int perfClassLevelH18 = CameraTestUtils.PERFORMANCE_CLASS_CURRENT;
-
-        // T Performance Class
-        int perfClassLevelH19 = CameraTestUtils.PERFORMANCE_CLASS_CURRENT;
-        int perfClassLevelH110 = CameraTestUtils.PERFORMANCE_CLASS_CURRENT;
-        int perfClassLevelH111 = CameraTestUtils.PERFORMANCE_CLASS_CURRENT;
-        int perfClassLevelH112 = CameraTestUtils.PERFORMANCE_CLASS_CURRENT;
-        int perfClassLevelH113 = CameraTestUtils.PERFORMANCE_CLASS_CURRENT;
-        int perfClassLevelH114 = CameraTestUtils.PERFORMANCE_CLASS_CURRENT;
-
-        DeviceReportLog reportLog = new DeviceReportLog(MPC_REPORT_LOG_NAME, MPC_STREAM_NAME);
-
-        String primaryRearId = null;
-        String primaryFrontId = null;
+        HashSet<String> primaryCameras = new HashSet<String>();
         for (int i = 0; i < mCameraIdsUnderTest.length; i++) {
             String cameraId = mCameraIdsUnderTest[i];
             boolean isPrimaryRear = CameraTestUtils.isPrimaryRearFacingCamera(
@@ -2940,42 +2980,27 @@
             List<Size> videoSizes = CameraTestUtils.getSupportedVideoSizes(cameraId,
                     mCameraManager, null /*bound*/);
 
+            Integer timestampSource = c.get(CameraCharacteristics.SENSOR_INFO_TIMESTAMP_SOURCE);
             if (isPrimaryRear) {
-                primaryRearId = cameraId;
-                if (sensorResolution < MIN_BACK_SENSOR_PERF_CLASS_RESOLUTION) {
-                    mCollector.expectTrue("Primary rear camera resolution should be at least " +
-                            MIN_BACK_SENSOR_PERF_CLASS_RESOLUTION + " pixels, is "+
-                            sensorResolution, !assertPerfClass);
-                    perfClassLevelH11 = CameraTestUtils.PERFORMANCE_CLASS_NOT_MET;
-                }
-                reportLog.addValue("rear camera resolution", sensorResolution,
-                        ResultType.NEUTRAL, ResultUnit.NONE);
+                primaryCameras.add(cameraId);
+                primaryRearReq.setPrimaryCameraSupported(true);
+                primaryRearReq.setResolution(sensorResolution);
+                hwLevelReq.setPrimaryRearCameraHwlLevel(staticInfo.getHardwareLevelChecked());
+                timestampSourceReq.setRearCameraTimestampSource(timestampSource);
 
                 // 4K @ 30fps
                 boolean supportUHD = videoSizes.contains(UHD);
                 boolean supportDC4K = videoSizes.contains(DC4K);
-                reportLog.addValue("rear camera 4k support", supportUHD | supportDC4K,
-                        ResultType.NEUTRAL, ResultUnit.NONE);
-                if (!supportUHD && !supportDC4K) {
-                    mCollector.expectTrue("Primary rear camera should support 4k video recording",
-                            !assertPerfClass);
-                    perfClassLevelH11 = CameraTestUtils.PERFORMANCE_CLASS_NOT_MET;
-                } else {
+                boolean support4K = (supportUHD || supportDC4K);
+                primaryRearReq.setVideoSizeReqSatisfied(support4K);
+                if (support4K) {
                     long minFrameDuration = config.getOutputMinFrameDuration(
                             android.media.MediaRecorder.class, supportDC4K ? DC4K : UHD);
-                    reportLog.addValue("rear camera 4k frame duration", minFrameDuration,
-                        ResultType.NEUTRAL, ResultUnit.NONE);
-                    if (minFrameDuration >= (1e9 / 29.9)) {
-                        mCollector.expectTrue("Primary rear camera should support 4k video @ 30fps",
-                                !assertPerfClass);
-                        perfClassLevelH11 = CameraTestUtils.PERFORMANCE_CLASS_NOT_MET;
-                    }
+                    primaryRearReq.setVideoFps(1e9 / minFrameDuration);
                 }
 
                 // H-1-9
                 boolean supportHighSpeed = staticInfo.isCapabilitySupported(CONSTRAINED_HIGH_SPEED);
-                mCollector.expectTrue("Primary rear camera should support high speed recording",
-                        !assertTPerfClass || supportHighSpeed);
                 boolean support240Fps = false;
                 if (supportHighSpeed) {
                     Size[] availableHighSpeedSizes = config.getHighSpeedVideoSizes();
@@ -2995,101 +3020,29 @@
                             break;
                         }
                     }
-                    mCollector.expectTrue("Primary rear camera should support HD or FULLHD @ 240",
-                            !assertTPerfClass || support240Fps);
                 }
-                perfClassLevelH19 = updatePerfClassLevel(support240Fps,
-                        perfClassLevelH19, CameraTestUtils.PERFORMANCE_CLASS_S);
-                reportLog.addValue("rear camera 720p/1080p @ 240fps support", support240Fps,
-                        ResultType.NEUTRAL, ResultUnit.NONE);
+                hfrReq.setRear240FpsSupported(support240Fps);
             } else {
-                primaryFrontId = cameraId;
-                if (sensorResolution < MIN_FRONT_SENSOR_S_PERF_CLASS_RESOLUTION) {
-                    mCollector.expectTrue("Primary front camera resolution should be at least "
-                            + MIN_FRONT_SENSOR_S_PERF_CLASS_RESOLUTION + " pixels, is "
-                            + sensorResolution, !(assertSPerfClass || assertTPerfClass));
-                    perfClassLevelH12 = Math.min(
-                            perfClassLevelH12, CameraTestUtils.PERFORMANCE_CLASS_R);
-                }
-                if (sensorResolution < MIN_FRONT_SENSOR_R_PERF_CLASS_RESOLUTION) {
-                    mCollector.expectTrue("Primary front camera resolution should be at least " +
-                            MIN_FRONT_SENSOR_S_PERF_CLASS_RESOLUTION + " pixels, is "+
-                            sensorResolution, !assertRPerfClass);
-                    perfClassLevelH12 = CameraTestUtils.PERFORMANCE_CLASS_NOT_MET;
-                }
-                reportLog.addValue("front camera resolution", sensorResolution,
-                        ResultType.NEUTRAL, ResultUnit.NONE);
+                primaryCameras.add(cameraId);
+                primaryFrontReq.setPrimaryCameraSupported(true);
+                primaryFrontReq.setResolution(sensorResolution);
+                hwLevelReq.setPrimaryFrontCameraHwlLevel(staticInfo.getHardwareLevelChecked());
+                timestampSourceReq.setFrontCameraTimestampSource(timestampSource);
 
                 // 1080P @ 30fps
                 boolean supportFULLHD = videoSizes.contains(FULLHD);
-                reportLog.addValue("front camera 1080p support", supportFULLHD,
-                        ResultType.NEUTRAL, ResultUnit.NONE);
-                if (!supportFULLHD) {
-                    mCollector.expectTrue(
-                            "Primary front camera should support 1080P video recording",
-                            !assertPerfClass);
-                    perfClassLevelH12 = CameraTestUtils.PERFORMANCE_CLASS_NOT_MET;
-                } else {
+                primaryFrontReq.setVideoSizeReqSatisfied(supportFULLHD);
+                if (supportFULLHD) {
                     long minFrameDuration = config.getOutputMinFrameDuration(
                             android.media.MediaRecorder.class, FULLHD);
-                    if (minFrameDuration >= (1e9 / 29.9)) {
-                        mCollector.expectTrue(
-                                "Primary front camera should support 1080P video @ 30fps",
-                                !assertPerfClass);
-                        perfClassLevelH12 = CameraTestUtils.PERFORMANCE_CLASS_NOT_MET;
-                    }
-                    reportLog.addValue("front camera 1080p frame duration", minFrameDuration,
-                        ResultType.NEUTRAL, ResultUnit.NONE);
+                    primaryFrontReq.setVideoFps(1e9 / minFrameDuration);
                 }
             }
 
-            String facingString = isPrimaryRear ? "rear" : "front";
-            // H-1-3
-            if (assertTPerfClass || assertSPerfClass || (assertRPerfClass && isPrimaryRear)) {
-                mCollector.expectTrue("Primary " + facingString +
-                        " camera should be at least FULL, but is " +
-                        toStringHardwareLevel(staticInfo.getHardwareLevelChecked()),
-                        staticInfo.isHardwareLevelAtLeastFull());
-            } else if (assertRPerfClass) {
-                mCollector.expectTrue("Primary " + facingString +
-                        " camera should be at least LIMITED, but is " +
-                        toStringHardwareLevel(staticInfo.getHardwareLevelChecked()),
-                        staticInfo.isHardwareLevelAtLeastLimited());
-            }
-
-            reportLog.addValue(facingString + " camera hardware level",
-                    staticInfo.getHardwareLevelChecked(), ResultType.NEUTRAL, ResultUnit.NONE);
-            if (isPrimaryRear) {
-                perfClassLevelH13 = updatePerfClassLevel(staticInfo.isHardwareLevelAtLeastFull(),
-                        perfClassLevelH13, CameraTestUtils.PERFORMANCE_CLASS_NOT_MET);
-            } else {
-                perfClassLevelH13 = updatePerfClassLevelRS(staticInfo.isHardwareLevelAtLeastFull(),
-                        staticInfo.isHardwareLevelAtLeastLimited(), perfClassLevelH13);
-            }
-
-            // H-1-4
-            Integer timestampSource = c.get(CameraCharacteristics.SENSOR_INFO_TIMESTAMP_SOURCE);
-            reportLog.addValue(facingString + " timestampSource",
-                    timestampSource, ResultType.NEUTRAL, ResultUnit.NONE);
-            boolean realtimeTimestamp = (timestampSource != null &&
-                    timestampSource.equals(CameraMetadata.SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME));
-            mCollector.expectTrue(
-                    "Primary " + facingString + " camera should support real-time timestamp source",
-                    !assertPerfClass || realtimeTimestamp);
-            perfClassLevelH14 = updatePerfClassLevel(realtimeTimestamp, perfClassLevelH14,
-                    CameraTestUtils.PERFORMANCE_CLASS_NOT_MET);
-
             // H-1-8
             if (isPrimaryRear) {
                 boolean supportRaw = staticInfo.isCapabilitySupported(RAW);
-                reportLog.addValue(facingString + " camera raw support",
-                        supportRaw, ResultType.NEUTRAL, ResultUnit.NONE);
-                if (assertSPerfClass || assertTPerfClass) {
-                    mCollector.expectTrue("Primary rear camera should support RAW capability",
-                            supportRaw);
-                }
-                perfClassLevelH18 = updatePerfClassLevel(supportRaw, perfClassLevelH18,
-                        CameraTestUtils.PERFORMANCE_CLASS_R);
+                rearRawReq.setRearRawSupported(supportRaw);
             }
 
             // H-1-10
@@ -3098,96 +3051,45 @@
             Range<Float> zoomRatioRange = staticInfo.getZoomRatioRangeChecked();
             boolean meetH110 = (primaryToMaxFovRatio >= 1.0f - FOV_THRESHOLD)
                     || (zoomRatioRange.getLower() < 1.0f - FOV_THRESHOLD);
-            mCollector.expectTrue("Primary " + facingString + " camera must support zoomRatio < "
-                    + "1.0f if there is an ultrawide lens with the same facing",
-                    !assertTPerfClass || meetH110);
-            perfClassLevelH110 = updatePerfClassLevel(meetH110, perfClassLevelH110,
-                    CameraTestUtils.PERFORMANCE_CLASS_S);
-            reportLog.addValue(facingString + " camera supports maximum FOV using zoom ratio",
-                    meetH110, ResultType.NEUTRAL, ResultUnit.NONE);
+            if (isPrimaryRear) {
+                ultrawideZoomRatioReq.setRearUltraWideZoomRatioReqMet(meetH110);
+            } else {
+                ultrawideZoomRatioReq.setFrontUltraWideZoomRatioReqMet(meetH110);
+            }
 
             // H-1-12
-            boolean meetH112 = staticInfo.isPreviewStabilizationSupported();
-            mCollector.expectTrue("Primary " + facingString + " camera must support preview "
-                    + "stabilization", !assertTPerfClass || meetH112);
-            perfClassLevelH112 = updatePerfClassLevel(meetH112, perfClassLevelH112,
-                    CameraTestUtils.PERFORMANCE_CLASS_S);
-            reportLog.addValue(facingString + " camera preview stabilization", meetH112,
-                    ResultType.NEUTRAL, ResultUnit.NONE);
+            boolean previewStab = staticInfo.isPreviewStabilizationSupported();
+            if (isPrimaryRear) {
+                previewStabilizationReq.setRearPreviewStabilizationSupported(previewStab);
+            } else {
+                previewStabilizationReq.setFrontPreviewStabilizationSupported(previewStab);
+            }
 
             // H-1-13
             int facing = staticInfo.getLensFacingChecked();
             int numOfPhysicalRgbCameras = getNumberOfRgbPhysicalCameras(facing);
-            boolean meetH113 = (numOfPhysicalRgbCameras <= 1) || staticInfo.isLogicalMultiCamera();
-            mCollector.expectTrue("Primary " + facingString + " camera must be LOGICAL_MULTI_CAMERA"
-                    + " in case of multiple RGB cameras with same facing",
-                    !assertTPerfClass || meetH113);
-            perfClassLevelH113 = updatePerfClassLevel(meetH113, perfClassLevelH113,
-                    CameraTestUtils.PERFORMANCE_CLASS_S);
-            reportLog.addValue(facingString + " camera is LOGICAL_MULTI_CAMERA in case of multiple "
-                    + "RGB cameras with same facing", meetH113, ResultType.NEUTRAL,
-                    ResultUnit.NONE);
+            boolean logicalMultiCameraReqMet =
+                    (numOfPhysicalRgbCameras <= 1) || staticInfo.isLogicalMultiCamera();
+            if (isPrimaryRear) {
+                logicalMultiCameraReq.setRearLogicalMultiCameraReqMet(logicalMultiCameraReqMet);
+            } else {
+                logicalMultiCameraReq.setFrontLogicalMultiCameraReqMet(logicalMultiCameraReqMet);
+            }
 
             // H-1-14
-            boolean meetH114 = staticInfo.isStreamUseCaseSupported();
-            mCollector.expectTrue("Primary " + facingString + " camera must support stream "
-                    + "use case", !assertTPerfClass || meetH114);
-            perfClassLevelH114 = updatePerfClassLevel(meetH114, perfClassLevelH114,
-                    CameraTestUtils.PERFORMANCE_CLASS_S);
-            reportLog.addValue(facingString + " camera stream use case", meetH114,
-                    ResultType.NEUTRAL, ResultUnit.NONE);
+            boolean streamUseCaseSupported = staticInfo.isStreamUseCaseSupported();
+            if (isPrimaryRear) {
+                streamUseCaseReq.setRearStreamUseCaseSupported(streamUseCaseSupported);
+            } else {
+                streamUseCaseReq.setFrontStreamUseCaseSupported(streamUseCaseSupported);
+            }
         }
-        HashSet<String> primaryCameras = new HashSet<String>();
-        if (primaryRearId == null) {
-            mCollector.expectTrue("There must be a primary rear camera for performance class.",
-                    !assertPerfClass);
-            perfClassLevelH11 = CameraTestUtils.PERFORMANCE_CLASS_NOT_MET;
-        } else {
-            primaryCameras.add(primaryRearId);
-        }
-        if (primaryFrontId == null) {
-            mCollector.expectTrue("There must be a primary front camera for performance class.",
-                    !assertPerfClass);
-            perfClassLevelH12 = CameraTestUtils.PERFORMANCE_CLASS_NOT_MET;
-        } else {
-            primaryCameras.add(primaryFrontId);
-        }
-
         // H-1-11
         Set<Set<String>> concurrentCameraIds = mCameraManager.getConcurrentCameraIds();
         boolean supportPrimaryFrontBack = concurrentCameraIds.contains(primaryCameras);
-        mCollector.expectTrue("Concurrent primary front and primary back streaming must be "
-                + "supported", !assertTPerfClass || supportPrimaryFrontBack);
-        perfClassLevelH111 = updatePerfClassLevel(supportPrimaryFrontBack,
-                perfClassLevelH111, CameraTestUtils.PERFORMANCE_CLASS_S);
-        reportLog.addValue("concurrent front back support", supportPrimaryFrontBack,
-                 ResultType.NEUTRAL, ResultUnit.NONE);
+        concurrentRearFrontReq.setConcurrentRearFrontSupported(supportPrimaryFrontBack);
 
-        reportLog.addValue("Version", "0.0.1", ResultType.NEUTRAL, ResultUnit.NONE);
-        final String PERF_CLASS_REQ_NUM_PREFIX = "2.2.7.2/7.5/";
-        reportLog.addValue(PERF_CLASS_REQ_NUM_PREFIX + "H-1-1",
-                perfClassLevelH11, ResultType.NEUTRAL, ResultUnit.NONE);
-        reportLog.addValue(PERF_CLASS_REQ_NUM_PREFIX + "H-1-2",
-                perfClassLevelH12, ResultType.NEUTRAL, ResultUnit.NONE);
-        reportLog.addValue(PERF_CLASS_REQ_NUM_PREFIX + "H-1-3",
-                perfClassLevelH13, ResultType.NEUTRAL, ResultUnit.NONE);
-        reportLog.addValue(PERF_CLASS_REQ_NUM_PREFIX + "H-1-4",
-                perfClassLevelH14, ResultType.NEUTRAL, ResultUnit.NONE);
-        reportLog.addValue(PERF_CLASS_REQ_NUM_PREFIX + "H-1-8",
-                perfClassLevelH18, ResultType.NEUTRAL, ResultUnit.NONE);
-        reportLog.addValue(PERF_CLASS_REQ_NUM_PREFIX + "H-1-9",
-                perfClassLevelH19, ResultType.NEUTRAL, ResultUnit.NONE);
-        reportLog.addValue(PERF_CLASS_REQ_NUM_PREFIX + "H-1-10",
-                perfClassLevelH110, ResultType.NEUTRAL, ResultUnit.NONE);
-        reportLog.addValue(PERF_CLASS_REQ_NUM_PREFIX + "H-1-11",
-                perfClassLevelH111, ResultType.NEUTRAL, ResultUnit.NONE);
-        reportLog.addValue(PERF_CLASS_REQ_NUM_PREFIX + "H-1-12",
-                perfClassLevelH112, ResultType.NEUTRAL, ResultUnit.NONE);
-        reportLog.addValue(PERF_CLASS_REQ_NUM_PREFIX + "H-1-13",
-                perfClassLevelH113, ResultType.NEUTRAL, ResultUnit.NONE);
-        reportLog.addValue(PERF_CLASS_REQ_NUM_PREFIX + "H-1-14",
-                perfClassLevelH114, ResultType.NEUTRAL, ResultUnit.NONE);
-        reportLog.submit(InstrumentationRegistry.getInstrumentation());
+        pce.submitAndCheck();
     }
 
     /**
diff --git a/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java b/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java
index 3c88a3a..c9c28ea 100644
--- a/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java
@@ -1234,8 +1234,13 @@
 
                         mOutMediaFileName = mDebugFileNameBase + "/test_cslowMo_video_" +
                             captureRate + "fps_" + id + "_" + size.toString() + ".mp4";
-                        Log.v(TAG, "previewFrameRate:" + previewFrameRate);
-                        prepareRecording(size, previewFrameRate, captureRate);
+
+                        // b/239101664 It appears that video frame rates higher than 30 fps may not
+                        // trigger slow motion recording consistently.
+                        int videoFrameRate = previewFrameRate > VIDEO_FRAME_RATE ?
+                                VIDEO_FRAME_RATE : previewFrameRate;
+                        Log.v(TAG, "videoFrameRate:" + videoFrameRate);
+                        prepareRecording(size, videoFrameRate, captureRate);
 
                         SystemClock.sleep(PREVIEW_DURATION_MS);
 
@@ -1243,7 +1248,7 @@
 
                         SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
                         // Start recording
-                        startSlowMotionRecording(/*useMediaRecorder*/true, previewFrameRate,
+                        startSlowMotionRecording(/*useMediaRecorder*/true, videoFrameRate,
                                 captureRate, fpsRange, resultListener,
                                 /*useHighSpeedSession*/true);
 
@@ -1256,7 +1261,7 @@
                         startConstrainedPreview(fpsRange, previewResultListener);
 
                         // Convert number of frames camera produced into the duration in unit of ms.
-                        float frameDurationMs = 1000.0f / previewFrameRate;
+                        float frameDurationMs = 1000.0f / videoFrameRate;
                         float durationMs = resultListener.getTotalNumFrames() * frameDurationMs;
 
                         // Validation.
diff --git a/tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java b/tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java
index e8d6168..4a86b49 100644
--- a/tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java
+++ b/tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java
@@ -142,8 +142,6 @@
 
     public static final String OFFLINE_CAMERA_ID = "offline_camera_id";
     public static final String REPORT_LOG_NAME = "CtsCameraTestCases";
-    public static final String MPC_REPORT_LOG_NAME = "MediaPerformanceClassLogs";
-    public static final String MPC_STREAM_NAME = "CameraCts";
 
     private static final int EXIF_DATETIME_LENGTH = 19;
     private static final int EXIF_DATETIME_ERROR_MARGIN_SEC = 60;
@@ -3815,33 +3813,6 @@
         return zoomRatios;
     }
 
-    public static final int PERFORMANCE_CLASS_NOT_MET = 0;
-    public static final int PERFORMANCE_CLASS_R = Build.VERSION_CODES.R;
-    public static final int PERFORMANCE_CLASS_S = Build.VERSION_CODES.R + 1;
-    public static final int PERFORMANCE_CLASS_T = Build.VERSION_CODES.S + 2;
-    public static final int PERFORMANCE_CLASS_CURRENT = PERFORMANCE_CLASS_T;
-
-    /**
-     * Check whether this mobile device is R performance class as defined in CDD
-     */
-    public static boolean isRPerfClass() {
-        return Build.VERSION.MEDIA_PERFORMANCE_CLASS == PERFORMANCE_CLASS_R;
-    }
-
-    /**
-     * Check whether this mobile device is S performance class as defined in CDD
-     */
-    public static boolean isSPerfClass() {
-        return Build.VERSION.MEDIA_PERFORMANCE_CLASS == PERFORMANCE_CLASS_S;
-    }
-
-    /**
-     * Check whether this mobile device is T performance class as defined in CDD
-     */
-    public static boolean isTPerfClass() {
-        return Build.VERSION.MEDIA_PERFORMANCE_CLASS == PERFORMANCE_CLASS_T;
-    }
-
     /**
      * Check whether a camera Id is a primary rear facing camera
      */
diff --git a/tests/camera/utils/src/android/hardware/camera2/cts/helpers/StaticMetadata.java b/tests/camera/utils/src/android/hardware/camera2/cts/helpers/StaticMetadata.java
index fc8c4db..f188685 100644
--- a/tests/camera/utils/src/android/hardware/camera2/cts/helpers/StaticMetadata.java
+++ b/tests/camera/utils/src/android/hardware/camera2/cts/helpers/StaticMetadata.java
@@ -229,6 +229,13 @@
      * at least the desired one (but could be higher)
      */
     public boolean isHardwareLevelAtLeast(int level) {
+        int deviceLevel = getHardwareLevelChecked();
+
+        return hardwareLevelPredicate(deviceLevel, level);
+    }
+
+    // Return true if level1 is at least level2
+    public static boolean hardwareLevelPredicate(int level1, int level2) {
         final int[] sortedHwLevels = {
             CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY,
             CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL,
@@ -236,19 +243,19 @@
             CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL,
             CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_3
         };
-        int deviceLevel = getHardwareLevelChecked();
-        if (level == deviceLevel) {
+
+        if (level1 == level2) {
             return true;
         }
 
         for (int sortedlevel : sortedHwLevels) {
-            if (sortedlevel == level) {
+            if (sortedlevel == level2) {
                 return true;
-            } else if (sortedlevel == deviceLevel) {
+            } else if (sortedlevel == level1) {
                 return false;
             }
         }
-        Assert.fail("Unknown hardwareLevel " + level + " and device hardware level " + deviceLevel);
+        Assert.fail("Unknown hardwareLevel " + level1 + " and device hardware level " + level2);
         return false;
     }
 
diff --git a/tests/devicepolicy/src/android/devicepolicy/cts/DevicePolicyManagementRoleHolderTest.java b/tests/devicepolicy/src/android/devicepolicy/cts/DevicePolicyManagementRoleHolderTest.java
index 286ccae..eee4b10 100644
--- a/tests/devicepolicy/src/android/devicepolicy/cts/DevicePolicyManagementRoleHolderTest.java
+++ b/tests/devicepolicy/src/android/devicepolicy/cts/DevicePolicyManagementRoleHolderTest.java
@@ -65,6 +65,7 @@
 import com.android.bedstead.remotedpc.RemoteDpc;
 import com.android.bedstead.testapp.TestApp;
 import com.android.bedstead.testapp.TestAppInstance;
+import com.android.compatibility.common.util.CddTest;
 import com.android.eventlib.truth.EventLogsSubject;
 import com.android.queryable.queries.ActivityQuery;
 
@@ -140,6 +141,7 @@
     @EnsureHasNoDpc
     @EnsureHasNoSecondaryUser
     @Test
+    @CddTest(requirements = {"3.9.4/C-3-1"})
     public void createAndProvisionManagedProfile_roleHolderIsInWorkProfile()
             throws ProvisioningException, InterruptedException {
         UserHandle profile = null;
@@ -173,6 +175,7 @@
     @RequireRunOnPrimaryUser
     @EnsureHasNoSecondaryUser
     @Test
+    @CddTest(requirements = {"3.9.4/C-3-1"})
     public void createAndManageUser_roleHolderIsInManagedUser() throws InterruptedException {
         UserHandle managedUser = null;
         String roleHolderPackageName = null;
diff --git a/tests/devicepolicy/src/android/devicepolicy/cts/UserControlDisabledPackagesTest.java b/tests/devicepolicy/src/android/devicepolicy/cts/UserControlDisabledPackagesTest.java
index fcf71d0..dfe77fb 100644
--- a/tests/devicepolicy/src/android/devicepolicy/cts/UserControlDisabledPackagesTest.java
+++ b/tests/devicepolicy/src/android/devicepolicy/cts/UserControlDisabledPackagesTest.java
@@ -45,6 +45,7 @@
 import com.android.bedstead.metricsrecorder.EnterpriseMetricsRecorder;
 import com.android.bedstead.nene.TestApis;
 import com.android.bedstead.nene.packages.Package;
+import com.android.bedstead.nene.utils.Poll;
 import com.android.bedstead.testapp.TestApp;
 import com.android.bedstead.testapp.TestAppInstance;
 import com.android.queryable.queries.StringQuery;
@@ -235,6 +236,11 @@
 
     private void assertPackageStopped(String packageName)
             throws Exception {
+        Poll.forValue("Package " + packageName + " stopped", () -> isPackageStopped(packageName))
+                .toBeEqualTo(true)
+                .errorOnFail()
+                .await();
+
         assertWithMessage("Package %s not stopped", packageName)
                 .that(isPackageStopped(packageName)).isTrue();
     }
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/TaskFragmentTrustedModeTest.java b/tests/framework/base/windowmanager/src/android/server/wm/TaskFragmentTrustedModeTest.java
index c13c4ee..9fd1a41 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/TaskFragmentTrustedModeTest.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/TaskFragmentTrustedModeTest.java
@@ -21,6 +21,7 @@
 import static android.server.wm.jetpack.utils.ActivityEmbeddingUtil.assumeActivityEmbeddingSupportedDevice;
 
 import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -33,6 +34,7 @@
 import android.graphics.Rect;
 import android.os.Binder;
 import android.os.IBinder;
+import android.platform.test.annotations.Presubmit;
 import android.server.wm.WindowManagerState.Task;
 import android.window.TaskFragmentCreationParams;
 import android.window.TaskFragmentInfo;
@@ -49,6 +51,7 @@
  * Build/Install/Run:
  *     atest CtsWindowManagerDeviceTestCases:TaskFragmentTrustedModeTest
  */
+@Presubmit
 public class TaskFragmentTrustedModeTest extends TaskFragmentOrganizerTestBase {
 
     private final ComponentName mTranslucentActivity = new ComponentName(mContext,
@@ -248,7 +251,7 @@
      */
     @Test
     public void testUntrustedModeTaskFragment_startActivityInTaskFragmentOutsideOfParentBounds() {
-        final Task parentTask = mWmState.getRootTask(mOwnerTaskId);
+        Task parentTask = mWmState.getRootTask(mOwnerTaskId);
         final Rect parentBounds = new Rect(parentTask.getBounds());
         final IBinder errorCallbackToken = new Binder();
         final WindowContainerTransaction wct = new WindowContainerTransaction()
@@ -263,8 +266,11 @@
         // It is disallowed to start activity to TaskFragment with bounds outside of its parent
         // in untrusted mode.
         assertTaskFragmentError(errorCallbackToken, SecurityException.class);
-        mWmState.waitForAppTransitionIdleOnDisplay(mOwnerActivity.getDisplayId());
-        mWmState.assertNotExist(SECOND_UNTRUSTED_EMBEDDING_ACTIVITY);
+
+        parentTask = mWmState.getRootTask(mOwnerTaskId);
+        assertWithMessage("Activity must be started in parent Task because it's not"
+                + " allowed to be embedded").that(parentTask.mActivities).contains(
+                mWmState.getActivity(SECOND_UNTRUSTED_EMBEDDING_ACTIVITY));
     }
 
     /**
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsControllerTests.java b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsControllerTests.java
index 65465b2..8dc33b1 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsControllerTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsControllerTests.java
@@ -59,6 +59,7 @@
 import android.app.Instrumentation;
 import android.content.Context;
 import android.content.pm.PackageManager;
+import android.content.res.Resources;
 import android.os.Bundle;
 import android.os.SystemClock;
 import android.platform.test.annotations.Presubmit;
@@ -226,6 +227,11 @@
         final Instrumentation instrumentation = getInstrumentation();
         assumeThat(MockImeSession.getUnavailabilityReason(instrumentation.getContext()),
                 nullValue());
+        final Resources resources = instrumentation.getContext().getResources();
+        final boolean isHideNavBarForKeyboardEnabled = resources.getBoolean(
+                resources.getIdentifier("config_hideNavBarForKeyboard", "bool", "android"));
+        assumeFalse("Device is configured to not show navigation bar for keyboard",
+                isHideNavBarForKeyboardEnabled);
         final MockImeSession imeSession = MockImeHelper.createManagedMockImeSession(this);
         final ImeEventStream stream = imeSession.openEventStream();
         final TestActivity activity = startActivityInWindowingModeFullScreen(TestActivity.class);
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 ccd8659..8855dee 100644
--- a/tests/inputmethod/mockime/src/com/android/cts/mockime/Watermark.java
+++ b/tests/inputmethod/mockime/src/com/android/cts/mockime/Watermark.java
@@ -32,7 +32,7 @@
      *
      * <p>See Bug 174534092 about why we ended up having this.</p>
      */
-    private static final int TOLERANCE = 4;
+    private static final int TOLERANCE = 6;
 
     /**
      * A utility class that represents A8R8G8B bitmap as an integer array.
diff --git a/tests/media/src/android/mediav2/cts/CodecInfoTest.java b/tests/media/src/android/mediav2/cts/CodecInfoTest.java
index 5f9aa09..39b90ff 100644
--- a/tests/media/src/android/mediav2/cts/CodecInfoTest.java
+++ b/tests/media/src/android/mediav2/cts/CodecInfoTest.java
@@ -158,10 +158,10 @@
                             .noneMatch(x -> x == COLOR_FormatSurface));
         }
 
-        // For devices launching with Android T, if a codec supports an HDR profile, it must
-        // advertise P010 support
+        // For devices launching with Android T, if a codec supports an HDR profile and device
+        // supports HDR display, it must advertise P010 support
         int[] HdrProfileArray = mProfileHdrMap.get(mMediaType);
-        if (FIRST_SDK_IS_AT_LEAST_T && HdrProfileArray != null) {
+        if (FIRST_SDK_IS_AT_LEAST_T && HdrProfileArray != null && DISPLAY_HDR_TYPES.length > 0) {
             for (CodecProfileLevel pl : caps.profileLevels) {
                 if (IntStream.of(HdrProfileArray).anyMatch(x -> x == pl.profile)) {
                     assertFalse(mCodecInfo.getName() + " supports HDR profile " + pl.profile + "," +
diff --git a/tests/mediapc/common/src/android/mediapc/cts/common/PerformanceClassEvaluator.java b/tests/mediapc/common/src/android/mediapc/cts/common/PerformanceClassEvaluator.java
index 327fb9c..d3fd292 100644
--- a/tests/mediapc/common/src/android/mediapc/cts/common/PerformanceClassEvaluator.java
+++ b/tests/mediapc/common/src/android/mediapc/cts/common/PerformanceClassEvaluator.java
@@ -20,6 +20,7 @@
 
 import static org.junit.Assume.assumeTrue;
 
+import android.hardware.camera2.CameraMetadata;
 import android.media.MediaFormat;
 import android.os.Build;
 
@@ -849,7 +850,493 @@
         }
     }
 
-    private <R extends Requirement> R addRequirement(R req) {
+    public static class PrimaryCameraRequirement extends Requirement {
+        private static final long MIN_BACK_SENSOR_PERF_CLASS_RESOLUTION = 12000000;
+        private static final long MIN_FRONT_SENSOR_S_PERF_CLASS_RESOLUTION = 5000000;
+        private static final long MIN_FRONT_SENSOR_R_PERF_CLASS_RESOLUTION = 4000000;
+        private static final String TAG = PrimaryCameraRequirement.class.getSimpleName();
+
+        private PrimaryCameraRequirement(String id, RequiredMeasurement<?> ... reqs) {
+            super(id, reqs);
+        }
+
+        public void setPrimaryCameraSupported(boolean hasPrimaryCamera) {
+            this.setMeasuredValue(RequirementConstants.PRIMARY_CAMERA_AVAILABLE,
+                    hasPrimaryCamera);
+        }
+
+        public void setResolution(long resolution) {
+            this.setMeasuredValue(RequirementConstants.PRIMARY_CAMERA_RESOLUTION,
+                    resolution);
+        }
+
+        public void setVideoSizeReqSatisfied(boolean videoSizeReqSatisfied) {
+            this.setMeasuredValue(RequirementConstants.PRIMARY_CAMERA_VIDEO_SIZE_REQ_SATISFIED,
+                    videoSizeReqSatisfied);
+        }
+
+        public void setVideoFps(double videoFps) {
+            this.setMeasuredValue(RequirementConstants.PRIMARY_CAMERA_VIDEO_FPS, videoFps);
+        }
+
+        /**
+         * [2.2.7.2/7.5/H-1-1] MUST have a primary rear facing camera with a resolution of at
+         * least 12 megapixels supporting video capture at 4k@30fps
+         */
+        public static PrimaryCameraRequirement createRearPrimaryCamera() {
+            RequiredMeasurement<Boolean> hasPrimaryCamera = RequiredMeasurement
+                .<Boolean>builder()
+                .setId(RequirementConstants.PRIMARY_CAMERA_AVAILABLE)
+                .setPredicate(RequirementConstants.BOOLEAN_EQ)
+                .addRequiredValue(Build.VERSION_CODES.R, true)
+                .addRequiredValue(Build.VERSION_CODES.S, true)
+                .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
+                .build();
+
+            RequiredMeasurement<Long> cameraResolution = RequiredMeasurement
+                .<Long>builder()
+                .setId(RequirementConstants.PRIMARY_CAMERA_RESOLUTION)
+                .setPredicate(RequirementConstants.LONG_GTE)
+                .addRequiredValue(Build.VERSION_CODES.R, MIN_BACK_SENSOR_PERF_CLASS_RESOLUTION)
+                .addRequiredValue(Build.VERSION_CODES.S, MIN_BACK_SENSOR_PERF_CLASS_RESOLUTION)
+                .addRequiredValue(Build.VERSION_CODES.TIRAMISU, MIN_BACK_SENSOR_PERF_CLASS_RESOLUTION)
+                .build();
+
+            RequiredMeasurement<Boolean> videoSizeReqSatisfied = RequiredMeasurement
+                .<Boolean>builder()
+                .setId(RequirementConstants.PRIMARY_CAMERA_VIDEO_SIZE_REQ_SATISFIED)
+                .setPredicate(RequirementConstants.BOOLEAN_EQ)
+                .addRequiredValue(Build.VERSION_CODES.R, true)
+                .addRequiredValue(Build.VERSION_CODES.S, true)
+                .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
+                .build();
+
+            RequiredMeasurement<Double> videoFps = RequiredMeasurement
+                .<Double>builder()
+                .setId(RequirementConstants.PRIMARY_CAMERA_VIDEO_FPS)
+                .setPredicate(RequirementConstants.DOUBLE_GTE)
+                .addRequiredValue(Build.VERSION_CODES.R, 29.9)
+                .addRequiredValue(Build.VERSION_CODES.S, 29.9)
+                .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 29.9)
+                .build();
+
+            return new PrimaryCameraRequirement(RequirementConstants.R7_5__H_1_1,
+                    hasPrimaryCamera, cameraResolution, videoSizeReqSatisfied,
+                    videoFps);
+        }
+
+        /**
+         * [2.2.7.2/7.5/H-1-2] MUST have a primary front facing camera with a resolution of
+         * at least 4 megapixels supporting video capture at 1080p@30fps.
+         */
+        public static PrimaryCameraRequirement createFrontPrimaryCamera() {
+            RequiredMeasurement<Boolean> hasPrimaryCamera = RequiredMeasurement
+                .<Boolean>builder()
+                .setId(RequirementConstants.PRIMARY_CAMERA_AVAILABLE)
+                .setPredicate(RequirementConstants.BOOLEAN_EQ)
+                .addRequiredValue(Build.VERSION_CODES.R, true)
+                .addRequiredValue(Build.VERSION_CODES.S, true)
+                .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
+                .build();
+
+            RequiredMeasurement<Long> cameraResolution = RequiredMeasurement
+                .<Long>builder()
+                .setId(RequirementConstants.PRIMARY_CAMERA_RESOLUTION)
+                .setPredicate(RequirementConstants.LONG_GTE)
+                .addRequiredValue(Build.VERSION_CODES.R, MIN_FRONT_SENSOR_R_PERF_CLASS_RESOLUTION)
+                .addRequiredValue(Build.VERSION_CODES.S, MIN_FRONT_SENSOR_S_PERF_CLASS_RESOLUTION)
+                .addRequiredValue(Build.VERSION_CODES.TIRAMISU,
+                        MIN_FRONT_SENSOR_S_PERF_CLASS_RESOLUTION)
+                .build();
+
+            RequiredMeasurement<Boolean> videoSizeReqSatisfied = RequiredMeasurement
+                .<Boolean>builder()
+                .setId(RequirementConstants.PRIMARY_CAMERA_VIDEO_SIZE_REQ_SATISFIED)
+                .setPredicate(RequirementConstants.BOOLEAN_EQ)
+                .addRequiredValue(Build.VERSION_CODES.R, true)
+                .addRequiredValue(Build.VERSION_CODES.S, true)
+                .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
+                .build();
+
+            RequiredMeasurement<Double> videoFps = RequiredMeasurement
+                .<Double>builder()
+                .setId(RequirementConstants.PRIMARY_CAMERA_VIDEO_FPS)
+                .setPredicate(RequirementConstants.DOUBLE_GTE)
+                .addRequiredValue(Build.VERSION_CODES.R, 29.9)
+                .addRequiredValue(Build.VERSION_CODES.S, 29.9)
+                .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 29.9)
+                .build();
+
+            return new PrimaryCameraRequirement(RequirementConstants.R7_5__H_1_2,
+                    hasPrimaryCamera, cameraResolution, videoSizeReqSatisfied,
+                    videoFps);
+        }
+    }
+
+    public static class CameraTimestampSourceRequirement extends Requirement {
+        private static final String TAG = CameraTimestampSourceRequirement.class.getSimpleName();
+        private static final int TIMESTAMP_REALTIME =
+                CameraMetadata.SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME;
+
+        private CameraTimestampSourceRequirement(String id, RequiredMeasurement<?> ... reqs) {
+            super(id, reqs);
+        }
+
+        public void setRearCameraTimestampSource(Integer timestampSource) {
+            this.setMeasuredValue(RequirementConstants.REAR_CAMERA_TIMESTAMP_SOURCE,
+                    timestampSource);
+        }
+
+        public void setFrontCameraTimestampSource(Integer timestampSource) {
+            this.setMeasuredValue(RequirementConstants.FRONT_CAMERA_TIMESTAMP_SOURCE,
+                    timestampSource);
+        }
+        /**
+         * [2.2.7.2/7.5/H-1-4] MUST support CameraMetadata.SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME
+         * for both primary cameras.
+         */
+        public static CameraTimestampSourceRequirement createTimestampSourceReq() {
+            RequiredMeasurement<Integer> rearTimestampSource = RequiredMeasurement
+                .<Integer>builder()
+                .setId(RequirementConstants.REAR_CAMERA_TIMESTAMP_SOURCE)
+                .setPredicate(RequirementConstants.INTEGER_EQ)
+                .addRequiredValue(Build.VERSION_CODES.R, TIMESTAMP_REALTIME)
+                .addRequiredValue(Build.VERSION_CODES.S, TIMESTAMP_REALTIME)
+                .addRequiredValue(Build.VERSION_CODES.TIRAMISU, TIMESTAMP_REALTIME)
+                .build();
+            RequiredMeasurement<Integer> frontTimestampSource = RequiredMeasurement
+                .<Integer>builder()
+                .setId(RequirementConstants.FRONT_CAMERA_TIMESTAMP_SOURCE)
+                .setPredicate(RequirementConstants.INTEGER_EQ)
+                .addRequiredValue(Build.VERSION_CODES.R, TIMESTAMP_REALTIME)
+                .addRequiredValue(Build.VERSION_CODES.S, TIMESTAMP_REALTIME)
+                .addRequiredValue(Build.VERSION_CODES.TIRAMISU, TIMESTAMP_REALTIME)
+                .build();
+
+            return new CameraTimestampSourceRequirement(RequirementConstants.R7_5__H_1_4,
+                    rearTimestampSource, frontTimestampSource);
+        }
+    }
+
+    public static class CameraLatencyRequirement extends Requirement {
+        private static final String TAG = CameraTimestampSourceRequirement.class.getSimpleName();
+
+        private CameraLatencyRequirement(String id, RequiredMeasurement<?> ... reqs) {
+            super(id, reqs);
+        }
+
+        public void setRearCameraLatency(float latency) {
+            this.setMeasuredValue(RequirementConstants.REAR_CAMERA_LATENCY, latency);
+        }
+
+        public void setFrontCameraLatency(float latency) {
+            this.setMeasuredValue(RequirementConstants.FRONT_CAMERA_LATENCY, latency);
+        }
+
+        /**
+         * [2.2.7.2/7.5/H-1-5] MUST have camera2 JPEG capture latency < 1000ms for 1080p resolution
+         * as measured by the CTS camera PerformanceTest under ITS lighting conditions
+         * (3000K) for both primary cameras.
+         */
+        public static CameraLatencyRequirement createJpegLatencyReq() {
+            RequiredMeasurement<Float> rearJpegLatency = RequiredMeasurement
+                .<Float>builder()
+                .setId(RequirementConstants.REAR_CAMERA_LATENCY)
+                .setPredicate(RequirementConstants.FLOAT_LTE)
+                .addRequiredValue(Build.VERSION_CODES.R, 1000.0f)
+                .addRequiredValue(Build.VERSION_CODES.S, 1000.0f)
+                .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 1000.0f)
+                .build();
+            RequiredMeasurement<Float> frontJpegLatency = RequiredMeasurement
+                .<Float>builder()
+                .setId(RequirementConstants.FRONT_CAMERA_LATENCY)
+                .setPredicate(RequirementConstants.FLOAT_LTE)
+                .addRequiredValue(Build.VERSION_CODES.R, 1000.0f)
+                .addRequiredValue(Build.VERSION_CODES.S, 1000.0f)
+                .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 1000.0f)
+                .build();
+
+            return new CameraLatencyRequirement(RequirementConstants.R7_5__H_1_5,
+                    rearJpegLatency, frontJpegLatency);
+        }
+
+        /**
+         * [2.2.7.2/7.5/H-1-6] MUST have camera2 startup latency (open camera to first
+         * preview frame) < 600ms as measured by the CTS camera PerformanceTest under ITS lighting
+         * conditions (3000K) for both primary cameras.
+         */
+        public static CameraLatencyRequirement createLaunchLatencyReq() {
+            RequiredMeasurement<Float> rearLaunchLatency = RequiredMeasurement
+                .<Float>builder()
+                .setId(RequirementConstants.REAR_CAMERA_LATENCY)
+                .setPredicate(RequirementConstants.FLOAT_LTE)
+                .addRequiredValue(Build.VERSION_CODES.R, 600.0f)
+                .addRequiredValue(Build.VERSION_CODES.S, 600.0f)
+                .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 600.0f)
+                .build();
+            RequiredMeasurement<Float> frontLaunchLatency = RequiredMeasurement
+                .<Float>builder()
+                .setId(RequirementConstants.FRONT_CAMERA_LATENCY)
+                .setPredicate(RequirementConstants.FLOAT_LTE)
+                .addRequiredValue(Build.VERSION_CODES.R, 600.0f)
+                .addRequiredValue(Build.VERSION_CODES.S, 600.0f)
+                .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 600.0f)
+                .build();
+
+            return new CameraLatencyRequirement(RequirementConstants.R7_5__H_1_6,
+                    rearLaunchLatency, frontLaunchLatency);
+        }
+    }
+
+    public static class CameraRawRequirement extends Requirement {
+        private static final String TAG = CameraRawRequirement.class.getSimpleName();
+
+        private CameraRawRequirement(String id, RequiredMeasurement<?> ... reqs) {
+            super(id, reqs);
+        }
+
+        public void setRearRawSupported(boolean rearRawSupported) {
+            this.setMeasuredValue(RequirementConstants.REAR_CAMERA_RAW_SUPPORTED,
+                    rearRawSupported);
+        }
+
+        /**
+         * [2.2.7.2/7.5/H-1-8] MUST support CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_RAW and
+         * android.graphics.ImageFormat.RAW_SENSOR for the primary back camera.
+         */
+        public static CameraRawRequirement createRawReq() {
+            RequiredMeasurement<Boolean> requirement = RequiredMeasurement
+                .<Boolean>builder()
+                .setId(RequirementConstants.REAR_CAMERA_RAW_SUPPORTED)
+                .setPredicate(RequirementConstants.BOOLEAN_EQ)
+                .addRequiredValue(Build.VERSION_CODES.S, true)
+                .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
+                .build();
+
+            return new CameraRawRequirement(RequirementConstants.R7_5__H_1_8, requirement);
+        }
+    }
+
+    public static class Camera240FpsRequirement extends Requirement {
+        private static final String TAG = Camera240FpsRequirement.class.getSimpleName();
+
+        private Camera240FpsRequirement(String id, RequiredMeasurement<?> ... reqs) {
+            super(id, reqs);
+        }
+
+        public void setRear240FpsSupported(boolean rear240FpsSupported) {
+            this.setMeasuredValue(RequirementConstants.REAR_CAMERA_240FPS_SUPPORTED,
+                    rear240FpsSupported);
+        }
+
+        /**
+         * [2.2.7.2/7.5/H-1-9] MUST have a rear-facing primary camera supporting 720p or 1080p @ 240fps.
+         */
+        public static Camera240FpsRequirement create240FpsReq() {
+            RequiredMeasurement<Boolean> requirement = RequiredMeasurement
+                .<Boolean>builder()
+                .setId(RequirementConstants.REAR_CAMERA_240FPS_SUPPORTED)
+                .setPredicate(RequirementConstants.BOOLEAN_EQ)
+                .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
+                .build();
+
+            return new Camera240FpsRequirement(RequirementConstants.R7_5__H_1_9, requirement);
+        }
+    }
+
+    public static class UltraWideZoomRatioRequirement extends Requirement {
+        private static final String TAG =
+                UltraWideZoomRatioRequirement.class.getSimpleName();
+
+        private UltraWideZoomRatioRequirement(String id, RequiredMeasurement<?> ... reqs) {
+            super(id, reqs);
+        }
+
+        public void setRearUltraWideZoomRatioReqMet(boolean ultrawideZoomRatioReqMet) {
+            this.setMeasuredValue(RequirementConstants.REAR_CAMERA_ULTRAWIDE_ZOOMRATIO_REQ_MET,
+                    ultrawideZoomRatioReqMet);
+        }
+
+        public void setFrontUltraWideZoomRatioReqMet(boolean ultrawideZoomRatioReqMet) {
+            this.setMeasuredValue(RequirementConstants.FRONT_CAMERA_ULTRAWIDE_ZOOMRATIO_REQ_MET,
+                    ultrawideZoomRatioReqMet);
+        }
+
+        /**
+         * [2.2.7.2/7.5/H-1-10] MUST have min ZOOM_RATIO < 1.0 for the primary cameras if
+         * there is an ultrawide RGB camera facing the same direction.
+         */
+        public static UltraWideZoomRatioRequirement createUltrawideZoomRatioReq() {
+            RequiredMeasurement<Boolean> rearRequirement = RequiredMeasurement
+                .<Boolean>builder()
+                .setId(RequirementConstants.REAR_CAMERA_ULTRAWIDE_ZOOMRATIO_REQ_MET)
+                .setPredicate(RequirementConstants.BOOLEAN_EQ)
+                .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
+                .build();
+            RequiredMeasurement<Boolean> frontRequirement = RequiredMeasurement
+                .<Boolean>builder()
+                .setId(RequirementConstants.FRONT_CAMERA_ULTRAWIDE_ZOOMRATIO_REQ_MET)
+                .setPredicate(RequirementConstants.BOOLEAN_EQ)
+                .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
+                .build();
+
+            return new UltraWideZoomRatioRequirement(RequirementConstants.R7_5__H_1_10,
+                    rearRequirement, frontRequirement);
+        }
+    }
+
+    public static class ConcurrentRearFrontRequirement extends Requirement {
+        private static final String TAG = ConcurrentRearFrontRequirement.class.getSimpleName();
+
+        private ConcurrentRearFrontRequirement(String id, RequiredMeasurement<?> ... reqs) {
+            super(id, reqs);
+        }
+
+        public void setConcurrentRearFrontSupported(boolean concurrentRearFrontSupported) {
+            this.setMeasuredValue(RequirementConstants.CONCURRENT_REAR_FRONT_SUPPORTED,
+                    concurrentRearFrontSupported);
+        }
+
+        /**
+         * [2.2.7.2/7.5/H-1-11] MUST implement concurrent front-back streaming on primary cameras.
+         */
+        public static ConcurrentRearFrontRequirement createConcurrentRearFrontReq() {
+            RequiredMeasurement<Boolean> requirement = RequiredMeasurement
+                .<Boolean>builder()
+                .setId(RequirementConstants.CONCURRENT_REAR_FRONT_SUPPORTED)
+                .setPredicate(RequirementConstants.BOOLEAN_EQ)
+                .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
+                .build();
+
+            return new ConcurrentRearFrontRequirement(RequirementConstants.R7_5__H_1_11,
+                    requirement);
+        }
+    }
+
+    public static class PreviewStabilizationRequirement extends Requirement {
+        private static final String TAG =
+                PreviewStabilizationRequirement.class.getSimpleName();
+
+        private PreviewStabilizationRequirement(String id, RequiredMeasurement<?> ... reqs) {
+            super(id, reqs);
+        }
+
+        public void setRearPreviewStabilizationSupported(boolean supported) {
+            this.setMeasuredValue(RequirementConstants.REAR_CAMERA_PREVIEW_STABILIZATION_SUPPORTED,
+                    supported);
+        }
+
+        public void setFrontPreviewStabilizationSupported(boolean supported) {
+            this.setMeasuredValue(RequirementConstants.FRONT_CAMERA_PREVIEW_STABILIZATION_SUPPORTED,
+                    supported);
+        }
+
+        /**
+         * [2.2.7.2/7.5/H-1-12] MUST support CONTROL_VIDEO_STABILIZATION_MODE_PREVIEW_STABILIZATION
+         * for both primary front and primary back camera.
+         */
+        public static PreviewStabilizationRequirement createPreviewStabilizationReq() {
+            RequiredMeasurement<Boolean> rearRequirement = RequiredMeasurement
+                .<Boolean>builder()
+                .setId(RequirementConstants.REAR_CAMERA_PREVIEW_STABILIZATION_SUPPORTED)
+                .setPredicate(RequirementConstants.BOOLEAN_EQ)
+                .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
+                .build();
+            RequiredMeasurement<Boolean> frontRequirement = RequiredMeasurement
+                .<Boolean>builder()
+                .setId(RequirementConstants.FRONT_CAMERA_PREVIEW_STABILIZATION_SUPPORTED)
+                .setPredicate(RequirementConstants.BOOLEAN_EQ)
+                .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
+                .build();
+
+            return new PreviewStabilizationRequirement(RequirementConstants.R7_5__H_1_12,
+                    rearRequirement, frontRequirement);
+        }
+    }
+
+    public static class LogicalMultiCameraRequirement extends Requirement {
+        private static final String TAG =
+                LogicalMultiCameraRequirement.class.getSimpleName();
+
+        private LogicalMultiCameraRequirement(String id, RequiredMeasurement<?> ... reqs) {
+            super(id, reqs);
+        }
+
+        public void setRearLogicalMultiCameraReqMet(boolean reqMet) {
+            this.setMeasuredValue(RequirementConstants.REAR_CAMERA_LOGICAL_MULTI_CAMERA_REQ_MET,
+                    reqMet);
+        }
+
+        public void setFrontLogicalMultiCameraReqMet(boolean reqMet) {
+            this.setMeasuredValue(RequirementConstants.FRONT_CAMERA_LOGICAL_MULTI_CAMERA_REQ_MET,
+                    reqMet);
+        }
+
+        /**
+         * [2.2.7.2/7.5/H-1-13] MUST support LOGICAL_MULTI_CAMERA capability for the primary
+         * cameras if there are greater than 1 RGB cameras facing the same direction.
+         */
+        public static LogicalMultiCameraRequirement createLogicalMultiCameraReq() {
+            RequiredMeasurement<Boolean> rearRequirement = RequiredMeasurement
+                .<Boolean>builder()
+                .setId(RequirementConstants.REAR_CAMERA_LOGICAL_MULTI_CAMERA_REQ_MET)
+                .setPredicate(RequirementConstants.BOOLEAN_EQ)
+                .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
+                .build();
+            RequiredMeasurement<Boolean> frontRequirement = RequiredMeasurement
+                .<Boolean>builder()
+                .setId(RequirementConstants.FRONT_CAMERA_LOGICAL_MULTI_CAMERA_REQ_MET)
+                .setPredicate(RequirementConstants.BOOLEAN_EQ)
+                .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
+                .build();
+
+            return new LogicalMultiCameraRequirement(RequirementConstants.R7_5__H_1_13,
+                    rearRequirement, frontRequirement);
+        }
+    }
+
+    public static class StreamUseCaseRequirement extends Requirement {
+        private static final String TAG =
+                StreamUseCaseRequirement.class.getSimpleName();
+
+        private StreamUseCaseRequirement(String id, RequiredMeasurement<?> ... reqs) {
+            super(id, reqs);
+        }
+
+        public void setRearStreamUseCaseSupported(boolean supported) {
+            this.setMeasuredValue(RequirementConstants.REAR_CAMERA_STREAM_USECASE_SUPPORTED,
+                    supported);
+        }
+
+        public void setFrontStreamUseCaseSupported(boolean supported) {
+            this.setMeasuredValue(RequirementConstants.FRONT_CAMERA_STREAM_USECASE_SUPPORTED,
+                    supported);
+        }
+
+        /**
+         * [2.2.7.2/7.5/H-1-14] MUST support STREAM_USE_CASE capability for both primary
+         * front and primary back camera.
+         */
+        public static StreamUseCaseRequirement createStreamUseCaseReq() {
+            RequiredMeasurement<Boolean> rearRequirement = RequiredMeasurement
+                .<Boolean>builder()
+                .setId(RequirementConstants.REAR_CAMERA_STREAM_USECASE_SUPPORTED)
+                .setPredicate(RequirementConstants.BOOLEAN_EQ)
+                .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
+                .build();
+            RequiredMeasurement<Boolean> frontRequirement = RequiredMeasurement
+                .<Boolean>builder()
+                .setId(RequirementConstants.FRONT_CAMERA_STREAM_USECASE_SUPPORTED)
+                .setPredicate(RequirementConstants.BOOLEAN_EQ)
+                .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
+                .build();
+
+            return new StreamUseCaseRequirement(RequirementConstants.R7_5__H_1_14,
+                    rearRequirement, frontRequirement);
+        }
+    }
+
+    public <R extends Requirement> R addRequirement(R req) {
         if (!this.mRequirements.add(req)) {
             throw new IllegalStateException("Requirement " + req.id() + " already added");
         }
@@ -1000,16 +1487,69 @@
         return this.addRequirement(ConcurrentCodecRequirement.createR5_1__H_1_10());
     }
 
+    public PrimaryCameraRequirement addPrimaryRearCameraReq() {
+        return this.addRequirement(PrimaryCameraRequirement.createRearPrimaryCamera());
+    }
+
+    public PrimaryCameraRequirement addPrimaryFrontCameraReq() {
+        return this.addRequirement(PrimaryCameraRequirement.createFrontPrimaryCamera());
+    }
+
+    public CameraTimestampSourceRequirement addR7_5__H_1_4() {
+        return this.addRequirement(CameraTimestampSourceRequirement.createTimestampSourceReq());
+    }
+
+    public CameraLatencyRequirement addR7_5__H_1_5() {
+        return this.addRequirement(CameraLatencyRequirement.createJpegLatencyReq());
+    }
+
+    public CameraLatencyRequirement addR7_5__H_1_6() {
+        return this.addRequirement(CameraLatencyRequirement.createLaunchLatencyReq());
+    }
+
+    public CameraRawRequirement addR7_5__H_1_8() {
+        return this.addRequirement(CameraRawRequirement.createRawReq());
+    }
+
+    public Camera240FpsRequirement addR7_5__H_1_9() {
+        return this.addRequirement(Camera240FpsRequirement.create240FpsReq());
+    }
+
+    public UltraWideZoomRatioRequirement addR7_5__H_1_10() {
+        return this.addRequirement(UltraWideZoomRatioRequirement.createUltrawideZoomRatioReq());
+    }
+
+    public ConcurrentRearFrontRequirement addR7_5__H_1_11() {
+        return this.addRequirement(ConcurrentRearFrontRequirement.createConcurrentRearFrontReq());
+    }
+
+    public PreviewStabilizationRequirement addR7_5__H_1_12() {
+        return this.addRequirement(PreviewStabilizationRequirement.createPreviewStabilizationReq());
+    }
+
+    public LogicalMultiCameraRequirement addR7_5__H_1_13() {
+        return this.addRequirement(LogicalMultiCameraRequirement.createLogicalMultiCameraReq());
+    }
+
+    public StreamUseCaseRequirement addR7_5__H_1_14() {
+        return this.addRequirement(StreamUseCaseRequirement.createStreamUseCaseReq());
+    }
+
     public void submitAndCheck() {
-        boolean perfClassMet = true;
-        for (Requirement req: this.mRequirements) {
-            perfClassMet &= req.writeLogAndCheck(this.mTestName);
-        }
+        boolean perfClassMet = submit();
 
         // check performance class
         assumeTrue("Build.VERSION.MEDIA_PERFORMANCE_CLASS is not declared", Utils.isPerfClass());
         assertThat(perfClassMet).isTrue();
-
-        this.mRequirements.clear(); // makes sure report isn't submitted twice
     }
+
+    public boolean submit() {
+        boolean perfClassMet = true;
+        for (Requirement req: this.mRequirements) {
+            perfClassMet &= req.writeLogAndCheck(this.mTestName);
+        }
+        this.mRequirements.clear(); // makes sure report isn't submitted twice
+        return perfClassMet;
+    }
+
 }
diff --git a/tests/mediapc/common/src/android/mediapc/cts/common/RequirementConstants.java b/tests/mediapc/common/src/android/mediapc/cts/common/RequirementConstants.java
index d93cb2e..ad0d0d5 100644
--- a/tests/mediapc/common/src/android/mediapc/cts/common/RequirementConstants.java
+++ b/tests/mediapc/common/src/android/mediapc/cts/common/RequirementConstants.java
@@ -16,8 +16,6 @@
 
 package android.mediapc.cts.common;
 
-import android.os.Build;
-
 import java.util.function.BiPredicate;
 
 public class RequirementConstants {
@@ -54,8 +52,13 @@
     public static final String R7_5__H_1_4 = "r7_5__h_1_4"; // 7.5/H-1-4
     public static final String R7_5__H_1_5 = "r7_5__h_1_5"; // 7.5/H-1-5
     public static final String R7_5__H_1_6 = "r7_5__h_1_6"; // 7.5/H-1-6
-    public static final String R7_5__H_1_7 = "r7_5__h_1_7"; // 7.5/H-1-7
     public static final String R7_5__H_1_8 = "r7_5__h_1_8"; // 7.5/H-1-8
+    public static final String R7_5__H_1_9 = "r7_5__h_1_9"; // 7.5/H-1-9
+    public static final String R7_5__H_1_10 = "r7_5__h_1_10"; // 7.5/H-1-10
+    public static final String R7_5__H_1_11 = "r7_5__h_1_11"; // 7.5/H-1-11
+    public static final String R7_5__H_1_12 = "r7_5__h_1_12"; // 7.5/H-1-12
+    public static final String R7_5__H_1_13 = "r7_5__h_1_13"; // 7.5/H-1-13
+    public static final String R7_5__H_1_14 = "r7_5__h_1_14"; // 7.5/H-1-14
     public static final String R7_1_1_1__H_1_1 = "r7_1_1_1__h_1_1"; // 7.1.1.1/H-1-1
     public static final String R7_1_1_3__H_1_1 = "r7_1_1_3__h_1_1"; // 7.1.1.3/H-1-1
     public static final String R7_6_1__H_1_1 = "r7_6_1__h_1_1"; // 7.6.1/H-1-1
@@ -90,14 +93,50 @@
     public static final String NUM_CRYPTO_HW_SECURE_ALL_SUPPORT =
         "number_crypto_hw_secure_all_support";
 
+    public static final String PRIMARY_CAMERA_AVAILABLE = "primary_camera_available";
+    public static final String PRIMARY_CAMERA_RESOLUTION = "primary_camera_resolution";
+    public static final String PRIMARY_CAMERA_VIDEO_SIZE_REQ_SATISFIED =
+            "primary_camera_video_size_req_satisfied";
+    public static final String PRIMARY_CAMERA_VIDEO_FPS =
+            "primary_camera_video_fps";
+    public static final String REAR_CAMERA_HWL_LEVEL = "rear_primary_camera_hwl_level";
+    public static final String FRONT_CAMERA_HWL_LEVEL = "front_primary_camera_hwl_level";
+    public static final String REAR_CAMERA_TIMESTAMP_SOURCE =
+            "rear_primary_camera_timestamp_source";
+    public static final String FRONT_CAMERA_TIMESTAMP_SOURCE =
+            "front_primary_camera_timestamp_source";
+    public static final String REAR_CAMERA_LATENCY = "rear_camera_latency";
+    public static final String FRONT_CAMERA_LATENCY = "front_camera_latency";
+    public static final String REAR_CAMERA_RAW_SUPPORTED = "rear_camera_raw_supported";
+    public static final String REAR_CAMERA_240FPS_SUPPORTED = "rear_camera_240fps_supported";
+    public static final String REAR_CAMERA_ULTRAWIDE_ZOOMRATIO_REQ_MET =
+            "rear_camera_ultrawide_zoom_req_met";
+    public static final String FRONT_CAMERA_ULTRAWIDE_ZOOMRATIO_REQ_MET =
+            "front_camera_ultrawide_zoom_req_met";
+    public static final String CONCURRENT_REAR_FRONT_SUPPORTED = "rear_front_concurrent_camera";
+    public static final String REAR_CAMERA_PREVIEW_STABILIZATION_SUPPORTED =
+            "rear_camera_preview_stabilization_supported";
+    public static final String FRONT_CAMERA_PREVIEW_STABILIZATION_SUPPORTED =
+            "front_camera_preview_stabilization_supported";
+    public static final String REAR_CAMERA_LOGICAL_MULTI_CAMERA_REQ_MET =
+            "rear_camera_logical_multi_camera_req_met";
+    public static final String FRONT_CAMERA_LOGICAL_MULTI_CAMERA_REQ_MET =
+            "front_camera_logical_multi_camera_req_met";
+    public static final String REAR_CAMERA_STREAM_USECASE_SUPPORTED =
+            "rear_camera_stream_usecase_supported";
+    public static final String FRONT_CAMERA_STREAM_USECASE_SUPPORTED =
+            "front_camera_stream_usecase_supported";
+
     public enum Result {
         NA, MET, UNMET
     }
 
     public static final BiPredicate<Long, Long> LONG_GTE = RequirementConstants.gte();
     public static final BiPredicate<Long, Long> LONG_LTE = RequirementConstants.lte();
+    public static final BiPredicate<Float, Float> FLOAT_LTE = RequirementConstants.lte();
     public static final BiPredicate<Integer, Integer> INTEGER_GTE = RequirementConstants.gte();
     public static final BiPredicate<Integer, Integer> INTEGER_LTE = RequirementConstants.lte();
+    public static final BiPredicate<Integer, Integer> INTEGER_EQ = RequirementConstants.eq();
     public static final BiPredicate<Double, Double> DOUBLE_EQ = RequirementConstants.eq();
     public static final BiPredicate<Boolean, Boolean> BOOLEAN_EQ = RequirementConstants.eq();
     public static final BiPredicate<Double, Double> DOUBLE_GTE = RequirementConstants.gte();
diff --git a/tests/mediapc/common/src/android/mediapc/cts/common/Utils.java b/tests/mediapc/common/src/android/mediapc/cts/common/Utils.java
index ac03705..28a122b 100644
--- a/tests/mediapc/common/src/android/mediapc/cts/common/Utils.java
+++ b/tests/mediapc/common/src/android/mediapc/cts/common/Utils.java
@@ -73,16 +73,24 @@
 
         Context context = InstrumentationRegistry.getInstrumentation().getContext();
         DisplayMetrics metrics = new DisplayMetrics();
-        WindowManager windowManager = context.getSystemService(WindowManager.class);
-        windowManager.getDefaultDisplay().getMetrics(metrics);
-        DISPLAY_DPI = metrics.densityDpi;
-        DISPLAY_LONG_PIXELS = Math.max(metrics.widthPixels, metrics.heightPixels);
-        DISPLAY_SHORT_PIXELS = Math.min(metrics.widthPixels, metrics.heightPixels);
+        // When used from ItsService, context will be null
+        if (context != null) {
+            WindowManager windowManager = context.getSystemService(WindowManager.class);
+            windowManager.getDefaultDisplay().getMetrics(metrics);
+            DISPLAY_DPI = metrics.densityDpi;
+            DISPLAY_LONG_PIXELS = Math.max(metrics.widthPixels, metrics.heightPixels);
+            DISPLAY_SHORT_PIXELS = Math.min(metrics.widthPixels, metrics.heightPixels);
 
-        ActivityManager activityManager = context.getSystemService(ActivityManager.class);
-        ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
-        activityManager.getMemoryInfo(memoryInfo);
-        TOTAL_MEMORY_MB = memoryInfo.totalMem / 1024 / 1024;
+            ActivityManager activityManager = context.getSystemService(ActivityManager.class);
+            ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
+            activityManager.getMemoryInfo(memoryInfo);
+            TOTAL_MEMORY_MB = memoryInfo.totalMem / 1024 / 1024;
+        } else {
+            DISPLAY_DPI = 0;
+            DISPLAY_LONG_PIXELS = 0;
+            DISPLAY_SHORT_PIXELS = 0;
+            TOTAL_MEMORY_MB = 0;
+        }
     }
 
     /**
diff --git a/tests/tests/assist/common/src/android/assist/common/Utils.java b/tests/tests/assist/common/src/android/assist/common/Utils.java
index 0ffcb271..98e8576 100755
--- a/tests/tests/assist/common/src/android/assist/common/Utils.java
+++ b/tests/tests/assist/common/src/android/assist/common/Utils.java
@@ -56,6 +56,7 @@
     public static final String COMPARE_SCREENSHOT_KEY = "compare_screenshot";
     public static final String DISPLAY_WIDTH_KEY = "display_width";
     public static final String DISPLAY_HEIGHT_KEY = "dislay_height";
+    public static final String DISPLAY_AREA_BOUNDS_KEY = "display_area_bounds";
     public static final String SCROLL_X_POSITION = "scroll_x_position";
     public static final String SCROLL_Y_POSITION = "scroll_y_position";
     public static final String SHOW_SESSION_FLAGS_TO_SET = "show_session_flags_to_set";
diff --git a/tests/tests/assist/service/src/android/assist/service/MainInteractionSession.java b/tests/tests/assist/service/src/android/assist/service/MainInteractionSession.java
index 7f35367..25c080b 100644
--- a/tests/tests/assist/service/src/android/assist/service/MainInteractionSession.java
+++ b/tests/tests/assist/service/src/android/assist/service/MainInteractionSession.java
@@ -56,6 +56,7 @@
     private int mCurColor;
     private int mDisplayHeight;
     private int mDisplayWidth;
+    private Rect mDisplayAreaBounds;
     private BroadcastReceiver mReceiver;
     private String mTestName;
     private View mContentView;
@@ -106,7 +107,7 @@
     public void onPrepareShow(Bundle args, int showFlags) {
         if (Utils.LIFECYCLE_NOUI.equals(args.getString(Utils.TESTCASE_TYPE, ""))) {
             setUiEnabled(false);
-        } else  {
+        } else {
             setUiEnabled(true);
         }
     }
@@ -122,6 +123,7 @@
         mCurColor = args.getInt(Utils.SCREENSHOT_COLOR_KEY);
         mDisplayHeight = args.getInt(Utils.DISPLAY_HEIGHT_KEY);
         mDisplayWidth = args.getInt(Utils.DISPLAY_WIDTH_KEY);
+        mDisplayAreaBounds = args.getParcelable(Utils.DISPLAY_AREA_BOUNDS_KEY);
         mRemoteCallback = args.getParcelable(Utils.EXTRA_REMOTE_CALLBACK);
         super.onShow(args, showFlags);
         if (mContentView == null) return; // Happens when ui is not enabled.
@@ -256,6 +258,11 @@
         int[] pixels = new int[size.x * size.y];
         screenshot.getPixels(pixels, 0, size.x, 0, 0, size.x, size.y);
 
+        // screenshot bitmap contains the screenshot for the entire physical display. A single
+        // physical display could have multiple display area with different applications.
+        // Let's grab the region of the display area from the original screenshot.
+        Bitmap displayAreaScreenshot = Bitmap.createBitmap(screenshot, mDisplayAreaBounds.left,
+                mDisplayAreaBounds.top, mDisplayAreaBounds.width(), mDisplayAreaBounds.height());
         int expectedColor = 0;
         for (int pixel : pixels) {
             // Check for roughly the same because there are rounding errors converting from the
@@ -267,7 +274,7 @@
             }
         }
 
-        int pixelCount = screenshot.getWidth() * screenshot.getHeight();
+        int pixelCount = displayAreaScreenshot.getWidth() * displayAreaScreenshot.getHeight();
         double colorRatio = (double) expectedColor / pixelCount;
         Log.i(TAG, "the ratio is " + colorRatio);
         return colorRatio >= 0.6;
diff --git a/tests/tests/assist/src/android/assist/cts/AssistTestBase.java b/tests/tests/assist/src/android/assist/cts/AssistTestBase.java
index 44a3109..c89119b 100644
--- a/tests/tests/assist/src/android/assist/cts/AssistTestBase.java
+++ b/tests/tests/assist/src/android/assist/cts/AssistTestBase.java
@@ -35,9 +35,9 @@
 import android.content.Context;
 import android.content.Intent;
 import android.graphics.Point;
+import android.graphics.Rect;
 import android.os.Bundle;
 import android.os.Handler;
-import android.os.HandlerThread;
 import android.os.LocaleList;
 import android.os.RemoteCallback;
 import android.provider.Settings;
@@ -341,6 +341,8 @@
             Display.Mode dMode = mTestActivity.getWindowManager().getDefaultDisplay().getMode();
             mDisplaySize = new Point(dMode.getPhysicalWidth(), dMode.getPhysicalHeight());
         }
+        Rect bounds = mTestActivity.getWindowManager().getMaximumWindowMetrics().getBounds();
+        intent.putExtra(Utils.DISPLAY_AREA_BOUNDS_KEY, bounds);
         intent.putExtra(Utils.DISPLAY_WIDTH_KEY, mDisplaySize.x);
         intent.putExtra(Utils.DISPLAY_HEIGHT_KEY, mDisplaySize.y);
     }
diff --git a/tests/tests/bluetooth/AndroidTest.xml b/tests/tests/bluetooth/AndroidTest.xml
index 9a3075b..9818962 100644
--- a/tests/tests/bluetooth/AndroidTest.xml
+++ b/tests/tests/bluetooth/AndroidTest.xml
@@ -33,6 +33,6 @@
     <!-- Only run Cts Tests in MTS if the Bluetooth Mainline module is installed. -->
     <object type="module_controller"
             class="com.android.tradefed.testtype.suite.module.MainlineTestModuleController">
-        <option name="mainline-module-package-name" value="com.google.android.bluetooth" />
+        <option name="mainline-module-package-name" value="com.android.btservices" />
     </object>
 </configuration>
diff --git a/tests/tests/content/CtsSyncAccountAccessOtherCertTests/src/com/android/cts/content/CtsSyncAccountAccessOtherCertTestCases.java b/tests/tests/content/CtsSyncAccountAccessOtherCertTests/src/com/android/cts/content/CtsSyncAccountAccessOtherCertTestCases.java
index 49b72549..8bd1bb8 100644
--- a/tests/tests/content/CtsSyncAccountAccessOtherCertTests/src/com/android/cts/content/CtsSyncAccountAccessOtherCertTestCases.java
+++ b/tests/tests/content/CtsSyncAccountAccessOtherCertTests/src/com/android/cts/content/CtsSyncAccountAccessOtherCertTestCases.java
@@ -43,6 +43,9 @@
 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 android.support.test.uiautomator.UiScrollable;
+import android.support.test.uiautomator.UiSelector;
 import android.support.test.uiautomator.Until;
 import android.util.Log;
 
@@ -140,7 +143,7 @@
                     } catch (Throwable t) {
                         if (scrollUps < 10) {
                             // The notification we search for is below the fold, scroll to find it
-                            swipeUp(uiDevice);
+                            scrollNotifications();
                             scrollUps++;
                             continue;
                         }
@@ -200,6 +203,18 @@
             50 /* numberOfSteps */);
     }
 
+    private boolean scrollNotifications() {
+        UiScrollable scrollable = new UiScrollable(new UiSelector().scrollable(true));
+        if (!scrollable.exists()) {
+            return false;
+        }
+        try {
+            return scrollable.scrollForward(50);
+        } catch (UiObjectNotFoundException e) {
+            return false;
+        }
+    }
+
     private boolean isRunningInVR() {
         final Context context = InstrumentationRegistry.getTargetContext();
         return ((context.getResources().getConfiguration().uiMode &
diff --git a/tests/tests/media/decoder/src/android/media/decoder/cts/DecoderTest.java b/tests/tests/media/decoder/src/android/media/decoder/cts/DecoderTest.java
index a424edb..0b8c505 100644
--- a/tests/tests/media/decoder/src/android/media/decoder/cts/DecoderTest.java
+++ b/tests/tests/media/decoder/src/android/media/decoder/cts/DecoderTest.java
@@ -124,10 +124,10 @@
     private static final int CONFIG_MODE_NONE = 0;
     private static final int CONFIG_MODE_QUEUE = 1;
 
-    private static final int CODEC_ALL = 0; // All codecs must support
-    private static final int CODEC_ANY = 1; // At least one codec must support
-    private static final int CODEC_DEFAULT = 2; // Default codec must support
-    private static final int CODEC_OPTIONAL = 3; // Codec support is optional
+    public static final int CODEC_ALL = 0; // All codecs must support
+    public static final int CODEC_ANY = 1; // At least one codec must support
+    public static final int CODEC_DEFAULT = 2; // Default codec must support
+    public static final int CODEC_OPTIONAL = 3; // Codec support is optional
 
     short[] mMasterBuffer;
     static final String mInpPrefix = WorkDir.getMediaDirString();
diff --git a/tests/tests/media/decoder/src/android/media/decoder/cts/DecoderTestAacFormat.java b/tests/tests/media/decoder/src/android/media/decoder/cts/DecoderTestAacFormat.java
index f34f9e2..0857809 100644
--- a/tests/tests/media/decoder/src/android/media/decoder/cts/DecoderTestAacFormat.java
+++ b/tests/tests/media/decoder/src/android/media/decoder/cts/DecoderTestAacFormat.java
@@ -81,9 +81,9 @@
                         AudioFormat.CHANNEL_OUT_QUAD | AudioFormat.CHANNEL_OUT_FRONT_CENTER},
                 {"noise_6ch_44khz_aot5_dr_sbr_sig2_mp4.m4a", 6, AudioFormat.CHANNEL_OUT_5POINT1},
         };
-
-        for (Object [] sample: samples) {
-            for (String codecName : DecoderTest.codecsFor((String)sample[0] /* resource */)) {
+        for (Object[] sample: samples) {
+            for (String codecName : DecoderTest.codecsFor((String)sample[0] /* resource */,
+                    DecoderTest.CODEC_DEFAULT)) {
                 // verify correct number of channels is observed without downmixing
                 AudioParameter chanParams = new AudioParameter();
                 decodeUpdateFormat(codecName, (String) sample[0] /*resource*/, chanParams,
diff --git a/tests/tests/permission/src/android/permission/cts/SafetyCenterUtils.kt b/tests/tests/permission/src/android/permission/cts/SafetyCenterUtils.kt
index f057b21..931ecd1 100644
--- a/tests/tests/permission/src/android/permission/cts/SafetyCenterUtils.kt
+++ b/tests/tests/permission/src/android/permission/cts/SafetyCenterUtils.kt
@@ -67,7 +67,7 @@
     @JvmStatic
     fun assertSafetyCenterStarted() {
         // CollapsingToolbar title can't be found by text, so using description instead.
-        waitFindObject(By.desc("Security & Privacy"))
+        waitFindObject(By.desc("Security & privacy"))
     }
 
     @JvmStatic
diff --git a/tests/tests/permission4/src/android/permission4/cts/CameraMicIndicatorsPermissionTest.kt b/tests/tests/permission4/src/android/permission4/cts/CameraMicIndicatorsPermissionTest.kt
index 598a59a..872a243 100644
--- a/tests/tests/permission4/src/android/permission4/cts/CameraMicIndicatorsPermissionTest.kt
+++ b/tests/tests/permission4/src/android/permission4/cts/CameraMicIndicatorsPermissionTest.kt
@@ -78,6 +78,8 @@
 private const val UNEXPECTED_TIMEOUT_MILLIS = 1000
 private const val TIMEOUT_MILLIS: Long = 20000
 private const val TV_MIC_INDICATOR_WINDOW_TITLE = "MicrophoneCaptureIndicator"
+private const val MIC_LABEL_NAME = "microphone_toggle_label_qs"
+private const val CAMERA_LABEL_NAME = "camera_toggle_label_qs"
 
 class CameraMicIndicatorsPermissionTest {
     private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
@@ -90,11 +92,9 @@
 
     private val isTv = packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK)
     private val isCar = packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)
+    private val micLabel = getPermissionControllerString(MIC_LABEL_NAME)
+    private val cameraLabel = getPermissionControllerString(CAMERA_LABEL_NAME)
     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 isScreenOn = false
     private var screenTimeoutBeforeTest: Long = 0L
 
@@ -520,4 +520,18 @@
             automatorMethod(remainingTime)
         }
     }
+
+    private fun getPermissionControllerString(resourceName: String): String {
+        val permissionControllerPkg = context.packageManager.permissionControllerPackageName
+        try {
+            val permissionControllerContext =
+                context.createPackageContext(permissionControllerPkg, 0)
+            val resourceId =
+                permissionControllerContext.resources.getIdentifier(
+                    resourceName, "string", "com.android.permissioncontroller")
+            return permissionControllerContext.getString(resourceId)
+        } catch (e: PackageManager.NameNotFoundException) {
+            throw RuntimeException(e)
+        }
+    }
 }
\ No newline at end of file
diff --git a/tests/tests/permission5/src/android/permission5/cts/RuntimePermissionsAppOpTrackingTest.kt b/tests/tests/permission5/src/android/permission5/cts/RuntimePermissionsAppOpTrackingTest.kt
index 8cff38a..67fa1bc 100644
--- a/tests/tests/permission5/src/android/permission5/cts/RuntimePermissionsAppOpTrackingTest.kt
+++ b/tests/tests/permission5/src/android/permission5/cts/RuntimePermissionsAppOpTrackingTest.kt
@@ -25,6 +25,7 @@
 import android.content.ContextParams
 import android.content.Intent
 import android.content.pm.PackageManager.FEATURE_LEANBACK
+import android.content.pm.PackageManager.FEATURE_TELEPHONY
 import android.net.Uri
 import android.os.Bundle
 import android.os.Process
@@ -44,6 +45,7 @@
 import com.google.common.truth.Truth.assertThat
 import org.junit.After
 import org.junit.Assume.assumeFalse
+import org.junit.Assume.assumeTrue
 import org.junit.Before
 import org.junit.Test
 import org.mockito.ArgumentMatcher
@@ -105,6 +107,7 @@
     @Throws(Exception::class)
     fun testSelfSmsAccess() {
         assumeNotTv()
+        assumeHasTelephony()
         testSelfAccess(Telephony.Sms.CONTENT_URI,
                 Manifest.permission.READ_SMS)
     }
@@ -178,6 +181,7 @@
     @Throws(Exception::class)
     fun testUntrustedSmsAccessAttributeToAnother() {
         assumeNotTv()
+        assumeHasTelephony()
         testUntrustedAccessAttributeToAnother(Telephony.Sms.CONTENT_URI,
                 Manifest.permission.READ_SMS)
     }
@@ -225,6 +229,7 @@
     @Throws(Exception::class)
     fun testUntrustedSmsAccessAttributeToAnotherThroughIntermediary() {
         assumeNotTv()
+        assumeHasTelephony()
         testUntrustedAccessAttributeToAnotherThroughIntermediary(
                 Telephony.Sms.CONTENT_URI,
                 Manifest.permission.READ_SMS)
@@ -323,6 +328,7 @@
     @Throws(Exception::class)
     fun testTrustedAccessSmsAttributeToAnother() {
         assumeNotTv()
+        assumeHasTelephony()
         testTrustedAccessAttributeToAnother(Telephony.Sms.CONTENT_URI,
                 Manifest.permission.READ_SMS)
     }
@@ -666,6 +672,7 @@
             get() = InstrumentationRegistry.getInstrumentation()
 
         private val isTv = context.packageManager.hasSystemFeature(FEATURE_LEANBACK)
+        private val isTel = context.packageManager.hasSystemFeature(FEATURE_TELEPHONY)
 
         fun ensureAuxiliaryAppsNotRunningAndNoResidualProcessState() {
             SystemUtil.runShellCommand("am force-stop $RECEIVER_PACKAGE_NAME")
@@ -1178,5 +1185,6 @@
         }
 
         private fun assumeNotTv() = assumeFalse(isTv)
+        private fun assumeHasTelephony() = assumeTrue(isTel)
     }
 }
diff --git a/tests/tests/preference/src/android/preference/cts/PreferenceActivityLegacyFlowTest.java b/tests/tests/preference/src/android/preference/cts/PreferenceActivityLegacyFlowTest.java
index 29cf672..782f30c 100644
--- a/tests/tests/preference/src/android/preference/cts/PreferenceActivityLegacyFlowTest.java
+++ b/tests/tests/preference/src/android/preference/cts/PreferenceActivityLegacyFlowTest.java
@@ -103,7 +103,8 @@
     }
 
     private void assertScreenshotsAreEqual(Bitmap before, Bitmap after) {
-        assertTrue("Screenshots do not match!", BitmapUtils.compareBitmaps(before, after));
+        // TODO(b/227553681): remove the precision=0.99 arg so it does a pixel-by-pixel check
+        assertTrue("Screenshots do not match!", BitmapUtils.compareBitmaps(before, after, 0.99));
     }
 
     private void assertTextShown(String text) {
diff --git a/tests/tests/security/src/android/security/cts/LocationDisabledAppOpsTest.java b/tests/tests/security/src/android/security/cts/LocationDisabledAppOpsTest.java
new file mode 100644
index 0000000..c6b7e35
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/LocationDisabledAppOpsTest.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts;
+
+import static android.app.AppOpsManager.MODE_ALLOWED;
+import static android.app.AppOpsManager.OPSTR_FINE_LOCATION;
+
+import static com.android.compatibility.common.util.SystemUtil.eventually;
+import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
+
+import android.app.ActivityManager;
+import android.app.AppOpsManager;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.location.LocationManager;
+import android.os.PackageTagsList;
+import android.os.Process;
+import android.os.UserHandle;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RunWith(AndroidJUnit4.class)
+public class LocationDisabledAppOpsTest extends StsExtraBusinessLogicTestCase {
+
+    private final Context mContext = InstrumentationRegistry.getContext();
+    private LocationManager mLm;
+    private AppOpsManager mAom;
+
+    @Before
+    public void setUp() {
+        mLm = mContext.getSystemService(LocationManager.class);
+        mAom = mContext.getSystemService(AppOpsManager.class);
+    }
+
+    @Test
+    @AsbSecurityTest(cveBugId = 231496105)
+    public void testLocationAppOpIsIgnoredForAppsWhenLocationIsDisabled() {
+        PackageTagsList ignoreList = mLm.getIgnoreSettingsAllowlist();
+
+        UserHandle[] userArr = {UserHandle.SYSTEM};
+        runWithShellPermissionIdentity(() -> {
+            userArr[0] = UserHandle.of(ActivityManager.getCurrentUser());
+        });
+
+        UserHandle user = userArr[0];
+
+        boolean wasEnabled = mLm.isLocationEnabledForUser(user);
+
+        try {
+            runWithShellPermissionIdentity(() -> {
+                mLm.setLocationEnabledForUser(false, user);
+            });
+            List<PackageInfo> pkgs =
+                    mContext.getPackageManager().getInstalledPackagesAsUser(
+                            0, user.getIdentifier());
+
+            eventually(() -> {
+                List<String> bypassedNoteOps = new ArrayList<>();
+                List<String> bypassedCheckOps = new ArrayList<>();
+                for (PackageInfo pi : pkgs) {
+                    ApplicationInfo ai = pi.applicationInfo;
+                    if (ai.uid != Process.SYSTEM_UID) {
+                        final int[] mode = {MODE_ALLOWED};
+                        runWithShellPermissionIdentity(() -> {
+                            mode[0] = mAom.noteOpNoThrow(
+                                    OPSTR_FINE_LOCATION, ai.uid, ai.packageName);
+                        });
+                        if (mode[0] == MODE_ALLOWED && !ignoreList.containsAll(pi.packageName)) {
+                            bypassedNoteOps.add(pi.packageName);
+                        }
+
+
+                        mode[0] = MODE_ALLOWED;
+                        runWithShellPermissionIdentity(() -> {
+                            mode[0] = mAom
+                                    .checkOpNoThrow(OPSTR_FINE_LOCATION, ai.uid, ai.packageName);
+                        });
+                        if (mode[0] == MODE_ALLOWED && !ignoreList.includes(pi.packageName)) {
+                            bypassedCheckOps.add(pi.packageName);
+                        }
+
+                    }
+                }
+
+                String msg = "";
+                if (!bypassedNoteOps.isEmpty()) {
+                    msg += "Apps which still have access from noteOp " + bypassedNoteOps;
+                }
+                if (!bypassedCheckOps.isEmpty()) {
+                    msg += (msg.isEmpty() ? "" : "\n\n")
+                            +  "Apps which still have access from checkOp " + bypassedCheckOps;
+                }
+                if (!msg.isEmpty()) {
+                    Assert.fail(msg);
+                }
+            });
+        } finally {
+            runWithShellPermissionIdentity(() -> {
+                mLm.setLocationEnabledForUser(wasEnabled, user);
+            });
+        }
+    }
+
+}
+
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ExactCanvasTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ExactCanvasTests.java
index 7d73da9..f00f0b1 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ExactCanvasTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ExactCanvasTests.java
@@ -125,6 +125,8 @@
                     canvas.drawColor(Color.WHITE);
                     p.setColor(Color.BLACK);
                     p.setAntiAlias(false);
+                    // ensure the lines do not hit pixel edges
+                    canvas.translate(0.05f, 0.05f);
                     float[] pts = {
                             0, 0, 80, 80, 80, 0, 0, 80, 40, 50, 60, 50
                     };
diff --git a/tests/tests/wifi/src/android/net/wifi/cts/ConcurrencyTest.java b/tests/tests/wifi/src/android/net/wifi/cts/ConcurrencyTest.java
index f7322dd..464fb4c 100644
--- a/tests/tests/wifi/src/android/net/wifi/cts/ConcurrencyTest.java
+++ b/tests/tests/wifi/src/android/net/wifi/cts/ConcurrencyTest.java
@@ -274,6 +274,29 @@
                 new LinkedList<Integer>(Arrays.asList(waitSingleSync)));
     }
 
+    private NetworkInfo.DetailedState waitForNextNetworkState() {
+        assertTrue(waitForBroadcasts(MySync.NETWORK_INFO));
+        assertNotNull(mMySync.expectedNetworkInfo);
+        return mMySync.expectedNetworkInfo.getDetailedState();
+    }
+
+    private boolean waitForConnectedNetworkState() {
+        // The possible orders of network states are:
+        // * IDLE > CONNECTING > CONNECTED for lazy initialization
+        // * DISCONNECTED > CONNECTING > CONNECTED for previous group removal
+        // * CONNECTING > CONNECTED
+        NetworkInfo.DetailedState state = waitForNextNetworkState();
+        if (state == NetworkInfo.DetailedState.IDLE
+                || state == NetworkInfo.DetailedState.DISCONNECTED) {
+            state = waitForNextNetworkState();
+        }
+        if (state != NetworkInfo.DetailedState.CONNECTING) {
+            return false;
+        }
+        state = waitForNextNetworkState();
+        return state == NetworkInfo.DetailedState.CONNECTED;
+    }
+
     private boolean waitForServiceResponse(MyResponse waitResponse) {
         synchronized (waitResponse) {
             long timeout = System.currentTimeMillis() + TIMEOUT_MSEC;
@@ -508,21 +531,7 @@
         mWifiP2pManager.createGroup(mWifiP2pChannel, mActionListener);
         assertTrue(waitForServiceResponse(mMyResponse));
         assertTrue(mMyResponse.success);
-
-        // The first network state might be IDLE due to
-        // lazy initialization, but not CONNECTED.
-        for (int i = 0; i < 2; i++) {
-            assertTrue(waitForBroadcasts(MySync.NETWORK_INFO));
-            assertNotNull(mMySync.expectedNetworkInfo);
-            if (NetworkInfo.DetailedState.CONNECTED ==
-                    mMySync.expectedNetworkInfo.getDetailedState()) {
-                break;
-            }
-            assertEquals(NetworkInfo.DetailedState.IDLE,
-                    mMySync.expectedNetworkInfo.getDetailedState());
-        }
-        assertEquals(NetworkInfo.DetailedState.CONNECTED,
-                mMySync.expectedNetworkInfo.getDetailedState());
+        assertTrue(waitForConnectedNetworkState());
 
         resetResponse(mMyResponse);
         mWifiP2pManager.requestNetworkInfo(mWifiP2pChannel,
@@ -660,21 +669,7 @@
         mWifiP2pManager.createGroup(mWifiP2pChannel, mActionListener);
         assertTrue(waitForServiceResponse(mMyResponse));
         assertTrue(mMyResponse.success);
-
-        // The first network state might be IDLE due to
-        // lazy initialization, but not CONNECTED.
-        for (int i = 0; i < 2; i++) {
-            assertTrue(waitForBroadcasts(MySync.NETWORK_INFO));
-            assertNotNull(mMySync.expectedNetworkInfo);
-            if (NetworkInfo.DetailedState.CONNECTED ==
-                    mMySync.expectedNetworkInfo.getDetailedState()) {
-                break;
-            }
-            assertEquals(NetworkInfo.DetailedState.IDLE,
-                    mMySync.expectedNetworkInfo.getDetailedState());
-        }
-        assertEquals(NetworkInfo.DetailedState.CONNECTED,
-                mMySync.expectedNetworkInfo.getDetailedState());
+        assertTrue(waitForConnectedNetworkState());
 
         resetResponse(mMyResponse);
         mWifiP2pManager.removeGroup(mWifiP2pChannel, mActionListener);
@@ -707,10 +702,7 @@
         mWifiP2pManager.createGroup(mWifiP2pChannel, mActionListener);
         assertTrue(waitForServiceResponse(mMyResponse));
         assertTrue(mMyResponse.success);
-        assertTrue(waitForBroadcasts(MySync.NETWORK_INFO));
-        assertNotNull(mMySync.expectedNetworkInfo);
-        assertEquals(NetworkInfo.DetailedState.CONNECTED,
-                mMySync.expectedNetworkInfo.getDetailedState());
+        assertTrue(waitForConnectedNetworkState());
 
         resetResponse(mMyResponse);
         mWifiP2pManager.removeGroup(mWifiP2pChannel, mActionListener);
@@ -812,21 +804,7 @@
         mWifiP2pManager.createGroup(mWifiP2pChannel, mActionListener);
         assertTrue(waitForServiceResponse(mMyResponse));
         assertTrue(mMyResponse.success);
-
-        // The first network state might be IDLE due to
-        // lazy initialization, but not CONNECTED.
-        for (int i = 0; i < 2; i++) {
-            assertTrue(waitForBroadcasts(MySync.NETWORK_INFO));
-            assertNotNull(mMySync.expectedNetworkInfo);
-            if (NetworkInfo.DetailedState.CONNECTED
-                    == mMySync.expectedNetworkInfo.getDetailedState()) {
-                break;
-            }
-            assertEquals(NetworkInfo.DetailedState.IDLE,
-                    mMySync.expectedNetworkInfo.getDetailedState());
-        }
-        assertEquals(NetworkInfo.DetailedState.CONNECTED,
-                mMySync.expectedNetworkInfo.getDetailedState());
+        assertTrue(waitForConnectedNetworkState());
 
         resetResponse(mMyResponse);
         MacAddress peerMacAddress = MacAddress.fromString(mTestWifiP2pPeerConfig.deviceAddress);