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",