Merge "Update test instructions for Device Owner Test / Disallow remove user." into rvc-dev am: ba909412dc

Original change: https://googleplex-android-review.googlesource.com/c/platform/cts/+/11833768

Change-Id: Ifd85e68778f1fe31c615c614412276bc7090c7e9
diff --git a/apps/CameraITS/Android.mk b/apps/CameraITS/Android.mk
index 8f7ed7c..b0cabc7 100644
--- a/apps/CameraITS/Android.mk
+++ b/apps/CameraITS/Android.mk
@@ -13,6 +13,8 @@
 # limitations under the License.
 #
 
+LOCAL_PATH := $(call my-dir)
+
 its-dir-name := CameraITS
 its-dir := $(HOST_OUT)/$(its-dir-name)
 its-build-stamp := $(its-dir)/build_stamp
@@ -21,11 +23,11 @@
 
 .PHONY: camera-its
 
-$(its-dir): $(its-build-stamp)
-
-$(its-build-stamp): $(ACP)
-	echo $(its_dir)
-	mkdir -p $(its-dir)
-	$(ACP) -rfp cts/apps/$(its-dir-name)/* $(its-dir)
-	rm $(its-dir)/Android.mk
+$(its-build-stamp): PRIVATE_PATH := $(LOCAL_PATH)
+$(its-build-stamp): PRIVATE_OUT := $(its-dir)
+$(its-build-stamp): $(ACP) $(call find-files-in-subdirs,.,*,$(LOCAL_PATH))
+	rm -rf $(PRIVATE_OUT)
+	mkdir -p $(PRIVATE_OUT)
+	$(ACP) -rfp $(PRIVATE_PATH)/* $(PRIVATE_OUT)/
+	rm $(PRIVATE_OUT)/Android.mk
 	touch $@
diff --git a/apps/CameraITS/tests/scene1_1/test_multi_camera_match.py b/apps/CameraITS/tests/scene1_1/test_multi_camera_match.py
index 2429837..5aa8620 100644
--- a/apps/CameraITS/tests/scene1_1/test_multi_camera_match.py
+++ b/apps/CameraITS/tests/scene1_1/test_multi_camera_match.py
@@ -47,8 +47,7 @@
             if i == ids[0]:  # get_available_output_sizes returns sorted list
                 yuv_match_sizes = yuv_sizes[i]
             else:
-                yuv_match_sizes = list(
-                        set(yuv_sizes[i]).intersection(yuv_match_sizes))
+                list(set(yuv_sizes[i]).intersection(yuv_match_sizes))
 
         # find matched size for captures
         yuv_match_sizes.sort()
diff --git a/apps/CtsVerifier/Android.mk b/apps/CtsVerifier/Android.mk
index a7651b6..c22e03d 100644
--- a/apps/CtsVerifier/Android.mk
+++ b/apps/CtsVerifier/Android.mk
@@ -172,7 +172,7 @@
 #	$(hide) $(ACP) -fp cts/apps/CtsVerifier/assets/scripts/execute_power_tests.py $@
 
 cts : $(verifier-zip)
-$(verifier-zip) : $(HOST_OUT)/CameraITS
+$(verifier-zip) : $(HOST_OUT)/CameraITS/build_stamp
 $(verifier-zip) : $(foreach app,$(apps-to-include),$(call apk-location-for,$(app)))
 $(verifier-zip) : $(call intermediates-dir-for,APPS,CtsVerifier)/package.apk | $(ACP)
 		$(hide) mkdir -p $(verifier-dir)
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index 14bbc39..38ab02a 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -209,7 +209,7 @@
                 <category android:name="android.cts.intent.category.MANUAL_TEST" />
             </intent-filter>
             <meta-data android:name="test_category" android:value="@string/test_category_device_admin" />
-            <meta-data android:name="test_excluded_features" android:value="android.hardware.type.automotive:android.software.lockscreen_disabled" />
+            <meta-data android:name="test_excluded_features" android:value="android.hardware.type.automotive:android.hardware.type.television:android.software.lockscreen_disabled" />
             <meta-data android:name="test_required_features"
                     android:value="android.software.device_admin" />
         </activity>
@@ -4295,6 +4295,32 @@
                 android:value="config_voice_capable"/>
         </activity>
 
+        <activity android:name=".telecom.TelecomDefaultDialerTestActivity"
+                  android:label="@string/telecom_default_dialer_test_title">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.cts.intent.category.MANUAL_TEST" />
+            </intent-filter>
+
+            <meta-data
+                android:name="test_category"
+                android:value="@string/test_category_telecom"/>
+            <meta-data
+                android:name="test_required_features"
+                android:value="android.hardware.telephony"/>
+            <meta-data
+                android:name="test_required_configs"
+                android:value="config_voice_capable"/>
+        </activity>
+
+        <activity android:name=".telecom.CtsVerifierInCallUi"
+                  android:label="@string/telecom_in_call_ui_label">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.cts.intent.category.MANUAL_TEST" />
+            </intent-filter>
+        </activity>
+
         <activity android:name=".managedprovisioning.LockscreenMessageTestActivity"
             android:label="@string/device_owner_customize_lockscreen_message" />
 
diff --git a/apps/CtsVerifier/jni/audio_loopback/Android.bp b/apps/CtsVerifier/jni/audio_loopback/Android.bp
index 29b7e13..ad09fb5 100644
--- a/apps/CtsVerifier/jni/audio_loopback/Android.bp
+++ b/apps/CtsVerifier/jni/audio_loopback/Android.bp
@@ -8,6 +8,7 @@
         "frameworks/av/media/ndk/include",
         "system/core/include/cutils",
     ],
+    header_libs: ["jni_headers"],
     shared_libs: [
         "libaaudio",
         "liblog",
@@ -17,6 +18,8 @@
     cflags: [
         "-Werror",
         "-Wall",
+        // For slCreateEngine
+        "-Wno-deprecated",
     ],
     sdk_version: "current",
 }
diff --git a/apps/CtsVerifier/jni/midi/Android.bp b/apps/CtsVerifier/jni/midi/Android.bp
index f437360..0928406 100644
--- a/apps/CtsVerifier/jni/midi/Android.bp
+++ b/apps/CtsVerifier/jni/midi/Android.bp
@@ -25,6 +25,7 @@
         "frameworks/av/media/ndk/include",
         "system/core/include/cutils",
     ],
+    header_libs: ["jni_headers"],
     sdk_version: "current",
     stl: "libc++_static",
     shared_libs: [
diff --git a/apps/CtsVerifier/jni/verifier/Android.bp b/apps/CtsVerifier/jni/verifier/Android.bp
index e34e86f..b5665a9 100644
--- a/apps/CtsVerifier/jni/verifier/Android.bp
+++ b/apps/CtsVerifier/jni/verifier/Android.bp
@@ -22,6 +22,7 @@
     ],
     sdk_version: "current",
     stl: "libc++_static",
+    header_libs: ["jni_headers"],
     shared_libs: ["liblog"],
     cflags: [
         "-Wall",
diff --git a/apps/CtsVerifier/res/layout/incall_screen.xml b/apps/CtsVerifier/res/layout/incall_screen.xml
new file mode 100644
index 0000000..1f5fba6
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/incall_screen.xml
@@ -0,0 +1,41 @@
+<!--
+  ~ Copyright (C) 2020 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<ScrollView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content">
+
+    <LinearLayout
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content">
+        <TextView
+            android:id="@+id/incoming_call_number"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content">
+        </TextView>
+
+        <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_centerInParent="true"
+            android:id="@+id/telecom_default_dialer_end_button"
+            android:text="@string/telecom_default_dialer_end_button">
+        </Button>
+    </LinearLayout>
+</ScrollView>
\ No newline at end of file
diff --git a/apps/CtsVerifier/res/layout/telecom_default_dialer.xml b/apps/CtsVerifier/res/layout/telecom_default_dialer.xml
new file mode 100644
index 0000000..8fb53d0
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/telecom_default_dialer.xml
@@ -0,0 +1,174 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<ScrollView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content">
+    <LinearLayout
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content">
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/telecom_default_dialer_test_info"/>
+
+        <RelativeLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="@dimen/js_padding"
+            android:layout_marginBottom="@dimen/js_padding">
+
+            <ImageView
+                android:id="@+id/step_1_status"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:src="@drawable/fs_indeterminate"
+                android:layout_marginRight="@dimen/js_padding"
+                android:layout_alignParentStart="true"
+                android:layout_alignParentTop="true" />
+            <TextView
+                android:id="@+id/step_1_instructions"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/telecom_default_dialer_step_1"
+                android:textSize="16dp"
+                android:layout_alignParentRight="true"
+                android:layout_alignParentTop="true"
+                android:layout_toRightOf="@id/step_1_status" />
+            <Button
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentRight="true"
+                android:layout_below="@id/step_1_instructions"
+                android:layout_marginLeft="20dip"
+                android:layout_marginRight="20dip"
+                android:layout_toRightOf="@id/step_1_status"
+                android:id="@+id/telecom_default_dialer_set_third_party_dialer_button"
+                android:text="@string/telecom_default_dialer_set_third_party_dialer_button"/>
+        </RelativeLayout>
+
+        <RelativeLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="@dimen/js_padding"
+            android:layout_marginBottom="@dimen/js_padding">
+
+            <ImageView
+                android:id="@+id/step_2_status"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:src="@drawable/fs_indeterminate"
+                android:layout_marginRight="@dimen/js_padding"
+                android:layout_alignParentStart="true"
+                android:layout_alignParentTop="true" />
+            <TextView
+                android:id="@+id/step_2_instructions"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/telecom_default_dialer_step_2"
+                android:textSize="16dp"
+                android:layout_alignParentRight="true"
+                android:layout_alignParentTop="true"
+                android:layout_toRightOf="@id/step_2_status" />
+            <Button
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentRight="true"
+                android:layout_below="@id/step_2_instructions"
+                android:layout_marginLeft="20dip"
+                android:layout_marginRight="20dip"
+                android:layout_toRightOf="@id/step_2_status"
+                android:id="@+id/telecom_confirm_lock_screen"
+                android:text="@string/telecom_confirm_lock_screen"/>
+        </RelativeLayout>
+
+        <RelativeLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="@dimen/js_padding"
+            android:layout_marginBottom="@dimen/js_padding">
+
+            <ImageView
+                android:id="@+id/step_3_status"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:src="@drawable/fs_indeterminate"
+                android:layout_marginRight="@dimen/js_padding"
+                android:layout_alignParentStart="true"
+                android:layout_alignParentTop="true" />
+            <TextView
+                android:id="@+id/step_3_instructions"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/telecom_default_dialer_step_3"
+                android:textSize="16dp"
+                android:layout_alignParentRight="true"
+                android:layout_alignParentTop="true"
+                android:layout_toRightOf="@id/step_3_status" />
+            <Button
+                android:id="@+id/telecom_default_dialer_lock_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_below="@id/step_3_instructions"
+                android:layout_marginLeft="20dip"
+                android:layout_marginRight="20dip"
+                android:layout_toRightOf="@id/step_3_status"
+                android:text="@string/telecom_default_dialer_lock_button"/>
+        </RelativeLayout>
+
+        <RelativeLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="@dimen/js_padding"
+            android:layout_marginBottom="@dimen/js_padding">
+
+            <ImageView
+                android:id="@+id/step_4_status"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:src="@drawable/fs_indeterminate"
+                android:layout_marginRight="@dimen/js_padding"
+                android:layout_alignParentStart="true"
+                android:layout_alignParentTop="true" />
+            <TextView
+                android:id="@+id/step_4_instructions"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/telecom_default_dialer_step_4"
+                android:textSize="16dp"
+                android:layout_alignParentRight="true"
+                android:layout_alignParentTop="true"
+                android:layout_toRightOf="@id/step_4_status" />
+            <Button
+                android:id="@+id/telecom_default_dialer_confirm_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentRight="true"
+                android:layout_below="@id/step_4_instructions"
+                android:layout_marginLeft="20dip"
+                android:layout_marginRight="20dip"
+                android:layout_toRightOf="@id/step_4_status"
+                android:text="@string/telecom_default_dialer_confirm_button"/>
+        </RelativeLayout>
+
+        <include layout="@layout/pass_fail_buttons" />
+    </LinearLayout>
+</ScrollView>
\ No newline at end of file
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index b898bc9..2308863 100755
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -5435,6 +5435,33 @@
         UI when prompted.
     </string>
     <string name="telecom_incoming_self_mgd_place_call_button">Start Self-Managed Call</string>
+    <string name="telecom_default_dialer_test_title">Default Dialer Test</string>
+    <string name="telecom_default_dialer_test_info">
+        This test verifies that a third party dialer can show an incoming call screen when the
+        device is locked.
+    </string>
+    <string name="telecom_default_dialer_step_1">
+        Click the button below to set CtsVerifier as the default dialer.
+    </string>
+    <string name="telecom_default_dialer_set_third_party_dialer_button">
+        Set third party dialer
+    </string>
+    <string name="telecom_default_dialer_step_2">
+        Click the button to make sure that this phone is secured with a lock screen.
+    </string>
+    <string name="telecom_confirm_lock_screen">Confirm lock screen</string>
+    <string name="telecom_default_dialer_step_3">
+        Click the button below to lock the phone and then call this device. Answer the incoming call
+        in the UI when prompted without unlock the phone.
+    </string>
+    <string name="telecom_default_dialer_lock_button">Lock phone and dail</string>
+    <string name="telecom_default_dialer_step_4">
+        Click the button below to confirm that the ongoing incoming call was answered when the
+        device is locked.
+    </string>
+    <string name="telecom_default_dialer_end_button">End call and confirm</string>
+    <string name="telecom_default_dialer_confirm_button">Confirm</string>
+    <string name="telecom_in_call_ui_label">CtsVerifierInCallUi</string>
     <!-- Strings for SetNewPasswordComplexityTest -->
     <string name="set_complexity_test_title">Set New Password Complexity Test</string>
     <string name="set_complexity_test_message">
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/admin/OWNERS b/apps/CtsVerifier/src/com/android/cts/verifier/admin/OWNERS
new file mode 100644
index 0000000..79d60e5
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/admin/OWNERS
@@ -0,0 +1,5 @@
+# Bug template url: https://b.corp.google.com/issues/new?component=100560&template=63204
+alexkershaw@google.com
+eranm@google.com
+rubinxu@google.com
+sandness@google.com
\ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/admin/tapjacking/OWNERS b/apps/CtsVerifier/src/com/android/cts/verifier/admin/tapjacking/OWNERS
new file mode 100644
index 0000000..e303d2b
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/admin/tapjacking/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 142675
+set noparent
+suprabh@google.com
\ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/OWNERS b/apps/CtsVerifier/src/com/android/cts/verifier/audio/OWNERS
new file mode 100644
index 0000000..eb8de3b
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 48436
+elaurent@google.com
+pmclean@google.com
+philburk@google.com
+per-file HifiUltrasound*.java = xlythe@google.com
\ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/OWNERS b/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/OWNERS
new file mode 100644
index 0000000..d791f40
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/OWNERS
@@ -0,0 +1,6 @@
+# Bug component: 114777
+curtislb@google.com
+ilyamaty@google.com
+jaggies@google.com
+joshmccloskey@google.com
+kchyn@google.com
\ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/OWNERS b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/OWNERS
new file mode 100644
index 0000000..52531aa
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 27441
+zachoverflow@google.com
\ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/OWNERS b/apps/CtsVerifier/src/com/android/cts/verifier/camera/OWNERS
new file mode 100644
index 0000000..8ebd7b8
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 41727
+include platform/frameworks/av:/camera/OWNER
\ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/companion/OWNERS b/apps/CtsVerifier/src/com/android/cts/verifier/companion/OWNERS
new file mode 100644
index 0000000..8e3d9b9
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/companion/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 24950
+eugenesusla@google.com
\ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/deskclock/OWNERS b/apps/CtsVerifier/src/com/android/cts/verifier/deskclock/OWNERS
new file mode 100644
index 0000000..78b6baa
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/deskclock/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 31568
+jplemieux@google.com
\ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/dialer/DialerCallTestService.java b/apps/CtsVerifier/src/com/android/cts/verifier/dialer/DialerCallTestService.java
index add6119..d608306 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/dialer/DialerCallTestService.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/dialer/DialerCallTestService.java
@@ -22,7 +22,11 @@
 import java.util.Observable;
 import android.telecom.Call;
 
+import com.android.cts.verifier.telecom.CtsIncomingCall;
+import com.android.cts.verifier.telecom.CtsVerifierInCallUi;
+
 public class DialerCallTestService extends InCallService {
+  public static final String EXTRA_CALL_NAME = "incoming_call_name";
 
   private static DialerCallTestServiceObservable sObservable =
       new DialerCallTestServiceObservable();
@@ -54,6 +58,14 @@
   public void onCallAdded(Call call) {
     if (call.getState() == Call.STATE_RINGING) {
       getObservable().setOnIncoming(true);
+      CtsIncomingCall.getInstance().setCall(call);
+      Intent intent = new Intent(Intent.ACTION_MAIN);
+      if (call.getDetails().getHandle() != null) {
+        intent.putExtra(EXTRA_CALL_NAME, call.getDetails().getHandle().getSchemeSpecificPart());
+      }
+      intent.setFlags(Intent.FLAG_ACTIVITY_NO_USER_ACTION | Intent.FLAG_ACTIVITY_NEW_TASK);
+      intent.setClass(this, CtsVerifierInCallUi.class);
+      startActivity(intent);
     }
   }
 }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/dialer/OWNERS b/apps/CtsVerifier/src/com/android/cts/verifier/dialer/OWNERS
new file mode 100644
index 0000000..a7c1795
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/dialer/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 20868
+tgunn@google.com
+breadley@google.com
+hallliu@google.com
+xiaotonj@google.com
\ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/forcestop/OWNERS b/apps/CtsVerifier/src/com/android/cts/verifier/forcestop/OWNERS
new file mode 100644
index 0000000..12c917b
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/forcestop/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 533114
+suprabh@google.com
\ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/instantapps/OWNERS b/apps/CtsVerifier/src/com/android/cts/verifier/instantapps/OWNERS
new file mode 100644
index 0000000..869f601
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/instantapps/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 187788
+dimuthu@google.com
+leegao@google.com
\ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/location/OWNERS b/apps/CtsVerifier/src/com/android/cts/verifier/location/OWNERS
new file mode 100644
index 0000000..b6377b0
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/location/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 32850
+wyattriley@google.com
+yuhany@google.com
\ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/OWNERS b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/OWNERS
new file mode 100644
index 0000000..79d60e5
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/OWNERS
@@ -0,0 +1,5 @@
+# Bug template url: https://b.corp.google.com/issues/new?component=100560&template=63204
+alexkershaw@google.com
+eranm@google.com
+rubinxu@google.com
+sandness@google.com
\ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/net/OWNERS b/apps/CtsVerifier/src/com/android/cts/verifier/net/OWNERS
new file mode 100644
index 0000000..733502a
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/net/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 31808
+lorenzo@google.com
+satk@google.com
\ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/OWNERS b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/OWNERS
new file mode 100644
index 0000000..ea76354
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 48448
+alisher@google.com
\ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/OWNERS b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/OWNERS
new file mode 100644
index 0000000..fec5943
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 34005
+juliacr@google.com
\ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/p2p/OWNERS b/apps/CtsVerifier/src/com/android/cts/verifier/p2p/OWNERS
index 008649d..2d23926 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/p2p/OWNERS
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/p2p/OWNERS
@@ -1,3 +1,5 @@
+# Bug component: 109606
 etancohen@google.com
 mplass@google.com
+rpius@google.com
 satk@google.com
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/qstiles/OWNERS b/apps/CtsVerifier/src/com/android/cts/verifier/qstiles/OWNERS
new file mode 100644
index 0000000..cbc5f31
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/qstiles/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 78930
+juliacr@google.com
+kozynski@google.com
\ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/OWNERS b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/OWNERS
new file mode 100644
index 0000000..e9e78a3
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 62965
+bduddie@google.com
+stange@google.com
+arthuri@google.com
\ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/streamquality/OWNERS b/apps/CtsVerifier/src/com/android/cts/verifier/streamquality/OWNERS
new file mode 100644
index 0000000..239d32e
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/streamquality/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 610698
+andrewlewis@google.com
+lajos@google.com
\ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/telecom/CtsIncomingCall.java b/apps/CtsVerifier/src/com/android/cts/verifier/telecom/CtsIncomingCall.java
new file mode 100644
index 0000000..1e472a4
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/telecom/CtsIncomingCall.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.verifier.telecom;
+
+import android.telecom.Call;
+
+public class CtsIncomingCall {
+    private static final CtsIncomingCall INSTANCE = new CtsIncomingCall();
+    private Call mCall;
+    private boolean mAcceptWhenLocked;
+
+    public static CtsIncomingCall getInstance() {
+        return INSTANCE;
+    }
+
+    public void setCall(Call call) {
+        mCall = call;
+        mAcceptWhenLocked = false;
+    }
+
+    public void disconnectCall() {
+        if (mCall != null) {
+            mCall.disconnect();
+            mCall = null;
+        }
+    }
+
+    public void setAcceptWhenLocked(boolean acceptWhenLocked) {
+        if (mCall != null) {
+            mAcceptWhenLocked = acceptWhenLocked;
+        }
+    }
+
+    public boolean isAcceptWhenLocked() {
+        return mAcceptWhenLocked;
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/telecom/CtsVerifierInCallUi.java b/apps/CtsVerifier/src/com/android/cts/verifier/telecom/CtsVerifierInCallUi.java
new file mode 100644
index 0000000..298eae0
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/telecom/CtsVerifierInCallUi.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.verifier.telecom;
+
+import static com.android.cts.verifier.dialer.DialerCallTestService.EXTRA_CALL_NAME;
+
+import android.app.Activity;
+import android.app.KeyguardManager;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
+import android.widget.TextView;
+
+import com.android.cts.verifier.R;
+
+public class CtsVerifierInCallUi extends Activity {
+    TextView mCallNumber;
+    Button mButton;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        View view = getLayoutInflater().inflate(R.layout.incall_screen, null);
+        setContentView(view);
+        setTurnScreenOn(true);
+        setShowWhenLocked(true);
+        KeyguardManager km = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
+        km.requestDismissKeyguard(this, null);
+
+        mCallNumber = view.findViewById(R.id.incoming_call_number);
+        if (mCallNumber == null) {
+            finish();
+            return;
+        }
+
+        mButton = view.findViewById(R.id.telecom_default_dialer_end_button);
+        if (mButton == null) {
+            finish();
+            return;
+        }
+
+        mCallNumber.setText(getIntent().getStringExtra(EXTRA_CALL_NAME));
+        mButton.setOnClickListener(v -> {
+            boolean pass = false;
+            if (km.isDeviceLocked()) {
+                pass = true;
+            }
+            CtsIncomingCall.getInstance().setAcceptWhenLocked(pass);
+            CtsIncomingCall.getInstance().disconnectCall();
+            finish();
+        });
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/telecom/OWNERS b/apps/CtsVerifier/src/com/android/cts/verifier/telecom/OWNERS
new file mode 100644
index 0000000..0cfd686
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/telecom/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 151185
+tgunn@google.com
\ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/telecom/TelecomDefaultDialerTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/telecom/TelecomDefaultDialerTestActivity.java
new file mode 100644
index 0000000..2e50d8a
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/telecom/TelecomDefaultDialerTestActivity.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.verifier.telecom;
+
+import android.app.KeyguardManager;
+import android.app.admin.DevicePolicyManager;
+import android.app.role.RoleManager;
+import android.content.Intent;
+import android.os.Bundle;
+import android.telecom.TelecomManager;
+import android.view.View;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.Toast;
+
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+import com.android.cts.verifier.managedprovisioning.DeviceAdminTestReceiver;
+
+public class TelecomDefaultDialerTestActivity extends PassFailButtons.Activity {
+    private Button mSetDefaultDialer;
+    private Button mConfirmLockScreen;
+    private Button mLockDevice;
+
+    private ImageView mStep1Status;
+    private ImageView mStep2Status;
+    private ImageView mStep3Status;
+    private ImageView mStep4Status;
+
+    private final String LOCK_SCREEN_ACTION = "com.android.settings.SETUP_LOCK_SCREEN";
+    private final int REQUEST_DIALER_ROLE = 1;
+    private final int REQUEST_LOCK_SCREEN = 2;
+    private final int REQUEST_ADD_ADMIN = 3;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        View view = getLayoutInflater().inflate(R.layout.telecom_default_dialer, null);
+        setContentView(view);
+        setInfoResources(R.string.telecom_default_dialer_test_title,
+                R.string.telecom_default_dialer_test_info, -1);
+        setPassFailButtonClickListeners();
+        getPassButton().setEnabled(false);
+
+        mSetDefaultDialer = view.findViewById(
+                R.id.telecom_default_dialer_set_third_party_dialer_button);
+        if (mSetDefaultDialer == null) {
+            finish();
+            return;
+        }
+
+        mConfirmLockScreen = view.findViewById(
+                R.id.telecom_confirm_lock_screen);
+        if (mConfirmLockScreen == null) {
+            finish();
+            return;
+        }
+
+        mLockDevice = view.findViewById(
+                R.id.telecom_default_dialer_lock_button);
+        if (mLockDevice == null) {
+            finish();
+            return;
+        }
+
+        mStep1Status = view.findViewById(R.id.step_1_status);
+        mStep2Status = view.findViewById(R.id.step_2_status);
+        mStep3Status = view.findViewById(R.id.step_3_status);
+        mStep4Status = view.findViewById(R.id.step_4_status);
+        mStep1Status.setImageResource(R.drawable.fs_indeterminate);
+        mStep2Status.setImageResource(R.drawable.fs_indeterminate);
+        mStep3Status.setImageResource(R.drawable.fs_indeterminate);
+        mStep3Status.setImageResource(R.drawable.fs_indeterminate);
+
+        mSetDefaultDialer.setOnClickListener(v -> {
+            RoleManager rm = (RoleManager) getSystemService(ROLE_SERVICE);
+            TelecomManager tm = (TelecomManager) getSystemService(TELECOM_SERVICE);
+            if (tm.getDefaultDialerPackage().equals(getPackageName())) {
+                Toast.makeText(this, R.string.voicemail_default_dialer_already_set,
+                        Toast.LENGTH_SHORT).show();
+                mStep1Status.setImageResource(R.drawable.fs_good);
+                return;
+            }
+            Intent intent = rm.createRequestRoleIntent(RoleManager.ROLE_DIALER);
+            startActivityForResult(intent, REQUEST_DIALER_ROLE);
+        });
+
+        mConfirmLockScreen.setOnClickListener(v -> {
+            KeyguardManager km = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
+            if (km.isKeyguardSecure()) {
+                mStep2Status.setImageResource(R.drawable.fs_good);
+                return;
+            }
+            Intent intent = new Intent(LOCK_SCREEN_ACTION);
+            startActivityForResult(intent, REQUEST_LOCK_SCREEN);
+        });
+
+        mLockDevice.setOnClickListener(v -> {
+            Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
+            intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN,
+                    DeviceAdminTestReceiver.getReceiverComponentName());
+            startActivityForResult(intent, REQUEST_ADD_ADMIN);
+        });
+    }
+
+    @Override
+    public void onActivityResult(int requestCode, int resultCode, Intent data) {
+        if (requestCode == REQUEST_DIALER_ROLE) {
+            if (resultCode == RESULT_OK) {
+                mStep1Status.setImageResource(R.drawable.fs_good);
+            } else {
+                mStep1Status.setImageResource(R.drawable.fs_error);
+            }
+        }
+        if (requestCode == REQUEST_LOCK_SCREEN) {
+            if (resultCode == RESULT_FIRST_USER) {
+                mStep2Status.setImageResource(R.drawable.fs_good);
+            } else {
+                mStep2Status.setImageResource(R.drawable.fs_error);
+            }
+        }
+        if (requestCode == REQUEST_ADD_ADMIN) {
+            if (resultCode == RESULT_OK) {
+                DevicePolicyManager dpm = (DevicePolicyManager)
+                        getSystemService(DEVICE_POLICY_SERVICE);
+                mStep3Status.setImageResource(R.drawable.fs_good);
+                dpm.lockNow();
+            } else {
+                mStep3Status.setImageResource(R.drawable.fs_error);
+            }
+        }
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        if (CtsIncomingCall.getInstance().isAcceptWhenLocked()) {
+            mStep4Status.setImageResource(R.drawable.fs_good);
+            getPassButton().setEnabled(true);
+        } else {
+            mStep4Status.setImageResource(R.drawable.fs_error);
+        }
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/OWNERS b/apps/CtsVerifier/src/com/android/cts/verifier/tv/OWNERS
new file mode 100644
index 0000000..f5d7374
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 105760
+nchalko@google.com
+per-file MicrophoneDeviceTestActivity.java = hoshi@google.com
\ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/DisplayModesTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/DisplayModesTestActivity.java
index 71cea14..b663801 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/DisplayModesTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/DisplayModesTestActivity.java
@@ -319,9 +319,8 @@
         }
 
         public void isEquivalentToAnyOf(final float refreshRatePrecision, Mode... modes) {
-            boolean found =
-                    Arrays.stream(modes)
-                            .anyMatch(mode -> mode.isEquivalent(actual(), refreshRatePrecision));
+            boolean found = Arrays.stream(modes)
+                    .anyMatch(mode -> mode.isEquivalent(actual(), refreshRatePrecision));
             if (!found) {
                 failWithActual("expected any of", Arrays.toString(modes));
             }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/usb/OWNERS b/apps/CtsVerifier/src/com/android/cts/verifier/usb/OWNERS
new file mode 100644
index 0000000..e176df9
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/usb/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 175220
+moltmann@google.com
\ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/vr/OWNERS b/apps/CtsVerifier/src/com/android/cts/verifier/vr/OWNERS
new file mode 100644
index 0000000..094362e
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/vr/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 345010
+santoscordon@google.com
+michaelwr@google.com
\ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/OWNERS b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/OWNERS
index 1848dfd..6ac1b8f 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/OWNERS
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/OWNERS
@@ -1,3 +1,5 @@
-rpius@google.com
+# Bug component: 33618
 etancohen@google.com
+mplass@google.com
+rpius@google.com
 satk@google.com
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/wifiaware/OWNERS b/apps/CtsVerifier/src/com/android/cts/verifier/wifiaware/OWNERS
index 4afc47f..d036b64 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/wifiaware/OWNERS
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/wifiaware/OWNERS
@@ -1,2 +1,5 @@
+# Bug component: 109581
 etancohen@google.com
-satk@google.com
\ No newline at end of file
+mplass@google.com
+rpius@google.com
+satk@google.com
diff --git a/common/device-side/util-axt/src/com/android/compatibility/common/util/CpuFeatures.java b/common/device-side/util-axt/src/com/android/compatibility/common/util/CpuFeatures.java
index 9360942..6ee08bb 100644
--- a/common/device-side/util-axt/src/com/android/compatibility/common/util/CpuFeatures.java
+++ b/common/device-side/util-axt/src/com/android/compatibility/common/util/CpuFeatures.java
@@ -46,14 +46,10 @@
 
     public static native boolean isArmCpu();
 
-    public static native boolean isMipsCpu();
-
     public static native boolean isX86Cpu();
 
     public static native boolean isArm64Cpu();
 
-    public static native boolean isMips64Cpu();
-
     public static native boolean isX86_64Cpu();
 
     public static native int getHwCaps();
diff --git a/common/device-side/util-axt/src/com/android/compatibility/common/util/DropBoxReceiver.java b/common/device-side/util-axt/src/com/android/compatibility/common/util/DropBoxReceiver.java
new file mode 100644
index 0000000..6de6fe2
--- /dev/null
+++ b/common/device-side/util-axt/src/com/android/compatibility/common/util/DropBoxReceiver.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.util;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.DropBoxManager;
+import android.util.Log;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+public class DropBoxReceiver {
+    private static final String TAG = "DropBoxReceiver";
+    private static final int TIMEOUT_SECS = 60 * 3;
+
+    private CountDownLatch mResultsReceivedSignal;
+    private long mStartMs;
+
+    public DropBoxReceiver(Context ctx, String wantTag, String... wantInStackTrace) {
+        mResultsReceivedSignal = new CountDownLatch(1);
+        mStartMs = System.currentTimeMillis();
+
+        DropBoxManager mDropbox = (DropBoxManager) ctx.getSystemService(Context.DROPBOX_SERVICE);
+
+        ctx.registerReceiver(
+                new BroadcastReceiver() {
+                    @Override
+                    public void onReceive(Context context, Intent intent) {
+                        // DropBox might receive other entries while we're waiting for the error
+                        // entry, so we need to check the tag and stack trace before continuing.
+                        while (true) {
+                            final DropBoxManager.Entry entry =
+                                    mDropbox.getNextEntry(wantTag, mStartMs);
+                            if (entry == null) {
+                                break;
+                            }
+                            Log.d(TAG, "ErrorsTest got message from drobpox: " + entry.getTag());
+                            mStartMs = entry.getTimeMillis();
+                            String stackTrace = entry.getText(64 * 1024);
+                            boolean allMatches = true;
+                            for (String line : wantInStackTrace) {
+                                boolean matched = stackTrace.contains(line);
+                                Log.d(TAG, "   matched=" + matched + " line: " + line);
+                                allMatches &= matched;
+                            }
+                            if (allMatches) {
+                                mResultsReceivedSignal.countDown();
+                            }
+                            entry.close();
+                        }
+                    }
+                },
+                new IntentFilter(DropBoxManager.ACTION_DROPBOX_ENTRY_ADDED));
+    }
+
+    public boolean await() throws InterruptedException {
+        return mResultsReceivedSignal.await(TIMEOUT_SECS, TimeUnit.SECONDS);
+    }
+}
diff --git a/common/device-side/util/jni/android_cts_CpuFeatures.cpp b/common/device-side/util/jni/android_cts_CpuFeatures.cpp
index 32a5903..ee5f606 100644
--- a/common/device-side/util/jni/android_cts_CpuFeatures.cpp
+++ b/common/device-side/util/jni/android_cts_CpuFeatures.cpp
@@ -25,12 +25,6 @@
     return cpuFamily == ANDROID_CPU_FAMILY_ARM;
 }
 
-jboolean android_cts_CpuFeatures_isMipsCpu(JNIEnv* env, jobject thiz)
-{
-    AndroidCpuFamily cpuFamily = android_getCpuFamily();
-    return cpuFamily == ANDROID_CPU_FAMILY_MIPS;
-}
-
 jboolean android_cts_CpuFeatures_isX86Cpu(JNIEnv* env, jobject thiz)
 {
     AndroidCpuFamily cpuFamily = android_getCpuFamily();
@@ -43,12 +37,6 @@
     return cpuFamily == ANDROID_CPU_FAMILY_ARM64;
 }
 
-jboolean android_cts_CpuFeatures_isMips64Cpu(JNIEnv* env, jobject thiz)
-{
-    AndroidCpuFamily cpuFamily = android_getCpuFamily();
-    return cpuFamily == ANDROID_CPU_FAMILY_MIPS64;
-}
-
 jboolean android_cts_CpuFeatures_isX86_64Cpu(JNIEnv* env, jobject thiz)
 {
     AndroidCpuFamily cpuFamily = android_getCpuFamily();
@@ -63,14 +51,10 @@
 static JNINativeMethod gMethods[] = {
     {  "isArmCpu", "()Z",
             (void *) android_cts_CpuFeatures_isArmCpu  },
-    {  "isMipsCpu", "()Z",
-            (void *) android_cts_CpuFeatures_isMipsCpu  },
     {  "isX86Cpu", "()Z",
             (void *) android_cts_CpuFeatures_isX86Cpu  },
     {  "isArm64Cpu", "()Z",
             (void *) android_cts_CpuFeatures_isArm64Cpu  },
-    {  "isMips64Cpu", "()Z",
-            (void *) android_cts_CpuFeatures_isMips64Cpu  },
     {  "isX86_64Cpu", "()Z",
             (void *) android_cts_CpuFeatures_isX86_64Cpu  },
     {  "getHwCaps", "()I",
diff --git a/hostsidetests/appcompat/OWNERS b/hostsidetests/appcompat/OWNERS
index 4e3ec29..11a1173 100644
--- a/hostsidetests/appcompat/OWNERS
+++ b/hostsidetests/appcompat/OWNERS
@@ -4,6 +4,5 @@
 platform-compat-eng+reviews@google.com
 
 andreionea@google.com
-atrost@google.com
 mathewi@google.com
-satayev@google.com
\ No newline at end of file
+satayev@google.com
diff --git a/hostsidetests/appcompat/host/lib/src/android/compat/cts/CompatChangeGatingTestCase.java b/hostsidetests/appcompat/host/lib/src/android/compat/cts/CompatChangeGatingTestCase.java
index 07a51af1d..a1033b1 100644
--- a/hostsidetests/appcompat/host/lib/src/android/compat/cts/CompatChangeGatingTestCase.java
+++ b/hostsidetests/appcompat/host/lib/src/android/compat/cts/CompatChangeGatingTestCase.java
@@ -321,7 +321,13 @@
                 .collect(Collectors.toMap(
                         atom -> atom.getChangeId(), // Key
                         atom -> atom.getState() ==  // Value
-                                AtomsProto.AppCompatibilityChangeReported.State.ENABLED));
+                                AtomsProto.AppCompatibilityChangeReported.State.ENABLED,
+                                (a, b) -> {
+                                  if (a != b) {
+                                    throw new IllegalStateException("inconsistent compatibility states");
+                                  }
+                                  return a;
+                                }));
     }
 
     /**
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/DocumentsTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/DocumentsTest.java
index 1c83284..a0f182b 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/DocumentsTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/DocumentsTest.java
@@ -26,6 +26,7 @@
  */
 public class DocumentsTest extends DocumentsTestCase {
     private static final String PROVIDER_PKG = "com.android.cts.documentprovider";
+    private static final String DUMMYIME_PKG = "com.android.cts.dummyime";
     private static final String PROVIDER_APK = "CtsDocumentProvider.apk";
     private static final String DUMMYIME_APK = "CtsDummyIme.apk";
 
@@ -46,7 +47,7 @@
         super.tearDown();
 
         getDevice().uninstallPackage(PROVIDER_PKG);
-        getDevice().uninstallPackage(DUMMYIME_APK);
+        getDevice().uninstallPackage(DUMMYIME_PKG);
     }
 
     public void testOpenSimple() throws Exception {
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/InstantAppUserTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/InstantAppUserTest.java
index bfecfaf..dee0358 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/InstantAppUserTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/InstantAppUserTest.java
@@ -231,7 +231,7 @@
 
     private void uninstallTestPackages() throws Exception {
         getDevice().uninstallPackage(NORMAL_PKG);
-        getDevice().uninstallPackage(IMPLICIT_APK);
+        getDevice().uninstallPackage(IMPLICIT_PKG);
         getDevice().uninstallPackage(EPHEMERAL_1_PKG);
         getDevice().uninstallPackage(USER_TEST_PKG);
         getDevice().uninstallPackage(USER_PKG);
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/OverlayHostTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/OverlayHostTest.java
index 21f8585..28b7158 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/OverlayHostTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/OverlayHostTest.java
@@ -229,6 +229,7 @@
                     .contains(" " + OVERLAY_ALL_PACKAGE + "\n"));
         } finally {
             getDevice().uninstallPackage(OVERLAY_ALL_PACKAGE);
+            getDevice().uninstallPackage(TARGET_PACKAGE);
         }
     }
 
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/UseEmbeddedDexTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/UseEmbeddedDexTest.java
index 42170cd..9db3ac2 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/UseEmbeddedDexTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/UseEmbeddedDexTest.java
@@ -19,6 +19,7 @@
 import android.platform.test.annotations.AppModeFull;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -35,6 +36,11 @@
     private static final String APK_SPLIT_COMPRESSED_DEX =
             "CtsUseEmbeddedDexAppSplit_CompressedDex.apk";
 
+    @After
+    public void tearDown() throws Exception {
+        getDevice().uninstallPackage(PACKAGE_NAME);
+    }
+
     @Test
     public void testCanonicalInstall() throws Exception {
         new InstallMultiple().addFile(APK_CANONICAL).run();
diff --git a/hostsidetests/appsecurity/test-apps/DeviceIdentifiers/OWNERS b/hostsidetests/appsecurity/test-apps/DeviceIdentifiers/OWNERS
new file mode 100644
index 0000000..7b7768d
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/DeviceIdentifiers/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 36824
+cbrubaker@google.com
diff --git a/hostsidetests/appsecurity/test-apps/MediaStorageApp/src/com/android/cts/mediastorageapp/MediaStorageTest.java b/hostsidetests/appsecurity/test-apps/MediaStorageApp/src/com/android/cts/mediastorageapp/MediaStorageTest.java
index 987efde..7ff47f7 100644
--- a/hostsidetests/appsecurity/test-apps/MediaStorageApp/src/com/android/cts/mediastorageapp/MediaStorageTest.java
+++ b/hostsidetests/appsecurity/test-apps/MediaStorageApp/src/com/android/cts/mediastorageapp/MediaStorageTest.java
@@ -64,6 +64,7 @@
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.concurrent.Callable;
+import java.util.concurrent.TimeoutException;
 
 @RunWith(AndroidJUnit4.class)
 public class MediaStorageTest {
@@ -561,6 +562,6 @@
                 Thread.sleep(500);
             }
         } 
-        return file;
+        throw new TimeoutException("File creation failed due to slow permission update");
     }
 }
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 d287311..a02ac15 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
@@ -45,6 +45,7 @@
 import android.os.storage.StorageManager;
 import android.provider.Settings;
 import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiScrollable;
 import android.support.test.uiautomator.UiSelector;
 import android.test.InstrumentationTestCase;
 
@@ -100,6 +101,8 @@
         device.waitForIdle();
 
         if (!isTV(getContext())) {
+            UiScrollable uiScrollable = new UiScrollable(new UiSelector().scrollable(true));
+            uiScrollable.scrollTextIntoView("internal storage");
             device.findObject(new UiSelector().textContains("internal storage")).click();
             device.waitForIdle();
         }
diff --git a/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp/src/com/android/cts/writeexternalstorageapp/ChangeDefaultUris.java b/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp/src/com/android/cts/writeexternalstorageapp/ChangeDefaultUris.java
index 7fa39b4..d1fc73e 100644
--- a/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp/src/com/android/cts/writeexternalstorageapp/ChangeDefaultUris.java
+++ b/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp/src/com/android/cts/writeexternalstorageapp/ChangeDefaultUris.java
@@ -24,20 +24,22 @@
 import android.test.AndroidTestCase;
 import com.android.compatibility.common.util.FileCopyHelper;
 import java.io.File;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
 
 /** Sets up providers and notifications using external storage. */
 public class ChangeDefaultUris extends AndroidTestCase {
 
     /** Unique title for provider insert and delete. */
     private static final String RINGER_TITLE = "CTS ringer title";
+    private static final int MAX_NUMBER_OF_ATTEMPTS = 10;
 
     public void testChangeDefaultUris() throws Exception {
         File mediaFile =
                 new File(
                         Environment.getExternalStorageDirectory(),
                         "ringer" + System.currentTimeMillis() + ".mp3");
-        FileCopyHelper copier = new FileCopyHelper(mContext);
-        copier.copyToExternalStorage(R.raw.ringer, mediaFile);
+        copyToExternalStorage(R.raw.ringer, mediaFile);
 
         ContentValues values = new ContentValues();
         values.put(MediaStore.MediaColumns.DATA, mediaFile.getPath());
@@ -73,4 +75,21 @@
         RingtoneManager.setActualDefaultRingtoneUri(
                 mContext, RingtoneManager.TYPE_NOTIFICATION, uri);
     }
+
+    /** After the apk installed in secondary user, it may take some time to update permissions. */
+    private void copyToExternalStorage(int resId, File path)
+            throws InterruptedException, TimeoutException {
+        FileCopyHelper copier = new FileCopyHelper(mContext);
+        int currentAttempt = 0;
+        while (currentAttempt < MAX_NUMBER_OF_ATTEMPTS) {
+            try {
+                copier.copyToExternalStorage(resId, path);
+                return;
+            } catch (Exception e) {
+                currentAttempt++;
+                TimeUnit.MILLISECONDS.sleep(500);
+            }
+        }
+        throw new TimeoutException();
+    }
 }
diff --git a/hostsidetests/appsecurity/test-apps/rro/OverlayApp/src/com/android/cts/overlay/app/OverlayableTest.java b/hostsidetests/appsecurity/test-apps/rro/OverlayApp/src/com/android/cts/overlay/app/OverlayableTest.java
index 2b8bad6..dbe7c0a 100644
--- a/hostsidetests/appsecurity/test-apps/rro/OverlayApp/src/com/android/cts/overlay/app/OverlayableTest.java
+++ b/hostsidetests/appsecurity/test-apps/rro/OverlayApp/src/com/android/cts/overlay/app/OverlayableTest.java
@@ -67,10 +67,11 @@
         return InstrumentationRegistry.getTargetContext().createPackageContext(TARGET_PACKAGE, 0);
     }
 
-    private void assertOverlayEnabled(Context context, String overlayPackage) throws Exception {
+    private void assertOverlayEnabled(String overlayPackage) throws Exception {
         // Wait for the overlay changes to propagate
         FutureTask<Boolean> task = new FutureTask<>(() -> {
             while (true) {
+                Context context = getTargetContext();
                 for (String path : context.getAssets().getApkPaths()) {
                     if (path.contains(overlayPackage)) {
                         return true;
@@ -85,8 +86,8 @@
 
     @Test
     public void testOverlayPolicyAll() throws Exception {
+        assertOverlayEnabled(POLICY_ALL_PACKAGE);
         Context context = getTargetContext();
-        assertOverlayEnabled(context, POLICY_ALL_PACKAGE);
 
         String result = context.getResources().getString(R.string.not_overlayable);
         assertEquals(NOT_OVERLAID, result);
@@ -112,8 +113,8 @@
 
     @Test
     public void testSameSignatureNoOverlayableSucceeds() throws Exception {
+        assertOverlayEnabled(POLICY_ALL_PACKAGE);
         Context context = getTargetContext();
-        assertOverlayEnabled(context, POLICY_ALL_PACKAGE);
 
         String result = context.getResources().getString(R.string.not_overlayable);
         assertEquals(OVERLAID, result);
diff --git a/hostsidetests/atrace/AtraceTestApp/jni/Android.bp b/hostsidetests/atrace/AtraceTestApp/jni/Android.bp
index a782ef6..70b47a7 100644
--- a/hostsidetests/atrace/AtraceTestApp/jni/Android.bp
+++ b/hostsidetests/atrace/AtraceTestApp/jni/Android.bp
@@ -20,6 +20,7 @@
         "-Wall",
         "-Werror",
     ],
+    header_libs: ["jni_headers"],
     shared_libs: ["libandroid"],
     sdk_version: "current",
 
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
index 2942a89..5c76fb7 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
@@ -573,6 +573,12 @@
         return userId;
     }
 
+    protected int createUserAndWaitStart() throws Exception {
+        int userId = createUser(0);
+        startUserAndWait(userId);
+        return userId;
+    }
+
     protected int createUser(int flags) throws Exception {
         boolean guest = FLAG_GUEST == (flags & FLAG_GUEST);
         boolean ephemeral = FLAG_EPHEMERAL == (flags & FLAG_EPHEMERAL);
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
index d828b86..517f018 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
@@ -1223,6 +1223,9 @@
             // Reboot while in kiosk mode and then unlock the device
             rebootAndWaitUntilReady();
 
+            // Wait for the LockTask starting
+            waitForBroadcastIdle();
+
             // Try to open settings via adb
             executeShellCommand("am start -a android.settings.SETTINGS");
 
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/UserRestrictionsTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/UserRestrictionsTest.java
index 90dbed9..45156c2 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/UserRestrictionsTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/UserRestrictionsTest.java
@@ -164,7 +164,7 @@
         setDo();
 
         // Create another user and set PO.
-        final int secondaryUserId = createUser();
+        final int secondaryUserId = createUserAndWaitStart();
         setPoAsUser(secondaryUserId);
 
         // Ensure that UserManager differentiates its own restrictions from DO restrictions.
@@ -236,7 +236,7 @@
         setDo();
 
         // Create another user with PO.
-        final int secondaryUserId = createUser();
+        final int secondaryUserId = createUserAndWaitStart();
         setPoAsUser(secondaryUserId);
 
         final int[] usersToCheck = {mDeviceOwnerUserId, secondaryUserId};
diff --git a/hostsidetests/dexmetadata/host/src/com/android/cts/dexmetadata/InstallDexMetadataHostTest.java b/hostsidetests/dexmetadata/host/src/com/android/cts/dexmetadata/InstallDexMetadataHostTest.java
index 15bb39b..ad6aef8 100644
--- a/hostsidetests/dexmetadata/host/src/com/android/cts/dexmetadata/InstallDexMetadataHostTest.java
+++ b/hostsidetests/dexmetadata/host/src/com/android/cts/dexmetadata/InstallDexMetadataHostTest.java
@@ -32,9 +32,12 @@
 import java.io.FileOutputStream;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
+import java.util.zip.Inflater;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipInputStream;
 import org.junit.After;
@@ -198,6 +201,28 @@
         assertTrue(runDeviceTests(TEST_PACKAGE, TEST_CLASS, "testDmForBaseButNoSplit"));
     }
 
+    static class ProfileReader {
+      byte[] data;
+
+      ProfileReader(byte[] bytes) throws Exception {
+        ByteBuffer bb = ByteBuffer.wrap(bytes);
+
+        // Read header.
+        bb.order(ByteOrder.LITTLE_ENDIAN);
+        assertEquals(0x006f7270 /* LE "pro\0" */, bb.getInt());
+        assertEquals(0x00303130 /* LE "010\0" */, bb.getInt());
+        bb.get(); // Skip dex file count.
+        int uncompressed_size = bb.getInt();
+        int compressed_size = bb.getInt();
+
+        // Decompress profile.
+        Inflater inflater = new Inflater();
+        inflater.setInput(bb.array(), bb.arrayOffset() + bb.position(), bb.remaining());
+        data = new byte[uncompressed_size];
+        assertEquals(uncompressed_size, inflater.inflate(data));
+      }
+    }
+
     @Test
     public void testProfileSnapshotAfterInstall() throws Exception {
         assumeProfilesAreEnabled();
@@ -211,8 +236,9 @@
         assertTrue(result.trim().isEmpty());
 
         // Extract the profile bytes from the dex metadata and from the profile snapshot.
-        byte[] snapshotProfileBytes = extractProfileSnapshotFromDevice();
-        byte[] expectedProfileBytes = extractProfileFromDexMetadata(mDmBaseFile);
+        byte[] snapshotProfileBytes = new ProfileReader(extractProfileSnapshotFromDevice()).data;
+        byte[] expectedProfileBytes =
+                new ProfileReader(extractProfileFromDexMetadata(mDmBaseFile)).data;
 
         assertArrayEquals(expectedProfileBytes, snapshotProfileBytes);
     }
diff --git a/hostsidetests/gputools/apps/Android.bp b/hostsidetests/gputools/apps/Android.bp
index 82f1ea5..3cfeafb 100644
--- a/hostsidetests/gputools/apps/Android.bp
+++ b/hostsidetests/gputools/apps/Android.bp
@@ -23,6 +23,7 @@
         "-Wall",
         "-Werror",
     ],
+    header_libs: ["jni_headers"],
     shared_libs: [
         "libandroid",
         "libvulkan",
diff --git a/hostsidetests/hdmicec/Android.bp b/hostsidetests/hdmicec/Android.bp
index 66d0e0a..4268ff1 100644
--- a/hostsidetests/hdmicec/Android.bp
+++ b/hostsidetests/hdmicec/Android.bp
@@ -28,6 +28,6 @@
         "compatibility-host-util",
     ],
     data: [
-        ":HdmiCecKeyEventCaptureApp",
+        ":HdmiCecHelperApp",
     ],
 }
diff --git a/hostsidetests/hdmicec/AndroidTest.xml b/hostsidetests/hdmicec/AndroidTest.xml
index f4f5281..a0a4350 100644
--- a/hostsidetests/hdmicec/AndroidTest.xml
+++ b/hostsidetests/hdmicec/AndroidTest.xml
@@ -22,7 +22,7 @@
     <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="HdmiCecKeyEventCaptureApp.apk" />
+        <option name="test-file-name" value="HdmiCecHelperApp.apk" />
     </target_preparer>
     <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
         <option name="jar" value="CtsHdmiCecHostTestCases.jar" />
diff --git a/hostsidetests/hdmicec/app/Android.bp b/hostsidetests/hdmicec/app/Android.bp
index 910aa30..6d713d3 100644
--- a/hostsidetests/hdmicec/app/Android.bp
+++ b/hostsidetests/hdmicec/app/Android.bp
@@ -13,8 +13,12 @@
 // limitations under the License.
 
 android_test_helper_app {
-    name: "HdmiCecKeyEventCaptureApp",
+    name: "HdmiCecHelperApp",
     defaults: ["cts_defaults"],
     srcs: ["src/**/*.java"],
-    sdk_version: "current",
+    static_libs: [
+        "services.core",
+        "guava",
+        "androidx.test.runner",
+    ],
 }
diff --git a/hostsidetests/hdmicec/app/AndroidManifest.xml b/hostsidetests/hdmicec/app/AndroidManifest.xml
index ce9fff7..bb19e50 100644
--- a/hostsidetests/hdmicec/app/AndroidManifest.xml
+++ b/hostsidetests/hdmicec/app/AndroidManifest.xml
@@ -26,6 +26,16 @@
                 <category android:name="android.intent.category.LEANBACK_LAUNCHER" />
             </intent-filter>
         </activity>
+         <activity android:name=".HdmiCecAudioManager" >
+            <intent-filter>
+                <action android:name="android.hdmicec.app.MUTE" />
+                <action android:name="android.hdmicec.app.UNMUTE" />
+                <action android:name="android.hdmicec.app.REPORT_VOLUME" />
+                <action android:name="android.hdmicec.app.SET_VOLUME" />
+                <action android:name="android.hdmicec.app.GET_SUPPORTED_SAD_FORMATS" />
+                <category android:name="android.intent.category.LEANBACK_LAUNCHER" />
+            </intent-filter>
+        </activity>
     </application>
 
 </manifest>
diff --git a/hostsidetests/hdmicec/app/src/android/hdmicec/app/HdmiCecAudioManager.java b/hostsidetests/hdmicec/app/src/android/hdmicec/app/HdmiCecAudioManager.java
new file mode 100644
index 0000000..f04490f
--- /dev/null
+++ b/hostsidetests/hdmicec/app/src/android/hdmicec/app/HdmiCecAudioManager.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hdmicec.app;
+
+import android.app.Activity;
+import android.content.Context;
+import android.media.AudioManager;
+import android.os.Bundle;
+import android.util.Log;
+
+import com.android.server.hdmi.SadConfigurationReaderTest;
+
+import org.junit.runner.JUnitCore;
+
+/**
+ * A simple app that can be used to mute, unmute, set volume or get the volume status of a device.
+ * The actions supported are:
+ *
+ * 1. android.hdmicec.app.MUTE: Mutes the STREAM_MUSIC of the device,
+ *                              irrespective of the previous state.
+ *    Usage: START_COMMAND -a android.hdmicec.app.MUTE
+ * 2. android.hdmicec.app.UNMUTE: Unmutes the STREAM_MUSIC of the device,
+ *                                irrespective of the previous state.
+ *    Usage: START_COMMAND -a android.hdmicec.app.UNMUTE
+ * 3. android.hdmicec.app.REPORT_VOLUME: Reports if the STREAM_MUSIC of the device is muted and
+ *                                       if not muted, the current volume level in percent.
+ *    Usage: START_COMMAND -a android.hdmicec.app.REPORT_VOLUME
+ * 4. android.hdmicec.app.SET_VOLUME: Sets the volume of STREAM_MUSIC to a particular level.
+ *                                    Has to be used with --ei "volumePercent" x.
+ *    Usage: START_COMMAND -a android.hdmicec.app.SET_VOLUME --ei "volumePercent" x
+ *
+ * where START_COMMAND is
+ * adb shell am start -n "android.hdmicec.app/android.hdmicec.app.HdmiCecAudioManager"
+ */
+public class HdmiCecAudioManager extends Activity {
+
+    private static final String TAG = HdmiCecAudioManager.class.getSimpleName();
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+
+        switch(getIntent().getAction()) {
+            case "android.hdmicec.app.MUTE":
+                audioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC,
+                        AudioManager.ADJUST_MUTE, 0);
+                break;
+            case "android.hdmicec.app.UNMUTE":
+                audioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC,
+                        AudioManager.ADJUST_UNMUTE, 0);
+                break;
+            case "android.hdmicec.app.REPORT_VOLUME":
+                if (audioManager.isStreamMute(AudioManager.STREAM_MUSIC)) {
+                    Log.i(TAG, "Device muted.");
+                } else {
+                    int minVolume = audioManager.getStreamMinVolume(AudioManager.STREAM_MUSIC);
+                    int maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
+                    int volume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
+                    int percentVolume = 100 * volume / (maxVolume - minVolume);
+                    Log.i(TAG, "Volume at " + percentVolume + "%");
+                }
+                break;
+            case "android.hdmicec.app.SET_VOLUME":
+                int percentVolume = getIntent().getIntExtra("volumePercent", 50);
+                int minVolume = audioManager.getStreamMinVolume(AudioManager.STREAM_MUSIC);
+                int maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
+                int volume = minVolume + ((maxVolume - minVolume) * percentVolume / 100);
+                audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, volume, 0);
+                Log.i(TAG, "Set volume to " + volume + " (" + percentVolume + "%)");
+                break;
+            case "android.hdmicec.app.GET_SUPPORTED_SAD_FORMATS":
+                JUnitCore junit = new JUnitCore();
+                junit.run(SadConfigurationReaderTest.class);
+                break;
+            default:
+                Log.w(TAG, "Unknown intent!");
+        }
+        finishAndRemoveTask();
+    }
+}
+
diff --git a/hostsidetests/hdmicec/app/src/com/android/server/hdmi/SadConfigurationReaderTest.java b/hostsidetests/hdmicec/app/src/com/android/server/hdmi/SadConfigurationReaderTest.java
new file mode 100644
index 0000000..48665ac
--- /dev/null
+++ b/hostsidetests/hdmicec/app/src/com/android/server/hdmi/SadConfigurationReaderTest.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.hdmi;
+
+import android.util.Log;
+
+import com.android.server.hdmi.HdmiUtils.CodecSad;
+import com.android.server.hdmi.HdmiUtils.DeviceConfig;
+import com.google.common.hash.HashCode;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+@RunWith(JUnit4.class)
+/**
+ * Reads short audio descriptors from a configuration file and outputs to a log
+ * for use by host side tests.
+ */
+public class SadConfigurationReaderTest {
+
+    private static final String TAG = "SadConfigurationReaderTest";
+
+    // Variable should be copy of SHORT_AUDIO_DESCRIPTOR_CONFIG_PATH in
+    // frameworks/base/services/core/java/com/android/server/hdmi/
+    //  HdmiCecLocalDeviceAudioSystem.java
+    private final String SHORT_AUDIO_DESCRIPTOR_CONFIG_PATH = "/vendor/etc/sadConfig.xml";
+
+    @Test
+    public void parseSadConfigXML() {
+        List<DeviceConfig> deviceConfigs = null;
+        File file = new File(SHORT_AUDIO_DESCRIPTOR_CONFIG_PATH);
+        if (file.exists()) {
+            try {
+                InputStream in = new FileInputStream(file);
+                deviceConfigs = HdmiUtils.ShortAudioDescriptorXmlParser.parse(in);
+                in.close();
+            } catch (IOException e) {
+                Log.e(TAG, "Error reading file: " + file.getAbsolutePath(), e);
+            } catch (XmlPullParserException e) {
+                Log.e(TAG, "Unable to parse file: " + file.getAbsolutePath(), e);
+            }
+        } else {
+            Log.e(TAG, "No config file present at " + file.getAbsolutePath());
+            return;
+        }
+        DeviceConfig deviceConfigToUse = null;
+        if (deviceConfigs != null && deviceConfigs.size() > 0) {
+            for (DeviceConfig deviceConfig : deviceConfigs) {
+                if (deviceConfig.name.equals("VX_AUDIO_DEVICE_IN_HDMI_ARC")) {
+                    deviceConfigToUse = deviceConfig;
+                    break;
+                }
+            }
+            if (deviceConfigToUse == null) {
+                Log.w(TAG, "sadConfig.xml does not have required device info for "
+                                   + "VX_AUDIO_DEVICE_IN_HDMI_ARC");
+                return;
+            }
+            List<Integer> audioCodecFormats = new ArrayList<>();
+            List<String> shortAudioDescriptors = new ArrayList<>();
+            for (CodecSad codecSad : deviceConfigToUse.supportedCodecs) {
+                audioCodecFormats.add(codecSad.audioCodec);
+                shortAudioDescriptors.add(HashCode.fromBytes(codecSad.sad).toString());
+            }
+            String audioCodecFormatsString = audioCodecFormats.toString();
+            String shortAudioDescriptorsString = shortAudioDescriptors.toString();
+            Log.i(TAG, "Supported Audio Formats");
+            Log.i(TAG, audioCodecFormatsString.substring(1, audioCodecFormatsString.length() - 1));
+            Log.i(TAG, shortAudioDescriptorsString
+                               .substring(1, shortAudioDescriptorsString.length() - 1));
+        }
+    }
+}
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/CecMessage.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/CecMessage.java
index 6437ec0..bce34e1 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/CecMessage.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/CecMessage.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,55 +16,152 @@
 
 package android.hdmicec.cts;
 
-import java.util.HashMap;
-import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
-public enum CecMessage {
-    FEATURE_ABORT(0x00),
-    TEXT_VIEW_ON(0x0d),
-    SET_MENU_LANGUAGE(0x32),
-    STANDBY(0x36),
-    USER_CONTROL_PRESSED(0x44),
-    USER_CONTROL_RELEASED(0x45),
-    GIVE_OSD_NAME(0x46),
-    SET_OSD_NAME(0x47),
-    SYSTEM_AUDIO_MODE_REQUEST(0x70),
-    SET_SYSTEM_AUDIO_MODE(0x72),
-    GIVE_SYSTEM_AUDIO_MODE_STATUS(0x7d),
-    ACTIVE_SOURCE(0x82),
-    GIVE_PHYSICAL_ADDRESS(0x83),
-    REPORT_PHYSICAL_ADDRESS(0x84),
-    REQUEST_ACTIVE_SOURCE(0x85),
-    SET_STREAM_PATH(0x86),
-    DEVICE_VENDOR_ID(0x87),
-    GIVE_DEVICE_VENDOR_ID(0x8c),
-    GIVE_POWER_STATUS(0x8f),
-    REPORT_POWER_STATUS(0x90),
-    GET_MENU_LANGUAGE(0x91),
-    INACTIVE_SOURCE(0x9d),
-    CEC_VERSION(0x9e),
-    GET_CEC_VERSION(0x9f),
-    ABORT(0xff);
+public class CecMessage {
 
-    private final int messageId;
-    private static Map messageMap = new HashMap<>();
+    private static final int HEXADECIMAL_RADIX = 16;
 
-    static {
-        for (CecMessage message : CecMessage.values()) {
-            messageMap.put(message.messageId, message);
+    /** Gets the hexadecimal ASCII character values of a string. */
+    public static String getHexAsciiString(String string) {
+        String asciiString = "";
+        byte[] ascii = string.trim().getBytes();
+
+        for (byte b : ascii) {
+            asciiString.concat(Integer.toHexString(b));
         }
+
+        return asciiString;
     }
 
-    public static CecMessage getMessage(int messageId) {
-        return (CecMessage) messageMap.get(messageId);
+    public static String formatParams(String rawParams) {
+        StringBuilder params = new StringBuilder("");
+        int position = 0;
+        int endPosition = 2;
+
+        do {
+            params.append(":" + rawParams.substring(position, endPosition));
+            position = endPosition;
+            endPosition += 2;
+        } while (endPosition <= rawParams.length());
+        return params.toString();
     }
 
-    @Override
-    public String toString() {
-        return String.format("%02x", messageId);
+    public static String formatParams(long rawParam) {
+        StringBuilder params = new StringBuilder("");
+
+        do {
+            params.insert(0, ":" + String.format("%02x", rawParam % 256));
+            rawParam >>= 8;
+        } while (rawParam > 0);
+
+        return params.toString();
     }
 
-    private CecMessage(int messageId) {
-        this.messageId = messageId;
+    /**
+     * Formats the rawParam into CEC message parameters. The parameters will be at least
+     * minimumNibbles long.
+     */
+    public static String formatParams(long rawParam, int minimumNibbles) {
+        StringBuilder params = new StringBuilder("");
+
+        do {
+            params.insert(0, ":" + String.format("%02x", rawParam % 256));
+            rawParam >>= 8;
+            minimumNibbles -= 2;
+        } while (rawParam > 0 || minimumNibbles > 0);
+
+        return params.toString();
+    }
+
+    public static int hexStringToInt(String message) {
+        return Integer.parseInt(message, HEXADECIMAL_RADIX);
+    }
+
+    public static String getAsciiString(String message) {
+        String params = getNibbles(message).substring(4);
+        StringBuilder builder = new StringBuilder();
+
+        for (int i = 2; i <= params.length(); i += 2) {
+            builder.append((char) hexStringToInt(params.substring(i - 2, i)));
+        }
+
+        return builder.toString();
+    }
+
+    public static String getParamsAsString(String message) {
+        return getNibbles(message).substring(4);
+    }
+
+    /** Gets the params from a CEC message. */
+    public static int getParams(String message) {
+        return hexStringToInt(getNibbles(message).substring(4));
+    }
+
+    /** Gets the first 'numNibbles' number of param nibbles from a CEC message. */
+    public static int getParams(String message, int numNibbles) {
+        int paramStart = 4;
+        int end = numNibbles + paramStart;
+        return hexStringToInt(getNibbles(message).substring(paramStart, end));
+    }
+
+    /**
+     * From the params of a CEC message, gets the nibbles from position start to position end.
+     * The start and end are relative to the beginning of the params. For example, in the following
+     * message - 4F:82:10:00:04, getParamsFromMessage(message, 0, 4) will return 0x1000 and
+     * getParamsFromMessage(message, 4, 6) will return 0x04.
+     */
+    public static int getParams(String message, int start, int end) {
+        return hexStringToInt(getNibbles(message).substring(4).substring(start, end));
+    }
+
+    /**
+     * Gets the source logical address from a CEC message.
+     */
+    public static LogicalAddress getSource(String message) {
+        String param = getNibbles(message).substring(0, 1);
+        return LogicalAddress.getLogicalAddress(hexStringToInt(param));
+    }
+
+    /** Gets the destination logical address from a CEC message. */
+    public static LogicalAddress getDestination(String message) {
+        String param = getNibbles(message).substring(1, 2);
+        return LogicalAddress.getLogicalAddress(hexStringToInt(param));
+    }
+
+    /** Gets the operand from a CEC message. */
+    public static CecOperand getOperand(String message) {
+        String param = getNibbles(message).substring(2, 4);
+        return CecOperand.getOperand(hexStringToInt(param));
+    }
+
+    /**
+     * Converts ascii characters to hexadecimal numbers that can be appended to a CEC message as
+     * params. For example, "spa" will be converted to ":73:70:61"
+     */
+    public static String convertStringToHexParams(String rawParams) {
+        StringBuilder params = new StringBuilder("");
+        for (int i = 0; i < rawParams.length(); i++) {
+            params.append(String.format(":%02x", (int) rawParams.charAt(i)));
+        }
+        return params.toString();
+    }
+
+    private static String getNibbles(String message) {
+        final String tag1 = "group1";
+        final String tag2 = "group2";
+        String paramsPattern = "(?:.*[>>|<<].*?)" +
+                "(?<" + tag1 + ">[\\p{XDigit}{2}:]+)" +
+                "(?<" + tag2 + ">\\p{XDigit}{2})" +
+                "(?:.*?)";
+        String nibbles = "";
+
+        Pattern p = Pattern.compile(paramsPattern);
+        Matcher m = p.matcher(message);
+        if (m.matches()) {
+            nibbles = m.group(tag1).replace(":", "") + m.group(tag2);
+        }
+        return nibbles;
     }
 }
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/CecOperand.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/CecOperand.java
new file mode 100644
index 0000000..5aa547e
--- /dev/null
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/CecOperand.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hdmicec.cts;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public enum CecOperand {
+    FEATURE_ABORT(0x00),
+    TEXT_VIEW_ON(0x0d),
+    SET_MENU_LANGUAGE(0x32),
+    STANDBY(0x36),
+    USER_CONTROL_PRESSED(0x44),
+    USER_CONTROL_RELEASED(0x45),
+    GIVE_OSD_NAME(0x46),
+    SET_OSD_NAME(0x47),
+    SYSTEM_AUDIO_MODE_REQUEST(0x70),
+    GIVE_AUDIO_STATUS(0x71),
+    SET_SYSTEM_AUDIO_MODE(0x72),
+    REPORT_AUDIO_STATUS(0x7a),
+    GIVE_SYSTEM_AUDIO_MODE_STATUS(0x7d),
+    SYSTEM_AUDIO_MODE_STATUS(0x7e),
+    ACTIVE_SOURCE(0x82),
+    GIVE_PHYSICAL_ADDRESS(0x83),
+    REPORT_PHYSICAL_ADDRESS(0x84),
+    REQUEST_ACTIVE_SOURCE(0x85),
+    SET_STREAM_PATH(0x86),
+    DEVICE_VENDOR_ID(0x87),
+    VENDOR_COMMAND(0x89),
+    GIVE_DEVICE_VENDOR_ID(0x8c),
+    GIVE_POWER_STATUS(0x8f),
+    REPORT_POWER_STATUS(0x90),
+    GET_MENU_LANGUAGE(0x91),
+    INACTIVE_SOURCE(0x9d),
+    CEC_VERSION(0x9e),
+    GET_CEC_VERSION(0x9f),
+    REPORT_SHORT_AUDIO_DESCRIPTOR(0xa3),
+    REQUEST_SHORT_AUDIO_DESCRIPTOR(0xa4),
+    INITIATE_ARC(0xc0),
+    ARC_INITIATED(0xc1),
+    REQUEST_ARC_INITIATION(0xc3),
+    REQUEST_ARC_TERMINATION(0xc4),
+    TERMINATE_ARC(0xc5),
+    ABORT(0xff);
+
+    private final int operandCode;
+    private static Map operandMap = new HashMap<>();
+
+    static {
+        for (CecOperand operand : CecOperand.values()) {
+            operandMap.put(operand.operandCode, operand);
+        }
+    }
+
+    public static CecOperand getOperand(int messageId) {
+        return (CecOperand) operandMap.get(messageId);
+    }
+
+    @Override
+    public String toString() {
+        return String.format("%02x", operandCode);
+    }
+
+    private CecOperand(int operandCode) {
+        this.operandCode = operandCode;
+    }
+}
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiCecClientWrapper.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiCecClientWrapper.java
index f9b1899..51da280 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiCecClientWrapper.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiCecClientWrapper.java
@@ -16,10 +16,6 @@
 
 package android.hdmicec.cts;
 
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assume.assumeTrue;
-
-import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.log.LogUtil.CLog;
 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
 import com.android.tradefed.util.RunUtil;
@@ -32,10 +28,8 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
-import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import org.junit.Rule;
 import org.junit.rules.ExternalResource;
 
 /** Class that helps communicate with the cec-client */
@@ -44,8 +38,6 @@
     private static final String CEC_CONSOLE_READY = "waiting for input";
     private static final int MILLISECONDS_TO_READY = 10000;
     private static final int DEFAULT_TIMEOUT = 20000;
-    private static final String HDMI_CEC_FEATURE = "feature:android.hardware.hdmi.cec";
-    private static final int HEXADECIMAL_RADIX = 16;
     private static final int BUFFER_SIZE = 1024;
 
     private Process mCecClient;
@@ -53,29 +45,16 @@
     private BufferedReader mInputConsole;
     private boolean mCecClientInitialised = false;
 
-    private CecDevice targetDevice;
-    private BaseHostJUnit4Test testObject;
+    private LogicalAddress targetDevice;
     private String clientParams[];
 
-    public HdmiCecClientWrapper(CecDevice targetDevice, BaseHostJUnit4Test testObject,
-            String ...clientParams) {
+    public HdmiCecClientWrapper(LogicalAddress targetDevice, String ...clientParams) {
         this.targetDevice = targetDevice;
-        this.testObject = testObject;
         this.clientParams = clientParams;
     }
 
     @Override
     protected void before() throws Throwable {
-        ITestDevice testDevice;
-        testDevice = testObject.getDevice();
-        assertNotNull("Device not set", testDevice);
-
-        assumeTrue(isHdmiCecFeatureSupported(testDevice));
-
-        String deviceTypeCsv = testDevice.executeShellCommand("getprop ro.hdmi.device_type").trim();
-        List<String> deviceType = Arrays.asList(deviceTypeCsv.replaceAll("\\s+", "").split(","));
-        assumeTrue(deviceType.contains(CecDevice.getDeviceType(targetDevice)));
-
         this.init();
     };
 
@@ -84,24 +63,18 @@
         this.killCecProcess();
     };
 
-    /**
-     * Checks if the HDMI CEC feature is running on the device. Call this function before running
-     * any HDMI CEC tests.
-     * This could throw a DeviceNotAvailableException.
-     */
-    private static boolean isHdmiCecFeatureSupported(ITestDevice device) throws Exception {
-        return device.hasFeature(HDMI_CEC_FEATURE);
-    }
-
     /** Initialise the client */
     private void init() throws Exception {
-        boolean gotExpectedOut = false;
         List<String> commands = new ArrayList();
-        int seconds = 0;
 
         commands.add("cec-client");
+        /* "-p 2" starts the client as if it is connected to HDMI port 2, taking the physical
+         * address 2.0.0.0 */
         commands.add("-p");
         commands.add("2");
+        /* "-t x" starts the client as a TV device */
+        commands.add("-t");
+        commands.add("x");
         commands.addAll(Arrays.asList(clientParams));
 
         mCecClient = RunUtil.getDefault().runCmdInBackground(commands);
@@ -133,15 +106,15 @@
      * Sends a CEC message with source marked as broadcast to the device passed in the constructor
      * through the output console of the cec-communication channel.
      */
-    public void sendCecMessage(CecMessage message) throws Exception {
-        sendCecMessage(CecDevice.BROADCAST, targetDevice, message, "");
+    public void sendCecMessage(CecOperand message) throws Exception {
+        sendCecMessage(LogicalAddress.BROADCAST, targetDevice, message, "");
     }
 
     /**
      * Sends a CEC message from source device to the device passed in the constructor through the
      * output console of the cec-communication channel.
      */
-    public void sendCecMessage(CecDevice source, CecMessage message) throws Exception {
+    public void sendCecMessage(LogicalAddress source, CecOperand message) throws Exception {
         sendCecMessage(source, targetDevice, message, "");
     }
 
@@ -149,8 +122,8 @@
      * Sends a CEC message from source device to a destination device through the output console of
      * the cec-communication channel.
      */
-    public void sendCecMessage(CecDevice source, CecDevice destination,
-        CecMessage message) throws Exception {
+    public void sendCecMessage(LogicalAddress source, LogicalAddress destination,
+        CecOperand message) throws Exception {
         sendCecMessage(source, destination, message, "");
     }
 
@@ -158,10 +131,11 @@
      * Sends a CEC message from source device to a destination device through the output console of
      * the cec-communication channel with the appended params.
      */
-    public void sendCecMessage(CecDevice source, CecDevice destination,
-            CecMessage message, String params) throws Exception {
+    public void sendCecMessage(LogicalAddress source, LogicalAddress destination,
+            CecOperand message, String params) throws Exception {
         checkCecClient();
         mOutputConsole.write("tx " + source + destination + ":" + message + params);
+        mOutputConsole.newLine();
         mOutputConsole.flush();
     }
 
@@ -169,13 +143,13 @@
      * Sends a <USER_CONTROL_PRESSED> and <USER_CONTROL_RELEASED> from source to destination
      * through the output console of the cec-communication channel with the mentioned keycode.
      */
-    public void sendUserControlPressAndRelease(CecDevice source, CecDevice destination,
+    public void sendUserControlPressAndRelease(LogicalAddress source, LogicalAddress destination,
             int keycode, boolean holdKey) throws Exception {
         sendUserControlPress(source, destination, keycode, holdKey);
         /* Sleep less than 200ms between press and release */
         TimeUnit.MILLISECONDS.sleep(100);
         mOutputConsole.write("tx " + source + destination + ":" +
-                              CecMessage.USER_CONTROL_RELEASED);
+                              CecOperand.USER_CONTROL_RELEASED);
         mOutputConsole.flush();
     }
 
@@ -184,11 +158,11 @@
      * cec-communication channel with the mentioned keycode. If holdKey is true, the method will
      * send multiple <UCP> messages to simulate a long press. No <UCR> will be sent.
      */
-    public void sendUserControlPress(CecDevice source, CecDevice destination,
+    public void sendUserControlPress(LogicalAddress source, LogicalAddress destination,
             int keycode, boolean holdKey) throws Exception {
         String key = String.format("%02x", keycode);
         String command = "tx " + source + destination + ":" +
-                CecMessage.USER_CONTROL_PRESSED + ":" + key;
+                CecOperand.USER_CONTROL_PRESSED + ":" + key;
 
         if (holdKey) {
             /* Repeat once between 200ms and 450ms for at least 5 seconds. Since message will be
@@ -212,7 +186,8 @@
      * of the cec-communication channel immediately followed by <UCP> [secondKeycode]. No <UCR>
      *  message is sent.
      */
-    public void sendUserControlInterruptedPressAndHold(CecDevice source, CecDevice destination,
+    public void sendUserControlInterruptedPressAndHold(
+        LogicalAddress source, LogicalAddress destination,
             int firstKeycode, int secondKeycode, boolean holdKey) throws Exception {
         sendUserControlPress(source, destination, firstKeycode, holdKey);
         /* Sleep less than 200ms between press and release */
@@ -253,13 +228,40 @@
         return false;
     }
 
+    /** Gets all the messages received from the given source device during a period of duration
+     * seconds.
+     */
+    public List<CecOperand> getAllMessages(LogicalAddress source, int duration) throws Exception {
+        List<CecOperand> receivedOperands = new ArrayList<>();
+        long startTime = System.currentTimeMillis();
+        long endTime = startTime;
+        Pattern pattern = Pattern.compile("(.*>>)(.*?)" +
+                "(" + source + "\\p{XDigit}):(.*)",
+            Pattern.CASE_INSENSITIVE);
+
+        while ((endTime - startTime <= duration)) {
+            if (mInputConsole.ready()) {
+                String line = mInputConsole.readLine();
+                if (pattern.matcher(line).matches()) {
+                    CecOperand operand = CecMessage.getOperand(line);
+                    if (!receivedOperands.contains(operand)) {
+                        receivedOperands.add(operand);
+                    }
+                }
+            }
+            endTime = System.currentTimeMillis();
+        }
+        return receivedOperands;
+    }
+
+
     /**
      * Looks for the CEC expectedMessage broadcast on the cec-client communication channel and
      * returns the first line that contains that message within default timeout. If the CEC message
      * is not found within the timeout, an exception is thrown.
      */
-    public String checkExpectedOutput(CecMessage expectedMessage) throws Exception {
-        return checkExpectedOutput(CecDevice.BROADCAST, expectedMessage, DEFAULT_TIMEOUT);
+    public String checkExpectedOutput(CecOperand expectedMessage) throws Exception {
+        return checkExpectedOutput(LogicalAddress.BROADCAST, expectedMessage, DEFAULT_TIMEOUT);
     }
 
     /**
@@ -267,8 +269,8 @@
      * communication channel and returns the first line that contains that message within
      * default timeout. If the CEC message is not found within the timeout, an exception is thrown.
      */
-    public String checkExpectedOutput(CecDevice toDevice,
-                                      CecMessage expectedMessage) throws Exception {
+    public String checkExpectedOutput(LogicalAddress toDevice,
+                                      CecOperand expectedMessage) throws Exception {
         return checkExpectedOutput(toDevice, expectedMessage, DEFAULT_TIMEOUT);
     }
 
@@ -277,9 +279,9 @@
      * returns the first line that contains that message within timeoutMillis. If the CEC message
      * is not found within the timeout, an exception is thrown.
      */
-    public String checkExpectedOutput(CecMessage expectedMessage,
+    public String checkExpectedOutput(CecOperand expectedMessage,
                                       long timeoutMillis) throws Exception {
-        return checkExpectedOutput(CecDevice.BROADCAST, expectedMessage, timeoutMillis);
+        return checkExpectedOutput(LogicalAddress.BROADCAST, expectedMessage, timeoutMillis);
     }
 
     /**
@@ -287,7 +289,7 @@
      * communication channel and returns the first line that contains that message within
      * timeoutMillis. If the CEC message is not found within the timeout, an exception is thrown.
      */
-    public String checkExpectedOutput(CecDevice toDevice, CecMessage expectedMessage,
+    public String checkExpectedOutput(LogicalAddress toDevice, CecOperand expectedMessage,
                                        long timeoutMillis) throws Exception {
         checkCecClient();
         long startTime = System.currentTimeMillis();
@@ -316,8 +318,8 @@
      * within the default timeout. If the CEC message is not found within the timeout, function
      * returns without error.
      */
-    public void checkOutputDoesNotContainMessage(CecDevice toDevice,
-            CecMessage incorrectMessage) throws Exception {
+    public void checkOutputDoesNotContainMessage(LogicalAddress toDevice,
+            CecOperand incorrectMessage) throws Exception {
         checkOutputDoesNotContainMessage(toDevice, incorrectMessage, DEFAULT_TIMEOUT);
      }
 
@@ -327,7 +329,7 @@
      * within timeoutMillis. If the CEC message is not found within the timeout, function returns
      * without error.
      */
-    public void checkOutputDoesNotContainMessage(CecDevice toDevice, CecMessage incorrectMessage,
+    public void checkOutputDoesNotContainMessage(LogicalAddress toDevice, CecOperand incorrectMessage,
             long timeoutMillis) throws Exception {
 
         checkCecClient();
@@ -344,146 +346,13 @@
                 if (pattern.matcher(line).matches()) {
                     CLog.v("Found " + incorrectMessage.name() + " in " + line);
                     throw new Exception("Found " + incorrectMessage.name() + " to " + toDevice +
-                            " with params " + getParamsFromMessage(line));
+                            " with params " + CecMessage.getParamsAsString(line));
                 }
             }
             endTime = System.currentTimeMillis();
         }
      }
 
-    /** Gets the hexadecimal ASCII character values of a string. */
-    public String getHexAsciiString(String string) {
-        String asciiString = "";
-        byte[] ascii = string.trim().getBytes();
-
-        for (byte b : ascii) {
-            asciiString.concat(Integer.toHexString(b));
-        }
-
-        return asciiString;
-    }
-
-    public String formatParams(String rawParams) {
-        StringBuilder params = new StringBuilder("");
-        int position = 0;
-        int endPosition = 2;
-
-        do {
-            params.append(":" + rawParams.substring(position, endPosition));
-            position = endPosition;
-            endPosition += 2;
-        } while (endPosition <= rawParams.length());
-        return params.toString();
-    }
-
-    public String formatParams(long rawParam) {
-        StringBuilder params = new StringBuilder("");
-
-        do {
-            params.insert(0, ":" + String.format("%02x", rawParam % 256));
-            rawParam >>= 8;
-        } while (rawParam > 0);
-
-        return params.toString();
-    }
-
-    /** Formats a CEC message in the hex colon format (sd:op:xx:xx). */
-    public String formatMessage(CecDevice source, CecDevice destination, CecMessage message,
-            int params) {
-        StringBuilder cecMessage = new StringBuilder("" + source + destination + ":" + message);
-
-        cecMessage.append(formatParams(params));
-
-        return cecMessage.toString();
-    }
-
-    public static int hexStringToInt(String message) {
-        return Integer.parseInt(message, HEXADECIMAL_RADIX);
-    }
-
-    public String getAsciiStringFromMessage(String message) {
-        String params = getNibbles(message).substring(4);
-        StringBuilder builder = new StringBuilder();
-
-        for (int i = 2; i <= params.length(); i += 2) {
-            builder.append((char) hexStringToInt(params.substring(i - 2, i)));
-        }
-
-        return builder.toString();
-    }
-
-    /**
-     * Gets the params from a CEC message.
-     */
-    public int getParamsFromMessage(String message) {
-        return hexStringToInt(getNibbles(message).substring(4));
-    }
-
-    /**
-     * Gets the first 'numNibbles' number of param nibbles from a CEC message.
-     */
-    public int getParamsFromMessage(String message, int numNibbles) {
-        int paramStart = 4;
-        int end = numNibbles + paramStart;
-        return hexStringToInt(getNibbles(message).substring(paramStart, end));
-    }
-
-    /**
-     * From the params of a CEC message, gets the nibbles from position start to position end.
-     * The start and end are relative to the beginning of the params. For example, in the following
-     * message - 4F:82:10:00:04, getParamsFromMessage(message, 0, 4) will return 0x1000 and
-     * getParamsFromMessage(message, 4, 6) will return 0x04.
-     */
-    public int getParamsFromMessage(String message, int start, int end) {
-        return hexStringToInt(getNibbles(message).substring(4).substring(start, end));
-    }
-
-    /**
-     * Gets the source logical address from a CEC message.
-     */
-    public CecDevice getSourceFromMessage(String message) {
-        String param = getNibbles(message).substring(0, 1);
-        return CecDevice.getDevice(hexStringToInt(param));
-    }
-
-    /**
-     * Converts ascii characters to hexadecimal numbers that can be appended to a CEC message as
-     * params. For example, "spa" will be converted to ":73:70:61"
-     */
-    public static String convertStringToHexParams(String rawParams) {
-        StringBuilder params = new StringBuilder("");
-        for (int i = 0; i < rawParams.length(); i++) {
-            params.append(String.format(":%02x", (int) rawParams.charAt(i)));
-        }
-        return params.toString();
-    }
-
-
-    /**
-     * Gets the destination logical address from a CEC message.
-     */
-    public CecDevice getDestinationFromMessage(String message) {
-        String param = getNibbles(message).substring(1, 2);
-        return CecDevice.getDevice(hexStringToInt(param));
-    }
-
-    private String getNibbles(String message) {
-        final String tag1 = "group1";
-        final String tag2 = "group2";
-        String paramsPattern = "(?:.*[>>|<<].*?)" +
-                               "(?<" + tag1 + ">[\\p{XDigit}{2}:]+)" +
-                               "(?<" + tag2 + ">\\p{XDigit}{2})" +
-                               "(?:.*?)";
-        String nibbles = "";
-
-        Pattern p = Pattern.compile(paramsPattern);
-        Matcher m = p.matcher(message);
-        if (m.matches()) {
-            nibbles = m.group(tag1).replace(":", "") + m.group(tag2);
-        }
-        return nibbles;
-    }
-
     /**
      * Kills the cec-client process that was created in init().
      */
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiCecConstants.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiCecConstants.java
index 0565eae..8af4a8b 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiCecConstants.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiCecConstants.java
@@ -47,4 +47,11 @@
     public static final int CEC_DEVICE_TYPE_PLAYBACK_DEVICE = 4;
     public static final int CEC_DEVICE_TYPE_AUDIO_SYSTEM = 5;
 
+    /** Feature Abort Reasons */
+    public static final int ABORT_UNRECOGNIZED_MODE = 0;
+    public static final int ABORT_NOT_IN_CORRECT_MODE = 1;
+    public static final int ABORT_CANNOT_PROVIDE_SOURCE = 2;
+    public static final int ABORT_INVALID_OPERAND = 3;
+    public static final int ABORT_REFUSED = 4;
+    public static final int ABORT_UNABLE_TO_DETERMINE = 5;
 }
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/CecDevice.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/LogicalAddress.java
similarity index 71%
rename from hostsidetests/hdmicec/src/android/hdmicec/cts/CecDevice.java
rename to hostsidetests/hdmicec/src/android/hdmicec/cts/LogicalAddress.java
index 68c270a..5bcf5d1 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/CecDevice.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/LogicalAddress.java
@@ -19,7 +19,7 @@
 import java.util.HashMap;
 import java.util.Map;
 
-public enum CecDevice {
+public enum LogicalAddress {
     TV(0x0),
     RECORDER_1(0x1),
     RECORDER_2(0x2),
@@ -37,22 +37,29 @@
     SPECIFIC_USE(0xe),
     BROADCAST(0xf);
 
-    private final int playerId;
+    private final int address;
     private static Map deviceMap = new HashMap<>();
 
+    // CEC Device feature list
+    public static final String HDMI_CEC_FEATURE = "feature:android.hardware.hdmi.cec";
+    public static final String LEANBACK_FEATURE = "feature:android.software.leanback";
+
+    // CEC Device property list
+    public static final String HDMI_DEVICE_TYPE_PROPERTY = "ro.hdmi.device_type";
+
     @Override
     public String toString() {
-        return Integer.toHexString(this.playerId);
+        return Integer.toHexString(this.address);
     }
 
     static {
-        for (CecDevice device : CecDevice.values()) {
-            deviceMap.put(device.playerId, device);
+        for (LogicalAddress device : LogicalAddress.values()) {
+            deviceMap.put(device.address, device);
         }
     }
 
-    public static String getDeviceType(CecDevice device) {
-        switch (device) {
+    public String getDeviceType() {
+        switch (this) {
             case PLAYBACK_1:
             case PLAYBACK_2:
             case PLAYBACK_3:
@@ -75,11 +82,11 @@
         }
     }
 
-    public static CecDevice getDevice(int playerId) {
-        return (CecDevice) deviceMap.get(playerId);
+    public static LogicalAddress getLogicalAddress(int address) {
+        return (LogicalAddress) deviceMap.get(address);
     }
 
-    private CecDevice(int playerId) {
-        this.playerId = playerId;
+    private LogicalAddress(int address) {
+        this.address = address;
     }
 }
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/RequiredFeatureRule.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/RequiredFeatureRule.java
new file mode 100644
index 0000000..8fb70ec
--- /dev/null
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/RequiredFeatureRule.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hdmicec.cts;
+
+import static org.junit.Assume.assumeTrue;
+
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+/**
+ * Rule to check if the required device feature is available on device.
+ */
+public class RequiredFeatureRule implements TestRule {
+
+    private final BaseHostJUnit4Test mTest;
+    private final String mFeature;
+
+    public RequiredFeatureRule(BaseHostJUnit4Test test, String feature) {
+        mTest = test;
+        mFeature = feature;
+    }
+
+    @Override
+    public Statement apply(final Statement base, Description description) {
+        return new Statement() {
+            @Override
+            public void evaluate() throws Throwable {
+                ITestDevice testDevice = mTest.getDevice();
+                // Checks if the device is available.
+                assumeTrue("Test device is not available", testDevice != null);
+                // Checks if the requested feature is available on the device.
+                assumeTrue(mFeature + " not present in DUT " + testDevice.getSerialNumber(),
+                    testDevice.hasFeature(mFeature));
+                base.evaluate();
+            }
+        };
+    }
+}
+
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/RequiredPropertyRule.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/RequiredPropertyRule.java
new file mode 100644
index 0000000..f3998ad
--- /dev/null
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/RequiredPropertyRule.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hdmicec.cts;
+
+import static org.junit.Assume.assumeTrue;
+
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+/**
+ * Rule class that allows for checking device property value against required values.
+ * Static functions in this class can be used to check properties as a list or single value.
+ */
+public class RequiredPropertyRule implements TestRule {
+
+    // Do not allow instantiation.
+    private RequiredPropertyRule(){}
+
+    @Override
+    public Statement apply(final Statement base, Description description) {
+        return new Statement() {
+            @Override
+            public void evaluate() throws Throwable {
+                base.evaluate();
+            }
+        };
+    }
+
+    private static String getDevicePropertyValue(BaseHostJUnit4Test test, String propertyName)
+        throws Throwable {
+        ITestDevice testDevice = test.getDevice();
+        // Checks if the device is available.
+        assumeTrue("Test device is not available", testDevice != null);
+        return testDevice.executeShellCommand("getprop " + propertyName).trim();
+
+    }
+
+    public static RequiredPropertyRule isEqualTo(final BaseHostJUnit4Test test,
+        final String propertyName, final String propertyValue) {
+        return new RequiredPropertyRule() {
+            @Override
+            public Statement apply(final Statement base, final Description description) {
+                return new Statement() {
+                    @Override
+                    public void evaluate() throws Throwable {
+                        String deviceProperty = getDevicePropertyValue(test, propertyName);
+                        assumeTrue("Required property " + propertyName + " = " + propertyValue
+                                + " is not present in " + deviceProperty
+                                + " of device " + test.getDevice().getSerialNumber(),
+                            deviceProperty.equals(propertyValue));
+                        base.evaluate();
+                    }
+                };
+            }
+        };
+    }
+
+    public static RequiredPropertyRule asCsvContainsValue(final BaseHostJUnit4Test test,
+        final String propertyName, final String propertyValue) {
+        return new RequiredPropertyRule() {
+            @Override
+            public Statement apply(final Statement base, final Description description) {
+                return new Statement() {
+                    @Override
+                    public void evaluate() throws Throwable {
+                        List<String> deviceProperties =
+                            Arrays.asList(getDevicePropertyValue(test, propertyName)
+                                .replaceAll("\\s+", "")
+                                .split(","));
+                        assumeTrue(
+                            "Required property " + propertyName + " = " + propertyValue
+                                + " is not present in " + deviceProperties.toString()
+                                + " of device " + test.getDevice().getSerialNumber(),
+                            deviceProperties.contains(propertyValue));
+                        base.evaluate();
+                    }
+                };
+            }
+        };
+    }
+}
+
+
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecAudioReturnChannelControlTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecAudioReturnChannelControlTest.java
new file mode 100644
index 0000000..897a35e
--- /dev/null
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecAudioReturnChannelControlTest.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hdmicec.cts.audio;
+
+import static org.junit.Assume.assumeNoException;
+
+import android.hdmicec.cts.CecMessage;
+import android.hdmicec.cts.CecOperand;
+import android.hdmicec.cts.HdmiCecClientWrapper;
+import android.hdmicec.cts.HdmiCecConstants;
+import android.hdmicec.cts.LogicalAddress;
+import android.hdmicec.cts.RequiredPropertyRule;
+import android.hdmicec.cts.RequiredFeatureRule;
+
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+
+import org.junit.Rule;
+import org.junit.rules.RuleChain;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+/** HDMI CEC test to test audio return channel control (Section 11.2.17) */
+@RunWith(DeviceJUnit4ClassRunner.class)
+public final class HdmiCecAudioReturnChannelControlTest extends BaseHostJUnit4Test {
+
+    private static final LogicalAddress AUDIO_DEVICE = LogicalAddress.AUDIO_SYSTEM;
+
+    public HdmiCecClientWrapper hdmiCecClient = new HdmiCecClientWrapper(AUDIO_DEVICE);
+
+    @Rule
+    public RuleChain ruleChain =
+        RuleChain
+            .outerRule(new RequiredFeatureRule(this, LogicalAddress.HDMI_CEC_FEATURE))
+            .around(new RequiredFeatureRule(this, LogicalAddress.LEANBACK_FEATURE))
+            .around(RequiredPropertyRule.asCsvContainsValue(
+                this,
+                LogicalAddress.HDMI_DEVICE_TYPE_PROPERTY,
+                AUDIO_DEVICE.getDeviceType()))
+            .around(hdmiCecClient);
+
+    private void checkArcIsInitiated(){
+        try {
+            hdmiCecClient.sendCecMessage(LogicalAddress.TV, AUDIO_DEVICE,
+                    CecOperand.REQUEST_ARC_INITIATION);
+            hdmiCecClient.checkExpectedOutput(LogicalAddress.TV, CecOperand.INITIATE_ARC);
+        } catch(Exception e) {
+            assumeNoException(e);
+        }
+    }
+
+    /**
+     * Test 11.2.17-1
+     * Tests that the device sends a directly addressed <Initiate ARC> message
+     * when it wants to initiate ARC.
+     */
+    @Test
+    public void cect_11_2_17_1_InitiateArc() throws Exception {
+        hdmiCecClient.sendCecMessage(LogicalAddress.TV, LogicalAddress.BROADCAST,
+                CecOperand.REPORT_PHYSICAL_ADDRESS,
+                CecMessage.formatParams(HdmiCecConstants.TV_PHYSICAL_ADDRESS,
+                HdmiCecConstants.PHYSICAL_ADDRESS_LENGTH));
+        getDevice().executeShellCommand("reboot");
+        getDevice().waitForBootComplete(HdmiCecConstants.REBOOT_TIMEOUT);
+        hdmiCecClient.checkExpectedOutput(LogicalAddress.TV, CecOperand.INITIATE_ARC);
+    }
+
+    /**
+     * Test 11.2.17-2
+     * Tests that the device sends a directly addressed <Terminate ARC> message
+     * when it wants to terminate ARC.
+     */
+    @Test
+    public void cect_11_2_17_2_TerminateArc() throws Exception {
+        checkArcIsInitiated();
+        hdmiCecClient.sendCecMessage(LogicalAddress.TV, LogicalAddress.BROADCAST,
+                CecOperand.REPORT_PHYSICAL_ADDRESS,
+                CecMessage.formatParams(HdmiCecConstants.TV_PHYSICAL_ADDRESS,
+                        HdmiCecConstants.PHYSICAL_ADDRESS_LENGTH));
+        getDevice().executeShellCommand("input keyevent KEYCODE_SLEEP");
+        try {
+            hdmiCecClient.checkExpectedOutput(LogicalAddress.TV, CecOperand.TERMINATE_ARC);
+        } finally {
+            getDevice().executeShellCommand("input keyevent KEYCODE_WAKEUP");
+        }
+    }
+
+    /**
+     * Test 11.2.17-3
+     * Tests that the device sends a directly addressed <Initiate ARC>
+     * message when it is requested to initiate ARC.
+     */
+    @Test
+    public void cect_11_2_17_3_RequestToInitiateArc() throws Exception {
+        hdmiCecClient.sendCecMessage(LogicalAddress.TV, LogicalAddress.BROADCAST,
+                CecOperand.REPORT_PHYSICAL_ADDRESS,
+                CecMessage.formatParams(HdmiCecConstants.TV_PHYSICAL_ADDRESS,
+                HdmiCecConstants.PHYSICAL_ADDRESS_LENGTH));
+        hdmiCecClient.sendCecMessage(LogicalAddress.TV, AUDIO_DEVICE,
+                CecOperand.REQUEST_ARC_INITIATION);
+        hdmiCecClient.checkExpectedOutput(LogicalAddress.TV, CecOperand.INITIATE_ARC);
+    }
+
+    /**
+     * Test 11.2.17-4
+     * Tests that the device sends a directly addressed <Terminate ARC> message
+     * when it is requested to terminate ARC.
+     */
+    @Test
+    public void cect_11_2_17_4_RequestToTerminateArc() throws Exception {
+        checkArcIsInitiated();
+        hdmiCecClient.sendCecMessage(LogicalAddress.TV, LogicalAddress.BROADCAST,
+                CecOperand.REPORT_PHYSICAL_ADDRESS,
+                CecMessage.formatParams(HdmiCecConstants.TV_PHYSICAL_ADDRESS,
+                        HdmiCecConstants.PHYSICAL_ADDRESS_LENGTH));
+        hdmiCecClient.sendCecMessage(LogicalAddress.TV, AUDIO_DEVICE,
+                CecOperand.REQUEST_ARC_TERMINATION);
+        hdmiCecClient.checkExpectedOutput(LogicalAddress.TV, CecOperand.TERMINATE_ARC);
+    }
+}
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecInvalidMessagesTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecInvalidMessagesTest.java
new file mode 100644
index 0000000..f7644f2
--- /dev/null
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecInvalidMessagesTest.java
@@ -0,0 +1,357 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hdmicec.cts.audio;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeTrue;
+
+import android.hdmicec.cts.CecMessage;
+import android.hdmicec.cts.CecOperand;
+import android.hdmicec.cts.HdmiCecClientWrapper;
+import android.hdmicec.cts.HdmiCecConstants;
+import android.hdmicec.cts.LogicalAddress;
+import android.hdmicec.cts.RequiredPropertyRule;
+import android.hdmicec.cts.RequiredFeatureRule;
+
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.RuleChain;
+import org.junit.runner.RunWith;
+
+import java.util.Scanner;
+import java.util.concurrent.TimeUnit;
+
+/** HDMI CEC test to verify that device ignores invalid messages (Section 12) */
+@RunWith(DeviceJUnit4ClassRunner.class)
+public final class HdmiCecInvalidMessagesTest extends BaseHostJUnit4Test {
+
+    private static final LogicalAddress AUDIO_DEVICE = LogicalAddress.AUDIO_SYSTEM;
+    private static final String PROPERTY_LOCALE = "persist.sys.locale";
+
+    /** The package name of the APK. */
+    private static final String PACKAGE = "android.hdmicec.app";
+
+    /** The class name of the main activity in the APK. */
+    private static final String CLASS = "HdmiCecKeyEventCapture";
+
+    /** The command to launch the main activity. */
+    private static final String START_COMMAND = String.format(
+            "am start -W -a android.intent.action.MAIN -n %s/%s.%s", PACKAGE, PACKAGE, CLASS);
+
+    /** The command to clear the main activity. */
+    private static final String CLEAR_COMMAND = String.format("pm clear %s", PACKAGE);
+
+    private static final int WAIT_TIME = 10;
+
+    public HdmiCecClientWrapper hdmiCecClient = new HdmiCecClientWrapper(AUDIO_DEVICE);
+
+    @Rule
+    public RuleChain ruleChain =
+        RuleChain
+            .outerRule(new RequiredFeatureRule(this, LogicalAddress.HDMI_CEC_FEATURE))
+            .around(new RequiredFeatureRule(this, LogicalAddress.LEANBACK_FEATURE))
+            .around(RequiredPropertyRule.asCsvContainsValue(
+                this,
+                LogicalAddress.HDMI_DEVICE_TYPE_PROPERTY,
+                AUDIO_DEVICE.getDeviceType()))
+            .around(hdmiCecClient);
+
+    private String getSystemLocale() throws Exception {
+        ITestDevice device = getDevice();
+        return device.executeShellCommand("getprop " + PROPERTY_LOCALE).trim();
+    }
+
+    private void setSystemLocale(String locale) throws Exception {
+        ITestDevice device = getDevice();
+        device.executeShellCommand("setprop " + PROPERTY_LOCALE + " " + locale);
+    }
+
+    private boolean isLanguageEditable() throws Exception {
+        String val = getDevice().executeShellCommand("getprop ro.hdmi.set_menu_language");
+        return val.trim().equals("true") ? true : false;
+    }
+
+    private static String extractLanguage(String locale) {
+        return locale.split("[^a-zA-Z]")[0];
+    }
+
+    private void checkArcIsInitiated(){
+        try {
+            hdmiCecClient.sendCecMessage(LogicalAddress.TV, AUDIO_DEVICE,
+                CecOperand.REQUEST_ARC_INITIATION);
+            hdmiCecClient.checkExpectedOutput(LogicalAddress.TV, CecOperand.INITIATE_ARC);
+        } catch(Exception e) {
+            assumeNoException(e);
+        }
+    }
+
+    private void logShouldNotContain(String expectedOut) throws Exception {
+        ITestDevice device = getDevice();
+        TimeUnit.SECONDS.sleep(WAIT_TIME);
+        String logs = device.executeAdbCommand("logcat", "-v", "brief", "-d", CLASS + ":I", "*:S");
+        // Search for string.
+        String testString = "";
+        Scanner in = new Scanner(logs);
+        while (in.hasNextLine()) {
+            String line = in.nextLine();
+            if(line.startsWith("I/" + CLASS)) {
+                testString = line.split(":")[1].trim();
+                break;
+            }
+        }
+        device.executeAdbCommand("logcat", "-c");
+        assertThat(testString).doesNotContain(expectedOut);
+    }
+
+    /**
+     * Test 12-1
+     * Tests that the device ignores every broadcast only message that is received as
+     * directly addressed.
+     */
+    @Test
+    public void cect_12_1_BroadcastReceivedAsDirectlyAddressed() throws Exception {
+        /* <Set Menu Language> */
+        assumeTrue(isLanguageEditable());
+        final String locale = getSystemLocale();
+        final String originalLanguage = extractLanguage(locale);
+        final String language = originalLanguage.equals("spa") ? "eng" : "spa";
+        try {
+            hdmiCecClient.sendCecMessage(
+                    LogicalAddress.TV,
+                    AUDIO_DEVICE,
+                    CecOperand.SET_MENU_LANGUAGE,
+                    CecMessage.convertStringToHexParams(language));
+            assertThat(originalLanguage).isEqualTo(extractLanguage(getSystemLocale()));
+        } finally {
+            // If the language was incorrectly changed during the test, restore it.
+            setSystemLocale(locale);
+        }
+    }
+
+    /**
+     * Test 12-2
+     * Tests that the device ignores directly addressed message <GET_CEC_VERSION> if received as
+     * a broadcast message
+     */
+    @Test
+    public void cect_12_2_DirectlyAddressedReceivedAsBroadcast_getCecVersion() throws Exception {
+        hdmiCecClient.sendCecMessage(
+                LogicalAddress.TV,
+                LogicalAddress.BROADCAST,
+                CecOperand.GET_CEC_VERSION);
+        hdmiCecClient.checkOutputDoesNotContainMessage(
+                LogicalAddress.TV,
+                CecOperand.CEC_VERSION);
+    }
+
+    /**
+     * Test 12-2
+     * Tests that the device ignores directly addressed message <GIVE_PHYSICAL_ADDRESS> if received
+     * as a broadcast message
+     */
+    @Test
+    public void cect_12_2_DirectlyAddressedReceivedAsBroadcast_givePhysicalAddress()
+        throws Exception {
+        hdmiCecClient.sendCecMessage(
+                LogicalAddress.TV,
+                LogicalAddress.BROADCAST,
+                CecOperand.GIVE_PHYSICAL_ADDRESS);
+        hdmiCecClient.checkOutputDoesNotContainMessage(
+                LogicalAddress.BROADCAST,
+                CecOperand.REPORT_PHYSICAL_ADDRESS);
+    }
+
+    /**
+     * Test 12-2
+     * Tests that the device ignores directly addressed message <GIVE_AUDIO_STATUS> if received as
+     * a broadcast message
+     */
+    @Test
+    public void cect_12_2_DirectlyAddressedReceivedAsBroadcast_giveAudioStatus() throws Exception {
+        hdmiCecClient.sendCecMessage(
+                LogicalAddress.TV,
+                LogicalAddress.BROADCAST,
+                CecOperand.GIVE_AUDIO_STATUS);
+        hdmiCecClient.checkOutputDoesNotContainMessage(
+                LogicalAddress.TV,
+                CecOperand.REPORT_AUDIO_STATUS);
+    }
+
+    /**
+     * Test 12-2
+     * Tests that the device ignores directly addressed message <GIVE_POWER_STATUS> if received as
+     * a broadcast message
+     */
+    @Test
+    public void cect_12_2_DirectlyAddressedReceivedAsBroadcast_givePowerStatus() throws Exception {
+        hdmiCecClient.sendCecMessage(
+                LogicalAddress.TV,
+                LogicalAddress.BROADCAST,
+                CecOperand.GIVE_POWER_STATUS);
+        hdmiCecClient.checkOutputDoesNotContainMessage(
+                LogicalAddress.TV,
+                CecOperand.REPORT_POWER_STATUS);
+    }
+
+    /**
+     * Test 12-2
+     * Tests that the device ignores directly addressed message <GIVE_DEVICE_VENDOR_ID> if received
+     * as a broadcast message
+     */
+    @Test
+    public void cect_12_2_DirectlyAddressedReceivedAsBroadcast_giveDeviceVendorId()
+        throws Exception {
+        hdmiCecClient.sendCecMessage(
+                LogicalAddress.TV,
+                LogicalAddress.BROADCAST,
+                CecOperand.GIVE_DEVICE_VENDOR_ID);
+        hdmiCecClient.checkOutputDoesNotContainMessage(
+                LogicalAddress.BROADCAST,
+                CecOperand.DEVICE_VENDOR_ID);
+    }
+
+    /**
+     * Test 12-2
+     * Tests that the device ignores directly addressed message <GIVE_OSD_NAME> if received as
+     * a broadcast message
+     */
+    @Test
+    public void cect_12_2_DirectlyAddressedReceivedAsBroadcast_giveOsdName() throws Exception {
+        hdmiCecClient.sendCecMessage(
+                LogicalAddress.TV,
+                LogicalAddress.BROADCAST,
+                CecOperand.GIVE_OSD_NAME);
+        hdmiCecClient.checkOutputDoesNotContainMessage(
+                LogicalAddress.TV,
+                CecOperand.SET_OSD_NAME);
+    }
+
+    /**
+     * Test 12-2
+     * Tests that the device ignores directly addressed message <GIVE_SYSTEM_AUDIO_MODE_STATUS> if
+     * received as a broadcast message
+     */
+    @Test
+    public void cect_12_2_DirectlyAddressedReceivedAsBroadcast_giveSystemAudioModeStatus()
+        throws Exception {
+        hdmiCecClient.sendCecMessage(
+                LogicalAddress.TV,
+                LogicalAddress.BROADCAST,
+                CecOperand.GIVE_SYSTEM_AUDIO_MODE_STATUS);
+        hdmiCecClient.checkOutputDoesNotContainMessage(
+                LogicalAddress.TV,
+                CecOperand.SYSTEM_AUDIO_MODE_STATUS);
+    }
+
+    /**
+     * Test 12-2
+     * Tests that the device ignores directly addressed message <REQUEST_SHORT_AUDIO_DESCRIPTOR> if
+     * received as a broadcast message
+     */
+    @Test
+    public void cect_12_2_DirectlyAddressedReceivedAsBroadcast_requestShortAudioDescriptor()
+        throws Exception {
+        hdmiCecClient.sendCecMessage(
+                LogicalAddress.TV,
+                LogicalAddress.BROADCAST,
+                CecOperand.REQUEST_SHORT_AUDIO_DESCRIPTOR,
+                CecMessage.formatParams("01020304"));
+        hdmiCecClient.checkOutputDoesNotContainMessage(
+                LogicalAddress.TV,
+                CecOperand.REPORT_SHORT_AUDIO_DESCRIPTOR);
+    }
+
+    /**
+     * Test 12-2
+     * Tests that the device ignores directly addressed message <SYSTEM_AUDIO_MODE_REQUEST> if
+     * received as a broadcast message
+     */
+    @Test
+    public void cect_12_2_DirectlyAddressedReceivedAsBroadcast_systemAudioModeRequest()
+        throws Exception {
+        hdmiCecClient.sendCecMessage(
+                LogicalAddress.TV,
+                LogicalAddress.BROADCAST,
+                CecOperand.SYSTEM_AUDIO_MODE_REQUEST);
+        hdmiCecClient.checkOutputDoesNotContainMessage(
+                LogicalAddress.BROADCAST,
+                CecOperand.SET_SYSTEM_AUDIO_MODE);
+    }
+
+    /**
+     * Test 12-2
+     * Tests that the device ignores directly addressed message <REQUEST_ARC_INITIATION> if
+     * received as a broadcast message
+     */
+    @Test
+    public void cect_12_2_DirectlyAddressedReceivedAsBroadcast_requestArcInitiation()
+        throws Exception {
+        hdmiCecClient.sendCecMessage(
+                LogicalAddress.TV,
+                LogicalAddress.BROADCAST,
+                CecOperand.REQUEST_ARC_INITIATION);
+        hdmiCecClient.checkOutputDoesNotContainMessage(
+                LogicalAddress.BROADCAST,
+                CecOperand.INITIATE_ARC);
+    }
+
+    /**
+     * Test 12-2
+     * Tests that the device ignores directly addressed message <REQUEST_ARC_TERMINATION> if
+     * received as a broadcast message
+     */
+    @Test
+    public void cect_12_2_DirectlyAddressedReceivedAsBroadcast_requestArcTermination()
+        throws Exception {
+        checkArcIsInitiated();
+        hdmiCecClient.sendCecMessage(
+                LogicalAddress.TV,
+                LogicalAddress.BROADCAST,
+                CecOperand.REQUEST_ARC_TERMINATION);
+        hdmiCecClient.checkOutputDoesNotContainMessage(
+                LogicalAddress.BROADCAST,
+                CecOperand.TERMINATE_ARC);
+    }
+
+    /**
+     * Test 12-2
+     * Tests that the device ignores directly addressed message <USER_CONTROL_PRESSED> if received
+     * as a broadcast message
+     */
+    @Test
+    public void cect_12_2_DirectlyAddressedReceivedAsBroadcast_userControlPressed()
+        throws Exception {
+        ITestDevice device = getDevice();
+        // Clear activity
+        device.executeShellCommand(CLEAR_COMMAND);
+        // Clear logcat.
+        device.executeAdbCommand("logcat", "-c");
+        // Start the APK and wait for it to complete.
+        device.executeShellCommand(START_COMMAND);
+        hdmiCecClient.sendUserControlPressAndRelease(
+                LogicalAddress.TV,
+                LogicalAddress.BROADCAST,
+                HdmiCecConstants.CEC_CONTROL_UP,
+                false);
+        logShouldNotContain("Short press KEYCODE_DPAD_UP");
+    }
+}
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecLogicalAddressTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecLogicalAddressTest.java
index 1305a2b..d0f052d 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecLogicalAddressTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecLogicalAddressTest.java
@@ -16,29 +16,43 @@
 
 package android.hdmicec.cts.audio;
 
-import static org.junit.Assert.assertThat;
-import static org.hamcrest.CoreMatchers.is;
+import static com.google.common.truth.Truth.assertThat;
 
-import android.hdmicec.cts.CecDevice;
 import android.hdmicec.cts.CecMessage;
+import android.hdmicec.cts.CecOperand;
 import android.hdmicec.cts.HdmiCecClientWrapper;
 import android.hdmicec.cts.HdmiCecConstants;
+import android.hdmicec.cts.LogicalAddress;
+import android.hdmicec.cts.RequiredPropertyRule;
+import android.hdmicec.cts.RequiredFeatureRule;
 
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
 
 import org.junit.Rule;
+import org.junit.rules.RuleChain;
 import org.junit.runner.RunWith;
 import org.junit.Test;
 
 /** HDMI CEC test to verify logical address after device reboot (Section 10.2.5) */
 @RunWith(DeviceJUnit4ClassRunner.class)
 public final class HdmiCecLogicalAddressTest extends BaseHostJUnit4Test {
-    private static final CecDevice AUDIO_DEVICE = CecDevice.AUDIO_SYSTEM;
+
+    private static final LogicalAddress AUDIO_DEVICE = LogicalAddress.AUDIO_SYSTEM;
+
+    public HdmiCecClientWrapper hdmiCecClient = new HdmiCecClientWrapper(AUDIO_DEVICE);
 
     @Rule
-    public HdmiCecClientWrapper hdmiCecClient = new HdmiCecClientWrapper(AUDIO_DEVICE, this);
+    public RuleChain ruleChain =
+        RuleChain
+            .outerRule(new RequiredFeatureRule(this, LogicalAddress.HDMI_CEC_FEATURE))
+            .around(new RequiredFeatureRule(this, LogicalAddress.LEANBACK_FEATURE))
+            .around(RequiredPropertyRule.asCsvContainsValue(
+                this,
+                LogicalAddress.HDMI_DEVICE_TYPE_PROPERTY,
+                AUDIO_DEVICE.getDeviceType()))
+            .around(hdmiCecClient);
 
     /**
      * Test 10.2.5-1
@@ -50,7 +64,7 @@
         ITestDevice device = getDevice();
         device.executeShellCommand("reboot");
         device.waitForBootComplete(HdmiCecConstants.REBOOT_TIMEOUT);
-        String message = hdmiCecClient.checkExpectedOutput(CecMessage.REPORT_PHYSICAL_ADDRESS);
-        assertThat(hdmiCecClient.getSourceFromMessage(message), is(AUDIO_DEVICE));
+        String message = hdmiCecClient.checkExpectedOutput(CecOperand.REPORT_PHYSICAL_ADDRESS);
+        assertThat(CecMessage.getSource(message)).isEqualTo(AUDIO_DEVICE);
     }
 }
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecRemoteControlPassThroughTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecRemoteControlPassThroughTest.java
index 9931e26..e7e0be4 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecRemoteControlPassThroughTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecRemoteControlPassThroughTest.java
@@ -18,15 +18,18 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import android.hdmicec.cts.CecDevice;
 import android.hdmicec.cts.HdmiCecClientWrapper;
 import android.hdmicec.cts.HdmiCecConstants;
+import android.hdmicec.cts.LogicalAddress;
+import android.hdmicec.cts.RequiredPropertyRule;
+import android.hdmicec.cts.RequiredFeatureRule;
 
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
 
 import org.junit.Rule;
+import org.junit.rules.RuleChain;
 import org.junit.runner.RunWith;
 import org.junit.Test;
 
@@ -51,9 +54,18 @@
 
     private static final int WAIT_TIME = 10;
 
+    public HdmiCecClientWrapper hdmiCecClient = new HdmiCecClientWrapper(LogicalAddress.AUDIO_SYSTEM);
+
     @Rule
-    public HdmiCecClientWrapper hdmiCecClient =
-            new HdmiCecClientWrapper(CecDevice.AUDIO_SYSTEM, this);
+    public RuleChain ruleChain =
+        RuleChain
+            .outerRule(new RequiredFeatureRule(this, LogicalAddress.HDMI_CEC_FEATURE))
+            .around(new RequiredFeatureRule(this, LogicalAddress.LEANBACK_FEATURE))
+            .around(RequiredPropertyRule.asCsvContainsValue(
+                this,
+                LogicalAddress.HDMI_DEVICE_TYPE_PROPERTY,
+                LogicalAddress.AUDIO_SYSTEM.getDeviceType()))
+            .around(hdmiCecClient);
 
     private void lookForLog(String expectedOut) throws Exception {
         ITestDevice device = getDevice();
@@ -87,22 +99,22 @@
         device.executeAdbCommand("logcat", "-c");
         // Start the APK and wait for it to complete.
         device.executeShellCommand(START_COMMAND);
-        hdmiCecClient.sendUserControlPressAndRelease(CecDevice.TV, CecDevice.AUDIO_SYSTEM,
+        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, LogicalAddress.AUDIO_SYSTEM,
                 HdmiCecConstants.CEC_CONTROL_UP, false);
         lookForLog("Short press KEYCODE_DPAD_UP");
-        hdmiCecClient.sendUserControlPressAndRelease(CecDevice.TV, CecDevice.AUDIO_SYSTEM,
+        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, LogicalAddress.AUDIO_SYSTEM,
                 HdmiCecConstants.CEC_CONTROL_DOWN, false);
         lookForLog("Short press KEYCODE_DPAD_DOWN");
-        hdmiCecClient.sendUserControlPressAndRelease(CecDevice.TV, CecDevice.AUDIO_SYSTEM,
+        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, LogicalAddress.AUDIO_SYSTEM,
                 HdmiCecConstants.CEC_CONTROL_LEFT, false);
         lookForLog("Short press KEYCODE_DPAD_LEFT");
-        hdmiCecClient.sendUserControlPressAndRelease(CecDevice.TV, CecDevice.AUDIO_SYSTEM,
+        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, LogicalAddress.AUDIO_SYSTEM,
                 HdmiCecConstants.CEC_CONTROL_RIGHT, false);
         lookForLog("Short press KEYCODE_DPAD_RIGHT");
-        hdmiCecClient.sendUserControlPressAndRelease(CecDevice.TV, CecDevice.AUDIO_SYSTEM,
+        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, LogicalAddress.AUDIO_SYSTEM,
                 HdmiCecConstants.CEC_CONTROL_SELECT, false);
         lookForLog("Short press KEYCODE_DPAD_CENTER");
-        hdmiCecClient.sendUserControlPressAndRelease(CecDevice.TV, CecDevice.AUDIO_SYSTEM,
+        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, LogicalAddress.AUDIO_SYSTEM,
                 HdmiCecConstants.CEC_CONTROL_BACK, false);
         lookForLog("Short press KEYCODE_BACK");
     }
@@ -121,22 +133,22 @@
         device.executeAdbCommand("logcat", "-c");
         // Start the APK and wait for it to complete.
         device.executeShellCommand(START_COMMAND);
-        hdmiCecClient.sendUserControlPressAndRelease(CecDevice.TV, CecDevice.AUDIO_SYSTEM,
+        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, LogicalAddress.AUDIO_SYSTEM,
                 HdmiCecConstants.CEC_CONTROL_UP, true);
         lookForLog("Long press KEYCODE_DPAD_UP");
-        hdmiCecClient.sendUserControlPressAndRelease(CecDevice.TV, CecDevice.AUDIO_SYSTEM,
+        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, LogicalAddress.AUDIO_SYSTEM,
                 HdmiCecConstants.CEC_CONTROL_DOWN, true);
         lookForLog("Long press KEYCODE_DPAD_DOWN");
-        hdmiCecClient.sendUserControlPressAndRelease(CecDevice.TV, CecDevice.AUDIO_SYSTEM,
+        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, LogicalAddress.AUDIO_SYSTEM,
                 HdmiCecConstants.CEC_CONTROL_LEFT, true);
         lookForLog("Long press KEYCODE_DPAD_LEFT");
-        hdmiCecClient.sendUserControlPressAndRelease(CecDevice.TV, CecDevice.AUDIO_SYSTEM,
+        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, LogicalAddress.AUDIO_SYSTEM,
                 HdmiCecConstants.CEC_CONTROL_RIGHT, true);
         lookForLog("Long press KEYCODE_DPAD_RIGHT");
-        hdmiCecClient.sendUserControlPressAndRelease(CecDevice.TV, CecDevice.AUDIO_SYSTEM,
+        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, LogicalAddress.AUDIO_SYSTEM,
                 HdmiCecConstants.CEC_CONTROL_SELECT, true);
         lookForLog("Long press KEYCODE_DPAD_CENTER");
-        hdmiCecClient.sendUserControlPressAndRelease(CecDevice.TV, CecDevice.AUDIO_SYSTEM,
+        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, LogicalAddress.AUDIO_SYSTEM,
                 HdmiCecConstants.CEC_CONTROL_BACK, true);
         lookForLog("Long press KEYCODE_BACK");
     }
@@ -155,22 +167,22 @@
         device.executeAdbCommand("logcat", "-c");
         // Start the APK and wait for it to complete.
         device.executeShellCommand(START_COMMAND);
-        hdmiCecClient.sendUserControlPress(CecDevice.TV, CecDevice.AUDIO_SYSTEM,
+        hdmiCecClient.sendUserControlPress(LogicalAddress.TV, LogicalAddress.AUDIO_SYSTEM,
                 HdmiCecConstants.CEC_CONTROL_UP, true);
         lookForLog("Long press KEYCODE_DPAD_UP");
-        hdmiCecClient.sendUserControlPress(CecDevice.TV, CecDevice.AUDIO_SYSTEM,
+        hdmiCecClient.sendUserControlPress(LogicalAddress.TV, LogicalAddress.AUDIO_SYSTEM,
                 HdmiCecConstants.CEC_CONTROL_DOWN, true);
         lookForLog("Long press KEYCODE_DPAD_DOWN");
-        hdmiCecClient.sendUserControlPress(CecDevice.TV, CecDevice.AUDIO_SYSTEM,
+        hdmiCecClient.sendUserControlPress(LogicalAddress.TV, LogicalAddress.AUDIO_SYSTEM,
                 HdmiCecConstants.CEC_CONTROL_LEFT, true);
         lookForLog("Long press KEYCODE_DPAD_LEFT");
-        hdmiCecClient.sendUserControlPress(CecDevice.TV, CecDevice.AUDIO_SYSTEM,
+        hdmiCecClient.sendUserControlPress(LogicalAddress.TV, LogicalAddress.AUDIO_SYSTEM,
                 HdmiCecConstants.CEC_CONTROL_RIGHT, true);
         lookForLog("Long press KEYCODE_DPAD_RIGHT");
-        hdmiCecClient.sendUserControlPress(CecDevice.TV, CecDevice.AUDIO_SYSTEM,
+        hdmiCecClient.sendUserControlPress(LogicalAddress.TV, LogicalAddress.AUDIO_SYSTEM,
                 HdmiCecConstants.CEC_CONTROL_SELECT, true);
         lookForLog("Long press KEYCODE_DPAD_CENTER");
-        hdmiCecClient.sendUserControlPress(CecDevice.TV, CecDevice.AUDIO_SYSTEM,
+        hdmiCecClient.sendUserControlPress(LogicalAddress.TV, LogicalAddress.AUDIO_SYSTEM,
                 HdmiCecConstants.CEC_CONTROL_BACK, true);
         lookForLog("Long press KEYCODE_BACK");
     }
@@ -190,28 +202,28 @@
         device.executeAdbCommand("logcat", "-c");
         // Start the APK and wait for it to complete.
         device.executeShellCommand(START_COMMAND);
-        hdmiCecClient.sendUserControlInterruptedPressAndHold(CecDevice.TV,
-                CecDevice.AUDIO_SYSTEM, HdmiCecConstants.CEC_CONTROL_UP,
+        hdmiCecClient.sendUserControlInterruptedPressAndHold(LogicalAddress.TV,
+                LogicalAddress.AUDIO_SYSTEM, HdmiCecConstants.CEC_CONTROL_UP,
                 HdmiCecConstants.CEC_CONTROL_BACK, true);
         lookForLog("Long press KEYCODE_DPAD_UP");
-        hdmiCecClient.sendUserControlInterruptedPressAndHold(CecDevice.TV,
-                CecDevice.AUDIO_SYSTEM, HdmiCecConstants.CEC_CONTROL_DOWN,
+        hdmiCecClient.sendUserControlInterruptedPressAndHold(LogicalAddress.TV,
+                LogicalAddress.AUDIO_SYSTEM, HdmiCecConstants.CEC_CONTROL_DOWN,
                 HdmiCecConstants.CEC_CONTROL_UP, true);
         lookForLog("Long press KEYCODE_DPAD_DOWN");
-        hdmiCecClient.sendUserControlInterruptedPressAndHold(CecDevice.TV,
-                CecDevice.AUDIO_SYSTEM, HdmiCecConstants.CEC_CONTROL_LEFT,
+        hdmiCecClient.sendUserControlInterruptedPressAndHold(LogicalAddress.TV,
+                LogicalAddress.AUDIO_SYSTEM, HdmiCecConstants.CEC_CONTROL_LEFT,
                 HdmiCecConstants.CEC_CONTROL_DOWN, true);
         lookForLog("Long press KEYCODE_DPAD_LEFT");
-        hdmiCecClient.sendUserControlInterruptedPressAndHold(CecDevice.TV,
-                CecDevice.AUDIO_SYSTEM, HdmiCecConstants.CEC_CONTROL_RIGHT,
+        hdmiCecClient.sendUserControlInterruptedPressAndHold(LogicalAddress.TV,
+                LogicalAddress.AUDIO_SYSTEM, HdmiCecConstants.CEC_CONTROL_RIGHT,
                 HdmiCecConstants.CEC_CONTROL_LEFT, true);
         lookForLog("Long press KEYCODE_DPAD_RIGHT");
-        hdmiCecClient.sendUserControlInterruptedPressAndHold(CecDevice.TV,
-                CecDevice.AUDIO_SYSTEM, HdmiCecConstants.CEC_CONTROL_SELECT,
+        hdmiCecClient.sendUserControlInterruptedPressAndHold(LogicalAddress.TV,
+                LogicalAddress.AUDIO_SYSTEM, HdmiCecConstants.CEC_CONTROL_SELECT,
                 HdmiCecConstants.CEC_CONTROL_RIGHT, true);
         lookForLog("Long press KEYCODE_DPAD_CENTER");
-        hdmiCecClient.sendUserControlInterruptedPressAndHold(CecDevice.TV,
-                CecDevice.AUDIO_SYSTEM, HdmiCecConstants.CEC_CONTROL_BACK,
+        hdmiCecClient.sendUserControlInterruptedPressAndHold(LogicalAddress.TV,
+                LogicalAddress.AUDIO_SYSTEM, HdmiCecConstants.CEC_CONTROL_BACK,
                 HdmiCecConstants.CEC_CONTROL_SELECT, true);
         lookForLog("Long press KEYCODE_BACK");
     }
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecSystemAudioModeTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecSystemAudioModeTest.java
index 6f6e4dc..4cb7b97 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecSystemAudioModeTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecSystemAudioModeTest.java
@@ -16,29 +16,260 @@
 
 package android.hdmicec.cts.audio;
 
-import static org.junit.Assert.assertThat;
-import static org.hamcrest.CoreMatchers.is;
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+import static org.junit.Assume.assumeTrue;
 
-import android.hdmicec.cts.CecDevice;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Range;
+
 import android.hdmicec.cts.CecMessage;
+import android.hdmicec.cts.CecOperand;
 import android.hdmicec.cts.HdmiCecClientWrapper;
 import android.hdmicec.cts.HdmiCecConstants;
+import android.hdmicec.cts.LogicalAddress;
+import android.hdmicec.cts.RequiredPropertyRule;
+import android.hdmicec.cts.RequiredFeatureRule;
 
+import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
 
+import org.junit.After;
 import org.junit.Rule;
+import org.junit.rules.RuleChain;
 import org.junit.runner.RunWith;
 import org.junit.Test;
 
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Scanner;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
 /** HDMI CEC test to test system audio mode (Section 11.2.15) */
 @RunWith(DeviceJUnit4ClassRunner.class)
 public final class HdmiCecSystemAudioModeTest extends BaseHostJUnit4Test {
-    private static final CecDevice AUDIO_DEVICE = CecDevice.AUDIO_SYSTEM;
+
+    /** The package name of the APK. */
+    private static final String PACKAGE = "android.hdmicec.app";
+
+    /** The class name of the main activity in the APK. */
+    private static final String CLASS = "HdmiCecAudioManager";
+
+    /** The tag of the SadConfigurationReaderTest launched by the APK. */
+    private static final String SAD_READER = "SadConfigurationReaderTest";
+
+    /** The command to launch the main activity. */
+    private static final String START_COMMAND = String.format(
+            "am start -n %s/%s.%s -a ", PACKAGE, PACKAGE, CLASS);
+
+    /** The command to clear the main activity. */
+    private static final String CLEAR_COMMAND = String.format("pm clear %s", PACKAGE);
+
+    private static final int WAIT_TIME = 10;
+    private static final LogicalAddress AUDIO_DEVICE = LogicalAddress.AUDIO_SYSTEM;
     private static final int ON = 0x1;
+    private static final int OFF = 0x0;
+    private static final int MAX_AUDIO_FORMATS = 4;
+    private static final int MAX_VALID_AUDIO_FORMATS = 2;
+    private static final String SAD_CONFIGURATION_MARKER = "Supported Audio Formats";
+
+    private List<Integer> mSupportedAudioFormats = null;
+
+    public HdmiCecClientWrapper hdmiCecClient = new HdmiCecClientWrapper(AUDIO_DEVICE, "-t", "t");
 
     @Rule
-    public HdmiCecClientWrapper hdmiCecClient = new HdmiCecClientWrapper(AUDIO_DEVICE, this);
+    public RuleChain ruleChain =
+        RuleChain
+            .outerRule(new RequiredFeatureRule(this, LogicalAddress.HDMI_CEC_FEATURE))
+            .around(new RequiredFeatureRule(this, LogicalAddress.LEANBACK_FEATURE))
+            .around(RequiredPropertyRule.asCsvContainsValue(
+                this,
+                LogicalAddress.HDMI_DEVICE_TYPE_PROPERTY,
+                AUDIO_DEVICE.getDeviceType()))
+            .around(hdmiCecClient);
+
+    private void lookForLogFromHdmiCecAudioManager(String expectedOut) throws Exception {
+        ITestDevice device = getDevice();
+        TimeUnit.SECONDS.sleep(WAIT_TIME);
+        String logs = device.executeAdbCommand("logcat", "-v", "brief", "-d", CLASS + ":I", "*:S");
+        // Search for string.
+        String testString = "";
+        Scanner in = new Scanner(logs);
+        while (in.hasNextLine()) {
+            String line = in.nextLine();
+            if(line.startsWith("I/" + CLASS)) {
+                testString = line.split(":")[1].trim();
+                break;
+            }
+        }
+        device.executeAdbCommand("logcat", "-c");
+        assertThat(testString).isEqualTo(expectedOut);
+    }
+
+    private void lookForLogFromSadConfigurationReaderTest(String expectedOut) throws Exception {
+        ITestDevice device = getDevice();
+        TimeUnit.SECONDS.sleep(WAIT_TIME);
+        String logs =
+                device.executeAdbCommand("logcat", "-v", "brief", "-d", SAD_READER + ":I", "*:S");
+        // Search for string.
+        String testString = "";
+        Scanner in = new Scanner(logs);
+        while (in.hasNextLine()) {
+            String line = in.nextLine();
+            if (line.startsWith("I/" + SAD_READER)) {
+                testString = line.split(":")[1].trim();
+                if (testString.equals(SAD_CONFIGURATION_MARKER)) {
+                    List<String> mFormatsLine =
+                            Arrays.asList(in.nextLine().split(":")[1].trim().split(", "));
+                    List<String> mCodecSADsLine =
+                            Arrays.asList(in.nextLine().split(":")[1].trim().split(", "));
+                    mSupportedAudioFormats =
+                            Lists.transform(mFormatsLine, fl -> Integer.parseInt(fl));
+                    break;
+                }
+            }
+        }
+        device.executeAdbCommand("logcat", "-c");
+        assumeTrue(testString.equals(expectedOut));
+    }
+
+    private String getRequestSadFormatsParams(boolean sendValidFormats) throws Exception {
+        ITestDevice device = getDevice();
+        // Clear activity
+        device.executeShellCommand(CLEAR_COMMAND);
+        // Clear logcat.
+        device.executeAdbCommand("logcat", "-c");
+        // Start the APK and wait for it to complete.
+        device.executeShellCommand(START_COMMAND + "android.hdmicec.app.GET_SUPPORTED_SAD_FORMATS");
+        lookForLogFromSadConfigurationReaderTest(SAD_CONFIGURATION_MARKER);
+
+        // Create a list of all the audio format codes according to CEA-861-D. Remove the supported
+        // audio format codes from it, to get the unsupported audio format codes.
+        List<Integer> mAllCodecFormats =
+                IntStream.range(1, 15).boxed().collect(Collectors.toList());
+        List<Integer> unsupportedAudioFormats = new ArrayList<>();
+        unsupportedAudioFormats.addAll(mAllCodecFormats);
+        unsupportedAudioFormats.removeAll(mSupportedAudioFormats);
+        // Create params message for REQUEST_SHORT_AUDIO_DESCRIPTOR
+        String messageParams = "";
+        int i = 0;
+        int listIndex = 0;
+        if (sendValidFormats) {
+            while (i < Math.min(MAX_VALID_AUDIO_FORMATS, mSupportedAudioFormats.size())) {
+                messageParams +=
+                        CecMessage.formatParams(mSupportedAudioFormats.get(listIndex), 2);
+                i++;
+                listIndex++;
+            }
+            listIndex = 0;
+        }
+        while (i < Math.min(MAX_AUDIO_FORMATS, unsupportedAudioFormats.size())) {
+            messageParams += CecMessage.formatParams(unsupportedAudioFormats.get(listIndex), 2);
+            i++;
+            listIndex++;
+        }
+        return messageParams;
+    }
+
+    private void muteDevice() throws Exception {
+        ITestDevice device = getDevice();
+        // Clear activity
+        device.executeShellCommand(CLEAR_COMMAND);
+        // Clear logcat.
+        device.executeAdbCommand("logcat", "-c");
+        // Start the APK and wait for it to complete.
+        device.executeShellCommand(START_COMMAND + "android.hdmicec.app.MUTE");
+    }
+
+    private void unmuteDevice() throws Exception {
+        ITestDevice device = getDevice();
+        // Clear activity
+        device.executeShellCommand(CLEAR_COMMAND);
+        // Start the APK and wait for it to complete.
+        device.executeShellCommand(START_COMMAND + "android.hdmicec.app.UNMUTE");
+    }
+
+    public boolean isDeviceMuted() throws Exception {
+        ITestDevice device = getDevice();
+        // Clear activity
+        device.executeShellCommand(CLEAR_COMMAND);
+        // Clear logcat.
+        device.executeAdbCommand("logcat", "-c");
+        // Start the APK and wait for it to complete.
+        device.executeShellCommand(START_COMMAND + "android.hdmicec.app.REPORT_VOLUME");
+        try {
+            lookForLogFromHdmiCecAudioManager("Device muted.");
+            return true;
+        } catch(Exception e) {
+            return false;
+        }
+    }
+
+    public void setDeviceVolume(int percentVolume) throws Exception {
+        ITestDevice device = getDevice();
+        // Clear activity
+        device.executeShellCommand(CLEAR_COMMAND);
+        // Start the APK and wait for it to complete.
+        device.executeShellCommand(START_COMMAND + "android.hdmicec.app.SET_VOLUME --ei " +
+                "\"volumePercent\" " + percentVolume);
+    }
+
+    public void sendSystemAudioModeTermination() throws Exception {
+        hdmiCecClient.sendCecMessage(LogicalAddress.TV, AUDIO_DEVICE,
+                CecOperand.SYSTEM_AUDIO_MODE_REQUEST);
+    }
+
+    public void sendSystemAudioModeInitiation() throws Exception {
+        hdmiCecClient.sendCecMessage(LogicalAddress.TV, AUDIO_DEVICE,
+                CecOperand.SYSTEM_AUDIO_MODE_REQUEST,
+                CecMessage.formatParams(HdmiCecConstants.TV_PHYSICAL_ADDRESS,
+                    HdmiCecConstants.PHYSICAL_ADDRESS_LENGTH));
+    }
+
+    private int getDutAudioStatus() throws Exception {
+        hdmiCecClient.sendCecMessage(LogicalAddress.TV, AUDIO_DEVICE, CecOperand.GIVE_AUDIO_STATUS);
+        String message = hdmiCecClient.checkExpectedOutput(LogicalAddress.TV,
+                CecOperand.REPORT_AUDIO_STATUS);
+        return CecMessage.getParams(message);
+    }
+
+    private void initateSystemAudioModeFromTuner() throws Exception {
+        getDevice().reboot();
+        hdmiCecClient.sendCecMessage(LogicalAddress.TUNER_1, AUDIO_DEVICE,
+                CecOperand.SYSTEM_AUDIO_MODE_REQUEST,
+                CecMessage.formatParams(HdmiCecConstants.TV_PHYSICAL_ADDRESS,
+                        HdmiCecConstants.PHYSICAL_ADDRESS_LENGTH));
+        handleSetSystemAudioModeOnToTv();
+    }
+
+    private void handleSetSystemAudioModeOnToTv() throws Exception {
+        hdmiCecClient.checkExpectedOutput(CecOperand.REQUEST_ACTIVE_SOURCE);
+        hdmiCecClient.sendCecMessage(LogicalAddress.TV, LogicalAddress.BROADCAST, CecOperand.ACTIVE_SOURCE,
+                CecMessage.formatParams("2000"));
+        String message = hdmiCecClient.checkExpectedOutput(LogicalAddress.TV,
+                CecOperand.SET_SYSTEM_AUDIO_MODE);
+        assertThat(CecMessage.getParams(message)).isEqualTo(ON);
+    }
+
+    private void initiateSystemAudioModeFromDut() throws Exception {
+        getDevice().reboot();
+        hdmiCecClient.checkExpectedOutput(CecOperand.REPORT_PHYSICAL_ADDRESS);
+        hdmiCecClient.sendCecMessage(LogicalAddress.TV, LogicalAddress.AUDIO_SYSTEM,
+                CecOperand.GIVE_SYSTEM_AUDIO_MODE_STATUS);
+        hdmiCecClient.checkExpectedOutput(LogicalAddress.TV, CecOperand.INITIATE_ARC);
+        hdmiCecClient.sendCecMessage(LogicalAddress.TV, LogicalAddress.AUDIO_SYSTEM,
+                CecOperand.ARC_INITIATED);
+        handleSetSystemAudioModeOnToTv();
+    }
+
+    @After
+    public void resetVolume() throws Exception {
+        setDeviceVolume(20);
+    }
 
     /**
      * Test 11.2.15-1
@@ -47,17 +278,303 @@
      */
     @Test
     public void cect_11_2_15_1_SystemAudioModeRequestAsFollower() throws Exception {
-        hdmiCecClient.sendCecMessage(CecDevice.TV, AUDIO_DEVICE,
-                CecMessage.SYSTEM_AUDIO_MODE_REQUEST,
-                hdmiCecClient.formatParams(HdmiCecConstants.TV_PHYSICAL_ADDRESS));
-        String message = hdmiCecClient.checkExpectedOutput(CecMessage.SET_SYSTEM_AUDIO_MODE);
-        assertThat(hdmiCecClient.getParamsFromMessage(message), is(ON));
+        hdmiCecClient.sendCecMessage(LogicalAddress.TV, AUDIO_DEVICE,
+                CecOperand.SYSTEM_AUDIO_MODE_REQUEST,
+                CecMessage.formatParams(HdmiCecConstants.TV_PHYSICAL_ADDRESS));
+        String message = hdmiCecClient.checkExpectedOutput(CecOperand.SET_SYSTEM_AUDIO_MODE);
+        assertThat(CecMessage.getParams(message)).isEqualTo(ON);
 
         /* Repeat test for device 0x3 (TUNER_1) */
-        hdmiCecClient.sendCecMessage(CecDevice.TUNER_1, AUDIO_DEVICE,
-                CecMessage.SYSTEM_AUDIO_MODE_REQUEST,
-                hdmiCecClient.formatParams(HdmiCecConstants.TV_PHYSICAL_ADDRESS));
-        message = hdmiCecClient.checkExpectedOutput(CecMessage.SET_SYSTEM_AUDIO_MODE);
-        assertThat(hdmiCecClient.getParamsFromMessage(message), is(ON));
+        hdmiCecClient.sendCecMessage(LogicalAddress.TUNER_1, AUDIO_DEVICE,
+                CecOperand.SYSTEM_AUDIO_MODE_REQUEST,
+                CecMessage.formatParams(HdmiCecConstants.TV_PHYSICAL_ADDRESS));
+        message = hdmiCecClient.checkExpectedOutput(CecOperand.SET_SYSTEM_AUDIO_MODE);
+        assertThat(CecMessage.getParams(message)).isEqualTo(ON);
+    }
+
+    /**
+     * Test 11.2.15-2
+     * Tests that the device issues <Set System Audio Mode>
+     * message when the feature is initiated in the device .
+     */
+    @Test
+    public void cect_11_2_15_2_SystemAudioModeWithFeatureInitiation() throws Exception {
+        initiateSystemAudioModeFromDut();
+        String message = hdmiCecClient.checkExpectedOutput(CecOperand.SET_SYSTEM_AUDIO_MODE);
+        assertThat(CecMessage.getParams(message)).isEqualTo(ON);
+    }
+
+    /**
+     * Test 11.2.15-3
+     * Tests that the device doesn't broadcast any <Set System Audio Mode>
+     * messages when TV responds with a <Feature Abort> to a directly addressed
+     * <Set System Audio Mode> message.
+     */
+    @Test
+    public void cect_11_2_15_3_SystemAudioModeWithFeatureAbort() throws Exception {
+        initiateSystemAudioModeFromDut();
+        hdmiCecClient.sendCecMessage(LogicalAddress.TV, AUDIO_DEVICE, CecOperand.FEATURE_ABORT,
+                CecMessage.formatParams(CecOperand.SET_SYSTEM_AUDIO_MODE + "04"));
+        hdmiCecClient.checkOutputDoesNotContainMessage(LogicalAddress.BROADCAST,
+                CecOperand.SET_SYSTEM_AUDIO_MODE);
+        //The DUT will need a reboot here so it'll forget the feature abort from the previous
+        // message. Else it may not respond correctly with a SET_SYSTEM_AUDIO_MODE message
+        // in future tests.
+        getDevice().reboot();
+    }
+
+    /**
+     * Test 11.2.15-4
+     * Tests that the device responds correctly to a <Give System Audio Status>
+     * message when System Audio Mode is "On".
+     */
+    @Test
+    public void cect_11_2_15_4_SystemAudioModeStatusOn() throws Exception {
+        sendSystemAudioModeInitiation();
+        String message = hdmiCecClient.checkExpectedOutput(CecOperand.SET_SYSTEM_AUDIO_MODE);
+        assertThat(CecMessage.getParams(message)).isEqualTo(ON);
+        hdmiCecClient.sendCecMessage(LogicalAddress.TV, AUDIO_DEVICE,
+                CecOperand.GIVE_SYSTEM_AUDIO_MODE_STATUS);
+        message = hdmiCecClient.checkExpectedOutput(LogicalAddress.TV,
+                CecOperand.SYSTEM_AUDIO_MODE_STATUS);
+        assertThat(CecMessage.getParams(message)).isEqualTo(ON);
+    }
+
+    /**
+     * Test 11.2.15-5
+     * Tests that the device sends a <Set System Audio Mode> ["Off"]
+     * message when a <System Audio Mode Request> is received with no operands
+     */
+    @Test
+    public void cect_11_2_15_5_SetSystemAudioModeOff() throws Exception {
+        sendSystemAudioModeInitiation();
+        String message = hdmiCecClient.checkExpectedOutput(CecOperand.SET_SYSTEM_AUDIO_MODE);
+        assertThat(CecMessage.getParams(message)).isEqualTo(ON);
+        sendSystemAudioModeTermination();
+        message = hdmiCecClient.checkExpectedOutput(CecOperand.SET_SYSTEM_AUDIO_MODE);
+        assertThat(CecMessage.getParams(message)).isEqualTo(OFF);
+    }
+
+    /**
+     * Test 11.2.15-6
+     * Tests that the device sends a <Set System Audio Mode> ["Off"]
+     * message before going into standby when System Audio Mode is on.
+     */
+    @Test
+    public void cect_11_2_15_6_SystemAudioModeOffBeforeStandby() throws Exception {
+        try {
+            getDevice().executeShellCommand("input keyevent KEYCODE_WAKEUP");
+            sendSystemAudioModeInitiation();
+            String message = hdmiCecClient.checkExpectedOutput(CecOperand.SET_SYSTEM_AUDIO_MODE);
+            assertThat(CecMessage.getParams(message)).isEqualTo(ON);
+            getDevice().executeShellCommand("input keyevent KEYCODE_SLEEP");
+            message = hdmiCecClient.checkExpectedOutput(CecOperand.SET_SYSTEM_AUDIO_MODE);
+            assertThat(CecMessage.getParams(message)).isEqualTo(OFF);
+        } finally {
+            getDevice().executeShellCommand("input keyevent KEYCODE_WAKEUP");
+        }
+    }
+
+    /**
+    * Test 11.2.15-7
+    * Tests that the device responds correctly to a <Give System Audio Mode Status>
+    * message when the System Audio Mode is "Off".
+    */
+   @Test
+    public void cect_11_2_15_7_SystemAudioModeStatusOff() throws Exception {
+        hdmiCecClient.sendCecMessage(LogicalAddress.TV, AUDIO_DEVICE,
+                CecOperand.SET_SYSTEM_AUDIO_MODE, CecMessage.formatParams(OFF));
+        hdmiCecClient.sendCecMessage(LogicalAddress.TV, AUDIO_DEVICE,
+                CecOperand.GIVE_SYSTEM_AUDIO_MODE_STATUS);
+        String message = hdmiCecClient.checkExpectedOutput(LogicalAddress.TV,
+                CecOperand.SYSTEM_AUDIO_MODE_STATUS);
+        assertThat(CecMessage.getParams(message)).isEqualTo(OFF);
+    }
+
+    /**
+     * Test 11.2.15-8
+     * Tests that the device handles <User Controlled Pressed> ["Mute"]
+     * correctly when System Audio Mode is "On".
+     */
+    @Test
+    public void cect_11_2_15_8_HandleUcpMute() throws Exception {
+        unmuteDevice();
+        hdmiCecClient.sendCecMessage(LogicalAddress.TV, AUDIO_DEVICE,
+                CecOperand.SYSTEM_AUDIO_MODE_REQUEST,
+                CecMessage.formatParams(HdmiCecConstants.TV_PHYSICAL_ADDRESS));
+        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, AUDIO_DEVICE,
+                HdmiCecConstants.CEC_CONTROL_MUTE, false);
+        assertWithMessage("Device is not muted").that(isDeviceMuted()).isTrue();
+    }
+
+    /**
+     * Test 11.2.15-9
+     * Tests that the DUT responds with a <Report Audio Status> message with correct parameters
+     * to a <Give Audio Status> message when volume is set to 0% and not muted.
+     */
+    @Test
+    public void cect_11_2_15_9_ReportAudioStatus_0_unmuted() throws Exception {
+        sendSystemAudioModeInitiation();
+        unmuteDevice();
+        setDeviceVolume(0);
+        int reportedVolume = getDutAudioStatus();
+        assertThat(reportedVolume).isEqualTo(0);
+    }
+
+    /**
+     * Test 11.2.15-9
+     * Tests that the DUT responds with a <Report Audio Status> message with correct parameters
+     * to a <Give Audio Status> message when volume is set to 50% and not muted.
+     */
+    @Test
+    public void cect_11_2_15_9_ReportAudioStatus_50_unmuted() throws Exception {
+        sendSystemAudioModeInitiation();
+        unmuteDevice();
+        setDeviceVolume(50);
+        int reportedVolume = getDutAudioStatus();
+        /* Allow for a range of volume, since the actual volume set will depend on the device's
+        volume resolution. */
+        assertThat(reportedVolume).isIn(Range.closed(46, 54));
+    }
+
+    /**
+     * Test 11.2.15-9
+     * Tests that the DUT responds with a <Report Audio Status> message with correct parameters
+     * to a <Give Audio Status> message when volume is set to 100% and not muted.
+     */
+    @Test
+    public void cect_11_2_15_9_ReportAudioStatus_100_unmuted() throws Exception {
+        sendSystemAudioModeInitiation();
+        unmuteDevice();
+        setDeviceVolume(100);
+        int reportedVolume = getDutAudioStatus();
+        assertThat(reportedVolume).isEqualTo(100);
+    }
+
+    /**
+     * Test 11.2.15-9
+     * Tests that the DUT responds with a <Report Audio Status> message with correct parameters
+     * to a <Give Audio Status> message when volume is muted.
+     */
+    @Test
+    public void cect_11_2_15_9_ReportAudioStatusMuted() throws Exception {
+        sendSystemAudioModeInitiation();
+        muteDevice();
+        int reportedVolume = getDutAudioStatus();
+        /* If device is muted, the 8th bit of CEC message parameters is set and the volume will
+        be greater than 127. */
+        assertWithMessage("Device not muted").that(reportedVolume).isGreaterThan(127);
+    }
+
+    /**
+     * Test 11.2.15-13
+     * Tests that the device responds to a <Request Short Audio Descriptor> message with a
+     * <Report Short Audio Descriptor> message with only those audio descriptors that are supported.
+     */
+    @Test
+    public void cect_11_2_15_13_ValidShortAudioDescriptor() throws Exception {
+        hdmiCecClient.sendCecMessage(LogicalAddress.TV, AUDIO_DEVICE,
+                CecOperand.REQUEST_SHORT_AUDIO_DESCRIPTOR, getRequestSadFormatsParams(true));
+        String message = hdmiCecClient.checkExpectedOutput(LogicalAddress.TV,
+                CecOperand.REPORT_SHORT_AUDIO_DESCRIPTOR);
+        /* Each Short Audio Descriptor is 3 bytes long. In the first byte of the params, bits 3-6
+         * will have the audio format. Bit 7 will always 0 for audio format defined in CEA-861-D.
+         * Bits 0-2 represent (Max number of channels - 1). Discard bits 0-2 and check for the
+         * format.
+         * Iterate the params by 3 bytes(6 nibbles) and extract only the first byte(2 nibbles).
+         */
+        for (int i = 0; i < Math.min(mSupportedAudioFormats.size(), MAX_VALID_AUDIO_FORMATS); i++) {
+            int audioFormat =
+                    CecMessage.getParams(message, 6 * i, 6 * i + 2) >>> 3;
+            assertWithMessage("Could not find audio format " + audioFormat)
+                    .that(mSupportedAudioFormats).contains(audioFormat);
+        }
+    }
+
+    /**
+     * Test 11.2.15-14
+     * Tests that the device responds to a <Request Short Audio Descriptor> message with a
+     * <Feature Abort> [“Invalid Operand”] when a <Request Short Audio Descriptor> message is
+     * received with a single [Audio Format ID][Audio Format Code] pair that is not supported.
+     */
+    @Test
+    public void cect_11_2_15_14_InvalidShortAudioDescriptor() throws Exception {
+        hdmiCecClient.sendCecMessage(LogicalAddress.TV, AUDIO_DEVICE,
+                CecOperand.REQUEST_SHORT_AUDIO_DESCRIPTOR, getRequestSadFormatsParams(false));
+        String message = hdmiCecClient.checkExpectedOutput(LogicalAddress.TV, CecOperand.FEATURE_ABORT);
+        assertThat(CecOperand.getOperand(CecMessage.getParams(message, 2)))
+                .isEqualTo(CecOperand.REQUEST_SHORT_AUDIO_DESCRIPTOR);
+        assertThat(CecMessage.getParams(message, 2, 4))
+                .isEqualTo(HdmiCecConstants.ABORT_INVALID_OPERAND);
+    }
+
+    /**
+     * Test 11.2.15-16
+     * Tests that the device unmute its volume when it broadcasts a
+     * <Set System Audio Mode> ["On"] message
+     */
+    @Test
+    public void cect_11_2_15_16_UnmuteForSystemAudioRequestOn() throws Exception {
+        muteDevice();
+        sendSystemAudioModeTermination();
+        String message = hdmiCecClient.checkExpectedOutput(CecOperand.SET_SYSTEM_AUDIO_MODE);
+        assertThat(CecMessage.getParams(message)).isEqualTo(OFF);
+        hdmiCecClient.sendCecMessage(LogicalAddress.TV, AUDIO_DEVICE,
+                CecOperand.SYSTEM_AUDIO_MODE_REQUEST,
+                CecMessage.formatParams(HdmiCecConstants.TV_PHYSICAL_ADDRESS,
+                    HdmiCecConstants.PHYSICAL_ADDRESS_LENGTH));
+        message = hdmiCecClient.checkExpectedOutput(CecOperand.SET_SYSTEM_AUDIO_MODE);
+        assertThat(CecMessage.getParams(message)).isEqualTo(ON);
+        assertWithMessage("Device muted").that(isDeviceMuted()).isFalse();
+    }
+
+    /**
+     * Test 11.2.15-17
+     * Tests that the device mute its volume when it broadcasts a
+     * <Set System Audio Mode> ["Off"] message
+     */
+    @Test
+    public void cect_11_2_15_17_MuteForSystemAudioRequestOff() throws Exception {
+        hdmiCecClient.sendCecMessage(LogicalAddress.TV, AUDIO_DEVICE,
+                CecOperand.SYSTEM_AUDIO_MODE_REQUEST,
+                CecMessage.formatParams(HdmiCecConstants.TV_PHYSICAL_ADDRESS,
+                    HdmiCecConstants.PHYSICAL_ADDRESS_LENGTH));
+        String message = hdmiCecClient.checkExpectedOutput(CecOperand.SET_SYSTEM_AUDIO_MODE);
+        assertThat(CecMessage.getParams(message)).isEqualTo(ON);
+        sendSystemAudioModeTermination();
+        message = hdmiCecClient.checkExpectedOutput(CecOperand.SET_SYSTEM_AUDIO_MODE);
+        assertThat(CecMessage.getParams(message)).isEqualTo(OFF);
+        assertWithMessage("Device not muted").that(isDeviceMuted()).isTrue();
+    }
+
+    /**
+     * Test 11.2.15-18
+     * Tests that the device doesn't broadcast <Set System Audio Mode>
+     * messages if TV responds with a <Feature Abort> message to directly addressed
+     * <Set System Audio Mode> message within the required maximum response time of 1 second.
+     */
+    @Test
+    public void cect_11_2_15_18_SystemAudioModeWithFeatureAbortWithinTime() throws Exception {
+        initiateSystemAudioModeFromDut();
+        hdmiCecClient.sendCecMessage(LogicalAddress.TV, AUDIO_DEVICE, CecOperand.FEATURE_ABORT,
+                CecMessage.formatParams(CecOperand.SET_SYSTEM_AUDIO_MODE + "04"));
+        hdmiCecClient.checkOutputDoesNotContainMessage(LogicalAddress.BROADCAST,
+                CecOperand.SET_SYSTEM_AUDIO_MODE);
+    }
+
+    /**
+     * Test 11.2.15-19
+     * Tests that the device doesn't broadcast <Set System Audio Mode>
+     * messages if TV responds with a <Feature Abort> message to directly addressed
+     * <Set System Audio Mode> message within the required maximum response time of 1 second.
+     * The <Set System Audio Mode> message should be initiated from logical address 3.
+     */
+    @Test
+    public void cect_11_2_15_19_SystemAudioModeWithFeatureAbortWithinTime() throws Exception {
+        initateSystemAudioModeFromTuner();
+        hdmiCecClient.sendCecMessage(LogicalAddress.TV, AUDIO_DEVICE, CecOperand.FEATURE_ABORT,
+                CecMessage.formatParams(CecOperand.SET_SYSTEM_AUDIO_MODE + "04"));
+        hdmiCecClient.checkOutputDoesNotContainMessage(LogicalAddress.BROADCAST,
+            CecOperand.SET_SYSTEM_AUDIO_MODE);
     }
 }
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecDeviceTypeTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecDeviceTypeTest.java
new file mode 100644
index 0000000..4c716cc
--- /dev/null
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecDeviceTypeTest.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hdmicec.cts.common;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Scanner;
+
+/** Tests to see that a valid HDMI CEC device type is declared by the device. */
+@RunWith(DeviceJUnit4ClassRunner.class)
+public final class HdmiCecDeviceTypeTest extends BaseHostJUnit4Test {
+
+    private static List<String> validTypes = new ArrayList<>(
+        Arrays.asList("", "0", "4", "4,5", "5,4"));
+    /**
+     * Tests that the device declares a valid HDMI CEC device type.
+     */
+    @Test
+    public void checkHdmiCecDeviceType() throws Exception {
+        ITestDevice device = getDevice();
+        String logs = device.executeShellCommand("cmd package list features");
+        Scanner in = new Scanner(logs);
+        while (in.hasNextLine()) {
+            String line = in.nextLine();
+            if (line.equals("feature:android.software.leanback")) {
+                // Remove "" as valid device type if android.software.leanback feature is supported
+                validTypes.remove("");
+            }
+        }
+        String deviceType = device.executeShellCommand("getprop ro.hdmi.device_type");
+        assertThat(deviceType.trim()).isIn(validTypes);
+    }
+}
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecDeviceOsdNameTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecDeviceOsdNameTest.java
index cda2951..ef10425 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecDeviceOsdNameTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecDeviceOsdNameTest.java
@@ -16,28 +16,42 @@
 
 package android.hdmicec.cts.playback;
 
-import static org.junit.Assert.assertEquals;
+import static com.google.common.truth.Truth.assertThat;
 
-import android.hdmicec.cts.CecDevice;
 import android.hdmicec.cts.CecMessage;
+import android.hdmicec.cts.CecOperand;
 import android.hdmicec.cts.HdmiCecClientWrapper;
+import android.hdmicec.cts.LogicalAddress;
+import android.hdmicec.cts.RequiredPropertyRule;
+import android.hdmicec.cts.RequiredFeatureRule;
 
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
 
 import org.junit.Rule;
+import org.junit.rules.RuleChain;
 import org.junit.runner.RunWith;
 import org.junit.Test;
 
 /** HDMI CEC tests related to the device reporting the device OSD name (Section 11.2.11) */
 @RunWith(DeviceJUnit4ClassRunner.class)
 public final class HdmiCecDeviceOsdNameTest extends BaseHostJUnit4Test {
-    private static final CecDevice PLAYBACK_DEVICE = CecDevice.PLAYBACK_1;
+
+    private static final LogicalAddress PLAYBACK_DEVICE = LogicalAddress.PLAYBACK_1;
+
+    public HdmiCecClientWrapper hdmiCecClient = new HdmiCecClientWrapper(LogicalAddress.PLAYBACK_1);
 
     @Rule
-    public HdmiCecClientWrapper hdmiCecClient =
-        new HdmiCecClientWrapper(CecDevice.PLAYBACK_1, this);
+    public RuleChain ruleChain =
+        RuleChain
+            .outerRule(new RequiredFeatureRule(this, LogicalAddress.HDMI_CEC_FEATURE))
+            .around(new RequiredFeatureRule(this, LogicalAddress.LEANBACK_FEATURE))
+            .around(RequiredPropertyRule.asCsvContainsValue(
+                this,
+                LogicalAddress.HDMI_DEVICE_TYPE_PROPERTY,
+                LogicalAddress.PLAYBACK_1.getDeviceType()))
+            .around(hdmiCecClient);
 
     /**
      * Test 11.2.11-1a
@@ -53,9 +67,9 @@
         if (deviceName.length() > nameLength) {
             deviceName = deviceName.substring(0, nameLength).trim();
         }
-        hdmiCecClient.sendCecMessage(CecDevice.TV, CecMessage.GIVE_OSD_NAME);
-        String message = hdmiCecClient.checkExpectedOutput(CecDevice.TV, CecMessage.SET_OSD_NAME);
-        assertEquals(deviceName, hdmiCecClient.getAsciiStringFromMessage(message));
+        hdmiCecClient.sendCecMessage(LogicalAddress.TV, CecOperand.GIVE_OSD_NAME);
+        String message = hdmiCecClient.checkExpectedOutput(LogicalAddress.TV, CecOperand.SET_OSD_NAME);
+        assertThat(CecMessage.getAsciiString(message)).isEqualTo(deviceName);
     }
 
     /**
@@ -70,10 +84,10 @@
         String originalName = device.executeShellCommand("settings get global device_name").trim();
         try {
             device.executeShellCommand("settings put global device_name '" + testName + "'");
-            hdmiCecClient.sendCecMessage(CecDevice.TV, CecMessage.GIVE_OSD_NAME);
-            String message = hdmiCecClient.checkExpectedOutput(CecDevice.TV,
-                    CecMessage.SET_OSD_NAME);
-            assertEquals(testName, hdmiCecClient.getAsciiStringFromMessage(message));
+            hdmiCecClient.sendCecMessage(LogicalAddress.TV, CecOperand.GIVE_OSD_NAME);
+            String message = hdmiCecClient.checkExpectedOutput(LogicalAddress.TV,
+                    CecOperand.SET_OSD_NAME);
+            assertThat(CecMessage.getAsciiString(message)).isEqualTo(testName);
         } finally {
             device.executeShellCommand("settings put global device_name '" + originalName + "'");
         }
@@ -85,11 +99,11 @@
      */
     @Test
     public void cect_11_2_11_2_UnregisteredDeviceGiveOsdNameTest() throws Exception {
-        hdmiCecClient.sendCecMessage(CecDevice.PLAYBACK_1, CecMessage.GIVE_OSD_NAME);
-        hdmiCecClient.checkOutputDoesNotContainMessage(CecDevice.PLAYBACK_1,
-                CecMessage.SET_OSD_NAME);
-        hdmiCecClient.sendCecMessage(CecDevice.BROADCAST, CecMessage.GIVE_OSD_NAME);
-        hdmiCecClient.checkOutputDoesNotContainMessage(CecDevice.BROADCAST,
-                CecMessage.SET_OSD_NAME);
+        hdmiCecClient.sendCecMessage(LogicalAddress.PLAYBACK_1, CecOperand.GIVE_OSD_NAME);
+        hdmiCecClient.checkOutputDoesNotContainMessage(LogicalAddress.PLAYBACK_1,
+                CecOperand.SET_OSD_NAME);
+        hdmiCecClient.sendCecMessage(LogicalAddress.BROADCAST, CecOperand.GIVE_OSD_NAME);
+        hdmiCecClient.checkOutputDoesNotContainMessage(LogicalAddress.BROADCAST,
+                CecOperand.SET_OSD_NAME);
     }
 }
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecLogicalAddressTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecLogicalAddressTest.java
index 83c9120..d48a6cd 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecLogicalAddressTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecLogicalAddressTest.java
@@ -16,29 +16,43 @@
 
 package android.hdmicec.cts.playback;
 
-import static org.junit.Assert.assertEquals;
+import static com.google.common.truth.Truth.assertThat;
 
-import android.hdmicec.cts.CecDevice;
 import android.hdmicec.cts.CecMessage;
+import android.hdmicec.cts.CecOperand;
 import android.hdmicec.cts.HdmiCecClientWrapper;
 import android.hdmicec.cts.HdmiCecConstants;
+import android.hdmicec.cts.LogicalAddress;
+import android.hdmicec.cts.RequiredPropertyRule;
+import android.hdmicec.cts.RequiredFeatureRule;
 
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
 
 import org.junit.Rule;
+import org.junit.rules.RuleChain;
 import org.junit.runner.RunWith;
 import org.junit.Test;
 
 /** HDMI CEC test to verify physical address after device reboot (Section 10.2.3) */
 @RunWith(DeviceJUnit4ClassRunner.class)
 public final class HdmiCecLogicalAddressTest extends BaseHostJUnit4Test {
-    private static final CecDevice PLAYBACK_DEVICE = CecDevice.PLAYBACK_1;
+
+    private static final LogicalAddress PLAYBACK_DEVICE = LogicalAddress.PLAYBACK_1;
+
+    public HdmiCecClientWrapper hdmiCecClient = new HdmiCecClientWrapper(LogicalAddress.PLAYBACK_1);
 
     @Rule
-    public HdmiCecClientWrapper hdmiCecClient =
-        new HdmiCecClientWrapper(CecDevice.PLAYBACK_1, this);
+    public RuleChain ruleChain =
+        RuleChain
+            .outerRule(new RequiredFeatureRule(this, LogicalAddress.HDMI_CEC_FEATURE))
+            .around(new RequiredFeatureRule(this, LogicalAddress.LEANBACK_FEATURE))
+            .around(RequiredPropertyRule.asCsvContainsValue(
+                this,
+                LogicalAddress.HDMI_DEVICE_TYPE_PROPERTY,
+                LogicalAddress.PLAYBACK_1.getDeviceType()))
+            .around(hdmiCecClient);
 
     /**
      * Test 10.2.3-1
@@ -50,7 +64,7 @@
         ITestDevice device = getDevice();
         device.executeShellCommand("reboot");
         device.waitForBootComplete(HdmiCecConstants.REBOOT_TIMEOUT);
-        String message = hdmiCecClient.checkExpectedOutput(CecMessage.REPORT_PHYSICAL_ADDRESS);
-        assertEquals(PLAYBACK_DEVICE, hdmiCecClient.getSourceFromMessage(message));
+        String message = hdmiCecClient.checkExpectedOutput(CecOperand.REPORT_PHYSICAL_ADDRESS);
+        assertThat(CecMessage.getSource(message)).isEqualTo(PLAYBACK_DEVICE);
     }
 }
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecOneTouchPlayTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecOneTouchPlayTest.java
index a4ca3d2..56a7df2 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecOneTouchPlayTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecOneTouchPlayTest.java
@@ -16,17 +16,21 @@
 
 package android.hdmicec.cts.playback;
 
-import static org.junit.Assert.assertEquals;
+import static com.google.common.truth.Truth.assertThat;
 
-import android.hdmicec.cts.CecDevice;
 import android.hdmicec.cts.CecMessage;
+import android.hdmicec.cts.CecOperand;
 import android.hdmicec.cts.HdmiCecClientWrapper;
+import android.hdmicec.cts.LogicalAddress;
+import android.hdmicec.cts.RequiredPropertyRule;
+import android.hdmicec.cts.RequiredFeatureRule;
 
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
 
 import org.junit.Rule;
+import org.junit.rules.RuleChain;
 import org.junit.runner.RunWith;
 import org.junit.Test;
 
@@ -36,9 +40,32 @@
 
     private static final int PHYSICAL_ADDRESS = 0x1000;
 
+    /** Intent to launch the remote pairing activity */
+    private static final String ACTION_CONNECT_INPUT_NORMAL =
+            "com.google.android.intent.action.CONNECT_INPUT";
+
+    /** Package name of the Settings app */
+    private static final String SETTINGS_PACKAGE =
+            "com.android.tv.settings";
+
+    /** The command to broadcast an intent. */
+    private static final String START_COMMAND = "am start -a ";
+
+    /** The command to stop an app. */
+    private static final String FORCE_STOP_COMMAND = "am force-stop ";
+
+    public HdmiCecClientWrapper hdmiCecClient = new HdmiCecClientWrapper(LogicalAddress.PLAYBACK_1);
+
     @Rule
-    public HdmiCecClientWrapper hdmiCecClient =
-        new HdmiCecClientWrapper(CecDevice.PLAYBACK_1, this);
+    public RuleChain ruleChain =
+        RuleChain
+            .outerRule(new RequiredFeatureRule(this, LogicalAddress.HDMI_CEC_FEATURE))
+            .around(new RequiredFeatureRule(this, LogicalAddress.LEANBACK_FEATURE))
+            .around(RequiredPropertyRule.asCsvContainsValue(
+                this,
+                LogicalAddress.HDMI_DEVICE_TYPE_PROPERTY,
+                LogicalAddress.PLAYBACK_1.getDeviceType()))
+            .around(hdmiCecClient);
 
     /**
      * Test 11.2.1-1
@@ -48,9 +75,25 @@
     @Test
     public void cect_11_2_1_1_OneTouchPlay() throws Exception {
         ITestDevice device = getDevice();
+        device.reboot();
         device.executeShellCommand("input keyevent KEYCODE_HOME");
-        hdmiCecClient.checkExpectedOutput(CecDevice.TV, CecMessage.TEXT_VIEW_ON);
-        String message = hdmiCecClient.checkExpectedOutput(CecMessage.ACTIVE_SOURCE);
-        assertEquals(PHYSICAL_ADDRESS, hdmiCecClient.getParamsFromMessage(message));
+        hdmiCecClient.checkExpectedOutput(LogicalAddress.TV, CecOperand.TEXT_VIEW_ON);
+        String message = hdmiCecClient.checkExpectedOutput(CecOperand.ACTIVE_SOURCE);
+        assertThat(CecMessage.getParams(message)).isEqualTo(PHYSICAL_ADDRESS);
+    }
+
+    /**
+     * Tests that the device sends a <TEXT_VIEW_ON> when the pairing activity is started on
+     * device, followed by a <ACTIVE_SOURCE> message.
+     */
+    @Test
+    public void cect_PairingActivity_OneTouchPlay() throws Exception {
+        ITestDevice device = getDevice();
+        device.reboot();
+        device.executeShellCommand(START_COMMAND + ACTION_CONNECT_INPUT_NORMAL);
+        hdmiCecClient.checkExpectedOutput(LogicalAddress.TV, CecOperand.TEXT_VIEW_ON);
+        String message = hdmiCecClient.checkExpectedOutput(CecOperand.ACTIVE_SOURCE);
+        assertThat(CecMessage.getParams(message)).isEqualTo(PHYSICAL_ADDRESS);
+        device.executeShellCommand(FORCE_STOP_COMMAND + SETTINGS_PACKAGE);
     }
 }
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecPhysicalAddressTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecPhysicalAddressTest.java
index 91280e7..bae8490 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecPhysicalAddressTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecPhysicalAddressTest.java
@@ -16,18 +16,22 @@
 
 package android.hdmicec.cts.playback;
 
-import static org.junit.Assert.assertEquals;
+import static com.google.common.truth.Truth.assertThat;
 
-import android.hdmicec.cts.CecDevice;
 import android.hdmicec.cts.CecMessage;
+import android.hdmicec.cts.CecOperand;
 import android.hdmicec.cts.HdmiCecClientWrapper;
 import android.hdmicec.cts.HdmiCecConstants;
+import android.hdmicec.cts.LogicalAddress;
+import android.hdmicec.cts.RequiredPropertyRule;
+import android.hdmicec.cts.RequiredFeatureRule;
 
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
 
 import org.junit.Rule;
+import org.junit.rules.RuleChain;
 import org.junit.runner.RunWith;
 import org.junit.Test;
 
@@ -35,9 +39,18 @@
 @RunWith(DeviceJUnit4ClassRunner.class)
 public final class HdmiCecPhysicalAddressTest extends BaseHostJUnit4Test {
 
+    public HdmiCecClientWrapper hdmiCecClient = new HdmiCecClientWrapper(LogicalAddress.PLAYBACK_1);
+
     @Rule
-    public HdmiCecClientWrapper hdmiCecClient =
-        new HdmiCecClientWrapper(CecDevice.PLAYBACK_1, this);
+    public RuleChain ruleChain =
+        RuleChain
+            .outerRule(new RequiredFeatureRule(this, LogicalAddress.HDMI_CEC_FEATURE))
+            .around(new RequiredFeatureRule(this, LogicalAddress.LEANBACK_FEATURE))
+            .around(RequiredPropertyRule.asCsvContainsValue(
+                this,
+                LogicalAddress.HDMI_DEVICE_TYPE_PROPERTY,
+                LogicalAddress.PLAYBACK_1.getDeviceType()))
+            .around(hdmiCecClient);
 
     /**
      * Test 10.1.2-1
@@ -49,9 +62,9 @@
         ITestDevice device = getDevice();
         device.executeShellCommand("reboot");
         device.waitForBootComplete(HdmiCecConstants.REBOOT_TIMEOUT);
-        String message = hdmiCecClient.checkExpectedOutput(CecMessage.REPORT_PHYSICAL_ADDRESS);
-        int physicalAddress = hdmiCecClient.getParamsFromMessage(message,
+        String message = hdmiCecClient.checkExpectedOutput(CecOperand.REPORT_PHYSICAL_ADDRESS);
+        int physicalAddress = CecMessage.getParams(message,
             HdmiCecConstants.PHYSICAL_ADDRESS_LENGTH);
-        assertEquals(HdmiCecConstants.PHYSICAL_ADDRESS, physicalAddress);
+        assertThat(HdmiCecConstants.PHYSICAL_ADDRESS).isEqualTo(physicalAddress);
     }
 }
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecPowerStatusTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecPowerStatusTest.java
index 911d233..b1bfb1e 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecPowerStatusTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecPowerStatusTest.java
@@ -16,18 +16,22 @@
 
 package android.hdmicec.cts.playback;
 
-import static org.junit.Assert.assertEquals;
+import static com.google.common.truth.Truth.assertThat;
 
-import android.hdmicec.cts.CecDevice;
 import android.hdmicec.cts.CecMessage;
+import android.hdmicec.cts.CecOperand;
 import android.hdmicec.cts.HdmiCecClientWrapper;
 import android.hdmicec.cts.HdmiCecConstants;
+import android.hdmicec.cts.LogicalAddress;
+import android.hdmicec.cts.RequiredPropertyRule;
+import android.hdmicec.cts.RequiredFeatureRule;
 
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
 
 import org.junit.Rule;
+import org.junit.rules.RuleChain;
 import org.junit.runner.RunWith;
 import org.junit.Test;
 
@@ -42,9 +46,18 @@
 
     private static final int WAIT_TIME = 5;
 
+    public HdmiCecClientWrapper hdmiCecClient = new HdmiCecClientWrapper(LogicalAddress.PLAYBACK_1);
+
     @Rule
-    public HdmiCecClientWrapper hdmiCecClient =
-        new HdmiCecClientWrapper(CecDevice.PLAYBACK_1, this);
+    public RuleChain ruleChain =
+        RuleChain
+            .outerRule(new RequiredFeatureRule(this, LogicalAddress.HDMI_CEC_FEATURE))
+            .around(new RequiredFeatureRule(this, LogicalAddress.LEANBACK_FEATURE))
+            .around(RequiredPropertyRule.asCsvContainsValue(
+                this,
+                LogicalAddress.HDMI_DEVICE_TYPE_PROPERTY,
+                LogicalAddress.PLAYBACK_1.getDeviceType()))
+            .around(hdmiCecClient);
 
     /**
      * Test 11.2.14-1
@@ -56,10 +69,10 @@
         ITestDevice device = getDevice();
         /* Make sure the device is not booting up/in standby */
         device.waitForBootComplete(HdmiCecConstants.REBOOT_TIMEOUT);
-        hdmiCecClient.sendCecMessage(CecDevice.TV, CecMessage.GIVE_POWER_STATUS);
-        String message = hdmiCecClient.checkExpectedOutput(CecDevice.TV,
-                                                            CecMessage.REPORT_POWER_STATUS);
-        assertEquals(ON, hdmiCecClient.getParamsFromMessage(message));
+        hdmiCecClient.sendCecMessage(LogicalAddress.TV, CecOperand.GIVE_POWER_STATUS);
+        String message = hdmiCecClient.checkExpectedOutput(LogicalAddress.TV,
+            CecOperand.REPORT_POWER_STATUS);
+        assertThat(CecMessage.getParams(message)).isEqualTo(ON);
     }
 
     /**
@@ -73,12 +86,14 @@
         try {
             /* Make sure the device is not booting up/in standby */
             device.waitForBootComplete(HdmiCecConstants.REBOOT_TIMEOUT);
+            /* Home Key to prevent device from going to deep suspend state */
+            device.executeShellCommand("input keyevent KEYCODE_HOME");
             device.executeShellCommand("input keyevent KEYCODE_SLEEP");
             TimeUnit.SECONDS.sleep(WAIT_TIME);
-            hdmiCecClient.sendCecMessage(CecDevice.TV, CecMessage.GIVE_POWER_STATUS);
-            String message = hdmiCecClient.checkExpectedOutput(CecDevice.TV,
-                                                              CecMessage.REPORT_POWER_STATUS);
-            assertEquals(OFF, hdmiCecClient.getParamsFromMessage(message));
+            hdmiCecClient.sendCecMessage(LogicalAddress.TV, CecOperand.GIVE_POWER_STATUS);
+            String message = hdmiCecClient.checkExpectedOutput(LogicalAddress.TV,
+                CecOperand.REPORT_POWER_STATUS);
+            assertThat(CecMessage.getParams(message)).isEqualTo(OFF);
         } finally {
             /* Wake up the device */
             device.executeShellCommand("input keyevent KEYCODE_WAKEUP");
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecRemoteControlPassThroughTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecRemoteControlPassThroughTest.java
index 9ac7eab..160e80f 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecRemoteControlPassThroughTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecRemoteControlPassThroughTest.java
@@ -16,17 +16,20 @@
 
 package android.hdmicec.cts.playback;
 
-import static org.junit.Assert.assertEquals;
+import static com.google.common.truth.Truth.assertThat;
 
-import android.hdmicec.cts.CecDevice;
 import android.hdmicec.cts.HdmiCecClientWrapper;
 import android.hdmicec.cts.HdmiCecConstants;
+import android.hdmicec.cts.LogicalAddress;
+import android.hdmicec.cts.RequiredPropertyRule;
+import android.hdmicec.cts.RequiredFeatureRule;
 
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
 
 import org.junit.Rule;
+import org.junit.rules.RuleChain;
 import org.junit.runner.RunWith;
 import org.junit.Test;
 
@@ -57,11 +60,30 @@
 
     private static final int WAIT_TIME = 10;
 
+    public HdmiCecClientWrapper hdmiCecClient = new HdmiCecClientWrapper(LogicalAddress.PLAYBACK_1);
+
     @Rule
-    public HdmiCecClientWrapper hdmiCecClient =
-            new HdmiCecClientWrapper(CecDevice.PLAYBACK_1, this);
+    public RuleChain ruleChain =
+        RuleChain
+            .outerRule(new RequiredFeatureRule(this, LogicalAddress.HDMI_CEC_FEATURE))
+            .around(new RequiredFeatureRule(this, LogicalAddress.LEANBACK_FEATURE))
+            .around(RequiredPropertyRule.asCsvContainsValue(
+                this,
+                LogicalAddress.HDMI_DEVICE_TYPE_PROPERTY,
+                LogicalAddress.PLAYBACK_1.getDeviceType()))
+            .around(hdmiCecClient);
 
     private void lookForLog(String expectedOut) throws Exception {
+        String testString = getKeyPressLog();
+        assertThat(testString).isEqualTo(expectedOut);
+    }
+
+    private void lookForLog(String expectedOut1, String expectedOut2) throws Exception {
+        String testString = getKeyPressLog();
+        assertThat(testString).isAnyOf(expectedOut1, expectedOut2);
+    }
+
+    private String getKeyPressLog() throws Exception {
         ITestDevice device = getDevice();
         TimeUnit.SECONDS.sleep(WAIT_TIME);
         String logs = device.executeAdbCommand("logcat", "-v", "brief", "-d", CLASS + ":I", "*:S");
@@ -76,7 +98,7 @@
             }
         }
         device.executeAdbCommand("logcat", "-c");
-        assertEquals(expectedOut, testString);
+        return testString;
     }
 
     /**
@@ -93,22 +115,22 @@
         device.executeAdbCommand("logcat", "-c");
         // Start the APK and wait for it to complete.
         device.executeShellCommand(START_COMMAND);
-        hdmiCecClient.sendUserControlPressAndRelease(CecDevice.TV, CecDevice.PLAYBACK_1,
+        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, LogicalAddress.PLAYBACK_1,
                 HdmiCecConstants.CEC_CONTROL_UP, false);
         lookForLog("Short press KEYCODE_DPAD_UP");
-        hdmiCecClient.sendUserControlPressAndRelease(CecDevice.TV, CecDevice.PLAYBACK_1,
+        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, LogicalAddress.PLAYBACK_1,
                 HdmiCecConstants.CEC_CONTROL_DOWN, false);
         lookForLog("Short press KEYCODE_DPAD_DOWN");
-        hdmiCecClient.sendUserControlPressAndRelease(CecDevice.TV, CecDevice.PLAYBACK_1,
+        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, LogicalAddress.PLAYBACK_1,
                 HdmiCecConstants.CEC_CONTROL_LEFT, false);
         lookForLog("Short press KEYCODE_DPAD_LEFT");
-        hdmiCecClient.sendUserControlPressAndRelease(CecDevice.TV, CecDevice.PLAYBACK_1,
+        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, LogicalAddress.PLAYBACK_1,
                 HdmiCecConstants.CEC_CONTROL_RIGHT, false);
         lookForLog("Short press KEYCODE_DPAD_RIGHT");
-        hdmiCecClient.sendUserControlPressAndRelease(CecDevice.TV, CecDevice.PLAYBACK_1,
+        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, LogicalAddress.PLAYBACK_1,
                 HdmiCecConstants.CEC_CONTROL_SELECT, false);
-        lookForLog("Short press KEYCODE_DPAD_CENTER");
-        hdmiCecClient.sendUserControlPressAndRelease(CecDevice.TV, CecDevice.PLAYBACK_1,
+        lookForLog("Short press KEYCODE_DPAD_CENTER", "Short press KEYCODE_ENTER");
+        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, LogicalAddress.PLAYBACK_1,
                 HdmiCecConstants.CEC_CONTROL_BACK, false);
         lookForLog("Short press KEYCODE_BACK");
     }
@@ -127,22 +149,22 @@
         device.executeAdbCommand("logcat", "-c");
         // Start the APK and wait for it to complete.
         device.executeShellCommand(START_COMMAND);
-        hdmiCecClient.sendUserControlPressAndRelease(CecDevice.TV, CecDevice.PLAYBACK_1,
+        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, LogicalAddress.PLAYBACK_1,
                 HdmiCecConstants.CEC_CONTROL_UP, true);
         lookForLog("Long press KEYCODE_DPAD_UP");
-        hdmiCecClient.sendUserControlPressAndRelease(CecDevice.TV, CecDevice.PLAYBACK_1,
+        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, LogicalAddress.PLAYBACK_1,
                 HdmiCecConstants.CEC_CONTROL_DOWN, true);
         lookForLog("Long press KEYCODE_DPAD_DOWN");
-        hdmiCecClient.sendUserControlPressAndRelease(CecDevice.TV, CecDevice.PLAYBACK_1,
+        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, LogicalAddress.PLAYBACK_1,
                 HdmiCecConstants.CEC_CONTROL_LEFT, true);
         lookForLog("Long press KEYCODE_DPAD_LEFT");
-        hdmiCecClient.sendUserControlPressAndRelease(CecDevice.TV, CecDevice.PLAYBACK_1,
+        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, LogicalAddress.PLAYBACK_1,
                 HdmiCecConstants.CEC_CONTROL_RIGHT, true);
         lookForLog("Long press KEYCODE_DPAD_RIGHT");
-        hdmiCecClient.sendUserControlPressAndRelease(CecDevice.TV, CecDevice.PLAYBACK_1,
+        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, LogicalAddress.PLAYBACK_1,
                 HdmiCecConstants.CEC_CONTROL_SELECT, true);
-        lookForLog("Long press KEYCODE_DPAD_CENTER");
-        hdmiCecClient.sendUserControlPressAndRelease(CecDevice.TV, CecDevice.PLAYBACK_1,
+        lookForLog("Long press KEYCODE_DPAD_CENTER", "Long press KEYCODE_ENTER");
+        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, LogicalAddress.PLAYBACK_1,
                 HdmiCecConstants.CEC_CONTROL_BACK, true);
         lookForLog("Long press KEYCODE_BACK");
     }
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecRoutingControlTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecRoutingControlTest.java
index 4fd2a89..8bec365 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecRoutingControlTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecRoutingControlTest.java
@@ -16,18 +16,22 @@
 
 package android.hdmicec.cts.playback;
 
-import static org.junit.Assert.assertEquals;
+import static com.google.common.truth.Truth.assertThat;
 
-import android.hdmicec.cts.CecDevice;
 import android.hdmicec.cts.CecMessage;
+import android.hdmicec.cts.CecOperand;
 import android.hdmicec.cts.HdmiCecClientWrapper;
 import android.hdmicec.cts.HdmiCecConstants;
+import android.hdmicec.cts.LogicalAddress;
+import android.hdmicec.cts.RequiredPropertyRule;
+import android.hdmicec.cts.RequiredFeatureRule;
 
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
 
 import org.junit.Rule;
+import org.junit.rules.RuleChain;
 import org.junit.runner.RunWith;
 import org.junit.Test;
 
@@ -39,9 +43,18 @@
 
     private static final int PHYSICAL_ADDRESS = 0x1000;
 
+    public HdmiCecClientWrapper hdmiCecClient = new HdmiCecClientWrapper(LogicalAddress.PLAYBACK_1);
+
     @Rule
-    public HdmiCecClientWrapper hdmiCecClient =
-            new HdmiCecClientWrapper(CecDevice.PLAYBACK_1, this);
+    public RuleChain ruleChain =
+        RuleChain
+            .outerRule(new RequiredFeatureRule(this, LogicalAddress.HDMI_CEC_FEATURE))
+            .around(new RequiredFeatureRule(this, LogicalAddress.LEANBACK_FEATURE))
+            .around(RequiredPropertyRule.asCsvContainsValue(
+                this,
+                LogicalAddress.HDMI_DEVICE_TYPE_PROPERTY,
+                LogicalAddress.PLAYBACK_1.getDeviceType()))
+            .around(hdmiCecClient);
 
     /**
      * Test 11.2.2-1
@@ -52,15 +65,14 @@
     public void cect_11_2_2_1_SetStreamPathToDut() throws Exception {
         final long hdmi2Address = 0x2000;
         /* Switch to HDMI2. Setup assumes DUT is connected to HDMI1. */
-        hdmiCecClient.sendCecMessage(CecDevice.PLAYBACK_2, CecDevice.BROADCAST,
-                CecMessage.ACTIVE_SOURCE, hdmiCecClient.formatParams(hdmi2Address));
+        hdmiCecClient.sendCecMessage(LogicalAddress.PLAYBACK_2, LogicalAddress.BROADCAST,
+                CecOperand.ACTIVE_SOURCE, CecMessage.formatParams(hdmi2Address));
         TimeUnit.SECONDS.sleep(3);
-        hdmiCecClient.sendCecMessage(CecDevice.TV, CecDevice.BROADCAST,
-                CecMessage.SET_STREAM_PATH,
-                hdmiCecClient.formatParams(HdmiCecConstants.PHYSICAL_ADDRESS));
-        String message = hdmiCecClient.checkExpectedOutput(CecMessage.ACTIVE_SOURCE);
-        assertEquals(HdmiCecConstants.PHYSICAL_ADDRESS,
-                hdmiCecClient.getParamsFromMessage(message));
+        hdmiCecClient.sendCecMessage(LogicalAddress.TV, LogicalAddress.BROADCAST,
+                CecOperand.SET_STREAM_PATH,
+                CecMessage.formatParams(HdmiCecConstants.PHYSICAL_ADDRESS));
+        String message = hdmiCecClient.checkExpectedOutput(CecOperand.ACTIVE_SOURCE);
+        assertThat(CecMessage.getParams(message)).isEqualTo(PHYSICAL_ADDRESS);
     }
 
     /**
@@ -72,10 +84,10 @@
     public void cect_11_2_2_2_RequestActiveSource() throws Exception {
         ITestDevice device = getDevice();
         device.executeShellCommand("input keyevent KEYCODE_HOME");
-        hdmiCecClient.sendCecMessage(CecDevice.TV, CecDevice.BROADCAST,
-            CecMessage.REQUEST_ACTIVE_SOURCE);
-        String message = hdmiCecClient.checkExpectedOutput(CecMessage.ACTIVE_SOURCE);
-        assertEquals(PHYSICAL_ADDRESS, hdmiCecClient.getParamsFromMessage(message));
+        hdmiCecClient.sendCecMessage(LogicalAddress.TV, LogicalAddress.BROADCAST,
+            CecOperand.REQUEST_ACTIVE_SOURCE);
+        String message = hdmiCecClient.checkExpectedOutput(CecOperand.ACTIVE_SOURCE);
+        assertThat(CecMessage.getParams(message)).isEqualTo(PHYSICAL_ADDRESS);
     }
 
     /**
@@ -89,10 +101,9 @@
         try {
             device.executeShellCommand("input keyevent KEYCODE_HOME");
             device.executeShellCommand("input keyevent KEYCODE_SLEEP");
-            String message = hdmiCecClient.checkExpectedOutput(CecDevice.TV,
-                    CecMessage.INACTIVE_SOURCE);
-            assertEquals(HdmiCecConstants.PHYSICAL_ADDRESS,
-                    hdmiCecClient.getParamsFromMessage(message));
+            String message = hdmiCecClient.checkExpectedOutput(LogicalAddress.TV,
+                    CecOperand.INACTIVE_SOURCE);
+            assertThat(CecMessage.getParams(message)).isEqualTo(PHYSICAL_ADDRESS);
         } finally {
             /* Wake up the device */
             device.executeShellCommand("input keyevent KEYCODE_WAKEUP");
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecStartupTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecStartupTest.java
new file mode 100644
index 0000000..06b62f9
--- /dev/null
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecStartupTest.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hdmicec.cts.playback;
+
+import static com.google.common.collect.Iterables.filter;
+import static com.google.common.truth.Truth.assertWithMessage;
+import static org.junit.Assume.assumeTrue;
+
+import android.hdmicec.cts.CecOperand;
+import android.hdmicec.cts.HdmiCecClientWrapper;
+import android.hdmicec.cts.HdmiCecConstants;
+import android.hdmicec.cts.LogicalAddress;
+import android.hdmicec.cts.RequiredPropertyRule;
+import android.hdmicec.cts.RequiredFeatureRule;
+
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableList;
+import javax.annotation.Nullable;
+import org.junit.Rule;
+import org.junit.rules.RuleChain;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+import java.util.List;
+
+/**
+ * HDMI CEC test to verify physical address after device reboot (Section 10.2.3)
+ */
+@RunWith(DeviceJUnit4ClassRunner.class)
+public final class HdmiCecStartupTest extends BaseHostJUnit4Test {
+
+  private static final LogicalAddress PLAYBACK_DEVICE = LogicalAddress.PLAYBACK_1;
+  private static final ImmutableList<CecOperand> necessaryMessages =
+      new ImmutableList.Builder<CecOperand>()
+          .add(CecOperand.REPORT_PHYSICAL_ADDRESS, CecOperand.CEC_VERSION,
+              CecOperand.DEVICE_VENDOR_ID, CecOperand.GIVE_POWER_STATUS).build();
+  private static final ImmutableList<CecOperand> permissibleMessages =
+      new ImmutableList.Builder<CecOperand>()
+          .add(CecOperand.VENDOR_COMMAND, CecOperand.GIVE_DEVICE_VENDOR_ID,
+              CecOperand.SET_OSD_NAME, CecOperand.GIVE_OSD_NAME).build();
+
+  public HdmiCecClientWrapper hdmiCecClient = new HdmiCecClientWrapper(LogicalAddress.PLAYBACK_1);
+
+  @Rule
+  public RuleChain ruleChain =
+      RuleChain
+          .outerRule(new RequiredFeatureRule(this, LogicalAddress.HDMI_CEC_FEATURE))
+          .around(new RequiredFeatureRule(this, LogicalAddress.LEANBACK_FEATURE))
+          .around(RequiredPropertyRule.asCsvContainsValue(
+              this,
+              LogicalAddress.HDMI_DEVICE_TYPE_PROPERTY,
+              PLAYBACK_DEVICE.getDeviceType()))
+          .around(hdmiCecClient);
+
+  /**
+   * Tests that the device sends all the messages that should be sent on startup. It also ensures
+   * that only the device only sends messages which are allowed by the spec.
+   */
+  @Test
+  public void cectVerifyStartupMessages() throws Exception {
+    ITestDevice device = getDevice();
+
+    /* Make sure device is playback only. Not applicable to playback/audio combinations */
+    String deviceTypeCsv = device.executeShellCommand("getprop ro.hdmi.device_type").trim();
+    assumeTrue(deviceTypeCsv.equals(LogicalAddress.PLAYBACK_1.getDeviceType()));
+
+    device.executeShellCommand("reboot");
+    device.waitForBootComplete(HdmiCecConstants.REBOOT_TIMEOUT);
+    /* Monitor CEC messages for 20s after reboot */
+    final List<CecOperand> messagesReceived =
+        hdmiCecClient.getAllMessages(LogicalAddress.PLAYBACK_1, 20);
+
+    /* Predicate to apply on necessaryMessages to ensure that all necessaryMessages are received. */
+    final Predicate<CecOperand> notReceived = new Predicate<CecOperand>() {
+      @Override
+      public boolean apply(@Nullable CecOperand cecOperand) {
+        return !messagesReceived.contains(cecOperand);
+      }
+    };
+
+    /* Predicate to apply on messagesReceived to ensure all messages received are permissible. */
+    final Predicate<CecOperand> notAllowed = new Predicate<CecOperand>() {
+      @Override
+      public boolean apply(@Nullable CecOperand cecOperand) {
+        return !(permissibleMessages.contains(cecOperand) || necessaryMessages.contains(cecOperand));
+      }
+    };
+
+    assertWithMessage("Some necessary messages are missing").
+        that(filter(necessaryMessages, notReceived)).isEmpty();
+
+    assertWithMessage("Some non-permissible messages received").
+        that(filter(messagesReceived, notAllowed)).isEmpty();
+  }
+}
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecSystemAudioControlTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecSystemAudioControlTest.java
index 3ac2e5f..6d8b6db 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecSystemAudioControlTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecSystemAudioControlTest.java
@@ -16,31 +16,44 @@
 
 package android.hdmicec.cts.playback;
 
-import static org.junit.Assert.assertEquals;
+import static com.google.common.truth.Truth.assertThat;
 
-import android.hdmicec.cts.CecDevice;
 import android.hdmicec.cts.CecMessage;
+import android.hdmicec.cts.CecOperand;
 import android.hdmicec.cts.HdmiCecClientWrapper;
 import android.hdmicec.cts.HdmiCecConstants;
+import android.hdmicec.cts.LogicalAddress;
+import android.hdmicec.cts.RequiredPropertyRule;
+import android.hdmicec.cts.RequiredFeatureRule;
 
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
 
 import org.junit.Rule;
+import org.junit.rules.RuleChain;
 import org.junit.runner.RunWith;
 import org.junit.Test;
 
-import java.util.concurrent.TimeUnit;
-
 /** HDMI CEC test to verify system audio control commands (Section 11.2.15) */
 @RunWith(DeviceJUnit4ClassRunner.class)
 public final class HdmiCecSystemAudioControlTest extends BaseHostJUnit4Test {
-    private static final CecDevice PLAYBACK_DEVICE = CecDevice.PLAYBACK_1;
+
+    private static final LogicalAddress PLAYBACK_DEVICE = LogicalAddress.PLAYBACK_1;
+
+    public HdmiCecClientWrapper hdmiCecClient =
+        new HdmiCecClientWrapper(LogicalAddress.PLAYBACK_1, "-t", "a");
 
     @Rule
-    public HdmiCecClientWrapper hdmiCecClient =
-        new HdmiCecClientWrapper(CecDevice.PLAYBACK_1, this, "-t", "a");
+    public RuleChain ruleChain =
+        RuleChain
+            .outerRule(new RequiredFeatureRule(this, LogicalAddress.HDMI_CEC_FEATURE))
+            .around(new RequiredFeatureRule(this, LogicalAddress.LEANBACK_FEATURE))
+            .around(RequiredPropertyRule.asCsvContainsValue(
+                this,
+                LogicalAddress.HDMI_DEVICE_TYPE_PROPERTY,
+                PLAYBACK_DEVICE.getDeviceType()))
+            .around(hdmiCecClient);
 
     /**
      * Test 11.2.15-10
@@ -49,10 +62,12 @@
     @Test
     public void cect_11_2_15_10_GiveSystemAudioModeStatus() throws Exception {
         ITestDevice device = getDevice();
+        /* Home Key to prevent device from going to deep suspend state */
+        device.executeShellCommand("input keyevent KEYCODE_HOME");
         device.executeShellCommand("input keyevent KEYCODE_SLEEP");
         device.executeShellCommand("input keyevent KEYCODE_WAKEUP");
-        hdmiCecClient.checkExpectedOutput(CecDevice.AUDIO_SYSTEM,
-                CecMessage.GIVE_SYSTEM_AUDIO_MODE_STATUS);
+        hdmiCecClient.checkExpectedOutput(LogicalAddress.AUDIO_SYSTEM,
+                CecOperand.GIVE_SYSTEM_AUDIO_MODE_STATUS);
     }
 
     /**
@@ -64,20 +79,22 @@
     @Test
     public void cect_11_2_15_11_VolumeUpDownUserControlPressed() throws Exception {
         ITestDevice device = getDevice();
+        hdmiCecClient.sendCecMessage(LogicalAddress.AUDIO_SYSTEM, LogicalAddress.BROADCAST,
+                CecOperand.SET_SYSTEM_AUDIO_MODE, CecMessage.formatParams(1));
         device.executeShellCommand("input keyevent KEYCODE_VOLUME_UP");
-        String message = hdmiCecClient.checkExpectedOutput(CecDevice.AUDIO_SYSTEM,
-                CecMessage.USER_CONTROL_PRESSED);
-        assertEquals(HdmiCecConstants.CEC_CONTROL_VOLUME_UP,
-                hdmiCecClient.getParamsFromMessage(message));
-        hdmiCecClient.checkExpectedOutput(CecDevice.AUDIO_SYSTEM, CecMessage.USER_CONTROL_RELEASED);
+        String message = hdmiCecClient.checkExpectedOutput(LogicalAddress.AUDIO_SYSTEM,
+                CecOperand.USER_CONTROL_PRESSED);
+        assertThat(CecMessage.getParams(message))
+                .isEqualTo(HdmiCecConstants.CEC_CONTROL_VOLUME_UP);
+        hdmiCecClient.checkExpectedOutput(LogicalAddress.AUDIO_SYSTEM, CecOperand.USER_CONTROL_RELEASED);
 
 
         device.executeShellCommand("input keyevent KEYCODE_VOLUME_DOWN");
-        message = hdmiCecClient.checkExpectedOutput(CecDevice.AUDIO_SYSTEM,
-                CecMessage.USER_CONTROL_PRESSED);
-        assertEquals(HdmiCecConstants.CEC_CONTROL_VOLUME_DOWN,
-                hdmiCecClient.getParamsFromMessage(message));
-        hdmiCecClient.checkExpectedOutput(CecDevice.AUDIO_SYSTEM, CecMessage.USER_CONTROL_RELEASED);
+        message = hdmiCecClient.checkExpectedOutput(LogicalAddress.AUDIO_SYSTEM,
+                CecOperand.USER_CONTROL_PRESSED);
+        assertThat(CecMessage.getParams(message))
+                .isEqualTo(HdmiCecConstants.CEC_CONTROL_VOLUME_DOWN);
+        hdmiCecClient.checkExpectedOutput(LogicalAddress.AUDIO_SYSTEM, CecOperand.USER_CONTROL_RELEASED);
     }
 
     /**
@@ -89,11 +106,12 @@
     @Test
     public void cect_11_2_15_12_MuteUserControlPressed() throws Exception {
         ITestDevice device = getDevice();
+        hdmiCecClient.sendCecMessage(LogicalAddress.AUDIO_SYSTEM, LogicalAddress.BROADCAST,
+                CecOperand.SET_SYSTEM_AUDIO_MODE, CecMessage.formatParams(1));
         device.executeShellCommand("input keyevent KEYCODE_MUTE");
-        String message = hdmiCecClient.checkExpectedOutput(CecDevice.AUDIO_SYSTEM,
-                CecMessage.USER_CONTROL_PRESSED);
-        assertEquals(HdmiCecConstants.CEC_CONTROL_MUTE,
-                hdmiCecClient.getParamsFromMessage(message));
-        hdmiCecClient.checkExpectedOutput(CecDevice.AUDIO_SYSTEM, CecMessage.USER_CONTROL_RELEASED);
+        String message = hdmiCecClient.checkExpectedOutput(LogicalAddress.AUDIO_SYSTEM,
+                CecOperand.USER_CONTROL_PRESSED);
+        assertThat(CecMessage.getParams(message)).isEqualTo(HdmiCecConstants.CEC_CONTROL_MUTE);
+        hdmiCecClient.checkExpectedOutput(LogicalAddress.AUDIO_SYSTEM, CecOperand.USER_CONTROL_RELEASED);
     }
 }
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecSystemInformationTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecSystemInformationTest.java
index c6df9f7..5e59a8f 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecSystemInformationTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecSystemInformationTest.java
@@ -16,20 +16,25 @@
 
 package android.hdmicec.cts.playback;
 
-import static org.junit.Assert.assertEquals;
+import static com.google.common.truth.Truth.assertThat;
+
 import static org.junit.Assume.assumeTrue;
 
 import android.hdmicec.cts.CecClientMessage;
-import android.hdmicec.cts.CecDevice;
 import android.hdmicec.cts.CecMessage;
+import android.hdmicec.cts.CecOperand;
 import android.hdmicec.cts.HdmiCecClientWrapper;
 import android.hdmicec.cts.HdmiCecConstants;
+import android.hdmicec.cts.LogicalAddress;
+import android.hdmicec.cts.RequiredPropertyRule;
+import android.hdmicec.cts.RequiredFeatureRule;
 
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
 
 import org.junit.Rule;
+import org.junit.rules.RuleChain;
 import org.junit.runner.RunWith;
 import org.junit.Test;
 
@@ -42,9 +47,18 @@
 
     private static final String PROPERTY_LOCALE = "persist.sys.locale";
 
+    public HdmiCecClientWrapper hdmiCecClient = new HdmiCecClientWrapper(LogicalAddress.PLAYBACK_1);
+
     @Rule
-    public HdmiCecClientWrapper hdmiCecClient =
-        new HdmiCecClientWrapper(CecDevice.PLAYBACK_1, this);
+    public RuleChain ruleChain =
+        RuleChain
+            .outerRule(new RequiredFeatureRule(this, LogicalAddress.HDMI_CEC_FEATURE))
+            .around(new RequiredFeatureRule(this, LogicalAddress.LEANBACK_FEATURE))
+            .around(RequiredPropertyRule.asCsvContainsValue(
+                this,
+                LogicalAddress.HDMI_DEVICE_TYPE_PROPERTY,
+                LogicalAddress.PLAYBACK_1.getDeviceType()))
+            .around(hdmiCecClient);
 
     /**
      * Test 11.2.6-1
@@ -52,7 +66,7 @@
      */
     @Test
     public void cect_11_2_6_1_Ack() throws Exception {
-        String command = CecClientMessage.POLL + " " + CecDevice.PLAYBACK_1;
+        String command = CecClientMessage.POLL + " " + LogicalAddress.PLAYBACK_1;
         String expectedOutput = "POLL sent";
         hdmiCecClient.sendConsoleMessage(command);
         if (!hdmiCecClient.checkConsoleOutput(expectedOutput)) {
@@ -67,13 +81,13 @@
      */
     @Test
     public void cect_11_2_6_2_GivePhysicalAddress() throws Exception {
-        hdmiCecClient.sendCecMessage(CecMessage.GIVE_PHYSICAL_ADDRESS);
-        String message = hdmiCecClient.checkExpectedOutput(CecMessage.REPORT_PHYSICAL_ADDRESS);
+        hdmiCecClient.sendCecMessage(CecOperand.GIVE_PHYSICAL_ADDRESS);
+        String message = hdmiCecClient.checkExpectedOutput(CecOperand.REPORT_PHYSICAL_ADDRESS);
         /* The checkExpectedOutput has already verified the first 4 nibbles of the message. We
             * have to verify the last 6 nibbles */
-        int receivedParams = hdmiCecClient.getParamsFromMessage(message);
-        assertEquals(HdmiCecConstants.PHYSICAL_ADDRESS, receivedParams >> 8);
-        assertEquals(HdmiCecConstants.PLAYBACK_DEVICE_TYPE, receivedParams & 0xFF);
+        int receivedParams = CecMessage.getParams(message);
+        assertThat(HdmiCecConstants.PHYSICAL_ADDRESS).isEqualTo(receivedParams >> 8);
+        assertThat(HdmiCecConstants.PLAYBACK_DEVICE_TYPE).isEqualTo(receivedParams & 0xFF);
     }
 
     /**
@@ -82,11 +96,10 @@
      */
     @Test
     public void cect_11_2_6_6_GiveCecVersion() throws Exception {
-        hdmiCecClient.sendCecMessage(CecDevice.TV, CecMessage.GET_CEC_VERSION);
-        String message = hdmiCecClient.checkExpectedOutput(CecDevice.TV,
-                                                            CecMessage.CEC_VERSION);
-
-        assertEquals(CEC_VERSION_NUMBER, hdmiCecClient.getParamsFromMessage(message));
+        hdmiCecClient.sendCecMessage(LogicalAddress.TV, CecOperand.GET_CEC_VERSION);
+        String message = hdmiCecClient.checkExpectedOutput(LogicalAddress.TV,
+                                                            CecOperand.CEC_VERSION);
+        assertThat(CecMessage.getParams(message)).isEqualTo(CEC_VERSION_NUMBER);
     }
 
     /**
@@ -95,11 +108,11 @@
      */
     @Test
     public void cect_11_2_6_7_GetMenuLanguage() throws Exception {
-        hdmiCecClient.sendCecMessage(CecDevice.TV, CecMessage.GET_MENU_LANGUAGE);
-        String message = hdmiCecClient.checkExpectedOutput(CecDevice.TV, CecMessage.FEATURE_ABORT);
-        int abortedOpcode = hdmiCecClient.getParamsFromMessage(message,
-                CecMessage.GET_MENU_LANGUAGE.toString().length());
-        assertEquals(CecMessage.getMessage(abortedOpcode), CecMessage.GET_MENU_LANGUAGE);
+        hdmiCecClient.sendCecMessage(LogicalAddress.TV, CecOperand.GET_MENU_LANGUAGE);
+        String message = hdmiCecClient.checkExpectedOutput(LogicalAddress.TV, CecOperand.FEATURE_ABORT);
+        int abortedOpcode = CecMessage.getParams(message,
+                CecOperand.GET_MENU_LANGUAGE.toString().length());
+        assertThat(CecOperand.getOperand(abortedOpcode)).isEqualTo(CecOperand.GET_MENU_LANGUAGE);
     }
 
     private String getSystemLocale() throws Exception {
@@ -133,9 +146,9 @@
         final String language = originalLanguage.equals("spa") ? "eng" : "spa";
         final String newLanguage = originalLanguage.equals("spa") ? "en" : "es";
         try {
-            hdmiCecClient.sendCecMessage(CecDevice.TV, CecDevice.BROADCAST,
-                    CecMessage.SET_MENU_LANGUAGE, hdmiCecClient.convertStringToHexParams(language));
-            assertEquals(newLanguage, extractLanguage(getSystemLocale()));
+            hdmiCecClient.sendCecMessage(LogicalAddress.TV, LogicalAddress.BROADCAST,
+                    CecOperand.SET_MENU_LANGUAGE, CecMessage.convertStringToHexParams(language));
+            assertThat(extractLanguage(getSystemLocale())).isEqualTo(newLanguage);
         } finally {
             setSystemLocale(locale);
         }
@@ -152,9 +165,9 @@
         final String originalLanguage = extractLanguage(locale);
         final String language = "spb";
         try {
-            hdmiCecClient.sendCecMessage(CecDevice.TV, CecDevice.BROADCAST,
-                    CecMessage.SET_MENU_LANGUAGE, hdmiCecClient.convertStringToHexParams(language));
-            assertEquals(originalLanguage, extractLanguage(getSystemLocale()));
+            hdmiCecClient.sendCecMessage(LogicalAddress.TV, LogicalAddress.BROADCAST,
+                    CecOperand.SET_MENU_LANGUAGE, CecMessage.convertStringToHexParams(language));
+            assertThat(extractLanguage(getSystemLocale())).isEqualTo(originalLanguage);
         } finally {
             setSystemLocale(locale);
         }
@@ -172,9 +185,9 @@
         final String originalLanguage = extractLanguage(locale);
         final String language = originalLanguage.equals("spa") ? "eng" : "spa";
         try {
-            hdmiCecClient.sendCecMessage(CecDevice.RECORDER_1, CecDevice.BROADCAST,
-                    CecMessage.SET_MENU_LANGUAGE, hdmiCecClient.convertStringToHexParams(language));
-            assertEquals(originalLanguage, extractLanguage(getSystemLocale()));
+            hdmiCecClient.sendCecMessage(LogicalAddress.RECORDER_1, LogicalAddress.BROADCAST,
+                    CecOperand.SET_MENU_LANGUAGE, CecMessage.convertStringToHexParams(language));
+            assertThat(extractLanguage(getSystemLocale())).isEqualTo(originalLanguage);
         } finally {
             setSystemLocale(locale);
         }
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecSystemStandbyTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecSystemStandbyTest.java
index 1aa8fe4..369542e 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecSystemStandbyTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecSystemStandbyTest.java
@@ -16,20 +16,21 @@
 
 package android.hdmicec.cts.playback;
 
-import static org.junit.Assert.assertEquals;
+import static com.google.common.truth.Truth.assertThat;
 
-import android.hdmicec.cts.CecDevice;
-import android.hdmicec.cts.CecMessage;
+import android.hdmicec.cts.CecOperand;
 import android.hdmicec.cts.HdmiCecClientWrapper;
 import android.hdmicec.cts.HdmiCecConstants;
+import android.hdmicec.cts.LogicalAddress;
+import android.hdmicec.cts.RequiredPropertyRule;
+import android.hdmicec.cts.RequiredFeatureRule;
 
 import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.device.TestDeviceState;
-import com.android.tradefed.log.LogUtil.CLog;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
 
 import org.junit.Rule;
+import org.junit.rules.RuleChain;
 import org.junit.runner.RunWith;
 import org.junit.Test;
 
@@ -38,14 +39,24 @@
 /** HDMI CEC test to verify the device handles standby correctly (Section 11.2.3) */
 @RunWith(DeviceJUnit4ClassRunner.class)
 public final class HdmiCecSystemStandbyTest extends BaseHostJUnit4Test {
-    private static final CecDevice PLAYBACK_DEVICE = CecDevice.PLAYBACK_1;
+
+    private static final LogicalAddress PLAYBACK_DEVICE = LogicalAddress.PLAYBACK_1;
 
     private static final String HDMI_CONTROL_DEVICE_AUTO_OFF =
             "hdmi_control_auto_device_off_enabled";
 
+    public HdmiCecClientWrapper hdmiCecClient = new HdmiCecClientWrapper(LogicalAddress.PLAYBACK_1);
+
     @Rule
-    public HdmiCecClientWrapper hdmiCecClient =
-        new HdmiCecClientWrapper(CecDevice.PLAYBACK_1, this);
+    public RuleChain ruleChain =
+        RuleChain
+            .outerRule(new RequiredFeatureRule(this, LogicalAddress.HDMI_CEC_FEATURE))
+            .around(new RequiredFeatureRule(this, LogicalAddress.LEANBACK_FEATURE))
+            .around(RequiredPropertyRule.asCsvContainsValue(
+                this,
+                LogicalAddress.HDMI_DEVICE_TYPE_PROPERTY,
+                PLAYBACK_DEVICE.getDeviceType()))
+            .around(hdmiCecClient);
 
     private boolean setHdmiControlDeviceAutoOff(boolean turnOn) throws Exception {
         ITestDevice device = getDevice();
@@ -58,16 +69,16 @@
         return val.equals("1") ? true : false;
     }
 
-    private void checkDeviceAsleepAfterStandbySent(CecDevice source, CecDevice destination)
+    private void checkDeviceAsleepAfterStandbySent(LogicalAddress source, LogicalAddress destination)
             throws Exception {
         ITestDevice device = getDevice();
         try {
             device.executeShellCommand("input keyevent KEYCODE_HOME");
             TimeUnit.SECONDS.sleep(5);
-            hdmiCecClient.sendCecMessage(source, destination, CecMessage.STANDBY);
+            hdmiCecClient.sendCecMessage(source, destination, CecOperand.STANDBY);
             TimeUnit.SECONDS.sleep(5);
             String wakeState = device.executeShellCommand("dumpsys power | grep mWakefulness=");
-            assertEquals("mWakefulness=Asleep", wakeState.trim());
+            assertThat(wakeState.trim()).isEqualTo("mWakefulness=Asleep");
         } finally {
             /* Wake up the device */
             device.executeShellCommand("input keyevent KEYCODE_WAKEUP");
@@ -84,19 +95,19 @@
         getDevice().waitForBootComplete(HdmiCecConstants.REBOOT_TIMEOUT);
         try {
             TimeUnit.SECONDS.sleep(5);
-            checkDeviceAsleepAfterStandbySent(CecDevice.TV, CecDevice.BROADCAST);
+            checkDeviceAsleepAfterStandbySent(LogicalAddress.TV, LogicalAddress.BROADCAST);
             /* Wake up the TV */
-            hdmiCecClient.sendConsoleMessage("on " + CecDevice.TV);
-            checkDeviceAsleepAfterStandbySent(CecDevice.RECORDER_1, CecDevice.BROADCAST);
+            hdmiCecClient.sendConsoleMessage("on " + LogicalAddress.TV);
+            checkDeviceAsleepAfterStandbySent(LogicalAddress.RECORDER_1, LogicalAddress.BROADCAST);
             /* Wake up the TV */
-            hdmiCecClient.sendConsoleMessage("on " + CecDevice.TV);
-            checkDeviceAsleepAfterStandbySent(CecDevice.AUDIO_SYSTEM, CecDevice.BROADCAST);
+            hdmiCecClient.sendConsoleMessage("on " + LogicalAddress.TV);
+            checkDeviceAsleepAfterStandbySent(LogicalAddress.AUDIO_SYSTEM, LogicalAddress.BROADCAST);
             /* Wake up the TV */
-            hdmiCecClient.sendConsoleMessage("on " + CecDevice.TV);
-            checkDeviceAsleepAfterStandbySent(CecDevice.PLAYBACK_2, CecDevice.BROADCAST);
+            hdmiCecClient.sendConsoleMessage("on " + LogicalAddress.TV);
+            checkDeviceAsleepAfterStandbySent(LogicalAddress.PLAYBACK_2, LogicalAddress.BROADCAST);
         } finally {
             /* Wake up the TV */
-            hdmiCecClient.sendConsoleMessage("on " + CecDevice.TV);
+            hdmiCecClient.sendConsoleMessage("on " + LogicalAddress.TV);
         }
     }
 
@@ -108,11 +119,11 @@
     public void cect_11_2_3_3_HandleAddressedStandby() throws Exception {
         getDevice().executeShellCommand("reboot");
         getDevice().waitForBootComplete(HdmiCecConstants.REBOOT_TIMEOUT);
-        checkDeviceAsleepAfterStandbySent(CecDevice.TV, CecDevice.PLAYBACK_1);
-        checkDeviceAsleepAfterStandbySent(CecDevice.RECORDER_1, CecDevice.PLAYBACK_1);
-        checkDeviceAsleepAfterStandbySent(CecDevice.AUDIO_SYSTEM, CecDevice.PLAYBACK_1);
-        checkDeviceAsleepAfterStandbySent(CecDevice.PLAYBACK_2, CecDevice.PLAYBACK_1);
-        checkDeviceAsleepAfterStandbySent(CecDevice.BROADCAST, CecDevice.PLAYBACK_1);
+        checkDeviceAsleepAfterStandbySent(LogicalAddress.TV, LogicalAddress.PLAYBACK_1);
+        checkDeviceAsleepAfterStandbySent(LogicalAddress.RECORDER_1, LogicalAddress.PLAYBACK_1);
+        checkDeviceAsleepAfterStandbySent(LogicalAddress.AUDIO_SYSTEM, LogicalAddress.PLAYBACK_1);
+        checkDeviceAsleepAfterStandbySent(LogicalAddress.PLAYBACK_2, LogicalAddress.PLAYBACK_1);
+        checkDeviceAsleepAfterStandbySent(LogicalAddress.BROADCAST, LogicalAddress.PLAYBACK_1);
     }
 
     /**
@@ -125,7 +136,7 @@
         boolean wasOn = setHdmiControlDeviceAutoOff(false);
         try {
             device.executeShellCommand("input keyevent KEYCODE_SLEEP");
-            hdmiCecClient.checkOutputDoesNotContainMessage(CecDevice.BROADCAST, CecMessage.STANDBY);
+            hdmiCecClient.checkOutputDoesNotContainMessage(LogicalAddress.BROADCAST, CecOperand.STANDBY);
             device.executeShellCommand("input keyevent KEYCODE_WAKEUP");
         } finally {
             setHdmiControlDeviceAutoOff(wasOn);
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecVendorCommandsTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecVendorCommandsTest.java
index df9bc5a..edff394 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecVendorCommandsTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecVendorCommandsTest.java
@@ -16,30 +16,44 @@
 
 package android.hdmicec.cts.playback;
 
-import static org.junit.Assert.assertNotEquals;
+import static com.google.common.truth.Truth.assertThat;
 
-import android.hdmicec.cts.CecDevice;
 import android.hdmicec.cts.CecMessage;
+import android.hdmicec.cts.CecOperand;
 import android.hdmicec.cts.HdmiCecClientWrapper;
 import android.hdmicec.cts.HdmiCecConstants;
+import android.hdmicec.cts.LogicalAddress;
+import android.hdmicec.cts.RequiredPropertyRule;
+import android.hdmicec.cts.RequiredFeatureRule;
 
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
 
 import org.junit.Rule;
+import org.junit.rules.RuleChain;
 import org.junit.runner.RunWith;
 import org.junit.Test;
 
 /** HDMI CEC test to verify device vendor specific commands (Section 11.2.9) */
 @RunWith(DeviceJUnit4ClassRunner.class)
 public final class HdmiCecVendorCommandsTest extends BaseHostJUnit4Test {
-    private static final CecDevice PLAYBACK_DEVICE = CecDevice.PLAYBACK_1;
+
+    private static final LogicalAddress PLAYBACK_DEVICE = LogicalAddress.PLAYBACK_1;
     private static final int INCORRECT_VENDOR_ID = 0x0;
 
+    public HdmiCecClientWrapper hdmiCecClient = new HdmiCecClientWrapper(LogicalAddress.PLAYBACK_1);
+
     @Rule
-    public HdmiCecClientWrapper hdmiCecClient =
-        new HdmiCecClientWrapper(CecDevice.PLAYBACK_1, this);
+    public RuleChain ruleChain =
+        RuleChain
+            .outerRule(new RequiredFeatureRule(this, LogicalAddress.HDMI_CEC_FEATURE))
+            .around(new RequiredFeatureRule(this, LogicalAddress.LEANBACK_FEATURE))
+            .around(RequiredPropertyRule.asCsvContainsValue(
+                this,
+                LogicalAddress.HDMI_DEVICE_TYPE_PROPERTY,
+                PLAYBACK_DEVICE.getDeviceType()))
+            .around(hdmiCecClient);
 
     /**
      * Test 11.2.9-1
@@ -48,10 +62,14 @@
      */
     @Test
     public void cect_11_2_9_1_GiveDeviceVendorId() throws Exception {
-        for (CecDevice cecDevice : CecDevice.values()) {
-            hdmiCecClient.sendCecMessage(cecDevice, CecMessage.GIVE_DEVICE_VENDOR_ID);
-            String message = hdmiCecClient.checkExpectedOutput(CecMessage.DEVICE_VENDOR_ID);
-            assertNotEquals(INCORRECT_VENDOR_ID, hdmiCecClient.getParamsFromMessage(message));
+        for (LogicalAddress logicalAddress : LogicalAddress.values()) {
+            // Skip the logical address of this device
+            if (logicalAddress == PLAYBACK_DEVICE) {
+                continue;
+            }
+            hdmiCecClient.sendCecMessage(logicalAddress, CecOperand.GIVE_DEVICE_VENDOR_ID);
+            String message = hdmiCecClient.checkExpectedOutput(CecOperand.DEVICE_VENDOR_ID);
+            assertThat(CecMessage.getParams(message)).isNotEqualTo(INCORRECT_VENDOR_ID);
         }
     }
 
@@ -65,7 +83,7 @@
         ITestDevice device = getDevice();
         device.executeShellCommand("reboot");
         device.waitForBootComplete(HdmiCecConstants.REBOOT_TIMEOUT);
-        String message = hdmiCecClient.checkExpectedOutput(CecMessage.DEVICE_VENDOR_ID);
-        assertNotEquals(INCORRECT_VENDOR_ID, hdmiCecClient.getParamsFromMessage(message));
+        String message = hdmiCecClient.checkExpectedOutput(CecOperand.DEVICE_VENDOR_ID);
+        assertThat(CecMessage.getParams(message)).isNotEqualTo(INCORRECT_VENDOR_ID);
     }
 }
diff --git a/hostsidetests/incident/apps/errorsapp/jni/Android.bp b/hostsidetests/incident/apps/errorsapp/jni/Android.bp
index 7c61818..2e7e1f0 100644
--- a/hostsidetests/incident/apps/errorsapp/jni/Android.bp
+++ b/hostsidetests/incident/apps/errorsapp/jni/Android.bp
@@ -20,5 +20,6 @@
         "-Werror",
         "-Wno-unused-parameter",
     ],
+    header_libs: ["jni_headers"],
     sdk_version: "current",
 }
diff --git a/hostsidetests/incident/apps/errorsapp/src/com/android/server/cts/errors/ErrorsTests.java b/hostsidetests/incident/apps/errorsapp/src/com/android/server/cts/errors/ErrorsTests.java
index 923211d..97a67ba 100644
--- a/hostsidetests/incident/apps/errorsapp/src/com/android/server/cts/errors/ErrorsTests.java
+++ b/hostsidetests/incident/apps/errorsapp/src/com/android/server/cts/errors/ErrorsTests.java
@@ -17,26 +17,20 @@
 
 import static org.junit.Assert.assertTrue;
 
-import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.DropBoxManager;
 import android.util.Log;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.compatibility.common.util.DropBoxReceiver;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Used by ErrorTest. Spawns misbehaving activities so reports will appear in Dropbox.
- */
+/** Used by ErrorTest. Spawns misbehaving activities so reports will appear in Dropbox. */
 @RunWith(AndroidJUnit4.class)
 public class ErrorsTests {
     private static final String TAG = "ErrorsTests";
@@ -46,37 +40,36 @@
     private static final String NATIVE_CRASH_TAG = "data_app_native_crash";
     private static final String TOMBSTONE_TAG = "SYSTEM_TOMBSTONE";
 
-    private static final int TIMEOUT_SECS = 60 * 3;
-
-    private CountDownLatch mResultsReceivedSignal;
-    private DropBoxManager mDropbox;
-    private long mStartMs;
     private Context mContext;
 
     @Before
     public void setUp() {
         mContext = InstrumentationRegistry.getTargetContext();
-        mDropbox = (DropBoxManager) mContext.getSystemService(Context.DROPBOX_SERVICE);
-        mResultsReceivedSignal = new CountDownLatch(1);
-        mStartMs = System.currentTimeMillis();
 
-        InstrumentationRegistry.getInstrumentation().getUiAutomation().executeShellCommand(
-                "appops set " + mContext.getPackageName() + " android:get_usage_stats allow");
+        InstrumentationRegistry.getInstrumentation()
+                .getUiAutomation()
+                .executeShellCommand(
+                        "appops set "
+                                + mContext.getPackageName()
+                                + " android:get_usage_stats allow");
     }
 
     @Test
     public void testException() throws Exception {
         Log.i(TAG, "testException");
 
-        registerReceiver(mContext, mResultsReceivedSignal, CRASH_TAG,
-                 mContext.getPackageName() + ":TestProcess",
-                "java.lang.RuntimeException: This is a test exception");
+        final DropBoxReceiver receiver =
+                new DropBoxReceiver(
+                        mContext,
+                        CRASH_TAG,
+                        mContext.getPackageName() + ":TestProcess",
+                        "java.lang.RuntimeException: This is a test exception");
         Intent intent = new Intent();
         intent.setClass(mContext, ExceptionActivity.class);
         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         mContext.startActivity(intent);
 
-        assertTrue(mResultsReceivedSignal.await(TIMEOUT_SECS, TimeUnit.SECONDS));
+        assertTrue(receiver.await());
     }
 
     @Test
@@ -84,76 +77,57 @@
         Log.i(TAG, "testANR");
 
         // Require that we get an ANR entry that shows that the activity is blocked in onCreate.
-        registerReceiver(mContext, mResultsReceivedSignal, ANR_TAG,
-                mContext.getPackageName() + ":TestProcess",
-                "com.android.server.cts.errors.ANRActivity.onCreate");
+        final DropBoxReceiver receiver =
+                new DropBoxReceiver(
+                        mContext,
+                        ANR_TAG,
+                        mContext.getPackageName() + ":TestProcess",
+                        "com.android.server.cts.errors.ANRActivity.onCreate");
         Intent intent = new Intent();
         intent.setClass(mContext, ANRActivity.class);
         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         mContext.startActivity(intent);
 
-        final Intent receiver = new Intent(mContext, Receiver.class);
-        mContext.sendBroadcast(receiver);
+        final Intent receiverIntent = new Intent(mContext, Receiver.class);
+        mContext.sendBroadcast(receiverIntent);
         Log.i(TAG, "testANR -- sent broadcast to " + receiver);
 
-        assertTrue(mResultsReceivedSignal.await(TIMEOUT_SECS, TimeUnit.SECONDS));
+        assertTrue(receiver.await());
     }
 
     @Test
     public void testNativeCrash() throws Exception {
         Log.i(TAG, "testNativeCrash");
 
-        registerReceiver(mContext, mResultsReceivedSignal, NATIVE_CRASH_TAG,
-                mContext.getPackageName() + ":TestProcess", "backtrace:");
+        final DropBoxReceiver receiver =
+                new DropBoxReceiver(
+                        mContext,
+                        NATIVE_CRASH_TAG,
+                        mContext.getPackageName() + ":TestProcess",
+                        "backtrace:");
         Intent intent = new Intent();
         intent.setClass(mContext, NativeActivity.class);
         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         mContext.startActivity(intent);
 
-        assertTrue(mResultsReceivedSignal.await(TIMEOUT_SECS, TimeUnit.SECONDS));
+        assertTrue(receiver.await());
     }
 
     @Test
     public void testTombstone() throws Exception {
         Log.i(TAG, "testTombstone");
 
-        registerReceiver(mContext, mResultsReceivedSignal, TOMBSTONE_TAG,
-                mContext.getPackageName() + ":TestProcess", "backtrace:");
+        final DropBoxReceiver receiver =
+                new DropBoxReceiver(
+                        mContext,
+                        TOMBSTONE_TAG,
+                        mContext.getPackageName() + ":TestProcess",
+                        "backtrace:");
         Intent intent = new Intent();
         intent.setClass(mContext, NativeActivity.class);
         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         mContext.startActivity(intent);
 
-        assertTrue(mResultsReceivedSignal.await(TIMEOUT_SECS, TimeUnit.SECONDS));
-    }
-
-    void registerReceiver(Context ctx, CountDownLatch onReceiveLatch, String wantTag,
-            String... wantInStackTrace) {
-        ctx.registerReceiver(new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                // DropBox might receive other entries while we're waiting for the error
-                // entry, so we need to check the tag and stack trace before continuing.
-                while (true) {
-                    final DropBoxManager.Entry entry = mDropbox.getNextEntry(wantTag, mStartMs);
-                    if (entry == null) {
-                        break;
-                    }
-                    Log.d(TAG, "ErrorsTest got message from drobpox: " + entry.getTag());
-                    mStartMs = entry.getTimeMillis();
-                    String stackTrace = entry.getText(64 * 1024);
-                    boolean allMatches = true;
-                    for (String line : wantInStackTrace) {
-                        boolean matched = stackTrace.contains(line);
-                        Log.d(TAG, "   matched=" + matched + " line: " + line);
-                        allMatches &= matched;
-                    }
-                    if (allMatches) {
-                        onReceiveLatch.countDown();
-                    }
-                    entry.close();
-                }
-            }
-        }, new IntentFilter(DropBoxManager.ACTION_DROPBOX_ENTRY_ADDED));
+        assertTrue(receiver.await());
     }
 }
diff --git a/hostsidetests/incrementalinstall/app/nativelibcompressed/Android.bp b/hostsidetests/incrementalinstall/app/nativelibcompressed/Android.bp
index e4a03f8..7d7a602 100644
--- a/hostsidetests/incrementalinstall/app/nativelibcompressed/Android.bp
+++ b/hostsidetests/incrementalinstall/app/nativelibcompressed/Android.bp
@@ -16,6 +16,7 @@
     name: "libcompressednativeincrementaltest",
     sdk_version: "current", // Oreo
     cppflags: ["-std=c++11"],
+    header_libs: ["jni_headers"],
     srcs: ["src/cpp/compressednative_lib.cpp"],
     stl: "c++_static",
 }
diff --git a/hostsidetests/incrementalinstall/app/nativelibuncompressed/Android.bp b/hostsidetests/incrementalinstall/app/nativelibuncompressed/Android.bp
index 9bc1662..3421fb8 100644
--- a/hostsidetests/incrementalinstall/app/nativelibuncompressed/Android.bp
+++ b/hostsidetests/incrementalinstall/app/nativelibuncompressed/Android.bp
@@ -16,6 +16,7 @@
     name: "libuncompressednativeincrementaltest",
     sdk_version: "current", // Oreo
     cppflags: ["-std=c++11"],
+    header_libs: ["jni_headers"],
     srcs: ["src/cpp/uncompressednative_lib.cpp"],
     stl: "c++_static",
 }
diff --git a/hostsidetests/incrementalinstall/appvalidator/src/android/incrementalinstall/inrementaltestappvalidation/jni/Android.bp b/hostsidetests/incrementalinstall/appvalidator/src/android/incrementalinstall/inrementaltestappvalidation/jni/Android.bp
index 96ddc04..28d7450 100644
--- a/hostsidetests/incrementalinstall/appvalidator/src/android/incrementalinstall/inrementaltestappvalidation/jni/Android.bp
+++ b/hostsidetests/incrementalinstall/appvalidator/src/android/incrementalinstall/inrementaltestappvalidation/jni/Android.bp
@@ -25,6 +25,7 @@
          "-Wunreachable-code",
          "-Wno-unused-parameter",
      ],
+     header_libs: ["jni_headers"],
      srcs: [
        "path_checker.cpp",
      ],
@@ -32,4 +33,4 @@
        "libbase",
        "libincfs",
      ],
- }
\ No newline at end of file
+ }
diff --git a/hostsidetests/inputmethodservice/deviceside/devicetest/src/android/inputmethodservice/cts/devicetest/InputMethodServiceDeviceTest.java b/hostsidetests/inputmethodservice/deviceside/devicetest/src/android/inputmethodservice/cts/devicetest/InputMethodServiceDeviceTest.java
index 7738e31..d508a1d 100644
--- a/hostsidetests/inputmethodservice/deviceside/devicetest/src/android/inputmethodservice/cts/devicetest/InputMethodServiceDeviceTest.java
+++ b/hostsidetests/inputmethodservice/deviceside/devicetest/src/android/inputmethodservice/cts/devicetest/InputMethodServiceDeviceTest.java
@@ -62,7 +62,7 @@
 @RunWith(AndroidJUnit4.class)
 public class InputMethodServiceDeviceTest {
 
-    private static final long TIMEOUT = TimeUnit.SECONDS.toMillis(5);
+    private static final long TIMEOUT = TimeUnit.SECONDS.toMillis(7);
 
     /** Test to check CtsInputMethod1 receives onCreate and onStartInput. */
     @Test
diff --git a/hostsidetests/jdwptunnel/Android.bp b/hostsidetests/jdwptunnel/Android.bp
index f649e5a..a8f562c 100644
--- a/hostsidetests/jdwptunnel/Android.bp
+++ b/hostsidetests/jdwptunnel/Android.bp
@@ -27,7 +27,8 @@
     data: [
         // Include the JDI classes in the testcases directory.
         ":jdi-support",
-        ":CtsJdwpTunnelSampleApp",
+        ":CtsJdwpTunnelDebuggableSampleApp",
+        ":CtsJdwpTunnelProfileableSampleApp",
     ],
 
     // Tag this module as a cts test artifact
@@ -37,5 +38,5 @@
         "general-tests",
     ],
 
-    // LOCAL_CTS_TEST_PACKAGE := android.host.jdwptunnel
+    // LOCAL_CTS_TEST_PACKAGE := android.host.jdwptunnel.*
 }
diff --git a/hostsidetests/jdwptunnel/sampleapp/Android.bp b/hostsidetests/jdwptunnel/sampleapps/debuggableapp/Android.bp
similarity index 94%
rename from hostsidetests/jdwptunnel/sampleapp/Android.bp
rename to hostsidetests/jdwptunnel/sampleapps/debuggableapp/Android.bp
index 0ed8655..384ee5f 100644
--- a/hostsidetests/jdwptunnel/sampleapp/Android.bp
+++ b/hostsidetests/jdwptunnel/sampleapps/debuggableapp/Android.bp
@@ -13,7 +13,7 @@
 // limitations under the License.
 
 android_test_helper_app {
-    name: "CtsJdwpTunnelSampleApp",
+    name: "CtsJdwpTunnelDebuggableSampleApp",
 
     dex_preopt: {
         enabled: false,
diff --git a/hostsidetests/jdwptunnel/sampleapp/AndroidManifest.xml b/hostsidetests/jdwptunnel/sampleapps/debuggableapp/AndroidManifest.xml
similarity index 89%
rename from hostsidetests/jdwptunnel/sampleapp/AndroidManifest.xml
rename to hostsidetests/jdwptunnel/sampleapps/debuggableapp/AndroidManifest.xml
index 67dd17d..2e2d2dd 100755
--- a/hostsidetests/jdwptunnel/sampleapp/AndroidManifest.xml
+++ b/hostsidetests/jdwptunnel/sampleapps/debuggableapp/AndroidManifest.xml
@@ -16,10 +16,10 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.jdwptunnel.sampleapp">
+    package="android.jdwptunnel.sampleapp.debuggable">
 
     <application android:debuggable="true">
-        <activity android:name=".SampleDeviceActivity" >
+        <activity android:name=".DebuggableSampleDeviceActivity" >
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.LAUNCHER" />
diff --git a/hostsidetests/jdwptunnel/sampleapp/res/layout/sample_layout.xml b/hostsidetests/jdwptunnel/sampleapps/debuggableapp/res/layout/sample_layout.xml
similarity index 100%
rename from hostsidetests/jdwptunnel/sampleapp/res/layout/sample_layout.xml
rename to hostsidetests/jdwptunnel/sampleapps/debuggableapp/res/layout/sample_layout.xml
diff --git a/hostsidetests/jdwptunnel/sampleapp/src/android/jdwptunnel/sampleapp/SampleDeviceActivity.java b/hostsidetests/jdwptunnel/sampleapps/debuggableapp/src/android/jdwptunnel/sampleapp/DebuggableSampleDeviceActivity.java
similarity index 88%
rename from hostsidetests/jdwptunnel/sampleapp/src/android/jdwptunnel/sampleapp/SampleDeviceActivity.java
rename to hostsidetests/jdwptunnel/sampleapps/debuggableapp/src/android/jdwptunnel/sampleapp/DebuggableSampleDeviceActivity.java
index ff3142d..f5da3f4 100644
--- a/hostsidetests/jdwptunnel/sampleapp/src/android/jdwptunnel/sampleapp/SampleDeviceActivity.java
+++ b/hostsidetests/jdwptunnel/sampleapps/debuggableapp/src/android/jdwptunnel/sampleapp/DebuggableSampleDeviceActivity.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.jdwptunnel.sampleapp;
+package android.jdwptunnel.sampleapp.debuggable;
 
 import android.app.Activity;
 import android.os.Bundle;
@@ -24,7 +24,7 @@
  *
  * <p>This serves as a simple target application/activity to attach a debugger to.
  */
-public final class SampleDeviceActivity extends Activity {
+public final class DebuggableSampleDeviceActivity extends Activity {
     @Override
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
diff --git a/hostsidetests/jdwptunnel/sampleapp/Android.bp b/hostsidetests/jdwptunnel/sampleapps/profileableapp/Android.bp
similarity index 87%
copy from hostsidetests/jdwptunnel/sampleapp/Android.bp
copy to hostsidetests/jdwptunnel/sampleapps/profileableapp/Android.bp
index 0ed8655..b78236a 100644
--- a/hostsidetests/jdwptunnel/sampleapp/Android.bp
+++ b/hostsidetests/jdwptunnel/sampleapps/profileableapp/Android.bp
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 The Android Open Source Project
+// Copyright (C) 2020 The Android Open Source Project
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -13,7 +13,7 @@
 // limitations under the License.
 
 android_test_helper_app {
-    name: "CtsJdwpTunnelSampleApp",
+    name: "CtsJdwpTunnelProfileableSampleApp",
 
     dex_preopt: {
         enabled: false,
diff --git a/hostsidetests/jdwptunnel/sampleapp/AndroidManifest.xml b/hostsidetests/jdwptunnel/sampleapps/profileableapp/AndroidManifest.xml
similarity index 77%
copy from hostsidetests/jdwptunnel/sampleapp/AndroidManifest.xml
copy to hostsidetests/jdwptunnel/sampleapps/profileableapp/AndroidManifest.xml
index 67dd17d..eb73f5d 100755
--- a/hostsidetests/jdwptunnel/sampleapp/AndroidManifest.xml
+++ b/hostsidetests/jdwptunnel/sampleapps/profileableapp/AndroidManifest.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,15 +16,16 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.jdwptunnel.sampleapp">
+    package="android.jdwptunnel.sampleapp.profileable">
 
-    <application android:debuggable="true">
-        <activity android:name=".SampleDeviceActivity" >
+    <application android:debuggable="false">
+        <activity android:name=".ProfileableSampleDeviceActivity" >
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
+       <profileable android:shell="true" />
     </application>
 
 </manifest>
diff --git a/hostsidetests/jdwptunnel/sampleapp/res/layout/sample_layout.xml b/hostsidetests/jdwptunnel/sampleapps/profileableapp/res/layout/sample_layout.xml
similarity index 100%
copy from hostsidetests/jdwptunnel/sampleapp/res/layout/sample_layout.xml
copy to hostsidetests/jdwptunnel/sampleapps/profileableapp/res/layout/sample_layout.xml
diff --git a/hostsidetests/jdwptunnel/sampleapp/src/android/jdwptunnel/sampleapp/SampleDeviceActivity.java b/hostsidetests/jdwptunnel/sampleapps/profileableapp/src/android/jdwptunnel/sampleapp/ProfileableSampleDeviceActivity.java
similarity index 83%
copy from hostsidetests/jdwptunnel/sampleapp/src/android/jdwptunnel/sampleapp/SampleDeviceActivity.java
copy to hostsidetests/jdwptunnel/sampleapps/profileableapp/src/android/jdwptunnel/sampleapp/ProfileableSampleDeviceActivity.java
index ff3142d..ff7b3e6 100644
--- a/hostsidetests/jdwptunnel/sampleapp/src/android/jdwptunnel/sampleapp/SampleDeviceActivity.java
+++ b/hostsidetests/jdwptunnel/sampleapps/profileableapp/src/android/jdwptunnel/sampleapp/ProfileableSampleDeviceActivity.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.jdwptunnel.sampleapp;
+package android.jdwptunnel.sampleapp.profileable;
 
 import android.app.Activity;
 import android.os.Bundle;
@@ -24,7 +24,7 @@
  *
  * <p>This serves as a simple target application/activity to attach a debugger to.
  */
-public final class SampleDeviceActivity extends Activity {
+public final class ProfileableSampleDeviceActivity extends Activity {
     @Override
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
diff --git a/hostsidetests/jdwptunnel/src/android/jdwptunnel/cts/JdwpTunnelTest.java b/hostsidetests/jdwptunnel/src/android/jdwptunnel/cts/JdwpTunnelTest.java
index 518a1c5..cbf2303 100644
--- a/hostsidetests/jdwptunnel/src/android/jdwptunnel/cts/JdwpTunnelTest.java
+++ b/hostsidetests/jdwptunnel/src/android/jdwptunnel/cts/JdwpTunnelTest.java
@@ -17,6 +17,8 @@
 package android.jdwptunnel.cts;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
@@ -50,7 +52,7 @@
  * <p>This test ensures that it is possible to attach a debugger to an app using 'adb' and perform
  * at least some basic debugging actions.
  *
- * <p>The {@link SampleDeviceActivity} is the activity we are debugging.
+ * <p>The {@link DebuggableSampleDeviceActivity} is the activity we are debugging.
  *
  * <p>We will start that activity with 'wait-for-debugger', set a breakpoint on the first line of
  * the {@code onCreate} method and wait for the breakpoint to be hit.
@@ -59,16 +61,21 @@
  */
 @RunWith(DeviceJUnit4ClassRunner.class)
 public class JdwpTunnelTest extends BaseHostJUnit4Test {
-    private static final String TEST_APP_PACKAGE_NAME = "android.jdwptunnel.sampleapp";
-    private static final String TEST_APP_ACTIVITY_CLASS_NAME = "SampleDeviceActivity";
-    private final static String TEST_APP_FULL_CLASS_NAME =
-            TEST_APP_PACKAGE_NAME + "." + TEST_APP_ACTIVITY_CLASS_NAME;
+    private static final String DEBUGGABLE_TEST_APP_PACKAGE_NAME =
+      "android.jdwptunnel.sampleapp.debuggable";
+    private static final String DEBUGGABLE_TEST_APP_ACTIVITY_CLASS_NAME =
+      "DebuggableSampleDeviceActivity";
+    private static final String PROFILEABLE_TEST_APP_PACKAGE_NAME =
+      "android.jdwptunnel.sampleapp.profileable";
+    private static final String PROFILEABLE_TEST_APP_ACTIVITY_CLASS_NAME =
+      "ProfileableSampleDeviceActivity";
 
     private ITestDevice mDevice;
 
     @Before
     public void setUp() throws Exception {
-        installPackage("CtsJdwpTunnelSampleApp.apk");
+        installPackage("CtsJdwpTunnelDebuggableSampleApp.apk");
+        installPackage("CtsJdwpTunnelProfileableSampleApp.apk");
         mDevice = getDevice();
     }
 
@@ -110,17 +117,17 @@
         return port;
     }
 
-    private VirtualMachine startupTest() throws Exception {
+    private VirtualMachine startupTest(String packageName, String shortClassName) throws Exception {
         moveToHomeScreen();
         mDevice.executeShellCommand("cmd activity start-activity -D -W -n " +
-                TEST_APP_PACKAGE_NAME + "/." + TEST_APP_ACTIVITY_CLASS_NAME);
+                packageName + "/." + shortClassName);
         // Don't keep trying after a minute.
         final Instant deadline = Instant.now().plusSeconds(60);
         String pid = "";
         while ((pid = mDevice.executeShellCommand(
-                    "pidof " + TEST_APP_PACKAGE_NAME).trim()).equals("")) {
+                    "pidof " + packageName).trim()).equals("")) {
             if (Instant.now().isAfter(deadline)) {
-                fail("Unable to find PID of " + TEST_APP_PACKAGE_NAME + " process!");
+                fail("Unable to find PID of " + packageName + " process!");
             }
             // Wait 1 second and try again.
             Thread.sleep(1000);
@@ -138,9 +145,11 @@
      *
      * TODO: We should expand this to more functions.
      */
-    @Test
-    public void testAttachDebugger() throws DeviceNotAvailableException, Exception {
-        VirtualMachine vm = startupTest();
+    private void testAttachDebugger(String packageName, String shortClassName)
+      throws DeviceNotAvailableException, Exception {
+        String fullClassName = packageName + "." + shortClassName;
+
+        VirtualMachine vm = startupTest(packageName, shortClassName);
         EventRequestManager erm = vm.eventRequestManager();
         try {
             // Just pause the runtime so it won't get ahead of us while we setup everything.
@@ -148,20 +157,20 @@
             // Overall timeout for this whole test. 2-minutes
             final Instant deadline = Instant.now().plusSeconds(120);
             // Check the test-activity class is not already loaded.
-            assertTrue(TEST_APP_ACTIVITY_CLASS_NAME + " is not yet loaded!",
+            assertTrue(shortClassName + " is not yet loaded!",
                     vm.allClasses().stream()
-                            .noneMatch(x -> x.name().equals(TEST_APP_FULL_CLASS_NAME)));
+                            .noneMatch(x -> x.name().equals(fullClassName)));
 
             // Wait for the class to load.
             ClassPrepareRequest cpr = erm.createClassPrepareRequest();
-            cpr.addClassFilter(TEST_APP_FULL_CLASS_NAME);
+            cpr.addClassFilter(fullClassName);
             cpr.setSuspendPolicy(EventRequest.SUSPEND_ALL);
             cpr.enable();
             vm.resume();
             ReferenceType activityType = null;
             while (activityType == null) {
                 if (Instant.now().isAfter(deadline)) {
-                    fail(TEST_APP_FULL_CLASS_NAME + " did not load within timeout!");
+                    fail(fullClassName + " did not load within timeout!");
                 }
                 activityType = vm.eventQueue().remove().stream()
                         .filter(e -> cpr == e.request())
@@ -180,7 +189,7 @@
             // Wait for the event.
             while (!vm.eventQueue().remove().stream().anyMatch(e -> e.request() == bpr)) {
                 if (Instant.now().isAfter(deadline)) {
-                    fail(TEST_APP_FULL_CLASS_NAME + " did hit onCreate breakpoint within timeout!");
+                    fail(fullClassName + " did hit onCreate breakpoint within timeout!");
                 }
             }
             bpr.disable();
@@ -190,4 +199,61 @@
             vm.dispose();
         }
     }
+
+    /**
+     * Tests that we can attach a debugger and perform basic debugging functions to a
+     * debuggable app.
+     *
+     * We start the app with Wait-for-debugger. Wait for the ClassPrepare of the activity
+     * class and put and wait for a breakpoint on the onCreate function.
+     */
+    @Test
+    public void testAttachDebuggerToDebuggableApp() throws DeviceNotAvailableException, Exception {
+        testAttachDebugger(DEBUGGABLE_TEST_APP_PACKAGE_NAME,
+                           DEBUGGABLE_TEST_APP_ACTIVITY_CLASS_NAME);
+    }
+
+    /**
+     * Tests that we CANNOT attach a debugger to a non-debuggable-but-profileable app.
+     *
+     * We test the attempt to attach the debuggable should fail on a user build device at the
+     * expected API call.
+     */
+    @Test
+    public void testAttachDebuggerToProfileableApp() throws DeviceNotAvailableException, Exception {
+        java.io.IOException thrownException = null;
+        try {
+            testAttachDebugger(PROFILEABLE_TEST_APP_PACKAGE_NAME,
+                               PROFILEABLE_TEST_APP_ACTIVITY_CLASS_NAME);
+        } catch (java.io.IOException e) {
+            thrownException = e;
+        }
+        String debuggableDevice = mDevice.getProperty("ro.debuggable");
+        if (debuggableDevice.equals("1")) {
+            assertNull(thrownException);
+            return;
+        }
+        // We are on a user (production) build device.
+        assertNotNull(thrownException);
+        if (thrownException != null) {
+            // Verify the exception is thrown from the "getDebuggerConnection" method in this test
+            // when it calls the "attach" method from class AttachingConnector or its subclass.
+            // In other words, the callstack is expected to look like
+            //
+            // at jdk.jdi/com.sun.tools.jdi.SocketAttachingConnector.attach(SocketAttachingConnector.java:83)
+            // at android.jdwptunnel.cts.JdwpTunnelTest.getDebuggerConnection(JdwpTunnelTest.java:96)
+            boolean thrownByGetDebuggerConnection = false;
+            StackTraceElement[] stack = thrownException.getStackTrace();
+            for (int i = 0; i < stack.length; i++) {
+                if (stack[i].getClassName().equals("android.jdwptunnel.cts.JdwpTunnelTest") &&
+                    stack[i].getMethodName().equals("getDebuggerConnection")) {
+                    thrownByGetDebuggerConnection = true;
+                    assertTrue(i > 0);
+                    assertEquals("attach", stack[i - 1].getMethodName());
+                    break;
+                }
+            }
+            assertTrue(thrownByGetDebuggerConnection);
+        }
+    }
 }
diff --git a/hostsidetests/jvmti/base/jni/Android.bp b/hostsidetests/jvmti/base/jni/Android.bp
index 4940df3..be7da74 100644
--- a/hostsidetests/jvmti/base/jni/Android.bp
+++ b/hostsidetests/jvmti/base/jni/Android.bp
@@ -24,6 +24,7 @@
     ],
 
     header_libs: [
+        "jni_headers",
         "libopenjdkjvmti_headers",
     ],
 
diff --git a/hostsidetests/jvmti/base/jni/cts_logging.cpp b/hostsidetests/jvmti/base/jni/cts_logging.cpp
index b37e1f9..e6b182e 100644
--- a/hostsidetests/jvmti/base/jni/cts_logging.cpp
+++ b/hostsidetests/jvmti/base/jni/cts_logging.cpp
@@ -25,18 +25,33 @@
 
 namespace art {
 
+typedef jvmtiError (*SetVerboseFlagExt)(jvmtiEnv*, const char*, jboolean);
 extern "C" JNIEXPORT void JNICALL
-Java_android_jvmti_cts_JvmtiRunTestBasedTest_setupExtraLogging(JNIEnv* env, jclass) {
-  JvmtiErrorToException(env, jvmti_env, jvmti_env->SetVerboseFlag(JVMTI_VERBOSE_OTHER, true));
+Java_android_jvmti_cts_JvmtiRunTestBasedTest_setupExtraLogging(JNIEnv* env, jclass, jstring arg) {
+  SetVerboseFlagExt set_flag_ext = GetExtensionFunction<SetVerboseFlagExt>(
+      env, jvmti_env, "com.android.art.misc.set_verbose_flag_ext");
+  if (set_flag_ext == nullptr) {
+    // Just do backup and enable everything.
+    JvmtiErrorToException(env, jvmti_env, jvmti_env->SetVerboseFlag(JVMTI_VERBOSE_OTHER, true));
+  } else {
+    // UTFChars doesn't need to be null terminated.
+    const char* data_raw = env->GetStringUTFChars(arg, nullptr);
+    std::string data;
+    data.resize(env->GetStringUTFLength(arg));
+    memcpy(data.data(), data_raw, data.size());
+    env->ReleaseStringUTFChars(arg, data_raw);
+    JvmtiErrorToException(env, jvmti_env, set_flag_ext(jvmti_env, data.c_str(), true));
+  }
 }
 
 static JNINativeMethod gMethods[] = {
-  { "setupExtraLogging", "()V",
-          (void*)Java_android_jvmti_cts_JvmtiRunTestBasedTest_setupExtraLogging },
+  { "setupExtraLogging",
+    "(Ljava/lang/String;)V",
+    (void*)Java_android_jvmti_cts_JvmtiRunTestBasedTest_setupExtraLogging },
 };
 void register_android_jvmti_cts_JvmtiRunTestBasedTest(jvmtiEnv* jenv, JNIEnv* env) {
-  ScopedLocalRef<jclass> klass(env, GetClass(jenv, env,
-          "android/jvmti/cts/JvmtiRunTestBasedTest", nullptr));
+  ScopedLocalRef<jclass> klass(
+      env, GetClass(jenv, env, "android/jvmti/cts/JvmtiRunTestBasedTest", nullptr));
   if (klass.get() == nullptr) {
     env->ExceptionClear();
     return;
diff --git a/hostsidetests/jvmti/base/run-test-based-app/Android.bp b/hostsidetests/jvmti/base/run-test-based-app/Android.bp
index d2f9d09..7f2303c 100644
--- a/hostsidetests/jvmti/base/run-test-based-app/Android.bp
+++ b/hostsidetests/jvmti/base/run-test-based-app/Android.bp
@@ -14,12 +14,8 @@
 
 java_library {
     name: "CtsJvmtiDeviceRunTestAppBase",
-
-    // We explicitly enumerate, as we have a definition of art.Main to simplify development
-    // in an IDE (but want the implementation of said class to come from the ART run-tests).
     srcs: [
         "src/android/jvmti/cts/JvmtiRunTestBasedTest.java",
-        ":art_cts_jvmti_test_library",
     ],
     // Allow sun.misc.Unsafe.
     target: {
@@ -36,6 +32,7 @@
         "junit",
     ],
     static_libs: [
+        "art_cts_jvmti_test_library",
         "CtsJvmtiDeviceAppBase",
         "expected_cts_outputs",
     ],
diff --git a/hostsidetests/jvmti/base/run-test-based-app/src/android/jvmti/cts/JvmtiRunTestBasedTest.java b/hostsidetests/jvmti/base/run-test-based-app/src/android/jvmti/cts/JvmtiRunTestBasedTest.java
index a59fd3f..b773c41 100644
--- a/hostsidetests/jvmti/base/run-test-based-app/src/android/jvmti/cts/JvmtiRunTestBasedTest.java
+++ b/hostsidetests/jvmti/base/run-test-based-app/src/android/jvmti/cts/JvmtiRunTestBasedTest.java
@@ -90,7 +90,11 @@
         System.setErr(oldErr);
     }
 
-    private native void setupExtraLogging();
+    private void setupExtraLogging() {
+      setupExtraLogging("plugin,deopt,jdwp,jit,agents,threads");
+    }
+
+    private native void setupExtraLogging(String arg);
 
     protected boolean doExtraLogging() throws Exception {
         return mActivity
diff --git a/hostsidetests/os/test-apps/StaticSharedNativeLibConsumer/Android.bp b/hostsidetests/os/test-apps/StaticSharedNativeLibConsumer/Android.bp
index 5c0a10e..547416a 100644
--- a/hostsidetests/os/test-apps/StaticSharedNativeLibConsumer/Android.bp
+++ b/hostsidetests/os/test-apps/StaticSharedNativeLibConsumer/Android.bp
@@ -38,6 +38,7 @@
         "-Werror",
     ],
     srcs: ["**/*.cpp"],
+    header_libs: ["jni_headers"],
     shared_libs: [
         "liblog",
         "libstaticsharednativelibprovider",
diff --git a/hostsidetests/packagemanager/extractnativelibs/apps/Android.bp b/hostsidetests/packagemanager/extractnativelibs/apps/Android.bp
index 8d1a673..656938e 100644
--- a/hostsidetests/packagemanager/extractnativelibs/apps/Android.bp
+++ b/hostsidetests/packagemanager/extractnativelibs/apps/Android.bp
@@ -21,6 +21,7 @@
         "-Werror",
         "-Wno-unused-parameter",
     ],
+    header_libs: ["jni_headers"],
     sdk_version: "current",
 }
 
diff --git a/hostsidetests/seccomp/app/jni/Android.bp b/hostsidetests/seccomp/app/jni/Android.bp
index 3dc4f1c..b528c53 100644
--- a/hostsidetests/seccomp/app/jni/Android.bp
+++ b/hostsidetests/seccomp/app/jni/Android.bp
@@ -20,6 +20,7 @@
         "android_seccomp_cts_app_SeccompDeviceTest.cpp",
     ],
     sdk_version: "current",
+    header_libs: ["jni_headers"],
     static_libs: ["cpufeatures"],
     cflags: [
         "-Wall",
diff --git a/hostsidetests/seccomp/app/src/android/seccomp/cts/app/SeccompDeviceTest.java b/hostsidetests/seccomp/app/src/android/seccomp/cts/app/SeccompDeviceTest.java
index a1ab899..20cf791 100644
--- a/hostsidetests/seccomp/app/src/android/seccomp/cts/app/SeccompDeviceTest.java
+++ b/hostsidetests/seccomp/app/src/android/seccomp/cts/app/SeccompDeviceTest.java
@@ -198,12 +198,8 @@
             return "x86_64";
         } else if (CpuFeatures.isX86Cpu()) {
             return "x86";
-        } else if (CpuFeatures.isMips64Cpu()) {
-            return "mips64";
-        } else if (CpuFeatures.isMipsCpu()) {
-            return "mips";
         } else {
-            Assert.fail("Unsupported OS");
+            Assert.fail("Unsupported architecture");
             return null;
         }
     }
diff --git a/hostsidetests/security/src/android/security/cts/KernelConfigTest.java b/hostsidetests/security/src/android/security/cts/KernelConfigTest.java
index 40a1391..f4cec1f 100644
--- a/hostsidetests/security/src/android/security/cts/KernelConfigTest.java
+++ b/hostsidetests/security/src/android/security/cts/KernelConfigTest.java
@@ -220,9 +220,12 @@
         put("Kirin710", new String[]{"CONFIG_HARDEN_BRANCH_PREDICTOR=y"});
         put("SM6150", new String[]{"CONFIG_HARDEN_BRANCH_PREDICTOR=y"});
         put("SM7150", new String[]{"CONFIG_HARDEN_BRANCH_PREDICTOR=y"});
+        put("SM7250", null);
         put("LITO", null);
+        put("LAGOON", null);
         put("SM8150", new String[]{"CONFIG_HARDEN_BRANCH_PREDICTOR=y"});
         put("SM8150P", new String[]{"CONFIG_HARDEN_BRANCH_PREDICTOR=y"});
+        put("SM8250", null);
         put("KONA", null);
         put("SDM429", null);
         put("SDM439", null);
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2016-2471/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2016-2471/Android.bp
index 26635d9..53f06a5 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2016-2471/Android.bp
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2016-2471/Android.bp
@@ -15,6 +15,7 @@
 cc_test {
     name: "CVE-2016-2471",
     defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+    header_libs: ["jni_headers"],
     srcs: ["poc.c"],
     ldflags: [
         "-fPIE",
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2016-3747/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2016-3747/poc.cpp
index 38a0afa..fcdcdcb 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2016-3747/poc.cpp
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2016-3747/poc.cpp
@@ -18,7 +18,6 @@
 
 #include <OMX_Component.h>
 #include <binder/MemoryDealer.h>
-#include <jni.h>
 #include <log/log.h>
 #include <media/IOMX.h>
 #include <media/OMXBuffer.h>
diff --git a/hostsidetests/securitybulletin/securityPatch/includes/omxUtils.h b/hostsidetests/securitybulletin/securityPatch/includes/omxUtils.h
index 8986c32..32da687 100644
--- a/hostsidetests/securitybulletin/securityPatch/includes/omxUtils.h
+++ b/hostsidetests/securitybulletin/securityPatch/includes/omxUtils.h
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#include <jni.h>
+
 #include <fcntl.h>
 #include <unistd.h>
 #include <sys/types.h>
diff --git a/hostsidetests/shortcuts/hostside/Android.bp b/hostsidetests/shortcuts/hostside/Android.bp
index 646953e..3613975 100644
--- a/hostsidetests/shortcuts/hostside/Android.bp
+++ b/hostsidetests/shortcuts/hostside/Android.bp
@@ -27,4 +27,7 @@
         "vts10",
         "general-tests",
     ],
+    required: [
+        "CtsBackupHostTestCases",
+    ],
 }
diff --git a/hostsidetests/statsd/apps/statsdapp/Android.bp b/hostsidetests/statsd/apps/statsdapp/Android.bp
index eabea94..4d22f72 100644
--- a/hostsidetests/statsd/apps/statsdapp/Android.bp
+++ b/hostsidetests/statsd/apps/statsdapp/Android.bp
@@ -19,6 +19,7 @@
         "-Wall",
         "-Werror",
     ],
+    header_libs: ["jni_headers"],
     shared_libs: ["liblog"],
     stl: "c++_static",
     sdk_version: "current",
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/DeviceAtomTestCase.java b/hostsidetests/statsd/src/android/cts/statsd/atom/DeviceAtomTestCase.java
index 453f628..035160f 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/DeviceAtomTestCase.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/atom/DeviceAtomTestCase.java
@@ -55,6 +55,7 @@
         super.setUp();
         getDevice().uninstallPackage(DEVICE_SIDE_TEST_PACKAGE);
         installTestApp();
+        Thread.sleep(1000);
     }
 
     @Override
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/GarageModeAtomTests.java b/hostsidetests/statsd/src/android/cts/statsd/atom/GarageModeAtomTests.java
new file mode 100644
index 0000000..067aa7d
--- /dev/null
+++ b/hostsidetests/statsd/src/android/cts/statsd/atom/GarageModeAtomTests.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.cts.statsd.atom;
+
+import com.android.os.AtomsProto.Atom;
+import com.android.os.StatsLog.EventMetricData;
+
+import java.util.List;
+
+/**
+ * Verifies that Automotive's Garage Mode reports its status.
+ * Statsd atom tests are done via adb (hostside).
+ */
+public class GarageModeAtomTests extends AtomTestCase {
+
+    private static final String TAG = "Statsd.GarageModeAtomTests";
+    private static final int SHORT_SLEEP = 100; // Milliseconds
+    private static final int TRY_LIMIT = WAIT_TIME_SHORT / SHORT_SLEEP;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    public void testGarageModeOnOff() throws Exception {
+        if (statsdDisabled()) {
+            return;
+        }
+        if (!hasFeature(FEATURE_AUTOMOTIVE, true)) {
+            return;
+        }
+
+        final int atomTag = Atom.GARAGE_MODE_INFO_FIELD_NUMBER;
+        createAndUploadConfig(atomTag);
+
+        // Flush any old metrics
+        List<EventMetricData> data = getEventMetricDataList();
+
+        turnOnGarageMode();
+        waitForGarageModeState(true);
+
+        turnOffGarageMode();
+        waitForGarageModeState(false);
+    }
+
+    private void turnOnGarageMode() throws Exception {
+        getDevice().executeShellCommand("cmd car_service garage-mode on");
+    }
+    private void turnOffGarageMode() throws Exception {
+        getDevice().executeShellCommand("cmd car_service garage-mode off");
+    }
+
+    private void waitForGarageModeState(boolean requiredState) throws Exception {
+        for (int tryCount = 0; tryCount < TRY_LIMIT; tryCount++) {
+            List<EventMetricData> data = getEventMetricDataList();
+            for (EventMetricData d : data) {
+                boolean isGarageMode = d.getAtom().getGarageModeInfo().getIsGarageMode();
+                if (isGarageMode == requiredState) {
+                    return;
+                }
+            }
+            Thread.sleep(SHORT_SLEEP);
+        }
+        assertTrue("Did not receive an atom with Garage Mode "
+                   + (requiredState ? "ON" : "OFF"), false);
+    }
+}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java b/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
index f9e1ce2..423e135 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
@@ -1219,9 +1219,8 @@
         // Start test app.
         try (AutoCloseable a = withActivity("StatsdCtsForegroundActivity", "action",
                 "action.show_notification")) {
-            // Trigger a pull and wait for new pull before killing the process.
             Thread.sleep(WAIT_TIME_LONG);
-            // Trigger new pull.
+            // Trigger a pull and wait for new pull before killing the process.
             setAppBreadcrumbPredicate();
             Thread.sleep(WAIT_TIME_LONG);
         }
diff --git a/hostsidetests/statsd/src/android/cts/statsd/uidmap/UidMapTests.java b/hostsidetests/statsd/src/android/cts/statsd/uidmap/UidMapTests.java
index dab7f0f..e24b0df 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/uidmap/UidMapTests.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/uidmap/UidMapTests.java
@@ -78,7 +78,7 @@
         final String result = getDevice().installPackage(
                 buildHelper.getTestFile(DEVICE_SIDE_TEST_APK), false, true);
 
-        Thread.sleep(WAIT_TIME_SHORT);
+        Thread.sleep(WAIT_TIME_LONG);
 
         ConfigMetricsReportList reports = getReportList();
         assertThat(reports.getReportsCount()).isGreaterThan(0);
diff --git a/hostsidetests/tagging/common/Android.bp b/hostsidetests/tagging/common/Android.bp
index 2fb8785..da16a8e 100644
--- a/hostsidetests/tagging/common/Android.bp
+++ b/hostsidetests/tagging/common/Android.bp
@@ -29,6 +29,7 @@
         "-Wall",
         "-Werror",
     ],
+    header_libs: ["jni_headers"],
     sdk_version: "current",
     gtest: false,
 }
diff --git a/hostsidetests/tagging/common/jni/android_cts_tagging_Utils.cpp b/hostsidetests/tagging/common/jni/android_cts_tagging_Utils.cpp
index 3a99929..45bedd9 100644
--- a/hostsidetests/tagging/common/jni/android_cts_tagging_Utils.cpp
+++ b/hostsidetests/tagging/common/jni/android_cts_tagging_Utils.cpp
@@ -45,3 +45,13 @@
   return 0;
 #endif
 }
+
+extern "C" __attribute__((no_sanitize("address", "hwaddress")))
+JNIEXPORT void JNICALL
+Java_android_cts_tagging_Utils_accessMistaggedPointer(JNIEnv *) {
+  int* p = new int[4];
+  int* mistagged_p = reinterpret_cast<int*>(reinterpret_cast<uintptr_t>(p) + (1ULL << 56));
+  volatile int load = *mistagged_p;
+  (void)load;
+  delete[] p;
+}
diff --git a/hostsidetests/tagging/common/src/android/cts/tagging/Utils.java b/hostsidetests/tagging/common/src/android/cts/tagging/Utils.java
index 013842d..2897c9c 100644
--- a/hostsidetests/tagging/common/src/android/cts/tagging/Utils.java
+++ b/hostsidetests/tagging/common/src/android/cts/tagging/Utils.java
@@ -22,4 +22,5 @@
     }
     public static native boolean kernelSupportsTaggedPointers();
     public static native int nativeHeapPointerTag();
+    public static native void accessMistaggedPointer();
 }
diff --git a/hostsidetests/tagging/none/Android.bp b/hostsidetests/tagging/none/Android.bp
index 4314775..9a8c3c2 100644
--- a/hostsidetests/tagging/none/Android.bp
+++ b/hostsidetests/tagging/none/Android.bp
@@ -23,6 +23,7 @@
     ],
     static_libs: [
 	"tagging-common-devicesidelib",
+        "compatibility-device-util-axt",
         "ctstestrunner-axt",
         "androidx.test.rules",
         "androidx.test.core",
@@ -32,5 +33,5 @@
         "libtagging-common-devicesidelib-jni",
     ],
     srcs: ["src/**/*.java"],
-    sdk_version: "current",
+    sdk_version: "test_current",
 }
diff --git a/hostsidetests/tagging/none/AndroidManifest.xml b/hostsidetests/tagging/none/AndroidManifest.xml
index 0141359..a5a3c9a 100644
--- a/hostsidetests/tagging/none/AndroidManifest.xml
+++ b/hostsidetests/tagging/none/AndroidManifest.xml
@@ -18,9 +18,11 @@
     package="android.cts.tagging.none">
 
     <uses-sdk android:targetSdkVersion="29" />
+    <uses-permission android:name="android.permission.READ_LOGS"/>
 
     <application android:debuggable="true">
         <uses-library android:name="android.test.runner" />
+        <activity android:name=".CrashActivity" android:process=":CrashProcess" />
     </application>
 
     <instrumentation
diff --git a/hostsidetests/jdwptunnel/sampleapp/src/android/jdwptunnel/sampleapp/SampleDeviceActivity.java b/hostsidetests/tagging/none/src/android/cts/tagging/none/CrashActivity.java
similarity index 60%
copy from hostsidetests/jdwptunnel/sampleapp/src/android/jdwptunnel/sampleapp/SampleDeviceActivity.java
copy to hostsidetests/tagging/none/src/android/cts/tagging/none/CrashActivity.java
index ff3142d..2d0e405 100644
--- a/hostsidetests/jdwptunnel/sampleapp/src/android/jdwptunnel/sampleapp/SampleDeviceActivity.java
+++ b/hostsidetests/tagging/none/src/android/cts/tagging/none/CrashActivity.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2017 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,20 +14,16 @@
  * limitations under the License.
  */
 
-package android.jdwptunnel.sampleapp;
+package android.cts.tagging.none;
 
 import android.app.Activity;
+import android.cts.tagging.Utils;
 import android.os.Bundle;
 
-/**
- * A simple activity which does nothing.
- *
- * <p>This serves as a simple target application/activity to attach a debugger to.
- */
-public final class SampleDeviceActivity extends Activity {
+public class CrashActivity extends Activity {
     @Override
-    public void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-        setContentView(R.layout.sample_layout);
+    public void onCreate(Bundle bundle) {
+        super.onCreate(bundle);
+        Utils.accessMistaggedPointer();
     }
 }
diff --git a/hostsidetests/tagging/none/src/android/cts/tagging/none/TaggingTest.java b/hostsidetests/tagging/none/src/android/cts/tagging/none/TaggingTest.java
index 2b1f0f3..ffbc5eb 100644
--- a/hostsidetests/tagging/none/src/android/cts/tagging/none/TaggingTest.java
+++ b/hostsidetests/tagging/none/src/android/cts/tagging/none/TaggingTest.java
@@ -16,35 +16,75 @@
 
 package android.cts.tagging.none;
 
-import android.os.Build;
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-import org.junit.Test;
-import org.junit.runner.RunWith;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
 
+import android.content.Context;
+import android.content.Intent;
 import android.cts.tagging.Utils;
+import android.os.Build;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.compatibility.common.util.DropBoxReceiver;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.TimeUnit;
 
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class TaggingTest {
+    private static final String NATIVE_CRASH_TAG = "data_app_native_crash";
+
+    private Context mContext;
+
+    @Before
+    public void setUp() {
+        mContext = InstrumentationRegistry.getTargetContext();
+    }
 
     @Test
     public void testHeapTaggingEnabled() {
-      // Skip the test if not Arm64.
-      if (Build.CPU_ABI.startsWith("arm64")) {
-        int tag = Utils.nativeHeapPointerTag();
-        if (Utils.kernelSupportsTaggedPointers()) {
-          assertNotEquals(0, tag);
-        } else {
-          assertEquals(0, tag);
+        // Skip the test if not Arm64.
+        if (Build.CPU_ABI.startsWith("arm64")) {
+            int tag = Utils.nativeHeapPointerTag();
+            if (Utils.kernelSupportsTaggedPointers()) {
+                assertNotEquals(0, tag);
+            } else {
+                assertEquals(0, tag);
+            }
         }
-      }
     }
 
     @Test
     public void testHeapTaggingDisabled() {
-      assertEquals(0, Utils.nativeHeapPointerTag());
+        assertEquals(0, Utils.nativeHeapPointerTag());
+    }
+
+    @Test
+    public void testMemoryTagChecksEnabled() throws Exception {
+        final DropBoxReceiver receiver =
+                new DropBoxReceiver(
+                        mContext,
+                        NATIVE_CRASH_TAG,
+                        mContext.getPackageName() + ":CrashProcess",
+                        "backtrace:");
+        Intent intent = new Intent();
+        intent.setClass(mContext, CrashActivity.class);
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        mContext.startActivity(intent);
+
+        assertTrue(receiver.await());
+    }
+
+    @Test
+    public void testMemoryTagChecksDisabled() {
+        Utils.accessMistaggedPointer();
     }
 }
diff --git a/hostsidetests/tagging/src/com/android/cts/tagging/TaggingDefaultTest.java b/hostsidetests/tagging/src/com/android/cts/tagging/TaggingDefaultTest.java
index 266c60b..3c4ffc3 100644
--- a/hostsidetests/tagging/src/com/android/cts/tagging/TaggingDefaultTest.java
+++ b/hostsidetests/tagging/src/com/android/cts/tagging/TaggingDefaultTest.java
@@ -25,10 +25,15 @@
     protected static final String TEST_APK = "CtsHostsideTaggingNoneApp.apk";
     protected static final String TEST_PKG = "android.cts.tagging.none";
 
+    private static final long NATIVE_MEMORY_TAGGING_CHANGE_ID = 135772972;
+
+    private boolean supportsMemoryTagging;
+
     @Override
     protected void setUp() throws Exception {
         super.setUp();
         installPackage(TEST_APK, true);
+        supportsMemoryTagging = !runCommand("grep 'Features.* mte' /proc/cpuinfo").isEmpty();
     }
 
     @Override
@@ -36,7 +41,7 @@
         uninstallPackage(TEST_PKG, true);
     }
 
-    public void testCompatFeatureEnabled() throws Exception {
+    public void testHeapTaggingCompatFeatureEnabled() throws Exception {
         if (supportsTaggedPointers) {
             runDeviceCompatTest(TEST_PKG, ".TaggingTest", "testHeapTaggingEnabled",
                 /*enabledChanges*/ImmutableSet.of(NATIVE_HEAP_POINTER_TAGGING_CHANGE_ID),
@@ -54,12 +59,30 @@
         }
     }
 
-    public void testCompatFeatureDisabled() throws Exception {
-        if (!supportsTaggedPointers) {
+      public void testCompatFeatureDisabled() throws Exception {
+        if (!supportsTaggedPointers || supportsMemoryTagging) {
             return;
         }
         runDeviceCompatTest(TEST_PKG, ".TaggingTest", "testHeapTaggingDisabled",
                 /*enabledChanges*/ImmutableSet.of(),
                 /*disabledChanges*/ ImmutableSet.of(NATIVE_HEAP_POINTER_TAGGING_CHANGE_ID));
     }
+
+    public void testMemoryTagChecksCompatFeatureEnabled() throws Exception {
+        if (!supportsMemoryTagging) {
+            return;
+        }
+        runDeviceCompatTest(TEST_PKG, ".TaggingTest", "testMemoryTagChecksEnabled",
+                /*enabledChanges*/ ImmutableSet.of(NATIVE_MEMORY_TAGGING_CHANGE_ID),
+                /*disabledChanges*/ImmutableSet.of());
+    }
+
+    public void testMemoryTagChecksCompatFeatureDisabled() throws Exception {
+        if (!supportsMemoryTagging) {
+            return;
+        }
+        runDeviceCompatTest(TEST_PKG, ".TaggingTest", "testMemoryTagChecksDisabled",
+                /*enabledChanges*/ImmutableSet.of(),
+                /*disabledChanges*/ ImmutableSet.of(NATIVE_MEMORY_TAGGING_CHANGE_ID));
+    }
 }
diff --git a/hostsidetests/theme/assets/S/140dpi.zip b/hostsidetests/theme/assets/S/140dpi.zip
new file mode 100644
index 0000000..48de32b
--- /dev/null
+++ b/hostsidetests/theme/assets/S/140dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/S/180dpi.zip b/hostsidetests/theme/assets/S/180dpi.zip
new file mode 100644
index 0000000..4def986
--- /dev/null
+++ b/hostsidetests/theme/assets/S/180dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/S/200dpi.zip b/hostsidetests/theme/assets/S/200dpi.zip
new file mode 100644
index 0000000..fe2495e
--- /dev/null
+++ b/hostsidetests/theme/assets/S/200dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/S/220dpi.zip b/hostsidetests/theme/assets/S/220dpi.zip
new file mode 100644
index 0000000..a2c2ea2
--- /dev/null
+++ b/hostsidetests/theme/assets/S/220dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/S/260dpi.zip b/hostsidetests/theme/assets/S/260dpi.zip
new file mode 100644
index 0000000..74890a2
--- /dev/null
+++ b/hostsidetests/theme/assets/S/260dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/S/280dpi.zip b/hostsidetests/theme/assets/S/280dpi.zip
new file mode 100644
index 0000000..83fd290
--- /dev/null
+++ b/hostsidetests/theme/assets/S/280dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/S/300dpi.zip b/hostsidetests/theme/assets/S/300dpi.zip
new file mode 100644
index 0000000..25334d8
--- /dev/null
+++ b/hostsidetests/theme/assets/S/300dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/S/340dpi.zip b/hostsidetests/theme/assets/S/340dpi.zip
new file mode 100644
index 0000000..2092326
--- /dev/null
+++ b/hostsidetests/theme/assets/S/340dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/S/360dpi.zip b/hostsidetests/theme/assets/S/360dpi.zip
new file mode 100644
index 0000000..c13ad5c
--- /dev/null
+++ b/hostsidetests/theme/assets/S/360dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/S/400dpi.zip b/hostsidetests/theme/assets/S/400dpi.zip
new file mode 100644
index 0000000..1df1a95
--- /dev/null
+++ b/hostsidetests/theme/assets/S/400dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/S/420dpi.zip b/hostsidetests/theme/assets/S/420dpi.zip
new file mode 100644
index 0000000..d58d418
--- /dev/null
+++ b/hostsidetests/theme/assets/S/420dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/S/440dpi.zip b/hostsidetests/theme/assets/S/440dpi.zip
new file mode 100644
index 0000000..535102f
--- /dev/null
+++ b/hostsidetests/theme/assets/S/440dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/S/560dpi.zip b/hostsidetests/theme/assets/S/560dpi.zip
new file mode 100644
index 0000000..20f1c7b
--- /dev/null
+++ b/hostsidetests/theme/assets/S/560dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/S/hdpi.zip b/hostsidetests/theme/assets/S/hdpi.zip
new file mode 100644
index 0000000..582989d
--- /dev/null
+++ b/hostsidetests/theme/assets/S/hdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/S/ldpi.zip b/hostsidetests/theme/assets/S/ldpi.zip
new file mode 100644
index 0000000..3035146
--- /dev/null
+++ b/hostsidetests/theme/assets/S/ldpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/S/mdpi.zip b/hostsidetests/theme/assets/S/mdpi.zip
new file mode 100644
index 0000000..a831e7b
--- /dev/null
+++ b/hostsidetests/theme/assets/S/mdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/S/tvdpi.zip b/hostsidetests/theme/assets/S/tvdpi.zip
new file mode 100644
index 0000000..bd4bf75
--- /dev/null
+++ b/hostsidetests/theme/assets/S/tvdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/S/xhdpi.zip b/hostsidetests/theme/assets/S/xhdpi.zip
new file mode 100644
index 0000000..0dd72e2
--- /dev/null
+++ b/hostsidetests/theme/assets/S/xhdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/S/xxhdpi.zip b/hostsidetests/theme/assets/S/xxhdpi.zip
new file mode 100644
index 0000000..64fc846
--- /dev/null
+++ b/hostsidetests/theme/assets/S/xxhdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/S/xxxhdpi.zip b/hostsidetests/theme/assets/S/xxxhdpi.zip
new file mode 100644
index 0000000..87beb9a
--- /dev/null
+++ b/hostsidetests/theme/assets/S/xxxhdpi.zip
Binary files differ
diff --git a/hostsidetests/ui/Android.mk b/hostsidetests/ui/Android.mk
index 5450454..61bb6d3 100644
--- a/hostsidetests/ui/Android.mk
+++ b/hostsidetests/ui/Android.mk
@@ -24,13 +24,8 @@
 
 LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed compatibility-host-util
 
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
-
-$(COMPATIBILITY_TESTCASES_OUT_cts)/CtsUiHostTestCases.jar : $(COMPATIBILITY_TESTCASES_OUT_cts)/com.replica.replicaisland.apk
-
-LOCAL_CTS_TEST_PACKAGE := android.ui.cts
-
 # *Not* tagged as a cts test artifact intentionally: b/109660132
+#$(COMPATIBILITY_TESTCASES_OUT_cts)/CtsUiHostTestCases.jar : $(COMPATIBILITY_TESTCASES_OUT_cts)/com.replica.replicaisland.apk
 LOCAL_COMPATIBILITY_SUITE := general-tests
 
 include $(BUILD_CTS_HOST_JAVA_LIBRARY)
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 2d8d3a2..b6abf8d 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/PinnedStackTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/PinnedStackTests.java
@@ -971,6 +971,7 @@
 
     @Test
     public void testSetRequestedOrientationWhilePinned() throws Exception {
+        assumeTrue("Skipping test: no rotation support", supportsRotation());
         // Launch the PiP activity fixed as portrait, and enter picture-in-picture
         launchActivity(PIP_ACTIVITY,
                 EXTRA_PIP_ORIENTATION, String.valueOf(ORIENTATION_PORTRAIT),
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/SurfaceControlTest.java b/tests/framework/base/windowmanager/src/android/server/wm/SurfaceControlTest.java
index 00fc83b..e3566b9 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/SurfaceControlTest.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/SurfaceControlTest.java
@@ -178,18 +178,23 @@
      */
     @Test
     public void testReparentOff() throws Throwable {
+        final SurfaceControl sc = buildDefaultRedSurface(null);
         verifyTest(
                 new SurfaceControlTestCase.ParentSurfaceConsumer () {
                     @Override
                     public void addChildren(SurfaceControl parent) {
-                        final SurfaceControl sc = buildDefaultRedSurface(parent);
-
+                        new SurfaceControl.Transaction().reparent(sc, parent).apply();
                         new SurfaceControl.Transaction().reparent(sc, null).apply();
-
-                        sc.release();
                     }
                 },
                 new RectChecker(new Rect(0, 0, 100, 100), PixelColor.WHITE));
+      // Since the SurfaceControl is parented off-screen, if we release our reference
+      // it may completely die. If this occurs while the render thread is still rendering
+      // the RED background we could trigger a crash. For this test defer destroying the
+      // Surface until we have collected our test results.
+      if (sc != null) {
+        sc.release();
+      }
     }
 
     /**
diff --git a/tests/libcore/jsr166/Android.bp b/tests/libcore/jsr166/Android.bp
index d714ada..57fde13 100644
--- a/tests/libcore/jsr166/Android.bp
+++ b/tests/libcore/jsr166/Android.bp
@@ -19,6 +19,9 @@
     static_libs: [
         "cts-core-test-runner-axt",
         "jsr166-tests",
+
+        // Jar containing expectations files.
+        "libcore-expectations-knownfailures-jar",
     ],
     dex_preopt: {
         enabled: false,
@@ -32,5 +35,4 @@
         "vts10",
         "general-tests",
     ],
-    java_resources: [":libcore-expectations-knownfailures"],
 }
diff --git a/tests/libcore/luni/Android.bp b/tests/libcore/luni/Android.bp
index 6d6903d..902b1be 100644
--- a/tests/libcore/luni/Android.bp
+++ b/tests/libcore/luni/Android.bp
@@ -22,6 +22,11 @@
         "conscrypt-tests",
         "core-tests",
         "cts-core-test-runner-axt",
+
+        // Jars containing expectations files.
+        "libcore-expectations-knownfailures-jar",
+        "libcore-expectations-virtualdeviceknownfailures-jar",
+
         "mockito-target-minus-junit4",
         "time_zone_distro-tests",
         "time_zone_distro_installer-tests",
@@ -56,8 +61,4 @@
         "vts10",
         "general-tests",
     ],
-    java_resources: [
-        ":libcore-expectations-knownfailures",
-        ":libcore-expectations-virtualdeviceknownfailures",
-    ],
 }
diff --git a/tests/libcore/ojluni/Android.bp b/tests/libcore/ojluni/Android.bp
index 59e57e3..54bc421 100644
--- a/tests/libcore/ojluni/Android.bp
+++ b/tests/libcore/ojluni/Android.bp
@@ -16,7 +16,12 @@
     name: "CtsLibcoreOjTestCases",
     defaults: ["cts_support_defaults"],
     platform_apis: true,
-    static_libs: ["core-ojtests-public"],
+    static_libs: [
+        "core-ojtests-public",
+
+        // Jar containing expectations files.
+        "libcore-expectations-knownfailures-jar",
+    ],
     libs: ["testng"],
     dxflags: ["--core-library"],
     dex_preopt: {
@@ -33,7 +38,6 @@
         "cts",
         "vts10",
         "general-tests",
-	"mts",
+        "mts",
     ],
-    java_resources: [":libcore-expectations-knownfailures"],
 }
diff --git a/tests/libcore/ojluni/AndroidTest.xml b/tests/libcore/ojluni/AndroidTest.xml
index f4d043a..d69101e 100644
--- a/tests/libcore/ojluni/AndroidTest.xml
+++ b/tests/libcore/ojluni/AndroidTest.xml
@@ -41,8 +41,8 @@
                 value="com.android.cts.core.runner.ExpectationBasedFilter" />
         <option name="core-expectation" value="/knownfailures.txt" />
         <option name="runtime-hint" value="35m"/>
-        <!-- 20x default timeout of 600sec -->
-        <option name="shell-timeout" value="12000000"/>
+        <!-- shell-timeout is the amount of time we wait for an output before stopping the instrumentation -->
+        <option name="shell-timeout" value="45m"/>
         <option name="hidden-api-checks" value="false"/>
     </test>
 
diff --git a/tests/libcore/okhttp/Android.bp b/tests/libcore/okhttp/Android.bp
index b0f17d2..4d38e82 100644
--- a/tests/libcore/okhttp/Android.bp
+++ b/tests/libcore/okhttp/Android.bp
@@ -20,6 +20,10 @@
     static_libs: [
         "bouncycastle-unbundled",
         "cts-core-test-runner-axt",
+
+        // Jar containing expectations files.
+        "libcore-expectations-knownfailures-jar",
+
         "okhttp-nojarjar",
         "okhttp-tests-nojarjar",
     ],
@@ -39,5 +43,4 @@
         "mts",
         "vts10",
     ],
-    java_resources: [":libcore-expectations-knownfailures"],
 }
diff --git a/tests/libcore/wycheproof-bc/Android.bp b/tests/libcore/wycheproof-bc/Android.bp
index 6457120..a967745 100644
--- a/tests/libcore/wycheproof-bc/Android.bp
+++ b/tests/libcore/wycheproof-bc/Android.bp
@@ -18,6 +18,10 @@
     platform_apis: true,
     static_libs: [
         "cts-core-test-runner-axt",
+
+        // Jar containing expectations files.
+        "libcore-expectations-knownfailures-jar",
+
         "wycheproof",
     ],
     srcs: ["src/**/*.java"],
@@ -35,5 +39,4 @@
         "cts",
         "vts10",
     ],
-    java_resources: [":libcore-expectations-knownfailures"],
 }
diff --git a/tests/libcore/wycheproof/Android.bp b/tests/libcore/wycheproof/Android.bp
index e0abd73..bc7dbb1 100644
--- a/tests/libcore/wycheproof/Android.bp
+++ b/tests/libcore/wycheproof/Android.bp
@@ -18,6 +18,10 @@
     platform_apis: true,
     static_libs: [
         "cts-core-test-runner-axt",
+
+        // Jar containing expectations files.
+        "libcore-expectations-knownfailures-jar",
+
         "wycheproof",
     ],
     srcs: ["src/**/*.java"],
@@ -36,5 +40,4 @@
         "vts10",
         "general-tests",
     ],
-    java_resources: [":libcore-expectations-knownfailures"],
 }
diff --git a/tests/media/jni/NativeCodecTestBase.cpp b/tests/media/jni/NativeCodecTestBase.cpp
index 750abe6..b07c1c3 100644
--- a/tests/media/jni/NativeCodecTestBase.cpp
+++ b/tests/media/jni/NativeCodecTestBase.cpp
@@ -528,10 +528,11 @@
 
 int CodecTestBase::getWidth(AMediaFormat* format) {
     int width = -1;
-    int cropLeft, cropRight;
+    int cropLeft, cropRight, cropTop, cropBottom;
     AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_WIDTH, &width);
-    if (AMediaFormat_getInt32(format, "crop-left", &cropLeft) &&
-        AMediaFormat_getInt32(format, "crop-right", &cropRight)) {
+    if (AMediaFormat_getRect(format, "crop", &cropLeft, &cropTop, &cropRight, &cropBottom) ||
+        (AMediaFormat_getInt32(format, "crop-left", &cropLeft) &&
+        AMediaFormat_getInt32(format, "crop-right", &cropRight))) {
         width = cropRight + 1 - cropLeft;
     }
     return width;
@@ -539,10 +540,11 @@
 
 int CodecTestBase::getHeight(AMediaFormat* format) {
     int height = -1;
-    int cropTop, cropBottom;
+    int cropLeft, cropRight, cropTop, cropBottom;
     AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_HEIGHT, &height);
-    if (AMediaFormat_getInt32(format, "crop-top", &cropTop) &&
-        AMediaFormat_getInt32(format, "crop-bottom", &cropBottom)) {
+    if (AMediaFormat_getRect(format, "crop", &cropLeft, &cropTop, &cropRight, &cropBottom) ||
+        (AMediaFormat_getInt32(format, "crop-top", &cropTop) &&
+        AMediaFormat_getInt32(format, "crop-bottom", &cropBottom))) {
         height = cropBottom + 1 - cropTop;
     }
     return height;
diff --git a/tests/media/jni/NativeMediaCommon.cpp b/tests/media/jni/NativeMediaCommon.cpp
index 0debeac..23d9804 100644
--- a/tests/media/jni/NativeMediaCommon.cpp
+++ b/tests/media/jni/NativeMediaCommon.cpp
@@ -48,11 +48,6 @@
 bool isCSDIdentical(AMediaFormat* refFormat, AMediaFormat* testFormat) {
     const char* mime;
     AMediaFormat_getString(refFormat, AMEDIAFORMAT_KEY_MIME, &mime);
-    /* TODO(b/154177490) */
-    if ((strcmp(mime, AMEDIA_MIMETYPE_VIDEO_VP9) == 0) ||
-        (strcmp(mime, AMEDIA_MIMETYPE_VIDEO_AV1) == 0)) {
-        return true;
-    }
     for (int i = 0;; i++) {
         std::pair<void*, size_t> refCsd;
         std::pair<void*, size_t> testCsd;
diff --git a/tests/openglperf2/jni/Android.bp b/tests/openglperf2/jni/Android.bp
index ad48757..e6a3a9a 100644
--- a/tests/openglperf2/jni/Android.bp
+++ b/tests/openglperf2/jni/Android.bp
@@ -29,6 +29,8 @@
     // Get all cpp files but not hidden files
     srcs: ["**/*.cpp"],
 
+    header_libs: ["jni_headers"],
+
     shared_libs: [
         "libEGL",
         "libGLESv2",
diff --git a/tests/sensor/src/android/hardware/cts/SensorAdditionalInfoTest.java b/tests/sensor/src/android/hardware/cts/SensorAdditionalInfoTest.java
index df86fa6..00defeb 100644
--- a/tests/sensor/src/android/hardware/cts/SensorAdditionalInfoTest.java
+++ b/tests/sensor/src/android/hardware/cts/SensorAdditionalInfoTest.java
@@ -266,7 +266,7 @@
 
         // Checks sensor placement data length and determinant of rotation matrix is 1.
         private void verifySensorPlacementData(float[] m) {
-            if(m.length != 12) {
+            if(m.length < 12) {
                 mIsSensorPlacementSizeValid = false;
                 return;
             }
diff --git a/tests/signature/api-check/OWNERS b/tests/signature/api-check/OWNERS
index 9cedf986..c8305d1 100644
--- a/tests/signature/api-check/OWNERS
+++ b/tests/signature/api-check/OWNERS
@@ -1,8 +1,7 @@
 # Bug component: 24949
 platform-compat-eng+reviews@google.com
 andreionea@google.com
-atrost@google.com
 mathewi@google.com
 ngeoffray@google.com
 paulduffin@google.com
-satayev@google.com
\ No newline at end of file
+satayev@google.com
diff --git a/tests/signature/api-check/hidden-api-blacklist-test-api/OWNERS b/tests/signature/api-check/hidden-api-blacklist-test-api/OWNERS
index f9ba708..66ea541 100644
--- a/tests/signature/api-check/hidden-api-blacklist-test-api/OWNERS
+++ b/tests/signature/api-check/hidden-api-blacklist-test-api/OWNERS
@@ -4,7 +4,6 @@
 platform-compat-eng+reviews@google.com
 
 andreionea@google.com
-atrost@google.com
 mathewi@google.com
 ngeoffray@google.com
 satayev@google.com
diff --git a/tests/signature/dex-checker/Android.bp b/tests/signature/dex-checker/Android.bp
index 44c8571..1e4f649 100644
--- a/tests/signature/dex-checker/Android.bp
+++ b/tests/signature/dex-checker/Android.bp
@@ -20,6 +20,7 @@
         "-Wall",
         "-Werror",
     ],
+    header_libs: ["jni_headers"],
     sdk_version: "current",
     stl: "c++_static",
 }
diff --git a/tests/simplecpu/jni/Android.bp b/tests/simplecpu/jni/Android.bp
index 2ed06c0..000173d 100644
--- a/tests/simplecpu/jni/Android.bp
+++ b/tests/simplecpu/jni/Android.bp
@@ -22,5 +22,6 @@
         "-Werror",
         "-Wno-unused-parameter",
     ],
+    header_libs: ["jni_headers"],
     gtest: false,
 }
diff --git a/tests/tests/appop/Android.bp b/tests/tests/appop/Android.bp
index 20ab4bf..930462b 100644
--- a/tests/tests/appop/Android.bp
+++ b/tests/tests/appop/Android.bp
@@ -25,6 +25,7 @@
 
     srcs: ["jni/**/*.cpp"],
 
+    header_libs: ["jni_headers"],
     shared_libs: [
         "libbinder",
         "libutils",
diff --git a/tests/tests/appop/jni/android/app/appops/cts/AppOpsLoggingTest.cpp b/tests/tests/appop/jni/android/app/appops/cts/AppOpsLoggingTest.cpp
index a403163..b5af257 100644
--- a/tests/tests/appop/jni/android/app/appops/cts/AppOpsLoggingTest.cpp
+++ b/tests/tests/appop/jni/android/app/appops/cts/AppOpsLoggingTest.cpp
@@ -36,22 +36,20 @@
     String16 callingPackageName(nativeCallingPackageName);
 
     const char *nativeAttributionTag;
-    std::unique_ptr<String16> attributionTag;
+    std::optional<String16> attributionTag;
     if (jAttributionTag != nullptr) {
         nativeAttributionTag = env->GetStringUTFChars(jAttributionTag, 0);
-        attributionTag = std::unique_ptr<String16>(new String16(nativeAttributionTag));
+        attributionTag = String16(nativeAttributionTag);
     }
 
     const char *nativeMessage;
-    String16 *message;
+    String16 message;
     if (jMessage != nullptr) {
         nativeMessage = env->GetStringUTFChars(jMessage, 0);
-        message = new String16(nativeMessage);
-    } else {
-        message = new String16();
+        message = String16(nativeMessage);
     }
 
-    appOpsManager.noteOp(op, uid, callingPackageName, attributionTag, *message);
+    appOpsManager.noteOp(op, uid, callingPackageName, attributionTag, message);
 
     env->ReleaseStringUTFChars(jCallingPackageName, nativeCallingPackageName);
 
@@ -62,5 +60,4 @@
     if (jMessage != nullptr) {
         env->ReleaseStringUTFChars(jMessage, nativeMessage);
     }
-    delete message;
 }
diff --git a/tests/tests/binder_ndk/libbinder_ndk_test/Android.bp b/tests/tests/binder_ndk/libbinder_ndk_test/Android.bp
index 036853e..e4ec9b4 100644
--- a/tests/tests/binder_ndk/libbinder_ndk_test/Android.bp
+++ b/tests/tests/binder_ndk/libbinder_ndk_test/Android.bp
@@ -12,8 +12,8 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-aidl_interface {
-    name: "libbinder_ndk_test_interface",
+filegroup {
+    name: "libbinder_ndk_test_interface_srcs",
     srcs: [
         "test_package/Bar.aidl",
         "test_package/ByteEnum.aidl",
@@ -24,6 +24,12 @@
         "test_package/LongEnum.aidl",
         "test_package/RegularPolygon.aidl",
     ],
+    visibility: ["//visibility:private"]
+}
+
+aidl_interface {
+    name: "libbinder_ndk_test_interface",
+    srcs: [":libbinder_ndk_test_interface_srcs"],
     versions: [
         "1",
         "2",
@@ -38,6 +44,29 @@
     },
 }
 
+aidl_interface {
+    name: "libbinder_ndk_test_interface_dup",
+    srcs: [":libbinder_ndk_test_interface_srcs"],
+    versions: [
+        "1",
+    ],
+    backend: {
+        java: {
+            enabled: false,
+        },
+        cpp: {
+            enabled: false,
+        },
+        ndk: {
+            enabled: true,
+        },
+    },
+    visibility: [
+        ":__subpackages__",
+        "//system/tools/aidl/build:__pkg__",
+    ]
+}
+
 cc_defaults {
     name: "libbinder_ndk_test_defaults",
     cflags: [
@@ -82,7 +111,8 @@
     cflags: ["-DUSING_VERSION_1"],
     // Using the frozen version 1 of the interface
     static_libs: [
-        "libbinder_ndk_test_interface-V1-ndk",
+        // this refers to the latest stable version which is 1
+        "libbinder_ndk_test_interface_dup-ndk",
     ],
     shared_libs: [
         "libbinder_ndk_test_utilities",
diff --git a/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/.hash b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/.hash
new file mode 100644
index 0000000..44d6213
--- /dev/null
+++ b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/.hash
@@ -0,0 +1 @@
+8e163a1b4a6f366aa0c00b6da7fc13a970ee55d8
diff --git a/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/test_package/Bar.aidl b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/test_package/Bar.aidl
new file mode 100644
index 0000000..6a5d253
--- /dev/null
+++ b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/test_package/Bar.aidl
@@ -0,0 +1,7 @@
+package test_package;
+parcelable Bar {
+  String a = "BAR";
+  String b = "BAR2";
+  float c = 4.200000f;
+  int d = 100;
+}
diff --git a/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/test_package/ByteEnum.aidl b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/test_package/ByteEnum.aidl
new file mode 100644
index 0000000..6884107
--- /dev/null
+++ b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/test_package/ByteEnum.aidl
@@ -0,0 +1,23 @@
+/*
+ * 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 test_package;
+
+@Backing(type="byte")
+enum ByteEnum {
+    FOO = 1,
+    BAR = 2,
+}
diff --git a/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/test_package/Foo.aidl b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/test_package/Foo.aidl
new file mode 100644
index 0000000..86af9b6
--- /dev/null
+++ b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/test_package/Foo.aidl
@@ -0,0 +1,15 @@
+package test_package;
+parcelable Foo {
+  String a = "FOO";
+  int b = 42;
+  float c = 3.140000f;
+  test_package.Bar d;
+  test_package.Bar e;
+  int f = 3;
+  test_package.ByteEnum shouldBeByteBar;
+  test_package.IntEnum shouldBeIntBar;
+  test_package.LongEnum shouldBeLongBar;
+  test_package.ByteEnum[] shouldContainTwoByteFoos;
+  test_package.IntEnum[] shouldContainTwoIntFoos;
+  test_package.LongEnum[] shouldContainTwoLongFoos;
+}
diff --git a/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/test_package/IEmpty.aidl b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/test_package/IEmpty.aidl
new file mode 100644
index 0000000..2baa52c
--- /dev/null
+++ b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/test_package/IEmpty.aidl
@@ -0,0 +1,3 @@
+package test_package;
+interface IEmpty {
+}
diff --git a/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/test_package/ITest.aidl b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/test_package/ITest.aidl
new file mode 100644
index 0000000..75e7a41
--- /dev/null
+++ b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/test_package/ITest.aidl
@@ -0,0 +1,69 @@
+package test_package;
+interface ITest {
+  String GetName();
+  void TestVoidReturn();
+  oneway void TestOneway();
+  int GiveMeMyCallingPid();
+  int GiveMeMyCallingUid();
+  oneway void CacheCallingInfoFromOneway();
+  int GiveMeMyCallingPidFromOneway();
+  int GiveMeMyCallingUidFromOneway();
+  int RepeatInt(int value);
+  long RepeatLong(long value);
+  float RepeatFloat(float value);
+  double RepeatDouble(double value);
+  boolean RepeatBoolean(boolean value);
+  char RepeatChar(char value);
+  byte RepeatByte(byte value);
+  test_package.ByteEnum RepeatByteEnum(test_package.ByteEnum value);
+  test_package.IntEnum RepeatIntEnum(test_package.IntEnum value);
+  test_package.LongEnum RepeatLongEnum(test_package.LongEnum value);
+  IBinder RepeatBinder(IBinder value);
+  @nullable IBinder RepeatNullableBinder(@nullable IBinder value);
+  test_package.IEmpty RepeatInterface(test_package.IEmpty value);
+  @nullable test_package.IEmpty RepeatNullableInterface(@nullable test_package.IEmpty value);
+  ParcelFileDescriptor RepeatFd(in ParcelFileDescriptor fd);
+  @nullable ParcelFileDescriptor RepeatNullableFd(in @nullable ParcelFileDescriptor fd);
+  String RepeatString(String value);
+  @nullable String RepeatNullableString(@nullable String value);
+  test_package.RegularPolygon RepeatPolygon(in test_package.RegularPolygon value);
+  @nullable test_package.RegularPolygon RepeatNullablePolygon(in @nullable test_package.RegularPolygon value);
+  void RenamePolygon(inout test_package.RegularPolygon value, String newName);
+  boolean[] RepeatBooleanArray(in boolean[] input, out boolean[] repeated);
+  byte[] RepeatByteArray(in byte[] input, out byte[] repeated);
+  char[] RepeatCharArray(in char[] input, out char[] repeated);
+  int[] RepeatIntArray(in int[] input, out int[] repeated);
+  long[] RepeatLongArray(in long[] input, out long[] repeated);
+  float[] RepeatFloatArray(in float[] input, out float[] repeated);
+  double[] RepeatDoubleArray(in double[] input, out double[] repeated);
+  test_package.ByteEnum[] RepeatByteEnumArray(in test_package.ByteEnum[] input, out test_package.ByteEnum[] repeated);
+  test_package.IntEnum[] RepeatIntEnumArray(in test_package.IntEnum[] input, out test_package.IntEnum[] repeated);
+  test_package.LongEnum[] RepeatLongEnumArray(in test_package.LongEnum[] input, out test_package.LongEnum[] repeated);
+  String[] RepeatStringArray(in String[] input, out String[] repeated);
+  test_package.RegularPolygon[] RepeatRegularPolygonArray(in test_package.RegularPolygon[] input, out test_package.RegularPolygon[] repeated);
+  ParcelFileDescriptor[] RepeatFdArray(in ParcelFileDescriptor[] input, out ParcelFileDescriptor[] repeated);
+  List<String> Repeat2StringList(in List<String> input, out List<String> repeated);
+  List<test_package.RegularPolygon> Repeat2RegularPolygonList(in List<test_package.RegularPolygon> input, out List<test_package.RegularPolygon> repeated);
+  @nullable boolean[] RepeatNullableBooleanArray(in @nullable boolean[] input);
+  @nullable byte[] RepeatNullableByteArray(in @nullable byte[] input);
+  @nullable char[] RepeatNullableCharArray(in @nullable char[] input);
+  @nullable int[] RepeatNullableIntArray(in @nullable int[] input);
+  @nullable long[] RepeatNullableLongArray(in @nullable long[] input);
+  @nullable float[] RepeatNullableFloatArray(in @nullable float[] input);
+  @nullable double[] RepeatNullableDoubleArray(in @nullable double[] input);
+  @nullable test_package.ByteEnum[] RepeatNullableByteEnumArray(in @nullable test_package.ByteEnum[] input);
+  @nullable test_package.IntEnum[] RepeatNullableIntEnumArray(in @nullable test_package.IntEnum[] input);
+  @nullable test_package.LongEnum[] RepeatNullableLongEnumArray(in @nullable test_package.LongEnum[] input);
+  @nullable String[] RepeatNullableStringArray(in @nullable String[] input);
+  @nullable String[] DoubleRepeatNullableStringArray(in @nullable String[] input, out @nullable String[] repeated);
+  test_package.Foo repeatFoo(in test_package.Foo inFoo);
+  void renameFoo(inout test_package.Foo foo, String name);
+  void renameBar(inout test_package.Foo foo, String name);
+  int getF(in test_package.Foo foo);
+  String RepeatStringNullableLater(String repeated);
+  const int kZero = 0;
+  const int kOne = 1;
+  const int kOnes = -1;
+  const String kEmpty = "";
+  const String kFoo = "foo";
+}
diff --git a/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/test_package/IntEnum.aidl b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/test_package/IntEnum.aidl
new file mode 100644
index 0000000..15b9891
--- /dev/null
+++ b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/test_package/IntEnum.aidl
@@ -0,0 +1,23 @@
+/*
+ * 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 test_package;
+
+@Backing(type="int")
+enum IntEnum {
+    FOO = 1000,
+    BAR = 2000,
+}
diff --git a/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/test_package/LongEnum.aidl b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/test_package/LongEnum.aidl
new file mode 100644
index 0000000..f21ea63
--- /dev/null
+++ b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/test_package/LongEnum.aidl
@@ -0,0 +1,23 @@
+/*
+ * 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 test_package;
+
+@Backing(type="long")
+enum LongEnum {
+    FOO = 100000000000,
+    BAR = 200000000000,
+}
diff --git a/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/test_package/RegularPolygon.aidl b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/test_package/RegularPolygon.aidl
new file mode 100644
index 0000000..14c6c2e
--- /dev/null
+++ b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/test_package/RegularPolygon.aidl
@@ -0,0 +1,6 @@
+package test_package;
+parcelable RegularPolygon {
+  String name = "square";
+  int numSides = 4;
+  float sideLength = 1.000000f;
+}
diff --git a/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/current/test_package/Bar.aidl b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/current/test_package/Bar.aidl
new file mode 100644
index 0000000..99ba6b5
--- /dev/null
+++ b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/current/test_package/Bar.aidl
@@ -0,0 +1,25 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package test_package;
+parcelable Bar {
+  String a = "BAR";
+  String b = "BAR2";
+  float c = 4.200000f;
+  int d = 100;
+  String e = "HELLO";
+}
diff --git a/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/current/test_package/ByteEnum.aidl b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/current/test_package/ByteEnum.aidl
new file mode 100644
index 0000000..16c6e1b
--- /dev/null
+++ b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/current/test_package/ByteEnum.aidl
@@ -0,0 +1,23 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package test_package;
+@Backing(type="byte")
+enum ByteEnum {
+  FOO = 1,
+  BAR = 2,
+}
diff --git a/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/current/test_package/Foo.aidl b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/current/test_package/Foo.aidl
new file mode 100644
index 0000000..8b71fee
--- /dev/null
+++ b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/current/test_package/Foo.aidl
@@ -0,0 +1,33 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package test_package;
+parcelable Foo {
+  String a = "FOO";
+  int b = 42;
+  float c = 3.140000f;
+  test_package.Bar d;
+  test_package.Bar e;
+  int f = 3;
+  test_package.ByteEnum shouldBeByteBar;
+  test_package.IntEnum shouldBeIntBar;
+  test_package.LongEnum shouldBeLongBar;
+  test_package.ByteEnum[] shouldContainTwoByteFoos;
+  test_package.IntEnum[] shouldContainTwoIntFoos;
+  test_package.LongEnum[] shouldContainTwoLongFoos;
+  @nullable String[] g;
+}
diff --git a/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/current/test_package/IEmpty.aidl b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/current/test_package/IEmpty.aidl
new file mode 100644
index 0000000..5a27b19
--- /dev/null
+++ b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/current/test_package/IEmpty.aidl
@@ -0,0 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package test_package;
+interface IEmpty {
+}
diff --git a/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/current/test_package/ITest.aidl b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/current/test_package/ITest.aidl
new file mode 100644
index 0000000..effb098
--- /dev/null
+++ b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/current/test_package/ITest.aidl
@@ -0,0 +1,87 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package test_package;
+interface ITest {
+  String GetName();
+  void TestVoidReturn();
+  oneway void TestOneway();
+  int GiveMeMyCallingPid();
+  int GiveMeMyCallingUid();
+  oneway void CacheCallingInfoFromOneway();
+  int GiveMeMyCallingPidFromOneway();
+  int GiveMeMyCallingUidFromOneway();
+  int RepeatInt(int value);
+  long RepeatLong(long value);
+  float RepeatFloat(float value);
+  double RepeatDouble(double value);
+  boolean RepeatBoolean(boolean value);
+  char RepeatChar(char value);
+  byte RepeatByte(byte value);
+  test_package.ByteEnum RepeatByteEnum(test_package.ByteEnum value);
+  test_package.IntEnum RepeatIntEnum(test_package.IntEnum value);
+  test_package.LongEnum RepeatLongEnum(test_package.LongEnum value);
+  IBinder RepeatBinder(IBinder value);
+  @nullable IBinder RepeatNullableBinder(@nullable IBinder value);
+  test_package.IEmpty RepeatInterface(test_package.IEmpty value);
+  @nullable test_package.IEmpty RepeatNullableInterface(@nullable test_package.IEmpty value);
+  ParcelFileDescriptor RepeatFd(in ParcelFileDescriptor fd);
+  @nullable ParcelFileDescriptor RepeatNullableFd(in @nullable ParcelFileDescriptor fd);
+  String RepeatString(String value);
+  @nullable String RepeatNullableString(@nullable String value);
+  test_package.RegularPolygon RepeatPolygon(in test_package.RegularPolygon value);
+  @nullable test_package.RegularPolygon RepeatNullablePolygon(in @nullable test_package.RegularPolygon value);
+  void RenamePolygon(inout test_package.RegularPolygon value, String newName);
+  boolean[] RepeatBooleanArray(in boolean[] input, out boolean[] repeated);
+  byte[] RepeatByteArray(in byte[] input, out byte[] repeated);
+  char[] RepeatCharArray(in char[] input, out char[] repeated);
+  int[] RepeatIntArray(in int[] input, out int[] repeated);
+  long[] RepeatLongArray(in long[] input, out long[] repeated);
+  float[] RepeatFloatArray(in float[] input, out float[] repeated);
+  double[] RepeatDoubleArray(in double[] input, out double[] repeated);
+  test_package.ByteEnum[] RepeatByteEnumArray(in test_package.ByteEnum[] input, out test_package.ByteEnum[] repeated);
+  test_package.IntEnum[] RepeatIntEnumArray(in test_package.IntEnum[] input, out test_package.IntEnum[] repeated);
+  test_package.LongEnum[] RepeatLongEnumArray(in test_package.LongEnum[] input, out test_package.LongEnum[] repeated);
+  String[] RepeatStringArray(in String[] input, out String[] repeated);
+  test_package.RegularPolygon[] RepeatRegularPolygonArray(in test_package.RegularPolygon[] input, out test_package.RegularPolygon[] repeated);
+  ParcelFileDescriptor[] RepeatFdArray(in ParcelFileDescriptor[] input, out ParcelFileDescriptor[] repeated);
+  List<String> Repeat2StringList(in List<String> input, out List<String> repeated);
+  List<test_package.RegularPolygon> Repeat2RegularPolygonList(in List<test_package.RegularPolygon> input, out List<test_package.RegularPolygon> repeated);
+  @nullable boolean[] RepeatNullableBooleanArray(in @nullable boolean[] input);
+  @nullable byte[] RepeatNullableByteArray(in @nullable byte[] input);
+  @nullable char[] RepeatNullableCharArray(in @nullable char[] input);
+  @nullable int[] RepeatNullableIntArray(in @nullable int[] input);
+  @nullable long[] RepeatNullableLongArray(in @nullable long[] input);
+  @nullable float[] RepeatNullableFloatArray(in @nullable float[] input);
+  @nullable double[] RepeatNullableDoubleArray(in @nullable double[] input);
+  @nullable test_package.ByteEnum[] RepeatNullableByteEnumArray(in @nullable test_package.ByteEnum[] input);
+  @nullable test_package.IntEnum[] RepeatNullableIntEnumArray(in @nullable test_package.IntEnum[] input);
+  @nullable test_package.LongEnum[] RepeatNullableLongEnumArray(in @nullable test_package.LongEnum[] input);
+  @nullable String[] RepeatNullableStringArray(in @nullable String[] input);
+  @nullable String[] DoubleRepeatNullableStringArray(in @nullable String[] input, out @nullable String[] repeated);
+  test_package.Foo repeatFoo(in test_package.Foo inFoo);
+  void renameFoo(inout test_package.Foo foo, String name);
+  void renameBar(inout test_package.Foo foo, String name);
+  int getF(in test_package.Foo foo);
+  @nullable String RepeatStringNullableLater(@nullable String repeated);
+  int NewMethodThatReturns10();
+  const int kZero = 0;
+  const int kOne = 1;
+  const int kOnes = -1;
+  const String kEmpty = "";
+  const String kFoo = "foo";
+}
diff --git a/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/current/test_package/IntEnum.aidl b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/current/test_package/IntEnum.aidl
new file mode 100644
index 0000000..f889ec4
--- /dev/null
+++ b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/current/test_package/IntEnum.aidl
@@ -0,0 +1,23 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package test_package;
+@Backing(type="int")
+enum IntEnum {
+  FOO = 1000,
+  BAR = 2000,
+}
diff --git a/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/current/test_package/LongEnum.aidl b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/current/test_package/LongEnum.aidl
new file mode 100644
index 0000000..b03c85c
--- /dev/null
+++ b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/current/test_package/LongEnum.aidl
@@ -0,0 +1,23 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package test_package;
+@Backing(type="long")
+enum LongEnum {
+  FOO = 100000000000,
+  BAR = 200000000000,
+}
diff --git a/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/current/test_package/RegularPolygon.aidl b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/current/test_package/RegularPolygon.aidl
new file mode 100644
index 0000000..8fdd8c84b
--- /dev/null
+++ b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/current/test_package/RegularPolygon.aidl
@@ -0,0 +1,23 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package test_package;
+parcelable RegularPolygon {
+  String name = "square";
+  int numSides = 4;
+  float sideLength = 1.000000f;
+}
diff --git a/tests/tests/binder_ndk/libbinder_ndk_test/itest_impl.h b/tests/tests/binder_ndk/libbinder_ndk_test/itest_impl.h
index 67d7930..89ea368 100644
--- a/tests/tests/binder_ndk/libbinder_ndk_test/itest_impl.h
+++ b/tests/tests/binder_ndk/libbinder_ndk_test/itest_impl.h
@@ -224,9 +224,9 @@
     *_aidl_return = in_value;
     return ::ndk::ScopedAStatus(AStatus_newOk());
   }
-  ::ndk::ScopedAStatus RepeatByteArray(
-      const std::vector<int8_t>& in_value, std::vector<int8_t>* out_repeated,
-      std::vector<int8_t>* _aidl_return) override {
+  ::ndk::ScopedAStatus RepeatByteArray(const std::vector<uint8_t>& in_value,
+                                       std::vector<uint8_t>* out_repeated,
+                                       std::vector<uint8_t>* _aidl_return) override {
     *out_repeated = in_value;
     *_aidl_return = in_value;
     return ::ndk::ScopedAStatus(AStatus_newOk());
@@ -341,8 +341,8 @@
     return ::ndk::ScopedAStatus(AStatus_newOk());
   }
   ::ndk::ScopedAStatus RepeatNullableByteArray(
-      const std::optional<std::vector<int8_t>>& in_value,
-      std::optional<std::vector<int8_t>>* _aidl_return) override {
+      const std::optional<std::vector<uint8_t>>& in_value,
+      std::optional<std::vector<uint8_t>>* _aidl_return) override {
     *_aidl_return = in_value;
     return ::ndk::ScopedAStatus(AStatus_newOk());
   }
diff --git a/tests/tests/binder_ndk/libbinder_ndk_test/test_native_aidl_client.cpp b/tests/tests/binder_ndk/libbinder_ndk_test/test_native_aidl_client.cpp
index f859df1..158f1de 100644
--- a/tests/tests/binder_ndk/libbinder_ndk_test/test_native_aidl_client.cpp
+++ b/tests/tests/binder_ndk/libbinder_ndk_test/test_native_aidl_client.cpp
@@ -550,12 +550,12 @@
                        {true},
                        {false, true, false},
                    });
-  testRepeat<int8_t>(iface, &ITest::RepeatByteArray,
-                     {
-                         {},
-                         {1},
-                         {1, 2, 3},
-                     });
+  testRepeat<uint8_t>(iface, &ITest::RepeatByteArray,
+                      {
+                          {},
+                          {1},
+                          {1, 2, 3},
+                      });
   testRepeat<char16_t>(iface, &ITest::RepeatCharArray,
                        {
                            {},
@@ -683,13 +683,13 @@
                        {{true}},
                        {{false, true, false}},
                    });
-  testRepeat<int8_t>(iface, &ITest::RepeatNullableByteArray,
-                     {
-                         std::nullopt,
-                         {{}},
-                         {{1}},
-                         {{1, 2, 3}},
-                     });
+  testRepeat<uint8_t>(iface, &ITest::RepeatNullableByteArray,
+                      {
+                          std::nullopt,
+                          {{}},
+                          {{1}},
+                          {{1, 2, 3}},
+                      });
   testRepeat<char16_t>(iface, &ITest::RepeatNullableCharArray,
                        {
                            std::nullopt,
diff --git a/tests/tests/content/src/android/content/cts/ContentProviderClientTest.java b/tests/tests/content/src/android/content/cts/ContentProviderClientTest.java
index 9119ea1..07223e6 100644
--- a/tests/tests/content/src/android/content/cts/ContentProviderClientTest.java
+++ b/tests/tests/content/src/android/content/cts/ContentProviderClientTest.java
@@ -38,7 +38,6 @@
 import android.os.RemoteException;
 import android.test.AndroidTestCase;
 import android.test.mock.MockContentResolver;
-import android.test.mock.MockIContentProvider;
 
 import org.mockito.stubbing.Answer;
 
@@ -84,7 +83,9 @@
     public void setUp() throws Exception {
         super.setUp();
 
-        mIContentProvider = mock(MockIContentProvider.class);
+        mIContentProvider = mock(IContentProvider.class, invocation -> {
+            throw new UnsupportedOperationException("unimplemented mock method");
+        });
         mICancellationSignal = mock(ICancellationSignal.class);
 
         when(mIContentProvider.createCancellationSignal()).thenReturn(mICancellationSignal);
diff --git a/tests/tests/cronet/Android.bp b/tests/tests/cronet/Android.bp
new file mode 100644
index 0000000..620e404
--- /dev/null
+++ b/tests/tests/cronet/Android.bp
@@ -0,0 +1,37 @@
+// 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.
+
+
+// TODO: Move this target to cts/tests/tests/net/cronet
+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
+    test_suites: [
+        "cts",
+        "vts10",
+        "general-tests",
+        "mts",
+    ],
+
+}
diff --git a/tests/tests/cronet/AndroidManifest.xml b/tests/tests/cronet/AndroidManifest.xml
new file mode 100644
index 0000000..b7ae844
--- /dev/null
+++ b/tests/tests/cronet/AndroidManifest.xml
@@ -0,0 +1,36 @@
+<?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
new file mode 100644
index 0000000..79c37f7
--- /dev/null
+++ b/tests/tests/cronet/AndroidTest.xml
@@ -0,0 +1,30 @@
+<?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
new file mode 100644
index 0000000..f4525df
--- /dev/null
+++ b/tests/tests/cronet/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 31808
+include ../net/OWNERS
\ No newline at end of file
diff --git a/tests/tests/display/src/android/display/cts/DisplayTest.java b/tests/tests/display/src/android/display/cts/DisplayTest.java
index aeb5ce0..33a908e 100644
--- a/tests/tests/display/src/android/display/cts/DisplayTest.java
+++ b/tests/tests/display/src/android/display/cts/DisplayTest.java
@@ -472,6 +472,16 @@
             params.setTitle("CtsTestPresentation");
             getWindow().setAttributes(params);
         }
+
+        @Override
+        public void cancel() {
+            // Ignore attempts to force cancel the presentation. This is going to happen when we
+            // change the mode of the display since doing so will change the display metrics, which
+            // Presentations don't yet support. Ignoring it means the Presentation will stay up and
+            // the mode will stay changed until dismiss is called, preventing a race condition
+            // between the test checking the mode of the display and the mode changing back to the
+            // default because the requesting Presentation is no longer showing.
+        }
     }
 
     private Activity launchScreenOnActivity() {
diff --git a/tests/tests/drm/jni/Android.bp b/tests/tests/drm/jni/Android.bp
index ce14d1e..aa6a94b 100644
--- a/tests/tests/drm/jni/Android.bp
+++ b/tests/tests/drm/jni/Android.bp
@@ -19,6 +19,7 @@
         "android_drm_cts_NativeCodeTest.cpp",
     ],
     gtest: false,
+    header_libs: ["jni_headers"],
     shared_libs: [
         "liblog",
         "libdl",
diff --git a/tests/tests/dynamic_linker/Android.bp b/tests/tests/dynamic_linker/Android.bp
index b9da8a2..8fda181 100644
--- a/tests/tests/dynamic_linker/Android.bp
+++ b/tests/tests/dynamic_linker/Android.bp
@@ -20,6 +20,7 @@
         "-Wall",
         "-Werror",
     ],
+    header_libs: ["jni_headers"],
     strip: {
         none: true,
     },
@@ -34,6 +35,7 @@
         "-Wall",
         "-Werror",
     ],
+    header_libs: ["jni_headers"],
     strip: {
         none: true,
     },
diff --git a/tests/tests/jni/Android.bp b/tests/tests/jni/Android.bp
index 386b2ae..ae5778b 100644
--- a/tests/tests/jni/Android.bp
+++ b/tests/tests/jni/Android.bp
@@ -49,6 +49,7 @@
         "-Wall",
         "-Werror",
     ],
+    header_libs: ["jni_headers"],
     local_include_dirs: ["libjnicommon"],
     host_ldlibs: ["-llog"],
     shared_libs: [
@@ -66,6 +67,7 @@
         "-Wall",
         "-Werror",
     ],
+    header_libs: ["jni_headers"],
     local_include_dirs: ["libjnicommon"],
     host_ldlibs: ["-llog"],
     shared_libs: [
@@ -83,6 +85,7 @@
         "-Wall",
         "-Werror",
     ],
+    header_libs: ["jni_headers"],
     local_include_dirs: ["libjnicommon"],
     host_ldlibs: ["-llog"],
     shared_libs: [
diff --git a/tests/tests/jni/libjnitest/android_jni_cts_LinkerNamespacesTest.cpp b/tests/tests/jni/libjnitest/android_jni_cts_LinkerNamespacesTest.cpp
index 208b43b..daef758 100644
--- a/tests/tests/jni/libjnitest/android_jni_cts_LinkerNamespacesTest.cpp
+++ b/tests/tests/jni/libjnitest/android_jni_cts_LinkerNamespacesTest.cpp
@@ -406,8 +406,6 @@
   // Check the runtime libraries.
   if (!check_path(env, clazz, kArtApexLibraryPath, {kArtApexLibraryPath},
                   runtime_public_libraries,
-                  // System.loadLibrary("icuuc") would fail since a copy exists in /system.
-                  // TODO(b/124218500): Change to true when the bug is resolved.
                   /*test_system_load_library=*/true,
                   check_absence, &errors)) {
     success = false;
diff --git a/tests/tests/jni/src/android/jni/cts/LinkerNamespacesHelper.java b/tests/tests/jni/src/android/jni/cts/LinkerNamespacesHelper.java
index 14fc592..6cd2441 100644
--- a/tests/tests/jni/src/android/jni/cts/LinkerNamespacesHelper.java
+++ b/tests/tests/jni/src/android/jni/cts/LinkerNamespacesHelper.java
@@ -82,6 +82,7 @@
     private final static String[] PUBLIC_ART_LIBRARIES = {
         "libicui18n.so",
         "libicuuc.so",
+        "libnativehelper.so"
     };
 
     // The grey-list.
@@ -93,7 +94,6 @@
         "libexpat.so",
         "libgui.so",
         "libmedia.so",
-        "libnativehelper.so",
         "libskia.so",
         "libssl.so",
         "libstagefright.so",
@@ -188,7 +188,7 @@
 
         Collections.addAll(systemLibs, PUBLIC_SYSTEM_LIBRARIES);
         Collections.addAll(systemLibs, OPTIONAL_SYSTEM_LIBRARIES);
-	// System path could contain public ART libraries on foreign arch. http://b/149852946
+        // System path could contain public ART libraries on foreign arch. http://b/149852946
         if (isForeignArchitecture()) {
             Collections.addAll(systemLibs, PUBLIC_ART_LIBRARIES);
         }
diff --git a/tests/tests/jvmti/attaching/jni/Android.bp b/tests/tests/jvmti/attaching/jni/Android.bp
index 8e26f86..5e84b2c 100644
--- a/tests/tests/jvmti/attaching/jni/Android.bp
+++ b/tests/tests/jvmti/attaching/jni/Android.bp
@@ -27,6 +27,7 @@
         "-Wno-unused-parameter",
         "-DAGENT_NR=1",
     ],
+    header_libs: ["jni_headers"],
 }
 
 cc_test_library {
@@ -40,6 +41,7 @@
         "-Wno-unused-parameter",
         "-DAGENT_NR=2",
     ],
+    header_libs: ["jni_headers"],
 }
 
 cc_test_library {
@@ -53,6 +55,7 @@
         "-Wno-unused-parameter",
         "-DAGENT_NR=3",
     ],
+    header_libs: ["jni_headers"],
 }
 
 cc_test_library {
@@ -66,4 +69,5 @@
         "-Wno-unused-parameter",
         "-DAGENT_NR=4",
     ],
+    header_libs: ["jni_headers"],
 }
diff --git a/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java b/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java
index 46592ca..4373fdc 100644
--- a/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java
@@ -68,6 +68,8 @@
 
 import com.google.common.collect.ImmutableSet;
 
+import androidx.test.filters.RequiresDevice;
+
 import org.bouncycastle.asn1.x500.X500Name;
 import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder;
 
@@ -163,21 +165,26 @@
         int[] purposes = {
                 KM_PURPOSE_SIGN, KM_PURPOSE_VERIFY, KM_PURPOSE_SIGN | KM_PURPOSE_VERIFY
         };
+        boolean[] devicePropertiesAttestationValues = {true, false};
+        boolean[] includeValidityDatesValues = {true, false};
 
         for (int curveIndex = 0; curveIndex < curves.length; ++curveIndex) {
             for (int challengeIndex = 0; challengeIndex < challenges.length; ++challengeIndex) {
                 for (int purposeIndex = 0; purposeIndex < purposes.length; ++purposeIndex) {
-                    try {
-                        testEcAttestation(challenges[challengeIndex],
-                                true /* includeValidityDates */,
-                                curves[curveIndex], keySizes[curveIndex], purposes[purposeIndex]);
-                        testEcAttestation(challenges[challengeIndex],
-                                false /* includeValidityDates */,
-                                curves[curveIndex], keySizes[curveIndex], purposes[purposeIndex]);
-                    } catch (Throwable e) {
-                        throw new Exception(
-                                "Failed on curve " + curveIndex + " and challege " + challengeIndex,
-                                e);
+                    for (boolean includeValidityDates : includeValidityDatesValues) {
+                        for (boolean devicePropertiesAttestation : devicePropertiesAttestationValues) {
+                            try {
+                                testEcAttestation(challenges[challengeIndex], includeValidityDates,
+                                        curves[curveIndex], keySizes[curveIndex],
+                                        purposes[purposeIndex], devicePropertiesAttestation);
+                            } catch (Throwable e) {
+                                throw new Exception("Failed on curve " + curveIndex +
+                                        " challenge " + challengeIndex + " purpose " +
+                                        purposeIndex + " includeValidityDates " +
+                                        includeValidityDates + " and devicePropertiesAttestation " +
+                                        devicePropertiesAttestation, e);
+                            }
+                        }
                     }
                 }
             }
@@ -185,43 +192,50 @@
     }
 
     public void testEcAttestation_TooLargeChallenge() throws Exception {
-        try {
-            testEcAttestation(new byte[129], true /* includeValidityDates */, "secp256r1", 256,
-                    KM_PURPOSE_SIGN);
-            fail("Attestation challenges larger than 128 bytes should be rejected");
-        } catch (ProviderException e) {
-            KeyStoreException cause = (KeyStoreException) e.getCause();
-            assertEquals(KM_ERROR_INVALID_INPUT_LENGTH, cause.getErrorCode());
+        boolean[] devicePropertiesAttestationValues = {true, false};
+        for (boolean devicePropertiesAttestation : devicePropertiesAttestationValues) {
+            try {
+                testEcAttestation(new byte[129], true /* includeValidityDates */, "secp256r1", 256,
+                        KM_PURPOSE_SIGN, devicePropertiesAttestation);
+                fail("Attestation challenges larger than 128 bytes should be rejected");
+            } catch (ProviderException e) {
+                KeyStoreException cause = (KeyStoreException) e.getCause();
+                assertEquals(KM_ERROR_INVALID_INPUT_LENGTH, cause.getErrorCode());
+            }
         }
     }
 
     public void testEcAttestation_NoChallenge() throws Exception {
-        String keystoreAlias = "test_key";
-        Date now = new Date();
-        Date originationEnd = new Date(now.getTime() + ORIGINATION_TIME_OFFSET);
-        Date consumptionEnd = new Date(now.getTime() + CONSUMPTION_TIME_OFFSET);
-        KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(keystoreAlias, PURPOSE_SIGN)
-                .setAlgorithmParameterSpec(new ECGenParameterSpec("secp256r1"))
-                .setDigests(DIGEST_NONE, DIGEST_SHA256, DIGEST_SHA512)
-                .setAttestationChallenge(null)
-                .setKeyValidityStart(now)
-                .setKeyValidityForOriginationEnd(originationEnd)
-                .setKeyValidityForConsumptionEnd(consumptionEnd)
-                .build();
+        boolean[] devicePropertiesAttestationValues = {true, false};
+        for (boolean devicePropertiesAttestation : devicePropertiesAttestationValues) {
+            String keystoreAlias = "test_key";
+            Date now = new Date();
+            Date originationEnd = new Date(now.getTime() + ORIGINATION_TIME_OFFSET);
+            Date consumptionEnd = new Date(now.getTime() + CONSUMPTION_TIME_OFFSET);
+            KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(keystoreAlias, PURPOSE_SIGN)
+                    .setAlgorithmParameterSpec(new ECGenParameterSpec("secp256r1"))
+                    .setDigests(DIGEST_NONE, DIGEST_SHA256, DIGEST_SHA512)
+                    .setAttestationChallenge(null)
+                    .setKeyValidityStart(now)
+                    .setKeyValidityForOriginationEnd(originationEnd)
+                    .setKeyValidityForConsumptionEnd(consumptionEnd)
+                    .setDevicePropertiesAttestationIncluded(devicePropertiesAttestation)
+                    .build();
 
-        generateKeyPair(KEY_ALGORITHM_EC, spec);
+            generateKeyPair(KEY_ALGORITHM_EC, spec);
 
-        KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
-        keyStore.load(null);
+            KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
+            keyStore.load(null);
 
-        try {
-            Certificate certificates[] = keyStore.getCertificateChain(keystoreAlias);
-            assertEquals(1, certificates.length);
+            try {
+                Certificate certificates[] = keyStore.getCertificateChain(keystoreAlias);
+                assertEquals(1, certificates.length);
 
-            X509Certificate attestationCert = (X509Certificate) certificates[0];
-            assertNull(attestationCert.getExtensionValue(Attestation.KEY_DESCRIPTION_OID));
-        } finally {
-            keyStore.deleteEntry(keystoreAlias);
+                X509Certificate attestationCert = (X509Certificate) certificates[0];
+                assertNull(attestationCert.getExtensionValue(Attestation.KEY_DESCRIPTION_OID));
+            } finally {
+                keyStore.deleteEntry(keystoreAlias);
+            }
         }
     }
 
@@ -325,14 +339,19 @@
                         SIGNATURE_PADDING_RSA_PSS,
                 },
         };
+        boolean[] devicePropertiesAttestationValues = {true, false};
 
-        for (int keySize : keySizes) {
-            for (byte[] challenge : challenges) {
-                for (int purpose : purposes) {
-                    if (isEncryptionPurpose(purpose)) {
-                        testRsaAttestations(keySize, challenge, purpose, encryptionPaddingModes);
-                    } else {
-                        testRsaAttestations(keySize, challenge, purpose, signaturePaddingModes);
+        for (boolean devicePropertiesAttestation : devicePropertiesAttestationValues) {
+            for (int keySize : keySizes) {
+                for (byte[] challenge : challenges) {
+                    for (int purpose : purposes) {
+                        if (isEncryptionPurpose(purpose)) {
+                            testRsaAttestations(keySize, challenge, purpose, encryptionPaddingModes,
+                                    devicePropertiesAttestation);
+                        } else {
+                            testRsaAttestations(keySize, challenge, purpose, signaturePaddingModes,
+                                    devicePropertiesAttestation);
+                        }
                     }
                 }
             }
@@ -340,46 +359,56 @@
     }
 
     public void testRsaAttestation_TooLargeChallenge() throws Exception {
-        try {
-            testRsaAttestation(new byte[129], true /* includeValidityDates */, 512, PURPOSE_SIGN,
-                    null /* paddingModes; may be empty because we'll never test them */);
-            fail("Attestation challenges larger than 128 bytes should be rejected");
-        } catch (ProviderException e) {
-            KeyStoreException cause = (KeyStoreException) e.getCause();
-            assertEquals(KM_ERROR_INVALID_INPUT_LENGTH, cause.getErrorCode());
+        boolean[] devicePropertiesAttestationValues = {true, false};
+        for (boolean devicePropertiesAttestation : devicePropertiesAttestationValues) {
+            try {
+                testRsaAttestation(new byte[129], true /* includeValidityDates */, 512,
+                        PURPOSE_SIGN,
+                        null /* paddingModes; may be empty because we'll never test them */,
+                        devicePropertiesAttestation);
+                fail("Attestation challenges larger than 128 bytes should be rejected");
+            } catch(ProviderException e){
+                KeyStoreException cause = (KeyStoreException) e.getCause();
+                assertEquals(KM_ERROR_INVALID_INPUT_LENGTH, cause.getErrorCode());
+            }
         }
     }
 
     public void testRsaAttestation_NoChallenge() throws Exception {
-        String keystoreAlias = "test_key";
-        Date now = new Date();
-        Date originationEnd = new Date(now.getTime() + ORIGINATION_TIME_OFFSET);
-        Date consumptionEnd = new Date(now.getTime() + CONSUMPTION_TIME_OFFSET);
-        KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(keystoreAlias, PURPOSE_SIGN)
-                .setDigests(DIGEST_NONE, DIGEST_SHA256, DIGEST_SHA512)
-                .setAttestationChallenge(null)
-                .setKeyValidityStart(now)
-                .setKeyValidityForOriginationEnd(originationEnd)
-                .setKeyValidityForConsumptionEnd(consumptionEnd)
-                .build();
+        boolean[] devicePropertiesAttestationValues = {true, false};
+        for (boolean devicePropertiesAttestation : devicePropertiesAttestationValues) {
+            String keystoreAlias = "test_key";
+            Date now = new Date();
+            Date originationEnd = new Date(now.getTime() + ORIGINATION_TIME_OFFSET);
+            Date consumptionEnd = new Date(now.getTime() + CONSUMPTION_TIME_OFFSET);
+            KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(keystoreAlias, PURPOSE_SIGN)
+                    .setDigests(DIGEST_NONE, DIGEST_SHA256, DIGEST_SHA512)
+                    .setAttestationChallenge(null)
+                    .setKeyValidityStart(now)
+                    .setKeyValidityForOriginationEnd(originationEnd)
+                    .setKeyValidityForConsumptionEnd(consumptionEnd)
+                    .setDevicePropertiesAttestationIncluded(devicePropertiesAttestation)
+                    .build();
 
-        generateKeyPair(KEY_ALGORITHM_RSA, spec);
+            generateKeyPair(KEY_ALGORITHM_RSA, spec);
 
-        KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
-        keyStore.load(null);
+            KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
+            keyStore.load(null);
 
-        try {
-            Certificate certificates[] = keyStore.getCertificateChain(keystoreAlias);
-            assertEquals(1, certificates.length);
+            try {
+                Certificate certificates[] = keyStore.getCertificateChain(keystoreAlias);
+                assertEquals(1, certificates.length);
 
-            X509Certificate attestationCert = (X509Certificate) certificates[0];
-            assertNull(attestationCert.getExtensionValue(Attestation.KEY_DESCRIPTION_OID));
-        } finally {
-            keyStore.deleteEntry(keystoreAlias);
+                X509Certificate attestationCert = (X509Certificate) certificates[0];
+                assertNull(attestationCert.getExtensionValue(Attestation.KEY_DESCRIPTION_OID));
+            } finally {
+                keyStore.deleteEntry(keystoreAlias);
+            }
         }
     }
 
     @RestrictedBuildTest
+    @RequiresDevice  // Emulators have no place to store the needed key
     public void testRsaAttestation_DeviceLocked() throws Exception {
         String keystoreAlias = "test_key";
         Date now = new Date();
@@ -417,52 +446,62 @@
     }
 
     public void testAesAttestation() throws Exception {
-        String keystoreAlias = "test_key";
-        KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(keystoreAlias, PURPOSE_ENCRYPT)
-                .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
-                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
-                .setAttestationChallenge(new byte[0])
-                .build();
-        generateKey(spec, KeyProperties.KEY_ALGORITHM_AES);
+        boolean[] devicePropertiesAttestationValues = {true, false};
+        for (boolean devicePropertiesAttestation : devicePropertiesAttestationValues) {
+            String keystoreAlias = "test_key";
+            KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(keystoreAlias,
+                    PURPOSE_ENCRYPT)
+                    .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
+                    .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
+                    .setAttestationChallenge(new byte[0])
+                    .setDevicePropertiesAttestationIncluded(devicePropertiesAttestation)
+                    .build();
+            generateKey(spec, KeyProperties.KEY_ALGORITHM_AES);
 
-        KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
-        keyStore.load(null);
-        try {
-            assertNull(keyStore.getCertificateChain(keystoreAlias));
-        } finally {
-            keyStore.deleteEntry(keystoreAlias);
+            KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
+            keyStore.load(null);
+            try {
+                assertNull(keyStore.getCertificateChain(keystoreAlias));
+            } finally {
+                keyStore.deleteEntry(keystoreAlias);
+            }
         }
     }
 
     public void testHmacAttestation() throws Exception {
-        String keystoreAlias = "test_key";
-        KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(keystoreAlias, PURPOSE_SIGN)
-                .build();
+        boolean[] devicePropertiesAttestationValues = {true, false};
+        for (boolean devicePropertiesAttestation : devicePropertiesAttestationValues) {
+            String keystoreAlias = "test_key";
+            KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(keystoreAlias, PURPOSE_SIGN)
+                    .setDevicePropertiesAttestationIncluded(devicePropertiesAttestation)
+                    .build();
 
-        generateKey(spec, KeyProperties.KEY_ALGORITHM_HMAC_SHA256);
+            generateKey(spec, KeyProperties.KEY_ALGORITHM_HMAC_SHA256);
 
-        KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
-        keyStore.load(null);
-        try {
-            assertNull(keyStore.getCertificateChain(keystoreAlias));
-        } finally {
-            keyStore.deleteEntry(keystoreAlias);
+            KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
+            keyStore.load(null);
+            try {
+                assertNull(keyStore.getCertificateChain(keystoreAlias));
+            } finally {
+                keyStore.deleteEntry(keystoreAlias);
+            }
         }
     }
 
     private void testRsaAttestations(int keySize, byte[] challenge, int purpose,
-            String[][] paddingModes) throws Exception {
+            String[][] paddingModes, boolean devicePropertiesAttestation) throws Exception {
         for (String[] paddings : paddingModes) {
             try {
                 testRsaAttestation(challenge, true /* includeValidityDates */, keySize, purpose,
-                        paddings);
+                        paddings, devicePropertiesAttestation);
                 testRsaAttestation(challenge, false /* includeValidityDates */, keySize, purpose,
-                        paddings);
+                        paddings, devicePropertiesAttestation);
             } catch (Throwable e) {
                 throw new Exception("Failed on key size " + keySize + " challenge [" +
                         new String(challenge) + "], purposes " +
-                        buildPurposeSet(purpose) + " and paddings " +
-                        ImmutableSet.copyOf(paddings),
+                        buildPurposeSet(purpose) + " paddings " +
+                        ImmutableSet.copyOf(paddings) + " and devicePropertiesAttestation "
+                        + devicePropertiesAttestation,
                         e);
             }
         }
@@ -476,9 +515,14 @@
 
     @SuppressWarnings("deprecation")
     private void testRsaAttestation(byte[] challenge, boolean includeValidityDates, int keySize,
-            int purposes, String[] paddingModes) throws Exception {
-        String keystoreAlias = "test_key";
+            int purposes, String[] paddingModes, boolean devicePropertiesAttestation)
+            throws Exception {
+        Log.i(TAG, "RSA key attestation with: challenge " + Arrays.toString(challenge) +
+                " / includeValidityDates " + includeValidityDates + " / keySize " + keySize +
+                " / purposes " + purposes + " / paddingModes " + Arrays.toString(paddingModes) +
+                " / devicePropertiesAttestation " + devicePropertiesAttestation);
 
+        String keystoreAlias = "test_key";
         Date startTime = new Date();
         Date originationEnd = new Date(startTime.getTime() + ORIGINATION_TIME_OFFSET);
         Date consumptionEnd = new Date(startTime.getTime() + CONSUMPTION_TIME_OFFSET);
@@ -486,7 +530,8 @@
             new KeyGenParameterSpec.Builder(keystoreAlias, purposes)
                         .setKeySize(keySize)
                         .setDigests(DIGEST_NONE, DIGEST_SHA256, DIGEST_SHA512)
-                        .setAttestationChallenge(challenge);
+                        .setAttestationChallenge(challenge)
+                        .setDevicePropertiesAttestationIncluded(devicePropertiesAttestation);
 
         if (includeValidityDates) {
             builder.setKeyValidityStart(startTime)
@@ -517,7 +562,7 @@
             checkRsaKeyDetails(attestation, keySize, purposes, ImmutableSet.copyOf(paddingModes));
             checkKeyUsage(attestationCert, purposes);
             checkKeyIndependentAttestationInfo(challenge, purposes, startTime, includeValidityDates,
-                    attestation);
+                    devicePropertiesAttestation, attestation);
         } finally {
             keyStore.deleteEntry(keystoreAlias);
         }
@@ -538,9 +583,13 @@
 
     @SuppressWarnings("deprecation")
     private void testEcAttestation(byte[] challenge, boolean includeValidityDates, String ecCurve,
-            int keySize, int purposes) throws Exception {
-        String keystoreAlias = "test_key";
+            int keySize, int purposes, boolean devicePropertiesAttestation) throws Exception {
+        Log.i(TAG, "EC key attestation with: challenge " + Arrays.toString(challenge) +
+                " / includeValidityDates " + includeValidityDates + " / ecCurve " + ecCurve +
+                " / keySize " + keySize + " / purposes " + purposes +
+                " / devicePropertiesAttestation " + devicePropertiesAttestation);
 
+        String keystoreAlias = "test_key";
         Date startTime = new Date();
         Date originationEnd = new Date(startTime.getTime() + ORIGINATION_TIME_OFFSET);
         Date consumptionEnd = new Date(startTime.getTime() + CONSUMPTION_TIME_OFFSET);
@@ -548,7 +597,8 @@
                 purposes)
                         .setAlgorithmParameterSpec(new ECGenParameterSpec(ecCurve))
                         .setDigests(DIGEST_NONE, DIGEST_SHA256, DIGEST_SHA512)
-                        .setAttestationChallenge(challenge);
+                        .setAttestationChallenge(challenge)
+                        .setDevicePropertiesAttestationIncluded(devicePropertiesAttestation);
 
         if (includeValidityDates) {
             builder.setKeyValidityStart(startTime)
@@ -571,7 +621,7 @@
             checkEcKeyDetails(attestation, ecCurve, keySize);
             checkKeyUsage(attestationCert, purposes);
             checkKeyIndependentAttestationInfo(challenge, purposes, startTime, includeValidityDates,
-                    attestation);
+                    devicePropertiesAttestation, attestation);
         } finally {
             keyStore.deleteEntry(keystoreAlias);
         }
@@ -596,9 +646,50 @@
         }
     }
 
+    private void checkAttestationDeviceProperties(boolean devicePropertiesAttestation,
+            Attestation attestation) {
+        final AuthorizationList keyDetailsList;
+        final AuthorizationList nonKeyDetailsList;
+        if (attestation.getKeymasterSecurityLevel() == KM_SECURITY_LEVEL_TRUSTED_ENVIRONMENT) {
+            keyDetailsList = attestation.getTeeEnforced();
+            nonKeyDetailsList = attestation.getSoftwareEnforced();
+        } else {
+            keyDetailsList = attestation.getSoftwareEnforced();
+            nonKeyDetailsList = attestation.getTeeEnforced();
+        }
+
+        if (devicePropertiesAttestation) {
+            assertEquals(Build.BRAND, keyDetailsList.getBrand());
+            assertEquals(Build.DEVICE, keyDetailsList.getDevice());
+            assertEquals(Build.PRODUCT, keyDetailsList.getProduct());
+            assertEquals(Build.MANUFACTURER, keyDetailsList.getManufacturer());
+            assertEquals(Build.MODEL, keyDetailsList.getModel());
+        } else {
+            assertNull(keyDetailsList.getBrand());
+            assertNull(keyDetailsList.getDevice());
+            assertNull(keyDetailsList.getProduct());
+            assertNull(keyDetailsList.getManufacturer());
+            assertNull(keyDetailsList.getModel());
+        }
+        assertNull(nonKeyDetailsList.getBrand());
+        assertNull(nonKeyDetailsList.getDevice());
+        assertNull(nonKeyDetailsList.getProduct());
+        assertNull(nonKeyDetailsList.getManufacturer());
+        assertNull(nonKeyDetailsList.getModel());
+    }
+
+    private void checkAttestationNoUniqueIds(Attestation attestation) {
+        assertNull(attestation.getTeeEnforced().getImei());
+        assertNull(attestation.getTeeEnforced().getMeid());
+        assertNull(attestation.getTeeEnforced().getSerialNumber());
+        assertNull(attestation.getSoftwareEnforced().getImei());
+        assertNull(attestation.getSoftwareEnforced().getMeid());
+        assertNull(attestation.getSoftwareEnforced().getSerialNumber());
+    }
+
     private void checkKeyIndependentAttestationInfo(byte[] challenge, int purposes, Date startTime,
-            boolean includesValidityDates, Attestation attestation)
-            throws NoSuchAlgorithmException, NameNotFoundException {
+            boolean includesValidityDates, boolean devicePropertiesAttestation,
+            Attestation attestation) throws NoSuchAlgorithmException, NameNotFoundException {
         checkUnexpectedOids(attestation);
         checkAttestationSecurityLevelDependentParams(attestation);
         assertNotNull(attestation.getAttestationChallenge());
@@ -612,6 +703,8 @@
         checkFlags(attestation);
         checkOrigin(attestation);
         checkAttestationApplicationId(attestation);
+        checkAttestationDeviceProperties(devicePropertiesAttestation, attestation);
+        checkAttestationNoUniqueIds(attestation);
     }
 
     private void checkUnexpectedOids(Attestation attestation) {
diff --git a/tests/tests/keystore/src/android/keystore/cts/KeyPairGeneratorTest.java b/tests/tests/keystore/src/android/keystore/cts/KeyPairGeneratorTest.java
index 40970f5..421e0e0 100644
--- a/tests/tests/keystore/src/android/keystore/cts/KeyPairGeneratorTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/KeyPairGeneratorTest.java
@@ -1815,7 +1815,7 @@
         @Override
         public String chooseEngineClientAlias(String[] keyType, Principal[] issuers,
             SSLEngine engine) {
-            return "fake";
+            throw new IllegalStateException();
         }
 
         @Override
@@ -1826,7 +1826,7 @@
         @Override
         public String chooseEngineServerAlias(String keyType, Principal[] issuers,
             SSLEngine engine) {
-            return "fake";
+            throw new IllegalStateException();
         }
 
         @Override
diff --git a/tests/tests/libthermalndk/jni/Android.bp b/tests/tests/libthermalndk/jni/Android.bp
index 9f95e7f..0990304 100644
--- a/tests/tests/libthermalndk/jni/Android.bp
+++ b/tests/tests/libthermalndk/jni/Android.bp
@@ -17,6 +17,7 @@
     srcs: [
         "NativeThermalTest.cpp",
     ],
+    header_libs: ["jni_headers"],
     shared_libs: [
         "libandroid",
         "liblog",
diff --git a/tests/tests/media/src/android/media/cts/OutputSurface.java b/tests/tests/media/src/android/media/cts/OutputSurface.java
index c87326d..5417bf4 100644
--- a/tests/tests/media/src/android/media/cts/OutputSurface.java
+++ b/tests/tests/media/src/android/media/cts/OutputSurface.java
@@ -228,7 +228,7 @@
      * data is available.
      */
     public void awaitNewImage() {
-        final int TIMEOUT_MS = 500;
+        final int TIMEOUT_MS = 2000;
 
         synchronized (mFrameSyncObject) {
             while (!mFrameAvailable) {
diff --git a/tests/tests/nativemidi/java/android/nativemidi/cts/NativeMidiEchoTest.java b/tests/tests/nativemidi/java/android/nativemidi/cts/NativeMidiEchoTest.java
index 32e46ac..fd92322 100644
--- a/tests/tests/nativemidi/java/android/nativemidi/cts/NativeMidiEchoTest.java
+++ b/tests/tests/nativemidi/java/android/nativemidi/cts/NativeMidiEchoTest.java
@@ -218,7 +218,6 @@
     @Before
     public void setUp() throws Exception {
         if (!hasMidiSupport()) {
-            Assert.assertTrue("FEATURE_MIDI Not Supported.", false);
             return; // Not supported so don't test it.
         }
 
@@ -265,6 +264,10 @@
             return; // Nothing to test
         }
 
+        if (!hasMidiSupport()) {
+            return; // Nothing to test
+        }
+
         Assert.assertEquals("Didn't start with 0 sends", 0, getNumSends(mTestContext));
         Assert.assertEquals("Didn't start with 0 bytes sent", 0, getNumBytesSent(mTestContext));
 
diff --git a/tests/tests/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionPskTest.java b/tests/tests/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionPskTest.java
index 0509fc0..13f953a 100644
--- a/tests/tests/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionPskTest.java
+++ b/tests/tests/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionPskTest.java
@@ -18,13 +18,14 @@
 
 import static android.app.AppOpsManager.OP_MANAGE_IPSEC_TUNNELS;
 import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_AUTHENTICATION_FAILED;
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_INTERNAL_ADDRESS_FAILURE;
 import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_NO_PROPOSAL_CHOSEN;
+import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_TS_UNACCEPTABLE;
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 
 import android.net.LinkAddress;
+import android.net.ipsec.ike.ChildSessionParams;
 import android.net.ipsec.ike.IkeFqdnIdentification;
 import android.net.ipsec.ike.IkeSession;
 import android.net.ipsec.ike.IkeSessionParams;
@@ -84,7 +85,15 @@
                     + "9352D71100777B00ABCC6BD7DBEA697827FFAAA48DF9A54D1D68161939F5DC8"
                     + "6743A7CEB2BE34AC00095A5B8";
 
-    private IkeSession openIkeSessionWithRemoteAddress(InetAddress remoteAddress) {
+    private IkeSession openIkeSessionWithTunnelModeChild(InetAddress remoteAddress) {
+        return openIkeSession(remoteAddress, buildTunnelModeChildSessionParams());
+    }
+
+    private IkeSession openIkeSessionWithTransportModeChild(InetAddress remoteAddress) {
+        return openIkeSession(remoteAddress, buildTransportModeChildParamsWithDefaultTs());
+    }
+
+    private IkeSession openIkeSession(InetAddress remoteAddress, ChildSessionParams childParams) {
         IkeSessionParams ikeParams =
                 new IkeSessionParams.Builder(sContext)
                         .setNetwork(mTunNetwork)
@@ -98,7 +107,7 @@
         return new IkeSession(
                 sContext,
                 ikeParams,
-                buildTunnelModeChildSessionParams(),
+                childParams,
                 mUserCbExecutor,
                 mIkeSessionCallback,
                 mFirstChildSessionCallback);
@@ -124,7 +133,7 @@
         if (!hasTunnelsFeature()) return;
 
         // Open IKE Session
-        IkeSession ikeSession = openIkeSessionWithRemoteAddress(mRemoteAddress);
+        IkeSession ikeSession = openIkeSessionWithTunnelModeChild(mRemoteAddress);
         performSetupIkeAndFirstChildBlocking(SUCCESS_IKE_INIT_RESP, SUCCESS_IKE_AUTH_RESP);
 
         // IKE INIT and IKE AUTH takes two exchanges. Message ID starts from 2
@@ -222,7 +231,7 @@
         setUpTestNetwork(mLocalAddress);
 
         // Open IKE Session
-        IkeSession ikeSession = openIkeSessionWithRemoteAddress(mRemoteAddress);
+        IkeSession ikeSession = openIkeSessionWithTunnelModeChild(mRemoteAddress);
         performSetupIkeAndFirstChildBlocking(
                 ikeInitResp,
                 1 /* expectedAuthReqPktCnt */,
@@ -258,7 +267,7 @@
         if (!hasTunnelsFeature()) return;
 
         // Open IKE Session
-        IkeSession ikeSession = openIkeSessionWithRemoteAddress(mRemoteAddress);
+        IkeSession ikeSession = openIkeSessionWithTunnelModeChild(mRemoteAddress);
         performSetupIkeAndFirstChildBlocking(SUCCESS_IKE_INIT_RESP, SUCCESS_IKE_AUTH_RESP);
 
         ikeSession.kill();
@@ -272,7 +281,7 @@
                 "46B8ECA1E0D72A180000000000000000292022200000000000000024000000080000000E";
 
         // Open IKE Session
-        IkeSession ikeSession = openIkeSessionWithRemoteAddress(mRemoteAddress);
+        IkeSession ikeSession = openIkeSessionWithTransportModeChild(mRemoteAddress);
         int expectedMsgId = 0;
         mTunUtils.awaitReqAndInjectResp(
                 IKE_DETERMINISTIC_INITIATOR_SPI,
@@ -309,7 +318,7 @@
                         + "AB6E4808BAC0CA1DAD6ADD0A126A41BD";
 
         // Open IKE Session
-        IkeSession ikeSession = openIkeSessionWithRemoteAddress(mRemoteAddress);
+        IkeSession ikeSession = openIkeSessionWithTransportModeChild(mRemoteAddress);
         performSetupIkeAndFirstChildBlocking(ikeInitRespHex, ikeAuthFailRespHex);
 
         mFirstChildSessionCallback.awaitOnClosed();
@@ -322,27 +331,28 @@
     @Test
     public void testIkeAuthHandlesFirstChildCreationFail() throws Exception {
         final String ikeInitRespHex =
-                "46B8ECA1E0D72A182B300285DA19E6452120222000000000000001502200"
-                        + "00300000002C010100040300000C0100000C800E01000300000803000005"
-                        + "0300000802000004000000080400000228000088000200005C9DE629981F"
-                        + "DB1FC45DB6CCF15D076C1F51BD9F63C771DC089F05CCDE6247965D15C616"
-                        + "C7B5A62342491715E4D1FEA19326477D24143E8E56AB6AD93F54B19BC32A"
-                        + "44BC0A5B5632E57D0A3C43E466E1547D8E4EF65EA4B864A348161666E229"
-                        + "84975A486251A17C4F096A6D5CF3DB83874B70324A31AA7ADDE2D73BADD8"
-                        + "238029000024CF06260F7C4923295E7C91F2B8479212892DA7A519A0322F"
-                        + "F5B2BF570B92972B2900001C00004004C7ACC2C7D58CF8C9F5E953993AF4"
-                        + "6CAC976635B42900001C00004005B64B190DFE7BDE8B9B1475EDE67B63D6"
-                        + "F1DBBF44290000080000402E290000100000402F00020003000400050000"
+                "46B8ECA1E0D72A18F5ABBF896A1240BE2120222000000000000001502200"
+                        + "00300000002C010100040300000C0100000C800E0100030000080300000C"
+                        + "03000008020000050000000804000002280000880002000074950F016B85"
+                        + "605E57E24651843AB70E41B552EDEE227DFE51E6CBEC00E75FFEFC7D5453"
+                        + "109B15F721FCD811FC9F113BE06050882F2FC5F5FF25857E555CCFB5AB64"
+                        + "8B0D1D7A819A3B05DE1FE89A4A627C60D5AA06CD0F66ACD3748722F9CD4F"
+                        + "F30AE7477CBC12049821F07AD6C9F0ED732321A6A36FA817722E025AC34B"
+                        + "ABE62900002432E3807F595070E95EDA341A787599B24B1151B535B0222B"
+                        + "65C003401B9B38F82900001C000040043BB760DB3037B51768DFFAB4B21D"
+                        + "B1716EA1C1382900001C0000400531098EB04DF1BE3F304606BD59B454A8"
+                        + "CC7E7311290000080000402E290000100000402F00020003000400050000"
                         + "000800004014";
         final String ikeAuthCreateChildFailHex =
-                "46B8ECA1E0D72A182B300285DA19E6452E202320000000010000008C2400"
-                        + "0070386FC9CCC67495A17915D0544390A2963A769F4A42C6FA668CEEC07F"
-                        + "EC0C87D681DE34267023DD394F1401B5A563E71002C0CE0928D0ABC0C4570"
-                        + "E39C2EDEF820F870AB71BD70A3F3EB5C96CA294B6D3F01677690DCF9F8CFC"
-                        + "9584650957573502BA83E32F18207A9ADEB1FA";
+                "46B8ECA1E0D72A18F5ABBF896A1240BE2E20232000000001000000B02400"
+                        + "009400B0861242E0C88ECB3848D772B560CAD65B6AC9DFFDC8622A394B8E"
+                        + "64E550BDD69FCD7E768129787ED9062992C1D6DB0F0631C2E05765B403CF"
+                        + "EF1D0A055B32F6698FF7DB5B8FB1B6A83A81634D00E22C86E35B3BFBEC73"
+                        + "EAC6806678926945BC7A57003DC1A3528A1EC423EE56C1075B36C0B57A6B"
+                        + "C6DD990182F6FABFFA167D199C7D629E5B830AAD2AFBD31CEBA6";
 
         // Open IKE Session
-        IkeSession ikeSession = openIkeSessionWithRemoteAddress(mRemoteAddress);
+        IkeSession ikeSession = openIkeSessionWithTransportModeChild(mRemoteAddress);
         performSetupIkeAndFirstChildBlocking(ikeInitRespHex, ikeAuthCreateChildFailHex);
 
         // Even though the child creation failed, the authentication succeeded, so the IKE Session's
@@ -352,7 +362,7 @@
         // Verify Child Creation failed
         IkeProtocolException protocolException =
                 (IkeProtocolException) mFirstChildSessionCallback.awaitOnClosedException();
-        assertEquals(ERROR_TYPE_INTERNAL_ADDRESS_FAILURE, protocolException.getErrorType());
+        assertEquals(ERROR_TYPE_TS_UNACCEPTABLE, protocolException.getErrorType());
         assertArrayEquals(EXPECTED_PROTOCOL_ERROR_DATA_NONE, protocolException.getErrorData());
 
         ikeSession.kill();
diff --git a/tests/tests/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionTestBase.java b/tests/tests/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionTestBase.java
index 2458b25..a81063b 100644
--- a/tests/tests/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionTestBase.java
+++ b/tests/tests/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionTestBase.java
@@ -276,6 +276,13 @@
                 .build();
     }
 
+    TransportModeChildSessionParams buildTransportModeChildParamsWithDefaultTs() {
+        return new TransportModeChildSessionParams.Builder()
+                .addSaProposal(SaProposalTest.buildChildSaProposalWithCombinedModeCipher())
+                .addSaProposal(SaProposalTest.buildChildSaProposalWithNormalModeCipher())
+                .build();
+    }
+
     TunnelModeChildSessionParams buildTunnelModeChildSessionParams() {
         return new TunnelModeChildSessionParams.Builder()
                 .addSaProposal(SaProposalTest.buildChildSaProposalWithNormalModeCipher())
diff --git a/tests/tests/opengl/libopengltest/Android.bp b/tests/tests/opengl/libopengltest/Android.bp
index bdff5f0..b7cf454 100644
--- a/tests/tests/opengl/libopengltest/Android.bp
+++ b/tests/tests/opengl/libopengltest/Android.bp
@@ -36,6 +36,7 @@
     ],
     sdk_version: "current",
     stl: "none",
+    header_libs: ["jni_headers"],
     shared_libs: [
         "libGLESv2",
         "liblog",
diff --git a/tests/tests/os/assets/platform_versions.txt b/tests/tests/os/assets/platform_versions.txt
index b4de394..3762249 100644
--- a/tests/tests/os/assets/platform_versions.txt
+++ b/tests/tests/os/assets/platform_versions.txt
@@ -1 +1 @@
-11
+S
diff --git a/tests/tests/os/src/android/os/cts/BuildTest.java b/tests/tests/os/src/android/os/cts/BuildTest.java
index 00cb97d..ca0f84a 100644
--- a/tests/tests/os/src/android/os/cts/BuildTest.java
+++ b/tests/tests/os/src/android/os/cts/BuildTest.java
@@ -223,6 +223,8 @@
         Pattern.compile("^([0-9A-Za-z._-]+)$");
     private static final Pattern SERIAL_NUMBER_PATTERN =
         Pattern.compile("^([0-9A-Za-z]{6,20})$");
+    private static final Pattern SKU_PATTERN =
+        Pattern.compile("^([0-9A-Za-z.,_-]+)$");
     private static final Pattern TAGS_PATTERN =
         Pattern.compile("^([0-9A-Za-z.,_-]+)$");
     private static final Pattern TYPE_PATTERN =
@@ -254,6 +256,8 @@
 
         assertTrue(SERIAL_NUMBER_PATTERN.matcher(Build.SERIAL).matches());
 
+        assertTrue(SKU_PATTERN.matcher(Build.SKU).matches());
+
         assertTrue(TAGS_PATTERN.matcher(Build.TAGS).matches());
 
         // No format requirements stated in CDD for Build.TIME
diff --git a/tests/tests/os/src/android/os/cts/ParcelTest.java b/tests/tests/os/src/android/os/cts/ParcelTest.java
index bb7b41a..270c938 100644
--- a/tests/tests/os/src/android/os/cts/ParcelTest.java
+++ b/tests/tests/os/src/android/os/cts/ParcelTest.java
@@ -126,7 +126,7 @@
         int dC1 = p.dataCapacity();
         p.writeDouble(2.19);
         int dC2 = p.dataCapacity();
-        assertTrue(dC2 > dC1);
+        assertTrue(dC2 >= dC1);
         p.recycle();
     }
 
diff --git a/tests/tests/packageinstaller/adminpackageinstaller/src/android/packageinstaller/admin/cts/SessionCommitBroadcastTest.java b/tests/tests/packageinstaller/adminpackageinstaller/src/android/packageinstaller/admin/cts/SessionCommitBroadcastTest.java
index 17f97fe..8d8d19e 100644
--- a/tests/tests/packageinstaller/adminpackageinstaller/src/android/packageinstaller/admin/cts/SessionCommitBroadcastTest.java
+++ b/tests/tests/packageinstaller/adminpackageinstaller/src/android/packageinstaller/admin/cts/SessionCommitBroadcastTest.java
@@ -41,12 +41,19 @@
 
     private ComponentName mDefaultLauncher;
     private ComponentName mThisAppLauncher;
+    private SessionCommitReceiver mReceiver;
 
     @Override
     protected void setUp() throws Exception {
         super.setUp();
         mDefaultLauncher = ComponentName.unflattenFromString(getDefaultLauncher());
         mThisAppLauncher = new ComponentName(mContext, LauncherActivity.class);
+        mReceiver = new SessionCommitReceiver();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mContext.unregisterReceiver(mReceiver);
     }
 
     public void testBroadcastNotReceivedForDifferentLauncher() throws Exception {
@@ -69,11 +76,10 @@
         }
 
         assertFalse("No default launcher found", mDefaultLauncher.equals(mThisAppLauncher));
-        SessionCommitReceiver receiver = new SessionCommitReceiver();
         // install the app
         assertInstallPackage();
         // Broadcast not received
-        assertNull(receiver.blockingGetIntent());
+        assertNull(mReceiver.blockingGetIntent());
 
         tryUninstallPackage();
     }
@@ -91,16 +97,15 @@
         }
         setLauncher(mThisAppLauncher.flattenToString());
 
-        SessionCommitReceiver receiver = new SessionCommitReceiver();
         // install the app
         assertInstallPackage();
 
-        verifySessionIntent(receiver.blockingGetIntent());
-
+        verifySessionIntent(mReceiver.blockingGetIntent());
+        mContext.unregisterReceiver(mReceiver);
         forceUninstall();
-        receiver = new SessionCommitReceiver();
+        mReceiver = new SessionCommitReceiver();
         assertInstallPackage();
-        verifySessionIntent(receiver.blockingGetIntent());
+        verifySessionIntent(mReceiver.blockingGetIntent());
 
         tryUninstallPackage();
         // Revert to default launcher
@@ -127,10 +132,9 @@
                 .toLowerCase().contains("success"));
 
         // Enable the app for this user
-        SessionCommitReceiver receiver = new SessionCommitReceiver();
         runShellCommand("cmd package install-existing --user " +
                 Process.myUserHandle().getIdentifier() + "  " + TEST_APP_PKG);
-        verifySessionIntent(receiver.blockingGetIntent());
+        verifySessionIntent(mReceiver.blockingGetIntent());
 
         // Cleanup
         setLauncher(mDefaultLauncher.flattenToString());
@@ -173,7 +177,6 @@
 
         public Intent blockingGetIntent() throws Exception {
             mLatch.await(BROADCAST_TIMEOUT_SECS, TimeUnit.SECONDS);
-            mContext.unregisterReceiver(this);
             return mIntent;
         }
     }
diff --git a/tests/tests/packageinstaller/atomicinstall/OWNERS b/tests/tests/packageinstaller/atomicinstall/OWNERS
deleted file mode 100644
index 25775b8..0000000
--- a/tests/tests/packageinstaller/atomicinstall/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 36137
-include /hostsidetests/stagedinstall/OWNERS
diff --git a/tests/tests/permission/src/android/permission/cts/SecureElementPermissionTest.java b/tests/tests/permission/src/android/permission/cts/SecureElementPermissionTest.java
index 0940d5f..1f04b1c 100644
--- a/tests/tests/permission/src/android/permission/cts/SecureElementPermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/SecureElementPermissionTest.java
@@ -59,8 +59,8 @@
                 .collect(Collectors.toList());
 
         if (nonSpecialPackages.size() > 1) {
-            fail("Only one app on the device is allowed to hold the "
-                    + "SECURE_ELEMENT_PRIVILEGED_OPERATION permission.");
+            fail("Only one app on the device is allowed to hold the " +
+                 "SECURE_ELEMENT_PRIVILEGED_OPERATION permission.");
         }
     }
 }
diff --git a/tests/tests/rsblas/libbnnmdata/Android.bp b/tests/tests/rsblas/libbnnmdata/Android.bp
index ec6a524..f9ffb54 100644
--- a/tests/tests/rsblas/libbnnmdata/Android.bp
+++ b/tests/tests/rsblas/libbnnmdata/Android.bp
@@ -22,4 +22,5 @@
         "-Werror",
         "-Wno-unused-const-variable",
     ],
+    header_libs: ["jni_headers"]
 }
diff --git a/tests/tests/security/Android.bp b/tests/tests/security/Android.bp
index 41d9fad..9a237d6 100644
--- a/tests/tests/security/Android.bp
+++ b/tests/tests/security/Android.bp
@@ -60,7 +60,6 @@
     test_suites: [
         "cts",
         "vts10",
-        "general-tests",
         "sts",
     ],
     certificate: ":security_cts_test_certificate",
@@ -75,4 +74,4 @@
 android_app_certificate {
     name: "security_cts_test_certificate",
     certificate: "security_cts_test_cert",
-}
\ No newline at end of file
+}
diff --git a/tests/tests/slice/src/android/slice/cts/SliceBindingTest.java b/tests/tests/slice/src/android/slice/cts/SliceBindingTest.java
index 710ac94..35b4f70 100644
--- a/tests/tests/slice/src/android/slice/cts/SliceBindingTest.java
+++ b/tests/tests/slice/src/android/slice/cts/SliceBindingTest.java
@@ -18,6 +18,7 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeFalse;
 
 import android.app.PendingIntent.CanceledException;
 import android.app.slice.Slice;
@@ -59,9 +60,7 @@
 
     @Test
     public void testProcess() {
-        if (isSliceDisabled) {
-            return;
-        }
+        assumeFalse(isSliceDisabled);
         sFlag = false;
         mSliceManager.bindSlice(BASE_URI.buildUpon().appendPath("set_flag").build(),
                 Collections.emptySet());
@@ -76,9 +75,7 @@
 
     @Test
     public void testSliceUri() {
-        if (isSliceDisabled) {
-            return;
-        }
+        assumeFalse(isSliceDisabled);
         Slice s = mSliceManager.bindSlice(BASE_URI,
                 Collections.emptySet());
         assertEquals(BASE_URI, s.getUri());
@@ -86,9 +83,7 @@
 
     @Test
     public void testSubSlice() {
-        if (isSliceDisabled) {
-            return;
-        }
+        assumeFalse(isSliceDisabled);
         Uri uri = BASE_URI.buildUpon().appendPath("subslice").build();
         Slice s = mSliceManager.bindSlice(uri, Collections.emptySet());
         assertEquals(uri, s.getUri());
@@ -104,9 +99,7 @@
 
     @Test
     public void testText() {
-        if (isSliceDisabled) {
-            return;
-        }
+        assumeFalse(isSliceDisabled);
         Uri uri = BASE_URI.buildUpon().appendPath("text").build();
         Slice s = mSliceManager.bindSlice(uri,
                 Collections.emptySet());
@@ -121,9 +114,7 @@
 
     @Test
     public void testIcon() {
-        if (isSliceDisabled) {
-            return;
-        }
+        assumeFalse(isSliceDisabled);
         Uri uri = BASE_URI.buildUpon().appendPath("icon").build();
         Slice s = mSliceManager.bindSlice(uri,
                 Collections.emptySet());
@@ -138,9 +129,7 @@
 
     @Test
     public void testAction() {
-        if (isSliceDisabled) {
-            return;
-        }
+        assumeFalse(isSliceDisabled);
         sFlag = false;
         CountDownLatch latch = new CountDownLatch(1);
         BroadcastReceiver receiver = new BroadcastReceiver() {
@@ -175,9 +164,7 @@
 
     @Test
     public void testInt() {
-        if (isSliceDisabled) {
-            return;
-        }
+        assumeFalse(isSliceDisabled);
         Uri uri = BASE_URI.buildUpon().appendPath("int").build();
         Slice s = mSliceManager.bindSlice(uri, Collections.emptySet());
         assertEquals(uri, s.getUri());
@@ -190,9 +177,7 @@
 
     @Test
     public void testTimestamp() {
-        if (isSliceDisabled) {
-            return;
-        }
+        assumeFalse(isSliceDisabled);
         Uri uri = BASE_URI.buildUpon().appendPath("timestamp").build();
         Slice s = mSliceManager.bindSlice(uri,
                 Collections.emptySet());
@@ -206,9 +191,7 @@
 
     @Test
     public void testHints() {
-        if (isSliceDisabled) {
-            return;
-        }
+        assumeFalse(isSliceDisabled);
         // Note this tests that hints are propagated through to the client but not that any specific
         // hints have any effects.
         Uri uri = BASE_URI.buildUpon().appendPath("hints").build();
@@ -223,9 +206,7 @@
 
     @Test
     public void testHasHints() {
-        if (isSliceDisabled) {
-            return;
-        }
+        assumeFalse(isSliceDisabled);
         Uri uri = BASE_URI.buildUpon().appendPath("hints").build();
         Slice s = mSliceManager.bindSlice(uri, Collections.emptySet());
 
@@ -235,9 +216,7 @@
 
     @Test
     public void testBundle() {
-        if (isSliceDisabled) {
-            return;
-        }
+        assumeFalse(isSliceDisabled);
         Uri uri = BASE_URI.buildUpon().appendPath("bundle").build();
         Slice s = mSliceManager.bindSlice(uri, Collections.emptySet());
         assertEquals(uri, s.getUri());
@@ -252,9 +231,7 @@
 
     @Test
     public void testGetDescendants() {
-        if (isSliceDisabled) {
-            return;
-        }
+        assumeFalse(isSliceDisabled);
         Collection<Uri> allUris = mSliceManager.getSliceDescendants(BASE_URI);
         assertEquals(SliceProvider.PATHS.length, allUris.size());
         Iterator<Uri> it = allUris.iterator();
@@ -268,9 +245,7 @@
 
     @Test
     public void testGetSliceSpec() {
-        if (isSliceDisabled) {
-            return;
-        }
+        assumeFalse(isSliceDisabled);
         Uri uri = BASE_URI.buildUpon().appendPath("spec").build();
         Slice s = mSliceManager.bindSlice(uri, Collections.emptySet());
         assertEquals(new SliceSpec(SliceProvider.SPEC_TYPE, SliceProvider.SPEC_REV), s.getSpec());
diff --git a/tests/tests/slice/src/android/slice/cts/SliceManagerTest.java b/tests/tests/slice/src/android/slice/cts/SliceManagerTest.java
index 1e5c718..135c67a 100644
--- a/tests/tests/slice/src/android/slice/cts/SliceManagerTest.java
+++ b/tests/tests/slice/src/android/slice/cts/SliceManagerTest.java
@@ -16,6 +16,7 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeFalse;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
@@ -60,9 +61,7 @@
 
     @Before
     public void setup() {
-        if (isSliceDisabled) {
-            return;
-        }
+        assumeFalse(isSliceDisabled);
         LocalSliceProvider.sProxy = mock(SliceProvider.class);
         try {
             mSliceManager.unpinSlice(BASE_URI);
@@ -83,9 +82,7 @@
 
     @Test
     public void testPinSlice() throws Exception {
-        if (isSliceDisabled) {
-            return;
-        }
+        assumeFalse(isSliceDisabled);
         mSliceManager.pinSlice(BASE_URI, Collections.emptySet());
 
         verify(LocalSliceProvider.sProxy, timeout(2000)).onSlicePinned(eq(BASE_URI));
@@ -93,9 +90,7 @@
 
     @Test
     public void testUnpinSlice() throws Exception {
-        if (isSliceDisabled) {
-            return;
-        }
+        assumeFalse(isSliceDisabled);
         mSliceManager.pinSlice(BASE_URI, Collections.emptySet());
 
         verify(LocalSliceProvider.sProxy, timeout(2000)).onSlicePinned(eq(BASE_URI));
@@ -107,9 +102,7 @@
 
     @Test
     public void testPinList() {
-        if (isSliceDisabled) {
-            return;
-        }
+        assumeFalse(isSliceDisabled);
         Uri uri = BASE_URI;
         Uri longerUri = uri.buildUpon().appendPath("something").build();
         try {
@@ -129,9 +122,7 @@
 
     @Test
     public void testMapIntentToUri() {
-        if (isSliceDisabled) {
-            return;
-        }
+        assumeFalse(isSliceDisabled);
         Intent intent = new Intent("android.slice.cts.action.TEST_ACTION");
         intent.setPackage("android.slice.cts");
         intent.putExtra("path", "intent");
@@ -148,9 +139,7 @@
 
     @Test
     public void testOnCreatePermissionSlice() {
-        if (isSliceDisabled) {
-            return;
-        }
+        assumeFalse(isSliceDisabled);
         LocalSliceProvider.sAnswer = invocation -> {
             throw new SecurityException("No slices allowed");
         };
diff --git a/tests/tests/slice/src/android/slice/cts/SlicePermissionsTest.java b/tests/tests/slice/src/android/slice/cts/SlicePermissionsTest.java
index c36e7c9..c3cf011 100644
--- a/tests/tests/slice/src/android/slice/cts/SlicePermissionsTest.java
+++ b/tests/tests/slice/src/android/slice/cts/SlicePermissionsTest.java
@@ -19,6 +19,7 @@
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assume.assumeFalse;
 
 import android.app.slice.SliceManager;
 import android.content.Context;
@@ -47,9 +48,7 @@
 
     @Before
     public void setup() throws NameNotFoundException {
-        if(isSliceDisabled) {
-          return;
-        }
+        assumeFalse(isSliceDisabled);
         mSliceManager = mContext.getSystemService(SliceManager.class);
         mTestPkg = mContext.getPackageName();
         mTestUid = mContext.getPackageManager().getPackageUid(mTestPkg, 0);
@@ -66,9 +65,7 @@
 
     @Test
     public void testGrant() {
-        if (isSliceDisabled) {
-            return;
-        }
+        assumeFalse(isSliceDisabled);
         assertEquals(PERMISSION_DENIED,
                 mSliceManager.checkSlicePermission(BASE_URI, mTestPid, mTestUid));
 
@@ -80,9 +77,7 @@
 
     @Test
     public void testGrantParent() {
-        if (isSliceDisabled) {
-            return;
-        }
+        assumeFalse(isSliceDisabled);
         Uri uri = BASE_URI.buildUpon()
                 .appendPath("something")
                 .build();
@@ -98,9 +93,7 @@
 
     @Test
     public void testGrantParentExpands() {
-        if (isSliceDisabled) {
-            return;
-        }
+        assumeFalse(isSliceDisabled);
         Uri uri = BASE_URI.buildUpon()
                 .appendPath("something")
                 .build();
@@ -127,9 +120,7 @@
 
     @Test
     public void testGrantChild() {
-        if (isSliceDisabled) {
-            return;
-        }
+        assumeFalse(isSliceDisabled);
         Uri uri = BASE_URI.buildUpon()
                 .appendPath("something")
                 .build();
@@ -146,9 +137,7 @@
 
     @Test
     public void testRevoke() {
-        if (isSliceDisabled) {
-            return;
-        }
+        assumeFalse(isSliceDisabled);
         assertEquals(PERMISSION_DENIED,
                 mSliceManager.checkSlicePermission(BASE_URI, mTestPid, mTestUid));
 
@@ -165,9 +154,7 @@
 
     @Test
     public void testRevokeParent() {
-        if (isSliceDisabled) {
-            return;
-        }
+        assumeFalse(isSliceDisabled);
         Uri uri = BASE_URI.buildUpon()
                 .appendPath("something")
                 .build();
@@ -188,9 +175,7 @@
 
     @Test
     public void testRevokeChild() {
-        if (isSliceDisabled) {
-            return;
-        }
+        assumeFalse(isSliceDisabled);
         Uri uri = BASE_URI.buildUpon()
                 .appendPath("something")
                 .build();
diff --git a/tests/tests/slice/src/android/slice/cts/SliceProviderTest.java b/tests/tests/slice/src/android/slice/cts/SliceProviderTest.java
index 2a2e8e4..b890447 100644
--- a/tests/tests/slice/src/android/slice/cts/SliceProviderTest.java
+++ b/tests/tests/slice/src/android/slice/cts/SliceProviderTest.java
@@ -16,6 +16,10 @@
 
 package android.slice.cts;
 
+import android.content.pm.PackageManager;
+import androidx.test.InstrumentationRegistry;
+import android.content.Context;
+
 import android.app.slice.Slice;
 import android.app.slice.SliceSpec;
 import android.content.ContentResolver;
@@ -32,6 +36,8 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import static org.junit.Assume.assumeFalse;
+
 @RunWith(AndroidJUnit4.class)
 public class SliceProviderTest {
 
@@ -43,6 +49,8 @@
             "content://" + VALID_AUTHORITY + ACTION_BLUETOOTH;
     private static final String SHADY_ACTION_URI_STRING =
             "content://" + SUSPICIOUS_AUTHORITY + ACTION_BLUETOOTH;
+    private final Context mContext = InstrumentationRegistry.getContext();
+    private boolean isSliceDisabled = mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_SLICES_DISABLED);
 
     @Rule
     public ActivityTestRule<Launcher> mLauncherActivityTestRule = new ActivityTestRule<>(Launcher.class);
@@ -60,6 +68,7 @@
 
     @Test
     public void testCallSliceUri_ValidAuthority() {
+        assumeFalse(isSliceDisabled);
         doQuery(validActionUri);
     }
 
diff --git a/tests/tests/telecom/src/android/telecom/cts/IncomingCallTest.java b/tests/tests/telecom/src/android/telecom/cts/IncomingCallTest.java
index 4c579ed..627ea62 100644
--- a/tests/tests/telecom/src/android/telecom/cts/IncomingCallTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/IncomingCallTest.java
@@ -16,14 +16,19 @@
 
 package android.telecom.cts;
 
+import static android.media.AudioAttributes.USAGE_NOTIFICATION_RINGTONE;
 import static android.telecom.cts.TestUtils.COMPONENT;
 import static android.telecom.cts.TestUtils.PACKAGE;
+import static android.telecom.cts.TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS;
 import static android.telephony.TelephonyManager.CALL_STATE_RINGING;
 
 import android.content.ComponentName;
+import android.media.AudioManager;
+import android.media.AudioPlaybackConfiguration;
 import android.net.Uri;
 import android.os.Bundle;
-import android.provider.Telephony;
+import android.os.Handler;
+import android.os.Looper;
 import android.telecom.Call;
 import android.telecom.Connection;
 import android.telecom.ConnectionRequest;
@@ -31,9 +36,12 @@
 import android.telecom.TelecomManager;
 import android.telephony.PhoneStateListener;
 
+import java.util.ArrayList;
 import java.util.Collection;
+import java.util.List;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.Executor;
+import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.TimeUnit;
 
 /**
@@ -110,6 +118,45 @@
     }
 
     /**
+     * This test verifies that when a default dialer is incapable of playing a ringtone that the
+     * platform still plays a ringtone.
+     * <p>
+     * Given that the default {@link MockInCallService} defined in the CTS tests does not declare
+     * {@link TelecomManager#METADATA_IN_CALL_SERVICE_RINGING}, we expect the Telecom framework to
+     * play a ringtone for an incoming call.
+     * @throws Exception
+     */
+    public void testRingOnIncomingCall() throws Exception {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+        LinkedBlockingQueue<Boolean> queue = new LinkedBlockingQueue(1);
+        setupConnectionService(null, FLAG_REGISTER | FLAG_ENABLE);
+        AudioManager audioManager = mContext.getSystemService(AudioManager.class);
+        AudioManager.AudioPlaybackCallback callback = new AudioManager.AudioPlaybackCallback() {
+            @Override
+            public void onPlaybackConfigChanged(List<AudioPlaybackConfiguration> configs) {
+                super.onPlaybackConfigChanged(configs);
+                boolean isPlayingRingtone = configs.stream()
+                        .anyMatch(c -> c.getAudioAttributes().getUsage()
+                                == USAGE_NOTIFICATION_RINGTONE);
+                if (isPlayingRingtone && queue.isEmpty()) {
+                    queue.add(isPlayingRingtone);
+                }
+            }
+        };
+        audioManager.registerAudioPlaybackCallback(callback, new Handler(Looper.getMainLooper()));
+        Uri testNumber = createTestNumber();
+        addAndVerifyNewIncomingCall(testNumber, null);
+        verifyConnectionForIncomingCall();
+        verifyPhoneStateListenerCallbacksForCall(CALL_STATE_RINGING,
+                testNumber.getSchemeSpecificPart());
+        Boolean ringing = queue.poll(WAIT_FOR_STATE_CHANGE_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+        assertTrue("Telecom should have played a ringtone.", ringing);
+        audioManager.unregisterAudioPlaybackCallback(callback);
+    }
+
+    /**
      * Tests to be sure that new incoming calls can only be added using a valid PhoneAccountHandle
      * (b/26864502). If a PhoneAccount has not been registered for the PhoneAccountHandle, then
      * a SecurityException will be thrown.
diff --git a/tests/tests/telecom/src/android/telecom/cts/OutgoingCallTest.java b/tests/tests/telecom/src/android/telecom/cts/OutgoingCallTest.java
index 90a2e1b..8b2ff44 100644
--- a/tests/tests/telecom/src/android/telecom/cts/OutgoingCallTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/OutgoingCallTest.java
@@ -16,16 +16,21 @@
 
 package android.telecom.cts;
 
+import static android.telecom.Call.STATE_SELECT_PHONE_ACCOUNT;
+
 import android.content.Context;
 import android.media.AudioManager;
 import android.net.Uri;
 import android.os.Bundle;
+import android.telecom.Call;
 import android.telecom.CallAudioState;
 import android.telecom.Connection;
 import android.telecom.TelecomManager;
 import android.telephony.PhoneStateListener;
 import android.telephony.TelephonyManager;
 
+import com.android.compatibility.common.util.SystemUtil;
+
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.Executor;
 import java.util.concurrent.TimeUnit;
@@ -195,4 +200,34 @@
         assertEquals(TestUtils.TEST_PHONE_ACCOUNT_HANDLE_2, conn.getPhoneAccountHandle());
         conn.onDisconnect();
     }
+
+    public void testAccountSelectionAvailable() throws Exception {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        CountDownLatch latch = new CountDownLatch(1);
+        mInCallCallbacks = new MockInCallService.InCallServiceCallbacks() {
+            @Override
+            public void onCallAdded(Call call, int numCalls) {
+                if (call.getState() == STATE_SELECT_PHONE_ACCOUNT) {
+                    latch.countDown();
+                }
+            }
+        };
+        MockInCallService.setCallbacks(mInCallCallbacks);
+
+        mTelecomManager.registerPhoneAccount(TestUtils.TEST_PHONE_ACCOUNT);
+        TestUtils.enablePhoneAccount(getInstrumentation(), TestUtils.TEST_PHONE_ACCOUNT_HANDLE);
+        mTelecomManager.registerPhoneAccount(TestUtils.TEST_PHONE_ACCOUNT_2);
+        TestUtils.enablePhoneAccount(getInstrumentation(), TestUtils.TEST_PHONE_ACCOUNT_HANDLE_2);
+        SystemUtil.runWithShellPermissionIdentity(() -> {
+            mTelecomManager.setUserSelectedOutgoingPhoneAccount(null);
+        });
+
+        Uri testNumber = createTestNumber();
+        mTelecomManager.placeCall(testNumber, null);
+
+        assertTrue(latch.await(TestUtils.WAIT_FOR_CALL_ADDED_TIMEOUT_S, TimeUnit.SECONDS));
+    }
 }
diff --git a/tests/tests/telephony/current/EmbmsMiddlewareTestApp/src/android/telephony/cts/embmstestapp/CtsDownloadService.java b/tests/tests/telephony/current/EmbmsMiddlewareTestApp/src/android/telephony/cts/embmstestapp/CtsDownloadService.java
index 30447b8..8a186c9 100644
--- a/tests/tests/telephony/current/EmbmsMiddlewareTestApp/src/android/telephony/cts/embmstestapp/CtsDownloadService.java
+++ b/tests/tests/telephony/current/EmbmsMiddlewareTestApp/src/android/telephony/cts/embmstestapp/CtsDownloadService.java
@@ -67,6 +67,7 @@
     public static final String METHOD_INITIALIZE = "initialize";
     public static final String METHOD_REQUEST_UPDATE_FILE_SERVICES =
             "requestUpdateFileServices";
+    public static final String METHOD_ADD_SERVICE_ANNOUNCEMENT = "addServiceAnnouncementFile";
     public static final String METHOD_SET_TEMP_FILE_ROOT = "setTempFileRootDirectory";
     public static final String METHOD_RESET_DOWNLOAD_KNOWLEDGE = "resetDownloadKnowledge";
     public static final String METHOD_GET_DOWNLOAD_STATUS = "getDownloadStatus";
@@ -82,6 +83,7 @@
     public static final String ARGUMENT_DOWNLOAD_REQUEST = "downloadRequest";
     public static final String ARGUMENT_FILE_INFO = "fileInfo";
     public static final String ARGUMENT_RESULT_CODE = "resultCode";
+    public static final String ARGUMENT_SERVICE_ANNOUNCEMENT_FILE = "serviceAnnouncementFile";
 
     public static final String CONTROL_INTERFACE_ACTION =
             "android.telephony.cts.embmstestapp.ACTION_CONTROL_MIDDLEWARE";
@@ -256,6 +258,16 @@
         }
 
         @Override
+        public int addServiceAnnouncementFile(int subscriptionId, byte[] announcementFile) {
+            Bundle b = new Bundle();
+            b.putString(METHOD_NAME, METHOD_ADD_SERVICE_ANNOUNCEMENT);
+            b.putInt(ARGUMENT_SUBSCRIPTION_ID, subscriptionId);
+            b.putByteArray(ARGUMENT_SERVICE_ANNOUNCEMENT_FILE, announcementFile);
+            mReceivedCalls.add(b);
+            return MbmsErrors.SUCCESS;
+        }
+
+        @Override
         public int cancelDownload(DownloadRequest request) {
             Bundle b = new Bundle();
             b.putString(METHOD_NAME, METHOD_CANCEL_DOWNLOAD);
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 a992b9b..65b2ddb 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/CellInfoTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/CellInfoTest.java
@@ -382,30 +382,32 @@
     private void verifyCellIdentityCdma(CellIdentityCdma cdma, boolean isRegistered) {
         int networkId = cdma.getNetworkId();
         assertTrue("getNetworkId() out of range [0,65535], networkId=" + networkId,
-                networkId == Integer.MAX_VALUE || (networkId >= 0 && networkId <= NETWORK_ID));
+                networkId == CellInfo.UNAVAILABLE || (networkId >= 0 && networkId <= NETWORK_ID));
 
         int systemId = cdma.getSystemId();
         assertTrue("getSystemId() out of range [0,32767], systemId=" + systemId,
-                systemId == Integer.MAX_VALUE || (systemId >= 0 && systemId <= SYSTEM_ID));
+                systemId == CellInfo.UNAVAILABLE || (systemId >= 0 && systemId <= SYSTEM_ID));
 
         int basestationId = cdma.getBasestationId();
         assertTrue("getBasestationId() out of range [0,65535], basestationId=" + basestationId,
-                basestationId == Integer.MAX_VALUE
+                basestationId == CellInfo.UNAVAILABLE
                         || (basestationId >= 0 && basestationId <= BASESTATION_ID));
 
         int longitude = cdma.getLongitude();
         assertTrue("getLongitude() out of range [-2592000,2592000], longitude=" + longitude,
-                longitude == Integer.MAX_VALUE
+                longitude == CellInfo.UNAVAILABLE
                         || (longitude >= -LONGITUDE && longitude <= LONGITUDE));
 
         int latitude = cdma.getLatitude();
         assertTrue("getLatitude() out of range [-1296000,1296000], latitude=" + latitude,
-                latitude == Integer.MAX_VALUE || (latitude >= -LATITUDE && latitude <= LATITUDE));
+                latitude == CellInfo.UNAVAILABLE
+                        || (latitude >= -LATITUDE && latitude <= LATITUDE));
 
         if (isRegistered) {
-            assertTrue("SID is required for registered cells", systemId != Integer.MAX_VALUE);
-            assertTrue("NID is required for registered cells", networkId != Integer.MAX_VALUE);
-            assertTrue("BSID is required for registered cells", basestationId != Integer.MAX_VALUE);
+            assertTrue("SID is required for registered cells", systemId != CellInfo.UNAVAILABLE);
+            assertTrue("NID is required for registered cells", networkId != CellInfo.UNAVAILABLE);
+            assertTrue("BSID is required for registered cells",
+                    basestationId != CellInfo.UNAVAILABLE);
         }
 
         verifyCellIdentityCdmaLocationSanitation(cdma);
@@ -458,7 +460,7 @@
 
         int evdoSnr = cdma.getEvdoSnr();
         assertTrue("getEvdoSnr() out of range [0,8], evdoSnr=" + evdoSnr,
-                (evdoSnr == Integer.MAX_VALUE) || (evdoSnr >= 0 && evdoSnr <= 8));
+                (evdoSnr == CellInfo.UNAVAILABLE) || (evdoSnr >= 0 && evdoSnr <= 8));
     }
 
     private void verifyCellSignalStrengthCdmaParcel(CellSignalStrengthCdma cdma) {
@@ -472,9 +474,9 @@
 
     private static void verifyPlmnInfo(String mccStr, String mncStr, int mcc, int mnc) {
         // If either int value is invalid, all values must be invalid
-        if (mcc == Integer.MAX_VALUE) {
+        if (mcc == CellInfo.UNAVAILABLE) {
             assertTrue("MNC and MNC must always be reported together.",
-                    mnc == Integer.MAX_VALUE && mccStr == null && mncStr == null);
+                    mnc == CellInfo.UNAVAILABLE && mccStr == null && mncStr == null);
             return;
         }
 
@@ -571,7 +573,7 @@
 
         // If the cell is reported as registered, then all the logical cell info must be reported
         if (isRegistered) {
-            assertTrue("TAC is required for registered cells", tac != Integer.MAX_VALUE);
+            assertTrue("TAC is required for registered cells", tac != CellInfo.UNAVAILABLE);
             assertTrue("MCC is required for registered cells", nr.getMccString() != null);
             assertTrue("MNC is required for registered cells", nr.getMncString() != null);
         }
@@ -596,17 +598,18 @@
 
         assertTrue("getCsiRsrp() out of range [-140, -44] | Integer.MAX_INTEGER, csiRsrp = "
                         + csiRsrp, -140 <= csiRsrp && csiRsrp <= -44
-                || csiRsrp == Integer.MAX_VALUE);
+                || csiRsrp == CellInfo.UNAVAILABLE);
         assertTrue("getCsiRsrq() out of range [-20, -3] | Integer.MAX_INTEGER, csiRsrq = "
-                + csiRsrq, -20 <= csiRsrq && csiRsrq <= -3 || csiRsrq == Integer.MAX_VALUE);
+                + csiRsrq, -20 <= csiRsrq && csiRsrq <= -3 || csiRsrq == CellInfo.UNAVAILABLE);
         assertTrue("getCsiSinr() out of range [-23, 40] | Integer.MAX_INTEGER, csiSinr = "
-                + csiSinr, -23 <= csiSinr && csiSinr <= 40 || csiSinr == Integer.MAX_VALUE);
+                + csiSinr, -23 <= csiSinr && csiSinr <= 40 || csiSinr == CellInfo.UNAVAILABLE);
         assertTrue("getSsRsrp() out of range [-140, -44] | Integer.MAX_INTEGER, ssRsrp = "
-                        + ssRsrp, -140 <= ssRsrp && ssRsrp <= -44 || ssRsrp == Integer.MAX_VALUE);
+                        + ssRsrp, -140 <= ssRsrp && ssRsrp <= -44
+                || ssRsrp == CellInfo.UNAVAILABLE);
         assertTrue("getSsRsrq() out of range [-20, -3] | Integer.MAX_INTEGER, ssRsrq = "
-                + ssRsrq, -20 <= ssRsrq && ssRsrq <= -3 || ssRsrq == Integer.MAX_VALUE);
+                + ssRsrq, -20 <= ssRsrq && ssRsrq <= -3 || ssRsrq == CellInfo.UNAVAILABLE);
         assertTrue("getSsSinr() out of range [-23, 40] | Integer.MAX_INTEGER, ssSinr = "
-                + ssSinr, -23 <= ssSinr && ssSinr <= 40 || ssSinr == Integer.MAX_VALUE);
+                + ssSinr, -23 <= ssSinr && ssSinr <= 40 || ssSinr == CellInfo.UNAVAILABLE);
     }
 
     private void verifyCellInfoLteParcelandHashcode(CellInfoLte lte) {
@@ -625,23 +628,23 @@
         // Cell identity ranges from 0 to 268435456.
         int ci = lte.getCi();
         assertTrue("getCi() out of range [0,268435456], ci=" + ci,
-                (ci == Integer.MAX_VALUE) || (ci >= 0 && ci <= CI));
+                (ci == CellInfo.UNAVAILABLE) || (ci >= 0 && ci <= CI));
 
         // Verify LTE physical cell id information.
         // Only physical cell id is available for LTE neighbor.
         int pci = lte.getPci();
         // Physical cell id should be within [0, 503].
         assertTrue("getPci() out of range [0, 503], pci=" + pci,
-                (pci== Integer.MAX_VALUE) || (pci >= 0 && pci <= PCI));
+                (pci == CellInfo.UNAVAILABLE) || (pci >= 0 && pci <= PCI));
 
         // Tracking area code ranges from 0 to 65535.
         int tac = lte.getTac();
         assertTrue("getTac() out of range [0,65535], tac=" + tac,
-                (tac == Integer.MAX_VALUE) || (tac >= 0 && tac <= TAC));
+                (tac == CellInfo.UNAVAILABLE) || (tac >= 0 && tac <= TAC));
 
         int bw = lte.getBandwidth();
         assertTrue("getBandwidth out of range [1400, 20000] | Integer.Max_Value, bw=",
-                bw == Integer.MAX_VALUE || bw >= BANDWIDTH_LOW && bw <= BANDWIDTH_HIGH);
+                bw == CellInfo.UNAVAILABLE || bw >= BANDWIDTH_LOW && bw <= BANDWIDTH_HIGH);
 
         int earfcn = lte.getEarfcn();
         // Reference 3GPP 36.101 Table 5.7.3-1
@@ -650,7 +653,7 @@
         // out of the range of the narrowest 1.4Mhz deployment.
         int minEarfcn = 7;
         int maxEarfcn = EARFCN_MAX - 7;
-        if (bw != Integer.MAX_VALUE) {
+        if (bw != CellInfo.UNAVAILABLE) {
             // The number of channels used by a cell is equal to the cell bandwidth divided
             // by the channel raster (bandwidth of a channel). The center channel is the channel
             // the n/2-th channel where n is the number of channels, and since it is the center
@@ -664,7 +667,7 @@
         }
         assertTrue(
                 "getEarfcn() out of range [" + minEarfcn + "," + maxEarfcn + "], earfcn=" + earfcn,
-                earfcn == Integer.MAX_VALUE || (earfcn >= minEarfcn && earfcn <= maxEarfcn));
+                earfcn == CellInfo.UNAVAILABLE || (earfcn >= minEarfcn && earfcn <= maxEarfcn));
 
         if (mRadioHalVersion >= RADIO_HAL_VERSION_1_5) {
             int[] bands = lte.getBands();
@@ -690,12 +693,12 @@
 
         // If the cell is reported as registered, then all the logical cell info must be reported
         if (isRegistered) {
-            assertTrue("TAC is required for registered cells", tac != Integer.MAX_VALUE);
-            assertTrue("CID is required for registered cells", ci != Integer.MAX_VALUE);
+            assertTrue("TAC is required for registered cells", tac != CellInfo.UNAVAILABLE);
+            assertTrue("CID is required for registered cells", ci != CellInfo.UNAVAILABLE);
             assertTrue("MCC is required for registered cells",
-                    lte.getMccString() != null || lte.getMcc() != Integer.MAX_VALUE);
+                    lte.getMccString() != null || lte.getMcc() != CellInfo.UNAVAILABLE);
             assertTrue("MNC is required for registered cells",
-                    lte.getMncString() != null || lte.getMnc() != Integer.MAX_VALUE);
+                    lte.getMncString() != null || lte.getMnc() != CellInfo.UNAVAILABLE);
         }
     }
 
@@ -719,32 +722,32 @@
     private void verifyCellSignalStrengthLte(CellSignalStrengthLte cellSignalStrengthLte) {
         verifyRssiDbm(cellSignalStrengthLte.getDbm());
 
-        //Integer.MAX_VALUE indicates an unavailable field
+        //ICellInfo.UNAVAILABLE indicates an unavailable field
         int rsrp = cellSignalStrengthLte.getRsrp();
         // RSRP is being treated as RSSI in LTE (they are similar but not quite right)
         // so reusing the constants here.
         assertTrue("getRsrp() out of range, rsrp=" + rsrp, rsrp >= MIN_RSRP && rsrp <= MAX_RSRP);
 
         int rsrq = cellSignalStrengthLte.getRsrq();
-        assertTrue("getRsrq() out of range | Integer.MAX_VALUE, rsrq=" + rsrq,
-            rsrq == Integer.MAX_VALUE || (rsrq >= MIN_RSRQ && rsrq <= MAX_RSRQ));
+        assertTrue("getRsrq() out of range | CellInfo.UNAVAILABLE, rsrq=" + rsrq,
+                rsrq == CellInfo.UNAVAILABLE || (rsrq >= MIN_RSRQ && rsrq <= MAX_RSRQ));
 
         int rssi = cellSignalStrengthLte.getRssi();
-        assertTrue("getRssi() out of range [-113, -51] or Integer.MAX_VALUE if unknown, rssi="
+        assertTrue("getRssi() out of range [-113, -51] or CellInfo.UNAVAILABLE if unknown, rssi="
                 + rssi, rssi == CellInfo.UNAVAILABLE
                 || (rssi >= MIN_LTE_RSSI && rssi <= MAX_LTE_RSSI));
 
         int rssnr = cellSignalStrengthLte.getRssnr();
-        assertTrue("getRssnr() out of range | Integer.MAX_VALUE, rssnr=" + rssnr,
-            rssnr == Integer.MAX_VALUE || (rssnr >= MIN_RSSNR && rssnr <= MAX_RSSNR));
+        assertTrue("getRssnr() out of range | CellInfo.UNAVAILABLE, rssnr=" + rssnr,
+                rssnr == CellInfo.UNAVAILABLE || (rssnr >= MIN_RSSNR && rssnr <= MAX_RSSNR));
 
         int cqi = cellSignalStrengthLte.getCqi();
-        assertTrue("getCqi() out of range | Integer.MAX_VALUE, cqi=" + cqi,
-            cqi == Integer.MAX_VALUE || (cqi >= MIN_CQI && cqi <= MAX_CQI));
+        assertTrue("getCqi() out of range | CellInfo.UNAVAILABLE, cqi=" + cqi,
+                cqi == CellInfo.UNAVAILABLE || (cqi >= MIN_CQI && cqi <= MAX_CQI));
 
         int ta = cellSignalStrengthLte.getTimingAdvance();
-        assertTrue("getTimingAdvance() invalid [0-1282] | Integer.MAX_VALUE, ta=" + ta,
-                ta == Integer.MAX_VALUE || (ta >= 0 && ta <=1282));
+        assertTrue("getTimingAdvance() invalid [0-1282] | CellInfo.UNAVAILABLE, ta=" + ta,
+                ta == CellInfo.UNAVAILABLE || (ta >= 0 && ta <= 1282));
 
         int level = cellSignalStrengthLte.getLevel();
         assertTrue("getLevel() out of range [0,4], level=" + level, level >= 0 && level <= 4);
@@ -755,7 +758,8 @@
 
         int timingAdvance = cellSignalStrengthLte.getTimingAdvance();
         assertTrue("getTimingAdvance() out of range [0,1282], timingAdvance=" + timingAdvance,
-                timingAdvance == Integer.MAX_VALUE || (timingAdvance >= 0 && timingAdvance <= 1282));
+                timingAdvance == CellInfo.UNAVAILABLE
+                        || (timingAdvance >= 0 && timingAdvance <= 1282));
 
         if (mRadioHalVersion >= RADIO_HAL_VERSION_1_2) {
             assertTrue("RSRP Must be valid for LTE",
@@ -797,17 +801,17 @@
 
         int lac = wcdma.getLac();
         assertTrue("getLac() out of range [0, 65535], lac=" + lac,
-                (lac >= 0 && lac <= LAC) || lac == Integer.MAX_VALUE);
+                (lac >= 0 && lac <= LAC) || lac == CellInfo.UNAVAILABLE);
 
         int cid = wcdma.getCid();
         assertTrue("getCid() out of range [0, 268435455], cid=" + cid,
-                (cid >= 0 && cid <= CID_UMTS) || cid == Integer.MAX_VALUE);
+                (cid >= 0 && cid <= CID_UMTS) || cid == CellInfo.UNAVAILABLE);
 
         // Verify wcdma primary scrambling code information.
         // Primary scrambling code should be within [0, 511].
         int psc = wcdma.getPsc();
         assertTrue("getPsc() out of range [0, 511], psc=" + psc,
-                (psc >= 0 && psc <= PSC) || psc == Integer.MAX_VALUE);
+                (psc >= 0 && psc <= PSC) || psc == CellInfo.UNAVAILABLE);
 
         String mobileNetworkOperator = wcdma.getMobileNetworkOperator();
         assertTrue("getMobileNetworkOperator() out of range [0, 999999], mobileNetworkOperator="
@@ -830,12 +834,12 @@
 
         // If the cell is reported as registered, then all the logical cell info must be reported
         if (isRegistered) {
-            assertTrue("LAC is required for registered cells", lac != Integer.MAX_VALUE);
-            assertTrue("CID is required for registered cells", cid != Integer.MAX_VALUE);
+            assertTrue("LAC is required for registered cells", lac != CellInfo.UNAVAILABLE);
+            assertTrue("CID is required for registered cells", cid != CellInfo.UNAVAILABLE);
             assertTrue("MCC is required for registered cells",
-                    wcdma.getMccString() != null || wcdma.getMcc() != Integer.MAX_VALUE);
+                    wcdma.getMccString() != null || wcdma.getMcc() != CellInfo.UNAVAILABLE);
             assertTrue("MNC is required for registered cells",
-                    wcdma.getMncString() != null || wcdma.getMnc() != Integer.MAX_VALUE);
+                    wcdma.getMncString() != null || wcdma.getMnc() != CellInfo.UNAVAILABLE);
         }
 
         verifyCellIdentityWcdmaLocationSanitation(wcdma);
@@ -924,15 +928,15 @@
         // Local area code and cellid should be with [0, 65535].
         int lac = gsm.getLac();
         assertTrue("getLac() out of range [0, 65535], lac=" + lac,
-                lac == Integer.MAX_VALUE || (lac >= 0 && lac <= LAC));
+                lac == CellInfo.UNAVAILABLE || (lac >= 0 && lac <= LAC));
         int cid = gsm.getCid();
         assertTrue("getCid() out range [0, 65535], cid=" + cid,
-                cid== Integer.MAX_VALUE || (cid >= 0 && cid <= CID_GSM));
+                cid == CellInfo.UNAVAILABLE || (cid >= 0 && cid <= CID_GSM));
 
         int arfcn = gsm.getArfcn();
         // Reference 3GPP 45.005 Table 2-2
         assertTrue("getArfcn() out of range [0,1024], arfcn=" + arfcn,
-                arfcn == Integer.MAX_VALUE || (arfcn >= 0 && arfcn <= ARFCN));
+                arfcn == CellInfo.UNAVAILABLE || (arfcn >= 0 && arfcn <= ARFCN));
 
         String mobileNetworkOperator = gsm.getMobileNetworkOperator();
         assertTrue("getMobileNetworkOperator() out of range [0, 999999], mobileNetworkOperator="
@@ -950,12 +954,12 @@
 
         // If the cell is reported as registered, then all the logical cell info must be reported
         if (isRegistered) {
-            assertTrue("LAC is required for registered cells", lac != Integer.MAX_VALUE);
-            assertTrue("CID is required for registered cells", cid != Integer.MAX_VALUE);
+            assertTrue("LAC is required for registered cells", lac != CellInfo.UNAVAILABLE);
+            assertTrue("CID is required for registered cells", cid != CellInfo.UNAVAILABLE);
             assertTrue("MCC is required for registered cells",
-                    gsm.getMccString() != null || gsm.getMcc() != Integer.MAX_VALUE);
+                    gsm.getMccString() != null || gsm.getMcc() != CellInfo.UNAVAILABLE);
             assertTrue("MNC is required for registered cells",
-                    gsm.getMncString() != null || gsm.getMnc() != Integer.MAX_VALUE);
+                    gsm.getMncString() != null || gsm.getMnc() != CellInfo.UNAVAILABLE);
         }
 
         verifyCellIdentityGsmLocationSanitation(gsm);
@@ -985,8 +989,8 @@
         assertTrue("getLevel() out of range [0,4], level=" + level, level >= 0 && level <= 4);
 
         int ta = gsm.getTimingAdvance();
-        assertTrue("getTimingAdvance() out of range [0,219] | Integer.MAX_VALUE, ta=" + ta,
-                ta == Integer.MAX_VALUE || (ta >= 0 && ta <= 219));
+        assertTrue("getTimingAdvance() out of range [0,219] | CellInfo.UNAVAILABLE, ta=" + ta,
+                ta == CellInfo.UNAVAILABLE || (ta >= 0 && ta <= 219));
 
         assertEquals(gsm.getDbm(), gsm.getRssi());
 
@@ -1044,11 +1048,11 @@
 
         int lac = tdscdma.getLac();
         assertTrue("getLac() out of range [0, 65535], lac=" + lac,
-                (lac >= 0 && lac <= LAC) || lac == Integer.MAX_VALUE);
+                (lac >= 0 && lac <= LAC) || lac == CellInfo.UNAVAILABLE);
 
         int cid = tdscdma.getCid();
         assertTrue("getCid() out of range [0, 268435455], cid=" + cid,
-                (cid >= 0 && cid <= CID_UMTS) || cid == Integer.MAX_VALUE);
+                (cid >= 0 && cid <= CID_UMTS) || cid == CellInfo.UNAVAILABLE);
 
         // Verify tdscdma primary scrambling code information.
         // Primary scrambling code should be within [0, 511].
@@ -1076,8 +1080,8 @@
 
         // If the cell is reported as registered, then all the logical cell info must be reported
         if (isRegistered) {
-            assertTrue("LAC is required for registered cells", lac != Integer.MAX_VALUE);
-            assertTrue("CID is required for registered cells", cid != Integer.MAX_VALUE);
+            assertTrue("LAC is required for registered cells", lac != CellInfo.UNAVAILABLE);
+            assertTrue("CID is required for registered cells", cid != CellInfo.UNAVAILABLE);
             assertTrue("MCC is required for registered cells", tdscdma.getMccString() != null);
             assertTrue("MNC is required for registered cells", tdscdma.getMncString() != null);
         }
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/ModemActivityInfoTest.java b/tests/tests/telephony/current/src/android/telephony/cts/ModemActivityInfoTest.java
new file mode 100644
index 0000000..f0acc85
--- /dev/null
+++ b/tests/tests/telephony/current/src/android/telephony/cts/ModemActivityInfoTest.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.telephony.cts;
+
+import android.telephony.ModemActivityInfo;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+/**
+ * CTS test for ModemActivityInfo APIs
+ */
+public class ModemActivityInfoTest {
+    private static final String TAG = "ModemActivityInfoTest";
+
+    private static final int VALID_SLEEP_TIME_MS = 1;
+    private static final int VALID_IDLE_TIME_MS = 1;
+    private static final int VALID_RX_TIME_MS = 1;
+    private static final int[] VALID_TX_TIME_MS = {1, 1};
+
+    private static final int INVALID_SLEEP_TIME_MS = -1;
+    private static final int INVALID_IDLE_TIME_MS = -1;
+    private static final int INVALID_RX_TIME_MS = -1;
+    private static final int[] INVALID_TX_TIME_MS = {-1, 1};
+
+    @Test
+    public void testModemActivityInfoIsValid() {
+        ModemActivityInfo modemActivityInfo = new ModemActivityInfo(0, VALID_SLEEP_TIME_MS,
+                VALID_IDLE_TIME_MS, VALID_TX_TIME_MS, VALID_RX_TIME_MS);
+        assertTrue("ModemActivityInfo should be valid", modemActivityInfo.isValid());
+
+        modemActivityInfo = new ModemActivityInfo(0, INVALID_SLEEP_TIME_MS,
+                VALID_IDLE_TIME_MS, VALID_TX_TIME_MS, VALID_RX_TIME_MS);
+        assertFalse("ModemActivityInfo should be invalid because sleep time is invalid",
+                modemActivityInfo.isValid());
+
+        modemActivityInfo = new ModemActivityInfo(0, VALID_SLEEP_TIME_MS,
+                INVALID_IDLE_TIME_MS, VALID_TX_TIME_MS, VALID_RX_TIME_MS);
+        assertFalse("ModemActivityInfo should be invalid because idle time is invalid",
+                modemActivityInfo.isValid());
+
+        modemActivityInfo = new ModemActivityInfo(0, VALID_SLEEP_TIME_MS,
+                VALID_IDLE_TIME_MS, VALID_TX_TIME_MS, INVALID_RX_TIME_MS);
+        assertFalse("ModemActivityInfo should be invalid because receive time is invalid",
+                modemActivityInfo.isValid());
+
+        modemActivityInfo = new ModemActivityInfo(0, VALID_SLEEP_TIME_MS,
+                VALID_IDLE_TIME_MS, INVALID_TX_TIME_MS, INVALID_RX_TIME_MS);
+        assertFalse("ModemActivityInfo should be invalid because transmit time is invalid",
+                modemActivityInfo.isValid());
+    }
+}
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 ecb11ee..d6fd098 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
@@ -29,11 +29,12 @@
 import android.telephony.mbms.FileServiceInfo;
 import android.telephony.mbms.MbmsErrors;
 
+import org.junit.Test;
+
 import java.io.File;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
-import org.junit.Test;
 
 public class MbmsDownloadSessionTest extends MbmsDownloadTestBase {
 
@@ -90,6 +91,15 @@
     }
 
     @Test
+    public void testAddServiceAnnouncementFile() throws Exception {
+        byte[] sampleAnnouncementFile = "<xml></xml>".getBytes();
+        mDownloadSession.addServiceAnnouncementFile(sampleAnnouncementFile);
+        List<Bundle> addServiceAnnouncementCalls =
+                getMiddlewareCalls(CtsDownloadService.METHOD_ADD_SERVICE_ANNOUNCEMENT);
+        assertEquals(1, addServiceAnnouncementCalls.size());
+    }
+
+    @Test
     public void testSetTempFileDirectory() throws Exception {
         String tempFileDirName = "CTSTestDir";
         File tempFileRootDirectory = new File(mContext.getFilesDir(), tempFileDirName);
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 6899e42..c665116 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
@@ -1672,6 +1672,45 @@
         overrideCarrierConfig(null);
     }
 
+    @Test
+    public void testProvisioningManagerRcsProvisioningCaps() throws Exception {
+        if (!ImsUtils.shouldTestImsService()) {
+            return;
+        }
+
+        triggerFrameworkConnectToCarrierImsService();
+
+        PersistableBundle bundle = new PersistableBundle();
+        bundle.putBoolean(CarrierConfigManager.KEY_USE_RCS_PRESENCE_BOOL, true);
+        bundle.putBoolean(CarrierConfigManager.KEY_CARRIER_RCS_PROVISIONING_REQUIRED_BOOL, true);
+        overrideCarrierConfig(bundle);
+
+        ProvisioningManager provisioningManager =
+                ProvisioningManager.createForSubscriptionId(sTestSub);
+
+        final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
+        try {
+            automan.adoptShellPermissionIdentity();
+            boolean provisioningStatus = provisioningManager.getRcsProvisioningStatusForCapability(
+                    RCS_CAP_PRESENCE);
+            provisioningManager.setRcsProvisioningStatusForCapability(RCS_CAP_PRESENCE,
+                    !provisioningStatus);
+            // Make sure the change in provisioning status is correctly returned.
+            assertEquals(!provisioningStatus,
+                    provisioningManager.getRcsProvisioningStatusForCapability(RCS_CAP_PRESENCE));
+            // TODO: Enhance test to make sure the provisioning change is also sent to the
+            // ImsService
+
+            // set back to current status
+            provisioningManager.setRcsProvisioningStatusForCapability(RCS_CAP_PRESENCE,
+                    provisioningStatus);
+        } finally {
+            automan.dropShellPermissionIdentity();
+        }
+
+        overrideCarrierConfig(null);
+    }
+
     private void verifyIntKey(ProvisioningManager pm,
             LinkedBlockingQueue<Pair<Integer, Integer>> intQueue, int key, int value)
             throws Exception {
diff --git a/tests/tests/telephony2/AndroidTest.xml b/tests/tests/telephony2/AndroidTest.xml
index 3d3d476..e8454b6 100644
--- a/tests/tests/telephony2/AndroidTest.xml
+++ b/tests/tests/telephony2/AndroidTest.xml
@@ -19,7 +19,7 @@
     <option name="not-shardable" value="true" />
     <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" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_secondary_user" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
         <option name="test-file-name" value="CtsTelephony2TestCases.apk" />
diff --git a/tests/tests/telephonyprovider/AndroidTest.xml b/tests/tests/telephonyprovider/AndroidTest.xml
index 50892c3..d8bd082 100644
--- a/tests/tests/telephonyprovider/AndroidTest.xml
+++ b/tests/tests/telephonyprovider/AndroidTest.xml
@@ -20,7 +20,7 @@
     <!-- TelephonyProvider uses permissions not available to instant apps. -->
     <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
     <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
-    <option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_secondary_user" />
 
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/tests/tests/text/OWNERS b/tests/tests/text/OWNERS
index a163bf7..73d670f6 100644
--- a/tests/tests/text/OWNERS
+++ b/tests/tests/text/OWNERS
@@ -5,5 +5,5 @@
 nona@google.com
 clarabayarri@google.com
 nfuller@google.com
-tobiast@google.com
+ngeoffray@google.com
 vichang@google.com
diff --git a/tests/tests/view/src/android/view/cts/TextureViewCtsActivity.java b/tests/tests/view/src/android/view/cts/TextureViewCtsActivity.java
index 66b1539..7ab5143 100644
--- a/tests/tests/view/src/android/view/cts/TextureViewCtsActivity.java
+++ b/tests/tests/view/src/android/view/cts/TextureViewCtsActivity.java
@@ -19,6 +19,7 @@
 import static android.opengl.GLES20.GL_COLOR_BUFFER_BIT;
 import static android.opengl.GLES20.glClear;
 import static android.opengl.GLES20.glClearColor;
+import static android.opengl.GLES20.glFinish;
 
 import android.app.Activity;
 import android.content.pm.ActivityInfo;
@@ -258,6 +259,7 @@
         int surfaceUpdateCount = mSurfaceUpdatedCount;
         runOnGLThread(() -> {
             callback.drawFrame(mSurfaceWidth, mSurfaceHeight);
+            glFinish();
             if (!mEgl.eglSwapBuffers(mEglDisplay, mEglSurface)) {
                 throw new RuntimeException("Cannot swap buffers");
             }
diff --git a/tests/tests/widget/AndroidManifest.xml b/tests/tests/widget/AndroidManifest.xml
index e9c5ca1..c30c71c 100644
--- a/tests/tests/widget/AndroidManifest.xml
+++ b/tests/tests/widget/AndroidManifest.xml
@@ -345,7 +345,7 @@
 
         <activity android:name="android.widget.cts.TextViewCtsActivity"
                   android:label="TextViewCtsActivity"
-                  android:screenOrientation="nosensor"
+                  android:screenOrientation="locked"
                   android:windowSoftInputMode="stateAlwaysHidden">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
diff --git a/tests/tests/widget/src/android/widget/cts/ProgressBarTest.java b/tests/tests/widget/src/android/widget/cts/ProgressBarTest.java
index 1d3a5ed..7a512af 100644
--- a/tests/tests/widget/src/android/widget/cts/ProgressBarTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ProgressBarTest.java
@@ -38,7 +38,9 @@
 import android.graphics.PorterDuff;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
+import android.graphics.drawable.LayerDrawable;
 import android.os.Parcelable;
+import android.os.SystemClock;
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.animation.AccelerateDecelerateInterpolator;
@@ -48,6 +50,7 @@
 import android.widget.ProgressBar;
 import android.widget.cts.util.TestUtils;
 
+import androidx.test.InstrumentationRegistry;
 import androidx.test.annotation.UiThreadTest;
 import androidx.test.filters.SmallTest;
 import androidx.test.rule.ActivityTestRule;
@@ -696,6 +699,30 @@
         assertEquals(maxHeight, mProgressBar.getMaxHeight());
     }
 
+    @Test
+    public void testAnimationNotOverwriteNewProgress() throws Throwable {
+        mActivityRule.runOnUiThread(() -> {
+            mProgressBarHorizontal.setMin(0);
+            mProgressBarHorizontal.setMax(10);
+            mProgressBarHorizontal.setProgress(10, true);
+            mProgressBarHorizontal.setProgress(0, false);
+        });
+        // wait for completion of animation.
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+        SystemClock.sleep(80);
+        assertEquals(0, mProgressBarHorizontal.getProgress());
+        // test level of progress drawable
+        Drawable progressDrawable = mProgressBarHorizontal.getCurrentDrawable();
+        if (progressDrawable instanceof LayerDrawable) {
+            Drawable d = ((LayerDrawable) progressDrawable)
+                    .findDrawableByLayerId(android.R.id.progress);
+            if (d != null) {
+                progressDrawable = d;
+            }
+        }
+        assertEquals(0, progressDrawable.getLevel());
+    }
+
     /*
      * Mock class for ProgressBar to test protected methods
      */
diff --git a/tools/cts-device-info/jni/Android.bp b/tools/cts-device-info/jni/Android.bp
index c8b788f..bbf7f5b 100644
--- a/tools/cts-device-info/jni/Android.bp
+++ b/tools/cts-device-info/jni/Android.bp
@@ -18,6 +18,7 @@
         "CtsDeviceInfoJniOnLoad.cpp",
         "com_android_cts_deviceinfo_VulkanDeviceInfo.cpp",
     ],
+    header_libs: ["jni_headers"],
     static_libs: ["libvkjson_ndk"],
     shared_libs: [
         "libvulkan",