Merge "media: test MediaCodec flush right after first frame"
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index e09cccd..7b9c427 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -37,6 +37,7 @@
tests/tests/widget/
common/device-side/util/
hostsidetests/stagedinstall/
+ hostsidetests/userspacereboot/
tests/tests/packageinstaller/atomicinstall/
ktlint_hook = ${REPO_ROOT}/prebuilts/ktlint/ktlint.py -f ${PREUPLOAD_FILES}
diff --git a/apps/CtsVerifier/res/layout/audio_frequency_mic_activity.xml b/apps/CtsVerifier/res/layout/audio_frequency_mic_activity.xml
index 272a9fc..a0a715f 100644
--- a/apps/CtsVerifier/res/layout/audio_frequency_mic_activity.xml
+++ b/apps/CtsVerifier/res/layout/audio_frequency_mic_activity.xml
@@ -32,6 +32,8 @@
android:orientation="vertical"
>
+ <include layout="@layout/audio_refmic_layout"/>
+
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
diff --git a/apps/CtsVerifier/res/layout/audio_frequency_speaker_activity.xml b/apps/CtsVerifier/res/layout/audio_frequency_speaker_activity.xml
index 435f5a7..a9aeafa 100644
--- a/apps/CtsVerifier/res/layout/audio_frequency_speaker_activity.xml
+++ b/apps/CtsVerifier/res/layout/audio_frequency_speaker_activity.xml
@@ -30,70 +30,72 @@
android:layout_height="wrap_content"
android:orientation="vertical">
- <TextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:scrollbars="vertical"
- android:gravity="bottom"
- android:id="@+id/info_text"
- android:text="@string/audio_frequency_speaker_instructions"/>
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical">
- <Button
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:id="@+id/audio_frequency_speaker_mic_ready_btn"
- android:text="@string/audio_frequency_speaker_mic_ready_btn"
- android:nextFocusForward="@+id/audio_frequency_speaker_test_btn"
- android:nextFocusDown="@+id/audio_frequency_speaker_test_btn"
- android:nextFocusRight="@+id/audio_frequency_speaker_test_btn" />
+ <include layout="@layout/audio_refmic_layout"/>
<TextView
- android:layout_width="wrap_content"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:text="@string/audio_frequency_speaker_usb_status"
- android:id="@+id/audio_frequency_speaker_usb_status"/>
+ android:scrollbars="vertical"
+ android:gravity="bottom"
+ android:id="@+id/info_text"
+ android:text="@string/audio_frequency_speaker_instructions"/>
<LinearLayout
- android:orientation="vertical"
android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <LinearLayout
- android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+ <Button
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:id="@+id/audio_frequency_speaker_layout">
- <Button
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/audio_frequency_speaker_test_btn"
- android:id="@+id/audio_frequency_speaker_test_btn"
- android:nextFocusForward="@+id/pass_button"
- android:nextFocusUp="@+id/audio_frequency_speaker_mic_ready_btn"
- android:nextFocusDown="@+id/pass_button"
- android:nextFocusLeft="@+id/audio_frequency_speaker_mic_ready_btn"
- android:nextFocusRight="@+id/pass_button" />
-
- <ProgressBar
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:id="@+id/audio_frequency_speaker_progress_bar"/>
- </LinearLayout>
+ android:id="@+id/audio_frequency_speaker_mic_ready_btn"
+ android:text="@string/audio_frequency_speaker_mic_ready_btn"
+ android:nextFocusForward="@+id/audio_frequency_speaker_test_btn"
+ android:nextFocusDown="@+id/audio_frequency_speaker_test_btn"
+ android:nextFocusRight="@+id/audio_frequency_speaker_test_btn" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="@string/audio_frequency_speaker_results_text"
- android:id="@+id/audio_frequency_speaker_results_text"/>
+ android:text="@string/audio_frequency_speaker_usb_status"
+ android:id="@+id/audio_frequency_speaker_usb_status"/>
+ <LinearLayout
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:id="@+id/audio_frequency_speaker_layout">
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/audio_frequency_speaker_test_btn"
+ android:id="@+id/audio_frequency_speaker_test_btn"
+ android:nextFocusForward="@+id/pass_button"
+ android:nextFocusUp="@+id/audio_frequency_speaker_mic_ready_btn"
+ android:nextFocusDown="@+id/pass_button"
+ android:nextFocusLeft="@+id/audio_frequency_speaker_mic_ready_btn"
+ android:nextFocusRight="@+id/pass_button" />
+
+ <ProgressBar
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:id="@+id/audio_frequency_speaker_progress_bar"/>
+ </LinearLayout>
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/audio_frequency_speaker_results_text"
+ android:id="@+id/audio_frequency_speaker_results_text"/>
+
+ </LinearLayout>
</LinearLayout>
- </LinearLayout>
- <include layout="@layout/pass_fail_buttons"/>
+ <include layout="@layout/pass_fail_buttons"/>
</LinearLayout>
</ScrollView>
diff --git a/apps/CtsVerifier/res/layout/audio_frequency_unprocessed_activity.xml b/apps/CtsVerifier/res/layout/audio_frequency_unprocessed_activity.xml
index d02ef0b..8032f93 100644
--- a/apps/CtsVerifier/res/layout/audio_frequency_unprocessed_activity.xml
+++ b/apps/CtsVerifier/res/layout/audio_frequency_unprocessed_activity.xml
@@ -23,6 +23,8 @@
android:layout_height="wrap_content"
android:orientation="vertical">
+ <include layout="@layout/audio_refmic_layout"/>
+
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
diff --git a/apps/CtsVerifier/res/layout/audio_frequency_voice_recognition_activity.xml b/apps/CtsVerifier/res/layout/audio_frequency_voice_recognition_activity.xml
index c6cd0cd..1ccd947 100644
--- a/apps/CtsVerifier/res/layout/audio_frequency_voice_recognition_activity.xml
+++ b/apps/CtsVerifier/res/layout/audio_frequency_voice_recognition_activity.xml
@@ -31,6 +31,8 @@
android:layout_height="wrap_content"
android:orientation="vertical">
+ <include layout="@layout/audio_refmic_layout"/>
+
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
diff --git a/apps/CtsVerifier/res/layout/audio_refmic_layout.xml b/apps/CtsVerifier/res/layout/audio_refmic_layout.xml
new file mode 100644
index 0000000..bd806a1
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/audio_refmic_layout.xml
@@ -0,0 +1,38 @@
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/refmic_test_question"/>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:soundEffectsEnabled="false"
+ android:text="@string/refmic_test_yes"
+ android:id="@+id/refmic_tests_yes_btn" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:soundEffectsEnabled="false"
+ android:text="@string/refmic_test_no"
+ android:id="@+id/refmic_tests_no_btn" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:soundEffectsEnabled="false"
+ android:text="@string/refmic_test_info"
+ android:id="@+id/refmic_test_info_btn" />
+ </LinearLayout>
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/uap_attribs_panel.xml b/apps/CtsVerifier/res/layout/uap_attribs_panel.xml
index 6c33d9f..b9c5d3e 100644
--- a/apps/CtsVerifier/res/layout/uap_attribs_panel.xml
+++ b/apps/CtsVerifier/res/layout/uap_attribs_panel.xml
@@ -9,6 +9,8 @@
android:layout_width="match_parent"
android:layout_height="wrap_content">
+ <include layout="@layout/uap_usb_confirm"/>
+
<include layout="@layout/uap_profile_header"/>
<LinearLayout
diff --git a/apps/CtsVerifier/res/layout/uap_buttons_panel.xml b/apps/CtsVerifier/res/layout/uap_buttons_panel.xml
index 4fdc757..355bfb6 100644
--- a/apps/CtsVerifier/res/layout/uap_buttons_panel.xml
+++ b/apps/CtsVerifier/res/layout/uap_buttons_panel.xml
@@ -9,6 +9,8 @@
android:layout_width="match_parent"
android:layout_height="wrap_content">
+ <include layout="@layout/uap_usb_confirm"/>
+
<include layout="@layout/uap_profile_header"/>
<LinearLayout
diff --git a/apps/CtsVerifier/res/layout/uap_play_panel.xml b/apps/CtsVerifier/res/layout/uap_play_panel.xml
index 2faa50c..30ef884 100644
--- a/apps/CtsVerifier/res/layout/uap_play_panel.xml
+++ b/apps/CtsVerifier/res/layout/uap_play_panel.xml
@@ -9,6 +9,8 @@
android:layout_width="match_parent"
android:layout_height="wrap_content">
+ <include layout="@layout/uap_usb_confirm"/>
+
<include layout="@layout/uap_profile_header"/>
<LinearLayout
diff --git a/apps/CtsVerifier/res/layout/uap_record_panel.xml b/apps/CtsVerifier/res/layout/uap_record_panel.xml
index 2deb738..a5bfcfc 100644
--- a/apps/CtsVerifier/res/layout/uap_record_panel.xml
+++ b/apps/CtsVerifier/res/layout/uap_record_panel.xml
@@ -9,6 +9,8 @@
android:layout_width="match_parent"
android:layout_height="wrap_content">
+ <include layout="@layout/uap_usb_confirm"/>
+
<include layout="@layout/uap_profile_header"/>
<LinearLayout
diff --git a/apps/CtsVerifier/res/layout/uap_usb_confirm.xml b/apps/CtsVerifier/res/layout/uap_usb_confirm.xml
new file mode 100644
index 0000000..ea73b88
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/uap_usb_confirm.xml
@@ -0,0 +1,38 @@
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/uap_test_question"/>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:soundEffectsEnabled="false"
+ android:text="@string/uap_test_yes"
+ android:id="@+id/uap_tests_yes_btn" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:soundEffectsEnabled="false"
+ android:text="@string/uap_test_no"
+ android:id="@+id/uap_tests_no_btn" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:soundEffectsEnabled="false"
+ android:text="@string/uap_test_info"
+ android:id="@+id/uap_test_info_btn" />
+ </LinearLayout>
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index 3df427f..4f9cc0a9 100755
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -2125,8 +2125,6 @@
<string name="nls_unblock_app">Please unblock the linked application and return here.</string>
<string name="nls_block_channel">Please block the linked notification channel and return here.</string>
<string name="nls_block_group">Please block the linked notification channel group and return here.</string>
- <string name="nls_cannot_enable_service">Please make sure you cannot enable
- \"Notification Listener for CTS Verifier\" and return here.</string>
<string name="nls_disable_service">Please disable \"Notification Listener for CTS Verifier\"
under Apps > Gear Icon > Special Access > Notification Access and return here.</string>
<string name="nls_start_settings">Launch Settings</string>
@@ -2158,11 +2156,10 @@
<string name="nas_note_missed_enqueued">Check that notification was not enqueued.</string>
<string name="cp_test">Condition Provider test</string>
<string name="cp_service_name">Condition Provider for CTS Verifier</string>
- <string name="cp_info">This test checks that on non-low ram a ConditionProviderService can be enabled
+ <string name="cp_info">This test checks that ConditionProviderService can be enabled
and disabled, and that once enabled the service is able to create, query, edit, and delete
- automatic zen rules. On low ram devices condition providers should not be bound.
+ automatic zen rules.
</string>
- <string name="cp_cannot_enable_service">Please make sure you cannot enable \"CTS Verifier\" under Do Not Disturb access and return here.</string>
<string name="cp_enable_service">Please enable \"CTS Verifier\" under Do Not Disturb access and return here.</string>
<string name="cp_disable_service">Please disable \"CTS Verifier\" under Do Not Disturb access and return here.</string>
<string name="cp_start_settings">Launch Settings</string>
@@ -5413,4 +5410,30 @@
6. Verify there is an action allowing user to clear/delete app. \n\n
7. Click Pass button if checks in step 5 and 6 passed, otherwise click Fail button.
</string>
+
+ <string name="uap_test_no">No</string>
+ <string name="uap_test_yes">Yes</string>
+ <string name="uap_test_info">Info</string>
+ <string name="uap_test_question">Does this device allow for the connectiono of a USB reference microphone?</string>
+ <string name="uap_mic_dlg_caption">USB Host Mode Audio Required</string>
+ <string name="uap_mic_dlg_text">This test requires a USB audio peripheral to be connected to the device.
+ If the device under test does not support USB Host Mode Audio (either because it does not have a
+ USB port, or USB Host Mode Audio has been removed from the OS) you can be granted a provisional
+ pass on this test by pressing the \"No\" button and indicating \"Test Pass\" at the bottom.\n
+ Note: Handheld devices supporting USB host mode MUST support USB audio class (CDD 7.7 .2/H-1-1)\n
+ Note: Devices declaring feature android.hardware.audio.pro MUST implement USB host mode (CDD 5.10 C-1-3) and if they omit a 4 conductor 3.5mm audio jack MUST support USB audio class (CDD 5.10 C-3-1)
+ </string>
+
+ <string name="refmic_test_no">No</string>
+ <string name="refmic_test_yes">Yes</string>
+ <string name="refmic_test_info">Info</string>
+ <string name="refmic_test_question">Does this device allow for the connection of a USB reference microphone?</string>
+ <string name="ref_mic_dlg_caption">Reference Mic Required</string>
+ <string name="ref_mic_dlg_text">This test requires a USB Reference Mic to be connected to the device.
+ If the device under test does not support USB Host Mode Audio (either because it does not have a
+ USB port, or USB Host Mode Audio has been removed from the OS) you can be granted a provisional
+ pass on this test by pressing the \"No\" button and indicating \"Test Pass\" at the bottom.\n
+ Note: Handheld devices supporting USB host mode MUST support USB audio class (CDD 7.7 .2/H-1-1)\n
+ Note: Devices declaring feature android.hardware.audio.pro MUST implement USB host mode (CDD 5.10 C-1-3) and if they omit a 4 conductor 3.5mm audio jack MUST support USB audio class (CDD 5.10 C-3-1)
+ </string>
</resources>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyActivity.java
index 3b97e37..ffc5f41 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyActivity.java
@@ -53,6 +53,65 @@
public int mMaxLevel = 0;
+ private OnBtnClickListener mBtnClickListener = new OnBtnClickListener();
+ //
+ // Common UI Handling
+ protected void connectRefMicUI() {
+ findViewById(R.id.refmic_tests_yes_btn).setOnClickListener(mBtnClickListener);
+ findViewById(R.id.refmic_tests_no_btn).setOnClickListener(mBtnClickListener);
+ findViewById(R.id.refmic_test_info_btn).setOnClickListener(mBtnClickListener);
+
+ enableTestUI(false);
+ }
+
+ private void showRefMicInfoDialog() {
+ new AlertDialog.Builder(this)
+ .setTitle(R.string.ref_mic_dlg_caption)
+ .setMessage(R.string.ref_mic_dlg_text)
+ .setPositiveButton(R.string.audio_general_ok, null)
+ .show();
+ }
+
+ private class OnBtnClickListener implements OnClickListener {
+ @Override
+ public void onClick(View v) {
+ switch (v.getId()) {
+ case R.id.refmic_tests_yes_btn:
+ recordRefMicStatus(true);
+ enableTestUI(true);
+ // disable test button so that they will now run the test(s)
+ getPassButton().setEnabled(false);
+ break;
+
+ case R.id.refmic_tests_no_btn:
+ recordRefMicStatus(false);
+ enableTestUI(false);
+ // Allow the user to "pass" the test.
+ getPassButton().setEnabled(true);
+ break;
+
+ case R.id.refmic_test_info_btn:
+ showRefMicInfoDialog();
+ break;
+ }
+ }
+ }
+
+ private void recordRefMicStatus(boolean has) {
+ getReportLog().addValue(
+ "User reported ref mic availability: ",
+ has ? 1.0 : 0,
+ ResultType.NEUTRAL,
+ ResultUnit.NONE);
+ }
+
+ //
+ // Overrides
+ //
+ void enableTestUI(boolean enable) {
+
+ }
+
public void setMaxLevel() {
AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
mMaxLevel = am.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyMicActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyMicActivity.java
index 129fb72..e296f86 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyMicActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyMicActivity.java
@@ -238,7 +238,22 @@
5.0, -50.0, /* start top,bottom value */
5.0, -50.0 /* stop top,bottom value */);
+ connectRefMicUI();
}
+
+ //
+ // Overrides
+ //
+ void enableTestUI(boolean enable) {
+ mButtonTestNoise.setEnabled(enable);
+ mButtonPlayNoise.setEnabled(enable);
+
+ mButtonTestUsbBackground.setEnabled(enable);
+
+ mButtonTestUsbNoise.setEnabled(enable);
+ mButtonPlayUsbNoise.setEnabled(enable);
+ }
+
private void playerToggleButton(int buttonId) {
if (playerIsPlaying()) {
playerStopAll();
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencySpeakerActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencySpeakerActivity.java
index 294e48d..f954b0c 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencySpeakerActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencySpeakerActivity.java
@@ -205,6 +205,15 @@
5.0, -50.0, /* start top,bottom value */
5.0, -50.0 /* stop top,bottom value */);
+ connectRefMicUI();
+ }
+
+ //
+ // Overrides
+ //
+ void enableTestUI(boolean enable) {
+ mLoopbackPlugReady.setEnabled(enable);
+ mTestButton.setEnabled(enable);
}
/**
@@ -212,8 +221,8 @@
*/
private void enableLayout(boolean enable) {
for (int i = 0; i < mLinearLayout.getChildCount(); i++) {
- View view = mLinearLayout.getChildAt(i);
- view.setEnabled(enable);
+ mLoopbackPlugReady.setEnabled(enable);
+ mTestButton.setEnabled(enable);
}
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyUnprocessedActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyUnprocessedActivity.java
index 009dd58..fb8460b 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyUnprocessedActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyUnprocessedActivity.java
@@ -292,6 +292,24 @@
mResultsMic = new Results("mic_response", mBands);
mResultsTone = new Results("tone_response", mBandsTone);
mResultsBack = new Results("background_response", mBandsBack);
+
+ connectRefMicUI();
+ }
+
+ //
+ // Overrides
+ //
+ void enableTestUI(boolean enable) {
+ mButtonTestTone.setEnabled(enable);
+ mButtonPlayTone.setEnabled(enable);
+
+ mButtonTestNoise.setEnabled(enable);
+ mButtonPlayNoise.setEnabled(enable);
+
+ mButtonTestUsbBackground.setEnabled(enable);
+
+ mButtonTestUsbNoise.setEnabled(enable);
+ mButtonPlayUsbNoise.setEnabled(enable);
}
private void playerToggleButton(int buttonId, int sourceId) {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyVoiceRecognitionActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyVoiceRecognitionActivity.java
index 4017973..efe666a 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyVoiceRecognitionActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyVoiceRecognitionActivity.java
@@ -329,6 +329,23 @@
mResultsMic = new Results("mic_response", BANDS_MIC);
mResultsTone = new Results("tone_response", BANDS_TONE);
mResultsBack = new Results("background_response", BANDS_BACKGROUND);
+ connectRefMicUI();
+ }
+
+ //
+ // Overrides
+ //
+ void enableTestUI(boolean enable) {
+ mButtonTestTone.setEnabled(enable);
+ mButtonPlayTone.setEnabled(enable);
+
+ mButtonTestNoise.setEnabled(enable);
+ mButtonPlayNoise.setEnabled(enable);
+
+ mButtonTestUsbBackground.setEnabled(enable);
+
+ mButtonTestUsbNoise.setEnabled(enable);
+ mButtonPlayUsbNoise.setEnabled(enable);
}
private void playerToggleButton(int buttonId, int sourceId) {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/RingerModeActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/RingerModeActivity.java
index fdb57fc..ebd2e6f 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/RingerModeActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/RingerModeActivity.java
@@ -108,10 +108,6 @@
@Override
protected List<InteractiveTestCase> createTestItems() {
List<InteractiveTestCase> tests = new ArrayList<>();
- if (supportsConditionProviders()) {
- tests.add(new PassTest());
- return tests;
- }
tests.add(new SetModeAllTest());
tests.add(new SetModePriorityTest());
tests.add(new TestAccessRingerModeDndOn());
@@ -136,12 +132,6 @@
return tests;
}
- private boolean supportsConditionProviders() {
- ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
- return !am.isLowRamDevice()
- || mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH);
- }
-
private int getVolumeDelta(int volume) {
return 1;
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/USBAudioPeripheralActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/USBAudioPeripheralActivity.java
index 140757d..8f0a9b0 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/USBAudioPeripheralActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/USBAudioPeripheralActivity.java
@@ -16,12 +16,18 @@
package com.android.cts.verifier.audio;
+import android.app.AlertDialog;
+import com.android.compatibility.common.util.ReportLog;
+import com.android.compatibility.common.util.ResultType;
+import com.android.compatibility.common.util.ResultUnit;
import android.media.AudioDeviceCallback;
import android.media.AudioDeviceInfo;
import android.media.AudioManager;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
+import android.view.View;
+import android.view.View.OnClickListener;
import android.widget.TextView;
import com.android.cts.verifier.audio.peripheralprofile.PeripheralProfile;
@@ -55,6 +61,68 @@
private TextView mPeripheralNameTx;
+ private OnBtnClickListener mBtnClickListener = new OnBtnClickListener();
+
+ //
+ // Common UI Handling
+ //
+ protected void connectUSBPeripheralUI() {
+ findViewById(R.id.uap_tests_yes_btn).setOnClickListener(mBtnClickListener);
+ findViewById(R.id.uap_tests_no_btn).setOnClickListener(mBtnClickListener);
+ findViewById(R.id.uap_test_info_btn).setOnClickListener(mBtnClickListener);
+
+ // Leave the default state in tact
+ // enableTestUI(false);
+ }
+
+ private void showUAPInfoDialog() {
+ new AlertDialog.Builder(this)
+ .setTitle(R.string.uap_mic_dlg_caption)
+ .setMessage(R.string.uap_mic_dlg_text)
+ .setPositiveButton(R.string.audio_general_ok, null)
+ .show();
+ }
+
+ private class OnBtnClickListener implements OnClickListener {
+ @Override
+ public void onClick(View v) {
+ switch (v.getId()) {
+ case R.id.uap_tests_yes_btn:
+ recordUSBAudioStatus(true);
+ enableTestUI(true);
+ // disable test button so that they will now run the test(s)
+ getPassButton().setEnabled(false);
+ break;
+
+ case R.id.uap_tests_no_btn:
+ recordUSBAudioStatus(false);
+ enableTestUI(false);
+ // Allow the user to "pass" the test.
+ getPassButton().setEnabled(true);
+ break;
+
+ case R.id.uap_test_info_btn:
+ showUAPInfoDialog();
+ break;
+ }
+ }
+ }
+
+ private void recordUSBAudioStatus(boolean has) {
+ getReportLog().addValue(
+ "User reported USB Host Audio Support: ",
+ has ? 1.0 : 0,
+ ResultType.NEUTRAL,
+ ResultUnit.NONE);
+ }
+
+ //
+ // Overrides
+ //
+ void enableTestUI(boolean enable) {
+
+ }
+
public USBAudioPeripheralActivity(boolean mandatedRequired) {
super();
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/USBAudioPeripheralAttributesActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/USBAudioPeripheralAttributesActivity.java
index 5029160..23ed91a 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/USBAudioPeripheralAttributesActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/USBAudioPeripheralAttributesActivity.java
@@ -47,6 +47,8 @@
setPassFailButtonClickListeners();
setInfoResources(R.string.usbaudio_attribs_test, R.string.usbaudio_attribs_info, -1);
+
+ connectUSBPeripheralUI();
}
//
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/USBAudioPeripheralButtonsActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/USBAudioPeripheralButtonsActivity.java
index de3ce7f..823f326 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/USBAudioPeripheralButtonsActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/USBAudioPeripheralButtonsActivity.java
@@ -83,6 +83,8 @@
setInfoResources(R.string.usbaudio_buttons_test, R.string.usbaudio_buttons_info, -1);
showDisableAssistantDialog();
+
+ connectUSBPeripheralUI();
}
private void showButtonsState() {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/USBAudioPeripheralPlayActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/USBAudioPeripheralPlayActivity.java
index de9016a..4ae5ec3 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/USBAudioPeripheralPlayActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/USBAudioPeripheralPlayActivity.java
@@ -50,11 +50,17 @@
setPassFailButtonClickListeners();
setInfoResources(R.string.usbaudio_play_test, R.string.usbaudio_play_info, -1);
+
+ connectUSBPeripheralUI();
}
//
// USBAudioPeripheralActivity
// Headset not publicly available, violates CTS Verifier additional equipment guidelines.
+ void enableTestUI(boolean enable) {
+ mPlayBtn.setEnabled(enable);
+ }
+
public void updateConnectStatus() {
mPlayBtn.setEnabled(mIsPeripheralAttached);
getPassButton().setEnabled(mIsPeripheralAttached);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/USBAudioPeripheralRecordActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/USBAudioPeripheralRecordActivity.java
index 268201c..d51eac3 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/USBAudioPeripheralRecordActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/USBAudioPeripheralRecordActivity.java
@@ -139,11 +139,18 @@
setPassFailButtonClickListeners();
setInfoResources(R.string.usbaudio_record_test, R.string.usbaudio_record_info, -1);
+
+ connectUSBPeripheralUI();
}
//
// USBAudioPeripheralActivity
//
+ void enableTestUI(boolean enable) {
+ mRecordBtn.setEnabled(enable);
+ mRecordLoopbackBtn.setEnabled(enable);
+ }
+
public void updateConnectStatus() {
mRecordBtn.setEnabled(mIsPeripheralAttached);
mRecordLoopbackBtn.setEnabled(mIsPeripheralAttached);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/AttentionManagementVerifierActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/AttentionManagementVerifierActivity.java
index 8764dbe..8391816 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/AttentionManagementVerifierActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/AttentionManagementVerifierActivity.java
@@ -20,12 +20,10 @@
import static com.android.cts.verifier.notifications.MockListener.JSON_MATCHES_ZEN_FILTER;
import static com.android.cts.verifier.notifications.MockListener.JSON_TAG;
-import android.app.ActivityManager;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.ContentProviderOperation;
-import android.content.Context;
import android.content.OperationApplicationException;
import android.database.Cursor;
import android.media.AudioAttributes;
@@ -94,37 +92,30 @@
@Override
protected List<InteractiveTestCase> createTestItems() {
-
List<InteractiveTestCase> tests = new ArrayList<>(17);
- ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
- if (am.isLowRamDevice()) {
- tests.add(new CannotBeEnabledTest());
- tests.add(new ServiceStoppedTest());
- } else {
- tests.add(new IsEnabledTest());
- tests.add(new ServiceStartedTest());
- tests.add(new InsertContactsTest());
- tests.add(new NoneInterceptsAllMessagesTest());
- tests.add(new NoneInterceptsAlarmEventReminderCategoriesTest());
- tests.add(new PriorityInterceptsSomeMessagesTest());
+ tests.add(new IsEnabledTest());
+ tests.add(new ServiceStartedTest());
+ tests.add(new InsertContactsTest());
+ tests.add(new NoneInterceptsAllMessagesTest());
+ tests.add(new NoneInterceptsAlarmEventReminderCategoriesTest());
+ tests.add(new PriorityInterceptsSomeMessagesTest());
- if (getApplicationInfo().targetSdkVersion > Build.VERSION_CODES.O_MR1) {
- // Tests targeting P and above:
- tests.add(new PriorityInterceptsAlarmsTest());
- tests.add(new PriorityInterceptsMediaSystemOtherTest());
- }
-
- tests.add(new AllInterceptsNothingMessagesTest());
- tests.add(new AllInterceptsNothingDiffCategoriesTest());
- tests.add(new DefaultOrderTest());
- tests.add(new PriorityOrderTest());
- tests.add(new InterruptionOrderTest());
- tests.add(new AmbientBitsTest());
- tests.add(new LookupUriOrderTest());
- tests.add(new EmailOrderTest());
- tests.add(new PhoneOrderTest());
- tests.add(new DeleteContactsTest());
+ if (getApplicationInfo().targetSdkVersion > Build.VERSION_CODES.O_MR1) {
+ // Tests targeting P and above:
+ tests.add(new PriorityInterceptsAlarmsTest());
+ tests.add(new PriorityInterceptsMediaSystemOtherTest());
}
+
+ tests.add(new AllInterceptsNothingMessagesTest());
+ tests.add(new AllInterceptsNothingDiffCategoriesTest());
+ tests.add(new DefaultOrderTest());
+ tests.add(new PriorityOrderTest());
+ tests.add(new InterruptionOrderTest());
+ tests.add(new AmbientBitsTest());
+ tests.add(new LookupUriOrderTest());
+ tests.add(new EmailOrderTest());
+ tests.add(new PhoneOrderTest());
+ tests.add(new DeleteContactsTest());
return tests;
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/ConditionProviderVerifierActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/ConditionProviderVerifierActivity.java
index bad4639..2260f6d 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/ConditionProviderVerifierActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/ConditionProviderVerifierActivity.java
@@ -21,9 +21,7 @@
import static android.app.NotificationManager.AUTOMATIC_RULE_STATUS_REMOVED;
import static android.app.NotificationManager.AUTOMATIC_RULE_STATUS_UNKNOWN;
import static android.app.NotificationManager.INTERRUPTION_FILTER_PRIORITY;
-import static android.provider.Settings.EXTRA_APP_PACKAGE;
-import android.app.ActivityManager;
import android.app.AutomaticZenRule;
import android.app.NotificationManager;
import android.content.ComponentName;
@@ -71,32 +69,26 @@
@Override
protected List<InteractiveTestCase> createTestItems() {
List<InteractiveTestCase> tests = new ArrayList<>(9);
- ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
- if (am.isLowRamDevice()) {
- tests.add(new CannotBeEnabledTest());
- tests.add(new ServiceStoppedTest());
- } else {
- tests.add(new IsEnabledTest());
- tests.add(new ServiceStartedTest());
- tests.add(new CreateAutomaticZenRuleTest());
- tests.add(new CreateAutomaticZenRuleWithZenPolicyTest());
- tests.add(new UpdateAutomaticZenRuleTest());
- tests.add(new UpdateAutomaticZenRuleWithZenPolicyTest());
- tests.add(new GetAutomaticZenRuleTest());
- tests.add(new GetAutomaticZenRulesTest());
- tests.add(new VerifyRulesIntent());
- tests.add(new VerifyRulesAvailableToUsers());
- tests.add(new ReceiveRuleDisableNoticeTest());
- tests.add(new ReceiveRuleEnabledNoticeTest());
- tests.add(new ReceiveRuleDeletedNoticeTest());
- tests.add(new SubscribeAutomaticZenRuleTest());
- tests.add(new DeleteAutomaticZenRuleTest());
- tests.add(new UnsubscribeAutomaticZenRuleTest());
- tests.add(new RequestUnbindTest());
- tests.add(new RequestBindTest());
- tests.add(new IsDisabledTest());
- tests.add(new ServiceStoppedTest());
- }
+ tests.add(new IsEnabledTest());
+ tests.add(new ServiceStartedTest());
+ tests.add(new CreateAutomaticZenRuleTest());
+ tests.add(new CreateAutomaticZenRuleWithZenPolicyTest());
+ tests.add(new UpdateAutomaticZenRuleTest());
+ tests.add(new UpdateAutomaticZenRuleWithZenPolicyTest());
+ tests.add(new GetAutomaticZenRuleTest());
+ tests.add(new GetAutomaticZenRulesTest());
+ tests.add(new VerifyRulesIntent());
+ tests.add(new VerifyRulesAvailableToUsers());
+ tests.add(new ReceiveRuleDisableNoticeTest());
+ tests.add(new ReceiveRuleEnabledNoticeTest());
+ tests.add(new ReceiveRuleDeletedNoticeTest());
+ tests.add(new SubscribeAutomaticZenRuleTest());
+ tests.add(new DeleteAutomaticZenRuleTest());
+ tests.add(new UnsubscribeAutomaticZenRuleTest());
+ tests.add(new RequestUnbindTest());
+ tests.add(new RequestBindTest());
+ tests.add(new IsDisabledTest());
+ tests.add(new ServiceStoppedTest());
return tests;
}
@@ -138,45 +130,6 @@
}
}
- protected class CannotBeEnabledTest extends InteractiveTestCase {
- @Override
- protected View inflate(ViewGroup parent) {
- return createNlsSettingsItem(parent, R.string.cp_cannot_enable_service);
- }
-
- @Override
- boolean autoStart() {
- return true;
- }
-
- @Override
- protected void test() {
- mNm.cancelAll();
- Intent settings = new Intent(Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS);
- if (settings.resolveActivity(mPackageManager) == null) {
- logFail("no settings activity");
- status = FAIL;
- } else {
- if (mNm.isNotificationPolicyAccessGranted()) {
- status = FAIL;
- } else {
- status = PASS;
- }
- next();
- }
- }
-
- protected void tearDown() {
- // wait for the service to start
- delay();
- }
-
- @Override
- protected Intent getIntent() {
- return new Intent(Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS);
- }
- }
-
protected class ServiceStartedTest extends InteractiveTestCase {
int mRetries = 5;
@Override
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/InteractiveVerifierActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/InteractiveVerifierActivity.java
index 296df5d..aa5e9c0 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/InteractiveVerifierActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/InteractiveVerifierActivity.java
@@ -36,6 +36,7 @@
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
+
import com.android.cts.verifier.PassFailButtons;
import com.android.cts.verifier.R;
@@ -524,47 +525,6 @@
}
}
- protected class CannotBeEnabledTest extends InteractiveTestCase {
- @Override
- protected View inflate(ViewGroup parent) {
- return createNlsSettingsItem(parent, R.string.nls_cannot_enable_service);
- }
-
- @Override
- boolean autoStart() {
- return true;
- }
-
- @Override
- protected void test() {
- mNm.cancelAll();
- Intent settings = new Intent(ACTION_NOTIFICATION_LISTENER_SETTINGS);
- if (settings.resolveActivity(mPackageManager) == null) {
- logFail("no settings activity");
- status = FAIL;
- } else {
- String listeners = Secure.getString(getContentResolver(),
- ENABLED_NOTIFICATION_LISTENERS);
- if (listeners != null && listeners.contains(LISTENER_PATH)) {
- status = FAIL;
- } else {
- status = PASS;
- }
- next();
- }
- }
-
- protected void tearDown() {
- // wait for the service to start
- delay();
- }
-
- @Override
- protected Intent getIntent() {
- return new Intent(ACTION_NOTIFICATION_LISTENER_SETTINGS);
- }
- }
-
protected class ServiceStartedTest extends InteractiveTestCase {
@Override
protected View inflate(ViewGroup parent) {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/NotificationListenerVerifierActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/NotificationListenerVerifierActivity.java
index 7297dbe..348c7a3 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/NotificationListenerVerifierActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/NotificationListenerVerifierActivity.java
@@ -35,7 +35,6 @@
import static com.android.cts.verifier.notifications.MockListener.REASON_LISTENER_CANCEL;
import android.annotation.SuppressLint;
-import android.app.ActivityManager;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationChannelGroup;
@@ -108,39 +107,32 @@
@Override
protected List<InteractiveTestCase> createTestItems() {
List<InteractiveTestCase> tests = new ArrayList<>(17);
- ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
- if (am.isLowRamDevice()) {
- tests.add(new CannotBeEnabledTest());
- tests.add(new ServiceStoppedTest());
- tests.add(new NotificationNotReceivedTest());
- } else {
- tests.add(new IsEnabledTest());
- tests.add(new ServiceStartedTest());
- tests.add(new NotificationReceivedTest());
- tests.add(new DataIntactTest());
- tests.add(new AudiblyAlertedTest());
- tests.add(new DismissOneTest());
- tests.add(new DismissOneWithReasonTest());
- tests.add(new DismissOneWithStatsTest());
- tests.add(new DismissAllTest());
- tests.add(new SnoozeNotificationForTimeTest());
- tests.add(new SnoozeNotificationForTimeCancelTest());
- tests.add(new GetSnoozedNotificationTest());
- tests.add(new EnableHintsTest());
- tests.add(new ReceiveAppBlockNoticeTest());
- tests.add(new ReceiveAppUnblockNoticeTest());
- if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
- tests.add(new ReceiveChannelBlockNoticeTest());
- tests.add(new ReceiveGroupBlockNoticeTest());
- }
- tests.add(new RequestUnbindTest());
- tests.add(new RequestBindTest());
- tests.add(new MessageBundleTest());
- tests.add(new EnableHintsTest());
- tests.add(new IsDisabledTest());
- tests.add(new ServiceStoppedTest());
- tests.add(new NotificationNotReceivedTest());
+ tests.add(new IsEnabledTest());
+ tests.add(new ServiceStartedTest());
+ tests.add(new NotificationReceivedTest());
+ tests.add(new DataIntactTest());
+ tests.add(new AudiblyAlertedTest());
+ tests.add(new DismissOneTest());
+ tests.add(new DismissOneWithReasonTest());
+ tests.add(new DismissOneWithStatsTest());
+ tests.add(new DismissAllTest());
+ tests.add(new SnoozeNotificationForTimeTest());
+ tests.add(new SnoozeNotificationForTimeCancelTest());
+ tests.add(new GetSnoozedNotificationTest());
+ tests.add(new EnableHintsTest());
+ tests.add(new ReceiveAppBlockNoticeTest());
+ tests.add(new ReceiveAppUnblockNoticeTest());
+ if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
+ tests.add(new ReceiveChannelBlockNoticeTest());
+ tests.add(new ReceiveGroupBlockNoticeTest());
}
+ tests.add(new RequestUnbindTest());
+ tests.add(new RequestBindTest());
+ tests.add(new MessageBundleTest());
+ tests.add(new EnableHintsTest());
+ tests.add(new IsDisabledTest());
+ tests.add(new ServiceStoppedTest());
+ tests.add(new NotificationNotReceivedTest());
return tests;
}
diff --git a/common/device-side/util-axt/src/com/android/compatibility/common/util/RetryRule.java b/common/device-side/util-axt/src/com/android/compatibility/common/util/RetryRule.java
index ca0e3e2..a24239c 100644
--- a/common/device-side/util-axt/src/com/android/compatibility/common/util/RetryRule.java
+++ b/common/device-side/util-axt/src/com/android/compatibility/common/util/RetryRule.java
@@ -31,16 +31,8 @@
private static final String TAG = "RetryRule";
- /**
- * An interface is used to clean up testing objects between the retries to make sure
- * the testing environment is clean.
- */
- public interface RetryCleaner {
- void clean();
- }
-
private final int mMaxAttempts;
- private final RetryCleaner mCleaner;
+ private final Runnable mCleaner;
/**
* Retries the underlying test when it catches a {@link RetryableException}.
@@ -57,12 +49,12 @@
* Retries the underlying test when it catches a {@link RetryableException}.
*
* @param retries number of retries. Use {@code 0} to disable rule.
- * @param cleaner a {@link RetryCleaner} to clean up the objects generated by the testing
+ * @param cleaner a {@link Runnable} to clean up the objects generated by the testing
* between retries
*
* @throws IllegalArgumentException if {@code retries} is less than {@code 0}.
*/
- public RetryRule(int retries, @Nullable RetryCleaner cleaner) {
+ public RetryRule(int retries, @Nullable Runnable cleaner) {
if (retries < 0) {
throw new IllegalArgumentException("retries must be more than 0");
}
@@ -105,7 +97,7 @@
}
caught = e;
if (i != mMaxAttempts && mCleaner != null) {
- mCleaner.clean();
+ mCleaner.run();
}
}
Log.w(TAG, "Arrrr! " + name + " failed at attempt " + i + "/" + mMaxAttempts
diff --git a/common/device-side/util-axt/tests/src/com/android/compatibility/common/util/RetryRuleTest.java b/common/device-side/util-axt/tests/src/com/android/compatibility/common/util/RetryRuleTest.java
index 644d95f..571a1b8 100644
--- a/common/device-side/util-axt/tests/src/com/android/compatibility/common/util/RetryRuleTest.java
+++ b/common/device-side/util-axt/tests/src/com/android/compatibility/common/util/RetryRuleTest.java
@@ -19,11 +19,15 @@
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.testng.Assert.assertThrows;
import static org.testng.Assert.expectThrows;
+import androidx.annotation.Nullable;
+
import org.junit.Test;
import org.junit.runner.Description;
import org.junit.runner.RunWith;
@@ -43,15 +47,22 @@
private final int mNumberFailures;
private int mNumberCalls;
private final T mException;
+ private final Runnable mCleaner;
RetryableStatement(int numberFailures, T exception) {
+ this(numberFailures, exception, null);
+ }
+
+ RetryableStatement(int numberFailures, T exception, @Nullable Runnable cleaner) {
mNumberFailures = numberFailures;
mException = exception;
+ mCleaner = cleaner;
}
@Override
public void evaluate() throws Throwable {
mNumberCalls++;
+ verifyCleaner();
if (mNumberCalls <= mNumberFailures) {
throw mException;
}
@@ -61,6 +72,13 @@
public String toString() {
return "RetryableStatement: failures=" + mNumberFailures + ", calls=" + mNumberCalls;
}
+
+ private void verifyCleaner() {
+ if (mCleaner == null) {
+ return;
+ }
+ verify(mCleaner, times(mNumberCalls - 1)).run();
+ }
}
private @Mock Statement mMockStatement;
@@ -68,6 +86,8 @@
@Test
public void testInvalidConstructor() throws Throwable {
assertThrows(IllegalArgumentException.class, () -> new RetryRule(-1));
+ assertThrows(IllegalArgumentException.class, () -> new RetryRule(-1, null));
+ assertThrows(IllegalArgumentException.class, () -> new RetryRule(-1, () -> {}));
}
@Test
@@ -78,6 +98,57 @@
}
@Test
+ public void testDoCleanOnRetryableException() throws Throwable {
+ final Runnable cleaner = mock(Runnable.class);
+ final RetryRule rule = new RetryRule(2, cleaner);
+
+ rule.apply(new RetryableStatement<RetryableException>(2, sRetryableException, cleaner),
+ mDescription).evaluate();
+
+ verify(cleaner, times(2)).run();
+ }
+
+ @Test
+ public void testKeepLastStatusWhenFailOnRetryableException() throws Throwable {
+ final Runnable cleaner = mock(Runnable.class);
+ final RetryRule rule = new RetryRule(2, cleaner);
+
+ final RetryableException actualException = expectThrows(RetryableException.class,
+ () -> rule.apply(
+ new RetryableStatement<RetryableException>(3, sRetryableException, cleaner),
+ mDescription).evaluate());
+
+ assertThat(actualException).isSameAs(sRetryableException);
+ verify(cleaner, times(2)).run();
+ }
+
+ @Test
+ public void testNeverCleanWhenStatementPass() throws Throwable {
+ final Runnable cleaner = mock(Runnable.class);
+ final RetryRule rule = new RetryRule(2, cleaner);
+
+ rule.apply(mMockStatement, mDescription).evaluate();
+
+ verify(mMockStatement, times(1)).evaluate();
+ verify(cleaner, never()).run();
+ }
+
+ @Test
+ public void testNeverCleanWhenDisabledAndStatementThrowsRetryableException() throws Throwable {
+ final RetryableException exception = new RetryableException("Y U NO?");
+ final Runnable cleaner = mock(Runnable.class);
+ final RetryRule rule = new RetryRule(0, cleaner);
+ doThrow(exception).when(mMockStatement).evaluate();
+
+ final RetryableException actualException = expectThrows(RetryableException.class,
+ () -> rule.apply(mMockStatement, mDescription).evaluate());
+
+ assertThat(actualException).isSameAs(exception);
+ verify(mMockStatement, times(1)).evaluate();
+ verify(cleaner, never()).run();
+ }
+
+ @Test
public void testPassOnRetryableExceptionWithTimeout() throws Throwable {
final Timeout timeout = new Timeout("YOUR TIME IS GONE", 1, 2, 10);
final RetryableException exception = new RetryableException(timeout, "Y U NO?");
diff --git a/hostsidetests/appsecurity/test-apps/EncryptionApp/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/EncryptionApp/AndroidManifest.xml
index 1231874..a6f7b1d 100644
--- a/hostsidetests/appsecurity/test-apps/EncryptionApp/AndroidManifest.xml
+++ b/hostsidetests/appsecurity/test-apps/EncryptionApp/AndroidManifest.xml
@@ -16,7 +16,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.cts.encryptionapp">
- <application android:label="EncryptionApp">
+ <application android:label="EncryptionApp" android:forceQueryable="true">
<activity android:name=".UnawareActivity"
android:exported="true">
<intent-filter>
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/SplitApp/AndroidManifest.xml
index 71d13ae..04ed8f4 100644
--- a/hostsidetests/appsecurity/test-apps/SplitApp/AndroidManifest.xml
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/AndroidManifest.xml
@@ -23,7 +23,7 @@
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
- <application android:label="SplitApp" android:multiArch="true">
+ <application android:label="SplitApp" android:multiArch="true" android:forceQueryable="true">
<activity android:name=".MyActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
diff --git a/hostsidetests/bootstats/Android.bp b/hostsidetests/bootstats/Android.bp
index ca1e292..07f9c84 100644
--- a/hostsidetests/bootstats/Android.bp
+++ b/hostsidetests/bootstats/Android.bp
@@ -17,12 +17,12 @@
defaults: ["cts_defaults"],
// Only compile source java files in this apk.
srcs: ["src/**/*.java"],
- static_libs: ["framework-protos"],
libs: [
"cts-tradefed",
"tradefed",
"compatibility-host-util",
"libprotobuf-java-full",
+ "platformprotos",
],
// tag this module as a cts test artifact
test_suites: [
diff --git a/hostsidetests/bootstats/src/android/bootstats/cts/BootStatsHostTest.java b/hostsidetests/bootstats/src/android/bootstats/cts/BootStatsHostTest.java
index 9ec3dad..e5eb36c 100644
--- a/hostsidetests/bootstats/src/android/bootstats/cts/BootStatsHostTest.java
+++ b/hostsidetests/bootstats/src/android/bootstats/cts/BootStatsHostTest.java
@@ -16,7 +16,7 @@
package android.bootstats.cts;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.os.AtomsProto.Atom;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.log.LogUtil.CLog;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
@@ -56,37 +56,53 @@
Thread.sleep(10000);
// find logs and parse them
- // ex: sysui_multi_action: [757,804,799,ota_boot_complete,801,85,802,1]
- // ex: 757,804,799,counter_name,801,bucket_value,802,increment_value
- final String bucketTag = Integer.toString(MetricsEvent.RESERVED_FOR_LOGBUILDER_BUCKET);
- final String counterNameTag = Integer.toString(MetricsEvent.RESERVED_FOR_LOGBUILDER_NAME);
- final String counterNamePattern = counterNameTag + ",boot_complete,";
- final String multiActionPattern = "sysui_multi_action: [";
+ // ex: Atom 239->10
+ // ex: Atom 240->9
+ final String bootTimeEventDurationReported =
+ Integer.toString(Atom.BOOT_TIME_EVENT_DURATION_REPORTED_FIELD_NUMBER);
+ final String bootTimeEventDurationReportedPattern = "Atom "
+ + bootTimeEventDurationReported + "->";
+ final String bootTimeEventElapsedTimeReported =
+ Integer.toString(Atom.BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED_FIELD_NUMBER);
+ final String bootTimeEventElapsedTimeReportedPattern = "Atom "
+ + bootTimeEventElapsedTimeReported + "->";
- final String log = getDevice().executeShellCommand("logcat --buffer=events -d");
+ final String log = getDevice().executeShellCommand("cmd stats print-stats");
- int counterNameIndex = log.indexOf(counterNamePattern);
- Assert.assertTrue("did not find boot logs", counterNameIndex != -1);
+ int bootTimeEventDurationReportedIndex =
+ log.indexOf(bootTimeEventDurationReportedPattern);
+ Assert.assertTrue("did not find boot duration logs",
+ bootTimeEventDurationReportedIndex != -1);
+ // extract the number after ->, e.g., 10 inside 239->10
+ int valueIndex = bootTimeEventDurationReportedIndex +
+ bootTimeEventDurationReportedPattern.length();
+ int value = getIntValue(log, valueIndex);
+ Assert.assertTrue("boot duration time smaller than 1", value > 1);
- int multiLogStart = log.lastIndexOf(multiActionPattern, counterNameIndex);
- multiLogStart += multiActionPattern.length();
- int multiLogEnd = log.indexOf("]", multiLogStart);
- String[] multiLogDataStrings = log.substring(multiLogStart, multiLogEnd).split(",");
+ int bootTimeEventElapsedTimeReportedIndex =
+ log.indexOf(bootTimeEventElapsedTimeReportedPattern);
+ Assert.assertTrue("did not find boot elapsed time logs",
+ bootTimeEventElapsedTimeReportedIndex != -1);
- boolean foundBucket = false;
- int bootTime = 0;
- for (int i = 0; i < multiLogDataStrings.length; i += 2) {
- if (bucketTag.equals(multiLogDataStrings[i])) {
- foundBucket = true;
- Assert.assertTrue("histogram data was truncated",
- (i + 1) < multiLogDataStrings.length);
- bootTime = Integer.valueOf(multiLogDataStrings[i + 1]);
+ // extract the number after ->, e.g., 9 inside Atom 240->9
+ valueIndex = bootTimeEventElapsedTimeReportedIndex +
+ bootTimeEventElapsedTimeReportedPattern.length();
+ value = getIntValue(log, valueIndex);
+ Assert.assertTrue("boot elapsed time smaller than 1", value > 1);
+ }
+
+ // extract the value from the string starting from index till EOL
+ private int getIntValue(String str, int index) throws Exception {
+ int lastIndex = index;
+ for (int i = index; i < str.length(); i++) {
+ if (str.charAt(i) == '\n') {
+ lastIndex = i;
+ break;
}
}
- Assert.assertTrue("log line did not contain a tag " + bucketTag, foundBucket);
- Assert.assertTrue("reported boot time must be less than observed boot time",
- bootTime < upperBoundSeconds);
- Assert.assertTrue("reported boot time must be non-zero", bootTime > 0);
+ String valueStr = str.substring(index, lastIndex);
+ int value = Integer.valueOf(valueStr);
+ return value;
}
private boolean isBootCompleted() throws Exception {
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/BaseDeviceAdminTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/BaseDeviceAdminTest.java
index 212d20f..889e91a 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/BaseDeviceAdminTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/BaseDeviceAdminTest.java
@@ -69,6 +69,7 @@
protected DevicePolicyManager mDevicePolicyManager;
protected UserManager mUserManager;
protected Context mContext;
+ protected boolean mHasSecureLockScreen;
static CountDownLatch mOnPasswordExpiryTimeoutCalled;
private final String mTag = getClass().getSimpleName();
@@ -84,6 +85,9 @@
mUserManager = mContext.getSystemService(UserManager.class);
assertNotNull(mUserManager);
+ mHasSecureLockScreen = mContext.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_SECURE_LOCK_SCREEN);
+
assertTrue(mDevicePolicyManager.isAdminActive(ADMIN_RECEIVER_COMPONENT));
assertTrue("App is neither device nor profile owner",
mDevicePolicyManager.isProfileOwnerApp(PACKAGE_NAME) ||
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/LockTaskTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/LockTaskTest.java
index 2f9bc37..78b5b2e 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/LockTaskTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/LockTaskTest.java
@@ -15,6 +15,7 @@
*/
package com.android.cts.deviceandprofileowner;
+import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_BLOCK_ACTIVITY_START_IN_TASK;
import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_GLOBAL_ACTIONS;
import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_HOME;
import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_KEYGUARD;
@@ -35,7 +36,11 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.Until;
import android.util.Log;
+import android.view.KeyEvent;
import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
@@ -134,11 +139,13 @@
private final Object mReceiverActivityRunningLock = new Object();
private Context mContext;
+ private UiDevice mUiDevice;
private ActivityManager mActivityManager;
private DevicePolicyManager mDevicePolicyManager;
public void setUp() {
mContext = InstrumentationRegistry.getContext();
+ mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
mDevicePolicyManager = mContext.getSystemService(DevicePolicyManager.class);
mDevicePolicyManager.setLockTaskPackages(ADMIN_COMPONENT, new String[0]);
@@ -302,6 +309,43 @@
stopAndFinish(UTILITY_ACTIVITY);
}
+ // When LOCK_TASK_FEATURE_BLOCK_ACTIVITY_START_IN_TASK is set, un-whitelisted apps cannot
+ // be launched in the same task.
+ public void testStartActivity_withinTask_blockInTask() throws Exception {
+ mDevicePolicyManager.setLockTaskPackages(ADMIN_COMPONENT, new String[] { PACKAGE_NAME });
+ mDevicePolicyManager.setLockTaskFeatures(
+ ADMIN_COMPONENT, LOCK_TASK_FEATURE_BLOCK_ACTIVITY_START_IN_TASK);
+ startLockTask(UTILITY_ACTIVITY);
+ waitForResume();
+
+ mIsReceiverActivityRunning = false;
+ Intent launchIntent = createReceiverActivityIntent(false /*newTask*/, false /*shouldWait*/);
+ Intent lockTaskUtility = getLockTaskUtility(UTILITY_ACTIVITY);
+ lockTaskUtility.putExtra(LockTaskUtilityActivity.START_ACTIVITY, launchIntent);
+ mContext.startActivity(lockTaskUtility);
+
+ synchronized (mReceiverActivityRunningLock) {
+ mReceiverActivityRunningLock.wait(ACTIVITY_RESUMED_TIMEOUT_MILLIS);
+ assertFalse(mIsReceiverActivityRunning);
+ }
+
+ Log.d(TAG, "Waiting for the system dialog");
+ mUiDevice.waitForIdle();
+ assertTrue(mUiDevice.wait(
+ Until.hasObject(By.textContains(RECEIVER_ACTIVITY_PACKAGE_NAME)),
+ ACTIVITY_RESUMED_TIMEOUT_MILLIS));
+ Log.d(TAG, "dialog found");
+
+ // Dismiss the system dialog
+ mUiDevice.pressKeyCode(KeyEvent.KEYCODE_ENTER);
+ mUiDevice.pressKeyCode(KeyEvent.KEYCODE_ENTER);
+ assertFalse(mUiDevice.wait(
+ Until.hasObject(By.textContains(RECEIVER_ACTIVITY_PACKAGE_NAME)),
+ ACTIVITY_RESUMED_TIMEOUT_MILLIS));
+
+ mDevicePolicyManager.setLockTaskFeatures(ADMIN_COMPONENT, 0);
+ }
+
// This launches a whitelisted activity that is not part of the current task.
// This should be permitted as a part of lock task.
public void testStartActivity_outsideTaskWhitelisted() throws Exception {
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SecurityLoggingTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/SecurityLoggingTest.java
similarity index 84%
rename from hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SecurityLoggingTest.java
rename to hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/SecurityLoggingTest.java
index ed4c19f..fc3a1f0 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SecurityLoggingTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/SecurityLoggingTest.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.cts.deviceowner;
+package com.android.cts.deviceandprofileowner;
import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
@@ -62,10 +62,12 @@
import android.content.SharedPreferences;
import android.os.Parcel;
import android.os.Process;
+import android.os.UserHandle;
import android.os.UserManager;
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyProperties;
import android.security.keystore.KeyProtection;
+import android.text.TextUtils;
import androidx.test.InstrumentationRegistry;
@@ -85,7 +87,7 @@
import javax.crypto.spec.SecretKeySpec;
-public class SecurityLoggingTest extends BaseDeviceOwnerTest {
+public class SecurityLoggingTest extends BaseDeviceAdminTest {
private static final String ARG_BATCH_NUMBER = "batchNumber";
private static final String PREF_KEY_PREFIX = "batch-last-id-";
private static final String PREF_NAME = "batchIds";
@@ -123,8 +125,8 @@
.put(TAG_KEY_GENERATED, of(I, S, I))
.put(TAG_KEY_IMPORT, of(I, S, I))
.put(TAG_KEY_DESTRUCTION, of(I, S, I))
- .put(TAG_CERT_AUTHORITY_INSTALLED, of(I, S))
- .put(TAG_CERT_AUTHORITY_REMOVED, of(I, S))
+ .put(TAG_CERT_AUTHORITY_INSTALLED, of(I, S, I))
+ .put(TAG_CERT_AUTHORITY_REMOVED, of(I, S, I))
.put(TAG_USER_RESTRICTION_ADDED, of(S, I, S))
.put(TAG_USER_RESTRICTION_REMOVED, of(S, I, S))
.put(TAG_CRYPTO_SELF_TEST_COMPLETED, of(I))
@@ -170,6 +172,7 @@
private static final int SUCCESS_INDEX = 0;
private static final int ALIAS_INDEX = 1;
private static final int UID_INDEX = 2;
+ private static final int USERID_INDEX = 2;
private static final int SUBJECT_INDEX = 1;
private static final int ADMIN_PKG_INDEX = 0;
private static final int ADMIN_USER_INDEX = 1;
@@ -208,7 +211,7 @@
*/
public void testRetrievingSecurityLogsThrowsSecurityException() {
try {
- mDevicePolicyManager.retrieveSecurityLogs(getWho());
+ mDevicePolicyManager.retrieveSecurityLogs(ADMIN_RECEIVER_COMPONENT);
fail("did not throw expected SecurityException");
} catch (SecurityException expected) {
}
@@ -220,7 +223,7 @@
*/
public void testRetrievingPreviousSecurityLogsThrowsSecurityException() {
try {
- mDevicePolicyManager.retrievePreRebootSecurityLogs(getWho());
+ mDevicePolicyManager.retrievePreRebootSecurityLogs(ADMIN_RECEIVER_COMPONENT);
fail("did not throw expected SecurityException");
} catch (SecurityException expected) {
}
@@ -236,6 +239,10 @@
verifyKeystoreEventsPresent(events);
verifyKeyChainEventsPresent(events);
verifyAdminEventsPresent(events);
+ verifyAdbShellCommand(events); // Event generated from host side logic
+ if (mDevicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile()) {
+ verifyEventsRedacted(events);
+ }
}
private void verifyAutomaticEventsPresent(List<SecurityEvent> events) {
@@ -264,6 +271,39 @@
verifyUserRestrictionEventsPresent(events);
verifyCameraPolicyEvents(events);
}
+ private void verifyAdbShellCommand(List<SecurityEvent> events) {
+ // Won't be able to locate the command on org-owned devices, as it will be redacted.
+ if (!mDevicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile()) {
+ findEvent("adb command", events,
+ e -> e.getTag() == TAG_ADB_SHELL_CMD &&
+ e.getData().equals("whoami"));
+
+ }
+ }
+
+ private void verifyEventsRedacted(List<SecurityEvent> events) {
+ final int userId = Process.myUserHandle().getIdentifier();
+ for (SecurityEvent event : events) {
+ switch (event.getTag()) {
+ case TAG_ADB_SHELL_CMD:
+ assertTrue(TextUtils.isEmpty((String) event.getData()));
+ break;
+ case TAG_APP_PROCESS_START:
+ case TAG_KEY_GENERATED:
+ case TAG_KEY_IMPORT:
+ case TAG_KEY_DESTRUCTION:
+ assertEquals(userId, UserHandle.getUserId(getInt(event, UID_INDEX)));
+ break;
+ case TAG_CERT_AUTHORITY_INSTALLED:
+ case TAG_CERT_AUTHORITY_REMOVED:
+ assertEquals(userId, getInt(event, USERID_INDEX));
+ break;
+ case TAG_KEY_INTEGRITY_VIOLATION:
+ assertEquals(userId, UserHandle.getUserId(getInt(event, 1)));
+ break;
+ }
+ }
+ }
/**
* Generates events for positive test cases.
@@ -303,7 +343,7 @@
// Retry once after seeping for 1 second, in case "dpm force-security-logs" hasn't taken
// effect just yet.
for (int i = 0; i < 2 && events == null; i++) {
- events = mDevicePolicyManager.retrieveSecurityLogs(getWho());
+ events = mDevicePolicyManager.retrieveSecurityLogs(ADMIN_RECEIVER_COMPONENT);
if (events == null) Thread.sleep(1000);
}
@@ -470,9 +510,9 @@
* security logging is enabled after its execution.
*/
public void testEnablingSecurityLogging() {
- assertFalse(mDevicePolicyManager.isSecurityLoggingEnabled(getWho()));
- mDevicePolicyManager.setSecurityLoggingEnabled(getWho(), true);
- assertTrue(mDevicePolicyManager.isSecurityLoggingEnabled(getWho()));
+ assertFalse(mDevicePolicyManager.isSecurityLoggingEnabled(ADMIN_RECEIVER_COMPONENT));
+ mDevicePolicyManager.setSecurityLoggingEnabled(ADMIN_RECEIVER_COMPONENT, true);
+ assertTrue(mDevicePolicyManager.isSecurityLoggingEnabled(ADMIN_RECEIVER_COMPONENT));
}
/**
@@ -480,11 +520,11 @@
* disabled after its execution.
*/
public void testDisablingSecurityLogging() {
- mDevicePolicyManager.setSecurityLoggingEnabled(getWho(), false);
- assertFalse(mDevicePolicyManager.isSecurityLoggingEnabled(getWho()));
+ mDevicePolicyManager.setSecurityLoggingEnabled(ADMIN_RECEIVER_COMPONENT, false);
+ assertFalse(mDevicePolicyManager.isSecurityLoggingEnabled(ADMIN_RECEIVER_COMPONENT));
// Verify that logs are actually not available.
- assertNull(mDevicePolicyManager.retrieveSecurityLogs(getWho()));
+ assertNull(mDevicePolicyManager.retrieveSecurityLogs(ADMIN_RECEIVER_COMPONENT));
}
/**
@@ -492,11 +532,12 @@
* null.
*/
public void testSecurityLoggingRetrievalRateLimited() {
- final List<SecurityEvent> logs = mDevicePolicyManager.retrieveSecurityLogs(getWho());
+ final List<SecurityEvent> logs = mDevicePolicyManager.retrieveSecurityLogs(
+ ADMIN_RECEIVER_COMPONENT);
// if logs is null it means that that attempt was rate limited => test PASS
if (logs != null) {
- assertNull(mDevicePolicyManager.retrieveSecurityLogs(getWho()));
- assertNull(mDevicePolicyManager.retrieveSecurityLogs(getWho()));
+ assertNull(mDevicePolicyManager.retrieveSecurityLogs(ADMIN_RECEIVER_COMPONENT));
+ assertNull(mDevicePolicyManager.retrieveSecurityLogs(ADMIN_RECEIVER_COMPONENT));
}
}
@@ -546,7 +587,8 @@
}
private void installCaCert() {
- mDevicePolicyManager.installCaCert(getWho(), TEST_CA.getBytes());
+ assertTrue(
+ mDevicePolicyManager.installCaCert(ADMIN_RECEIVER_COMPONENT, TEST_CA.getBytes()));
}
private void verifyCertInstalledEventPresent(List<SecurityEvent> events) {
@@ -557,7 +599,7 @@
}
private void uninstallCaCert() {
- mDevicePolicyManager.uninstallCaCert(getWho(), TEST_CA.getBytes());
+ mDevicePolicyManager.uninstallCaCert(ADMIN_RECEIVER_COMPONENT, TEST_CA.getBytes());
}
private void verifyCertUninstalledEventPresent(List<SecurityEvent> events) {
@@ -568,21 +610,21 @@
}
private void generatePasswordComplexityEvents() {
- mDevicePolicyManager.setPasswordQuality(getWho(), PASSWORD_QUALITY_COMPLEX);
- mDevicePolicyManager.setPasswordMinimumLength(getWho(), TEST_PWD_LENGTH);
- mDevicePolicyManager.setPasswordMinimumLetters(getWho(), TEST_PWD_CHARS);
- mDevicePolicyManager.setPasswordMinimumNonLetter(getWho(), TEST_PWD_CHARS);
- mDevicePolicyManager.setPasswordMinimumUpperCase(getWho(), TEST_PWD_CHARS);
- mDevicePolicyManager.setPasswordMinimumLowerCase(getWho(), TEST_PWD_CHARS);
- mDevicePolicyManager.setPasswordMinimumNumeric(getWho(), TEST_PWD_CHARS);
- mDevicePolicyManager.setPasswordMinimumSymbols(getWho(), TEST_PWD_CHARS);
+ mDevicePolicyManager.setPasswordQuality(ADMIN_RECEIVER_COMPONENT, PASSWORD_QUALITY_COMPLEX);
+ mDevicePolicyManager.setPasswordMinimumLength(ADMIN_RECEIVER_COMPONENT, TEST_PWD_LENGTH);
+ mDevicePolicyManager.setPasswordMinimumLetters(ADMIN_RECEIVER_COMPONENT, TEST_PWD_CHARS);
+ mDevicePolicyManager.setPasswordMinimumNonLetter(ADMIN_RECEIVER_COMPONENT, TEST_PWD_CHARS);
+ mDevicePolicyManager.setPasswordMinimumUpperCase(ADMIN_RECEIVER_COMPONENT, TEST_PWD_CHARS);
+ mDevicePolicyManager.setPasswordMinimumLowerCase(ADMIN_RECEIVER_COMPONENT, TEST_PWD_CHARS);
+ mDevicePolicyManager.setPasswordMinimumNumeric(ADMIN_RECEIVER_COMPONENT, TEST_PWD_CHARS);
+ mDevicePolicyManager.setPasswordMinimumSymbols(ADMIN_RECEIVER_COMPONENT, TEST_PWD_CHARS);
}
private void verifyPasswordComplexityEventsPresent(List<SecurityEvent> events) {
final int userId = Process.myUserHandle().getIdentifier();
// This reflects default values for password complexity event payload fields.
final Object[] expectedPayload = new Object[] {
- getWho().getPackageName(), // admin package
+ ADMIN_RECEIVER_COMPONENT.getPackageName(), // admin package
userId, // admin user
userId, // target user
0, // default password length
@@ -617,37 +659,40 @@
private void generateLockingPolicyEvents() {
if (mHasSecureLockScreen) {
- mDevicePolicyManager.setPasswordExpirationTimeout(getWho(),
+ mDevicePolicyManager.setPasswordExpirationTimeout(ADMIN_RECEIVER_COMPONENT,
TEST_PWD_EXPIRATION_TIMEOUT);
- mDevicePolicyManager.setPasswordHistoryLength(getWho(), TEST_PWD_HISTORY_LENGTH);
- mDevicePolicyManager.setMaximumFailedPasswordsForWipe(getWho(), TEST_PWD_MAX_ATTEMPTS);
+ mDevicePolicyManager.setPasswordHistoryLength(ADMIN_RECEIVER_COMPONENT,
+ TEST_PWD_HISTORY_LENGTH);
+ mDevicePolicyManager.setMaximumFailedPasswordsForWipe(ADMIN_RECEIVER_COMPONENT,
+ TEST_PWD_MAX_ATTEMPTS);
}
- mDevicePolicyManager.setKeyguardDisabledFeatures(getWho(), KEYGUARD_DISABLE_FINGERPRINT);
- mDevicePolicyManager.setMaximumTimeToLock(getWho(), TEST_MAX_TIME_TO_LOCK);
+ mDevicePolicyManager.setKeyguardDisabledFeatures(ADMIN_RECEIVER_COMPONENT,
+ KEYGUARD_DISABLE_FINGERPRINT);
+ mDevicePolicyManager.setMaximumTimeToLock(ADMIN_RECEIVER_COMPONENT, TEST_MAX_TIME_TO_LOCK);
mDevicePolicyManager.lockNow();
}
private void verifyLockingPolicyEventsPresent(List<SecurityEvent> events) {
final int userId = Process.myUserHandle().getIdentifier();
-
+ final String packageName = ADMIN_RECEIVER_COMPONENT.getPackageName();
if (mHasSecureLockScreen) {
findEvent("set password expiration", events,
e -> e.getTag() == TAG_PASSWORD_EXPIRATION_SET &&
- getString(e, ADMIN_PKG_INDEX).equals(getWho().getPackageName()) &&
+ getString(e, ADMIN_PKG_INDEX).equals(packageName) &&
getInt(e, ADMIN_USER_INDEX) == userId &&
getInt(e, TARGET_USER_INDEX) == userId &&
getLong(e, PWD_EXPIRATION_INDEX) == TEST_PWD_EXPIRATION_TIMEOUT);
findEvent("set password history length", events,
e -> e.getTag() == TAG_PASSWORD_HISTORY_LENGTH_SET &&
- getString(e, ADMIN_PKG_INDEX).equals(getWho().getPackageName()) &&
+ getString(e, ADMIN_PKG_INDEX).equals(packageName) &&
getInt(e, ADMIN_USER_INDEX) == userId &&
getInt(e, TARGET_USER_INDEX) == userId &&
getInt(e, PWD_HIST_LEN_INDEX) == TEST_PWD_HISTORY_LENGTH);
findEvent("set password attempts", events,
e -> e.getTag() == TAG_MAX_PASSWORD_ATTEMPTS_SET &&
- getString(e, ADMIN_PKG_INDEX).equals(getWho().getPackageName()) &&
+ getString(e, ADMIN_PKG_INDEX).equals(packageName) &&
getInt(e, ADMIN_USER_INDEX) == userId &&
getInt(e, TARGET_USER_INDEX) == userId &&
getInt(e, MAX_PWD_ATTEMPTS_INDEX) == TEST_PWD_MAX_ATTEMPTS);
@@ -655,21 +700,21 @@
findEvent("set keyguard disabled features", events,
e -> e.getTag() == TAG_KEYGUARD_DISABLED_FEATURES_SET &&
- getString(e, ADMIN_PKG_INDEX).equals(getWho().getPackageName()) &&
+ getString(e, ADMIN_PKG_INDEX).equals(packageName) &&
getInt(e, ADMIN_USER_INDEX) == userId &&
getInt(e, TARGET_USER_INDEX) == userId &&
getInt(e, KEYGUARD_FEATURES_INDEX) == KEYGUARD_DISABLE_FINGERPRINT);
findEvent("set screen lock timeout", events,
e -> e.getTag() == TAG_MAX_SCREEN_LOCK_TIMEOUT_SET &&
- getString(e, ADMIN_PKG_INDEX).equals(getWho().getPackageName()) &&
+ getString(e, ADMIN_PKG_INDEX).equals(packageName) &&
getInt(e, ADMIN_USER_INDEX) == userId &&
getInt(e, TARGET_USER_INDEX) == userId &&
getLong(e, MAX_SCREEN_TIMEOUT_INDEX) == TEST_MAX_TIME_TO_LOCK);
findEvent("set screen lock timeout", events,
e -> e.getTag() == TAG_REMOTE_LOCK &&
- getString(e, ADMIN_PKG_INDEX).equals(getWho().getPackageName()) &&
+ getString(e, ADMIN_PKG_INDEX).equals(packageName) &&
getInt(e, ADMIN_USER_INDEX) == userId);
}
@@ -681,8 +726,10 @@
}
private void generateUserRestrictionEvents() {
- mDevicePolicyManager.addUserRestriction(getWho(), UserManager.DISALLOW_FUN);
- mDevicePolicyManager.clearUserRestriction(getWho(), UserManager.DISALLOW_FUN);
+ mDevicePolicyManager.addUserRestriction(ADMIN_RECEIVER_COMPONENT,
+ UserManager.DISALLOW_PRINTING);
+ mDevicePolicyManager.clearUserRestriction(ADMIN_RECEIVER_COMPONENT,
+ UserManager.DISALLOW_PRINTING);
}
private void verifyUserRestrictionEventsPresent(List<SecurityEvent> events) {
@@ -694,14 +741,15 @@
final int userId = Process.myUserHandle().getIdentifier();
findEvent(description, events,
e -> e.getTag() == tag &&
- getString(e, ADMIN_PKG_INDEX).equals(getWho().getPackageName()) &&
+ getString(e, ADMIN_PKG_INDEX).equals(
+ ADMIN_RECEIVER_COMPONENT.getPackageName()) &&
getInt(e, ADMIN_USER_INDEX) == userId &&
- UserManager.DISALLOW_FUN.equals(getString(e, USER_RESTRICTION_INDEX)));
+ UserManager.DISALLOW_PRINTING.equals(getString(e, USER_RESTRICTION_INDEX)));
}
private void generateCameraPolicyEvents() {
- mDevicePolicyManager.setCameraDisabled(getWho(), true);
- mDevicePolicyManager.setCameraDisabled(getWho(), false);
+ mDevicePolicyManager.setCameraDisabled(ADMIN_RECEIVER_COMPONENT, true);
+ mDevicePolicyManager.setCameraDisabled(ADMIN_RECEIVER_COMPONENT, false);
}
private void verifyCameraPolicyEvents(List<SecurityEvent> events) {
@@ -709,14 +757,16 @@
findEvent("set camera disabled", events,
e -> e.getTag() == TAG_CAMERA_POLICY_SET &&
- getString(e, ADMIN_PKG_INDEX).equals(getWho().getPackageName()) &&
+ getString(e, ADMIN_PKG_INDEX).equals(
+ ADMIN_RECEIVER_COMPONENT.getPackageName()) &&
getInt(e, ADMIN_USER_INDEX) == userId &&
getInt(e, TARGET_USER_INDEX) == userId &&
getInt(e, CAMERA_DISABLED_INDEX) == 1);
findEvent("set camera enabled", events,
e -> e.getTag() == TAG_CAMERA_POLICY_SET &&
- getString(e, ADMIN_PKG_INDEX).equals(getWho().getPackageName()) &&
+ getString(e, ADMIN_PKG_INDEX).equals(
+ ADMIN_RECEIVER_COMPONENT.getPackageName()) &&
getInt(e, ADMIN_USER_INDEX) == userId &&
getInt(e, TARGET_USER_INDEX) == userId &&
getInt(e, CAMERA_DISABLED_INDEX) == 0);
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/RequestSetLocationProviderAllowedTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/RequestSetLocationProviderAllowedTest.java
deleted file mode 100644
index 6b30207..0000000
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/RequestSetLocationProviderAllowedTest.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * 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.deviceowner;
-
-import static android.location.LocationManager.EXTRA_PROVIDER_NAME;
-import static android.location.LocationManager.MODE_CHANGED_ACTION;
-import static android.location.LocationManager.PROVIDERS_CHANGED_ACTION;
-
-import android.app.admin.DevicePolicyManager;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.location.Criteria;
-import android.location.LocationManager;
-
-import androidx.test.platform.app.InstrumentationRegistry;
-
-import com.android.compatibility.common.util.LocationUtils;
-
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Test {@link DevicePolicyManager#requestSetLocationProviderAllowed}.
- */
-public class RequestSetLocationProviderAllowedTest extends BaseDeviceOwnerTest {
-
- private static final long TIMEOUT_MS = 5000;
-
- private static final String TEST_PROVIDER = "test_provider";
-
- private LocationManager mLocationManager;
-
- private boolean mLocationEnabled;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
-
- // allow us to add mock location providers
- LocationUtils.registerMockLocationProvider(mInstrumentation, /*enable=*/true);
-
- mLocationManager = mContext.getSystemService(LocationManager.class);
-
- mLocationEnabled = mLocationManager.isLocationEnabled();
- if (!mLocationEnabled) {
- setLocationEnabledAndAssert(true);
- }
- }
-
- @Override
- protected void tearDown() throws Exception {
- if (!mLocationEnabled) {
- setLocationEnabledAndAssert(false);
- }
-
- LocationUtils.registerMockLocationProvider(mInstrumentation, /*enable=*/false);
- super.tearDown();
- }
-
- public void testRequestSetLocationProviderAllowedTest() throws Exception {
- mLocationManager.addTestProvider(TEST_PROVIDER,
- /* requiresNetwork=*/ true,
- /* requiresSatellite=*/ false,
- /* requiresCell=*/ true,
- /* hasMonetaryCost=*/ false,
- /* supportsAltitude=*/ false,
- /* supportsSpeed=*/ false,
- /* supportsBearing=*/ false,
- Criteria.POWER_MEDIUM,
- Criteria.ACCURACY_FINE);
- try {
- mLocationManager.setTestProviderEnabled(TEST_PROVIDER, false);
-
- requestProviderAllowedAndAssert(TEST_PROVIDER, true);
- requestProviderAllowedAndAssert(TEST_PROVIDER, false);
- } finally {
- mLocationManager.removeTestProvider(TEST_PROVIDER);
- }
- }
-
- private void requestProviderAllowedAndAssert(String provider, boolean allowed) throws Exception {
- final CountDownLatch latch = new CountDownLatch(1);
- final BroadcastReceiver receiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (provider.equals(intent.getStringExtra(EXTRA_PROVIDER_NAME))) {
- latch.countDown();
- }
- }
- };
- mContext.registerReceiver(receiver, new IntentFilter(PROVIDERS_CHANGED_ACTION));
-
- try {
- mDevicePolicyManager.requestSetLocationProviderAllowed(getWho(), provider, allowed);
- assertTrue("timed out waiting for provider change broadcast",
- latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
- assertEquals(allowed, mLocationManager.isProviderEnabled(provider));
- } finally {
- mContext.unregisterReceiver(receiver);
- }
- }
-
- private void setLocationEnabledAndAssert(boolean enabled) throws Exception {
- final CountDownLatch latch = new CountDownLatch(1);
- final BroadcastReceiver receiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- latch.countDown();
- }
- };
- mContext.registerReceiver(receiver, new IntentFilter(MODE_CHANGED_ACTION));
-
- try {
- mDevicePolicyManager.setLocationEnabled(getWho(), enabled);
- assertTrue("timed out waiting for location mode change broadcast",
- latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
- } finally {
- mContext.unregisterReceiver(receiver);
- }
- }
-}
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/ManagedProfileTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CrossProfileIntentFilterTest.java
similarity index 68%
rename from hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/ManagedProfileTest.java
rename to hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CrossProfileIntentFilterTest.java
index 91f2046..15123d4 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/ManagedProfileTest.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CrossProfileIntentFilterTest.java
@@ -16,29 +16,33 @@
package com.android.cts.managedprofile;
import static com.android.cts.managedprofile.BaseManagedProfileTest.ADMIN_RECEIVER_COMPONENT;
+import static com.google.common.truth.Truth.assertThat;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.test.ActivityInstrumentationTestCase2;
import androidx.test.InstrumentationRegistry;
+import java.util.List;
+
/**
* Test for {@link DevicePolicyManager#addCrossProfileIntentFilter} API.
*
- * Note that it expects that there is an activity responding to {@code PrimaryUserActivity.ACTION}
- * in the primary profile, one to {@code ManagedProfileActivity.ACTION} in the secondary profile,
- * and one to {@code AllUsersActivity.ACTION} in both profiles.
+ * <p>Note that it expects that there is an activity responding to {@code PrimaryUserActivity
+ * .ACTION} in the primary profile, one to {@code ManagedProfileActivity.ACTION} in the secondary
+ * profile, and one to {@code AllUsersActivity.ACTION} in both profiles.
*/
-public class ManagedProfileTest extends ActivityInstrumentationTestCase2<TestActivity> {
+public class CrossProfileIntentFilterTest extends ActivityInstrumentationTestCase2<TestActivity> {
private PackageManager mPackageManager;
private DevicePolicyManager mDevicePolicyManager;
- public ManagedProfileTest() {
+ public CrossProfileIntentFilterTest() {
super(TestActivity.class);
}
@@ -65,8 +69,11 @@
testIntentFilter.addAction(PrimaryUserActivity.ACTION);
mDevicePolicyManager.addCrossProfileIntentFilter(ADMIN_RECEIVER_COMPONENT,
testIntentFilter, DevicePolicyManager.FLAG_PARENT_CAN_ACCESS_MANAGED);
- assertEquals(1, mPackageManager.queryIntentActivities(
- new Intent(PrimaryUserActivity.ACTION), /* flags = */ 0).size());
+ final List<ResolveInfo> activities =
+ mPackageManager.queryIntentActivities(
+ new Intent(PrimaryUserActivity.ACTION), /* flags = */ 0);
+ assertThat(activities).hasSize(1);
+ assertThat(activitiesIncludeCrossProfileIntentForwarderActivity(activities)).isTrue();
mDevicePolicyManager.clearCrossProfileIntentFilters(ADMIN_RECEIVER_COMPONENT);
@@ -85,8 +92,11 @@
mDevicePolicyManager.addCrossProfileIntentFilter(ADMIN_RECEIVER_COMPONENT,
testIntentFilter, DevicePolicyManager.FLAG_PARENT_CAN_ACCESS_MANAGED);
- assertEquals(1, mPackageManager.queryIntentActivities(
- new Intent(PrimaryUserActivity.ACTION), /* flags = */ 0).size());
+ final List<ResolveInfo> activities =
+ mPackageManager.queryIntentActivities(
+ new Intent(PrimaryUserActivity.ACTION), /* flags = */ 0);
+ assertThat(activities).hasSize(1);
+ assertThat(activitiesIncludeCrossProfileIntentForwarderActivity(activities)).isTrue();
getActivity().startActivity(PrimaryUserActivity.ACTION);
assertTrue(getActivity().checkActivityStarted());
}
@@ -100,13 +110,16 @@
mDevicePolicyManager.addCrossProfileIntentFilter(ADMIN_RECEIVER_COMPONENT,
testIntentFilter, DevicePolicyManager.FLAG_PARENT_CAN_ACCESS_MANAGED);
- assertEquals(2, mPackageManager.queryIntentActivities(
- new Intent(AllUsersActivity.ACTION), /* flags = */ 0).size());
+ final List<ResolveInfo> activities =
+ mPackageManager.queryIntentActivities(
+ new Intent(AllUsersActivity.ACTION), /* flags = */ 0);
+ assertThat(activities).hasSize(2);
+ assertThat(activitiesIncludeCrossProfileIntentForwarderActivity(activities)).isTrue();
// If we used startActivity(), the user would have a disambiguation dialog presented which
// requires human intervention, so we won't be testing like that
}
- public void testAddCrossProfileIntentFilter_managed() {
+ public void testAddCrossProfileIntentFilter_work() {
assertEquals(1, mPackageManager.queryIntentActivities(
new Intent(ManagedProfileActivity.ACTION), /* flags = */ 0).size());
@@ -116,9 +129,22 @@
testIntentFilter, DevicePolicyManager.FLAG_PARENT_CAN_ACCESS_MANAGED);
// We should still be resolving in the profile
- assertEquals(1, mPackageManager.queryIntentActivities(
- new Intent(ManagedProfileActivity.ACTION), /* flags = */ 0).size());
+ final List<ResolveInfo> activities =
+ mPackageManager.queryIntentActivities(
+ new Intent(ManagedProfileActivity.ACTION), /* flags = */ 0);
+ assertThat(activities).hasSize(1);
+ assertThat(activitiesIncludeCrossProfileIntentForwarderActivity(activities)).isFalse();
getActivity().startActivity(ManagedProfileActivity.ACTION);
assertTrue(getActivity().checkActivityStarted());
}
+
+ private boolean activitiesIncludeCrossProfileIntentForwarderActivity(
+ List<ResolveInfo> activities) {
+ for (ResolveInfo activity : activities) {
+ if (activity.isCrossProfileIntentForwarderActivity()) {
+ return true;
+ }
+ }
+ return false;
+ }
}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
index 3878d10..a6b92a6 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
@@ -237,7 +237,7 @@
if (getDevice().executeShellCommand(command).startsWith(USER_STATE_UNLOCKED)) {
return;
}
- Thread.sleep(100);
+ Thread.sleep(1000);
}
fail("User is not unlocked.");
}
@@ -1000,4 +1000,15 @@
getDevice().pushFile(file, TEST_UPDATE_LOCATION + "/" + fileName);
file.delete();
}
+
+ boolean hasService(String service) {
+ String command = "service check " + service;
+ try {
+ String commandOutput = getDevice().executeShellCommand(command);
+ return !commandOutput.contains("not found");
+ } catch (Exception e) {
+ CLog.w("Exception running '" + command + "': " + e);
+ return false;
+ }
+ }
}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
index 3a41d0f..09c05aa 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
@@ -2095,6 +2095,11 @@
runDeviceTestsAsUser(DEVICE_ADMIN_PKG, className, testName, mUserId);
}
+ protected void executeDeviceTestMethod(String className, String testName,
+ Map<String, String> params) throws Exception {
+ runDeviceTestsAsUser(DEVICE_ADMIN_PKG, className, testName, mUserId, params);
+ }
+
private void installAppPermissionAppAsUser()
throws FileNotFoundException, DeviceNotAvailableException {
installAppAsUser(PERMISSIONS_APP_APK, false, mUserId);
@@ -2312,19 +2317,4 @@
getDevice().executeShellCommand(
restricted ? RESTRICT_BACKGROUND_ON_CMD : RESTRICT_BACKGROUND_OFF_CMD);
}
-
- // TODO: copied from RequiredServiceRule, which is on compatibility-device-util
- // (and we use compatibility-host-util)
- public boolean hasService(String service) {
- // TODO: ideally should call SystemServiceManager directly, but we would need to open
- // some @Testing APIs for that.
- String command = "service check " + service;
- try {
- String commandOutput = getDevice().executeShellCommand(command);
- return !commandOutput.contains("not found");
- } catch (Exception e) {
- CLog.w("Exception running '" + command + "': " + e);
- return false;
- }
- }
}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
index a4e8877..e45e647 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
@@ -78,9 +78,6 @@
private static final String TEST_APP_PKG = "android.packageinstaller.emptytestapp.cts";
private static final String TEST_APP_LOCATION = "/data/local/tmp/cts/packageinstaller/";
- private static final String ARG_SECURITY_LOGGING_BATCH_NUMBER = "batchNumber";
- private static final int SECURITY_EVENTS_BATCH_SIZE = 100;
-
private static final String ARG_NETWORK_LOGGING_BATCH_COUNT = "batchCount";
private static final String LAUNCHER_TESTS_HAS_LAUNCHER_ACTIVITY_APK =
@@ -456,97 +453,6 @@
}
@Test
- public void testSecurityLoggingWithTwoUsers() throws Exception {
- if (!mHasFeature || !canCreateAdditionalUsers(1)) {
- return;
- }
-
- final int userId = createUser();
- try {
- // The feature can be enabled, but in a "paused" state. Attempting to retrieve logs
- // should throw security exception.
- executeDeviceTestMethod(".SecurityLoggingTest", "testEnablingSecurityLogging");
- executeDeviceTestMethod(".SecurityLoggingTest",
- "testRetrievingSecurityLogsThrowsSecurityException");
- executeDeviceTestMethod(".SecurityLoggingTest",
- "testRetrievingPreviousSecurityLogsThrowsSecurityException");
- } finally {
- removeUser(userId);
- executeDeviceTestMethod(".SecurityLoggingTest", "testDisablingSecurityLogging");
- }
- }
-
- @FlakyTest(bugId = 137093665)
- @Test
- public void testSecurityLoggingWithSingleUser() throws Exception {
- if (!mHasFeature) {
- return;
- }
- // Backup stay awake setting because testGenerateLogs() will turn it off.
- final String stayAwake = getDevice().getSetting("global", "stay_on_while_plugged_in");
- try {
- // Turn logging on.
- executeDeviceTestMethod(".SecurityLoggingTest", "testEnablingSecurityLogging");
- // Reboot to ensure ro.device_owner is set to true in logd and logging is on.
- rebootAndWaitUntilReady();
-
- // Generate various types of events on device side and check that they are logged.
- executeDeviceTestMethod(".SecurityLoggingTest", "testGenerateLogs");
- getDevice().executeShellCommand("dpm force-security-logs");
- executeDeviceTestMethod(".SecurityLoggingTest", "testVerifyGeneratedLogs");
-
- // Reboot the device, so the security event ids are reset.
- rebootAndWaitUntilReady();
-
- // Verify event ids are consistent across a consecutive batch.
- for (int batchNumber = 0; batchNumber < 3; batchNumber++) {
- generateDummySecurityLogs();
- getDevice().executeShellCommand("dpm force-security-logs");
- executeDeviceTestMethod(".SecurityLoggingTest", "testVerifyLogIds",
- Collections.singletonMap(ARG_SECURITY_LOGGING_BATCH_NUMBER,
- Integer.toString(batchNumber)));
- }
-
- // Immediately attempting to fetch events again should fail.
- executeDeviceTestMethod(".SecurityLoggingTest",
- "testSecurityLoggingRetrievalRateLimited");
- // Turn logging off.
- executeDeviceTestMethod(".SecurityLoggingTest", "testDisablingSecurityLogging");
- } finally {
- // Restore stay awake setting.
- if (stayAwake != null) {
- getDevice().setSetting("global", "stay_on_while_plugged_in", stayAwake);
- }
- }
- }
-
- @Test
- public void testSecurityLoggingEnabledLogged() throws Exception {
- if (!mHasFeature || !isStatsdEnabled(getDevice())) {
- return;
- }
- assertMetricsLogged(getDevice(), () -> {
- executeDeviceTestMethod(".SecurityLoggingTest", "testEnablingSecurityLogging");
- executeDeviceTestMethod(".SecurityLoggingTest", "testDisablingSecurityLogging");
- }, new DevicePolicyEventWrapper.Builder(EventId.SET_SECURITY_LOGGING_ENABLED_VALUE)
- .setAdminPackageName(DEVICE_OWNER_PKG)
- .setBoolean(true)
- .build(),
- new DevicePolicyEventWrapper.Builder(EventId.SET_SECURITY_LOGGING_ENABLED_VALUE)
- .setAdminPackageName(DEVICE_OWNER_PKG)
- .setBoolean(false)
- .build());
-
- }
-
- private void generateDummySecurityLogs() throws DeviceNotAvailableException {
- // Trigger security events of type TAG_ADB_SHELL_CMD.
- for (int i = 0; i < SECURITY_EVENTS_BATCH_SIZE; i++) {
- getDevice().executeShellCommand("echo just_testing_" + i);
- }
- }
-
- @Test
public void testNetworkLoggingWithTwoUsers() throws Exception {
if (!mHasFeature || !canCreateAdditionalUsers(1)) {
return;
@@ -789,14 +695,6 @@
}
@Test
- public void testRequestSetLocationProviderAllowed() throws Exception {
- if (!mHasFeature) {
- return;
- }
- executeDeviceOwnerTest("RequestSetLocationProviderAllowedTest");
- }
-
- @Test
public void testDeviceOwnerProvisioning() throws Exception {
if (!mHasFeature) {
return;
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileCrossProfileTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileCrossProfileTest.java
index 6e7477b..450dc44 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileCrossProfileTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileCrossProfileTest.java
@@ -73,7 +73,7 @@
if (isStatsdEnabled(getDevice())) {
assertMetricsLogged(getDevice(), () -> {
runDeviceTestsAsUser(
- MANAGED_PROFILE_PKG, MANAGED_PROFILE_PKG + ".ManagedProfileTest",
+ MANAGED_PROFILE_PKG, MANAGED_PROFILE_PKG + ".CrossProfileIntentFilterTest",
"testAddCrossProfileIntentFilter_all", mProfileUserId);
}, new DevicePolicyEventWrapper.Builder(ADD_CROSS_PROFILE_INTENT_FILTER_VALUE)
.setAdminPackageName(MANAGED_PROFILE_PKG)
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedDeviceOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedDeviceOwnerTest.java
index d28ecd9..794cb06 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedDeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedDeviceOwnerTest.java
@@ -37,6 +37,7 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -49,6 +50,9 @@
private static final String DELEGATION_NETWORK_LOGGING = "delegation-network-logging";
+ private static final String ARG_SECURITY_LOGGING_BATCH_NUMBER = "batchNumber";
+ private static final int SECURITY_EVENTS_BATCH_SIZE = 100;
+
@Override
public void setUp() throws Exception {
super.setUp();
@@ -302,6 +306,97 @@
.build());
}
+ @FlakyTest(bugId = 137093665)
+ @Test
+ public void testSecurityLoggingWithSingleUser() throws Exception {
+ if (!mHasFeature) {
+ return;
+ }
+ // Backup stay awake setting because testGenerateLogs() will turn it off.
+ final String stayAwake = getDevice().getSetting("global", "stay_on_while_plugged_in");
+ try {
+ // Turn logging on.
+ executeDeviceTestMethod(".SecurityLoggingTest", "testEnablingSecurityLogging");
+ // Reboot to ensure ro.device_owner is set to true in logd and logging is on.
+ rebootAndWaitUntilReady();
+ waitForUserUnlock(mUserId);
+
+ // Generate various types of events on device side and check that they are logged.
+ executeDeviceTestMethod(".SecurityLoggingTest", "testGenerateLogs");
+ getDevice().executeShellCommand("whoami"); // Generate adb command securty event
+ getDevice().executeShellCommand("dpm force-security-logs");
+ executeDeviceTestMethod(".SecurityLoggingTest", "testVerifyGeneratedLogs");
+
+ // Reboot the device, so the security event ids are reset.
+ rebootAndWaitUntilReady();
+
+ // Verify event ids are consistent across a consecutive batch.
+ for (int batchNumber = 0; batchNumber < 3; batchNumber++) {
+ generateDummySecurityLogs();
+ getDevice().executeShellCommand("dpm force-security-logs");
+ executeDeviceTestMethod(".SecurityLoggingTest", "testVerifyLogIds",
+ Collections.singletonMap(ARG_SECURITY_LOGGING_BATCH_NUMBER,
+ Integer.toString(batchNumber)));
+ }
+
+ // Immediately attempting to fetch events again should fail.
+ executeDeviceTestMethod(".SecurityLoggingTest",
+ "testSecurityLoggingRetrievalRateLimited");
+ } finally {
+ // Turn logging off.
+ executeDeviceTestMethod(".SecurityLoggingTest", "testDisablingSecurityLogging");
+ // Restore stay awake setting.
+ if (stayAwake != null) {
+ getDevice().setSetting("global", "stay_on_while_plugged_in", stayAwake);
+ }
+ }
+ }
+
+ @Test
+ public void testSecurityLoggingEnabledLogged() throws Exception {
+ if (!mHasFeature || !isStatsdEnabled(getDevice())) {
+ return;
+ }
+ assertMetricsLogged(getDevice(), () -> {
+ executeDeviceTestMethod(".SecurityLoggingTest", "testEnablingSecurityLogging");
+ executeDeviceTestMethod(".SecurityLoggingTest", "testDisablingSecurityLogging");
+ }, new DevicePolicyEventWrapper.Builder(EventId.SET_SECURITY_LOGGING_ENABLED_VALUE)
+ .setAdminPackageName(DEVICE_ADMIN_PKG)
+ .setBoolean(true)
+ .build(),
+ new DevicePolicyEventWrapper.Builder(EventId.SET_SECURITY_LOGGING_ENABLED_VALUE)
+ .setAdminPackageName(DEVICE_ADMIN_PKG)
+ .setBoolean(false)
+ .build());
+ }
+
+ @Test
+ public void testSecurityLoggingWithTwoUsers() throws Exception {
+ if (!mHasFeature || !canCreateAdditionalUsers(1)) {
+ return;
+ }
+
+ final int userId = createUser();
+ try {
+ // The feature can be enabled, but in a "paused" state. Attempting to retrieve logs
+ // should throw security exception.
+ executeDeviceTestMethod(".SecurityLoggingTest", "testEnablingSecurityLogging");
+ executeDeviceTestMethod(".SecurityLoggingTest",
+ "testRetrievingSecurityLogsThrowsSecurityException");
+ executeDeviceTestMethod(".SecurityLoggingTest",
+ "testRetrievingPreviousSecurityLogsThrowsSecurityException");
+ } finally {
+ removeUser(userId);
+ executeDeviceTestMethod(".SecurityLoggingTest", "testDisablingSecurityLogging");
+ }
+ }
+
+ private void generateDummySecurityLogs() throws Exception {
+ // Trigger security events of type TAG_ADB_SHELL_CMD.
+ for (int i = 0; i < SECURITY_EVENTS_BATCH_SIZE; i++) {
+ getDevice().executeShellCommand("echo just_testing_" + i);
+ }
+ }
private int createSecondaryUserAsProfileOwner() throws Exception {
final int userId = createUser();
installAppAsUser(INTENT_RECEIVER_APK, userId);
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/OrgOwnedProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/OrgOwnedProfileOwnerTest.java
index 207b1b4..9973fac 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/OrgOwnedProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/OrgOwnedProfileOwnerTest.java
@@ -273,6 +273,44 @@
.build());
}
+ @FlakyTest(bugId = 137093665)
+ @Test
+ public void testSecurityLogging() throws Exception {
+ if (!mHasFeature) {
+ return;
+ }
+ // Backup stay awake setting because testGenerateLogs() will turn it off.
+ final String stayAwake = getDevice().getSetting("global", "stay_on_while_plugged_in");
+ try {
+ // Turn logging on.
+ runDeviceTestsAsUser(DEVICE_ADMIN_PKG, ".SecurityLoggingTest",
+ "testEnablingSecurityLogging", mUserId);
+ // Reboot to ensure ro.device_owner is set to true in logd and logging is on.
+ rebootAndWaitUntilReady();
+ waitForUserUnlock(mUserId);
+
+ // Generate various types of events on device side and check that they are logged.
+ runDeviceTestsAsUser(DEVICE_ADMIN_PKG,".SecurityLoggingTest",
+ "testGenerateLogs", mUserId);
+ getDevice().executeShellCommand("whoami"); // Generate adb command securty event
+ getDevice().executeShellCommand("dpm force-security-logs");
+ runDeviceTestsAsUser(DEVICE_ADMIN_PKG, ".SecurityLoggingTest",
+ "testVerifyGeneratedLogs", mUserId);
+
+ // Immediately attempting to fetch events again should fail.
+ runDeviceTestsAsUser(DEVICE_ADMIN_PKG, ".SecurityLoggingTest",
+ "testSecurityLoggingRetrievalRateLimited", mUserId);
+ } finally {
+ // Turn logging off.
+ runDeviceTestsAsUser(DEVICE_ADMIN_PKG, ".SecurityLoggingTest",
+ "testDisablingSecurityLogging", mUserId);
+ // Restore stay awake setting.
+ if (stayAwake != null) {
+ getDevice().setSetting("global", "stay_on_while_plugged_in", stayAwake);
+ }
+ }
+ }
+
private void failToCreateUser() throws Exception {
String command ="pm create-user " + "TestUser_" + System.currentTimeMillis();
String commandOutput = getDevice().executeShellCommand(command);
@@ -282,25 +320,6 @@
assertEquals("Error:", tokens[0]);
}
- protected int createUser() throws Exception {
- String command ="pm create-user " + "TestUser_" + System.currentTimeMillis();
- String commandOutput = getDevice().executeShellCommand(command);
-
- String[] tokens = commandOutput.split("\\s+");
- assertTrue(tokens.length > 0);
- assertEquals("Success:", tokens[0]);
- int userId = Integer.parseInt(tokens[tokens.length-1]);
- startUser(userId);
- return userId;
- }
-
- protected void removeUser(int userId) throws Exception {
- if (listUsers().contains(userId) && userId != USER_SYSTEM) {
- String command = "am stop-user -w -f " + userId;
- getDevice().executeShellCommand(command);
- }
- }
-
@Test
public void testSetTime() throws Exception {
if (!mHasFeature) {
@@ -397,7 +416,7 @@
}
@Test
- public void testApplicationHidden() throws Exception {
+ public void testApplicationHiddenParent() throws Exception {
if (!mHasFeature) {
return;
}
@@ -465,14 +484,14 @@
}
runDeviceTestsAsUser(DEVICE_ADMIN_PKG, ".AccountManagementParentTest",
- "testCanSetAccountManagementRestriction", mUserId);
+ "testSetAccountManagementDisabledOnParent", mUserId);
installAppAsUser(DEVICE_ADMIN_APK, mPrimaryUserId);
try {
runDeviceTestsAsUser(DEVICE_ADMIN_PKG, ".AccountManagementParentTest",
- "testAccountRestricted", mPrimaryUserId);
+ "testAccountManagementDisabled", mPrimaryUserId);
} finally {
runDeviceTestsAsUser(DEVICE_ADMIN_PKG, ".AccountManagementParentTest",
- "testCanRemoveAccountManagementRestriction", mUserId);
+ "testEnableAccountManagement", mUserId);
}
}
@@ -532,17 +551,6 @@
userId, /* expectFailure */ false));
}
- private boolean hasService(String service) {
- String command = "service check " + service;
- try {
- String commandOutput = getDevice().executeShellCommand(command);
- return !commandOutput.contains("not found");
- } catch (Exception e) {
- LogUtil.CLog.w("Exception running '" + command + "': " + e);
- return false;
- }
- }
-
@Test
public void testSetPersonalAppsSuspendedLogged() throws Exception {
if (!mHasFeature|| !isStatsdEnabled(getDevice())) {
diff --git a/hostsidetests/jvmti/base/jni/Android.bp b/hostsidetests/jvmti/base/jni/Android.bp
index 3567373..4940df3 100644
--- a/hostsidetests/jvmti/base/jni/Android.bp
+++ b/hostsidetests/jvmti/base/jni/Android.bp
@@ -17,6 +17,7 @@
srcs: [
"cts_agent.cpp",
+ "cts_logging.cpp",
"tagging.cpp",
"tracking.cpp",
"redefine.cpp",
diff --git a/hostsidetests/jvmti/base/jni/cts_agent.cpp b/hostsidetests/jvmti/base/jni/cts_agent.cpp
index 3f3a836..55f2471 100644
--- a/hostsidetests/jvmti/base/jni/cts_agent.cpp
+++ b/hostsidetests/jvmti/base/jni/cts_agent.cpp
@@ -29,6 +29,7 @@
extern void register_android_jvmti_cts_JvmtiRedefineClassesTest(jvmtiEnv*, JNIEnv*);
extern void register_android_jvmti_cts_JvmtiTaggingTest(jvmtiEnv*, JNIEnv*);
extern void register_android_jvmti_cts_JvmtiTrackingTest(jvmtiEnv*, JNIEnv*);
+extern void register_android_jvmti_cts_JvmtiRunTestBasedTest(jvmtiEnv*, JNIEnv*);
static void InformMainAttach(jvmtiEnv* jenv,
JNIEnv* env,
@@ -42,6 +43,7 @@
register_android_jvmti_cts_JvmtiRedefineClassesTest(jenv, env);
register_android_jvmti_cts_JvmtiTaggingTest(jenv, env);
register_android_jvmti_cts_JvmtiTrackingTest(jenv, env);
+ register_android_jvmti_cts_JvmtiRunTestBasedTest(jenv, env);
// Use JNI to load the class.
ScopedLocalRef<jclass> klass(env, GetClass(jenv, env, class_name, nullptr));
diff --git a/hostsidetests/jvmti/base/jni/cts_logging.cpp b/hostsidetests/jvmti/base/jni/cts_logging.cpp
new file mode 100644
index 0000000..b37e1f9
--- /dev/null
+++ b/hostsidetests/jvmti/base/jni/cts_logging.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <jni.h>
+#include <jvmti.h>
+
+#include "android-base/logging.h"
+#include "jni_binder.h"
+#include "jvmti_helper.h"
+#include "scoped_local_ref.h"
+#include "test_env.h"
+
+namespace art {
+
+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));
+}
+
+static JNINativeMethod gMethods[] = {
+ { "setupExtraLogging", "()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));
+ if (klass.get() == nullptr) {
+ env->ExceptionClear();
+ return;
+ }
+
+ env->RegisterNatives(klass.get(), gMethods, sizeof(gMethods) / sizeof(JNINativeMethod));
+ if (env->ExceptionCheck()) {
+ env->ExceptionClear();
+ LOG(ERROR) << "Could not register natives for JvmtiRedefineClassesTest class";
+ }
+}
+
+} // namespace art
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 fcb718a..a59fd3f 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
@@ -18,11 +18,14 @@
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
+import java.io.IOException;
+import java.io.OutputStream;
import java.io.PrintStream;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
import android.content.pm.PackageManager;
+import android.util.Log;
import org.junit.After;
import org.junit.Before;
@@ -36,13 +39,49 @@
private PrintStream oldOut, oldErr;
private ByteArrayOutputStream bufferedOut, bufferedErr;
+ private class TeeLogcatOutputStream extends OutputStream {
+ private OutputStream os;
+ private ByteArrayOutputStream lc_os;
+ public TeeLogcatOutputStream(OutputStream os) {
+ this.lc_os = new ByteArrayOutputStream();
+ this.os = os;
+ }
+ public void write(int b) throws IOException {
+ os.write(b);
+ if (b == (int)'\n') {
+ lc_os.flush();
+ Log.i(mActivity.getPackageName(), "Test Output: " + lc_os.toString());
+ lc_os.reset();
+ } else {
+ lc_os.write(b);
+ }
+ }
+ public void close() throws IOException {
+ flush();
+ os.close();
+ lc_os.close();
+ }
+ public void flush() throws IOException {
+ os.flush();
+ lc_os.flush();
+ }
+ }
+
@Before
public void setUp() throws Exception {
oldOut = System.out;
oldErr = System.err;
+ bufferedOut = new ByteArrayOutputStream();
+ bufferedErr = new ByteArrayOutputStream();
- System.setOut(new PrintStream(bufferedOut = new ByteArrayOutputStream(), true));
- System.setErr(new PrintStream(bufferedErr = new ByteArrayOutputStream(), true));
+ if (doExtraLogging()) {
+ setupExtraLogging();
+ System.setOut(new PrintStream(new TeeLogcatOutputStream(bufferedOut), true));
+ System.setErr(new PrintStream(new TeeLogcatOutputStream(bufferedErr), true));
+ } else {
+ System.setOut(new PrintStream(bufferedOut, true));
+ System.setErr(new PrintStream(bufferedErr, true));
+ }
}
@After
@@ -51,6 +90,16 @@
System.setErr(oldErr);
}
+ private native void setupExtraLogging();
+
+ protected boolean doExtraLogging() throws Exception {
+ return mActivity
+ .getPackageManager()
+ .getApplicationInfo(mActivity.getPackageName(), PackageManager.GET_META_DATA)
+ .metaData
+ .getBoolean("android.jvmti.cts.run_test.extra_logging", /*defaultValue*/false);
+ }
+
protected int getTestNumber() throws Exception {
return mActivity.getPackageManager().getApplicationInfo(mActivity.getPackageName(),
PackageManager.GET_META_DATA).metaData.getInt("android.jvmti.cts.run_test_nr");
diff --git a/hostsidetests/jvmti/run-tests/test-1924/app/AndroidManifest.xml b/hostsidetests/jvmti/run-tests/test-1924/app/AndroidManifest.xml
index 4388209..176ef69 100644
--- a/hostsidetests/jvmti/run-tests/test-1924/app/AndroidManifest.xml
+++ b/hostsidetests/jvmti/run-tests/test-1924/app/AndroidManifest.xml
@@ -21,6 +21,8 @@
<application android:debuggable="true">
<uses-library android:name="android.test.runner" />
<meta-data android:name="android.jvmti.cts.run_test_nr" android:value="1924" />
+ <!-- Perform extra logging to try to get to the bottom of b/144947842 -->
+ <meta-data android:name="android.jvmti.cts.run_test.extra_logging" android:value="true" />
<activity android:name="android.jvmti.JvmtiActivity" >
</activity>
</application>
diff --git a/hostsidetests/jvmti/run-tests/test-1925/app/AndroidManifest.xml b/hostsidetests/jvmti/run-tests/test-1925/app/AndroidManifest.xml
index b3fab4f..9b8f768 100644
--- a/hostsidetests/jvmti/run-tests/test-1925/app/AndroidManifest.xml
+++ b/hostsidetests/jvmti/run-tests/test-1925/app/AndroidManifest.xml
@@ -21,6 +21,8 @@
<application android:debuggable="true">
<uses-library android:name="android.test.runner" />
<meta-data android:name="android.jvmti.cts.run_test_nr" android:value="1925" />
+ <!-- Perform extra logging to try to get to the bottom of b/144947842 -->
+ <meta-data android:name="android.jvmti.cts.run_test.extra_logging" android:value="true" />
<activity android:name="android.jvmti.JvmtiActivity" >
</activity>
</application>
diff --git a/hostsidetests/jvmti/run-tests/test-1926/app/AndroidManifest.xml b/hostsidetests/jvmti/run-tests/test-1926/app/AndroidManifest.xml
index ee5da05..a07a28f 100644
--- a/hostsidetests/jvmti/run-tests/test-1926/app/AndroidManifest.xml
+++ b/hostsidetests/jvmti/run-tests/test-1926/app/AndroidManifest.xml
@@ -21,6 +21,8 @@
<application android:debuggable="true">
<uses-library android:name="android.test.runner" />
<meta-data android:name="android.jvmti.cts.run_test_nr" android:value="1926" />
+ <!-- Perform extra logging to try to get to the bottom of b/144947842 -->
+ <meta-data android:name="android.jvmti.cts.run_test.extra_logging" android:value="true" />
<activity android:name="android.jvmti.JvmtiActivity" >
</activity>
</application>
diff --git a/hostsidetests/jvmti/run-tests/test-1936/app/AndroidManifest.xml b/hostsidetests/jvmti/run-tests/test-1936/app/AndroidManifest.xml
index 57cf5cd..d51b1b6 100644
--- a/hostsidetests/jvmti/run-tests/test-1936/app/AndroidManifest.xml
+++ b/hostsidetests/jvmti/run-tests/test-1936/app/AndroidManifest.xml
@@ -21,6 +21,8 @@
<application android:debuggable="true">
<uses-library android:name="android.test.runner" />
<meta-data android:name="android.jvmti.cts.run_test_nr" android:value="1936" />
+ <!-- Perform extra logging to try to get to the bottom of b/144947842 -->
+ <meta-data android:name="android.jvmti.cts.run_test.extra_logging" android:value="true" />
<activity android:name="android.jvmti.JvmtiActivity" >
</activity>
</application>
diff --git a/hostsidetests/jvmti/run-tests/test-1982/app/AndroidManifest.xml b/hostsidetests/jvmti/run-tests/test-1982/app/AndroidManifest.xml
index 1bed7f1..1d29560 100644
--- a/hostsidetests/jvmti/run-tests/test-1982/app/AndroidManifest.xml
+++ b/hostsidetests/jvmti/run-tests/test-1982/app/AndroidManifest.xml
@@ -21,6 +21,8 @@
<application android:debuggable="true">
<uses-library android:name="android.test.runner" />
<meta-data android:name="android.jvmti.cts.run_test_nr" android:value="1982" />
+ <!-- Perform extra logging to try to get to the bottom of b/144947842 -->
+ <meta-data android:name="android.jvmti.cts.run_test.extra_logging" android:value="true" />
<activity android:name="android.jvmti.JvmtiActivity" >
</activity>
</application>
diff --git a/hostsidetests/jvmti/run-tests/test-1995/app/AndroidManifest.xml b/hostsidetests/jvmti/run-tests/test-1995/app/AndroidManifest.xml
index 6f1d556..b04fa7b 100644
--- a/hostsidetests/jvmti/run-tests/test-1995/app/AndroidManifest.xml
+++ b/hostsidetests/jvmti/run-tests/test-1995/app/AndroidManifest.xml
@@ -21,6 +21,8 @@
<application android:debuggable="true">
<uses-library android:name="android.test.runner" />
<meta-data android:name="android.jvmti.cts.run_test_nr" android:value="1995" />
+ <!-- Perform extra logging to try to get to the bottom of b/144947842 -->
+ <meta-data android:name="android.jvmti.cts.run_test.extra_logging" android:value="true" />
<activity android:name="android.jvmti.JvmtiActivity" >
</activity>
</application>
diff --git a/hostsidetests/jvmti/run-tests/test-2004/app/AndroidManifest.xml b/hostsidetests/jvmti/run-tests/test-2004/app/AndroidManifest.xml
index c5ecaec..673d7d0 100644
--- a/hostsidetests/jvmti/run-tests/test-2004/app/AndroidManifest.xml
+++ b/hostsidetests/jvmti/run-tests/test-2004/app/AndroidManifest.xml
@@ -21,6 +21,8 @@
<application android:debuggable="true">
<uses-library android:name="android.test.runner" />
<meta-data android:name="android.jvmti.cts.run_test_nr" android:value="2004" />
+ <!-- Perform extra logging to try to get to the bottom of b/144947842 -->
+ <meta-data android:name="android.jvmti.cts.run_test.extra_logging" android:value="true" />
<activity android:name="android.jvmti.JvmtiActivity" >
</activity>
</application>
diff --git a/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/DeviceJUnit4ClassRunnerWithParameters.java b/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/DeviceJUnit4ClassRunnerWithParameters.java
index f8e5576..944e258 100644
--- a/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/DeviceJUnit4ClassRunnerWithParameters.java
+++ b/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/DeviceJUnit4ClassRunnerWithParameters.java
@@ -18,12 +18,15 @@
import com.android.tradefed.build.IBuildInfo;
import com.android.tradefed.config.Option;
import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.invoker.TestInformation;
import com.android.tradefed.testtype.HostTest;
import com.android.tradefed.testtype.IAbi;
import com.android.tradefed.testtype.IAbiReceiver;
import com.android.tradefed.testtype.IBuildReceiver;
import com.android.tradefed.testtype.IDeviceTest;
import com.android.tradefed.testtype.ISetOptionReceiver;
+import com.android.tradefed.testtype.ITestInformationReceiver;
+
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@@ -41,7 +44,7 @@
* Custom JUnit4 parameterized test runner that also accommodate {@link IDeviceTest}.
*/
public class DeviceJUnit4ClassRunnerWithParameters extends BlockJUnit4ClassRunnerWithParameters
- implements IDeviceTest, IBuildReceiver, IAbiReceiver, ISetOptionReceiver {
+ implements IDeviceTest, IBuildReceiver, IAbiReceiver, ISetOptionReceiver, ITestInformationReceiver {
@Option(
name = HostTest.SET_OPTION_NAME,
@@ -49,6 +52,7 @@
)
private Set<String> mKeyValueOptions = new HashSet<>();
+ private TestInformation mTestInformation;
private ITestDevice mDevice;
private IBuildInfo mBuildInfo;
private IAbi mAbi;
@@ -78,6 +82,15 @@
return mDevice;
}
+ @Override
+ public void setTestInformation(TestInformation testInformation) {
+ mTestInformation = testInformation;
+ }
+
+ @Override
+ public TestInformation getTestInformation() {
+ return mTestInformation;
+ }
@Override
public Description getDescription() {
@@ -122,6 +135,9 @@
if (testObj instanceof IAbiReceiver) {
((IAbiReceiver) testObj).setAbi(mAbi);
}
+ if (testObj instanceof ITestInformationReceiver) {
+ ((ITestInformationReceiver) testObj).setTestInformation(mTestInformation);
+ }
HostTest.setOptionToLoadedObject(testObj, new ArrayList<String>(mKeyValueOptions));
return testObj;
}
diff --git a/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/DeviceJUnit4Parameterized.java b/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/DeviceJUnit4Parameterized.java
index e28d81d..ea7ce7f 100644
--- a/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/DeviceJUnit4Parameterized.java
+++ b/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/DeviceJUnit4Parameterized.java
@@ -20,6 +20,7 @@
import com.android.tradefed.config.Option;
import com.android.tradefed.config.OptionSetter;
import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.invoker.TestInformation;
import com.android.tradefed.log.LogUtil.CLog;
import com.android.tradefed.testtype.HostTest;
import com.android.tradefed.testtype.IAbi;
@@ -27,20 +28,21 @@
import com.android.tradefed.testtype.IBuildReceiver;
import com.android.tradefed.testtype.IDeviceTest;
import com.android.tradefed.testtype.ISetOptionReceiver;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import org.junit.runner.Description;
+import com.android.tradefed.testtype.ITestInformationReceiver;
+
import org.junit.runner.Runner;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.Parameterized;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
/**
* Custom JUnit4 parameterized test runner that also accommodate {@link IDeviceTest}.
*/
public class DeviceJUnit4Parameterized extends Parameterized
- implements IDeviceTest, IBuildReceiver, IAbiReceiver, ISetOptionReceiver {
+ implements IDeviceTest, IBuildReceiver, IAbiReceiver, ISetOptionReceiver, ITestInformationReceiver {
@Option(
name = HostTest.SET_OPTION_NAME,
@@ -49,6 +51,7 @@
private Set<String> mKeyValueOptions = new HashSet<>();
private ITestDevice mDevice;
+ private TestInformation mTestInformation;
private List<Runner> mRunners;
public DeviceJUnit4Parameterized(Class<?> klass) throws Throwable {
@@ -89,13 +92,27 @@
return mDevice;
}
-
@Override
protected List<Runner> getChildren() {
return mRunners;
}
@Override
+ public void setTestInformation(TestInformation testInformation) {
+ mTestInformation = testInformation;
+ for (Runner runner : mRunners) {
+ if (runner instanceof ITestInformationReceiver) {
+ ((ITestInformationReceiver) runner).setTestInformation(mTestInformation);
+ }
+ }
+ }
+
+ @Override
+ public TestInformation getTestInformation() {
+ return mTestInformation;
+ }
+
+ @Override
protected void runChild(Runner runner, RunNotifier notifier) {
try {
OptionSetter setter = new OptionSetter(runner);
diff --git a/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/MediaBitstreamsTest.java b/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/MediaBitstreamsTest.java
index 24a96a7..69a7d9c 100644
--- a/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/MediaBitstreamsTest.java
+++ b/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/MediaBitstreamsTest.java
@@ -25,12 +25,22 @@
import com.android.tradefed.config.OptionClass;
import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.invoker.TestInformation;
import com.android.tradefed.log.LogUtil.CLog;
import com.android.tradefed.testtype.IAbi;
import com.android.tradefed.testtype.IAbiReceiver;
import com.android.tradefed.testtype.IBuildReceiver;
import com.android.tradefed.testtype.IDeviceTest;
+import com.android.tradefed.testtype.ITestInformationReceiver;
import com.android.tradefed.util.FileUtil;
+
+import org.junit.Assert;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlPullParserFactory;
+
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileFilter;
@@ -53,18 +63,12 @@
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
-import org.junit.Assert;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlPullParserFactory;
/**
* Test that verifies video bitstreams decode pixel perfectly
*/
@OptionClass(alias="media-bitstreams-test")
-public abstract class MediaBitstreamsTest implements IDeviceTest, IBuildReceiver, IAbiReceiver {
+public abstract class MediaBitstreamsTest implements IDeviceTest, IBuildReceiver, IAbiReceiver, ITestInformationReceiver {
@Option(name = MediaBitstreams.OPT_HOST_BITSTREAMS_PATH,
description = "Absolute path of Ittiam bitstreams (host)",
@@ -132,6 +136,7 @@
private IAbi mAbi;
private ITestDevice mDevice;
+ private TestInformation mTestInfo;
static File getDefaultBitstreamsDir() {
File mediaDir = MediaPreparer.getDefaultMediaDir();
@@ -239,6 +244,16 @@
return mDevice;
}
+ @Override
+ public void setTestInformation(TestInformation testInformation) {
+ mTestInfo = testInformation;
+ }
+
+ @Override
+ public TestInformation getTestInformation() {
+ return mTestInfo;
+ }
+
/*
* Returns true if all necessary media files exist on the device, and false otherwise.
*
@@ -453,6 +468,7 @@
public void testGetBitstreamsFormats() throws DeviceNotAvailableException, IOException {
ReportProcessor processor = new ProcessBitstreamsFormats();
processor.processDeviceReport(
+ getTestInformation(),
getDevice(),
getCurrentMethod(),
MediaBitstreams.KEY_BITSTREAMS_FORMATS_XML);
@@ -497,6 +513,7 @@
SupportedBitstreamsProcessor preparer;
preparer = new SupportedBitstreamsProcessor(prefix, mDebugTargetDevice);
preparer.processDeviceReport(
+ getTestInformation(),
device,
MediaBitstreams.K_TEST_GET_SUPPORTED_BITSTREAMS,
MediaBitstreams.KEY_SUPPORTED_BITSTREAMS_TXT);
@@ -547,6 +564,7 @@
ReportProcessor processor;
processor = new ProcessBitstreamsValidation(toPush, curMethod);
processor.processDeviceReport(
+ getTestInformation(),
device,
curMethod,
MediaBitstreams.KEY_BITSTREAMS_VALIDATION_TXT);
diff --git a/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/ReportProcessor.java b/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/ReportProcessor.java
index b334b0b..c924cbc 100644
--- a/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/ReportProcessor.java
+++ b/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/ReportProcessor.java
@@ -19,6 +19,7 @@
import com.android.tradefed.config.Configuration;
import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.invoker.TestInformation;
import com.android.tradefed.log.LogUtil.CLog;
import com.android.tradefed.metrics.proto.MetricMeasurement.Metric;
import com.android.tradefed.result.ITestInvocationListener;
@@ -139,6 +140,7 @@
}
private boolean runDeviceTest(
+ TestInformation testInfo,
ITestDevice device, String method, String reportKey, int testTimeout,
long shellTimeout)
throws DeviceNotAvailableException {
@@ -160,7 +162,7 @@
// AndroidJUnitTest requires a IConfiguration to work properly, add a stub to this
// implementation to avoid an NPE.
instrTest.setConfiguration(new Configuration("stub", "stub"));
- instrTest.run(new MediaBitstreamsListener());
+ instrTest.run(testInfo, new MediaBitstreamsListener());
return checkFile(reportKey);
@@ -178,12 +180,12 @@
return true;
}
- void processDeviceReport(
+ void processDeviceReport(TestInformation testInfo,
ITestDevice device, String method, String reportKey)
throws DeviceNotAvailableException, IOException {
try {
setUp(device);
- while (!runDeviceTest(device, method, reportKey, 0, 0)) {
+ while (!runDeviceTest(testInfo, device, method, reportKey, 0, 0)) {
if (!recover(device, mMetrics.get(reportKey))) {
return;
}
diff --git a/hostsidetests/media/src/android/media/session/cts/MediaSessionManagerHostTest.java b/hostsidetests/media/src/android/media/session/cts/MediaSessionManagerHostTest.java
index 07fa856..750e98c 100644
--- a/hostsidetests/media/src/android/media/session/cts/MediaSessionManagerHostTest.java
+++ b/hostsidetests/media/src/android/media/session/cts/MediaSessionManagerHostTest.java
@@ -24,7 +24,6 @@
import android.media.cts.BaseMultiUserTest;
import android.media.cts.MediaSessionTestHelperConstants;
-
import android.platform.test.annotations.AppModeFull;
import android.platform.test.annotations.AppModeInstant;
import android.platform.test.annotations.RequiresDevice;
@@ -61,8 +60,6 @@
private final List<Integer> mNotificationListeners = new ArrayList<>();
- private boolean mNotificationListenerDisabled;
-
@Override
public void setUp() throws Exception {
super.setUp();
@@ -70,7 +67,6 @@
// Ensure that the previously running media session test helper app doesn't exist.
getDevice().uninstallPackage(MEDIA_SESSION_TEST_HELPER_PKG);
mNotificationListeners.clear();
- mNotificationListenerDisabled = "true".equals(getDevice().getProperty("ro.config.low_ram"));
}
@Override
@@ -101,11 +97,6 @@
}
private void testGetActiveSessions_primaryUser(boolean instant) throws Exception {
- if (mNotificationListenerDisabled) {
- CLog.logAndDisplay(LogLevel.INFO,
- "NotificationListener is disabled. Test won't run.");
- return;
- }
int primaryUserId = getDevice().getPrimaryUserId();
setAllowGetActiveSessionForTest(true, primaryUserId);
@@ -144,11 +135,6 @@
"Cannot create a new user. Skipping multi-user test cases.");
return;
}
- if (mNotificationListenerDisabled) {
- CLog.logAndDisplay(LogLevel.INFO,
- "NotificationListener is disabled. Test won't run.");
- return;
- }
// Test if another user can get the session.
int newUser = createAndStartUser();
@@ -183,11 +169,6 @@
"Cannot create a new user. Skipping multi-user test cases.");
return;
}
- if (mNotificationListenerDisabled) {
- CLog.logAndDisplay(LogLevel.INFO,
- "NotificationListener is disabled. Test won't run.");
- return;
- }
// Test if another restricted profile can get the session.
// Remove the created user first not to exceed system's user number limit.
@@ -223,11 +204,6 @@
"Device doesn't support managed profiles. Test won't run.");
return;
}
- if (mNotificationListenerDisabled) {
- CLog.logAndDisplay(LogLevel.INFO,
- "NotificationListener is disabled. Test won't run.");
- return;
- }
// Test if another managed profile can get the session.
// Remove the created user first not to exceed system's user number limit.
@@ -241,12 +217,6 @@
@AppModeFull
@RequiresDevice
public void testGetActiveSessions_noSession2() throws Exception {
- if (mNotificationListenerDisabled) {
- CLog.logAndDisplay(LogLevel.INFO,
- "NotificationListener is disabled. Test won't run.");
- return;
- }
-
int primaryUserId = getDevice().getPrimaryUserId();
setAllowGetActiveSessionForTest(true, primaryUserId);
@@ -264,12 +234,6 @@
@AppModeFull
@RequiresDevice
public void testGetActiveSessions_withSession2() throws Exception {
- if (mNotificationListenerDisabled) {
- CLog.logAndDisplay(LogLevel.INFO,
- "NotificationListener is disabled. Test won't run.");
- return;
- }
-
int primaryUserId = getDevice().getPrimaryUserId();
setAllowGetActiveSessionForTest(true, primaryUserId);
diff --git a/hostsidetests/net/app/src/com/android/cts/net/hostside/DumpOnFailureRule.java b/hostsidetests/net/app/src/com/android/cts/net/hostside/DumpOnFailureRule.java
index cedd62a..5ecb399 100644
--- a/hostsidetests/net/app/src/com/android/cts/net/hostside/DumpOnFailureRule.java
+++ b/hostsidetests/net/app/src/com/android/cts/net/hostside/DumpOnFailureRule.java
@@ -16,6 +16,7 @@
package com.android.cts.net.hostside;
import static com.android.cts.net.hostside.AbstractRestrictBackgroundNetworkTestCase.TAG;
+import static com.android.cts.net.hostside.AbstractRestrictBackgroundNetworkTestCase.TEST_APP2_PKG;
import static com.android.cts.net.hostside.AbstractRestrictBackgroundNetworkTestCase.TEST_PKG;
import android.os.Environment;
@@ -58,7 +59,7 @@
for (String cmd : new String[] {
"dumpsys netpolicy",
"dumpsys network_management",
- "dumpsys usagestats " + TEST_PKG,
+ "dumpsys usagestats " + TEST_PKG + " " + TEST_APP2_PKG,
"dumpsys usagestats appstandby",
}) {
dumpCommandOutput(out, cmd);
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java b/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
index 1ac8a18..d94316d 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
@@ -56,6 +56,7 @@
import com.android.os.AtomsProto.ProcessMemorySnapshot;
import com.android.os.AtomsProto.ProcessMemoryState;
import com.android.os.AtomsProto.ScheduledJobStateChanged;
+import com.android.os.AtomsProto.SnapshotMergeReported;
import com.android.os.AtomsProto.SyncStateChanged;
import com.android.os.AtomsProto.TestAtomReported;
import com.android.os.AtomsProto.VibratorStateChanged;
@@ -69,6 +70,7 @@
import com.google.common.collect.Range;
+import java.lang.ProcessBuilder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -123,6 +125,32 @@
assertThat(atom.getOomAdjScore()).isAtLeast(500);
}
+ public void testSnapshotMergeReported() throws Exception {
+ if (statsdDisabled()) {
+ return;
+ }
+
+ // Test is only valid for Virtual A/B devices
+ if (!"true".equals(getProperty("ro.virtual_ab.enabled"))) {
+ return;
+ }
+
+ final int atomTag = Atom.SNAPSHOT_MERGE_REPORTED_FIELD_NUMBER;
+ createAndUploadConfig(atomTag, false);
+ Thread.sleep(WAIT_TIME_SHORT);
+
+ Process process = new ProcessBuilder("snapshotctl", "--dry-run", "--report").start();
+
+ Thread.sleep(WAIT_TIME_SHORT);
+
+ List<EventMetricData> data = getEventMetricDataList();
+
+ SnapshotMergeReported atom = data.get(0).getAtom().getSnapshotMergeReported();
+ assertThat(atom.getFinalState()).isEqualTo(SnapshotMergeReported.UpdateState.MERGE_COMPLETED);
+ assertThat(atom.getDurationMillis()).isEqualTo(1234);
+ assertThat(atom.getIntermediateReboots()).isEqualTo(56);
+ }
+
public void testAppCrashOccurred() throws Exception {
if (statsdDisabled()) {
return;
diff --git a/hostsidetests/userspacereboot/AndroidTest.xml b/hostsidetests/userspacereboot/AndroidTest.xml
index 97f67af..5df919f 100644
--- a/hostsidetests/userspacereboot/AndroidTest.xml
+++ b/hostsidetests/userspacereboot/AndroidTest.xml
@@ -20,7 +20,7 @@
<option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
<option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
<option name="config-descriptor:metadata" key="parameter" value="not_secondary_user" />
- <test class="com.android.tradefed.testtype.HostTest" >
+ <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
<option name="class" value="com.android.cts.userspacereboot.host.UserspaceRebootHostTest" />
</test>
</configuration>
diff --git a/hostsidetests/userspacereboot/src/com/android/cts/userspacereboot/host/UserspaceRebootHostTest.java b/hostsidetests/userspacereboot/src/com/android/cts/userspacereboot/host/UserspaceRebootHostTest.java
index f953a1d..0100e6a 100644
--- a/hostsidetests/userspacereboot/src/com/android/cts/userspacereboot/host/UserspaceRebootHostTest.java
+++ b/hostsidetests/userspacereboot/src/com/android/cts/userspacereboot/host/UserspaceRebootHostTest.java
@@ -155,7 +155,7 @@
}
private void rebootUserspaceAndWaitForBootComplete() throws Exception {
- getDevice().setProperty("test.userspace_reboot.requested", "1");
+ assertThat(getDevice().setProperty("test.userspace_reboot.requested", "1")).isTrue();
getDevice().rebootUserspace();
assertWithMessage("Device did not boot withing 2 minutes").that(
getDevice().waitForBootComplete(Duration.ofMinutes(2).toMillis())).isTrue();
@@ -164,7 +164,11 @@
private void assertUserspaceRebootSucceed() throws Exception {
// If userspace reboot fails and fallback to hard reboot is triggered then
// test.userspace_reboot.requested won't be set.
- assertWithMessage("Userspace reboot failed and fallback to full reboot was triggered").that(
- getDevice().getProperty("test.userspace_reboot.requested")).isEqualTo("1");
+ final String bootReason = getDevice().getProperty("sys.boot.reason.last");
+ final boolean result = getDevice().getBooleanProperty("test.userspace_reboot.requested",
+ false);
+ assertWithMessage(
+ "Userspace reboot failed and fallback to full reboot was triggered. Boot reason: "
+ + "%s", bootReason).that(result).isTrue();
}
}
diff --git a/hostsidetests/webkit/app/src/com/android/cts/webkit/WebViewDeviceSideStartupTest.java b/hostsidetests/webkit/app/src/com/android/cts/webkit/WebViewDeviceSideStartupTest.java
index 80a8964..fae440b 100644
--- a/hostsidetests/webkit/app/src/com/android/cts/webkit/WebViewDeviceSideStartupTest.java
+++ b/hostsidetests/webkit/app/src/com/android/cts/webkit/WebViewDeviceSideStartupTest.java
@@ -174,6 +174,8 @@
.build());
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
.detectAll()
+ // TODO(b/149790106): Fix and remove.
+ .permitIncorrectContextUse()
.penaltyLog()
.penaltyDeath()
.build());
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/ConnectivityConstraintTest.java b/tests/JobScheduler/src/android/jobscheduler/cts/ConnectivityConstraintTest.java
index c0fada5..9c177cd 100644
--- a/tests/JobScheduler/src/android/jobscheduler/cts/ConnectivityConstraintTest.java
+++ b/tests/JobScheduler/src/android/jobscheduler/cts/ConnectivityConstraintTest.java
@@ -75,8 +75,7 @@
super.setUp();
mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE);
- mCm =
- (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
+ mCm = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
PackageManager packageManager = mContext.getPackageManager();
mHasWifi = packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI);
@@ -84,7 +83,9 @@
mBuilder =
new JobInfo.Builder(CONNECTIVITY_JOB_ID, kJobServiceComponent);
- mInitialWiFiState = mWifiManager.isWifiEnabled();
+ if (mHasWifi) {
+ mInitialWiFiState = mWifiManager.isWifiEnabled();
+ }
mInitialRestrictBackground = SystemUtil
.runShellCommand(getInstrumentation(), RESTRICT_BACKGROUND_GET_CMD)
.contains("enabled");
@@ -101,7 +102,7 @@
setDataSaverEnabled(mInitialRestrictBackground);
// Ensure that we leave WiFi in its previous state.
- if (mWifiManager.isWifiEnabled() != mInitialWiFiState) {
+ if (mHasWifi && mWifiManager.isWifiEnabled() != mInitialWiFiState) {
setWifiState(mInitialWiFiState, mCm, mWifiManager);
}
diff --git a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityServiceInfoTest.java b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityServiceInfoTest.java
index ada5019..d2f7c2d 100644
--- a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityServiceInfoTest.java
+++ b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityServiceInfoTest.java
@@ -98,7 +98,7 @@
| AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION
| AccessibilityServiceInfo.CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT);
assertEquals("foo.bar.Activity", speakingService.getSettingsActivityName());
- assertEquals(R.drawable.size_48x48, speakingService.getAnimatedImageRes());
+ assertNotNull(speakingService.loadAnimatedImage(getInstrumentation().getContext()));
assertEquals("Some description", speakingService.loadDescription(
getInstrumentation().getContext().getPackageManager()));
assertEquals("Some html description", speakingService.loadHtmlDescription(
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityMagnificationTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityMagnificationTest.java
index c832368..659aaf7 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityMagnificationTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityMagnificationTest.java
@@ -313,7 +313,7 @@
final Rect boundsInScreen = new Rect();
final DisplayMetrics displayMetrics = new DisplayMetrics();
buttonNode.getBoundsInScreen(boundsInScreen);
- mInstrumentation.getContext().getDisplay().getMetrics(displayMetrics);
+ activity.getDisplay().getMetrics(displayMetrics);
final Rect displayRect = new Rect(0, 0,
displayMetrics.widthPixels, displayMetrics.heightPixels);
// The boundsInScreen of button is adjusted to outside of screen by framework,
diff --git a/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java b/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java
index dc3c57e..c1a02ab 100644
--- a/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java
+++ b/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java
@@ -145,55 +145,58 @@
}
}
- public void testSetSecurityLoggingEnabled_failIfNotDeviceOwner() {
+ public void testSetSecurityLoggingEnabled_failIfNotOrganizationOwnedProfileOwner() {
if (!mDeviceAdmin) {
- Log.w(TAG, "Skipping testSetSecurityLoggingEnabled_failIfNotDeviceOwner");
+ Log.w(TAG, "Skipping testSetSecurityLoggingEnabled_"
+ + "failIfNotOrganizationOwnedProfileOwner");
return;
}
try {
mDevicePolicyManager.setSecurityLoggingEnabled(mComponent, true);
fail("did not throw expected SecurityException");
} catch (SecurityException e) {
- assertDeviceOwnerMessage(e.getMessage());
+ assertOrganizationOwnedProfileOwnerMessage(e.getMessage());
}
}
- public void testIsSecurityLoggingEnabled_failIfNotDeviceOwner() {
+ public void testIsSecurityLoggingEnabled_failIfNotOrganizationOwnedProfileOwner() {
if (!mDeviceAdmin) {
- Log.w(TAG, "Skipping testIsSecurityLoggingEnabled_failIfNotDeviceOwner");
+ Log.w(TAG, "Skipping testIsSecurityLoggingEnabled_"
+ + "failIfNotOrganizationOwnedProfileOwner");
return;
}
try {
mDevicePolicyManager.isSecurityLoggingEnabled(mComponent);
fail("did not throw expected SecurityException");
} catch (SecurityException e) {
- assertDeviceOwnerMessage(e.getMessage());
+ assertOrganizationOwnedProfileOwnerMessage(e.getMessage());
}
}
- public void testRetrieveSecurityLogs_failIfNotDeviceOwner() {
+ public void testRetrieveSecurityLogs_failIfNotOrganizationOwnedProfileOwner() {
if (!mDeviceAdmin) {
- Log.w(TAG, "Skipping testRetrieveSecurityLogs_failIfNotDeviceOwner");
+ Log.w(TAG, "Skipping testRetrieveSecurityLogs_failIfNotOrganizationOwnedProfileOwner");
return;
}
try {
mDevicePolicyManager.retrieveSecurityLogs(mComponent);
fail("did not throw expected SecurityException");
} catch (SecurityException e) {
- assertDeviceOwnerMessage(e.getMessage());
+ assertOrganizationOwnedProfileOwnerMessage(e.getMessage());
}
}
- public void testRetrievePreRebootSecurityLogs_failIfNotDeviceOwner() {
+ public void testRetrievePreRebootSecurityLogs_failIfNotOrganizationOwnedProfileOwner() {
if (!mDeviceAdmin) {
- Log.w(TAG, "Skipping testRetrievePreRebootSecurityLogs_failIfNotDeviceOwner");
+ Log.w(TAG, "Skipping testRetrievePreRebootSecurityLogs_"
+ + "failIfNotOrganizationOwnedProfileOwner");
return;
}
try {
mDevicePolicyManager.retrievePreRebootSecurityLogs(mComponent);
fail("did not throw expected SecurityException");
} catch (SecurityException e) {
- assertDeviceOwnerMessage(e.getMessage());
+ assertOrganizationOwnedProfileOwnerMessage(e.getMessage());
}
}
@@ -287,20 +290,6 @@
}
}
- public void testRequestSetLocationProviderEnabled_failIfNotDeviceOwner() {
- if (!mDeviceAdmin) {
- Log.w(TAG, "Skipping testRequestSetLocationProviderEnabled_failIfNotDeviceOwner");
- return;
- }
- try {
- mDevicePolicyManager.requestSetLocationProviderAllowed(mComponent, "test_provider",
- true);
- fail("did not throw expected SecurityException");
- } catch (SecurityException e) {
- assertDeviceOwnerMessage(e.getMessage());
- }
- }
-
public void testSetGlobalSetting_failIfNotDeviceOwner() {
if (!mDeviceAdmin) {
Log.w(TAG, "Skipping testSetGlobalSetting_failIfNotDeviceOwner");
diff --git a/tests/app/src/android/app/cts/NotificationManagerTest.java b/tests/app/src/android/app/cts/NotificationManagerTest.java
index 6115dfb..2c9ff16 100644
--- a/tests/app/src/android/app/cts/NotificationManagerTest.java
+++ b/tests/app/src/android/app/cts/NotificationManagerTest.java
@@ -731,10 +731,6 @@
}
public void testConsolidatedNotificationPolicy() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
-
final int originalFilter = mNotificationManager.getCurrentInterruptionFilter();
Policy origPolicy = mNotificationManager.getNotificationPolicy();
try {
@@ -794,10 +790,6 @@
}
public void testConsolidatedNotificationPolicyMultiRules() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
-
final int originalFilter = mNotificationManager.getCurrentInterruptionFilter();
Policy origPolicy = mNotificationManager.getNotificationPolicy();
try {
@@ -863,10 +855,6 @@
}
public void testPostPCanToggleAlarmsMediaSystemTest() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
-
toggleNotificationPolicyAccess(mContext.getPackageName(),
InstrumentationRegistry.getInstrumentation(), true);
@@ -897,10 +885,6 @@
}
public void testPostRCanToggleConversationsTest() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
-
toggleNotificationPolicyAccess(mContext.getPackageName(),
InstrumentationRegistry.getInstrumentation(), true);
@@ -1267,10 +1251,6 @@
}
public void testSuspendPackage() throws Exception {
- if (mActivityManager.isLowRamDevice() && !mPackageManager.hasSystemFeature(FEATURE_WATCH)) {
- return;
- }
-
toggleListenerAccess(TestNotificationListener.getId(),
InstrumentationRegistry.getInstrumentation(), true);
Thread.sleep(500); // wait for listener to be allowed
@@ -1313,10 +1293,6 @@
}
public void testSuspendedPackageSendsNotification() throws Exception {
- if (mActivityManager.isLowRamDevice() && !mPackageManager.hasSystemFeature(FEATURE_WATCH)) {
- return;
- }
-
toggleListenerAccess(TestNotificationListener.getId(),
InstrumentationRegistry.getInstrumentation(), true);
Thread.sleep(500); // wait for listener to be allowed
@@ -1405,10 +1381,6 @@
}
public void testShowBadging_ranking() throws Exception {
- if (mActivityManager.isLowRamDevice() && !mPackageManager.hasSystemFeature(FEATURE_WATCH)) {
- return;
- }
-
final int originalBadging = Settings.Secure.getInt(
mContext.getContentResolver(), Settings.Secure.NOTIFICATION_BADGING);
@@ -1461,10 +1433,6 @@
}
public void testGetSuppressedVisualEffectsOff_ranking() throws Exception {
- if (mActivityManager.isLowRamDevice() && !mPackageManager.hasSystemFeature(FEATURE_WATCH)) {
- return;
- }
-
toggleListenerAccess(TestNotificationListener.getId(),
InstrumentationRegistry.getInstrumentation(), true);
Thread.sleep(500); // wait for listener to be allowed
@@ -1491,10 +1459,6 @@
}
public void testGetSuppressedVisualEffects_ranking() throws Exception {
- if (mActivityManager.isLowRamDevice() && !mPackageManager.hasSystemFeature(FEATURE_WATCH)) {
- return;
- }
-
final int originalFilter = mNotificationManager.getCurrentInterruptionFilter();
NotificationManager.Policy origPolicy = mNotificationManager.getNotificationPolicy();
try {
@@ -1547,10 +1511,6 @@
}
public void testKeyChannelGroupOverrideImportanceExplanation_ranking() throws Exception {
- if (mActivityManager.isLowRamDevice() && !mPackageManager.hasSystemFeature(FEATURE_WATCH)) {
- return;
- }
-
toggleListenerAccess(TestNotificationListener.getId(),
InstrumentationRegistry.getInstrumentation(), true);
Thread.sleep(500); // wait for listener to be allowed
@@ -1952,10 +1912,6 @@
}
public void testTotalSilenceOnlyMuteStreams() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
-
final int originalFilter = mNotificationManager.getCurrentInterruptionFilter();
Policy origPolicy = mNotificationManager.getNotificationPolicy();
try {
@@ -1997,10 +1953,6 @@
}
public void testAlarmsOnlyMuteStreams() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
-
final int originalFilter = mNotificationManager.getCurrentInterruptionFilter();
Policy origPolicy = mNotificationManager.getNotificationPolicy();
try {
@@ -2042,10 +1994,6 @@
}
public void testAddAutomaticZenRule_configActivity() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
-
toggleNotificationPolicyAccess(mContext.getPackageName(),
InstrumentationRegistry.getInstrumentation(), true);
@@ -2058,10 +2006,6 @@
}
public void testUpdateAutomaticZenRule_configActivity() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
-
toggleNotificationPolicyAccess(mContext.getPackageName(),
InstrumentationRegistry.getInstrumentation(), true);
@@ -2076,10 +2020,6 @@
}
public void testRemoveAutomaticZenRule_configActivity() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
-
toggleNotificationPolicyAccess(mContext.getPackageName(),
InstrumentationRegistry.getInstrumentation(), true);
@@ -2095,10 +2035,6 @@
}
public void testSetAutomaticZenRuleState() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
-
toggleNotificationPolicyAccess(mContext.getPackageName(),
InstrumentationRegistry.getInstrumentation(), true);
@@ -2118,10 +2054,6 @@
}
public void testSetAutomaticZenRuleState_turnOff() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
-
toggleNotificationPolicyAccess(mContext.getPackageName(),
InstrumentationRegistry.getInstrumentation(), true);
@@ -2150,10 +2082,6 @@
}
public void testSetAutomaticZenRuleState_deletedRule() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
-
toggleNotificationPolicyAccess(mContext.getPackageName(),
InstrumentationRegistry.getInstrumentation(), true);
@@ -2178,10 +2106,6 @@
}
public void testSetAutomaticZenRuleState_multipleRules() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
-
toggleNotificationPolicyAccess(mContext.getPackageName(),
InstrumentationRegistry.getInstrumentation(), true);
@@ -2215,9 +2139,6 @@
}
public void testSetNotificationPolicy_P_setOldFields() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
toggleNotificationPolicyAccess(mContext.getPackageName(),
InstrumentationRegistry.getInstrumentation(), true);
Policy origPolicy = mNotificationManager.getNotificationPolicy();
@@ -2240,9 +2161,6 @@
}
public void testSetNotificationPolicy_P_setNewFields() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
toggleNotificationPolicyAccess(mContext.getPackageName(),
InstrumentationRegistry.getInstrumentation(), true);
Policy origPolicy = mNotificationManager.getNotificationPolicy();
@@ -2265,9 +2183,6 @@
}
public void testSetNotificationPolicy_P_setOldNewFields() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
toggleNotificationPolicyAccess(mContext.getPackageName(),
InstrumentationRegistry.getInstrumentation(), true);
Policy origPolicy = mNotificationManager.getNotificationPolicy();
@@ -2401,10 +2316,6 @@
public void testNotificationDelegate_cannotCancelNotificationsPostedByDelegator()
throws Exception {
- if (mActivityManager.isLowRamDevice() && !mPackageManager.hasSystemFeature(FEATURE_WATCH)) {
- return;
- }
-
toggleListenerAccess(TestNotificationListener.getId(),
InstrumentationRegistry.getInstrumentation(), true);
Thread.sleep(500); // wait for listener to be allowed
@@ -2555,10 +2466,6 @@
}
public void testShouldHideSilentStatusIcons() throws Exception {
- if (mActivityManager.isLowRamDevice() && !mPackageManager.hasSystemFeature(FEATURE_WATCH)) {
- return;
- }
-
try {
mNotificationManager.shouldHideSilentStatusBarIcons();
fail("Non-privileged apps should not get this information");
@@ -2573,10 +2480,6 @@
}
public void testMatchesCallFilter() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
-
// allow all callers
toggleNotificationPolicyAccess(mContext.getPackageName(),
InstrumentationRegistry.getInstrumentation(), true);
@@ -2634,10 +2537,6 @@
}
public void testNotificationListener_setNotificationsShown() throws Exception {
- if (mActivityManager.isLowRamDevice() && !mPackageManager.hasSystemFeature(FEATURE_WATCH)) {
- return;
- }
-
toggleListenerAccess(TestNotificationListener.getId(),
InstrumentationRegistry.getInstrumentation(), true);
Thread.sleep(500); // wait for listener to be allowed
@@ -2667,10 +2566,6 @@
}
public void testNotificationListener_getNotificationChannels() throws Exception {
- if (mActivityManager.isLowRamDevice() && !mPackageManager.hasSystemFeature(FEATURE_WATCH)) {
- return;
- }
-
toggleListenerAccess(TestNotificationListener.getId(),
InstrumentationRegistry.getInstrumentation(), true);
Thread.sleep(500); // wait for listener to be allowed
@@ -2687,10 +2582,6 @@
}
public void testNotificationListener_getNotificationChannelGroups() throws Exception {
- if (mActivityManager.isLowRamDevice() && !mPackageManager.hasSystemFeature(FEATURE_WATCH)) {
- return;
- }
-
toggleListenerAccess(TestNotificationListener.getId(),
InstrumentationRegistry.getInstrumentation(), true);
Thread.sleep(500); // wait for listener to be allowed
@@ -2706,10 +2597,6 @@
}
public void testNotificationListener_updateNotificationChannel() throws Exception {
- if (mActivityManager.isLowRamDevice() && !mPackageManager.hasSystemFeature(FEATURE_WATCH)) {
- return;
- }
-
toggleListenerAccess(TestNotificationListener.getId(),
InstrumentationRegistry.getInstrumentation(), true);
Thread.sleep(500); // wait for listener to be allowed
@@ -2730,10 +2617,6 @@
}
public void testNotificationListener_getActiveNotifications() throws Exception {
- if (mActivityManager.isLowRamDevice() && !mPackageManager.hasSystemFeature(FEATURE_WATCH)) {
- return;
- }
-
toggleListenerAccess(TestNotificationListener.getId(),
InstrumentationRegistry.getInstrumentation(), true);
Thread.sleep(500); // wait for listener to be allowed
@@ -2762,10 +2645,6 @@
public void testNotificationListener_getCurrentRanking() throws Exception {
- if (mActivityManager.isLowRamDevice() && !mPackageManager.hasSystemFeature(FEATURE_WATCH)) {
- return;
- }
-
toggleListenerAccess(TestNotificationListener.getId(),
InstrumentationRegistry.getInstrumentation(), true);
Thread.sleep(500); // wait for listener to be allowed
@@ -2780,10 +2659,6 @@
}
public void testNotificationListener_cancelNotifications() throws Exception {
- if (mActivityManager.isLowRamDevice() && !mPackageManager.hasSystemFeature(FEATURE_WATCH)) {
- return;
- }
-
toggleListenerAccess(TestNotificationListener.getId(),
InstrumentationRegistry.getInstrumentation(), true);
Thread.sleep(500); // wait for listener to be allowed
diff --git a/tests/autofillservice/Android.bp b/tests/autofillservice/Android.bp
index d39b86c..7882a76 100644
--- a/tests/autofillservice/Android.bp
+++ b/tests/autofillservice/Android.bp
@@ -17,6 +17,7 @@
defaults: ["cts_defaults"],
static_libs: [
"androidx.annotation_annotation",
+ "androidx.autofill_autofill",
"androidx.test.ext.junit",
"compatibility-device-util-axt",
"ctsdeviceutillegacy-axt",
diff --git a/tests/autofillservice/AndroidManifest.xml b/tests/autofillservice/AndroidManifest.xml
index cf21314..cd52ef5 100644
--- a/tests/autofillservice/AndroidManifest.xml
+++ b/tests/autofillservice/AndroidManifest.xml
@@ -164,6 +164,18 @@
</meta-data>
</service>
<service
+ android:name=".inline.InstrumentedAutoFillServiceInlineEnabled"
+ android:label="InstrumentedAutoFillServiceInlineEnabled"
+ android:permission="android.permission.BIND_AUTOFILL_SERVICE" >
+ <intent-filter>
+ <action android:name="android.service.autofill.AutofillService" />
+ </intent-filter>
+ <meta-data
+ android:name="android.autofill"
+ android:resource="@xml/autofill_service_inline_enabled">
+ </meta-data>
+ </service>
+ <service
android:name=".NoOpAutofillService"
android:label="NoOpAutofillService"
android:permission="android.permission.BIND_AUTOFILL_SERVICE" >
diff --git a/tests/autofillservice/res/xml/autofill_service_inline_enabled.xml b/tests/autofillservice/res/xml/autofill_service_inline_enabled.xml
new file mode 100644
index 0000000..6e4f2bb
--- /dev/null
+++ b/tests/autofillservice/res/xml/autofill_service_inline_enabled.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<autofill-service xmlns:android="http://schemas.android.com/apk/res/android"
+ android:supportsInlineSuggestions="true">
+</autofill-service>
diff --git a/tests/autofillservice/src/android/autofillservice/cts/AbstractLoginActivityTestCase.java b/tests/autofillservice/src/android/autofillservice/cts/AbstractLoginActivityTestCase.java
index e7c0cf7..e496c24 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/AbstractLoginActivityTestCase.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/AbstractLoginActivityTestCase.java
@@ -48,6 +48,13 @@
}
/**
+ * Performs a click on username.
+ */
+ protected void requestClickOnUsername() throws TimeoutException {
+ mUiBot.waitForWindowChange(() -> mActivity.onUsername(View::performClick));
+ }
+
+ /**
* Requests focus on username and expect no Window event happens.
*/
protected void requestFocusOnUsernameNoWindowChange() {
diff --git a/tests/autofillservice/src/android/autofillservice/cts/AutoFillServiceTestCase.java b/tests/autofillservice/src/android/autofillservice/cts/AutoFillServiceTestCase.java
index a5ac282..54986d6 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/AutoFillServiceTestCase.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/AutoFillServiceTestCase.java
@@ -31,11 +31,16 @@
import android.content.pm.PackageManager;
import android.provider.DeviceConfig;
import android.provider.Settings;
+import android.service.autofill.InlinePresentation;
import android.util.Log;
+import android.util.Size;
import android.view.autofill.AutofillManager;
+import android.view.inline.InlinePresentationSpec;
import android.widget.RemoteViews;
import androidx.annotation.NonNull;
+import androidx.autofill.InlinePresentationBuilder;
+import androidx.test.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.compatibility.common.util.DeviceConfigStateChangerRule;
@@ -44,6 +49,7 @@
import com.android.compatibility.common.util.SafeCleanerRule;
import com.android.compatibility.common.util.SettingsStateKeeperRule;
import com.android.compatibility.common.util.TestNameUtils;
+import com.android.cts.mockime.ImeSettings;
import com.android.cts.mockime.MockImeSessionRule;
import org.junit.AfterClass;
@@ -193,7 +199,10 @@
};
@ClassRule
- public static final MockImeSessionRule sMockImeSessionRule = new MockImeSessionRule();
+ public static final MockImeSessionRule sMockImeSessionRule = new MockImeSessionRule(
+ InstrumentationRegistry.getTargetContext(),
+ InstrumentationRegistry.getInstrumentation().getUiAutomation(),
+ new ImeSettings.Builder().setInlineSuggestionsEnabled(true));
protected static final RequiredFeatureRule sRequiredFeatureRule =
new RequiredFeatureRule(PackageManager.FEATURE_AUTOFILL);
@@ -416,6 +425,12 @@
return presentation;
}
+ protected InlinePresentation createInlinePresentation(String message) {
+ return new InlinePresentation(new InlinePresentationBuilder(message).build(),
+ new InlinePresentationSpec.Builder(new Size(100, 100), new Size(400, 100))
+ .build(), /* pinned= */ false);
+ }
+
@NonNull
protected AutofillManager getAutofillManager() {
return mContext.getSystemService(AutofillManager.class);
diff --git a/tests/autofillservice/src/android/autofillservice/cts/CannedFillResponse.java b/tests/autofillservice/src/android/autofillservice/cts/CannedFillResponse.java
index 5523e7a3..cd099d7 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/CannedFillResponse.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/CannedFillResponse.java
@@ -27,6 +27,7 @@
import android.service.autofill.FillCallback;
import android.service.autofill.FillContext;
import android.service.autofill.FillResponse;
+import android.service.autofill.InlinePresentation;
import android.service.autofill.SaveInfo;
import android.service.autofill.UserData;
import android.util.Log;
@@ -75,6 +76,7 @@
private final CharSequence mSaveDescription;
private final Bundle mExtras;
private final RemoteViews mPresentation;
+ private final InlinePresentation mInlinePresentation;
private final RemoteViews mHeader;
private final RemoteViews mFooter;
private final IntentSender mAuthentication;
@@ -106,6 +108,7 @@
mSaveType = builder.mSaveType;
mExtras = builder.mExtras;
mPresentation = builder.mPresentation;
+ mInlinePresentation = builder.mInlinePresentation;
mHeader = builder.mHeader;
mFooter = builder.mFooter;
mAuthentication = builder.mAuthentication;
@@ -227,7 +230,7 @@
}
if (mAuthenticationIds != null) {
builder.setAuthentication(getAutofillIds(nodeResolver, mAuthenticationIds),
- mAuthentication, mPresentation);
+ mAuthentication, mPresentation, mInlinePresentation);
}
if (mDisableDuration > 0) {
builder.disableAutofill(mDisableDuration);
@@ -278,6 +281,7 @@
+ ", failureMessage=" + mFailureMessage
+ ", saveDescription=" + mSaveDescription
+ ", hasPresentation=" + (mPresentation != null)
+ + ", hasInlinePresentation=" + (mInlinePresentation != null)
+ ", hasHeader=" + (mHeader != null)
+ ", hasFooter=" + (mFooter != null)
+ ", hasAuthentication=" + (mAuthentication != null)
@@ -313,6 +317,7 @@
public int mSaveType = -1;
private Bundle mExtras;
private RemoteViews mPresentation;
+ private InlinePresentation mInlinePresentation;
private RemoteViews mFooter;
private RemoteViews mHeader;
private IntentSender mAuthentication;
@@ -400,6 +405,14 @@
}
/**
+ * Sets the view to present the response in the UI.
+ */
+ public Builder setInlinePresentation(InlinePresentation inlinePresentation) {
+ mInlinePresentation = inlinePresentation;
+ return this;
+ }
+
+ /**
* Sets the authentication intent.
*/
public Builder setAuthentication(IntentSender authentication, String... ids) {
@@ -558,16 +571,20 @@
public static class CannedDataset {
private final Map<String, AutofillValue> mFieldValues;
private final Map<String, RemoteViews> mFieldPresentations;
+ private final Map<String, InlinePresentation> mFieldInlinePresentations;
private final Map<String, Pair<Boolean, Pattern>> mFieldFilters;
private final RemoteViews mPresentation;
+ private final InlinePresentation mInlinePresentation;
private final IntentSender mAuthentication;
private final String mId;
private CannedDataset(Builder builder) {
mFieldValues = builder.mFieldValues;
mFieldPresentations = builder.mFieldPresentations;
+ mFieldInlinePresentations = builder.mFieldInlinePresentations;
mFieldFilters = builder.mFieldFilters;
mPresentation = builder.mPresentation;
+ mInlinePresentation = builder.mInlinePresentation;
mAuthentication = builder.mAuthentication;
mId = builder.mId;
}
@@ -576,9 +593,13 @@
* Creates a new dataset, replacing the field ids by the real ids from the assist structure.
*/
Dataset asDataset(Function<String, ViewNode> nodeResolver) {
- final Dataset.Builder builder = (mPresentation == null)
- ? new Dataset.Builder()
- : new Dataset.Builder(mPresentation);
+ final Dataset.Builder builder = mPresentation != null
+ ? mInlinePresentation == null
+ ? new Dataset.Builder(mPresentation)
+ : new Dataset.Builder(mPresentation, mInlinePresentation)
+ : mInlinePresentation == null
+ ? new Dataset.Builder()
+ : new Dataset.Builder(mInlinePresentation);
if (mFieldValues != null) {
for (Map.Entry<String, AutofillValue> entry : mFieldValues.entrySet()) {
@@ -590,18 +611,34 @@
final AutofillId autofillId = node.getAutofillId();
final AutofillValue value = entry.getValue();
final RemoteViews presentation = mFieldPresentations.get(id);
+ final InlinePresentation inlinePresentation = mFieldInlinePresentations.get(id);
final Pair<Boolean, Pattern> filter = mFieldFilters.get(id);
if (presentation != null) {
if (filter == null) {
- builder.setValue(autofillId, value, presentation);
+ if (inlinePresentation != null) {
+ builder.setValue(autofillId, value, presentation,
+ inlinePresentation);
+ } else {
+ builder.setValue(autofillId, value, presentation);
+ }
} else {
- builder.setValue(autofillId, value, filter.second, presentation);
+ if (inlinePresentation != null) {
+ builder.setValue(autofillId, value, filter.second, presentation,
+ inlinePresentation);
+ } else {
+ builder.setValue(autofillId, value, filter.second, presentation);
+ }
}
} else {
- if (filter == null) {
- builder.setValue(autofillId, value);
+ if (inlinePresentation != null) {
+ builder.setInlinePresentation(autofillId, value,
+ filter != null ? filter.second : null, inlinePresentation);
} else {
- builder.setValue(autofillId, value, filter.second);
+ if (filter == null) {
+ builder.setValue(autofillId, value);
+ } else {
+ builder.setValue(autofillId, value, filter.second);
+ }
}
}
}
@@ -613,7 +650,9 @@
@Override
public String toString() {
return "CannedDataset " + mId + " : [hasPresentation=" + (mPresentation != null)
+ + ", hasInlinePresentation=" + (mInlinePresentation != null)
+ ", fieldPresentations=" + (mFieldPresentations)
+ + ", fieldInlinePresentations=" + (mFieldInlinePresentations)
+ ", hasAuthentication=" + (mAuthentication != null)
+ ", fieldValues=" + mFieldValues
+ ", fieldFilters=" + mFieldFilters + "]";
@@ -622,9 +661,12 @@
public static class Builder {
private final Map<String, AutofillValue> mFieldValues = new HashMap<>();
private final Map<String, RemoteViews> mFieldPresentations = new HashMap<>();
+ private final Map<String, InlinePresentation> mFieldInlinePresentations =
+ new HashMap<>();
private final Map<String, Pair<Boolean, Pattern>> mFieldFilters = new HashMap<>();
private RemoteViews mPresentation;
+ private InlinePresentation mInlinePresentation;
private IntentSender mAuthentication;
private String mId;
@@ -749,6 +791,35 @@
}
/**
+ * Sets the canned value of a field based on its {@code id}.
+ *
+ * <p>The meaning of the id is defined by the object using the canned dataset.
+ * For example, {@link InstrumentedAutoFillService.Replier} resolves the id based on
+ * {@link IdMode}.
+ */
+ public Builder setField(String id, String text, RemoteViews presentation,
+ InlinePresentation inlinePresentation) {
+ setField(id, text);
+ mFieldPresentations.put(id, presentation);
+ mFieldInlinePresentations.put(id, inlinePresentation);
+ return this;
+ }
+
+ /**
+ * Sets the canned value of a field based on its {@code id}.
+ *
+ * <p>The meaning of the id is defined by the object using the canned dataset.
+ * For example, {@link InstrumentedAutoFillService.Replier} resolves the id based on
+ * {@link IdMode}.
+ */
+ public Builder setField(String id, String text, RemoteViews presentation,
+ InlinePresentation inlinePresentation, Pattern filter) {
+ setField(id, text, presentation, inlinePresentation);
+ mFieldFilters.put(id, new Pair<>(true, filter));
+ return this;
+ }
+
+ /**
* Sets the view to present the response in the UI.
*/
public Builder setPresentation(RemoteViews presentation) {
@@ -757,6 +828,14 @@
}
/**
+ * Sets the view to present the response in the UI.
+ */
+ public Builder setInlinePresentation(InlinePresentation inlinePresentation) {
+ mInlinePresentation = inlinePresentation;
+ return this;
+ }
+
+ /**
* Sets the authentication intent.
*/
public Builder setAuthentication(IntentSender authentication) {
@@ -772,6 +851,9 @@
return this;
}
+ /**
+ * Builds the canned dataset.
+ */
public CannedDataset build() {
return new CannedDataset(this);
}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/Timeouts.java b/tests/autofillservice/src/android/autofillservice/cts/Timeouts.java
index d64aa41..a4799c8 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/Timeouts.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/Timeouts.java
@@ -26,7 +26,7 @@
private static final long ONE_TIMEOUT_TO_RULE_THEN_ALL_MS = 20_000;
private static final long ONE_NAPTIME_TO_RULE_THEN_ALL_MS = 2_000;
- static final long MOCK_IME_TIMEOUT_MS = 5_000;
+ public static final long MOCK_IME_TIMEOUT_MS = 5_000;
/**
* Timeout until framework binds / unbinds from service.
diff --git a/tests/autofillservice/src/android/autofillservice/cts/UiBot.java b/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
index 9287e71..136bcba 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
@@ -70,6 +70,7 @@
import com.android.compatibility.common.util.RetryableException;
import com.android.compatibility.common.util.Timeout;
+import com.android.cts.mockime.MockIme;
import java.io.File;
import java.io.FileInputStream;
@@ -94,6 +95,8 @@
private static final String RESOURCE_ID_SAVE_BUTTON_NO = "autofill_save_no";
private static final String RESOURCE_ID_SAVE_BUTTON_YES = "autofill_save_yes";
private static final String RESOURCE_ID_OVERFLOW = "overflow";
+ //TODO: Change magic constant
+ private static final String RESOURCE_ID_SUGGESTION_STRIP = "message";
private static final String RESOURCE_STRING_SAVE_TITLE = "autofill_save_title";
private static final String RESOURCE_STRING_SAVE_TITLE_WITH_TYPE =
@@ -132,6 +135,8 @@
private static final BySelector SAVE_UI_SELECTOR = By.res("android", RESOURCE_ID_SAVE_SNACKBAR);
private static final BySelector DATASET_HEADER_SELECTOR =
By.res("android", RESOURCE_ID_DATASET_HEADER);
+ private static final BySelector SUGGESTION_STRIP_SELECTOR =
+ By.res("android", RESOURCE_ID_SUGGESTION_STRIP);
// TODO: figure out a more reliable solution that does not depend on SystemUI resources.
private static final String SPLIT_WINDOW_DIVIDER_ID =
@@ -258,6 +263,14 @@
}
/**
+ * Asserts the suggestion strip was never shown.
+ */
+ public void assertNoSuggestionStripEver() throws Exception {
+ assertNeverShown("suggestion strip", SUGGESTION_STRIP_SELECTOR,
+ DATASET_PICKER_NOT_SHOWN_NAPTIME_MS);
+ }
+
+ /**
* Asserts the dataset chooser is shown and contains exactly the given datasets.
*
* @return the dataset picker object.
@@ -332,6 +345,32 @@
}
/**
+ * Asserts the suggestion strip on the {@link MockIme} is shown and contains the given number
+ * of child suggestions.
+ *
+ * @param childrenCount the expected number of children.
+ *
+ * @return the suggestion strip object
+ */
+ public UiObject2 assertSuggestionStrip(int childrenCount) throws Exception {
+ final UiObject2 strip = findSuggestionStrip(UI_TIMEOUT);
+ assertThat(strip.getChildCount()).isEqualTo(childrenCount);
+ return strip;
+ }
+
+ /**
+ * Selects the suggestion in the {@link MockIme}'s suggestion strip at the given index.
+ *
+ * @param index the index of the suggestion to select.
+ */
+ public void selectSuggestion(int index) throws Exception {
+ final UiObject2 strip = findSuggestionStrip(UI_TIMEOUT);
+ assertThat(index).isAtLeast(0);
+ assertThat(index).isLessThan(strip.getChildCount());
+ strip.getChildren().get(index).click();
+ }
+
+ /**
* Gets the text of this object children.
*/
public List<String> getChildrenAsText(UiObject2 object) {
@@ -1037,6 +1076,10 @@
return picker;
}
+ private UiObject2 findSuggestionStrip(Timeout timeout) throws Exception {
+ return waitForObject(SUGGESTION_STRIP_SELECTOR, timeout);
+ }
+
/**
* Asserts a given object has the expected accessibility title.
*/
diff --git a/tests/autofillservice/src/android/autofillservice/cts/inline/InlineLoginActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineLoginActivityTest.java
new file mode 100644
index 0000000..39139eb
--- /dev/null
+++ b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineLoginActivityTest.java
@@ -0,0 +1,173 @@
+/*
+ * 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.autofillservice.cts.inline;
+
+import static android.autofillservice.cts.Helper.ID_PASSWORD;
+import static android.autofillservice.cts.Helper.ID_USERNAME;
+import static android.autofillservice.cts.Helper.assertTextIsSanitized;
+import static android.autofillservice.cts.Helper.findAutofillIdByResourceId;
+import static android.autofillservice.cts.Helper.findNodeByResourceId;
+import static android.autofillservice.cts.Helper.getContext;
+import static android.autofillservice.cts.InstrumentedAutoFillService.waitUntilDisconnected;
+import static android.autofillservice.cts.Timeouts.MOCK_IME_TIMEOUT_MS;
+import static android.autofillservice.cts.inline.InstrumentedAutoFillServiceInlineEnabled.SERVICE_NAME;
+
+import static com.android.cts.mockime.ImeEventStreamTestUtils.editorMatcher;
+import static com.android.cts.mockime.ImeEventStreamTestUtils.expectBindInput;
+import static com.android.cts.mockime.ImeEventStreamTestUtils.expectEvent;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import static org.junit.Assume.assumeTrue;
+
+import android.autofillservice.cts.AbstractLoginActivityTestCase;
+import android.autofillservice.cts.CannedFillResponse;
+import android.autofillservice.cts.Helper;
+import android.autofillservice.cts.InstrumentedAutoFillService;
+import android.os.Process;
+import android.service.autofill.FillContext;
+
+import com.android.compatibility.common.util.RetryableException;
+import com.android.cts.mockime.ImeEventStream;
+import com.android.cts.mockime.MockImeSession;
+
+import org.junit.Test;
+
+import java.util.concurrent.TimeoutException;
+
+public class InlineLoginActivityTest extends AbstractLoginActivityTestCase {
+
+ private static final String TAG = "InlineLoginActivityTest";
+
+ @Override
+ protected void enableService() {
+ Helper.enableAutofillService(getContext(), SERVICE_NAME);
+ }
+
+ @Test
+ public void testAutofill_noDataset() throws Exception {
+ // Set service.
+ enableService();
+
+ final MockImeSession mockImeSession = sMockImeSessionRule.getMockImeSession();
+ assumeTrue("MockIME not available", mockImeSession != null);
+
+ sReplier.addResponse(CannedFillResponse.NO_RESPONSE);
+
+ final ImeEventStream stream = mockImeSession.openEventStream();
+ mockImeSession.callRequestShowSelf(0);
+
+ // Wait until the MockIme gets bound to the TestActivity.
+ expectBindInput(stream, Process.myPid(), MOCK_IME_TIMEOUT_MS);
+
+ // Trigger auto-fill.
+ requestFocusOnUsername();
+ expectEvent(stream, editorMatcher("onStartInput", mActivity.getUsername().getId()),
+ MOCK_IME_TIMEOUT_MS);
+
+ sReplier.getNextFillRequest();
+
+ mUiBot.assertNoSuggestionStripEver();
+ mUiBot.assertNoDatasetsEver();
+
+ waitUntilDisconnected();
+ }
+
+ @Test
+ public void testAutofill_oneDataset() throws Exception {
+ testBasicLoginAutofill(/* numDatasets= */ 1, /* selectedDatasetIndex= */ 0);
+ }
+
+ @Test
+ public void testAutofill_twoDatasets_selectFirstDataset() throws Exception {
+ testBasicLoginAutofill(/* numDatasets= */ 2, /* selectedDatasetIndex= */ 0);
+
+ }
+
+ @Test
+ public void testAutofill_twoDatasets_selectSecondDataset() throws Exception {
+ testBasicLoginAutofill(/* numDatasets= */ 2, /* selectedDatasetIndex= */ 1);
+ }
+
+ private void testBasicLoginAutofill(int numDatasets, int selectedDatasetIndex)
+ throws Exception {
+ // Set service.
+ enableService();
+
+ final MockImeSession mockImeSession = sMockImeSessionRule.getMockImeSession();
+ assumeTrue("MockIME not available", mockImeSession != null);
+
+ final CannedFillResponse.Builder builder = new CannedFillResponse.Builder();
+ for (int i = 0; i < numDatasets; i++) {
+ builder.addDataset(new CannedFillResponse.CannedDataset.Builder()
+ .setField(ID_USERNAME, "dude" + i)
+ .setField(ID_PASSWORD, "sweet" + i)
+ .setPresentation(createPresentation("The Dude" + i))
+ .setInlinePresentation(createInlinePresentation("The Dude" + i))
+ .build());
+ }
+
+ sReplier.addResponse(builder.build());
+ mActivity.expectAutoFill("dude" + selectedDatasetIndex, "sweet" + selectedDatasetIndex);
+
+ // Dynamically set password to make sure it's sanitized.
+ mActivity.onPassword((v) -> v.setText("I AM GROOT"));
+
+ final ImeEventStream stream = mockImeSession.openEventStream();
+ mockImeSession.callRequestShowSelf(0);
+
+ // Wait until the MockIme gets bound to the TestActivity.
+ expectBindInput(stream, Process.myPid(), MOCK_IME_TIMEOUT_MS);
+
+ // Trigger auto-fill.
+ requestFocusOnUsername();
+ expectEvent(stream, editorMatcher("onStartInput", mActivity.getUsername().getId()),
+ MOCK_IME_TIMEOUT_MS);
+
+ //TODO: extServices bug cause test to fail first time, retry if suggestion strip missing.
+ try {
+ expectEvent(stream, event -> "onSuggestionViewUpdated".equals(event.getEventName()),
+ MOCK_IME_TIMEOUT_MS);
+ } catch (TimeoutException e) {
+ sReplier.getNextFillRequest();
+ throw new RetryableException("Retry inline test");
+ }
+
+ mUiBot.assertSuggestionStrip(numDatasets);
+ mUiBot.assertNoDatasetsEver();
+
+ mUiBot.selectSuggestion(selectedDatasetIndex);
+
+ // Check the results.
+ mActivity.assertAutoFilled();
+
+ // Make sure input was sanitized.
+ final InstrumentedAutoFillService.FillRequest request = sReplier.getNextFillRequest();
+ assertWithMessage("CancelationSignal is null").that(request.cancellationSignal).isNotNull();
+ assertTextIsSanitized(request.structure, ID_PASSWORD);
+ final FillContext fillContext = request.contexts.get(request.contexts.size() - 1);
+ assertThat(fillContext.getFocusedId())
+ .isEqualTo(findAutofillIdByResourceId(fillContext, ID_USERNAME));
+
+ // Make sure initial focus was properly set.
+ assertWithMessage("Username node is not focused").that(
+ findNodeByResourceId(request.structure, ID_USERNAME).isFocused()).isTrue();
+ assertWithMessage("Password node is focused").that(
+ findNodeByResourceId(request.structure, ID_PASSWORD).isFocused()).isFalse();
+ }
+}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/inline/InstrumentedAutoFillServiceInlineEnabled.java b/tests/autofillservice/src/android/autofillservice/cts/inline/InstrumentedAutoFillServiceInlineEnabled.java
new file mode 100644
index 0000000..a931c53
--- /dev/null
+++ b/tests/autofillservice/src/android/autofillservice/cts/inline/InstrumentedAutoFillServiceInlineEnabled.java
@@ -0,0 +1,37 @@
+/*
+ * 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.autofillservice.cts.inline;
+
+import android.autofillservice.cts.InstrumentedAutoFillService;
+import android.service.autofill.AutofillService;
+
+/**
+ * Implementation of {@link AutofillService} that has inline suggestions support enabled.
+ */
+public class InstrumentedAutoFillServiceInlineEnabled extends InstrumentedAutoFillService {
+ @SuppressWarnings("hiding")
+ static final String SERVICE_PACKAGE = "android.autofillservice.cts";
+ @SuppressWarnings("hiding")
+ static final String SERVICE_CLASS = "InstrumentedAutoFillServiceInlineEnabled";
+ @SuppressWarnings("hiding")
+ static final String SERVICE_NAME = SERVICE_PACKAGE + "/.inline." + SERVICE_CLASS;
+
+ public InstrumentedAutoFillServiceInlineEnabled() {
+ sInstance.set(this);
+ sServiceLabel = SERVICE_CLASS;
+ }
+}
diff --git a/tests/camera/AndroidManifest.xml b/tests/camera/AndroidManifest.xml
index f311b99..85221d3 100644
--- a/tests/camera/AndroidManifest.xml
+++ b/tests/camera/AndroidManifest.xml
@@ -25,6 +25,7 @@
<uses-permission android:name="android.permission.REORDER_TASKS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
+ <uses-sdk android:targetSdkVersion="28" />
<application android:largeHeap="true">
<uses-library android:name="android.test.runner" />
diff --git a/tests/camera/libctscamera2jni/native-camera-jni.cpp b/tests/camera/libctscamera2jni/native-camera-jni.cpp
index 9dcc34f..31218db 100644
--- a/tests/camera/libctscamera2jni/native-camera-jni.cpp
+++ b/tests/camera/libctscamera2jni/native-camera-jni.cpp
@@ -939,18 +939,28 @@
}
camera_status_t initWithErrorLog() {
+ return initWithErrorLog(nullptr /*env*/, nullptr /*jOverrideCameraId*/);
+ }
+
+ camera_status_t initWithErrorLog(JNIEnv* env, jstring jOverrideCameraId) {
camera_status_t ret = ACameraManager_getCameraIdList(
mCameraManager, &mCameraIdList);
if (ret != ACAMERA_OK) {
LOG_ERROR(errorString, "Get camera id list failed: ret %d", ret);
return ret;
}
+
+ if (env != nullptr && jOverrideCameraId != nullptr) {
+ mOverrideCameraId = env->GetStringUTFChars(jOverrideCameraId, 0);
+ }
ret = ACameraManager_registerAvailabilityCallback(mCameraManager, &mServiceCb);
if (ret != ACAMERA_OK) {
LOG_ERROR(errorString, "Register availability callback failed: ret %d", ret);
return ret;
}
mMgrInited = true;
+ mJOverrideCameraId = jOverrideCameraId;
+ mJNIEnv = env;
return ACAMERA_OK;
}
@@ -971,6 +981,12 @@
mCameraIdList = nullptr;
}
mMgrInited = false;
+ if (mOverrideCameraId != nullptr && mJNIEnv != nullptr) {
+ mJNIEnv->ReleaseStringUTFChars(mJOverrideCameraId, mOverrideCameraId);
+ mOverrideCameraId = nullptr;
+ mJOverrideCameraId = nullptr;
+ mJNIEnv = nullptr;
+ }
return ACAMERA_OK;
}
@@ -978,6 +994,9 @@
if (!mMgrInited || !mCameraIdList) {
return -1;
}
+ if (mOverrideCameraId != nullptr) {
+ return 1;
+ }
return mCameraIdList->numCameras;
}
@@ -985,6 +1004,13 @@
if (!mMgrInited || !mCameraIdList || idx < 0 || idx >= mCameraIdList->numCameras) {
return nullptr;
}
+ if (mOverrideCameraId != nullptr) {
+ if (idx >= 1) {
+ return nullptr;
+ } else {
+ return mOverrideCameraId;
+ }
+ }
return mCameraIdList->cameraIds[idx];
}
@@ -993,10 +1019,18 @@
if (!mMgrInited || !mCameraIdList || idx < 0 || idx >= mCameraIdList->numCameras) {
return nullptr;
}
+ const char* cameraId = mCameraIdList->cameraIds[idx];
+ if (mOverrideCameraId != nullptr) {
+ if (idx >= 1) {
+ return nullptr;
+ } else {
+ cameraId = mOverrideCameraId;
+ }
+ }
ACameraMetadata* chars;
camera_status_t ret = ACameraManager_getCameraCharacteristics(
- mCameraManager, mCameraIdList->cameraIds[idx], &chars);
+ mCameraManager, cameraId, &chars);
if (ret != ACAMERA_OK) {
LOG_ERROR(errorString, "Get camera characteristics failed: ret %d", ret);
return nullptr;
@@ -1618,6 +1652,9 @@
ACameraOutputTarget* mReqPreviewOutput = nullptr;
ACameraOutputTarget* mReqImgReaderOutput = nullptr;
const char* mCameraId;
+ JNIEnv* mJNIEnv = nullptr;
+ jstring mJOverrideCameraId;
+ const char* mOverrideCameraId = nullptr;
bool mMgrInited = false; // cameraId, serviceListener
bool mImgReaderInited = false;
@@ -2014,13 +2051,13 @@
extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
testCameraDeviceOpenAndCloseNative(
- JNIEnv* env, jclass /*clazz*/) {
+ JNIEnv* env, jclass /*clazz*/, jstring jOverrideCameraId) {
ALOGV("%s", __FUNCTION__);
int numCameras = 0;
bool pass = false;
PreviewTestCase testCase;
- camera_status_t ret = testCase.initWithErrorLog();
+ camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
if (ret != ACAMERA_OK) {
// Don't log error here. testcase did it
goto cleanup;
@@ -2084,7 +2121,7 @@
extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
testCameraDeviceCreateCaptureRequestNative(
- JNIEnv* env, jclass /*clazz*/) {
+ JNIEnv* env, jclass /*clazz*/, jstring jOverrideCameraId) {
ALOGV("%s", __FUNCTION__);
bool pass = false;
ACameraManager* mgr = ACameraManager_create();
@@ -2095,9 +2132,18 @@
camera_status_t ret = ACameraManager_getCameraIdList(mgr, &cameraIdList);
int numCameras = cameraIdList->numCameras;
+ const char* overrideCameraId = nullptr;
+ if (jOverrideCameraId != nullptr) {
+ overrideCameraId = env->GetStringUTFChars(jOverrideCameraId, nullptr);
+ }
+
for (int i = 0; i < numCameras; i++) {
CameraDeviceListener deviceListener;
const char* cameraId = cameraIdList->cameraIds[i];
+ if (overrideCameraId != nullptr && strcmp(overrideCameraId, cameraId)) {
+ // Skip other cameras if overriding camera id to be tested.
+ continue;
+ }
ACameraDevice_StateCallbacks deviceCb {
&deviceListener,
CameraDeviceListener::onDisconnected,
@@ -2322,13 +2368,14 @@
extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
testCameraDeviceSessionOpenAndCloseNative(
- JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface) {
+ JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface,
+ jstring jOverrideCameraId) {
ALOGV("%s", __FUNCTION__);
int numCameras = 0;
bool pass = false;
PreviewTestCase testCase;
- camera_status_t ret = testCase.initWithErrorLog();
+ camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
if (ret != ACAMERA_OK) {
// Don't log error here. testcase did it
goto cleanup;
@@ -2460,7 +2507,8 @@
extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
testCameraDeviceSharedOutputUpdate(
- JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface, jobject jSharedSurface) {
+ JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface, jobject jSharedSurface,
+ jstring jOverrideCameraId) {
ALOGV("%s", __FUNCTION__);
int numCameras = 0;
bool pass = false;
@@ -2477,7 +2525,7 @@
uint32_t timeoutSec = 1;
uint32_t runPreviewSec = 2;
- camera_status_t ret = testCase.initWithErrorLog();
+ camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
if (ret != ACAMERA_OK) {
// Don't log error here. testcase did it
goto cleanup;
@@ -2729,13 +2777,14 @@
extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
testCameraDeviceSimplePreviewNative(
- JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface) {
+ JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface,
+ jstring jOverrideCameraId) {
ALOGV("%s", __FUNCTION__);
int numCameras = 0;
bool pass = false;
PreviewTestCase testCase;
- camera_status_t ret = testCase.initWithErrorLog();
+ camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
if (ret != ACAMERA_OK) {
// Don't log error here. testcase did it
goto cleanup;
@@ -2837,7 +2886,8 @@
extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
testCameraDevicePreviewWithSessionParametersNative(
- JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface) {
+ JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface,
+ jstring jOverrideCameraId) {
ALOGV("%s", __FUNCTION__);
int numCameras = 0;
bool pass = false;
@@ -2845,7 +2895,7 @@
ACameraMetadata* chars = nullptr;
PreviewTestCase testCase;
- camera_status_t ret = testCase.initWithErrorLog();
+ camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
if (ret != ACAMERA_OK) {
// Don't log error here. testcase did it
goto cleanup;
@@ -2965,7 +3015,8 @@
}
bool nativeCameraDeviceLogicalPhysicalStreaming(
- JNIEnv* env, jobject jPreviewSurface, bool usePhysicalSettings) {
+ JNIEnv* env, jobject jPreviewSurface, bool usePhysicalSettings,
+ jstring jOverrideCameraId) {
const int NUM_TEST_IMAGES = 10;
const int TEST_WIDTH = 640;
const int TEST_HEIGHT = 480;
@@ -2981,7 +3032,7 @@
uint32_t timeoutSec = 1;
uint32_t runPreviewSec = 2;
- camera_status_t ret = testCase.initWithErrorLog();
+ camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
if (ret != ACAMERA_OK) {
// Don't log error here. testcase did it
goto cleanup;
@@ -3244,22 +3295,26 @@
extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
testCameraDeviceLogicalPhysicalStreamingNative(
- JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface) {
+ JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface,
+ jstring jOverrideCameraId) {
return nativeCameraDeviceLogicalPhysicalStreaming(env,
- jPreviewSurface, false /*usePhysicalSettings*/);
+ jPreviewSurface, false /*usePhysicalSettings*/,
+ jOverrideCameraId);
}
extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
testCameraDeviceLogicalPhysicalSettingsNative(
- JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface) {
+ JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface,
+ jstring jOverrideCameraId) {
return nativeCameraDeviceLogicalPhysicalStreaming(env,
- jPreviewSurface, true /*usePhysicalSettings*/);
+ jPreviewSurface, true /*usePhysicalSettings*/,
+ jOverrideCameraId);
}
-
bool nativeImageReaderTestBase(
- JNIEnv* env, jstring jOutPath, jint format, AImageReader_ImageCallback cb) {
+ JNIEnv* env, jstring jOutPath, jint format, AImageReader_ImageCallback cb,
+ jstring jOverrideCameraId) {
const int NUM_TEST_IMAGES = 10;
const int TEST_WIDTH = 640;
const int TEST_HEIGHT = 480;
@@ -3275,7 +3330,7 @@
ALOGI("%s: out path is %s", __FUNCTION__, outPath);
}
- camera_status_t ret = testCase.initWithErrorLog();
+ camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
if (ret != ACAMERA_OK) {
// Don't log error here. testcase did it
goto cleanup;
@@ -3523,7 +3578,7 @@
// surface will eventually run out of free buffers and start reporting capture errors.
extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
-testCameraDeviceCaptureFailureNative(JNIEnv* env) {
+testCameraDeviceCaptureFailureNative(JNIEnv* env, jclass /*clazz*/, jstring jOverrideCameraId) {
const size_t NUM_TEST_IMAGES = 10;
const size_t NUM_FAILED_FRAMES = 3; // Wait for at least 3 consecutive failed capture requests
const int64_t NUM_TOTAL_FRAMES = 60; // Avoid waiting for more than 60 frames
@@ -3536,7 +3591,7 @@
uint32_t timeoutSec = 10; // It is important to keep this timeout bigger than the framework
// timeout
- camera_status_t ret = testCase.initWithErrorLog();
+ camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
if (ret != ACAMERA_OK) {
// Don't log error here. testcase did it
goto exit;
@@ -3697,46 +3752,51 @@
extern "C" jboolean
Java_android_hardware_camera2_cts_NativeImageReaderTest_\
testJpegNative(
- JNIEnv* env, jclass /*clazz*/, jstring jOutPath) {
+ JNIEnv* env, jclass /*clazz*/, jstring jOutPath,
+ jstring jOverrideCameraId) {
ALOGV("%s", __FUNCTION__);
return nativeImageReaderTestBase(env, jOutPath, AIMAGE_FORMAT_JPEG,
- ImageReaderListener::validateImageCb);
+ ImageReaderListener::validateImageCb, jOverrideCameraId);
}
extern "C" jboolean
Java_android_hardware_camera2_cts_NativeImageReaderTest_\
testY8Native(
- JNIEnv* env, jclass /*clazz*/, jstring jOutPath) {
+ JNIEnv* env, jclass /*clazz*/, jstring jOutPath,
+ jstring jOverrideCameraId) {
ALOGV("%s", __FUNCTION__);
return nativeImageReaderTestBase(env, jOutPath, AIMAGE_FORMAT_Y8,
- ImageReaderListener::validateImageCb);
+ ImageReaderListener::validateImageCb, jOverrideCameraId);
}
extern "C" jboolean
Java_android_hardware_camera2_cts_NativeImageReaderTest_\
testHeicNative(
- JNIEnv* env, jclass /*clazz*/, jstring jOutPath) {
+ JNIEnv* env, jclass /*clazz*/, jstring jOutPath,
+ jstring jOverrideCameraId) {
ALOGV("%s", __FUNCTION__);
return nativeImageReaderTestBase(env, jOutPath, AIMAGE_FORMAT_HEIC,
- ImageReaderListener::validateImageCb);
+ ImageReaderListener::validateImageCb, jOverrideCameraId);
}
extern "C" jboolean
Java_android_hardware_camera2_cts_NativeImageReaderTest_\
testDepthJpegNative(
- JNIEnv* env, jclass /*clazz*/, jstring jOutPath) {
+ JNIEnv* env, jclass /*clazz*/, jstring jOutPath,
+ jstring jOverrideCameraId) {
ALOGV("%s", __FUNCTION__);
return nativeImageReaderTestBase(env, jOutPath, AIMAGE_FORMAT_DEPTH_JPEG,
- ImageReaderListener::validateImageCb);
+ ImageReaderListener::validateImageCb, jOverrideCameraId);
}
extern "C" jboolean
Java_android_hardware_camera2_cts_NativeImageReaderTest_\
testImageReaderCloseAcquiredImagesNative(
- JNIEnv* env, jclass /*clazz*/) {
+ JNIEnv* env, jclass /*clazz*/,
+ jstring jOverrideCameraId) {
ALOGV("%s", __FUNCTION__);
return nativeImageReaderTestBase(env, nullptr, AIMAGE_FORMAT_JPEG,
- ImageReaderListener::acquireImageCb);
+ ImageReaderListener::acquireImageCb, jOverrideCameraId);
}
template <>
@@ -3858,7 +3918,8 @@
extern "C" jboolean
Java_android_hardware_camera2_cts_NativeStillCaptureTest_\
testStillCaptureNative(
- JNIEnv* env, jclass /*clazz*/, jstring jOutPath, jobject jPreviewSurface) {
+ JNIEnv* env, jclass /*clazz*/, jstring jOutPath, jobject jPreviewSurface,
+ jstring jOverrideCameraId) {
ALOGV("%s", __FUNCTION__);
const int NUM_TEST_IMAGES = 10;
const int TEST_WIDTH = 640;
@@ -3872,7 +3933,7 @@
const char* outPath = env->GetStringUTFChars(jOutPath, nullptr);
ALOGI("%s: out path is %s", __FUNCTION__, outPath);
- camera_status_t ret = testCase.initWithErrorLog();
+ camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
if (ret != ACAMERA_OK) {
// Don't log error here. testcase did it
goto cleanup;
diff --git a/tests/camera/src/android/hardware/camera2/cts/CameraManagerTest.java b/tests/camera/src/android/hardware/camera2/cts/CameraManagerTest.java
index 8f9f44b..19223b0 100644
--- a/tests/camera/src/android/hardware/camera2/cts/CameraManagerTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/CameraManagerTest.java
@@ -16,16 +16,13 @@
package android.hardware.camera2.cts;
-import static org.mockito.Mockito.*;
-import static org.mockito.AdditionalMatchers.not;
-import static org.mockito.AdditionalMatchers.and;
import static junit.framework.Assert.*;
-import android.app.ActivityManager;
+import static org.mockito.Mockito.*;
+
import android.app.Instrumentation;
import android.app.NotificationManager;
import android.app.UiAutomation;
-import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCharacteristics;
@@ -40,17 +37,17 @@
import android.os.Handler;
import android.os.HandlerThread;
import android.os.ParcelFileDescriptor;
-import android.test.AndroidTestCase;
import android.util.Log;
import android.util.Pair;
+
import androidx.test.InstrumentationRegistry;
import com.android.compatibility.common.util.PropertyUtil;
import com.android.ex.camera2.blocking.BlockingStateCallback;
-import org.junit.runners.Parameterized;
-import org.junit.runner.RunWith;
import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
import org.mockito.ArgumentCaptor;
import org.mockito.InOrder;
@@ -61,9 +58,9 @@
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingQueue;
-import java.util.Set;
/**
* <p>Basic test for CameraManager class.</p>
@@ -575,6 +572,10 @@
*/
@Test
public void testCameraManagerListenerCallbacks() throws Exception {
+ if (mOverrideCameraId != null) {
+ // Testing is done for individual camera. Skip.
+ return;
+ }
testCameraManagerListenerCallbacks(/*useExecutor*/ false);
testCameraManagerListenerCallbacks(/*useExecutor*/ true);
}
@@ -809,14 +810,6 @@
Log.i(TAG, "No cameras present, skipping test");
return;
}
-
- ActivityManager am = mContext.getSystemService(ActivityManager.class);
-
- // Go devices do not support all interrupt filtering functionality
- if (am.isLowRamDevice()) {
- return;
- }
-
// Allow the test package to adjust notification policy
toggleNotificationPolicyAccess(mContext.getPackageName(),
InstrumentationRegistry.getInstrumentation(), true);
diff --git a/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java b/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
index 30dba3e..770f3e4 100644
--- a/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
@@ -2428,6 +2428,10 @@
// Skip test, http://b/141496896
return;
}
+ if (mOverrideCameraId != null) {
+ // A single camera is being tested. Skip test.
+ return;
+ }
int legacyDeviceCount = Camera.getNumberOfCameras();
assertTrue("More legacy devices: " + legacyDeviceCount + " compared to Camera2 devices: " +
mCharacteristics.size(), legacyDeviceCount <= mCharacteristics.size());
diff --git a/tests/camera/src/android/hardware/camera2/cts/FastBasicsTest.java b/tests/camera/src/android/hardware/camera2/cts/FastBasicsTest.java
index fc09e51..dc34087 100644
--- a/tests/camera/src/android/hardware/camera2/cts/FastBasicsTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/FastBasicsTest.java
@@ -25,6 +25,7 @@
import android.graphics.ImageFormat;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
+import android.hardware.cts.helpers.CameraUtils;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CaptureRequest;
@@ -193,7 +194,8 @@
@Presubmit
@Test
public void testCamera1() throws Exception {
- for (int i = 0; i < Camera.getNumberOfCameras(); i++) {
+ int[] cameraIds = CameraUtils.deriveCameraIdsUnderTest();
+ for (int i : cameraIds) {
Camera camera = null;
try {
Log.i(TAG, "Testing android.hardware.Camera API for camera device " + i);
diff --git a/tests/camera/src/android/hardware/camera2/cts/NativeCameraDeviceTest.java b/tests/camera/src/android/hardware/camera2/cts/NativeCameraDeviceTest.java
index 207c3e3..ff1d790 100644
--- a/tests/camera/src/android/hardware/camera2/cts/NativeCameraDeviceTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/NativeCameraDeviceTest.java
@@ -47,13 +47,13 @@
@Test
public void testCameraDeviceOpenAndClose() {
assertTrue("testCameraDeviceOpenAndClose fail, see log for details",
- testCameraDeviceOpenAndCloseNative());
+ testCameraDeviceOpenAndCloseNative(mOverrideCameraId));
}
@Test
public void testCameraDeviceCreateCaptureRequest() {
assertTrue("testCameraDeviceCreateCaptureRequest fail, see log for details",
- testCameraDeviceCreateCaptureRequestNative());
+ testCameraDeviceCreateCaptureRequestNative(mOverrideCameraId));
}
@Test
@@ -61,7 +61,7 @@
// Init preview surface to a guaranteed working size
updatePreviewSurface(new Size(640, 480));
assertTrue("testCameraDeviceSessionOpenAndClose fail, see log for details",
- testCameraDeviceSessionOpenAndCloseNative(mPreviewSurface));
+ testCameraDeviceSessionOpenAndCloseNative(mPreviewSurface, mOverrideCameraId));
}
@Test
@@ -69,7 +69,7 @@
// Init preview surface to a guaranteed working size
updatePreviewSurface(new Size(640, 480));
assertTrue("testCameraDeviceSimplePreview fail, see log for details",
- testCameraDeviceSimplePreviewNative(mPreviewSurface));
+ testCameraDeviceSimplePreviewNative(mPreviewSurface, mOverrideCameraId));
}
@Test
@@ -77,7 +77,8 @@
// Init preview surface to a guaranteed working size
updatePreviewSurface(new Size(640, 480));
assertTrue("testCameraDevicePreviewWithSessionParameters fail, see log for details",
- testCameraDevicePreviewWithSessionParametersNative(mPreviewSurface));
+ testCameraDevicePreviewWithSessionParametersNative(mPreviewSurface,
+ mOverrideCameraId));
}
@Test
@@ -89,7 +90,8 @@
outputTexture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight());
Surface outputSurface = new Surface(outputTexture);
assertTrue("testCameraDeviceSharedOutputUpdate fail, see log for details",
- testCameraDeviceSharedOutputUpdate(mPreviewSurface, outputSurface));
+ testCameraDeviceSharedOutputUpdate(mPreviewSurface, outputSurface,
+ mOverrideCameraId));
}
@Test
@@ -101,7 +103,7 @@
outputTexture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight());
Surface outputSurface = new Surface(outputTexture);
assertTrue("testCameraDeviceLogicalPhysicalStreaming fail, see log for details",
- testCameraDeviceLogicalPhysicalStreamingNative(mPreviewSurface));
+ testCameraDeviceLogicalPhysicalStreamingNative(mPreviewSurface, mOverrideCameraId));
}
@Test
@@ -113,24 +115,30 @@
outputTexture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight());
Surface outputSurface = new Surface(outputTexture);
assertTrue("testCameraDeviceLogicalPhysicalSettings fail, see log for details",
- testCameraDeviceLogicalPhysicalSettingsNative(mPreviewSurface));
+ testCameraDeviceLogicalPhysicalSettingsNative(mPreviewSurface, mOverrideCameraId));
}
@Test
public void testCameraDeviceCaptureFailure() {
assertTrue("testCameraDeviceCaptureFailure fail, see log for details",
- testCameraDeviceCaptureFailureNative());
+ testCameraDeviceCaptureFailureNative(mOverrideCameraId));
}
- private static native boolean testCameraDeviceOpenAndCloseNative();
- private static native boolean testCameraDeviceCreateCaptureRequestNative();
- private static native boolean testCameraDeviceSessionOpenAndCloseNative(Surface preview);
- private static native boolean testCameraDeviceSimplePreviewNative(Surface preview);
+ private static native boolean testCameraDeviceOpenAndCloseNative(String overrideCameraId);
+ private static native boolean testCameraDeviceCreateCaptureRequestNative(
+ String overrideCameraId);
+ private static native boolean testCameraDeviceSessionOpenAndCloseNative(Surface preview,
+ String overrideCameraId);
+ private static native boolean testCameraDeviceSimplePreviewNative(Surface preview,
+ String overrideCameraId);
private static native boolean testCameraDevicePreviewWithSessionParametersNative(
- Surface preview);
- private static native boolean testCameraDeviceSharedOutputUpdate(Surface src, Surface dst);
- private static native boolean testCameraDeviceLogicalPhysicalStreamingNative(Surface preview);
- private static native boolean testCameraDeviceLogicalPhysicalSettingsNative(Surface preview);
- private static native boolean testCameraDeviceCaptureFailureNative();
+ Surface preview, String overrideCameraId);
+ private static native boolean testCameraDeviceSharedOutputUpdate(Surface src, Surface dst,
+ String overrideCameraId);
+ private static native boolean testCameraDeviceLogicalPhysicalStreamingNative(Surface preview,
+ String overrideCameraId);
+ private static native boolean testCameraDeviceLogicalPhysicalSettingsNative(Surface preview,
+ String overrideCameraId);
+ private static native boolean testCameraDeviceCaptureFailureNative(String overrideCameraId);
}
diff --git a/tests/camera/src/android/hardware/camera2/cts/NativeImageReaderTest.java b/tests/camera/src/android/hardware/camera2/cts/NativeImageReaderTest.java
index 493e670..ef9a57c 100644
--- a/tests/camera/src/android/hardware/camera2/cts/NativeImageReaderTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/NativeImageReaderTest.java
@@ -43,36 +43,36 @@
@Test
public void testJpeg() {
assertTrue("testJpeg fail, see log for details",
- testJpegNative(mDebugFileNameBase));
+ testJpegNative(mDebugFileNameBase, mOverrideCameraId));
}
@Test
public void testY8() {
assertTrue("testY8 fail, see log for details",
- testY8Native(mDebugFileNameBase));
+ testY8Native(mDebugFileNameBase, mOverrideCameraId));
}
@Test
public void testHeic() {
assertTrue("testHeic fail, see log for details",
- testHeicNative(mDebugFileNameBase));
+ testHeicNative(mDebugFileNameBase, mOverrideCameraId));
}
@Test
public void testDepthJpeg() {
assertTrue("testDepthJpeg fail, see log for details",
- testDepthJpegNative(mDebugFileNameBase));
+ testDepthJpegNative(mDebugFileNameBase, mOverrideCameraId));
}
@Test
public void testImageReaderCloseAcquiredImages() {
assertTrue("testImageReaderClose fail, see log for details",
- testImageReaderCloseAcquiredImagesNative());
+ testImageReaderCloseAcquiredImagesNative(mOverrideCameraId));
}
- private static native boolean testJpegNative(String filePath);
- private static native boolean testY8Native(String filePath);
- private static native boolean testHeicNative(String filePath);
- private static native boolean testDepthJpegNative(String filePath);
- private static native boolean testImageReaderCloseAcquiredImagesNative();
+ private static native boolean testJpegNative(String filePath, String overrideCameraId);
+ private static native boolean testY8Native(String filePath, String overrideCameraId);
+ private static native boolean testHeicNative(String filePath, String overrideCameraId);
+ private static native boolean testDepthJpegNative(String filePath, String overrideCameraId);
+ private static native boolean testImageReaderCloseAcquiredImagesNative(String overrideCameraId);
}
diff --git a/tests/camera/src/android/hardware/camera2/cts/NativeStillCaptureTest.java b/tests/camera/src/android/hardware/camera2/cts/NativeStillCaptureTest.java
index a778f7d..cfefd62 100644
--- a/tests/camera/src/android/hardware/camera2/cts/NativeStillCaptureTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/NativeStillCaptureTest.java
@@ -48,9 +48,9 @@
// Init preview surface to a guaranteed working size
updatePreviewSurface(new Size(640, 480));
assertTrue("testStillCapture fail, see log for details",
- testStillCaptureNative(mDebugFileNameBase, mPreviewSurface));
+ testStillCaptureNative(mDebugFileNameBase, mPreviewSurface, mOverrideCameraId));
}
private static native boolean testStillCaptureNative(
- String filePath, Surface previewSurface);
+ String filePath, Surface previewSurface, String overrideCameraId);
}
diff --git a/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2AndroidTestRule.java b/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2AndroidTestRule.java
index 91f6b80..13ce89a 100644
--- a/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2AndroidTestRule.java
+++ b/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2AndroidTestRule.java
@@ -38,12 +38,15 @@
import android.media.Image;
import android.media.Image.Plane;
import android.media.ImageReader;
+import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.util.Log;
import android.view.Surface;
import android.view.WindowManager;
+import androidx.test.InstrumentationRegistry;
+
import com.android.ex.camera2.blocking.BlockingSessionCallback;
import com.android.ex.camera2.blocking.BlockingStateCallback;
@@ -87,6 +90,10 @@
private WindowManager mWindowManager;
private Context mContext;
+ private static final String CAMERA_ID_INSTR_ARG_KEY = "camera-id";
+ private static final Bundle mBundle = InstrumentationRegistry.getArguments();
+ private static final String mOverrideCameraId = mBundle.getString(CAMERA_ID_INSTR_ARG_KEY);
+
public Camera2AndroidTestRule(Context context) {
mContext = context;
}
@@ -175,6 +182,20 @@
return mCollector;
}
+ private String[] deriveCameraIdsUnderTest() throws Exception {
+ String[] idsUnderTest = mCameraManager.getCameraIdListNoLazy();
+ assertNotNull("Camera ids shouldn't be null", idsUnderTest);
+ if (mOverrideCameraId != null) {
+ if (Arrays.asList(idsUnderTest).contains(mOverrideCameraId)) {
+ idsUnderTest = new String[]{mOverrideCameraId};
+ } else {
+ idsUnderTest = new String[]{};
+ }
+ }
+
+ return idsUnderTest;
+ }
+
/**
* Set up the camera2 test case required environments, including CameraManager,
* HandlerThread, Camera IDs, and CameraStateCallback etc.
@@ -193,8 +214,7 @@
*/
System.setProperty("dexmaker.dexcache", getContext().getCacheDir().toString());
- mCameraIdsUnderTest = mCameraManager.getCameraIdListNoLazy();
- assertNotNull("Camera ids shouldn't be null", mCameraIdsUnderTest);
+ mCameraIdsUnderTest = deriveCameraIdsUnderTest();
mHandlerThread = new HandlerThread(TAG);
mHandlerThread.start();
mHandler = new Handler(mHandlerThread.getLooper());
@@ -239,8 +259,7 @@
Log.v(TAG, "Tear down...");
if (mCameraManager != null) {
try {
- String[] cameraIdsPostTest = mCameraManager.getCameraIdListNoLazy();
- assertNotNull("Camera ids shouldn't be null", cameraIdsPostTest);
+ String[] cameraIdsPostTest = deriveCameraIdsUnderTest();
Log.i(TAG, "Camera ids in setup:" + Arrays.toString(mCameraIdsUnderTest));
Log.i(TAG, "Camera ids in tearDown:" + Arrays.toString(cameraIdsPostTest));
assertTrue(
@@ -710,4 +729,4 @@
// Expected.
}
}
-}
\ No newline at end of file
+}
diff --git a/tests/camera/src/android/hardware/cts/CameraGLTest.java b/tests/camera/src/android/hardware/cts/CameraGLTest.java
index c83f074..a9e82ef 100644
--- a/tests/camera/src/android/hardware/cts/CameraGLTest.java
+++ b/tests/camera/src/android/hardware/cts/CameraGLTest.java
@@ -78,6 +78,7 @@
private Looper mLooper = null;
private final ConditionVariable mSurfaceTextureDone = new ConditionVariable();
private final ConditionVariable mPreviewDone = new ConditionVariable();
+ private int[] mCameraIds;
Camera mCamera;
boolean mIsExternalCamera;
@@ -105,6 +106,8 @@
GLSurfaceViewCtsActivity ctsActivity = mActivityRule.getActivity();
// Store a link to the view so we can redraw it when needed
mGLView = ctsActivity.getView();
+
+ mCameraIds = CameraUtils.deriveCameraIdsUnderTest();
}
@After
@@ -324,8 +327,7 @@
wl.acquire();
try {
/* Run the requested test per camera */
- int nCameras = Camera.getNumberOfCameras();
- for (int id = 0; id < nCameras; id++) {
+ for (int id : mCameraIds) {
Log.v(TAG, "Camera id=" + id);
test.run(id);
}
diff --git a/tests/camera/src/android/hardware/cts/CameraTest.java b/tests/camera/src/android/hardware/cts/CameraTest.java
index 47ffca6..c8330f7 100644
--- a/tests/camera/src/android/hardware/cts/CameraTest.java
+++ b/tests/camera/src/android/hardware/cts/CameraTest.java
@@ -124,6 +124,7 @@
private final ConditionVariable mPreviewDone = new ConditionVariable();
private final ConditionVariable mFocusDone = new ConditionVariable();
private final ConditionVariable mSnapshotDone = new ConditionVariable();
+ private int[] mCameraIds;
Camera mCamera;
boolean mIsExternalCamera;
@@ -134,6 +135,7 @@
@Before
public void setUp() throws Exception {
+ mCameraIds = CameraUtils.deriveCameraIdsUnderTest();
}
@After
@@ -408,8 +410,7 @@
@UiThreadTest
@Test
public void testTakePicture() throws Exception {
- int nCameras = Camera.getNumberOfCameras();
- for (int id = 0; id < nCameras; id++) {
+ for (int id : mCameraIds) {
Log.v(TAG, "Camera id=" + id);
initializeMessageLooper(id);
mCamera.startPreview();
@@ -454,8 +455,7 @@
@UiThreadTest
@Test
public void testPreviewCallback() throws Exception {
- int nCameras = Camera.getNumberOfCameras();
- for (int id = 0; id < nCameras; id++) {
+ for (int id : mCameraIds) {
Log.v(TAG, "Camera id=" + id);
testPreviewCallbackByCamera(id);
}
@@ -509,8 +509,7 @@
@UiThreadTest
@Test
public void testStabilizationOneShotPreviewCallback() throws Exception {
- int nCameras = Camera.getNumberOfCameras();
- for (int id = 0; id < nCameras; id++) {
+ for (int id : mCameraIds) {
Log.v(TAG, "Camera id=" + id);
testStabilizationOneShotPreviewCallbackByCamera(id);
}
@@ -535,8 +534,7 @@
@UiThreadTest
@Test
public void testSetOneShotPreviewCallback() throws Exception {
- int nCameras = Camera.getNumberOfCameras();
- for (int id = 0; id < nCameras; id++) {
+ for (int id : mCameraIds) {
Log.v(TAG, "Camera id=" + id);
testSetOneShotPreviewCallbackByCamera(id);
}
@@ -559,8 +557,7 @@
@UiThreadTest
@Test
public void testSetPreviewDisplay() throws Exception {
- int nCameras = Camera.getNumberOfCameras();
- for (int id = 0; id < nCameras; id++) {
+ for (int id : mCameraIds) {
Log.v(TAG, "Camera id=" + id);
testSetPreviewDisplayByCamera(id);
}
@@ -603,8 +600,7 @@
@UiThreadTest
@Test
public void testDisplayOrientation() throws Exception {
- int nCameras = Camera.getNumberOfCameras();
- for (int id = 0; id < nCameras; id++) {
+ for (int id : mCameraIds) {
Log.v(TAG, "Camera id=" + id);
testDisplayOrientationByCamera(id);
}
@@ -642,8 +638,7 @@
@UiThreadTest
@Test
public void testParameters() throws Exception {
- int nCameras = Camera.getNumberOfCameras();
- for (int id = 0; id < nCameras; id++) {
+ for (int id : mCameraIds) {
Log.v(TAG, "Camera id=" + id);
testParametersByCamera(id);
}
@@ -866,8 +861,7 @@
@UiThreadTest
@Test
public void testJpegThumbnailSize() throws Exception {
- int nCameras = Camera.getNumberOfCameras();
- for (int id = 0; id < nCameras; id++) {
+ for (int id : mCameraIds) {
Log.v(TAG, "Camera id=" + id);
initializeMessageLooper(id);
testJpegThumbnailSizeByCamera(false, 0, 0);
@@ -940,8 +934,7 @@
@UiThreadTest
@Test
public void testJpegExif() throws Exception {
- int nCameras = Camera.getNumberOfCameras();
- for (int id = 0; id < nCameras; id++) {
+ for (int id : mCameraIds) {
Log.v(TAG, "Camera id=" + id);
initializeMessageLooper(id);
testJpegExifByCamera(false);
@@ -1233,8 +1226,7 @@
@UiThreadTest
@Test
public void testLockUnlock() throws Exception {
- int nCameras = Camera.getNumberOfCameras();
- for (int id = 0; id < nCameras; id++) {
+ for (int id : mCameraIds) {
Log.v(TAG, "Camera id=" + id);
testLockUnlockByCamera(id);
}
@@ -1426,8 +1418,7 @@
@UiThreadTest
@Test
public void testPreviewCallbackWithBuffer() throws Exception {
- int nCameras = Camera.getNumberOfCameras();
- for (int id = 0; id < nCameras; id++) {
+ for (int id : mCameraIds) {
Log.v(TAG, "Camera id=" + id);
testPreviewCallbackWithBufferByCamera(id);
}
@@ -1524,8 +1515,7 @@
@UiThreadTest
@Test
public void testImmediateZoom() throws Exception {
- int nCameras = Camera.getNumberOfCameras();
- for (int id = 0; id < nCameras; id++) {
+ for (int id : mCameraIds) {
Log.v(TAG, "Camera id=" + id);
testImmediateZoomByCamera(id);
}
@@ -1596,8 +1586,7 @@
@UiThreadTest
@Test
public void testSmoothZoom() throws Exception {
- int nCameras = Camera.getNumberOfCameras();
- for (int id = 0; id < nCameras; id++) {
+ for (int id : mCameraIds) {
Log.v(TAG, "Camera id=" + id);
testSmoothZoomByCamera(id);
}
@@ -1722,8 +1711,7 @@
@UiThreadTest
@Test
public void testFocusDistances() throws Exception {
- int nCameras = Camera.getNumberOfCameras();
- for (int id = 0; id < nCameras; id++) {
+ for (int id : mCameraIds) {
Log.v(TAG, "Camera id=" + id);
testFocusDistancesByCamera(id);
}
@@ -1831,8 +1819,7 @@
@UiThreadTest
@Test
public void testCancelAutofocus() throws Exception {
- int nCameras = Camera.getNumberOfCameras();
- for (int id = 0; id < nCameras; id++) {
+ for (int id : mCameraIds) {
Log.v(TAG, "Camera id=" + id);
testCancelAutofocusByCamera(id);
}
@@ -1913,6 +1900,11 @@
@UiThreadTest
@Test
public void testMultipleCameras() throws Exception {
+ if (CameraUtils.mOverrideCameraId != null) {
+ // A single camera is being tested. Skip.
+ return;
+ }
+
int nCameras = Camera.getNumberOfCameras();
Log.v(TAG, "total " + nCameras + " cameras");
assertTrue(nCameras >= 0);
@@ -1976,8 +1968,7 @@
@UiThreadTest
@Test(timeout=60*60*1000) // timeout = 60 mins for long running tests
public void testPreviewPictureSizesCombination() throws Exception {
- int nCameras = Camera.getNumberOfCameras();
- for (int id = 0; id < nCameras; id++) {
+ for (int id : mCameraIds) {
Log.v(TAG, "Camera id=" + id);
testPreviewPictureSizesCombinationByCamera(id);
}
@@ -2093,8 +2084,7 @@
@UiThreadTest
@Test
public void testPreviewFpsRange() throws Exception {
- int nCameras = Camera.getNumberOfCameras();
- for (int id = 0; id < nCameras; id++) {
+ for (int id : mCameraIds) {
Log.v(TAG, "Camera id=" + id);
testPreviewFpsRangeByCamera(id);
}
@@ -2322,8 +2312,7 @@
@UiThreadTest
@Test
public void testSceneMode() throws Exception {
- int nCameras = Camera.getNumberOfCameras();
- for (int id = 0; id < nCameras; id++) {
+ for (int id : mCameraIds) {
Log.v(TAG, "Camera id=" + id);
testSceneModeByCamera(id);
}
@@ -2423,8 +2412,7 @@
@UiThreadTest
@Test
public void testInvalidParameters() throws Exception {
- int nCameras = Camera.getNumberOfCameras();
- for (int id = 0; id < nCameras; id++) {
+ for (int id : mCameraIds) {
Log.v(TAG, "Camera id=" + id);
testInvalidParametersByCamera(id);
}
@@ -2478,8 +2466,7 @@
@UiThreadTest
@Test
public void testGetParameterDuringFocus() throws Exception {
- int nCameras = Camera.getNumberOfCameras();
- for (int id = 0; id < nCameras; id++) {
+ for (int id : mCameraIds) {
Log.v(TAG, "Camera id=" + id);
testGetParameterDuringFocusByCamera(id);
}
@@ -2514,8 +2501,7 @@
@UiThreadTest
@Test
public void testPreviewFormats() throws Exception {
- int nCameras = Camera.getNumberOfCameras();
- for (int id = 0; id < nCameras; id++) {
+ for (int id : mCameraIds) {
Log.v(TAG, "Camera id=" + id);
testPreviewFormatsByCamera(id);
}
@@ -2539,6 +2525,11 @@
@UiThreadTest
@Test
public void testMultiCameraRelease() throws Exception {
+ if (CameraUtils.mOverrideCameraId != null) {
+ // A single camera is being tested. Skip.
+ return;
+ }
+
// Verify that multiple cameras exist, and that they can be opened at the same time
if (VERBOSE) Log.v(TAG, "testMultiCameraRelease: Checking pre-conditions.");
int nCameras = Camera.getNumberOfCameras();
@@ -2628,8 +2619,7 @@
@UiThreadTest
@Test
public void testFocusAreas() throws Exception {
- int nCameras = Camera.getNumberOfCameras();
- for (int id = 0; id < nCameras; id++) {
+ for (int id : mCameraIds) {
Log.v(TAG, "Camera id=" + id);
initializeMessageLooper(id);
@@ -2648,8 +2638,7 @@
@UiThreadTest
@Test
public void testMeteringAreas() throws Exception {
- int nCameras = Camera.getNumberOfCameras();
- for (int id = 0; id < nCameras; id++) {
+ for (int id : mCameraIds) {
Log.v(TAG, "Camera id=" + id);
initializeMessageLooper(id);
Parameters parameters = mCamera.getParameters();
@@ -2785,8 +2774,7 @@
@UiThreadTest
@Test
public void testJpegCallbackStartPreview() throws Exception {
- int nCameras = Camera.getNumberOfCameras();
- for (int id = 0; id < nCameras; id++) {
+ for (int id : mCameraIds) {
Log.v(TAG, "Camera id=" + id);
testJpegCallbackStartPreviewByCamera(id);
}
@@ -2815,8 +2803,7 @@
@UiThreadTest
@Test
public void testRecordingHint() throws Exception {
- int nCameras = Camera.getNumberOfCameras();
- for (int id = 0; id < nCameras; id++) {
+ for (int id : mCameraIds) {
Log.v(TAG, "Camera id=" + id);
testRecordingHintByCamera(id);
}
@@ -2911,8 +2898,7 @@
@UiThreadTest
@Test
public void testAutoExposureLock() throws Exception {
- int nCameras = Camera.getNumberOfCameras();
- for (int id = 0; id < nCameras; id++) {
+ for (int id : mCameraIds) {
Log.v(TAG, "Camera id=" + id);
initializeMessageLooper(id);
Parameters parameters = mCamera.getParameters();
@@ -2928,8 +2914,7 @@
@UiThreadTest
@Test
public void testAutoWhiteBalanceLock() throws Exception {
- int nCameras = Camera.getNumberOfCameras();
- for (int id = 0; id < nCameras; id++) {
+ for (int id : mCameraIds) {
Log.v(TAG, "Camera id=" + id);
initializeMessageLooper(id);
Parameters parameters = mCamera.getParameters();
@@ -2945,8 +2930,7 @@
@UiThreadTest
@Test
public void test3ALockInteraction() throws Exception {
- int nCameras = Camera.getNumberOfCameras();
- for (int id = 0; id < nCameras; id++) {
+ for (int id : mCameraIds) {
Log.v(TAG, "Camera id=" + id);
initializeMessageLooper(id);
Parameters parameters = mCamera.getParameters();
@@ -3170,8 +3154,7 @@
@UiThreadTest
@Test
public void testFaceDetection() throws Exception {
- int nCameras = Camera.getNumberOfCameras();
- for (int id = 0; id < nCameras; id++) {
+ for (int id : mCameraIds) {
Log.v(TAG, "Camera id=" + id);
testFaceDetectionByCamera(id);
}
@@ -3297,8 +3280,7 @@
@UiThreadTest
@Test(timeout=60*60*1000) // timeout = 60 mins for long running tests
public void testVideoSnapshot() throws Exception {
- int nCameras = Camera.getNumberOfCameras();
- for (int id = 0; id < nCameras; id++) {
+ for (int id : mCameraIds) {
Log.v(TAG, "Camera id=" + id);
testVideoSnapshotByCamera(id, /*recordingHint*/false);
testVideoSnapshotByCamera(id, /*recordingHint*/true);
@@ -3378,8 +3360,7 @@
@Test
public void testPreviewCallbackWithPicture() throws Exception {
- int nCameras = Camera.getNumberOfCameras();
- for (int id = 0; id < nCameras; id++) {
+ for (int id : mCameraIds) {
Log.v(TAG, "Camera id=" + id);
testPreviewCallbackWithPictureByCamera(id);
}
@@ -3438,8 +3419,7 @@
@Test
public void testEnableShutterSound() throws Exception {
- int nCameras = Camera.getNumberOfCameras();
- for (int id = 0; id < nCameras; id++) {
+ for (int id : mCameraIds) {
Log.v(TAG, "Camera id=" + id);
testEnableShutterSoundByCamera(id);
}
diff --git a/tests/camera/src/android/hardware/cts/Camera_SizeTest.java b/tests/camera/src/android/hardware/cts/Camera_SizeTest.java
index 77e75dd..785535c 100644
--- a/tests/camera/src/android/hardware/cts/Camera_SizeTest.java
+++ b/tests/camera/src/android/hardware/cts/Camera_SizeTest.java
@@ -70,7 +70,8 @@
* @see {@link android.hardware.camera2.CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL}
*/
public void testMaxAspectRatios() throws Exception {
- for (int id = 0; id < Camera.getNumberOfCameras(); ++id) {
+ int[] cameraIds = CameraUtils.deriveCameraIdsUnderTest();
+ for (int id : cameraIds) {
if (CameraUtils.isLegacyHAL(getContext(), id)) {
Camera camera = Camera.open(id);
diff --git a/tests/camera/src/android/hardware/cts/LegacyCameraPerformanceTest.java b/tests/camera/src/android/hardware/cts/LegacyCameraPerformanceTest.java
index ac3f6dd..5cc67fd 100644
--- a/tests/camera/src/android/hardware/cts/LegacyCameraPerformanceTest.java
+++ b/tests/camera/src/android/hardware/cts/LegacyCameraPerformanceTest.java
@@ -20,6 +20,7 @@
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
+import android.hardware.cts.helpers.CameraUtils;
import android.os.SystemClock;
import android.util.Log;
@@ -49,29 +50,31 @@
private Instrumentation mInstrumentation;
private CameraPerformanceTestHelper mHelper;
+ private int[] mCameraIds;
@Before
public void setUp() throws Exception {
mInstrumentation = InstrumentationRegistry.getInstrumentation();
mHelper = new CameraPerformanceTestHelper();
+ mCameraIds = CameraUtils.deriveCameraIdsUnderTest();
}
@After
public void tearDown() throws Exception {
if (mHelper.getCamera() != null) {
mHelper.getCamera().release();
-
}
}
@Test
public void testLegacyApiPerformance() throws Exception {
final int NUM_TEST_LOOPS = 10;
+ if (mCameraIds.length == 0) return;
- int nCameras = Camera.getNumberOfCameras();
- double[] avgCameraTakePictureTimes = new double[nCameras];
+ double[] avgCameraTakePictureTimes = new double[mCameraIds.length];
- for (int id = 0; id < nCameras; id++) {
+ int count = 0;
+ for (int id : mCameraIds) {
DeviceReportLog reportLog = new DeviceReportLog(REPORT_LOG_NAME,
"test_camera_takePicture");
reportLog.addValue("camera_id", id, ResultType.NEUTRAL, ResultUnit.NONE);
@@ -172,7 +175,7 @@
+ ". Max(ms): " + Stat.getMax(cameraTakePictureTimes));
}
- avgCameraTakePictureTimes[id] = Stat.getAverage(cameraTakePictureTimes);
+ avgCameraTakePictureTimes[count++] = Stat.getAverage(cameraTakePictureTimes);
reportLog.addValues("camera_open_time", cameraOpenTimes, ResultType.LOWER_BETTER,
ResultUnit.MS);
reportLog.addValues("camera_start_preview_time", startPreviewTimes,
@@ -191,7 +194,7 @@
reportLog.submit(mInstrumentation);
}
- if (nCameras != 0) {
+ if (mCameraIds.length != 0) {
DeviceReportLog reportLog = new DeviceReportLog(REPORT_LOG_NAME,
"test_camera_takepicture_average");
reportLog.setSummary("camera_takepicture_average_time_for_all_cameras",
@@ -200,4 +203,4 @@
reportLog.submit(mInstrumentation);
}
}
-}
\ No newline at end of file
+}
diff --git a/tests/camera/utils/src/android/hardware/camera2/cts/Camera2ParameterizedTestCase.java b/tests/camera/utils/src/android/hardware/camera2/cts/Camera2ParameterizedTestCase.java
index c7deb5a..6d90f2e 100644
--- a/tests/camera/utils/src/android/hardware/camera2/cts/Camera2ParameterizedTestCase.java
+++ b/tests/camera/utils/src/android/hardware/camera2/cts/Camera2ParameterizedTestCase.java
@@ -49,15 +49,13 @@
System.setProperty("dexmaker.dexcache", mContext.getCacheDir().toString());
mCameraManager = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE);
assertNotNull("Unable to get CameraManager", mCameraManager);
- mCameraIdsUnderTest =
- CameraTestUtils.getCameraIdListForTesting(mCameraManager, mAdoptShellPerm);
+ mCameraIdsUnderTest = deriveCameraIdsUnderTest();
assertNotNull("Unable to get camera ids", mCameraIdsUnderTest);
}
@Override
public void tearDown() throws Exception {
- String[] cameraIdsPostTest =
- CameraTestUtils.getCameraIdListForTesting(mCameraManager, mAdoptShellPerm);
+ String[] cameraIdsPostTest = deriveCameraIdsUnderTest();
assertNotNull("Camera ids shouldn't be null", cameraIdsPostTest);
Log.i(TAG, "Camera ids in setup:" + Arrays.toString(mCameraIdsUnderTest));
Log.i(TAG, "Camera ids in tearDown:" + Arrays.toString(cameraIdsPostTest));
@@ -67,4 +65,19 @@
mCameraIdsUnderTest.length == cameraIdsPostTest.length);
super.tearDown();
}
+
+ private String[] deriveCameraIdsUnderTest() throws Exception {
+ String[] idsUnderTest =
+ CameraTestUtils.getCameraIdListForTesting(mCameraManager, mAdoptShellPerm);
+ assertNotNull("Camera ids shouldn't be null", idsUnderTest);
+ if (mOverrideCameraId != null) {
+ if (Arrays.asList(idsUnderTest).contains(mOverrideCameraId)) {
+ idsUnderTest = new String[]{mOverrideCameraId};
+ } else {
+ idsUnderTest = new String[]{};
+ }
+ }
+
+ return idsUnderTest;
+ }
}
diff --git a/tests/camera/utils/src/android/hardware/cts/helpers/CameraParameterizedTestCase.java b/tests/camera/utils/src/android/hardware/cts/helpers/CameraParameterizedTestCase.java
index b2f4c04..047fba5 100644
--- a/tests/camera/utils/src/android/hardware/cts/helpers/CameraParameterizedTestCase.java
+++ b/tests/camera/utils/src/android/hardware/cts/helpers/CameraParameterizedTestCase.java
@@ -18,6 +18,7 @@
import android.app.UiAutomation;
import android.content.Context;
+import android.os.Bundle;
import android.util.Log;
import androidx.test.InstrumentationRegistry;
@@ -42,6 +43,10 @@
@Parameter(0)
public boolean mAdoptShellPerm;
+ private static final String CAMERA_ID_INSTR_ARG_KEY = "camera-id";
+ private static final Bundle mBundle = InstrumentationRegistry.getArguments();
+ protected static final String mOverrideCameraId = mBundle.getString(CAMERA_ID_INSTR_ARG_KEY);
+
@Parameters
public static Iterable<? extends Object> data() {
List<Boolean> adoptShellPerm = new ArrayList<Boolean>();
diff --git a/tests/camera/utils/src/android/hardware/cts/helpers/CameraUtils.java b/tests/camera/utils/src/android/hardware/cts/helpers/CameraUtils.java
index 82df26e..2370023 100644
--- a/tests/camera/utils/src/android/hardware/cts/helpers/CameraUtils.java
+++ b/tests/camera/utils/src/android/hardware/cts/helpers/CameraUtils.java
@@ -20,14 +20,22 @@
import android.hardware.Camera;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraManager;
+import android.os.Bundle;
+
+import androidx.test.InstrumentationRegistry;
import java.util.Comparator;
+import java.util.stream.IntStream;
/**
* Utility class containing helper functions for the Camera CTS tests.
*/
public class CameraUtils {
+ private static final String CAMERA_ID_INSTR_ARG_KEY = "camera-id";
+ private static final Bundle mBundle = InstrumentationRegistry.getArguments();
+ public static final String mOverrideCameraId = mBundle.getString(CAMERA_ID_INSTR_ARG_KEY);
+
/**
* Returns {@code true} if this device only supports {@code LEGACY} mode operation in the
* Camera2 API for the given camera ID.
@@ -104,4 +112,19 @@
}
}
+ public static int[] deriveCameraIdsUnderTest() throws Exception {
+ int numberOfCameras = Camera.getNumberOfCameras();
+ int[] cameraIds;
+ if (mOverrideCameraId == null) {
+ cameraIds = IntStream.range(0, numberOfCameras).toArray();
+ } else {
+ int overrideCameraId = Integer.parseInt(mOverrideCameraId);
+ if (overrideCameraId >= 0 && overrideCameraId < numberOfCameras) {
+ cameraIds = new int[]{overrideCameraId};
+ } else {
+ cameraIds = new int[]{};
+ }
+ }
+ return cameraIds;
+ }
}
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/ActivityTaskAffinityTests.java b/tests/framework/base/windowmanager/src/android/server/wm/ActivityTaskAffinityTests.java
index 3043ef3..c6baec7 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/ActivityTaskAffinityTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/ActivityTaskAffinityTests.java
@@ -33,7 +33,7 @@
/**
* Build/Install/Run:
- * atest CtsWindowManagerDeviceTestCases:ActivitySecurityTests
+ * atest CtsWindowManagerDeviceTestCases:ActivityTaskAffinityTests
*
* Tests if activities with the same taskAffinity can be in the same task.
*/
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/DisplayTests.java b/tests/framework/base/windowmanager/src/android/server/wm/DisplayTests.java
index 983cb54..369904f 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/DisplayTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/DisplayTests.java
@@ -140,7 +140,7 @@
launchHomeActivity();
final DisplayMetricsSession displayMetricsSession =
- mObjectTracker.manage(new DisplayMetricsSession(DEFAULT_DISPLAY));
+ createManagedDisplayMetricsSession(DEFAULT_DISPLAY);
final LockScreenSession lockScreenSession = createManagedLockScreenSession();
// Read initial sizes.
@@ -189,32 +189,4 @@
return config;
}
}
-
- private static class DisplayMetricsSession implements AutoCloseable {
-
- private final ReportedDisplayMetrics mInitialDisplayMetrics;
- private final int mDisplayId;
-
- DisplayMetricsSession(int displayId) {
- mDisplayId = displayId;
- mInitialDisplayMetrics = ReportedDisplayMetrics.getDisplayMetrics(mDisplayId);
- }
-
- ReportedDisplayMetrics getInitialDisplayMetrics() {
- return mInitialDisplayMetrics;
- }
-
- ReportedDisplayMetrics getDisplayMetrics() {
- return ReportedDisplayMetrics.getDisplayMetrics(mDisplayId);
- }
-
- void overrideDisplayMetrics(final Size size, final int density) {
- mInitialDisplayMetrics.setDisplayMetrics(size, density);
- }
-
- @Override
- public void close() {
- mInitialDisplayMetrics.restoreDisplayMetrics();
- }
- }
}
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayActivityLaunchTests.java b/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayActivityLaunchTests.java
index 43ddaee..de0372f 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayActivityLaunchTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayActivityLaunchTests.java
@@ -275,7 +275,7 @@
nonResizeableSession.takeCallbackHistory();
// Try to move the non-resizeable activity to the top of stack on secondary display.
- moveActivityToStack(NON_RESIZEABLE_ACTIVITY, externalFrontStackId);
+ moveActivityToStackOrOnTop(NON_RESIZEABLE_ACTIVITY, externalFrontStackId);
// Wait for a while to check that it will move.
assertTrue("Non-resizeable activity should be moved",
mWmState.waitForWithAmState(
@@ -653,10 +653,10 @@
assertEquals("Activity launched on secondary display must be resumed",
getActivityName(LAUNCHING_ACTIVITY), secondFrontStack.mResumedActivity);
mWmState.assertFocusedStack("Top stack must be on primary display", frontStackId);
- assertEquals("Top stack must only contain 1 task",
- 1, secondFrontStack.getTasks().size());
- assertEquals("Top task must only contain 1 activity",
- 1, secondFrontStack.getTasks().get(0).mActivities.size());
+ assertEquals("Second display must only contain 1 root task", 1,
+ mWmState.getDisplay(newDisplay.mId).getRootTasks().size());
+ assertEquals("Top task must only contain 1 activity", 1,
+ secondFrontStack.getActivities().size());
}
/**
@@ -719,10 +719,10 @@
getActivityName(ALT_LAUNCHING_ACTIVITY),
secondFrontStack.mResumedActivity);
mWmState.assertFocusedStack("Top stack must be on secondary display", secondFrontStackId);
- assertEquals("Top stack must only contain 1 task",
- 1, secondFrontStack.getTasks().size());
+ assertEquals("Second display must only contain 1 task",
+ 1, mWmState.getDisplay(newDisplay.mId).getRootTasks().size());
assertEquals("Top stack task must contain 2 activities",
- 2, secondFrontStack.getTasks().get(0).mActivities.size());
+ 2, secondFrontStack.getActivities().size());
}
/**
@@ -848,6 +848,7 @@
getPendingIntentActivity(TEST_ACTIVITY).send(mContext, resultCode, null /* intent */,
null /* onFinished */, null /* handler */, null /* requiredPermission */,
options.toBundle());
+ waitAndAssertActivityState(TOP_ACTIVITY, STATE_STOPPED, "Activity should be stopped");
waitAndAssertTopResumedActivity(TEST_ACTIVITY, displayContent.mId,
"Activity launched on secondary display and on top");
}
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayKeyguardTests.java b/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayKeyguardTests.java
index b45d621..e1df6d0 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayKeyguardTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayKeyguardTests.java
@@ -18,6 +18,7 @@
import static android.server.wm.UiDeviceUtils.pressBackButton;
import static android.server.wm.app.Components.DISMISS_KEYGUARD_ACTIVITY;
+import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
import static org.junit.Assert.assertFalse;
@@ -26,6 +27,7 @@
import android.platform.test.annotations.Presubmit;
import android.server.wm.WindowManagerState.DisplayContent;
+import android.util.Size;
import org.junit.Before;
import org.junit.Test;
@@ -70,7 +72,6 @@
/**
* Tests keyguard dialog shows on secondary display.
- * @throws Exception
*/
@Test
public void testShowKeyguardDialogOnSecondaryDisplay() {
@@ -93,8 +94,77 @@
}
/**
+ * Tests keyguard dialog should exist after secondary display changed.
+ */
+ @Test
+ public void testShowKeyguardDialogSecondaryDisplayChange() {
+ final LockScreenSession lockScreenSession = createManagedLockScreenSession();
+ final VirtualDisplaySession virtualDisplaySession = createManagedVirtualDisplaySession();
+
+ final DisplayContent publicDisplay = virtualDisplaySession
+ .setPublicDisplay(true)
+ .createDisplay();
+
+ lockScreenSession.gotoKeyguard();
+ assertTrue("KeyguardDialog must show on external public display",
+ mWmState.waitForWithAmState(
+ state -> isKeyguardOnDisplay(state, publicDisplay.mId),
+ "keyguard window to show"));
+
+ // By default, a Presentation object should be dismissed if the DisplayMetrics changed.
+ // But this rule should not apply to KeyguardPresentation.
+ virtualDisplaySession.resizeDisplay();
+ mWmState.computeState();
+ assertTrue("KeyguardDialog must show on external public display even display changed",
+ mWmState.waitForWithAmState(
+ state -> isKeyguardOnDisplay(state, publicDisplay.mId),
+ "keyguard window to show"));
+ }
+
+ /**
+ * Tests keyguard dialog should exist after default display changed.
+ */
+ @Test
+ public void testShowKeyguardDialogDefaultDisplayChange() {
+ final LockScreenSession lockScreenSession = createManagedLockScreenSession();
+ final VirtualDisplaySession virtualDisplaySession = createManagedVirtualDisplaySession();
+ final DisplayMetricsSession displayMetricsSession =
+ createManagedDisplayMetricsSession(DEFAULT_DISPLAY);
+
+ // Use simulate display instead of virtual display, because VirtualDisplayActivity will
+ // relaunch after configuration change.
+ final DisplayContent publicDisplay = virtualDisplaySession
+ .setSimulateDisplay(true)
+ .createDisplay();
+
+ lockScreenSession.gotoKeyguard();
+ assertTrue("KeyguardDialog must show on external public display",
+ mWmState.waitForWithAmState(
+ state -> isKeyguardOnDisplay(state, publicDisplay.mId),
+ "keyguard window to show"));
+
+ // Unlock then lock again, to ensure the display metrics has updated.
+ lockScreenSession.wakeUpDevice().unlockDevice();
+ // Overriding the display metrics on the default display should not affect Keyguard to show
+ // on secondary display.
+ final ReportedDisplayMetrics originalDisplayMetrics =
+ displayMetricsSession.getInitialDisplayMetrics();
+ final Size overrideSize = new Size(
+ (int) (originalDisplayMetrics.physicalSize.getWidth() * 1.5),
+ (int) (originalDisplayMetrics.physicalSize.getHeight() * 1.5));
+ final Integer overrideDensity = (int) (originalDisplayMetrics.physicalDensity * 1.1);
+ displayMetricsSession.overrideDisplayMetrics(overrideSize, overrideDensity);
+
+ lockScreenSession.gotoKeyguard();
+ assertTrue("KeyguardDialog must show on external public display",
+ mWmState.waitForWithAmState(
+ state -> isKeyguardOnDisplay(state, publicDisplay.mId),
+ "keyguard window to show"));
+
+ }
+
+ /**
* Tests keyguard dialog cannot be shown on private display.
- * @throws Exception
*/
@Test
public void testNoKeyguardDialogOnPrivateDisplay() {
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayPolicyTests.java b/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayPolicyTests.java
index 5ba2c63..da874ab 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayPolicyTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayPolicyTests.java
@@ -389,7 +389,7 @@
pair(newDisplay.mId, TEST_ACTIVITY));
// Move activity from secondary display to primary.
- moveActivityToStack(TEST_ACTIVITY, defaultDisplayStackId);
+ moveActivityToStackOrOnTop(TEST_ACTIVITY, defaultDisplayStackId);
waitAndAssertTopResumedActivity(TEST_ACTIVITY, DEFAULT_DISPLAY,
"Moved activity must be on top");
}
@@ -734,8 +734,7 @@
private void assertTopTaskSameSurfaceSizeWithDisplay(int displayId) {
final DisplayContent display = mWmState.getDisplay(displayId);
final int stackId = mWmState.getFrontRootTaskId(displayId);
- final ActivityTask task =
- mWmState.getRootTask(stackId).mTasks.get(0);
+ final ActivityTask task = mWmState.getRootTask(stackId).getTopTask();
assertEquals("Task must have same surface width with its display",
display.getSurfaceSize(), task.getSurfaceWidth());
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplaySecurityTests.java b/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplaySecurityTests.java
index 1e2e8c3..c48d80a 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplaySecurityTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplaySecurityTests.java
@@ -555,7 +555,8 @@
waitAndAssertTopResumedActivity(SECOND_ACTIVITY, newDisplay.mId,
"Top activity must be the newly launched one");
frontStack = mWmState.getRootTask(frontStackId);
- assertEquals("Secondary display must contain 1 task", 1, frontStack.getTasks().size());
+ assertEquals("Secondary display must contain 1 task", 1,
+ mWmState.getDisplay(newDisplay.mId).getRootTasks().size());
}
/**
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayTestBase.java b/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayTestBase.java
index 8ff9745..8cf1b47 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayTestBase.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayTestBase.java
@@ -241,6 +241,38 @@
}
}
+ public static class DisplayMetricsSession implements AutoCloseable {
+ private final ReportedDisplayMetrics mInitialDisplayMetrics;
+ private final int mDisplayId;
+
+ DisplayMetricsSession(int displayId) {
+ mDisplayId = displayId;
+ mInitialDisplayMetrics = ReportedDisplayMetrics.getDisplayMetrics(mDisplayId);
+ }
+
+ ReportedDisplayMetrics getInitialDisplayMetrics() {
+ return mInitialDisplayMetrics;
+ }
+
+ ReportedDisplayMetrics getDisplayMetrics() {
+ return ReportedDisplayMetrics.getDisplayMetrics(mDisplayId);
+ }
+
+ void overrideDisplayMetrics(final Size size, final int density) {
+ mInitialDisplayMetrics.setDisplayMetrics(size, density);
+ }
+
+ @Override
+ public void close() {
+ mInitialDisplayMetrics.restoreDisplayMetrics();
+ }
+ }
+
+ /** @see ObjectTracker#manage(AutoCloseable) */
+ protected DisplayMetricsSession createManagedDisplayMetricsSession(int displayId) {
+ return mObjectTracker.manage(new DisplayMetricsSession(displayId));
+ }
+
void waitForDisplayGone(Predicate<DisplayContent> displayPredicate) {
waitForOrFail("displays to be removed", () -> {
mWmState.computeState();
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 debc7ef..998f553 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/PinnedStackTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/PinnedStackTests.java
@@ -574,7 +574,7 @@
launchActivity(PIP_ACTIVITY2, EXTRA_ENTER_PIP, "true");
final ActivityTask pinnedStack = getPinnedStack();
- assertEquals(1, pinnedStack.getTasks().size());
+ assertEquals(0, pinnedStack.getTasks().size());
assertTrue(mWmState.containsActivityInWindowingMode(
PIP_ACTIVITY2, WINDOWING_MODE_PINNED));
assertTrue(mWmState.containsActivityInWindowingMode(
@@ -1017,8 +1017,7 @@
launchActivity(PIP_ACTIVITY, EXTRA_ENTER_PIP, "true");
waitForEnterPip(PIP_ACTIVITY);
assertPinnedStackExists();
- ActivityTask stack = mWmState.getStandardStackByWindowingMode(
- WINDOWING_MODE_PINNED);
+ ActivityTask stack = mWmState.getStandardStackByWindowingMode(WINDOWING_MODE_PINNED);
int stackId = stack.mRootTaskId;
int taskId = stack.getTopTask().mTaskId;
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleSplitScreenTests.java b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleSplitScreenTests.java
index 4c21f49..93ecabc 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleSplitScreenTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleSplitScreenTests.java
@@ -112,7 +112,7 @@
}
@Test
- public void testOccludingMovedBetweenStacks() throws Exception {
+ public void testOccludingOnSplitSecondaryStack() throws Exception {
// Launch first activity
final Activity firstActivity = launchActivityAndWait(FirstActivity.class);
@@ -140,21 +140,10 @@
.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK)
.launch();
waitAndAssertActivityStates(state(secondActivity, ON_STOP));
-
- // Move occluding third activity to side, it will occlude first now
- getLifecycleLog().clear();
- moveActivityToStack(getComponentName(ThirdActivity.class), primarySplitStack);
-
- waitAndAssertActivityStates(state(secondActivity, ON_RESUME),
- state(firstActivity, ON_STOP));
- LifecycleVerifier.assertEmptySequence(ThirdActivity.class, getLifecycleLog(), "moveToSide");
- LifecycleVerifier.assertRestartAndResumeSequence(SecondActivity.class, getLifecycleLog());
- LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(),
- Arrays.asList(ON_PAUSE, ON_STOP), "moveToSide");
}
@Test
- public void testTranslucentMovedBetweenStacks() throws Exception {
+ public void testTranslucentOnSplitSecondaryStack() throws Exception {
// Launch first activity
final Activity firstActivity = launchActivityAndWait(FirstActivity.class);
@@ -183,17 +172,6 @@
.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK)
.launch();
waitAndAssertActivityStates(state(secondActivity, ON_PAUSE));
-
- // Move translucent activity to side, it will be on top of the first now
- getLifecycleLog().clear();
- moveActivityToStack(getComponentName(TranslucentActivity.class), primarySplitStack);
-
- waitAndAssertActivityStates(state(firstActivity, ON_PAUSE),
- state(secondActivity, ON_RESUME));
- LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(),
- Arrays.asList(ON_PAUSE), "moveToSide");
- // Translucent activity can be either relaunched or preserved depending on whether the split
- // sizes match. Not verifying its lifecycle here.
}
@Test
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleTests.java b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleTests.java
index 3d31935..941b941 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleTests.java
@@ -157,7 +157,7 @@
// Move translucent activity into the stack with the first activity
getLifecycleLog().clear();
- moveActivityToStack(getComponentName(TranslucentActivity.class), firstActivityStack);
+ moveActivityToStackOrOnTop(getComponentName(TranslucentActivity.class), firstActivityStack);
// Wait for translucent activity to resume and first activity to pause
waitAndAssertActivityStates(state(translucentActivity, ON_RESUME),
diff --git a/tests/framework/base/windowmanager/util/src/android/server/wm/ActivityManagerTestBase.java b/tests/framework/base/windowmanager/util/src/android/server/wm/ActivityManagerTestBase.java
index b6fa201..b7352fe 100644
--- a/tests/framework/base/windowmanager/util/src/android/server/wm/ActivityManagerTestBase.java
+++ b/tests/framework/base/windowmanager/util/src/android/server/wm/ActivityManagerTestBase.java
@@ -60,7 +60,6 @@
import static android.server.wm.ActivityLauncher.KEY_USE_APPLICATION_CONTEXT;
import static android.server.wm.ActivityLauncher.KEY_WINDOWING_MODE;
import static android.server.wm.ActivityLauncher.launchActivityFromExtras;
-import static android.server.wm.WindowManagerState.STATE_RESUMED;
import static android.server.wm.CommandSession.KEY_FORWARD;
import static android.server.wm.ComponentNameUtils.getActivityName;
import static android.server.wm.ComponentNameUtils.getLogTag;
@@ -74,6 +73,7 @@
import static android.server.wm.UiDeviceUtils.pressUnlockButton;
import static android.server.wm.UiDeviceUtils.pressWakeupButton;
import static android.server.wm.UiDeviceUtils.waitForDeviceIdle;
+import static android.server.wm.WindowManagerState.STATE_RESUMED;
import static android.server.wm.app.Components.BROADCAST_RECEIVER_ACTIVITY;
import static android.server.wm.app.Components.BroadcastReceiverActivity.ACTION_TRIGGER_BROADCAST;
import static android.server.wm.app.Components.BroadcastReceiverActivity.EXTRA_BROADCAST_ORIENTATION;
@@ -141,6 +141,7 @@
import android.view.InputDevice;
import android.view.KeyEvent;
import android.view.MotionEvent;
+import android.view.ViewConfiguration;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -533,11 +534,33 @@
return ComponentName.unflattenFromString(mContext.getResources().getString(resId));
}
+ /**
+ * Move around center of the specific display to ensures the display to be focused without
+ * triggering potential clicked event to impact the test environment.
+ * (e.g: Keyguard credential activated unexpectedly.)
+ *
+ * @param displayId the display ID to gain focused by inject swipe action
+ */
+ protected void moveAroundCenterSync(int displayId) {
+ final Rect bounds = mWmState.getDisplay(displayId).getDisplayRect();
+ final long downTime = SystemClock.uptimeMillis();
+ final int touchSlop = ViewConfiguration.get(mContext).getScaledTouchSlop();
+ final int downX = bounds.left + bounds.width() / 2;
+ final int downY = bounds.top + bounds.height() / 2;
+ injectMotion(downTime, downTime, MotionEvent.ACTION_DOWN, downX, downY, displayId, true);
+
+ final int moveX = downX + Float.floatToIntBits(touchSlop / 2.0f);
+ final int moveY = downY + Float.floatToIntBits(touchSlop / 2.0f);
+ injectMotion(downTime, downTime, MotionEvent.ACTION_MOVE, moveX, moveY, displayId, true);
+
+ final long upTime = SystemClock.uptimeMillis();
+ injectMotion(downTime, upTime, MotionEvent.ACTION_UP, moveX, moveY, displayId, true);
+ }
+
protected void tapOnDisplaySync(int x, int y, int displayId) {
tapOnDisplay(x, y, displayId, true /* sync*/);
}
-
private void tapOnDisplay(int x, int y, int displayId, boolean sync) {
final long downTime = SystemClock.uptimeMillis();
injectMotion(downTime, downTime, MotionEvent.ACTION_DOWN, x, y, displayId, sync);
@@ -658,10 +681,19 @@
mWmState.computeState();
final List<WindowManagerState.ActivityTask> stacks = mWmState.getRootTasks();
for (WindowManagerState.ActivityTask stack : stacks) {
- for (WindowManagerState.ActivityTask task : stack.mTasks) {
- if (task.mTaskId == taskId) {
- return stack;
- }
+ if (stack.getTask(taskId) != null) {
+ return stack;
+ }
+ }
+ return null;
+ }
+
+ protected WindowManagerState.ActivityTask getRootTask(int taskId) {
+ mWmState.computeState();
+ final List<WindowManagerState.ActivityTask> rootTasks = mWmState.getRootTasks();
+ for (WindowManagerState.ActivityTask rootTask : rootTasks) {
+ if (rootTask.getTaskId() == taskId) {
+ return rootTask;
}
}
return null;
@@ -831,12 +863,25 @@
return result[0];
}
- protected void moveActivityToStack(ComponentName activityName, int stackId) {
+ /** Move activity to stack or on top of the given stack when the stack is a leak task. */
+ protected void moveActivityToStackOrOnTop(ComponentName activityName, int stackId) {
mWmState.computeState(activityName);
- final int taskId = mWmState.getTaskByActivity(activityName).mTaskId;
- SystemUtil.runWithShellPermissionIdentity(
- () -> mAtm.moveTaskToStack(taskId, stackId, true));
-
+ WindowManagerState.ActivityTask rootTask = getRootTask(stackId);
+ if (rootTask.getActivities().size() != 0) {
+ // If the root task is a 1-level task, start the activity on top of given task.
+ getLaunchActivityBuilder()
+ .setDisplayId(rootTask.mDisplayId)
+ .setWindowingMode(rootTask.getWindowingMode())
+ .setActivityType(rootTask.getActivityType())
+ .setTargetActivity(activityName)
+ .allowMultipleInstances(false)
+ .setUseInstrumentation()
+ .execute();
+ } else {
+ final int taskId = mWmState.getTaskByActivity(activityName).mTaskId;
+ SystemUtil.runWithShellPermissionIdentity(
+ () -> mAtm.moveTaskToStack(taskId, stackId, true));
+ }
mWmState.waitForValidState(new WaitForValidActivityState.Builder(activityName)
.setStackId(stackId)
.build());
@@ -1188,7 +1233,7 @@
public LockScreenSession enterAndConfirmLockCredential() {
// Ensure focus will switch to default display. Meanwhile we cannot tap on center area,
// which may tap on input credential area.
- tapOnDisplaySync(10, 10, DEFAULT_DISPLAY);
+ moveAroundCenterSync(DEFAULT_DISPLAY);
waitForDeviceIdle(3000);
SystemUtil.runWithShellPermissionIdentity(() ->
@@ -1230,7 +1275,7 @@
LockScreenSession unlockDevice() {
// Make sure the unlock button event is send to the default display.
- tapOnDisplaySync(10, 10, DEFAULT_DISPLAY);
+ moveAroundCenterSync(DEFAULT_DISPLAY);
pressUnlockButton();
return this;
@@ -2201,7 +2246,7 @@
// all tests afterward would also fail (since the leakage is always there) and fire
// unnecessary false alarms.
try {
- mWmState.assertEmptyStackOrTask();
+ mWmState.assertNoneEmptyTasks();
} catch (Throwable t) {
sStackTaskLeakFound = true;
addError(t);
diff --git a/tests/framework/base/windowmanager/util/src/android/server/wm/CommandSession.java b/tests/framework/base/windowmanager/util/src/android/server/wm/CommandSession.java
index e3a1b62..4039a13 100644
--- a/tests/framework/base/windowmanager/util/src/android/server/wm/CommandSession.java
+++ b/tests/framework/base/windowmanager/util/src/android/server/wm/CommandSession.java
@@ -956,7 +956,7 @@
/** Same as {@link #getConfigInfo()}, but for Application. */
private ConfigInfo getAppConfigInfo() {
final Application application = (Application) getApplicationContext();
- return new ConfigInfo(application, application.getDisplay());
+ return new ConfigInfo(application, getDisplay());
}
}
diff --git a/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerState.java b/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerState.java
index 793ece8..61c3a380 100644
--- a/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerState.java
+++ b/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerState.java
@@ -76,6 +76,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -412,11 +413,9 @@
public String getTopActivityName(int displayId) {
if (!getDisplay(displayId).mRootTasks.isEmpty()) {
final ActivityTask topStack = getDisplay(displayId).mRootTasks.get(0);
- if (!topStack.mTasks.isEmpty()) {
- final ActivityTask topTask = topStack.mTasks.get(0);
- if (!topTask.mActivities.isEmpty()) {
- return topTask.mActivities.get(0).name;
- }
+ final ActivityTask topTask = topStack.getTopTask();
+ if (!topTask.mActivities.isEmpty()) {
+ return topTask.mActivities.get(0).name;
}
}
return null;
@@ -519,7 +518,7 @@
continue;
}
if (stack.getWindowingMode() == windowingMode) {
- count += stack.mTasks.size();
+ count += stack.mTasks.isEmpty() ? 1 : stack.mTasks.size();
}
}
return count;
@@ -673,16 +672,16 @@
ActivityTask getHomeTask() {
final ActivityTask homeStack = getStackByActivityType(ACTIVITY_TYPE_HOME);
- if (homeStack != null && !homeStack.mTasks.isEmpty()) {
- return homeStack.mTasks.get(0);
+ if (homeStack != null) {
+ return homeStack.getTopTask();
}
return null;
}
private ActivityTask getRecentsTask() {
final ActivityTask recentsStack = getStackByActivityType(ACTIVITY_TYPE_RECENTS);
- if (recentsStack != null && !recentsStack.mTasks.isEmpty()) {
- return recentsStack.mTasks.get(0);
+ if (recentsStack != null) {
+ return recentsStack.getTopTask();
}
return null;
}
@@ -704,24 +703,15 @@
}
public ActivityTask getTaskByActivity(ComponentName activityName) {
- return getTaskByActivityInternal(getActivityName(activityName), WINDOWING_MODE_UNDEFINED);
+ return getTaskByActivity(activityName, WINDOWING_MODE_UNDEFINED);
}
ActivityTask getTaskByActivity(ComponentName activityName, int windowingMode) {
- return getTaskByActivityInternal(getActivityName(activityName), windowingMode);
- }
-
- private ActivityTask getTaskByActivityInternal(String fullName, int windowingMode) {
for (ActivityTask stack : mRootTasks) {
if (windowingMode == WINDOWING_MODE_UNDEFINED
|| windowingMode == stack.getWindowingMode()) {
- for (ActivityTask task : stack.mTasks) {
- for (Activity activity : task.mActivities) {
- if (activity.name.equals(fullName)) {
- return task;
- }
- }
- }
+ Activity activity = stack.getActivity(activityName);
+ if (activity != null) return activity.task;
}
}
return null;
@@ -739,21 +729,20 @@
// If activityName is null, count all activities in the task.
// Otherwise count activities that have specified name.
for (ActivityTask stack : mRootTasks) {
- for (ActivityTask task : stack.mTasks) {
- if (task.mTaskId == taskId) {
- if (activityName == null) {
- return task.mActivities.size();
- }
- final String fullName = getActivityName(activityName);
- int count = 0;
- for (Activity activity : task.mActivities) {
- if (activity.name.equals(fullName)) {
- count++;
- }
- }
- return count;
+ final ActivityTask task = stack.getTask(taskId);
+ if (task == null) continue;
+
+ if (activityName == null) {
+ return task.mActivities.size();
+ }
+ final String fullName = getActivityName(activityName);
+ int count = 0;
+ for (Activity activity : task.mActivities) {
+ if (activity.name.equals(fullName)) {
+ count++;
}
}
+ return count;
}
return 0;
}
@@ -1102,7 +1091,7 @@
mTasks.add(new ActivityTask(proto.tasks[i]));
}
for (int i = 0; i < proto.activities.length; i++) {
- mActivities.add(new Activity(proto.activities[i]));
+ mActivities.add(new Activity(proto.activities[i], this));
}
}
@@ -1130,33 +1119,37 @@
return mActivities;
}
- /**
- * @return the top task in the stack.
- */
+ /** @return the top task in the stack. */
ActivityTask getTopTask() {
- if (!mTasks.isEmpty()) {
- // NOTE: Unlike the ActivityManager internals, we dump the state from top to bottom,
- // so the indices are inverted
- return mTasks.get(0);
- }
- return null;
+ // NOTE: Unlike the WindowManager internals, we dump the state from top to bottom,
+ // so the indices are inverted
+ return getTask((t) -> true);
+ }
+
+ public String getResumedActivity() {
+ return mResumedActivity;
}
public List<ActivityTask> getTasks() {
return new ArrayList<>(mTasks);
}
- ActivityTask getTask(int taskId) {
+ ActivityTask getTask(Predicate<ActivityTask> predicate) {
for (ActivityTask task : mTasks) {
- if (taskId == task.mTaskId) {
- return task;
- }
+ if (predicate.test(task)) return task;
}
- return null;
+ return predicate.test(this) ? this : null;
}
- public String getResumedActivity() {
- return mResumedActivity;
+ ActivityTask getTask(int taskId) {
+ return getTask((t) -> t.mTaskId == taskId);
+ }
+
+ void forAllTasks(Consumer<ActivityTask> consumer) {
+ for (ActivityTask task : mTasks) {
+ consumer.accept(task);
+ }
+ consumer.accept(this);
}
Activity getActivity(Predicate<Activity> predicate) {
@@ -1188,9 +1181,11 @@
boolean frontOfTask;
int procId = -1;
public boolean translucent;
+ ActivityTask task;
- Activity(ActivityRecordProto proto) {
+ Activity(ActivityRecordProto proto, ActivityTask parent) {
super(proto.windowToken.windowContainer);
+ task = parent;
name = proto.name;
state = proto.state;
visible = proto.visible;
diff --git a/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerStateHelper.java b/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerStateHelper.java
index b387965..fc31bd6 100644
--- a/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerStateHelper.java
+++ b/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerStateHelper.java
@@ -590,17 +590,12 @@
getKeyguardControllerState().aodShowing);
}
- public void assertEmptyStackOrTask() {
+ public void assertNoneEmptyTasks() {
computeState();
- final List<ActivityTask> stacks = getRootTasks();
- for (ActivityTask stack : stacks) {
- assertWithMessage("Empty stack was found, id = " + stack.mRootTaskId)
- .that(stack.getTopTask()).isNotNull();
- final List<ActivityTask> tasks = stack.getTasks();
- for (ActivityTask task : tasks) {
- assertWithMessage("Empty task was found, id = " + task.mTaskId)
- .that(task.getActivities().size()).isGreaterThan(0);
- }
+ final List<ActivityTask> tasks = getRootTasks();
+ for (ActivityTask task : tasks) {
+ task.forAllTasks((t) -> assertWithMessage("Empty task was found, id = " + t.mTaskId)
+ .that(t.mTasks.size() + t.mActivities.size()).isGreaterThan(0));
}
}
diff --git a/tests/inputmethod/mockime/res/xml/method.xml b/tests/inputmethod/mockime/res/xml/method.xml
index 2266fba..5b3cf85 100644
--- a/tests/inputmethod/mockime/res/xml/method.xml
+++ b/tests/inputmethod/mockime/res/xml/method.xml
@@ -15,5 +15,6 @@
limitations under the License.
-->
-<input-method xmlns:android="http://schemas.android.com/apk/res/android">
+<input-method xmlns:android="http://schemas.android.com/apk/res/android"
+ android:supportsInlineSuggestions="true">
</input-method>
diff --git a/tests/inputmethod/mockime/src/com/android/cts/mockime/ImeSettings.java b/tests/inputmethod/mockime/src/com/android/cts/mockime/ImeSettings.java
index a7bf781..a9d1414 100644
--- a/tests/inputmethod/mockime/src/com/android/cts/mockime/ImeSettings.java
+++ b/tests/inputmethod/mockime/src/com/android/cts/mockime/ImeSettings.java
@@ -47,6 +47,7 @@
private static final String INPUT_VIEW_SYSTEM_UI_VISIBILITY = "InputViewSystemUiVisibility";
private static final String HARD_KEYBOARD_CONFIGURATION_BEHAVIOR_ALLOWED =
"HardKeyboardConfigurationBehaviorAllowed";
+ private static final String INLINE_SUGGESTIONS_ENABLED = "InlineSuggestionsEnabled";
@NonNull
private final PersistableBundle mBundle;
@@ -105,6 +106,10 @@
return mBundle.getBoolean(HARD_KEYBOARD_CONFIGURATION_BEHAVIOR_ALLOWED, defaultValue);
}
+ public boolean getInlineSuggestionsEnabled() {
+ return mBundle.getBoolean(INLINE_SUGGESTIONS_ENABLED);
+ }
+
static Bundle serializeToBundle(@NonNull String eventCallbackActionName,
@Nullable Builder builder) {
final Bundle result = new Bundle();
@@ -214,5 +219,16 @@
mBundle.putBoolean(HARD_KEYBOARD_CONFIGURATION_BEHAVIOR_ALLOWED, allowed);
return this;
}
+
+ /**
+ * Controls whether inline suggestions are enabled for {@link MockIme}. If enabled, a
+ * suggestion strip will be rendered at the top of the keyboard.
+ *
+ * @param enabled {@code true} when {@link MockIme} is enabled to show inline suggestions.
+ */
+ public Builder setInlineSuggestionsEnabled(boolean enabled) {
+ mBundle.putBoolean(INLINE_SUGGESTIONS_ENABLED, enabled);
+ return this;
+ }
}
}
diff --git a/tests/inputmethod/mockime/src/com/android/cts/mockime/MockIme.java b/tests/inputmethod/mockime/src/com/android/cts/mockime/MockIme.java
index 590ce86..6142b9e 100644
--- a/tests/inputmethod/mockime/src/com/android/cts/mockime/MockIme.java
+++ b/tests/inputmethod/mockime/src/com/android/cts/mockime/MockIme.java
@@ -16,6 +16,8 @@
package com.android.cts.mockime;
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
import android.content.BroadcastReceiver;
@@ -25,6 +27,7 @@
import android.content.IntentFilter;
import android.content.res.Configuration;
import android.inputmethodservice.InputMethodService;
+import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
@@ -36,31 +39,43 @@
import android.os.SystemClock;
import android.text.TextUtils;
import android.util.Log;
+import android.util.Size;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
+import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowInsets;
import android.view.WindowManager;
+import android.view.inline.InlinePresentationSpec;
import android.view.inputmethod.CompletionInfo;
import android.view.inputmethod.CorrectionInfo;
import android.view.inputmethod.CursorAnchorInfo;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.ExtractedTextRequest;
+import android.view.inputmethod.InlineSuggestion;
+import android.view.inputmethod.InlineSuggestionsRequest;
+import android.view.inputmethod.InlineSuggestionsResponse;
import android.view.inputmethod.InputBinding;
import android.view.inputmethod.InputContentInfo;
import android.view.inputmethod.InputMethod;
import android.widget.LinearLayout;
-import android.widget.RelativeLayout;
+import android.widget.ScrollView;
import android.widget.TextView;
import androidx.annotation.AnyThread;
import androidx.annotation.CallSuper;
+import androidx.annotation.GuardedBy;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.BooleanSupplier;
import java.util.function.Consumer;
@@ -407,23 +422,38 @@
final int defaultBackgroundColor =
getResources().getColor(android.R.color.holo_orange_dark, null);
- setBackgroundColor(mSettings.getBackgroundColor(defaultBackgroundColor));
final int mainSpacerHeight = mSettings.getInputViewHeightWithoutSystemWindowInset(
LayoutParams.WRAP_CONTENT);
{
- final RelativeLayout layout = new RelativeLayout(getContext());
+ final LinearLayout layout = new LinearLayout(getContext());
+ layout.setOrientation(LinearLayout.VERTICAL);
+
+ if (mSettings.getInlineSuggestionsEnabled()) {
+ final ScrollView scrollView = new ScrollView(getContext());
+ final LayoutParams scrollViewParams = new LayoutParams(MATCH_PARENT, 100);
+ scrollView.setLayoutParams(scrollViewParams);
+
+ sSuggestionView = new LinearLayout(getContext());
+ sSuggestionView.setBackgroundColor(0xFFEEEEEE);
+ //TODO: Change magic id
+ sSuggestionView.setId(0x0102000b);
+ scrollView.addView(sSuggestionView,
+ new LayoutParams(MATCH_PARENT, MATCH_PARENT));
+
+ layout.addView(scrollView);
+ }
+
final TextView textView = new TextView(getContext());
- final RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
- RelativeLayout.LayoutParams.MATCH_PARENT,
- RelativeLayout.LayoutParams.WRAP_CONTENT);
- params.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
+ final LayoutParams params = new LayoutParams(MATCH_PARENT, WRAP_CONTENT);
textView.setLayoutParams(params);
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20);
textView.setGravity(Gravity.CENTER);
textView.setText(getImeId());
+ textView.setBackgroundColor(mSettings.getBackgroundColor(defaultBackgroundColor));
layout.addView(textView);
- addView(layout, LayoutParams.MATCH_PARENT, mainSpacerHeight);
+
+ addView(layout, MATCH_PARENT, mainSpacerHeight);
}
final int systemUiVisibility = mSettings.getInputViewSystemUiVisibility(0);
@@ -598,6 +628,114 @@
return new ImeState(hasInputBinding, hasDummyInputConnectionConnection);
}
+ private static LinearLayout sSuggestionView;
+ @GuardedBy("this")
+ private List<View> mSuggestionViews = new ArrayList<>();
+ @GuardedBy("this")
+ private List<Size> mSuggestionViewSizes = new ArrayList<>();
+ @GuardedBy("this")
+ private boolean mSuggestionViewVisible = false;
+
+ public InlineSuggestionsRequest onCreateInlineSuggestionsRequest(Bundle uiExtras) {
+ Log.d(TAG, "onCreateInlineSuggestionsRequest() called");
+ final ArrayList<InlinePresentationSpec> presentationSpecs = new ArrayList<>();
+ presentationSpecs.add(new InlinePresentationSpec.Builder(new Size(100, 100),
+ new Size(400, 100)).build());
+ presentationSpecs.add(new InlinePresentationSpec.Builder(new Size(100, 100),
+ new Size(400, 100)).build());
+
+ return new InlineSuggestionsRequest.Builder(presentationSpecs)
+ .setMaxSuggestionCount(6)
+ .build();
+ }
+
+ @Override
+ public boolean onInlineSuggestionsResponse(InlineSuggestionsResponse response) {
+ Log.d(TAG, "onInlineSuggestionsResponse() called");
+ AsyncTask.THREAD_POOL_EXECUTOR.execute(() -> {
+ onInlineSuggestionsResponseInternal(response);
+ });
+ return true;
+ }
+
+ private synchronized void updateInlineSuggestionVisibility(boolean visible, boolean force) {
+ Log.d(TAG, "updateInlineSuggestionVisibility() called, visible=" + visible + ", force="
+ + force);
+ mMainHandler.post(() -> {
+ Log.d(TAG, "updateInlineSuggestionVisibility() running");
+ if (visible == mSuggestionViewVisible && !force) {
+ return;
+ } else if (visible) {
+ sSuggestionView.removeAllViews();
+ final int size = mSuggestionViews.size();
+ for (int i = 0; i < size; i++) {
+ if(mSuggestionViews.get(i) == null) {
+ continue;
+ }
+ ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(
+ mSuggestionViewSizes.get(i).getWidth(),
+ mSuggestionViewSizes.get(i).getHeight());
+ sSuggestionView.addView(mSuggestionViews.get(i), layoutParams);
+ }
+ mSuggestionViewVisible = true;
+ } else {
+ sSuggestionView.removeAllViews();
+ mSuggestionViewVisible = false;
+ }
+ });
+ }
+
+ private void onSuggestionViewUpdated() {
+ getTracer().onSuggestionViewUpdated();
+ }
+
+ private synchronized void updateSuggestionViews(View[] suggestionViews, Size[] sizes) {
+ Log.d(TAG, "updateSuggestionViews() called on " + suggestionViews.length + " views");
+ mSuggestionViews = Arrays.asList(suggestionViews);
+ mSuggestionViewSizes = Arrays.asList(sizes);
+ final boolean visible = !mSuggestionViews.isEmpty();
+ updateInlineSuggestionVisibility(visible, true);
+ onSuggestionViewUpdated();
+ }
+
+ private void onInlineSuggestionsResponseInternal(InlineSuggestionsResponse response) {
+ if (response == null || response.getInlineSuggestions() == null) {
+ Log.w(TAG, "onInlineSuggestionsResponseInternal() null response/suggestions");
+ return;
+ }
+ final List<InlineSuggestion> inlineSuggestions = response.getInlineSuggestions();
+ final int totalSuggestionsCount = inlineSuggestions.size();
+ Log.d(TAG, "onInlineSuggestionsResponseInternal() called. Suggestion="
+ + totalSuggestionsCount);
+
+ if (totalSuggestionsCount == 0) {
+ updateSuggestionViews(new View[]{} , new Size[]{});
+ }
+
+ final AtomicInteger suggestionsCount = new AtomicInteger(totalSuggestionsCount);
+ final View[] suggestionViews = new View[totalSuggestionsCount];
+ final Size[] sizes = new Size[totalSuggestionsCount];
+
+ for (int i = 0; i < totalSuggestionsCount; i++) {
+ final int index = i;
+ InlineSuggestion inlineSuggestion = inlineSuggestions.get(index);
+ Size size = inlineSuggestion.getInfo().getPresentationSpec().getMaxSize();
+ Log.d(TAG, "Calling inflate on suggestion " + i);
+ inlineSuggestion.inflate(this, size,
+ AsyncTask.THREAD_POOL_EXECUTOR,
+ suggestionView -> {
+ Log.d(TAG, "new inline suggestion view ready");
+ if(suggestionView != null) {
+ suggestionViews[index] = suggestionView;
+ sizes[index] = size;
+ }
+ if (suggestionsCount.decrementAndGet() == 0) {
+ updateSuggestionViews(suggestionViews, sizes);
+ }
+ });
+ }
+ }
+
/**
* Event tracing helper class for {@link MockIme}.
*/
@@ -822,5 +960,9 @@
imeLayoutInfo.writeToBundle(arguments);
recordEventInternal("onInputViewLayoutChanged", runnable, arguments);
}
+
+ public void onSuggestionViewUpdated() {
+ recordEventInternal("onSuggestionViewUpdated", () -> {}, new Bundle());
+ }
}
}
diff --git a/tests/location/location_fine/AndroidManifest.xml b/tests/location/location_fine/AndroidManifest.xml
index 01fe459..0804333 100644
--- a/tests/location/location_fine/AndroidManifest.xml
+++ b/tests/location/location_fine/AndroidManifest.xml
@@ -27,6 +27,7 @@
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/>
+ <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
android:targetPackage="android.location.cts.fine"
diff --git a/tests/location/location_fine/src/android/location/cts/fine/GnssAntennaInfoRegistrationTest.java b/tests/location/location_fine/src/android/location/cts/fine/GnssAntennaInfoRegistrationTest.java
index fa7c032..5aa2bd3 100644
--- a/tests/location/location_fine/src/android/location/cts/fine/GnssAntennaInfoRegistrationTest.java
+++ b/tests/location/location_fine/src/android/location/cts/fine/GnssAntennaInfoRegistrationTest.java
@@ -71,32 +71,30 @@
@Test
public void testGnssAntennaInfoCallbackRegistration() {
- TestGnssAntennaInfoCallback callback = new TestGnssAntennaInfoCallback();
-
// TODO(skz): check that version code is greater than R
- mManager.registerAntennaInfoCallback(Executors.newSingleThreadExecutor(), callback);
+ if(!mManager.getGnssCapabilities().hasGnssAntennaInfo()) {
+ // GnssAntennaInfo is not supported
+ return;
+ }
+
+ TestGnssAntennaInfoListener listener = new TestGnssAntennaInfoListener();
+
+ mManager.registerAntennaInfoListener(Executors.newSingleThreadExecutor(), listener);
try {
mAntennaInfoReciept.await(ANTENNA_INFO_TIMEOUT_SEC, TimeUnit.SECONDS);
} catch (InterruptedException e) {
Log.e(TAG, "Test was interrupted.");
}
- if(!callback.verifyStatus()) {
- // GnssAntennaInfo is not supported (or is taking too long)
- mManager.unregisterAntennaInfoCallback(callback);
- return;
- }
+ listener.verifyRegistration();
- callback.verifyRegistration();
-
- mManager.unregisterAntennaInfoCallback(callback);
+ mManager.unregisterAntennaInfoListener(listener);
}
- private class TestGnssAntennaInfoCallback extends GnssAntennaInfo.Callback {
+ private class TestGnssAntennaInfoListener implements GnssAntennaInfo.Listener {
private boolean receivedAntennaInfo = false;
private int numResults = 0;
- private int status = -10000;
@Override
public void onGnssAntennaInfoReceived(@NonNull List<GnssAntennaInfo> gnssAntennaInfos) {
@@ -109,15 +107,6 @@
}
}
- @Override
- public void onStatusChanged(@GnssAntennaInfoStatus int status) {
- this.status = status;
- }
-
- public boolean verifyStatus() {
- return (status == GnssAntennaInfo.Callback.STATUS_READY);
- }
-
public void verifyRegistration() {
assertTrue(receivedAntennaInfo);
assertThat(numResults).isGreaterThan(0);
diff --git a/tests/location/location_fine/src/android/location/cts/fine/GnssAntennaInfoTest.java b/tests/location/location_fine/src/android/location/cts/fine/GnssAntennaInfoTest.java
index 7805059..cbaabf7 100644
--- a/tests/location/location_fine/src/android/location/cts/fine/GnssAntennaInfoTest.java
+++ b/tests/location/location_fine/src/android/location/cts/fine/GnssAntennaInfoTest.java
@@ -18,11 +18,11 @@
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
import android.location.GnssAntennaInfo;
-import android.location.GnssAntennaInfo.PhaseCenterOffsetCoordinates;
-import android.location.GnssAntennaInfo.PhaseCenterVariationCorrections;
-import android.location.GnssAntennaInfo.SignalGainCorrections;
+import android.location.GnssAntennaInfo.PhaseCenterOffset;
+import android.location.GnssAntennaInfo.SphericalCorrections;
import android.os.Parcel;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -73,33 +73,56 @@
};
@Test
- public void testDescribeContents() {
- GnssAntennaInfo gnssAntennaInfo = createTestGnssAntennaInfo();
+ public void testFullAntennaInfoDescribeContents() {
+ GnssAntennaInfo gnssAntennaInfo = createFullTestGnssAntennaInfo();
assertEquals(0, gnssAntennaInfo.describeContents());
}
@Test
- public void testWriteToParcel() {
- GnssAntennaInfo gnssAntennaInfo = createTestGnssAntennaInfo();
+ public void testPartialAntennaInfoDescribeContents() {
+ GnssAntennaInfo gnssAntennaInfo = createPartialTestGnssAntennaInfo();
+ assertEquals(0, gnssAntennaInfo.describeContents());
+ }
+
+ @Test
+ public void testFullAntennaInfoWriteToParcel() {
+ GnssAntennaInfo gnssAntennaInfo = createFullTestGnssAntennaInfo();
Parcel parcel = Parcel.obtain();
gnssAntennaInfo.writeToParcel(parcel, 0);
parcel.setDataPosition(0);
GnssAntennaInfo newGnssAntennaInfo = GnssAntennaInfo.CREATOR.createFromParcel(parcel);
- verifyGnssAntennaInfoValuesAndGetters(newGnssAntennaInfo);
+ verifyFullGnssAntennaInfoValuesAndGetters(newGnssAntennaInfo);
parcel.recycle();
}
@Test
- public void testCreateGnssAntennaInfoAndGetValues() {
- GnssAntennaInfo gnssAntennaInfo = createTestGnssAntennaInfo();
- verifyGnssAntennaInfoValuesAndGetters(gnssAntennaInfo);
+ public void testPartialAntennaInfoWriteToParcel() {
+ GnssAntennaInfo gnssAntennaInfo = createPartialTestGnssAntennaInfo();
+ Parcel parcel = Parcel.obtain();
+ gnssAntennaInfo.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0);
+ GnssAntennaInfo newGnssAntennaInfo = GnssAntennaInfo.CREATOR.createFromParcel(parcel);
+ verifyPartialGnssAntennaInfoValuesAndGetters(newGnssAntennaInfo);
+ parcel.recycle();
}
- private static GnssAntennaInfo createTestGnssAntennaInfo() {
+ @Test
+ public void testCreateFullGnssAntennaInfoAndGetValues() {
+ GnssAntennaInfo gnssAntennaInfo = createFullTestGnssAntennaInfo();
+ verifyFullGnssAntennaInfoValuesAndGetters(gnssAntennaInfo);
+ }
+
+ @Test
+ public void testCreatePartialGnssAntennaInfoAndGetValues() {
+ GnssAntennaInfo gnssAntennaInfo = createPartialTestGnssAntennaInfo();
+ verifyPartialGnssAntennaInfoValuesAndGetters(gnssAntennaInfo);
+ }
+
+ private static GnssAntennaInfo createFullTestGnssAntennaInfo() {
double carrierFrequencyMHz = 13758.0;
- GnssAntennaInfo.PhaseCenterOffsetCoordinates phaseCenterOffsetCoordinates = new
- GnssAntennaInfo.PhaseCenterOffsetCoordinates(
+ GnssAntennaInfo.PhaseCenterOffset phaseCenterOffset = new
+ GnssAntennaInfo.PhaseCenterOffset(
4.3d,
1.4d,
2.10d,
@@ -110,75 +133,109 @@
double[][] phaseCenterVariationCorrectionsMillimeters = PHASE_CENTER_VARIATION_CORRECTIONS;
double[][] phaseCenterVariationCorrectionsUncertaintyMillimeters =
PHASE_CENTER_VARIATION_CORRECTION_UNCERTAINTIES;
- GnssAntennaInfo.PhaseCenterVariationCorrections
+ SphericalCorrections
phaseCenterVariationCorrections =
- new GnssAntennaInfo.PhaseCenterVariationCorrections(
+ new SphericalCorrections(
phaseCenterVariationCorrectionsMillimeters,
phaseCenterVariationCorrectionsUncertaintyMillimeters);
double[][] signalGainCorrectionsDbi = SIGNAL_GAIN_CORRECTIONS;
double[][] signalGainCorrectionsUncertaintyDbi = SIGNAL_GAIN_CORRECTION_UNCERTAINTIES;
- GnssAntennaInfo.SignalGainCorrections signalGainCorrections = new
- GnssAntennaInfo.SignalGainCorrections(
+ SphericalCorrections signalGainCorrections = new
+ SphericalCorrections(
signalGainCorrectionsDbi,
signalGainCorrectionsUncertaintyDbi);
- return new GnssAntennaInfo(carrierFrequencyMHz, phaseCenterOffsetCoordinates,
- phaseCenterVariationCorrections, signalGainCorrections);
+ return new GnssAntennaInfo.Builder()
+ .setCarrierFrequencyMHz(carrierFrequencyMHz)
+ .setPhaseCenterOffset(phaseCenterOffset)
+ .setPhaseCenterVariationCorrections(phaseCenterVariationCorrections)
+ .setSignalGainCorrections(signalGainCorrections)
+ .build();
}
- private static void verifyGnssAntennaInfoValuesAndGetters(GnssAntennaInfo gnssAntennaInfo) {
+ private static GnssAntennaInfo createPartialTestGnssAntennaInfo() {
+ double carrierFrequencyMHz = 13758.0;
+
+ GnssAntennaInfo.PhaseCenterOffset phaseCenterOffset = new
+ GnssAntennaInfo.PhaseCenterOffset(
+ 4.3d,
+ 1.4d,
+ 2.10d,
+ 2.1d,
+ 3.12d,
+ 0.5d);
+
+ return new GnssAntennaInfo.Builder()
+ .setCarrierFrequencyMHz(carrierFrequencyMHz)
+ .setPhaseCenterOffset(phaseCenterOffset)
+ .build();
+ }
+
+ private static void verifyPartialGnssAntennaInfoValuesAndGetters(GnssAntennaInfo gnssAntennaInfo) {
assertEquals(13758.0d, gnssAntennaInfo.getCarrierFrequencyMHz(), PRECISION);
// Phase Center Offset Tests --------------------------------------------------------
- PhaseCenterOffsetCoordinates phaseCenterOffsetCoordinates =
- gnssAntennaInfo.getPhaseCenterOffsetCoordinates();
- assertEquals(4.3d, phaseCenterOffsetCoordinates.getXCoordMillimeters(),
+ PhaseCenterOffset phaseCenterOffset =
+ gnssAntennaInfo.getPhaseCenterOffset();
+ assertEquals(4.3d, phaseCenterOffset.getXOffsetMm(),
PRECISION);
- assertEquals(1.4d, phaseCenterOffsetCoordinates.getXCoordUncertaintyMillimeters(),
+ assertEquals(1.4d, phaseCenterOffset.getXOffsetUncertaintyMm(),
PRECISION);
- assertEquals(2.10d, phaseCenterOffsetCoordinates.getYCoordMillimeters(),
+ assertEquals(2.10d, phaseCenterOffset.getYOffsetMm(),
PRECISION);
- assertEquals(2.1d, phaseCenterOffsetCoordinates.getYCoordUncertaintyMillimeters(),
+ assertEquals(2.1d, phaseCenterOffset.getYOffsetUncertaintyMm(),
PRECISION);
- assertEquals(3.12d, phaseCenterOffsetCoordinates.getZCoordMillimeters(),
+ assertEquals(3.12d, phaseCenterOffset.getZOffsetMm(),
PRECISION);
- assertEquals(0.5d, phaseCenterOffsetCoordinates.getZCoordUncertaintyMillimeters(),
+ assertEquals(0.5d, phaseCenterOffset.getZOffsetUncertaintyMm(),
PRECISION);
// Phase Center Variation Corrections Tests -----------------------------------------
- PhaseCenterVariationCorrections phaseCenterVariationCorrections =
+ assertNull(gnssAntennaInfo.getPhaseCenterVariationCorrections());
+
+ // Signal Gain Corrections Tests -----------------------------------------------------
+ assertNull(gnssAntennaInfo.getSignalGainCorrections());
+ }
+
+ private static void verifyFullGnssAntennaInfoValuesAndGetters(GnssAntennaInfo gnssAntennaInfo) {
+ assertEquals(13758.0d, gnssAntennaInfo.getCarrierFrequencyMHz(), PRECISION);
+
+ // Phase Center Offset Tests --------------------------------------------------------
+ PhaseCenterOffset phaseCenterOffset =
+ gnssAntennaInfo.getPhaseCenterOffset();
+ assertEquals(4.3d, phaseCenterOffset.getXOffsetMm(),
+ PRECISION);
+ assertEquals(1.4d, phaseCenterOffset.getXOffsetUncertaintyMm(),
+ PRECISION);
+ assertEquals(2.10d, phaseCenterOffset.getYOffsetMm(),
+ PRECISION);
+ assertEquals(2.1d, phaseCenterOffset.getYOffsetUncertaintyMm(),
+ PRECISION);
+ assertEquals(3.12d, phaseCenterOffset.getZOffsetMm(),
+ PRECISION);
+ assertEquals(0.5d, phaseCenterOffset.getZOffsetUncertaintyMm(),
+ PRECISION);
+
+ // Phase Center Variation Corrections Tests -----------------------------------------
+ SphericalCorrections phaseCenterVariationCorrections =
gnssAntennaInfo.getPhaseCenterVariationCorrections();
- assertEquals(6, phaseCenterVariationCorrections.getNumRows());
- assertEquals(6, phaseCenterVariationCorrections.getNumColumns());
assertEquals(60.0d, phaseCenterVariationCorrections.getDeltaTheta(), PRECISION);
assertEquals(36.0d, phaseCenterVariationCorrections.getDeltaPhi(), PRECISION);
assertArrayEquals(PHASE_CENTER_VARIATION_CORRECTIONS, phaseCenterVariationCorrections
- .getRawCorrectionsArray());
+ .getCorrectionsArray());
assertArrayEquals(PHASE_CENTER_VARIATION_CORRECTION_UNCERTAINTIES,
- phaseCenterVariationCorrections.getRawCorrectionUncertaintiesArray());
- assertEquals(13.46d, phaseCenterVariationCorrections
- .getPhaseCenterVariationCorrectionMillimetersAt(2, 2), PRECISION);
- assertEquals(2.23d, phaseCenterVariationCorrections
- .getPhaseCenterVariationCorrectionUncertaintyMillimetersAt(2,
- 2), PRECISION);
+ phaseCenterVariationCorrections.getCorrectionUncertaintiesArray());
// Signal Gain Corrections Tests -----------------------------------------------------
- SignalGainCorrections signalGainCorrections = gnssAntennaInfo.getSignalGainCorrections();
+ SphericalCorrections signalGainCorrections = gnssAntennaInfo.getSignalGainCorrections();
- assertEquals(6, signalGainCorrections.getNumRows());
- assertEquals(6, signalGainCorrections.getNumColumns());
assertEquals(60.0d, signalGainCorrections.getDeltaTheta(), PRECISION);
assertEquals(36.0d, signalGainCorrections.getDeltaPhi(), PRECISION);
assertArrayEquals(SIGNAL_GAIN_CORRECTIONS, signalGainCorrections
- .getRawCorrectionsArray());
+ .getCorrectionsArray());
assertArrayEquals(SIGNAL_GAIN_CORRECTION_UNCERTAINTIES,
- signalGainCorrections.getRawCorrectionUncertaintiesArray());
- assertEquals(7.92d, signalGainCorrections
- .getSignalGainCorrectionDbiAt(2, 2), PRECISION);
- assertEquals(2.10d, signalGainCorrections
- .getSignalGainCorrectionUncertaintyDbiAt(2,
- 2), PRECISION);
+ signalGainCorrections.getCorrectionUncertaintiesArray());
}
}
diff --git a/tests/location/location_fine/src/android/location/cts/fine/LocationManagerFineTest.java b/tests/location/location_fine/src/android/location/cts/fine/LocationManagerFineTest.java
index 9afc79b..9e0ed0b 100644
--- a/tests/location/location_fine/src/android/location/cts/fine/LocationManagerFineTest.java
+++ b/tests/location/location_fine/src/android/location/cts/fine/LocationManagerFineTest.java
@@ -1146,11 +1146,10 @@
@Test
public void testRegisterGnssAntennaInfoCallback() {
- GnssAntennaInfo.Callback callback = new GnssAntennaInfo.Callback() {
- };
+ GnssAntennaInfo.Listener listener = (gnssAntennaInfos) -> {};
- mManager.registerAntennaInfoCallback(Executors.newSingleThreadExecutor(), callback);
- mManager.unregisterAntennaInfoCallback(callback);
+ mManager.registerAntennaInfoListener(Executors.newSingleThreadExecutor(), listener);
+ mManager.unregisterAntennaInfoListener(listener);
}
@Test
diff --git a/tests/location/location_fine/src/android/location/cts/fine/ScanningSettingsTest.java b/tests/location/location_fine/src/android/location/cts/fine/ScanningSettingsTest.java
index 802aa2c..b7853e8 100644
--- a/tests/location/location_fine/src/android/location/cts/fine/ScanningSettingsTest.java
+++ b/tests/location/location_fine/src/android/location/cts/fine/ScanningSettingsTest.java
@@ -22,6 +22,7 @@
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.database.ContentObserver;
+import android.net.wifi.WifiManager;
import android.os.Handler;
import android.os.HandlerThread;
import android.platform.test.annotations.AppModeFull;
@@ -33,6 +34,7 @@
import android.test.AndroidTestCase;
import com.android.compatibility.common.util.CddTest;
+import com.android.compatibility.common.util.PollingCheck;
import androidx.test.platform.app.InstrumentationRegistry;
@@ -76,12 +78,35 @@
}
@CddTest(requirement = "7.4.2/C-2-1")
- public void testWifiScanningSettings() throws PackageManager.NameNotFoundException {
+ public void testWifiScanningSettings() throws Exception {
if (isTv()) {
return;
}
launchScanningSettings();
- toggleSettingAndVerify(WIFI_SCANNING_TITLE_RES, Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE);
+
+ final Resources res = mPackageManager.getResourcesForApplication(SETTINGS_PACKAGE);
+ final int resId = res.getIdentifier(WIFI_SCANNING_TITLE_RES, "string", SETTINGS_PACKAGE);
+ final UiObject2 pref = mDevice.findObject(By.text(res.getString(resId)));
+
+ final WifiManager wifiManager = mContext.getSystemService(WifiManager.class);
+
+ final boolean checked = wifiManager.isScanAlwaysAvailable();
+
+ // Click the preference to toggle the setting.
+ pref.click();
+ PollingCheck.check(
+ "Scan Always Available wasn't toggled from " + checked + " to " + !checked,
+ TIMEOUT,
+ () -> !checked == wifiManager.isScanAlwaysAvailable()
+ );
+
+ // Click the preference again to toggle the setting back.
+ pref.click();
+ PollingCheck.check(
+ "Scan Always Available wasn't toggled from " + !checked + " to " + checked,
+ TIMEOUT,
+ () -> checked == wifiManager.isScanAlwaysAvailable()
+ );
}
@CddTest(requirement = "7.4.3/C-4-1")
diff --git a/tests/media/Android.bp b/tests/media/Android.bp
index b813fb2..adcf3de 100644
--- a/tests/media/Android.bp
+++ b/tests/media/Android.bp
@@ -24,6 +24,7 @@
"android.test.runner.stubs",
"android.test.base.stubs",
],
+ jni_uses_platform_apis: true,
jni_libs: [
"libctsmediav2muxer_jni",
"libctsmediav2extractor_jni",
diff --git a/tests/media/src/android/mediav2/cts/CodecDecoderTest.java b/tests/media/src/android/mediav2/cts/CodecDecoderTest.java
index 19fe20a..f3ef46d 100644
--- a/tests/media/src/android/mediav2/cts/CodecDecoderTest.java
+++ b/tests/media/src/android/mediav2/cts/CodecDecoderTest.java
@@ -794,7 +794,6 @@
* Test Decoder by Queuing CSD separately
*/
@LargeTest
- @Ignore("TODO(b/149031058)")
@Test(timeout = PER_TEST_TIMEOUT_LARGE_TEST_MS)
public void testSimpleDecodeQueueCSD() throws IOException, InterruptedException {
MediaFormat format = setUpSource(mTestFile);
diff --git a/tests/media/src/android/mediav2/cts/CodecTestBase.java b/tests/media/src/android/mediav2/cts/CodecTestBase.java
index a09cf5a..739b60a 100644
--- a/tests/media/src/android/mediav2/cts/CodecTestBase.java
+++ b/tests/media/src/android/mediav2/cts/CodecTestBase.java
@@ -45,22 +45,24 @@
private static final String LOG_TAG = CodecAsyncHandler.class.getSimpleName();
private final Lock mLock = new ReentrantLock();
private final Condition mCondition = mLock.newCondition();
- private CallBackQueue mCbInputQueue;
- private CallBackQueue mCbOutputQueue;
+ private final LinkedList<Pair<Integer, MediaCodec.BufferInfo>> mCbInputQueue;
+ private final LinkedList<Pair<Integer, MediaCodec.BufferInfo>> mCbOutputQueue;
private MediaFormat mOutFormat;
private boolean mSignalledOutFormatChanged;
private volatile boolean mSignalledError;
CodecAsyncHandler() {
- mCbInputQueue = new CallBackQueue();
- mCbOutputQueue = new CallBackQueue();
+ mCbInputQueue = new LinkedList<>();
+ mCbOutputQueue = new LinkedList<>();
mSignalledError = false;
mSignalledOutFormatChanged = false;
}
void clearQueues() {
+ mLock.lock();
mCbInputQueue.clear();
mCbOutputQueue.clear();
+ mLock.unlock();
}
void resetContext() {
@@ -73,14 +75,20 @@
@Override
public void onInputBufferAvailable(@NonNull MediaCodec codec, int bufferIndex) {
assertTrue(bufferIndex >= 0);
- mCbInputQueue.push(new Pair<>(bufferIndex, (MediaCodec.BufferInfo) null));
+ mLock.lock();
+ mCbInputQueue.add(new Pair<>(bufferIndex, (MediaCodec.BufferInfo) null));
+ mCondition.signalAll();
+ mLock.unlock();
}
@Override
public void onOutputBufferAvailable(@NonNull MediaCodec codec, int bufferIndex,
@NonNull MediaCodec.BufferInfo info) {
assertTrue(bufferIndex >= 0);
- mCbOutputQueue.push(new Pair<>(bufferIndex, info));
+ mLock.lock();
+ mCbOutputQueue.add(new Pair<>(bufferIndex, info));
+ mCondition.signalAll();
+ mLock.unlock();
}
@Override
@@ -109,51 +117,52 @@
Pair<Integer, MediaCodec.BufferInfo> getInput() throws InterruptedException {
Pair<Integer, MediaCodec.BufferInfo> element = null;
+ mLock.lock();
while (!mSignalledError) {
if (mCbInputQueue.isEmpty()) {
- mLock.lock();
mCondition.await();
- mLock.unlock();
} else {
- element = mCbInputQueue.pop();
+ element = mCbInputQueue.remove(0);
break;
}
}
+ mLock.unlock();
return element;
}
Pair<Integer, MediaCodec.BufferInfo> getOutput() throws InterruptedException {
Pair<Integer, MediaCodec.BufferInfo> element = null;
+ mLock.lock();
while (!mSignalledError) {
if (mCbOutputQueue.isEmpty()) {
- mLock.lock();
mCondition.await();
- mLock.unlock();
} else {
- element = mCbOutputQueue.pop();
+ element = mCbOutputQueue.remove(0);
break;
}
}
+ mLock.unlock();
return element;
}
Pair<Integer, MediaCodec.BufferInfo> getWork() throws InterruptedException {
Pair<Integer, MediaCodec.BufferInfo> element = null;
+ mLock.lock();
while (!mSignalledError) {
if (mCbInputQueue.isEmpty() && mCbOutputQueue.isEmpty()) {
- mLock.lock();
mCondition.await();
- mLock.unlock();
- }
- if (!mCbOutputQueue.isEmpty()) {
- element = mCbOutputQueue.pop();
- break;
- }
- if (!mCbInputQueue.isEmpty()) {
- element = mCbInputQueue.pop();
- break;
+ } else {
+ if (!mCbOutputQueue.isEmpty()) {
+ element = mCbOutputQueue.remove(0);
+ break;
+ }
+ if (!mCbInputQueue.isEmpty()) {
+ element = mCbInputQueue.remove(0);
+ break;
+ }
}
}
+ mLock.unlock();
return element;
}
@@ -168,38 +177,6 @@
MediaFormat getOutputFormat() {
return mOutFormat;
}
-
- private class CallBackQueue {
- private final LinkedList<Pair<Integer, MediaCodec.BufferInfo>> mQueue = new LinkedList<>();
-
- void push(Pair<Integer, MediaCodec.BufferInfo> element) {
- mLock.lock();
- mQueue.add(element);
- mCondition.signalAll();
- mLock.unlock();
- }
-
- Pair<Integer, MediaCodec.BufferInfo> pop() {
- Pair<Integer, MediaCodec.BufferInfo> element = null;
- mLock.lock();
- if (mQueue.size() != 0) element = mQueue.remove(0);
- mLock.unlock();
- return element;
- }
-
- boolean isEmpty() {
- mLock.lock();
- boolean isEmpty = (mQueue.size() == 0);
- mLock.unlock();
- return isEmpty;
- }
-
- void clear() {
- mLock.lock();
- mQueue.clear();
- mLock.unlock();
- }
- }
}
class OutputManager {
@@ -461,8 +438,10 @@
int bufferID = element.first;
MediaCodec.BufferInfo info = element.second;
if (info != null) {
+ // <id, info> corresponds to output callback. Handle it accordingly
dequeueOutput(bufferID, info);
} else {
+ // <id, null> corresponds to input callback. Handle it accordingly
enqueueInput(bufferID);
frameCount++;
}
diff --git a/tests/sensor/src/android/hardware/cts/SensorTest.java b/tests/sensor/src/android/hardware/cts/SensorTest.java
index 80ac77d..5096b3d 100644
--- a/tests/sensor/src/android/hardware/cts/SensorTest.java
+++ b/tests/sensor/src/android/hardware/cts/SensorTest.java
@@ -250,17 +250,11 @@
sensors.get(0).isWakeUpSensor());
}
- private void hasAtLeastOneWakeupSensorOrEmpty(List<Sensor> sensors, String sensorName) {
- if (sensors == null || sensors.isEmpty()) return;
- boolean foundWakeup = false;
- for (Sensor sensor : sensors) {
- if (sensor.isWakeUpSensor()) {
- foundWakeup = true;
- break;
- }
- }
+ private void hasDefaultWakeupSensorOrEmpty(int sensorType, String sensorName) {
+ Sensor sensor = mSensorManager.getDefaultSensor(sensorType);
+ if (sensor == null) return;
- assertTrue("No wake-up " + sensorName + " sensors implemented", foundWakeup);
+ assertTrue("Default " + sensorName + " sensor is not a wake-up sensor", sensor.isWakeUpSensor());
}
// Some sensors like proximity, significant motion etc. are defined as wake-up sensors by
@@ -276,8 +270,8 @@
hasOnlyOneWakeUpSensorOrEmpty(mSensorManager.getSensorList(TYPE_GLANCE_GESTURE));
hasOnlyOneWakeUpSensorOrEmpty(mSensorManager.getSensorList(TYPE_PICK_UP_GESTURE));
- hasAtLeastOneWakeupSensorOrEmpty(mSensorManager.getSensorList(Sensor.TYPE_PROXIMITY), "proximity");
- hasAtLeastOneWakeupSensorOrEmpty(mSensorManager.getSensorList(Sensor.TYPE_HINGE_ANGLE), "hinge");
+ hasDefaultWakeupSensorOrEmpty(Sensor.TYPE_PROXIMITY, "proximity");
+ hasDefaultWakeupSensorOrEmpty(Sensor.TYPE_HINGE_ANGLE, "hinge");
}
public void testGetDefaultSensorWithWakeUpFlag() {
diff --git a/tests/signature/api-check/system-annotation/AndroidTest.xml b/tests/signature/api-check/system-annotation/AndroidTest.xml
index 691516c..816ff81 100644
--- a/tests/signature/api-check/system-annotation/AndroidTest.xml
+++ b/tests/signature/api-check/system-annotation/AndroidTest.xml
@@ -28,7 +28,7 @@
<option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
<option name="class" value="android.signature.cts.api.AnnotationTest" />
<option name="instrumentation-arg" key="expected-api-files" value="system-current.txt,system-removed.txt,car-system-current.txt,car-system-removed.txt" />
- <option name="instrumentation-arg" key="annotation-for-exact-match" value="@android.annotation.SystemApi\(client=PRIVILEGED_APPS,\ process=ALL\)" />
+ <option name="instrumentation-arg" key="annotation-for-exact-match" value="@android.annotation.SystemApi\(client=PRIVILEGED_APPS\)" />
<option name="runtime-hint" value="30s" />
</test>
diff --git a/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java b/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java
index b228c49..0ca1fc9 100644
--- a/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java
+++ b/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java
@@ -18,6 +18,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -122,24 +123,27 @@
private static final long TIME_DIFF_THRESHOLD = 200;
private static final String CHANNEL_ID = "my_channel";
-
+ private Context mContext;
private UiDevice mUiDevice;
private UsageStatsManager mUsageStatsManager;
+ private KeyguardManager mKeyguardManager;
private String mTargetPackage;
private String mCachedUsageSourceSetting;
@Before
public void setUp() throws Exception {
+ mContext = InstrumentationRegistry.getInstrumentation().getContext();
mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
- mUsageStatsManager = (UsageStatsManager) InstrumentationRegistry.getInstrumentation()
- .getContext().getSystemService(Context.USAGE_STATS_SERVICE);
- mTargetPackage = InstrumentationRegistry.getContext().getPackageName();
+ mUsageStatsManager = (UsageStatsManager) mContext.getSystemService(
+ Context.USAGE_STATS_SERVICE);
+ mKeyguardManager = mContext.getSystemService(KeyguardManager.class);
+ mTargetPackage = mContext.getPackageName();
+
assumeTrue("App Standby not enabled on device", AppStandbyUtils.isAppStandbyEnabled());
setAppOpsMode("allow");
mCachedUsageSourceSetting = getUsageSourceSetting();
}
-
@After
public void cleanUp() throws Exception {
if (mCachedUsageSourceSetting != null &&
@@ -158,33 +162,27 @@
}
private void setAppOpsMode(String mode) throws Exception {
- final String command = MessageFormat.format(APPOPS_SET_SHELL_COMMAND,
- InstrumentationRegistry.getContext().getPackageName(), mode);
- mUiDevice.executeShellCommand(command);
+ executeShellCmd(MessageFormat.format(APPOPS_SET_SHELL_COMMAND, mTargetPackage, mode));
}
-
private String getUsageSourceSetting() throws Exception {
- return mUiDevice.executeShellCommand(USAGE_SOURCE_GET_SHELL_COMMAND);
+ return executeShellCmd(USAGE_SOURCE_GET_SHELL_COMMAND);
}
private void setUsageSourceSetting(String usageSource) throws Exception {
if (usageSource.equals("null")) {
- mUiDevice.executeShellCommand(USAGE_SOURCE_DELETE_SHELL_COMMAND);
+ executeShellCmd(USAGE_SOURCE_DELETE_SHELL_COMMAND);
} else {
- final String command = MessageFormat.format(USAGE_SOURCE_SET_SHELL_COMMAND,
- usageSource);
- mUiDevice.executeShellCommand(command);
+ executeShellCmd(MessageFormat.format(USAGE_SOURCE_SET_SHELL_COMMAND, usageSource));
}
mUsageStatsManager.forceUsageSourceSettingRead();
}
private void launchSubActivity(Class<? extends Activity> clazz) {
- final Context context = InstrumentationRegistry.getInstrumentation().getContext();
final Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setClassName(mTargetPackage, clazz.getName());
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- context.startActivity(intent);
+ mContext.startActivity(intent);
mUiDevice.wait(Until.hasObject(By.clazz(clazz)), TIMEOUT);
}
@@ -316,7 +314,7 @@
@Test
public void testStandbyBucketChangeLog() throws Exception {
final long startTime = System.currentTimeMillis();
- mUiDevice.executeShellCommand("am set-standby-bucket " + mTargetPackage + " rare");
+ setStandByBucket(mTargetPackage, "rare");
final long endTime = System.currentTimeMillis();
UsageEvents events = mUsageStatsManager.queryEvents(startTime - 1_000, endTime + 1_000);
@@ -342,7 +340,7 @@
assumeTrue("Skip GetAppStandby test: app standby is disabled.",
AppStandbyUtils.isAppStandbyEnabled());
- mUiDevice.executeShellCommand("am set-standby-bucket " + mTargetPackage + " rare");
+ setStandByBucket(mTargetPackage, "rare");
Map<String, Integer> bucketMap = mUsageStatsManager.getAppStandbyBuckets();
assertTrue("No bucket data returned", bucketMap.size() > 0);
final int bucket = bucketMap.getOrDefault(mTargetPackage, -1);
@@ -365,9 +363,9 @@
setAppOpsMode("ignore"); // To ensure permission is not required
// Time drifts of 2s are expected inside usage stats
final long start = System.currentTimeMillis() - 2_000;
- mUiDevice.executeShellCommand("am set-standby-bucket " + mTargetPackage + " rare");
+ setStandByBucket(mTargetPackage, "rare");
Thread.sleep(100);
- mUiDevice.executeShellCommand("am set-standby-bucket " + mTargetPackage + " working_set");
+ setStandByBucket(mTargetPackage, "working_set");
Thread.sleep(100);
final long end = System.currentTimeMillis() + 2_000;
final UsageEvents events = mUsageStatsManager.queryEventsForSelf(start, end);
@@ -537,20 +535,20 @@
assertTrue(stats.isEmpty());
}
- private void generateAndSendNotification(Context context) throws Exception {
+ private void generateAndSendNotification() throws Exception {
final NotificationManager mNotificationManager =
- (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
+ (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
final NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID, "Channel",
NotificationManager.IMPORTANCE_DEFAULT);
// Configure the notification channel.
mChannel.setDescription("Test channel");
mNotificationManager.createNotificationChannel(mChannel);
final Notification.Builder mBuilder =
- new Notification.Builder(context, CHANNEL_ID)
+ new Notification.Builder(mContext, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_notification)
.setContentTitle("My notification")
.setContentText("Hello World!");
- final PendingIntent pi = PendingIntent.getActivity(context, 1,
+ final PendingIntent pi = PendingIntent.getActivity(mContext, 1,
new Intent(Settings.ACTION_SETTINGS), 0);
mBuilder.setContentIntent(pi);
mNotificationManager.notify(1, mBuilder.build());
@@ -561,15 +559,15 @@
@Test
public void testNotificationSeen() throws Exception {
final long startTime = System.currentTimeMillis();
- final Context context = InstrumentationRegistry.getContext();
// Skip the test for wearable devices and televisions; neither has a notification shade.
assumeFalse("Test cannot run on a watch- notification shade is not shown",
- context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH));
+ mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH));
assumeFalse("Test cannot run on a television- notifications are not shown",
- context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK_ONLY));
+ mContext.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_LEANBACK_ONLY));
- generateAndSendNotification(context);
+ generateAndSendNotification();
long endTime = System.currentTimeMillis();
UsageEvents events = queryEventsAsShell(startTime, endTime);
@@ -606,15 +604,15 @@
@Test
public void testNotificationInterruptionEventsObfuscation() throws Exception {
final long startTime = System.currentTimeMillis();
- final Context context = InstrumentationRegistry.getContext();
// Skip the test for wearable devices and televisions; neither has a notification shade.
assumeFalse("Test cannot run on a watch- notification shade is not shown",
- context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH));
+ mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH));
assumeFalse("Test cannot run on a television- notifications are not shown",
- context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK_ONLY));
+ mContext.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_LEANBACK_ONLY));
- generateAndSendNotification(context);
+ generateAndSendNotification();
final long endTime = System.currentTimeMillis();
final UsageEvents obfuscatedEvents = mUsageStatsManager.queryEvents(startTime, endTime);
@@ -667,7 +665,7 @@
mUsageStatsManager.getAppStandbyBucket(mTargetPackage));
// User force shouldn't have to deal with the timeout.
- mUiDevice.executeShellCommand("am set-standby-bucket " + mTargetPackage + " restricted");
+ setStandByBucket(mTargetPackage, "restricted");
assertEquals("User was unable to force an ACTIVE app down into RESTRICTED bucket",
UsageStatsManager.STANDBY_BUCKET_RESTRICTED,
mUsageStatsManager.getAppStandbyBucket(mTargetPackage));
@@ -678,7 +676,7 @@
@AppModeFull(reason = "Test APK Activity not found when installed as an instant app")
@Test
public void testUserLaunchRemovesFromRestricted() throws IOException {
- mUiDevice.executeShellCommand("am set-standby-bucket " + mTargetPackage + " restricted");
+ setStandByBucket(mTargetPackage, "restricted");
assertEquals("User was unable to force an app into RESTRICTED bucket",
UsageStatsManager.STANDBY_BUCKET_RESTRICTED,
mUsageStatsManager.getAppStandbyBucket(mTargetPackage));
@@ -691,7 +689,7 @@
@Test
public void testIsAppInactive_Charging() throws Exception {
- mUiDevice.executeShellCommand("am set-standby-bucket " + TEST_APP_PKG + " rare");
+ setStandByBucket(TEST_APP_PKG, "rare");
try {
BatteryUtils.runDumpsysBatteryUnplug();
@@ -707,17 +705,17 @@
}
}
- static final int[] INTERACTIVE_EVENTS = new int[] {
+ private static final int[] INTERACTIVE_EVENTS = new int[] {
Event.SCREEN_INTERACTIVE,
Event.SCREEN_NON_INTERACTIVE
};
- static final int[] KEYGUARD_EVENTS = new int[] {
+ private static final int[] KEYGUARD_EVENTS = new int[] {
Event.KEYGUARD_SHOWN,
Event.KEYGUARD_HIDDEN
};
- static final int[] ALL_EVENTS = new int[] {
+ private static final int[] ALL_EVENTS = new int[] {
Event.SCREEN_INTERACTIVE,
Event.SCREEN_NON_INTERACTIVE,
Event.KEYGUARD_SHOWN,
@@ -803,19 +801,9 @@
final AggrEventData nonInteractive = new AggrEventData("Non-interactive");
final AggrEventData keyguardShown = new AggrEventData("Keyguard shown");
final AggrEventData keyguardHidden = new AggrEventData("Keyguard hidden");
- int interactiveCount;
- long interactiveDuration;
- long interactiveLastEventTime;
- int nonInteractiveCount;
- long nonInteractiveDuration;
- long nonInteractiveLastEventTime;
- int keyguardShownCount;
- long keyguardShownDuration;
- int keyguardHiddenCount;
- long keyguardHiddenDuration;
}
- private SparseArray<AggrAllEventsData> getAggrEventData(long beforeTime) {
+ private SparseArray<AggrAllEventsData> getAggrEventData() {
final long endTime = System.currentTimeMillis();
final SparseLongArray intervalLengths = new SparseLongArray();
@@ -954,49 +942,35 @@
@AppModeFull(reason = "No usage events access in instant apps")
@Test
public void testInteractiveEvents() throws Exception {
- final KeyguardManager kmgr = InstrumentationRegistry.getInstrumentation()
- .getContext().getSystemService(KeyguardManager.class);
-
// We need to start out with the screen on.
- if (!mUiDevice.isScreenOn()) {
- pressWakeUp();
- SystemClock.sleep(1000);
- }
-
- // Also want to start out with the keyguard dismissed.
- if (kmgr.isKeyguardLocked()) {
- final long startTime = getEvents(KEYGUARD_EVENTS, 0, null) + 1;
- mUiDevice.executeShellCommand("wm dismiss-keyguard");
- ArrayList<Event> events = waitForEventCount(KEYGUARD_EVENTS, startTime, 1);
- assertEquals(Event.KEYGUARD_HIDDEN, events.get(0).getEventType());
- SystemClock.sleep(500);
- }
+ mUiDevice.wakeUp();
+ dismissKeyguard(); // also want to start out with the keyguard dismissed.
try {
ArrayList<Event> events;
// Determine time to start looking for events.
final long startTime = getEvents(ALL_EVENTS, 0, null) + 1;
- SparseArray<AggrAllEventsData> baseAggr = getAggrEventData(0);
+ SparseArray<AggrAllEventsData> baseAggr = getAggrEventData();
// First test -- put device to sleep and make sure we see this event.
- pressSleep();
+ mUiDevice.sleep();
// Do we have one event, going in to non-interactive mode?
events = waitForEventCount(INTERACTIVE_EVENTS, startTime, 1);
assertEquals(Event.SCREEN_NON_INTERACTIVE, events.get(0).getEventType());
- SparseArray<AggrAllEventsData> offAggr = getAggrEventData(startTime);
+ SparseArray<AggrAllEventsData> offAggr = getAggrEventData();
verifyAggrInteractiveEventData(baseAggr, offAggr, true, false);
// Next test -- turn screen on and make sure we have a second event.
// XXX need to wait a bit so we don't accidentally trigger double-power
// to launch camera. (SHOULD FIX HOW WE WAKEUP / SLEEP TO NOT USE POWER KEY)
SystemClock.sleep(500);
- pressWakeUp();
+ mUiDevice.wakeUp();
events = waitForEventCount(INTERACTIVE_EVENTS, startTime, 2);
assertEquals(Event.SCREEN_NON_INTERACTIVE, events.get(0).getEventType());
assertEquals(Event.SCREEN_INTERACTIVE, events.get(1).getEventType());
- SparseArray<AggrAllEventsData> onAggr = getAggrEventData(startTime);
+ SparseArray<AggrAllEventsData> onAggr = getAggrEventData();
verifyAggrInteractiveEventData(offAggr, onAggr, false, true);
// If the device is doing a lock screen, verify that we are also seeing the
@@ -1005,25 +979,25 @@
// the screen back on (at which point it must be shown).
// XXX CTS seems to be preventing the keyguard from showing, so this path is
// never being tested.
- if (kmgr.isKeyguardLocked()) {
+ if (mKeyguardManager.isKeyguardLocked()) {
events = waitForEventCount(KEYGUARD_EVENTS, startTime, 1);
assertEquals(Event.KEYGUARD_SHOWN, events.get(0).getEventType());
- SparseArray<AggrAllEventsData> shownAggr = getAggrEventData(startTime);
+ SparseArray<AggrAllEventsData> shownAggr = getAggrEventData();
verifyAggrKeyguardEventData(offAggr, shownAggr, true, false);
// Now dismiss the keyguard and verify the resulting events.
- mUiDevice.executeShellCommand("wm dismiss-keyguard");
+ executeShellCmd("wm dismiss-keyguard");
events = waitForEventCount(KEYGUARD_EVENTS, startTime, 2);
assertEquals(Event.KEYGUARD_SHOWN, events.get(0).getEventType());
assertEquals(Event.KEYGUARD_HIDDEN, events.get(1).getEventType());
- SparseArray<AggrAllEventsData> hiddenAggr = getAggrEventData(startTime);
+ SparseArray<AggrAllEventsData> hiddenAggr = getAggrEventData();
verifyAggrKeyguardEventData(shownAggr, hiddenAggr, false, true);
}
} finally {
// Dismiss keyguard to get device back in its normal state.
- pressWakeUp();
- mUiDevice.executeShellCommand("wm dismiss-keyguard");
+ mUiDevice.wakeUp();
+ executeShellCmd("wm dismiss-keyguard");
}
}
@@ -1032,14 +1006,14 @@
final String fakePackageName = "android.fake.package.name";
final int defaultValue = -1;
- mUiDevice.executeShellCommand("am set-standby-bucket " + fakePackageName + " rare");
+ setStandByBucket(fakePackageName, "rare");
// Verify the above does not add a new entry to the App Standby bucket map
Map<String, Integer> bucketMap = mUsageStatsManager.getAppStandbyBuckets();
int bucket = bucketMap.getOrDefault(fakePackageName, defaultValue);
assertFalse("Meaningful bucket value " + bucket + " returned for " + fakePackageName
+ " after set-standby-bucket", bucket > 0);
- mUiDevice.executeShellCommand("am get-standby-bucket " + fakePackageName);
+ executeShellCmd("am get-standby-bucket " + fakePackageName);
// Verify the above does not add a new entry to the App Standby bucket map
bucketMap = mUsageStatsManager.getAppStandbyBuckets();
bucket = bucketMap.getOrDefault(fakePackageName, defaultValue);
@@ -1109,12 +1083,11 @@
// This test start a foreground service then stop it. The event list should have one
// FOREGROUND_SERVICE_START and one FOREGROUND_SERVICE_STOP event.
final long startTime = System.currentTimeMillis();
- final Context context = InstrumentationRegistry.getInstrumentation().getContext();
- context.startService(new Intent(context, TestService.class));
+ mContext.startService(new Intent(mContext, TestService.class));
mUiDevice.wait(Until.hasObject(By.clazz(TestService.class)), TIMEOUT);
final long sleepTime = 500;
SystemClock.sleep(sleepTime);
- context.stopService(new Intent(context, TestService.class));
+ mContext.stopService(new Intent(mContext, TestService.class));
mUiDevice.wait(Until.gone(By.clazz(TestService.class)), TIMEOUT);
final long endTime = System.currentTimeMillis();
UsageEvents events = mUsageStatsManager.queryEvents(startTime, endTime);
@@ -1161,17 +1134,8 @@
@AppModeFull(reason = "No usage events access in instant apps")
@Test
public void testTaskRootEventField() throws Exception {
- final KeyguardManager kmgr = InstrumentationRegistry.getInstrumentation()
- .getContext().getSystemService(KeyguardManager.class);
mUiDevice.wakeUp();
- // Also want to start out with the keyguard dismissed.
- if (kmgr.isKeyguardLocked()) {
- final long startTime = getEvents(KEYGUARD_EVENTS, 0, null) + 1;
- mUiDevice.executeShellCommand("wm dismiss-keyguard");
- ArrayList<Event> events = waitForEventCount(KEYGUARD_EVENTS, startTime, 1);
- assertEquals(Event.KEYGUARD_HIDDEN, events.get(0).getEventType());
- SystemClock.sleep(500);
- }
+ dismissKeyguard(); // also want to start out with the keyguard dismissed.
final long startTime = System.currentTimeMillis();
launchSubActivity(TaskRootActivity.class);
@@ -1195,29 +1159,18 @@
@AppModeFull(reason = "No usage events access in instant apps")
@Test
public void testUsageSourceAttribution() throws Exception {
- final KeyguardManager kmgr = InstrumentationRegistry.getInstrumentation()
- .getContext().getSystemService(KeyguardManager.class);
mUiDevice.wakeUp();
- // Also want to start out with the keyguard dismissed.
- if (kmgr.isKeyguardLocked()) {
- final long startTime = getEvents(KEYGUARD_EVENTS, 0, null) + 1;
- mUiDevice.executeShellCommand("wm dismiss-keyguard");
- ArrayList<Event> events = waitForEventCount(KEYGUARD_EVENTS, startTime, 1);
- assertEquals(Event.KEYGUARD_HIDDEN, events.get(0).getEventType());
- SystemClock.sleep(500);
- }
-
+ dismissKeyguard(); // also want to start out with the keyguard dismissed.
mUiDevice.pressHome();
- setUsageSourceSetting(Integer.toString(mUsageStatsManager.USAGE_SOURCE_CURRENT_ACTIVITY));
+ setUsageSourceSetting(Integer.toString(UsageStatsManager.USAGE_SOURCE_CURRENT_ACTIVITY));
launchSubActivity(TaskRootActivity.class);
// Usage should be attributed to the test app package
assertAppOrTokenUsed(TaskRootActivity.TEST_APP_PKG, true);
mUiDevice.pressHome();
- setUsageSourceSetting(Integer.toString(
- mUsageStatsManager.USAGE_SOURCE_TASK_ROOT_ACTIVITY));
+ setUsageSourceSetting(Integer.toString(UsageStatsManager.USAGE_SOURCE_TASK_ROOT_ACTIVITY));
launchSubActivity(TaskRootActivity.class);
// Usage should be attributed to this package
assertAppOrTokenUsed(mTargetPackage, true);
@@ -1248,13 +1201,12 @@
int stops = 0;
// Only look at events belongs to mTargetPackage.
- ArrayList<UsageEvents.Event> eventList = new ArrayList<>();
while (events.hasNextEvent()) {
final UsageEvents.Event event = new UsageEvents.Event();
assertTrue(events.getNextEvent(event));
// There should be no events with this packages name
- assertFalse("Instant app package name found in usage event list",
- mTargetPackage.equals(event.getPackageName()));
+ assertNotEquals("Instant app package name found in usage event list",
+ mTargetPackage, event.getPackageName());
// Look for the obfuscated instant app string instead
if(UsageEvents.INSTANT_APP_PACKAGE_NAME.equals(event.getPackageName())) {
@@ -1279,28 +1231,17 @@
@AppModeFull(reason = "No usage events access in instant apps")
@Test
public void testSuddenDestroy() throws Exception {
- final Context context = InstrumentationRegistry.getInstrumentation().getContext();
- final KeyguardManager kmgr = InstrumentationRegistry.getInstrumentation()
- .getContext().getSystemService(KeyguardManager.class);
mUiDevice.wakeUp();
- // Also want to start out with the keyguard dismissed.
- if (kmgr.isKeyguardLocked()) {
- final long startTime = getEvents(KEYGUARD_EVENTS, 0, null) + 1;
- mUiDevice.executeShellCommand("wm dismiss-keyguard");
- ArrayList<Event> events = waitForEventCount(KEYGUARD_EVENTS, startTime, 1);
- assertEquals(Event.KEYGUARD_HIDDEN, events.get(0).getEventType());
- SystemClock.sleep(500);
- }
-
+ dismissKeyguard(); // also want to start out with the keyguard dismissed.
mUiDevice.pressHome();
final long startTime = System.currentTimeMillis();
- final ActivityManager mAm = context.getSystemService(ActivityManager.class);
+ final ActivityManager mAm = mContext.getSystemService(ActivityManager.class);
Intent intent = new Intent();
intent.setClassName(TEST_APP_PKG, TEST_APP_CLASS);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- context.startActivity(intent);
+ mContext.startActivity(intent);
mUiDevice.wait(Until.hasObject(By.clazz(TEST_APP_PKG, TEST_APP_CLASS)), TIMEOUT);
SystemClock.sleep(500);
@@ -1352,13 +1293,12 @@
}
private void startAndDestroyActivityWithLocus() {
- final Context context = InstrumentationRegistry.getInstrumentation().getContext();
- final ActivityManager mAm = context.getSystemService(ActivityManager.class);
+ final ActivityManager mAm = mContext.getSystemService(ActivityManager.class);
Intent intent = new Intent();
intent.setClassName(TEST_APP_PKG, TEST_APP_CLASS_LOCUS);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- context.startActivity(intent);
+ mContext.startActivity(intent);
mUiDevice.wait(Until.hasObject(By.clazz(TEST_APP_PKG, TEST_APP_CLASS_LOCUS)), TIMEOUT);
SystemClock.sleep(500);
@@ -1387,22 +1327,13 @@
}
}
- private void pressWakeUp() {
- mUiDevice.pressKeyCode(KeyEvent.KEYCODE_WAKEUP);
- }
-
- private void pressSleep() {
- mUiDevice.pressKeyCode(KeyEvent.KEYCODE_SLEEP);
- }
-
/**
* Assert on an app or token's usage state.
* @param entity name of the app or token
* @param expected expected usage state, true for in use, false for not in use
*/
private void assertAppOrTokenUsed(String entity, boolean expected) throws IOException {
- final String activeUsages =
- mUiDevice.executeShellCommand("dumpsys usagestats apptimelimit actives");
+ final String activeUsages = executeShellCmd("dumpsys usagestats apptimelimit actives");
final String[] actives = activeUsages.split("\n");
boolean found = false;
@@ -1421,6 +1352,24 @@
}
}
+ private void dismissKeyguard() throws Exception {
+ if (mKeyguardManager.isKeyguardLocked()) {
+ final long startTime = getEvents(KEYGUARD_EVENTS, 0, null) + 1;
+ executeShellCmd("wm dismiss-keyguard");
+ final ArrayList<Event> events = waitForEventCount(KEYGUARD_EVENTS, startTime, 1);
+ assertEquals(Event.KEYGUARD_HIDDEN, events.get(0).getEventType());
+ SystemClock.sleep(500);
+ }
+ }
+
+ private void setStandByBucket(String packageName, String bucket) throws IOException {
+ executeShellCmd("am set-standby-bucket " + packageName + " " + bucket);
+ }
+
+ private String executeShellCmd(String command) throws IOException {
+ return mUiDevice.executeShellCommand(command);
+ }
+
private UsageEvents queryEventsAsShell(long start, long end) {
return SystemUtil.runWithShellPermissionIdentity(() ->
mUsageStatsManager.queryEvents(start, end));
diff --git a/tests/tests/display/src/android/display/cts/DisplayTest.java b/tests/tests/display/src/android/display/cts/DisplayTest.java
index d6c1cc4..48dddbd 100644
--- a/tests/tests/display/src/android/display/cts/DisplayTest.java
+++ b/tests/tests/display/src/android/display/cts/DisplayTest.java
@@ -16,6 +16,8 @@
package android.display.cts;
+import static android.view.Display.DEFAULT_DISPLAY;
+
import static org.junit.Assert.*;
import android.app.Activity;
@@ -88,6 +90,7 @@
private UiModeManager mUiModeManager;
private Context mContext;
private ColorSpace[] mSupportedWideGamuts;
+ private Display mDefaultDisplay;
// To test display mode switches.
private TestPresentation mPresentation;
@@ -106,7 +109,8 @@
mDisplayManager = (DisplayManager)mContext.getSystemService(Context.DISPLAY_SERVICE);
mWindowManager = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
mUiModeManager = (UiModeManager)mContext.getSystemService(Context.UI_MODE_SERVICE);
- mSupportedWideGamuts = mContext.getDisplay().getSupportedWideColorGamut();
+ mDefaultDisplay = mDisplayManager.getDisplay(DEFAULT_DISPLAY);
+ mSupportedWideGamuts = mDefaultDisplay.getSupportedWideColorGamut();
}
@After
@@ -171,7 +175,7 @@
boolean hasDefaultDisplay = false;
boolean hasSecondaryDisplay = false;
for (Display display : displays) {
- if (display.getDisplayId() == Display.DEFAULT_DISPLAY) {
+ if (display.getDisplayId() == DEFAULT_DISPLAY) {
hasDefaultDisplay = true;
}
if (isSecondaryDisplay(display)) {
@@ -188,7 +192,7 @@
@Presubmit
@Test
public void testDefaultDisplay() {
- assertEquals(Display.DEFAULT_DISPLAY, mWindowManager.getDefaultDisplay().getDisplayId());
+ assertEquals(DEFAULT_DISPLAY, mWindowManager.getDefaultDisplay().getDisplayId());
}
/**
@@ -196,7 +200,7 @@
*/
@Test
public void testDefaultDisplayHdrCapability() {
- Display display = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY);
+ Display display = mDisplayManager.getDisplay(DEFAULT_DISPLAY);
HdrCapabilities cap = display.getHdrCapabilities();
int[] hdrTypes = cap.getSupportedHdrTypes();
for (int type : hdrTypes) {
@@ -219,7 +223,7 @@
public void testSecondaryDisplay() {
Display display = getSecondaryDisplay(mDisplayManager.getDisplays());
assertNotNull(display);
- assertTrue(Display.DEFAULT_DISPLAY != display.getDisplayId());
+ assertTrue(DEFAULT_DISPLAY != display.getDisplayId());
}
/**
@@ -384,10 +388,9 @@
*/
@Test
public void testGetPreferredWideGamutColorSpace() {
- final Display defaultDisplay = mWindowManager.getDefaultDisplay();
- final ColorSpace colorSpace = defaultDisplay.getPreferredWideGamutColorSpace();
+ final ColorSpace colorSpace = mDefaultDisplay.getPreferredWideGamutColorSpace();
- if (defaultDisplay.isWideColorGamut()) {
+ if (mDefaultDisplay.isWideColorGamut()) {
assertFalse(colorSpace.isSrgb());
assertTrue(colorSpace.isWideGamut());
} else {
@@ -430,7 +433,7 @@
final ColorSpace displayP3 = ColorSpace.get(ColorSpace.Named.DISPLAY_P3);
final ColorSpace dciP3 = ColorSpace.get(ColorSpace.Named.DCI_P3);
final List<ColorSpace> list = Arrays.asList(mSupportedWideGamuts);
- final boolean supportsWideGamut = mContext.getDisplay().isWideColorGamut()
+ final boolean supportsWideGamut = mDefaultDisplay.isWideColorGamut()
&& mSupportedWideGamuts.length > 0;
final boolean supportsP3 = list.contains(displayP3) || list.contains(dciP3);
assertEquals(supportsWideGamut, supportsP3);
diff --git a/tests/tests/dynamic_linker/Android.bp b/tests/tests/dynamic_linker/Android.bp
index 76b6603..ee88e21 100644
--- a/tests/tests/dynamic_linker/Android.bp
+++ b/tests/tests/dynamic_linker/Android.bp
@@ -14,6 +14,7 @@
cc_test_library {
name: "libdynamiclinker_native_lib_a",
+ sdk_version: "current",
srcs: ["native_lib_a.cpp"],
cflags: [
"-Wall",
@@ -27,6 +28,7 @@
cc_test_library {
name: "libdynamiclinker_native_lib_b",
+ sdk_version: "current",
srcs: ["native_lib_b.cpp"],
cflags: [
"-Wall",
diff --git a/tests/tests/graphics/src/android/graphics/cts/VulkanDeqpLevelTest.java b/tests/tests/graphics/src/android/graphics/cts/VulkanDeqpLevelTest.java
index 3f8c011..0374082 100644
--- a/tests/tests/graphics/src/android/graphics/cts/VulkanDeqpLevelTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/VulkanDeqpLevelTest.java
@@ -29,7 +29,6 @@
import com.android.compatibility.common.util.CddTest;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -70,7 +69,6 @@
}
@CddTest(requirement = "7.1.4.2/C-1-8")
- @Ignore("b/149464764: Test disabled until certain targets get the new feature flag.")
@Test
public void testVulkanDeqpLevel() {
if (mVulkanHardwareVersion.version >= VULKAN_1_0) {
diff --git a/tests/tests/hardware/res/raw/asus_gamepad_register.json b/tests/tests/hardware/res/raw/asus_gamepad_register.json
index dd422a4..64cf5e4 100644
--- a/tests/tests/hardware/res/raw/asus_gamepad_register.json
+++ b/tests/tests/hardware/res/raw/asus_gamepad_register.json
@@ -4,6 +4,7 @@
"name": "Asus Gamepad (Test)",
"vid": 0x0b05,
"pid": 0x4500,
+ "bus": "bluetooth",
"descriptor": [0x05, 0x01, 0x09, 0x05, 0xa1, 0x01, 0x85, 0x01, 0x05, 0x09, 0x0a, 0x01, 0x00,
0x0a, 0x02, 0x00, 0x0a, 0x04, 0x00, 0x0a, 0x05, 0x00, 0x0a, 0x07, 0x00, 0x0a, 0x08, 0x00,
0x0a, 0x0e, 0x00, 0x0a, 0x0f, 0x00, 0x0a, 0x0d, 0x00, 0x05, 0x0c, 0x0a, 0x24, 0x02, 0x0a,
diff --git a/tests/tests/hardware/res/raw/microsoft_designer_keyboard_register.json b/tests/tests/hardware/res/raw/microsoft_designer_keyboard_register.json
index a426740..263b14d 100644
--- a/tests/tests/hardware/res/raw/microsoft_designer_keyboard_register.json
+++ b/tests/tests/hardware/res/raw/microsoft_designer_keyboard_register.json
@@ -4,6 +4,7 @@
"name": "Designer Keyboard (Test)",
"vid": 0x045e,
"pid": 0x0806,
+ "bus": "bluetooth",
"descriptor": [
0x06, 0xbc, 0xff, 0x09, 0x88, 0xa1, 0x01, 0x85, 0x22, 0x06, 0x00, 0xff,
0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, 0x95, 0x13, 0x0a, 0x0a, 0xfa,
diff --git a/tests/tests/hardware/res/raw/microsoft_sculpttouch_register.json b/tests/tests/hardware/res/raw/microsoft_sculpttouch_register.json
index a9fd5ab..8ee16b4 100644
--- a/tests/tests/hardware/res/raw/microsoft_sculpttouch_register.json
+++ b/tests/tests/hardware/res/raw/microsoft_sculpttouch_register.json
@@ -4,6 +4,7 @@
"name": "Microsoft Sculpt Touch Mouse (Test)",
"vid": 0x045e,
"pid": 0x077c,
+ "bus": "bluetooth",
"descriptor": [
0x05, 0x01, 0x09, 0x02, 0xa1, 0x01, 0x05, 0x01, 0x09, 0x02, 0xa1, 0x02,
0x85, 0x1a, 0x09, 0x01, 0xa1, 0x00, 0x05, 0x09, 0x19, 0x01, 0x29, 0x05,
diff --git a/tests/tests/hardware/res/raw/microsoft_xboxones_register.json b/tests/tests/hardware/res/raw/microsoft_xboxones_register.json
index c1757e8..d789297 100755
--- a/tests/tests/hardware/res/raw/microsoft_xboxones_register.json
+++ b/tests/tests/hardware/res/raw/microsoft_xboxones_register.json
@@ -1,28 +1,31 @@
{
- "id": 1,
- "command": "register",
- "name": "Xbox One S (Bluetooth Test)",
- "vid": 0x045e,
- "pid": 0x02fd,
- "descriptor": [0x05, 0x01, 0x09, 0x05, 0xa1, 0x01, 0x85, 0x01, 0x09, 0x01, 0xa1, 0x00, 0x09, 0x30,
- 0x09, 0x31, 0x15, 0x00, 0x27, 0xff, 0xff, 0x00, 0x00, 0x95, 0x02, 0x75, 0x10, 0x81, 0x02, 0xc0,
- 0x09, 0x01, 0xa1, 0x00, 0x09, 0x32, 0x09, 0x35, 0x15, 0x00, 0x27, 0xff, 0xff, 0x00, 0x00, 0x95,
- 0x02, 0x75, 0x10, 0x81, 0x02, 0xc0, 0x05, 0x02, 0x09, 0xc5, 0x15, 0x00, 0x26, 0xff, 0x03, 0x95,
- 0x01, 0x75, 0x0a, 0x81, 0x02, 0x15, 0x00, 0x25, 0x00, 0x75, 0x06, 0x95, 0x01, 0x81, 0x03, 0x05,
- 0x02, 0x09, 0xc4, 0x15, 0x00, 0x26, 0xff, 0x03, 0x95, 0x01, 0x75, 0x0a, 0x81, 0x02, 0x15, 0x00,
- 0x25, 0x00, 0x75, 0x06, 0x95, 0x01, 0x81, 0x03, 0x05, 0x01, 0x09, 0x39, 0x15, 0x01, 0x25, 0x08,
- 0x35, 0x00, 0x46, 0x3b, 0x01, 0x66, 0x14, 0x00, 0x75, 0x04, 0x95, 0x01, 0x81, 0x42, 0x75, 0x04,
- 0x95, 0x01, 0x15, 0x00, 0x25, 0x00, 0x35, 0x00, 0x45, 0x00, 0x65, 0x00, 0x81, 0x03, 0x05, 0x09,
- 0x19, 0x01, 0x29, 0x0f, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x0f, 0x81, 0x02, 0x15, 0x00,
- 0x25, 0x00, 0x75, 0x01, 0x95, 0x01, 0x81, 0x03, 0x05, 0x0c, 0x0a, 0x24, 0x02, 0x15, 0x00, 0x25,
- 0x01, 0x95, 0x01, 0x75, 0x01, 0x81, 0x02, 0x15, 0x00, 0x25, 0x00, 0x75, 0x07, 0x95, 0x01, 0x81,
- 0x03, 0x05, 0x0c, 0x09, 0x01, 0x85, 0x02, 0xa1, 0x01, 0x05, 0x0c, 0x0a, 0x23, 0x02, 0x15, 0x00,
- 0x25, 0x01, 0x95, 0x01, 0x75, 0x01, 0x81, 0x02, 0x15, 0x00, 0x25, 0x00, 0x75, 0x07, 0x95, 0x01,
- 0x81, 0x03, 0xc0, 0x05, 0x0f, 0x09, 0x21, 0x85, 0x03, 0xa1, 0x02, 0x09, 0x97, 0x15, 0x00, 0x25,
- 0x01, 0x75, 0x04, 0x95, 0x01, 0x91, 0x02, 0x15, 0x00, 0x25, 0x00, 0x75, 0x04, 0x95, 0x01, 0x91,
- 0x03, 0x09, 0x70, 0x15, 0x00, 0x25, 0x64, 0x75, 0x08, 0x95, 0x04, 0x91, 0x02, 0x09, 0x50, 0x66,
- 0x01, 0x10, 0x55, 0x0e, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, 0x95, 0x01, 0x91, 0x02, 0x09,
- 0xa7, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, 0x95, 0x01, 0x91, 0x02, 0x65, 0x00, 0x55, 0x00,
- 0x09, 0x7c, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, 0x95, 0x01, 0x91, 0x02, 0xc0, 0x05, 0x06,
- 0x09, 0x20, 0x85, 0x04, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, 0x95, 0x01, 0x81, 0x02, 0xc0]
- }
+ "id": 1,
+ "command": "register",
+ "name": "Xbox One S (Bluetooth Test)",
+ "vid": 0x045e,
+ "pid": 0x02fd,
+ "bus": "bluetooth",
+ "descriptor": [
+ 0x05, 0x01, 0x09, 0x05, 0xa1, 0x01, 0x85, 0x01, 0x09, 0x01, 0xa1, 0x00, 0x09, 0x30,
+ 0x09, 0x31, 0x15, 0x00, 0x27, 0xff, 0xff, 0x00, 0x00, 0x95, 0x02, 0x75, 0x10, 0x81, 0x02, 0xc0,
+ 0x09, 0x01, 0xa1, 0x00, 0x09, 0x32, 0x09, 0x35, 0x15, 0x00, 0x27, 0xff, 0xff, 0x00, 0x00, 0x95,
+ 0x02, 0x75, 0x10, 0x81, 0x02, 0xc0, 0x05, 0x02, 0x09, 0xc5, 0x15, 0x00, 0x26, 0xff, 0x03, 0x95,
+ 0x01, 0x75, 0x0a, 0x81, 0x02, 0x15, 0x00, 0x25, 0x00, 0x75, 0x06, 0x95, 0x01, 0x81, 0x03, 0x05,
+ 0x02, 0x09, 0xc4, 0x15, 0x00, 0x26, 0xff, 0x03, 0x95, 0x01, 0x75, 0x0a, 0x81, 0x02, 0x15, 0x00,
+ 0x25, 0x00, 0x75, 0x06, 0x95, 0x01, 0x81, 0x03, 0x05, 0x01, 0x09, 0x39, 0x15, 0x01, 0x25, 0x08,
+ 0x35, 0x00, 0x46, 0x3b, 0x01, 0x66, 0x14, 0x00, 0x75, 0x04, 0x95, 0x01, 0x81, 0x42, 0x75, 0x04,
+ 0x95, 0x01, 0x15, 0x00, 0x25, 0x00, 0x35, 0x00, 0x45, 0x00, 0x65, 0x00, 0x81, 0x03, 0x05, 0x09,
+ 0x19, 0x01, 0x29, 0x0f, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x0f, 0x81, 0x02, 0x15, 0x00,
+ 0x25, 0x00, 0x75, 0x01, 0x95, 0x01, 0x81, 0x03, 0x05, 0x0c, 0x0a, 0x24, 0x02, 0x15, 0x00, 0x25,
+ 0x01, 0x95, 0x01, 0x75, 0x01, 0x81, 0x02, 0x15, 0x00, 0x25, 0x00, 0x75, 0x07, 0x95, 0x01, 0x81,
+ 0x03, 0x05, 0x0c, 0x09, 0x01, 0x85, 0x02, 0xa1, 0x01, 0x05, 0x0c, 0x0a, 0x23, 0x02, 0x15, 0x00,
+ 0x25, 0x01, 0x95, 0x01, 0x75, 0x01, 0x81, 0x02, 0x15, 0x00, 0x25, 0x00, 0x75, 0x07, 0x95, 0x01,
+ 0x81, 0x03, 0xc0, 0x05, 0x0f, 0x09, 0x21, 0x85, 0x03, 0xa1, 0x02, 0x09, 0x97, 0x15, 0x00, 0x25,
+ 0x01, 0x75, 0x04, 0x95, 0x01, 0x91, 0x02, 0x15, 0x00, 0x25, 0x00, 0x75, 0x04, 0x95, 0x01, 0x91,
+ 0x03, 0x09, 0x70, 0x15, 0x00, 0x25, 0x64, 0x75, 0x08, 0x95, 0x04, 0x91, 0x02, 0x09, 0x50, 0x66,
+ 0x01, 0x10, 0x55, 0x0e, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, 0x95, 0x01, 0x91, 0x02, 0x09,
+ 0xa7, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, 0x95, 0x01, 0x91, 0x02, 0x65, 0x00, 0x55, 0x00,
+ 0x09, 0x7c, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, 0x95, 0x01, 0x91, 0x02, 0xc0, 0x05, 0x06,
+ 0x09, 0x20, 0x85, 0x04, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, 0x95, 0x01, 0x81, 0x02, 0xc0
+ ]
+}
diff --git a/tests/tests/hardware/res/raw/razer_serval_register.json b/tests/tests/hardware/res/raw/razer_serval_register.json
index 3d8bb96..ab27177 100644
--- a/tests/tests/hardware/res/raw/razer_serval_register.json
+++ b/tests/tests/hardware/res/raw/razer_serval_register.json
@@ -4,6 +4,7 @@
"name": "Razer Serval (Test)",
"vid": 0x1532,
"pid": 0x0900,
+ "bus": "bluetooth",
"descriptor": [
0x05, 0x01, 0x09, 0x05, 0xa1, 0x01, 0xa1, 0x02, 0x85, 0x01, 0x75, 0x08, 0x95, 0x04,
0x15, 0x00, 0x26, 0xff, 0x00, 0x09, 0x30, 0x09, 0x31, 0x09, 0x32, 0x09, 0x35, 0x81,
diff --git a/tests/tests/hardware/res/raw/sony_dualshock3_usb_keyeventtests.json b/tests/tests/hardware/res/raw/sony_dualshock3_usb_keyeventtests.json
new file mode 100644
index 0000000..fd152c2
--- /dev/null
+++ b/tests/tests/hardware/res/raw/sony_dualshock3_usb_keyeventtests.json
@@ -0,0 +1,325 @@
+[
+ {
+ "name": "Press BUTTON_A",
+ "reports": [
+ [0x01, 0x00, 0x00, 0x40, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb],
+ [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb]
+ ],
+ "source": "KEYBOARD | GAMEPAD",
+ "events": [
+ {"action": "DOWN", "keycode": "BUTTON_A"},
+ {"action": "UP", "keycode": "BUTTON_A"}
+ ]
+ },
+
+ {
+ "name": "Press BUTTON_B",
+ "reports": [
+ [0x01, 0x00, 0x00, 0x20, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb],
+ [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb]
+ ],
+ "source": "KEYBOARD | GAMEPAD",
+ "events": [
+ {"action": "DOWN", "keycode": "BUTTON_B"},
+ {"action": "UP", "keycode": "BUTTON_B"}
+ ]
+ },
+
+ {
+ "name": "Press BUTTON_X",
+ "reports": [
+ [0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb],
+ [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb]
+ ],
+ "source": "KEYBOARD | GAMEPAD",
+ "events": [
+ {"action": "DOWN", "keycode": "BUTTON_X"},
+ {"action": "UP", "keycode": "BUTTON_X"}
+ ]
+ },
+
+ {
+ "name": "Press BUTTON_Y",
+ "reports": [
+ [0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb],
+ [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb]
+ ],
+ "source": "KEYBOARD | GAMEPAD",
+ "events": [
+ {"action": "DOWN", "keycode": "BUTTON_Y"},
+ {"action": "UP", "keycode": "BUTTON_Y"}
+ ]
+ },
+
+ {
+ "name": "Press BUTTON_L1",
+ "reports": [
+ [0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb],
+ [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb]
+ ],
+ "source": "KEYBOARD | GAMEPAD",
+ "events": [
+ {"action": "DOWN", "keycode": "BUTTON_L1"},
+ {"action": "UP", "keycode": "BUTTON_L1"}
+ ]
+ },
+
+ {
+ "name": "Press BUTTON_R1",
+ "reports": [
+ [0x01, 0x00, 0x00, 0x08, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb],
+ [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb]
+ ],
+ "source": "KEYBOARD | GAMEPAD",
+ "events": [
+ {"action": "DOWN", "keycode": "BUTTON_R1"},
+ {"action": "UP", "keycode": "BUTTON_R1"}
+ ]
+ },
+
+ {
+ "name": "Press BUTTON_L2",
+ "reports": [
+ [0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb],
+ [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb]
+ ],
+ "source": "KEYBOARD | GAMEPAD",
+ "events": [
+ {"action": "DOWN", "keycode": "BUTTON_L2"},
+ {"action": "UP", "keycode": "BUTTON_L2"}
+ ]
+ },
+
+ {
+ "name": "Press BUTTON_R2",
+ "reports": [
+ [0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb],
+ [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb]
+ ],
+ "source": "KEYBOARD | GAMEPAD",
+ "events": [
+ {"action": "DOWN", "keycode": "BUTTON_R2"},
+ {"action": "UP", "keycode": "BUTTON_R2"}
+ ]
+ },
+
+ {
+ "name": "Press BUTTON_L3",
+ "reports": [
+ [0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb],
+ [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb]
+ ],
+ "source": "KEYBOARD | GAMEPAD",
+ "events": [
+ {"action": "DOWN", "keycode": "BUTTON_THUMBL"},
+ {"action": "UP", "keycode": "BUTTON_THUMBL"}
+ ]
+ },
+
+ {
+ "name": "Press BUTTON_R3",
+ "reports": [
+ [0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb],
+ [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb]
+ ],
+ "source": "KEYBOARD | GAMEPAD",
+ "events": [
+ {"action": "DOWN", "keycode": "BUTTON_THUMBR"},
+ {"action": "UP", "keycode": "BUTTON_THUMBR"}
+ ]
+ },
+
+ {
+ "name": "Press BUTTON_SELECT",
+ "reports": [
+ [0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb],
+ [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb]
+ ],
+ "source": "KEYBOARD | GAMEPAD",
+ "events": [
+ {"action": "DOWN", "keycode": "BUTTON_SELECT"},
+ {"action": "UP", "keycode": "BUTTON_SELECT"}
+ ]
+ },
+
+ {
+ "name": "Press BUTTON_START",
+ "reports": [
+ [0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb],
+ [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb]
+ ],
+ "source": "KEYBOARD | GAMEPAD",
+ "events": [
+ {"action": "DOWN", "keycode": "BUTTON_START"},
+ {"action": "UP", "keycode": "BUTTON_START"}
+ ]
+ },
+
+ {
+ "name": "Press BUTTON_PS",
+ "reports": [
+ [0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb],
+ [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb]
+ ],
+ "source": "KEYBOARD | GAMEPAD",
+ "events": [
+ {"action": "DOWN", "keycode": "BUTTON_MODE"},
+ {"action": "UP", "keycode": "BUTTON_MODE"}
+ ]
+ },
+
+ {
+ "name": "Press left DPAD key",
+ "reports": [
+ [0x01, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb],
+ [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb]
+ ],
+ "source": "KEYBOARD | GAMEPAD",
+ "events": [
+ {"action": "DOWN", "keycode": "KEYCODE_DPAD_LEFT"},
+ {"action": "UP", "keycode": "KEYCODE_DPAD_LEFT"}
+ ]
+ },
+
+ {
+ "name": "Press right DPAD key",
+ "reports": [
+ [0x01, 0x00, 0x20, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb],
+ [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb]
+ ],
+ "source": "KEYBOARD | GAMEPAD",
+ "events": [
+ {"action": "DOWN", "keycode": "KEYCODE_DPAD_RIGHT"},
+ {"action": "UP", "keycode": "KEYCODE_DPAD_RIGHT"}
+ ]
+ },
+
+ {
+ "name": "Press up DPAD key",
+ "reports": [
+ [0x01, 0x00, 0x10, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb],
+ [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb]
+ ],
+ "source": "KEYBOARD | GAMEPAD",
+ "events": [
+ {"action": "DOWN", "keycode": "KEYCODE_DPAD_UP"},
+ {"action": "UP", "keycode": "KEYCODE_DPAD_UP"}
+ ]
+ },
+
+ {
+ "name": "Press down DPAD key",
+ "reports": [
+ [0x01, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb],
+ [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb]
+ ],
+ "source": "KEYBOARD | GAMEPAD",
+ "events": [
+ {"action": "DOWN", "keycode": "KEYCODE_DPAD_DOWN"},
+ {"action": "UP", "keycode": "KEYCODE_DPAD_DOWN"}
+ ]
+ }
+]
+
diff --git a/tests/tests/hardware/res/raw/sony_dualshock3_usb_motioneventtests.json b/tests/tests/hardware/res/raw/sony_dualshock3_usb_motioneventtests.json
new file mode 100644
index 0000000..bae0f94
--- /dev/null
+++ b/tests/tests/hardware/res/raw/sony_dualshock3_usb_motioneventtests.json
@@ -0,0 +1,257 @@
+[
+ {
+ "name": "Sanity check - should not produce any events",
+ "reports": [
+ [0x11, 0xc0, 0x00, 0x80, 0x80, 0x80, 0x80, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c,
+ 0x2e, 0x80, 0xf2]
+ ],
+ "source": "JOYSTICK",
+ "events": [
+ ]
+ },
+
+ {
+ "name": "Left stick - press left",
+ "reports": [
+ [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb],
+ [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb],
+ [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb]
+ ],
+ "source": "JOYSTICK",
+ "events": [
+ {"action": "MOVE", "axes": {"AXIS_X": -0.5}},
+ {"action": "MOVE", "axes": {"AXIS_X": -1}},
+ {"action": "MOVE", "axes": {"AXIS_X": 0}}
+ ]
+ },
+
+ {
+ "name": "Left stick - press right",
+ "reports": [
+ [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb],
+ [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb],
+ [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb]
+ ],
+ "source": "JOYSTICK",
+ "events": [
+ {"action": "MOVE", "axes": {"AXIS_X": 0.51}},
+ {"action": "MOVE", "axes": {"AXIS_X": 1}},
+ {"action": "MOVE", "axes": {"AXIS_X": 0}}
+ ]
+ },
+
+ {
+ "name": "Left stick - press up",
+ "reports": [
+ [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb],
+ [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb],
+ [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb]
+ ],
+ "source": "JOYSTICK",
+ "events": [
+ {"action": "MOVE", "axes": {"AXIS_Y": -0.5}},
+ {"action": "MOVE", "axes": {"AXIS_Y": -1}},
+ {"action": "MOVE", "axes": {"AXIS_Y": 0}}
+ ]
+ },
+
+ {
+ "name": "Left stick - press down",
+ "reports": [
+ [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb],
+ [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb],
+ [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb]
+ ],
+ "source": "JOYSTICK",
+ "events": [
+ {"action": "MOVE", "axes": {"AXIS_Y": 0.51}},
+ {"action": "MOVE", "axes": {"AXIS_Y": 1}},
+ {"action": "MOVE", "axes": {"AXIS_Y": 0}}
+ ]
+ },
+
+ {
+ "name": "Right stick - press left",
+ "reports": [
+ [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb],
+ [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb],
+ [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb]
+ ],
+ "source": "JOYSTICK",
+ "events": [
+ {"action": "MOVE", "axes": {"AXIS_Z": -0.5}},
+ {"action": "MOVE", "axes": {"AXIS_Z": -1}},
+ {"action": "MOVE", "axes": {"AXIS_Z": 0}}
+ ]
+ },
+
+ {
+ "name": "Right stick - press right",
+ "reports": [
+ [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb],
+ [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb],
+ [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb]
+ ],
+ "source": "JOYSTICK",
+ "events": [
+ {"action": "MOVE", "axes": {"AXIS_Z": 0.51}},
+ {"action": "MOVE", "axes": {"AXIS_Z": 1}},
+ {"action": "MOVE", "axes": {"AXIS_Z": 0}}
+ ]
+ },
+
+ {
+ "name": "Right stick - press up",
+ "reports": [
+ [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb],
+ [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb],
+ [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb]
+ ],
+ "source": "JOYSTICK",
+ "events": [
+ {"action": "MOVE", "axes": {"AXIS_RZ": -0.5}},
+ {"action": "MOVE", "axes": {"AXIS_RZ": -1}},
+ {"action": "MOVE", "axes": {"AXIS_RZ": 0}}
+ ]
+ },
+
+ {
+ "name": "Right stick - press down",
+ "reports": [
+ [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb],
+ [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb],
+ [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb]
+ ],
+ "source": "JOYSTICK",
+ "events": [
+ {"action": "MOVE", "axes": {"AXIS_RZ": 0.51}},
+ {"action": "MOVE", "axes": {"AXIS_RZ": 1}},
+ {"action": "MOVE", "axes": {"AXIS_RZ": 0}}
+ ]
+ },
+
+ {
+ "name": "Left trigger - quick press",
+ "reports": [
+ [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb],
+ [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb],
+ [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb]
+ ],
+ "source": "JOYSTICK",
+ "events": [
+ {"action": "MOVE", "axes": {"AXIS_LTRIGGER": 0.5, "AXIS_BRAKE": 0.5}},
+ {"action": "MOVE", "axes": {"AXIS_LTRIGGER": 1.0, "AXIS_BRAKE": 1.0}},
+ {"action": "MOVE", "axes": {"AXIS_LTRIGGER": 0, "AXIS_BRAKE": 0}}
+ ]
+ },
+
+ {
+ "name": "Right trigger - quick press",
+ "reports": [
+ [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb],
+ [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb],
+ [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xee, 0x12, 0x00, 0x00, 0x00, 0x00, 0x12, 0xd6, 0x77, 0x00, 0x40, 0x01, 0xfa, 0x02, 0x62,
+ 0x02, 0x33, 0x01, 0xeb]
+ ],
+ "source": "JOYSTICK",
+ "events": [
+ {"action": "MOVE", "axes": {"AXIS_RTRIGGER": 0.5, "AXIS_GAS": 0.5}},
+ {"action": "MOVE", "axes": {"AXIS_RTRIGGER": 1.0, "AXIS_GAS": 1.0}},
+ {"action": "MOVE", "axes": {"AXIS_RTRIGGER": 0, "AXIS_GAS": 0}}
+ ]
+ }
+]
+
diff --git a/tests/tests/hardware/res/raw/sony_dualshock3_usb_register.json b/tests/tests/hardware/res/raw/sony_dualshock3_usb_register.json
new file mode 100644
index 0000000..3d22120
--- /dev/null
+++ b/tests/tests/hardware/res/raw/sony_dualshock3_usb_register.json
@@ -0,0 +1,30 @@
+{
+ "id": 1,
+ "command": "register",
+ "name": "Sony DS3 (model CECHZC2U)(USB Test)",
+ "vid": 0x054c,
+ "pid": 0x0268,
+ "bus": "usb",
+ "descriptor": [0x05, 0x01, 0x09, 0x04, 0xa1, 0x01, 0xa1, 0x02, 0x85, 0x01, 0x75, 0x08, 0x95, 0x01,
+ 0x15, 0x00, 0x26, 0xff, 0x00, 0x81, 0x03, 0x75, 0x01, 0x95, 0x13, 0x15, 0x00, 0x25, 0x01, 0x35,
+ 0x00, 0x45, 0x01, 0x05, 0x09, 0x19, 0x01, 0x29, 0x13, 0x81, 0x02, 0x75, 0x01, 0x95, 0x0d, 0x06,
+ 0x00, 0xff, 0x81, 0x03, 0x15, 0x00, 0x26, 0xff, 0x00, 0x05, 0x01, 0x09, 0x01, 0xa1, 0x00, 0x75,
+ 0x08, 0x95, 0x04, 0x35, 0x00, 0x46, 0xff, 0x00, 0x09, 0x30, 0x09, 0x31, 0x09, 0x32, 0x09, 0x35,
+ 0x81, 0x02, 0xc0, 0x05, 0x01, 0x75, 0x08, 0x95, 0x27, 0x09, 0x01, 0x81, 0x02, 0x75, 0x08, 0x95,
+ 0x30, 0x09, 0x01, 0x91, 0x02, 0x75, 0x08, 0x95, 0x30, 0x09, 0x01, 0xb1, 0x02, 0xc0, 0xa1, 0x02,
+ 0x85, 0x02, 0x75, 0x08, 0x95, 0x30, 0x09, 0x01, 0xb1, 0x02, 0xc0, 0xa1, 0x02, 0x85, 0xee, 0x75,
+ 0x08, 0x95, 0x30, 0x09, 0x01, 0xb1, 0x02, 0xc0, 0xa1, 0x02, 0x85, 0xef, 0x75, 0x08, 0x95, 0x30,
+ 0x09, 0x01, 0xb1, 0x02, 0xc0, 0xc0],
+ "feature_reports": [
+ {
+ "id": 0xf2,
+ "data": [0xf2, 0xff, 0xff, 0x00, 0x08, 0xa9, 0x5a, 0x15, 0x4a, 0xfe, 0x00, 0x03, 0x50, 0x81,
+ 0xd8, 0x01, 0x8a]
+ },
+ {
+ "id": 0xf5,
+ "data": [0x01, 0x00, 0xc8, 0xbc, 0xc8, 0xcf, 0x6f, 0xb8]
+ }
+ ]
+}
+
diff --git a/tests/tests/hardware/res/raw/sony_dualshock4_keyeventtests.json b/tests/tests/hardware/res/raw/sony_dualshock4_bluetooth_keyeventtests.json
similarity index 100%
rename from tests/tests/hardware/res/raw/sony_dualshock4_keyeventtests.json
rename to tests/tests/hardware/res/raw/sony_dualshock4_bluetooth_keyeventtests.json
diff --git a/tests/tests/hardware/res/raw/sony_dualshock4_motioneventtests.json b/tests/tests/hardware/res/raw/sony_dualshock4_bluetooth_motioneventtests.json
similarity index 100%
rename from tests/tests/hardware/res/raw/sony_dualshock4_motioneventtests.json
rename to tests/tests/hardware/res/raw/sony_dualshock4_bluetooth_motioneventtests.json
diff --git a/tests/tests/hardware/res/raw/sony_dualshock4_bluetooth_register.json b/tests/tests/hardware/res/raw/sony_dualshock4_bluetooth_register.json
new file mode 100644
index 0000000..4c49453
--- /dev/null
+++ b/tests/tests/hardware/res/raw/sony_dualshock4_bluetooth_register.json
@@ -0,0 +1,46 @@
+{
+ "id": 1,
+ "command": "register",
+ "name": "Sony DS4 (model CUH-ZCT1U)(Bluetooth Test)",
+ "vid": 0x054c,
+ "pid": 0x05c4,
+ "bus": "bluetooth",
+ "descriptor": [0x05, 0x01, 0x09, 0x05, 0xa1, 0x01, 0x85, 0x01, 0x09, 0x30, 0x09, 0x31, 0x09, 0x32,
+ 0x09, 0x35, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, 0x95, 0x04, 0x81, 0x02, 0x09, 0x39, 0x15,
+ 0x00, 0x25, 0x07, 0x75, 0x04, 0x95, 0x01, 0x81, 0x42, 0x05, 0x09, 0x19, 0x01, 0x29, 0x0e, 0x15,
+ 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x0e, 0x81, 0x02, 0x75, 0x06, 0x95, 0x01, 0x81, 0x01, 0x05,
+ 0x01, 0x09, 0x33, 0x09, 0x34, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, 0x95, 0x02, 0x81, 0x02,
+ 0x06, 0x04, 0xff, 0x85, 0x02, 0x09, 0x24, 0x95, 0x24, 0xb1, 0x02, 0x85, 0xa3, 0x09, 0x25, 0x95,
+ 0x30, 0xb1, 0x02, 0x85, 0x05, 0x09, 0x26, 0x95, 0x28, 0xb1, 0x02, 0x85, 0x06, 0x09, 0x27, 0x95,
+ 0x34, 0xb1, 0x02, 0x85, 0x07, 0x09, 0x28, 0x95, 0x30, 0xb1, 0x02, 0x85, 0x08, 0x09, 0x29, 0x95,
+ 0x2f, 0xb1, 0x02, 0x06, 0x03, 0xff, 0x85, 0x03, 0x09, 0x21, 0x95, 0x26, 0xb1, 0x02, 0x85, 0x04,
+ 0x09, 0x22, 0x95, 0x2e, 0xb1, 0x02, 0x85, 0xf0, 0x09, 0x47, 0x95, 0x3f, 0xb1, 0x02, 0x85, 0xf1,
+ 0x09, 0x48, 0x95, 0x3f, 0xb1, 0x02, 0x85, 0xf2, 0x09, 0x49, 0x95, 0x0f, 0xb1, 0x02, 0x06, 0x00,
+ 0xff, 0x85, 0x11, 0x09, 0x20, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, 0x95, 0x4d, 0x81, 0x02,
+ 0x09, 0x21, 0x91, 0x02, 0x85, 0x12, 0x09, 0x22, 0x95, 0x8d, 0x81, 0x02, 0x09, 0x23, 0x91, 0x02,
+ 0x85, 0x13, 0x09, 0x24, 0x95, 0xcd, 0x81, 0x02, 0x09, 0x25, 0x91, 0x02, 0x85, 0x14, 0x09, 0x26,
+ 0x96, 0x0d, 0x01, 0x81, 0x02, 0x09, 0x27, 0x91, 0x02, 0x85, 0x15, 0x09, 0x28, 0x96, 0x4d, 0x01,
+ 0x81, 0x02, 0x09, 0x29, 0x91, 0x02, 0x85, 0x16, 0x09, 0x2a, 0x96, 0x8d, 0x01, 0x81, 0x02, 0x09,
+ 0x2b, 0x91, 0x02, 0x85, 0x17, 0x09, 0x2c, 0x96, 0xcd, 0x01, 0x81, 0x02, 0x09, 0x2d, 0x91, 0x02,
+ 0x85, 0x18, 0x09, 0x2e, 0x96, 0x0d, 0x02, 0x81, 0x02, 0x09, 0x2f, 0x91, 0x02, 0x85, 0x19, 0x09,
+ 0x30, 0x96, 0x22, 0x02, 0x81, 0x02, 0x09, 0x31, 0x91, 0x02, 0x06, 0x80, 0xff, 0x85, 0x82, 0x09,
+ 0x22, 0x95, 0x3f, 0xb1, 0x02, 0x85, 0x83, 0x09, 0x23, 0xb1, 0x02, 0x85, 0x84, 0x09, 0x24, 0xb1,
+ 0x02, 0x85, 0x90, 0x09, 0x30, 0xb1, 0x02, 0x85, 0x91, 0x09, 0x31, 0xb1, 0x02, 0x85, 0x92, 0x09,
+ 0x32, 0xb1, 0x02, 0x85, 0x93, 0x09, 0x33, 0xb1, 0x02, 0x85, 0xa0, 0x09, 0x40, 0xb1, 0x02, 0x85,
+ 0xa4, 0x09, 0x44, 0xb1, 0x02, 0xc0],
+ "feature_reports": [
+ {
+ "id": 0x05,
+ "data": [0x05, 0x1e, 0x00, 0x05, 0x00, 0xe2, 0xff, 0xf2, 0x22, 0xbe, 0x22, 0x8d, 0x22, 0x4f,
+ 0xdd, 0x4d, 0xdd, 0x39, 0xdd, 0x1c, 0x02, 0x1c, 0x02, 0xe3, 0x1f, 0x8b, 0xdf, 0x8c, 0x1e,
+ 0xb4, 0xde, 0x30, 0x20, 0x71, 0xe0, 0x10, 0x00, 0xca, 0xfc, 0x64, 0x4d]
+ },
+ {
+ "id": 0xa3,
+ "data": [0xa3, 0x41, 0x70, 0x72, 0x20, 0x20, 0x38, 0x20, 0x32, 0x30, 0x31, 0x34, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x30, 0x39, 0x3a, 0x34, 0x36, 0x3a, 0x30, 0x36, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x43, 0x03, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05,
+ 0x00, 0x00, 0x80, 0x03, 0x00]
+ }
+ ]
+}
diff --git a/tests/tests/hardware/res/raw/sony_dualshock4_usb_keyeventtests.json b/tests/tests/hardware/res/raw/sony_dualshock4_usb_keyeventtests.json
new file mode 100644
index 0000000..17ab0c9
--- /dev/null
+++ b/tests/tests/hardware/res/raw/sony_dualshock4_usb_keyeventtests.json
@@ -0,0 +1,275 @@
+[
+ {
+ "name": "Press BUTTON_A",
+ "reports": [
+ [0x01, 0x80, 0x80, 0x80, 0x80, 0x28, 0x00, 0x8c, 0x00, 0x00, 0xfb, 0x8c, 0x10, 0x0e, 0x00,
+ 0x06, 0x00, 0xe6, 0xff, 0x09, 0x00, 0x87, 0x1d, 0x61, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00],
+ [0x01, 0x80, 0x80, 0x80, 0x80, 0x08, 0x00, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00]
+ ],
+ "source": "KEYBOARD | GAMEPAD",
+ "events": [
+ {"action": "DOWN", "keycode": "BUTTON_A"},
+ {"action": "UP", "keycode": "BUTTON_A"}
+ ]
+ },
+
+ {
+ "name": "Press BUTTON_B",
+ "reports": [
+ [0x01, 0x80, 0x80, 0x80, 0x80, 0x48, 0x00, 0x5c, 0x00, 0x00, 0xf0, 0xd8, 0x12, 0x0f, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0x68, 0x00, 0xf8, 0x1d, 0xc4, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00],
+ [0x01, 0x80, 0x80, 0x80, 0x80, 0x08, 0x00, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00]
+ ],
+ "source": "KEYBOARD | GAMEPAD",
+ "events": [
+ {"action": "DOWN", "keycode": "BUTTON_B"},
+ {"action": "UP", "keycode": "BUTTON_B"}
+ ]
+ },
+
+ {
+ "name": "Press BUTTON_X",
+ "reports": [
+ [0x01, 0x80, 0x80, 0x80, 0x80, 0x18, 0x00, 0x68, 0x00, 0x00, 0xfe, 0x2f, 0x12, 0x0f, 0x00,
+ 0x04, 0x00, 0xe5, 0xff, 0x36, 0x00, 0xd3, 0x1d, 0xdb, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00],
+ [0x01, 0x80, 0x80, 0x80, 0x80, 0x08, 0x00, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00]
+ ],
+ "source": "KEYBOARD | GAMEPAD",
+ "events": [
+ {"action": "DOWN", "keycode": "BUTTON_X"},
+ {"action": "UP", "keycode": "BUTTON_X"}
+ ]
+ },
+
+ {
+ "name": "Press BUTTON_Y",
+ "reports": [
+ [0x01, 0x80, 0x80, 0x80, 0x80, 0x88, 0x00, 0x58, 0x00, 0x00, 0x1f, 0x91, 0x12, 0x0e, 0x00,
+ 0x06, 0x00, 0xe4, 0xff, 0x41, 0x00, 0x30, 0x1e, 0xed, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0x37, 0x81, 0x3e, 0x07, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00],
+ [0x01, 0x80, 0x80, 0x80, 0x80, 0x08, 0x00, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00]
+ ],
+ "source": "KEYBOARD | GAMEPAD",
+ "events": [
+ {"action": "DOWN", "keycode": "BUTTON_Y"},
+ {"action": "UP", "keycode": "BUTTON_Y"}
+ ]
+ },
+
+ {
+ "name": "Press BUTTON_L1",
+ "reports": [
+ [0x01, 0x80, 0x80, 0x80, 0x80, 0x08, 0x01, 0xf0, 0x00, 0x00, 0xe9, 0x57, 0x12, 0x14, 0x00,
+ 0xf0, 0xff, 0xf3, 0xff, 0xbc, 0xfb, 0x58, 0x1d, 0xc4, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0x37, 0x81, 0x3e, 0x07, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00],
+ [0x01, 0x80, 0x80, 0x80, 0x80, 0x08, 0x00, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00]
+ ],
+ "source": "KEYBOARD | GAMEPAD",
+ "events": [
+ {"action": "DOWN", "keycode": "BUTTON_L1"},
+ {"action": "UP", "keycode": "BUTTON_L1"}
+ ]
+ },
+
+ {
+ "name": "Press BUTTON_R1",
+ "reports": [
+ [0x01, 0x80, 0x80, 0x80, 0x80, 0x08, 0x02, 0xfc, 0x00, 0x00, 0x2f, 0x36, 0x12, 0x0e, 0x00,
+ 0x02, 0x00, 0xe3, 0xff, 0x50, 0x00, 0xfe, 0x1d, 0xec, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0x37, 0x81, 0x3e, 0x07, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00],
+ [0x01, 0x80, 0x80, 0x80, 0x80, 0x08, 0x00, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00]
+ ],
+ "source": "KEYBOARD | GAMEPAD",
+ "events": [
+ {"action": "DOWN", "keycode": "BUTTON_R1"},
+ {"action": "UP", "keycode": "BUTTON_R1"}
+ ]
+ },
+
+ {
+ "name": "Press BUTTON_L2",
+ "reports": [
+ [0x01, 0x80, 0x80, 0x80, 0x80, 0x08, 0x04, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00],
+ [0x01, 0x80, 0x80, 0x80, 0x80, 0x08, 0x00, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00]
+ ],
+ "source": "KEYBOARD | GAMEPAD",
+ "events": [
+ {"action": "DOWN", "keycode": "BUTTON_L2"},
+ {"action": "UP", "keycode": "BUTTON_L2"}
+ ]
+ },
+
+ {
+ "name": "Press BUTTON_R2",
+ "reports": [
+ [0x01, 0x80, 0x80, 0x80, 0x80, 0x08, 0x08, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00],
+ [0x01, 0x80, 0x80, 0x80, 0x80, 0x08, 0x00, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00]
+ ],
+ "source": "KEYBOARD | GAMEPAD",
+ "events": [
+ {"action": "DOWN", "keycode": "BUTTON_R2"},
+ {"action": "UP", "keycode": "BUTTON_R2"}
+ ]
+ },
+
+ {
+ "name": "Press BUTTON_L3",
+ "reports": [
+ [0x01, 0x80, 0x80, 0x80, 0x80, 0x08, 0x40, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00],
+ [0x01, 0x80, 0x80, 0x80, 0x80, 0x08, 0x00, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00]
+ ],
+ "source": "KEYBOARD | GAMEPAD",
+ "events": [
+ {"action": "DOWN", "keycode": "BUTTON_THUMBL"},
+ {"action": "UP", "keycode": "BUTTON_THUMBL"}
+ ]
+ },
+
+ {
+ "name": "Press BUTTON_R3",
+ "reports": [
+ [0x01, 0x80, 0x80, 0x80, 0x80, 0x08, 0x80, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00],
+ [0x01, 0x80, 0x80, 0x80, 0x80, 0x08, 0x00, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00]
+ ],
+ "source": "KEYBOARD | GAMEPAD",
+ "events": [
+ {"action": "DOWN", "keycode": "BUTTON_THUMBR"},
+ {"action": "UP", "keycode": "BUTTON_THUMBR"}
+ ]
+ },
+
+ {
+ "name": "Press BUTTON_SHARE",
+ "reports": [
+ [0x01, 0x80, 0x80, 0x80, 0x80, 0x08, 0x10, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00],
+ [0x01, 0x80, 0x80, 0x80, 0x80, 0x08, 0x00, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00]
+ ],
+ "source": "KEYBOARD | GAMEPAD",
+ "events": [
+ {"action": "DOWN", "keycode": "BUTTON_SELECT"},
+ {"action": "UP", "keycode": "BUTTON_SELECT"}
+ ]
+ },
+
+ {
+ "name": "Press BUTTON_OPTIONS",
+ "reports": [
+ [0x01, 0x80, 0x80, 0x80, 0x80, 0x08, 0x20, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00],
+ [0x01, 0x80, 0x80, 0x80, 0x80, 0x08, 0x00, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00]
+ ],
+ "source": "KEYBOARD | GAMEPAD",
+ "events": [
+ {"action": "DOWN", "keycode": "BUTTON_START"},
+ {"action": "UP", "keycode": "BUTTON_START"}
+ ]
+ },
+
+ {
+ "name": "Press BUTTON_PS",
+ "reports": [
+ [0x01, 0x80, 0x80, 0x80, 0x80, 0x08, 0x00, 0x11, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00],
+ [0x01, 0x80, 0x80, 0x80, 0x80, 0x08, 0x00, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00]
+ ],
+ "source": "KEYBOARD | GAMEPAD",
+ "events": [
+ {"action": "DOWN", "keycode": "BUTTON_MODE"},
+ {"action": "UP", "keycode": "BUTTON_MODE"}
+ ]
+ }
+
+]
diff --git a/tests/tests/hardware/res/raw/sony_dualshock4_usb_motioneventtests.json b/tests/tests/hardware/res/raw/sony_dualshock4_usb_motioneventtests.json
new file mode 100644
index 0000000..f0be94e
--- /dev/null
+++ b/tests/tests/hardware/res/raw/sony_dualshock4_usb_motioneventtests.json
@@ -0,0 +1,370 @@
+[
+ {
+ "name": "Sanity check - should not produce any events",
+ "reports": [
+ [0x11, 0xc0, 0x00, 0x80, 0x80, 0x80, 0x80, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c,
+ 0x2e, 0x80, 0xf2]
+ ],
+ "source": "JOYSTICK",
+ "events": [
+ ]
+ },
+
+ {
+ "name": "Press left DPAD key",
+ "reports": [
+ [0x01, 0x80, 0x80, 0x80, 0x80, 0x06, 0x00, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00],
+ [0x01, 0x80, 0x80, 0x80, 0x80, 0x08, 0x00, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00]
+ ],
+ "source": "JOYSTICK",
+ "events": [
+ {"action": "MOVE", "axes": {"AXIS_HAT_X": -1}},
+ {"action": "MOVE", "axes": {"AXIS_HAT_X": 0}}
+ ]
+ },
+
+ {
+ "name": "Press right DPAD key",
+ "reports": [
+ [0x01, 0x80, 0x80, 0x80, 0x80, 0x02, 0x00, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00],
+ [0x01, 0x80, 0x80, 0x80, 0x80, 0x08, 0x00, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00]
+ ],
+ "source": "JOYSTICK",
+ "events": [
+ {"action": "MOVE", "axes": {"AXIS_HAT_X": 1}},
+ {"action": "MOVE", "axes": {"AXIS_HAT_X": 0}}
+ ]
+ },
+
+ {
+ "name": "Press up DPAD key",
+ "reports": [
+ [0x01, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00],
+ [0x01, 0x80, 0x80, 0x80, 0x80, 0x08, 0x00, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00]
+ ],
+ "source": "JOYSTICK",
+ "events": [
+ {"action": "MOVE", "axes": {"AXIS_HAT_Y": -1}},
+ {"action": "MOVE", "axes": {"AXIS_HAT_Y": 0}}
+ ]
+ },
+
+ {
+ "name": "Press down DPAD key",
+ "reports": [
+ [0x01, 0x80, 0x80, 0x80, 0x80, 0x04, 0x00, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00],
+ [0x01, 0x80, 0x80, 0x80, 0x80, 0x08, 0x00, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00]
+ ],
+ "source": "JOYSTICK",
+ "events": [
+ {"action": "MOVE", "axes": {"AXIS_HAT_Y": 1}},
+ {"action": "MOVE", "axes": {"AXIS_HAT_Y": 0}}
+ ]
+ },
+
+ {
+ "name": "Left stick - press left",
+ "reports": [
+ [0x01, 0x40, 0x80, 0x80, 0x80, 0x08, 0x00, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00],
+ [0x01, 0x00, 0x80, 0x80, 0x80, 0x08, 0x00, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00],
+ [0x01, 0x80, 0x80, 0x80, 0x80, 0x08, 0x00, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00]
+ ],
+ "source": "JOYSTICK",
+ "events": [
+ {"action": "MOVE", "axes": {"AXIS_X": -0.5}},
+ {"action": "MOVE", "axes": {"AXIS_X": -1}},
+ {"action": "MOVE", "axes": {"AXIS_X": 0}}
+ ]
+ },
+
+ {
+ "name": "Left stick - press right",
+ "reports": [
+ [0x01, 0xc0, 0x80, 0x80, 0x80, 0x08, 0x00, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00],
+ [0x01, 0xff, 0x80, 0x80, 0x80, 0x08, 0x00, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00],
+ [0x01, 0x80, 0x80, 0x80, 0x80, 0x08, 0x00, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00]
+ ],
+ "source": "JOYSTICK",
+ "events": [
+ {"action": "MOVE", "axes": {"AXIS_X": 0.51}},
+ {"action": "MOVE", "axes": {"AXIS_X": 1}},
+ {"action": "MOVE", "axes": {"AXIS_X": 0}}
+ ]
+ },
+
+ {
+ "name": "Left stick - press up",
+ "reports": [
+ [0x01, 0x80, 0x40, 0x80, 0x80, 0x08, 0x00, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00],
+ [0x01, 0x80, 0x00, 0x80, 0x80, 0x08, 0x00, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00],
+ [0x01, 0x80, 0x80, 0x80, 0x80, 0x08, 0x00, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00]
+ ],
+ "source": "JOYSTICK",
+ "events": [
+ {"action": "MOVE", "axes": {"AXIS_Y": -0.5}},
+ {"action": "MOVE", "axes": {"AXIS_Y": -1}},
+ {"action": "MOVE", "axes": {"AXIS_Y": 0}}
+ ]
+ },
+
+ {
+ "name": "Left stick - press down",
+ "reports": [
+ [0x01, 0x80, 0xc0, 0x80, 0x80, 0x08, 0x00, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00],
+ [0x01, 0x80, 0xff, 0x80, 0x80, 0x08, 0x00, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00],
+ [0x01, 0x80, 0x80, 0x80, 0x80, 0x08, 0x00, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00]
+ ],
+ "source": "JOYSTICK",
+ "events": [
+ {"action": "MOVE", "axes": {"AXIS_Y": 0.51}},
+ {"action": "MOVE", "axes": {"AXIS_Y": 1}},
+ {"action": "MOVE", "axes": {"AXIS_Y": 0}}
+ ]
+ },
+
+ {
+ "name": "Right stick - press left",
+ "reports": [
+ [0x01, 0x80, 0x80, 0x40, 0x80, 0x08, 0x00, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00],
+ [0x01, 0x80, 0x80, 0x00, 0x80, 0x08, 0x00, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00],
+ [0x01, 0x80, 0x80, 0x80, 0x80, 0x08, 0x00, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00]
+ ],
+ "source": "JOYSTICK",
+ "events": [
+ {"action": "MOVE", "axes": {"AXIS_Z": -0.5}},
+ {"action": "MOVE", "axes": {"AXIS_Z": -1}},
+ {"action": "MOVE", "axes": {"AXIS_Z": 0}}
+ ]
+ },
+
+ {
+ "name": "Right stick - press right",
+ "reports": [
+ [0x01, 0x80, 0x80, 0xc0, 0x80, 0x08, 0x00, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00],
+ [0x01, 0x80, 0x80, 0xff, 0x80, 0x08, 0x00, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00],
+ [0x01, 0x80, 0x80, 0x80, 0x80, 0x08, 0x00, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00]
+ ],
+ "source": "JOYSTICK",
+ "events": [
+ {"action": "MOVE", "axes": {"AXIS_Z": 0.51}},
+ {"action": "MOVE", "axes": {"AXIS_Z": 1}},
+ {"action": "MOVE", "axes": {"AXIS_Z": 0}}
+ ]
+ },
+
+ {
+ "name": "Right stick - press up",
+ "reports": [
+ [0x01, 0x80, 0x80, 0x80, 0x40, 0x08, 0x00, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00],
+ [0x01, 0x80, 0x80, 0x80, 0x00, 0x08, 0x00, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00],
+ [0x01, 0x80, 0x80, 0x80, 0x80, 0x08, 0x00, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00]
+ ],
+ "source": "JOYSTICK",
+ "events": [
+ {"action": "MOVE", "axes": {"AXIS_RZ": -0.5}},
+ {"action": "MOVE", "axes": {"AXIS_RZ": -1}},
+ {"action": "MOVE", "axes": {"AXIS_RZ": 0}}
+ ]
+ },
+
+ {
+ "name": "Right stick - press down",
+ "reports": [
+ [0x01, 0x80, 0x80, 0x80, 0xc0, 0x08, 0x00, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00],
+ [0x01, 0x80, 0x80, 0x80, 0xff, 0x08, 0x00, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00],
+ [0x01, 0x80, 0x80, 0x80, 0x80, 0x08, 0x00, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00]
+ ],
+ "source": "JOYSTICK",
+ "events": [
+ {"action": "MOVE", "axes": {"AXIS_RZ": 0.51}},
+ {"action": "MOVE", "axes": {"AXIS_RZ": 1}},
+ {"action": "MOVE", "axes": {"AXIS_RZ": 0}}
+ ]
+ },
+
+ {
+ "name": "Left trigger - quick press",
+ "reports": [
+ [0x01, 0x80, 0x80, 0x80, 0x80, 0x08, 0x00, 0x10, 0x80, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00],
+ [0x01, 0x80, 0x80, 0x80, 0x80, 0x08, 0x00, 0x10, 0xff, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00],
+ [0x01, 0x80, 0x80, 0x80, 0x80, 0x08, 0x00, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00]
+ ],
+ "source": "JOYSTICK",
+ "events": [
+ {"action": "MOVE", "axes": {"AXIS_LTRIGGER": 0.5, "AXIS_BRAKE": 0.5}},
+ {"action": "MOVE", "axes": {"AXIS_LTRIGGER": 1.0, "AXIS_BRAKE": 1.0}},
+ {"action": "MOVE", "axes": {"AXIS_LTRIGGER": 0, "AXIS_BRAKE": 0}}
+ ]
+ },
+
+ {
+ "name": "Right trigger - quick press",
+ "reports": [
+ [0x01, 0x80, 0x80, 0x80, 0x80, 0x08, 0x00, 0x10, 0x00, 0x80, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00],
+ [0x01, 0x80, 0x80, 0x80, 0x80, 0x08, 0x00, 0x10, 0x00, 0xff, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00],
+ [0x01, 0x80, 0x80, 0x80, 0x80, 0x08, 0x00, 0x10, 0x00, 0x00, 0x34, 0xdf, 0x10, 0x0e, 0x00,
+ 0x05, 0x00, 0xe6, 0xff, 0xe9, 0xff, 0x3e, 0x1e, 0x9c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1b, 0x00, 0x00, 0x01, 0xf4, 0x80, 0x55, 0x70, 0x25, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00]
+ ],
+ "source": "JOYSTICK",
+ "events": [
+ {"action": "MOVE", "axes": {"AXIS_RTRIGGER": 0.5, "AXIS_GAS": 0.5}},
+ {"action": "MOVE", "axes": {"AXIS_RTRIGGER": 1.0, "AXIS_GAS": 1.0}},
+ {"action": "MOVE", "axes": {"AXIS_RTRIGGER": 0, "AXIS_GAS": 0}}
+ ]
+ }
+]
diff --git a/tests/tests/hardware/res/raw/sony_dualshock4_usb_register.json b/tests/tests/hardware/res/raw/sony_dualshock4_usb_register.json
new file mode 100644
index 0000000..5654c50
--- /dev/null
+++ b/tests/tests/hardware/res/raw/sony_dualshock4_usb_register.json
@@ -0,0 +1,58 @@
+{
+ "id": 1,
+ "command": "register",
+ "name": "Sony DS4 (model CUH-ZCT1U)(USB Test)",
+ "vid": 0x054c,
+ "pid": 0x05c4,
+ "bus": "usb",
+ "descriptor": [0x05, 0x01, 0x09, 0x05, 0xa1, 0x01, 0x85, 0x01, 0x09, 0x30, 0x09, 0x31, 0x09, 0x32,
+ 0x09, 0x35, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, 0x95, 0x04, 0x81, 0x02, 0x09, 0x39, 0x15,
+ 0x00, 0x25, 0x07, 0x35, 0x00, 0x46, 0x3b, 0x01, 0x65, 0x14, 0x75, 0x04, 0x95, 0x01, 0x81, 0x42,
+ 0x65, 0x00, 0x05, 0x09, 0x19, 0x01, 0x29, 0x0e, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x0e,
+ 0x81, 0x02, 0x06, 0x00, 0xff, 0x09, 0x20, 0x75, 0x06, 0x95, 0x01, 0x15, 0x00, 0x25, 0x7f, 0x81,
+ 0x02, 0x05, 0x01, 0x09, 0x33, 0x09, 0x34, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, 0x95, 0x02,
+ 0x81, 0x02, 0x06, 0x00, 0xff, 0x09, 0x21, 0x95, 0x36, 0x81, 0x02, 0x85, 0x05, 0x09, 0x22, 0x95,
+ 0x1f, 0x91, 0x02, 0x85, 0x04, 0x09, 0x23, 0x95, 0x24, 0xb1, 0x02, 0x85, 0x02, 0x09, 0x24, 0x95,
+ 0x24, 0xb1, 0x02, 0x85, 0x08, 0x09, 0x25, 0x95, 0x03, 0xb1, 0x02, 0x85, 0x10, 0x09, 0x26, 0x95,
+ 0x04, 0xb1, 0x02, 0x85, 0x11, 0x09, 0x27, 0x95, 0x02, 0xb1, 0x02, 0x85, 0x12, 0x06, 0x02, 0xff,
+ 0x09, 0x21, 0x95, 0x0f, 0xb1, 0x02, 0x85, 0x13, 0x09, 0x22, 0x95, 0x16, 0xb1, 0x02, 0x85, 0x14,
+ 0x06, 0x05, 0xff, 0x09, 0x20, 0x95, 0x10, 0xb1, 0x02, 0x85, 0x15, 0x09, 0x21, 0x95, 0x2c, 0xb1,
+ 0x02, 0x06, 0x80, 0xff, 0x85, 0x80, 0x09, 0x20, 0x95, 0x06, 0xb1, 0x02, 0x85, 0x81, 0x09, 0x21,
+ 0x95, 0x06, 0xb1, 0x02, 0x85, 0x82, 0x09, 0x22, 0x95, 0x05, 0xb1, 0x02, 0x85, 0x83, 0x09, 0x23,
+ 0x95, 0x01, 0xb1, 0x02, 0x85, 0x84, 0x09, 0x24, 0x95, 0x04, 0xb1, 0x02, 0x85, 0x85, 0x09, 0x25,
+ 0x95, 0x06, 0xb1, 0x02, 0x85, 0x86, 0x09, 0x26, 0x95, 0x06, 0xb1, 0x02, 0x85, 0x87, 0x09, 0x27,
+ 0x95, 0x23, 0xb1, 0x02, 0x85, 0x88, 0x09, 0x28, 0x95, 0x22, 0xb1, 0x02, 0x85, 0x89, 0x09, 0x29,
+ 0x95, 0x02, 0xb1, 0x02, 0x85, 0x90, 0x09, 0x30, 0x95, 0x05, 0xb1, 0x02, 0x85, 0x91, 0x09, 0x31,
+ 0x95, 0x03, 0xb1, 0x02, 0x85, 0x92, 0x09, 0x32, 0x95, 0x03, 0xb1, 0x02, 0x85, 0x93, 0x09, 0x33,
+ 0x95, 0x0c, 0xb1, 0x02, 0x85, 0xa0, 0x09, 0x40, 0x95, 0x06, 0xb1, 0x02, 0x85, 0xa1, 0x09, 0x41,
+ 0x95, 0x01, 0xb1, 0x02, 0x85, 0xa2, 0x09, 0x42, 0x95, 0x01, 0xb1, 0x02, 0x85, 0xa3, 0x09, 0x43,
+ 0x95, 0x30, 0xb1, 0x02, 0x85, 0xa4, 0x09, 0x44, 0x95, 0x0d, 0xb1, 0x02, 0x85, 0xa5, 0x09, 0x45,
+ 0x95, 0x15, 0xb1, 0x02, 0x85, 0xa6, 0x09, 0x46, 0x95, 0x15, 0xb1, 0x02, 0x85, 0xf0, 0x09, 0x47,
+ 0x95, 0x3f, 0xb1, 0x02, 0x85, 0xf1, 0x09, 0x48, 0x95, 0x3f, 0xb1, 0x02, 0x85, 0xf2, 0x09, 0x49,
+ 0x95, 0x0f, 0xb1, 0x02, 0x85, 0xa7, 0x09, 0x4a, 0x95, 0x01, 0xb1, 0x02, 0x85, 0xa8, 0x09, 0x4b,
+ 0x95, 0x01, 0xb1, 0x02, 0x85, 0xa9, 0x09, 0x4c, 0x95, 0x08, 0xb1, 0x02, 0x85, 0xaa, 0x09, 0x4e,
+ 0x95, 0x01, 0xb1, 0x02, 0x85, 0xab, 0x09, 0x4f, 0x95, 0x39, 0xb1, 0x02, 0x85, 0xac, 0x09, 0x50,
+ 0x95, 0x39, 0xb1, 0x02, 0x85, 0xad, 0x09, 0x51, 0x95, 0x0b, 0xb1, 0x02, 0x85, 0xae, 0x09, 0x52,
+ 0x95, 0x01, 0xb1, 0x02, 0x85, 0xaf, 0x09, 0x53, 0x95, 0x02, 0xb1, 0x02, 0x85, 0xb0, 0x09, 0x54,
+ 0x95, 0x3f, 0xb1, 0x02, 0x85, 0xb1, 0x09, 0x55, 0x95, 0x02, 0xb1, 0x02, 0x85, 0xb2, 0x09, 0x56,
+ 0x95, 0x02, 0xb1, 0x02, 0xc0],
+ "feature_reports": [
+ {
+ "id": 0x02,
+ "data": [0x02, 0xf8, 0xff, 0xfd, 0xff, 0xf9, 0xff, 0xdf, 0x21, 0xf1, 0xdd, 0x95, 0x22, 0x67,
+ 0xdd, 0xf2, 0x23, 0x1c, 0xdc, 0x1c, 0x02, 0x1c, 0x02, 0xaa, 0x1f, 0x56, 0xe0, 0xf7, 0x20,
+ 0x08, 0xdf, 0x0a, 0x20, 0xf7, 0xdf, 0x06, 0x00]
+ },
+ {
+ "id": 0xa3,
+ "data": [0xa3, 0x41, 0x70, 0x72, 0x20, 0x20, 0x38, 0x20, 0x32, 0x30, 0x31, 0x34, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x30, 0x39, 0x3a, 0x34, 0x36, 0x3a, 0x30, 0x36, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x43, 0x03, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05,
+ 0x00, 0x00, 0x80, 0x03, 0x00]
+ },
+ {
+ "id": 0x81,
+ "data": [0x81, 0x62, 0x97, 0xc9, 0x00, 0x00, 0x00]
+ }
+ ]
+}
diff --git a/tests/tests/hardware/res/raw/sony_dualshock4_register.json b/tests/tests/hardware/res/raw/sony_dualshock4pro_bluetooth_register.json
similarity index 96%
rename from tests/tests/hardware/res/raw/sony_dualshock4_register.json
rename to tests/tests/hardware/res/raw/sony_dualshock4pro_bluetooth_register.json
index cd33b9e..d4fa66d 100644
--- a/tests/tests/hardware/res/raw/sony_dualshock4_register.json
+++ b/tests/tests/hardware/res/raw/sony_dualshock4pro_bluetooth_register.json
@@ -1,9 +1,10 @@
{
"id": 1,
"command": "register",
- "name": "Sony DS4 Joystick (Test)",
+ "name": "Sony DS4 Pro (model CUH-ZCT2U)(Bluetooth Test)",
"vid": 0x054c,
"pid": 0x09cc,
+ "bus": "bluetooth",
"descriptor": [0x05, 0x01, 0x09, 0x05, 0xa1, 0x01, 0x85, 0x01, 0x09, 0x30, 0x09, 0x31, 0x09, 0x32,
0x09, 0x35, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, 0x95, 0x04, 0x81, 0x02, 0x09, 0x39, 0x15,
0x00, 0x25, 0x07, 0x75, 0x04, 0x95, 0x01, 0x81, 0x42, 0x05, 0x09, 0x19, 0x01, 0x29, 0x0e, 0x15,
@@ -33,7 +34,7 @@
0x46, 0xb1, 0x02, 0x85, 0xb3, 0x09, 0x45, 0xb1, 0x02, 0x85, 0xb4, 0x09, 0x46, 0xb1, 0x02, 0xc0],
"feature_reports": [
{
- "id": 5,
+ "id": 0x05,
"data": [0x05, 0x1e, 0x00, 0x05, 0x00, 0xe2, 0xff, 0xf2, 0x22, 0xbe, 0x22, 0x8d, 0x22, 0x4f,
0xdd, 0x4d, 0xdd, 0x39, 0xdd, 0x1c, 0x02, 0x1c, 0x02, 0xe3, 0x1f, 0x8b, 0xdf, 0x8c, 0x1e,
0xb4, 0xde, 0x30, 0x20, 0x71, 0xe0, 0x10, 0x00, 0xca, 0xfc, 0x64, 0x4d]
diff --git a/tests/tests/hardware/res/raw/sony_dualshock4pro_usb_register.json b/tests/tests/hardware/res/raw/sony_dualshock4pro_usb_register.json
new file mode 100644
index 0000000..4514fd4
--- /dev/null
+++ b/tests/tests/hardware/res/raw/sony_dualshock4pro_usb_register.json
@@ -0,0 +1,59 @@
+{
+ "id": 1,
+ "command": "register",
+ "name": "Sony DS4 Pro (model CUH-ZCT2U)(USB Test)",
+ "vid": 0x054c,
+ "pid": 0x09cc,
+ "bus": "usb",
+ "descriptor": [0x05, 0x01, 0x09, 0x05, 0xa1, 0x01, 0x85, 0x01, 0x09, 0x30, 0x09, 0x31, 0x09, 0x32,
+ 0x09, 0x35, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, 0x95, 0x04, 0x81, 0x02, 0x09, 0x39, 0x15,
+ 0x00, 0x25, 0x07, 0x35, 0x00, 0x46, 0x3b, 0x01, 0x65, 0x14, 0x75, 0x04, 0x95, 0x01, 0x81, 0x42,
+ 0x65, 0x00, 0x05, 0x09, 0x19, 0x01, 0x29, 0x0e, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x0e,
+ 0x81, 0x02, 0x06, 0x00, 0xff, 0x09, 0x20, 0x75, 0x06, 0x95, 0x01, 0x15, 0x00, 0x25, 0x7f, 0x81,
+ 0x02, 0x05, 0x01, 0x09, 0x33, 0x09, 0x34, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, 0x95, 0x02,
+ 0x81, 0x02, 0x06, 0x00, 0xff, 0x09, 0x21, 0x95, 0x36, 0x81, 0x02, 0x85, 0x05, 0x09, 0x22, 0x95,
+ 0x1f, 0x91, 0x02, 0x85, 0x04, 0x09, 0x23, 0x95, 0x24, 0xb1, 0x02, 0x85, 0x02, 0x09, 0x24, 0x95,
+ 0x24, 0xb1, 0x02, 0x85, 0x08, 0x09, 0x25, 0x95, 0x03, 0xb1, 0x02, 0x85, 0x10, 0x09, 0x26, 0x95,
+ 0x04, 0xb1, 0x02, 0x85, 0x11, 0x09, 0x27, 0x95, 0x02, 0xb1, 0x02, 0x85, 0x12, 0x06, 0x02, 0xff,
+ 0x09, 0x21, 0x95, 0x0f, 0xb1, 0x02, 0x85, 0x13, 0x09, 0x22, 0x95, 0x16, 0xb1, 0x02, 0x85, 0x14,
+ 0x06, 0x05, 0xff, 0x09, 0x20, 0x95, 0x10, 0xb1, 0x02, 0x85, 0x15, 0x09, 0x21, 0x95, 0x2c, 0xb1,
+ 0x02, 0x06, 0x80, 0xff, 0x85, 0x80, 0x09, 0x20, 0x95, 0x06, 0xb1, 0x02, 0x85, 0x81, 0x09, 0x21,
+ 0x95, 0x06, 0xb1, 0x02, 0x85, 0x82, 0x09, 0x22, 0x95, 0x05, 0xb1, 0x02, 0x85, 0x83, 0x09, 0x23,
+ 0x95, 0x01, 0xb1, 0x02, 0x85, 0x84, 0x09, 0x24, 0x95, 0x04, 0xb1, 0x02, 0x85, 0x85, 0x09, 0x25,
+ 0x95, 0x06, 0xb1, 0x02, 0x85, 0x86, 0x09, 0x26, 0x95, 0x06, 0xb1, 0x02, 0x85, 0x87, 0x09, 0x27,
+ 0x95, 0x23, 0xb1, 0x02, 0x85, 0x88, 0x09, 0x28, 0x95, 0x22, 0xb1, 0x02, 0x85, 0x89, 0x09, 0x29,
+ 0x95, 0x02, 0xb1, 0x02, 0x85, 0x90, 0x09, 0x30, 0x95, 0x05, 0xb1, 0x02, 0x85, 0x91, 0x09, 0x31,
+ 0x95, 0x03, 0xb1, 0x02, 0x85, 0x92, 0x09, 0x32, 0x95, 0x03, 0xb1, 0x02, 0x85, 0x93, 0x09, 0x33,
+ 0x95, 0x0c, 0xb1, 0x02, 0x85, 0xa0, 0x09, 0x40, 0x95, 0x06, 0xb1, 0x02, 0x85, 0xa1, 0x09, 0x41,
+ 0x95, 0x01, 0xb1, 0x02, 0x85, 0xa2, 0x09, 0x42, 0x95, 0x01, 0xb1, 0x02, 0x85, 0xa3, 0x09, 0x43,
+ 0x95, 0x30, 0xb1, 0x02, 0x85, 0xa4, 0x09, 0x44, 0x95, 0x0d, 0xb1, 0x02, 0x85, 0xa5, 0x09, 0x45,
+ 0x95, 0x15, 0xb1, 0x02, 0x85, 0xa6, 0x09, 0x46, 0x95, 0x15, 0xb1, 0x02, 0x85, 0xf0, 0x09, 0x47,
+ 0x95, 0x3f, 0xb1, 0x02, 0x85, 0xf1, 0x09, 0x48, 0x95, 0x3f, 0xb1, 0x02, 0x85, 0xf2, 0x09, 0x49,
+ 0x95, 0x0f, 0xb1, 0x02, 0x85, 0xa7, 0x09, 0x4a, 0x95, 0x01, 0xb1, 0x02, 0x85, 0xa8, 0x09, 0x4b,
+ 0x95, 0x01, 0xb1, 0x02, 0x85, 0xa9, 0x09, 0x4c, 0x95, 0x08, 0xb1, 0x02, 0x85, 0xaa, 0x09, 0x4e,
+ 0x95, 0x01, 0xb1, 0x02, 0x85, 0xab, 0x09, 0x4f, 0x95, 0x39, 0xb1, 0x02, 0x85, 0xac, 0x09, 0x50,
+ 0x95, 0x39, 0xb1, 0x02, 0x85, 0xad, 0x09, 0x51, 0x95, 0x0b, 0xb1, 0x02, 0x85, 0xae, 0x09, 0x52,
+ 0x95, 0x01, 0xb1, 0x02, 0x85, 0xaf, 0x09, 0x53, 0x95, 0x02, 0xb1, 0x02, 0x85, 0xb0, 0x09, 0x54,
+ 0x95, 0x3f, 0xb1, 0x02, 0x85, 0xb1, 0x09, 0x55, 0x95, 0x02, 0xb1, 0x02, 0x85, 0xb2, 0x09, 0x56,
+ 0x95, 0x02, 0xb1, 0x02, 0x85, 0xe0, 0x09, 0x57, 0x95, 0x02, 0xb1, 0x02, 0x85, 0xb3, 0x09, 0x55,
+ 0x95, 0x3f, 0xb1, 0x02, 0x85, 0xb4, 0x09, 0x55, 0x95, 0x3f, 0xb1, 0x02, 0xc0],
+ "feature_reports": [
+ {
+ "id": 0x02,
+ "data": [0x02, 0x1e, 0x00, 0x05, 0x00, 0xe2, 0xff, 0xf2, 0x22, 0x4f, 0xdd, 0x4d, 0xdd, 0xbe,
+ 0x22, 0x8d, 0x22, 0x39, 0xdd, 0x1c, 0x02, 0x1c, 0x02, 0xe3, 0x1f, 0x8b, 0xdf, 0x8c, 0x1e,
+ 0xb4, 0xde, 0x30, 0x20, 0x71, 0xe0, 0x10, 0x00]
+ },
+ {
+ "id": 0xa3,
+ "data": [0xa3, 0x41, 0x70, 0x72, 0x20, 0x20, 0x38, 0x20, 0x32, 0x30, 0x31, 0x34, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x30, 0x39, 0x3a, 0x34, 0x36, 0x3a, 0x30, 0x36, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x43, 0x03, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05,
+ 0x00, 0x00, 0x80, 0x03, 0x00]
+ },
+ {
+ "id": 0x81,
+ "data": [0x81, 0x62, 0x97, 0xc9, 0x00, 0x00, 0x00]
+ }
+ ]
+}
diff --git a/tests/tests/hardware/src/android/hardware/input/cts/tests/SonyDualshock4Test.java b/tests/tests/hardware/src/android/hardware/input/cts/tests/SonyDualshock3UsbTest.java
similarity index 69%
copy from tests/tests/hardware/src/android/hardware/input/cts/tests/SonyDualshock4Test.java
copy to tests/tests/hardware/src/android/hardware/input/cts/tests/SonyDualshock3UsbTest.java
index 409c84f..e65fa7a 100644
--- a/tests/tests/hardware/src/android/hardware/input/cts/tests/SonyDualshock4Test.java
+++ b/tests/tests/hardware/src/android/hardware/input/cts/tests/SonyDualshock3UsbTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * 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.
@@ -26,19 +26,20 @@
@SmallTest
@RunWith(AndroidJUnit4.class)
-public class SonyDualshock4Test extends InputTestCase {
+public class SonyDualshock3UsbTest extends InputTestCase {
- public SonyDualshock4Test() {
- super(R.raw.sony_dualshock4_register);
+ // Simulates the behavior of PlayStation DualShock3 gamepad (model CECHZC2U)
+ public SonyDualshock3UsbTest() {
+ super(R.raw.sony_dualshock3_usb_register);
}
@Test
public void testAllKeys() {
- testInputEvents(R.raw.sony_dualshock4_keyeventtests);
+ testInputEvents(R.raw.sony_dualshock3_usb_keyeventtests);
}
@Test
public void testAllMotions() {
- testInputEvents(R.raw.sony_dualshock4_motioneventtests);
+ testInputEvents(R.raw.sony_dualshock3_usb_motioneventtests);
}
}
diff --git a/tests/tests/hardware/src/android/hardware/input/cts/tests/SonyDualshock4Test.java b/tests/tests/hardware/src/android/hardware/input/cts/tests/SonyDualshock4BluetoothTest.java
similarity index 68%
copy from tests/tests/hardware/src/android/hardware/input/cts/tests/SonyDualshock4Test.java
copy to tests/tests/hardware/src/android/hardware/input/cts/tests/SonyDualshock4BluetoothTest.java
index 409c84f..ca36a68 100644
--- a/tests/tests/hardware/src/android/hardware/input/cts/tests/SonyDualshock4Test.java
+++ b/tests/tests/hardware/src/android/hardware/input/cts/tests/SonyDualshock4BluetoothTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * 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.
@@ -26,19 +26,20 @@
@SmallTest
@RunWith(AndroidJUnit4.class)
-public class SonyDualshock4Test extends InputTestCase {
+public class SonyDualshock4BluetoothTest extends InputTestCase {
- public SonyDualshock4Test() {
- super(R.raw.sony_dualshock4_register);
+ // Simulates the behavior of PlayStation DualShock4 gamepad (model CUH-ZCT1U)
+ public SonyDualshock4BluetoothTest() {
+ super(R.raw.sony_dualshock4_bluetooth_register);
}
@Test
public void testAllKeys() {
- testInputEvents(R.raw.sony_dualshock4_keyeventtests);
+ testInputEvents(R.raw.sony_dualshock4_bluetooth_keyeventtests);
}
@Test
public void testAllMotions() {
- testInputEvents(R.raw.sony_dualshock4_motioneventtests);
+ testInputEvents(R.raw.sony_dualshock4_bluetooth_motioneventtests);
}
}
diff --git a/tests/tests/hardware/src/android/hardware/input/cts/tests/SonyDualshock4Test.java b/tests/tests/hardware/src/android/hardware/input/cts/tests/SonyDualshock4ProBluetoothTest.java
similarity index 70%
rename from tests/tests/hardware/src/android/hardware/input/cts/tests/SonyDualshock4Test.java
rename to tests/tests/hardware/src/android/hardware/input/cts/tests/SonyDualshock4ProBluetoothTest.java
index 409c84f..c5f761f 100644
--- a/tests/tests/hardware/src/android/hardware/input/cts/tests/SonyDualshock4Test.java
+++ b/tests/tests/hardware/src/android/hardware/input/cts/tests/SonyDualshock4ProBluetoothTest.java
@@ -26,19 +26,20 @@
@SmallTest
@RunWith(AndroidJUnit4.class)
-public class SonyDualshock4Test extends InputTestCase {
+public class SonyDualshock4ProBluetoothTest extends InputTestCase {
- public SonyDualshock4Test() {
- super(R.raw.sony_dualshock4_register);
+ // Simulates the behavior of PlayStation DualShock4 Pro gamepad (model CUH-ZCT2U)
+ public SonyDualshock4ProBluetoothTest() {
+ super(R.raw.sony_dualshock4pro_bluetooth_register);
}
@Test
public void testAllKeys() {
- testInputEvents(R.raw.sony_dualshock4_keyeventtests);
+ testInputEvents(R.raw.sony_dualshock4_bluetooth_keyeventtests);
}
@Test
public void testAllMotions() {
- testInputEvents(R.raw.sony_dualshock4_motioneventtests);
+ testInputEvents(R.raw.sony_dualshock4_bluetooth_motioneventtests);
}
}
diff --git a/tests/tests/hardware/src/android/hardware/input/cts/tests/SonyDualshock4Test.java b/tests/tests/hardware/src/android/hardware/input/cts/tests/SonyDualshock4ProUsbTest.java
similarity index 68%
copy from tests/tests/hardware/src/android/hardware/input/cts/tests/SonyDualshock4Test.java
copy to tests/tests/hardware/src/android/hardware/input/cts/tests/SonyDualshock4ProUsbTest.java
index 409c84f..8e967ff 100644
--- a/tests/tests/hardware/src/android/hardware/input/cts/tests/SonyDualshock4Test.java
+++ b/tests/tests/hardware/src/android/hardware/input/cts/tests/SonyDualshock4ProUsbTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * 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.
@@ -26,19 +26,20 @@
@SmallTest
@RunWith(AndroidJUnit4.class)
-public class SonyDualshock4Test extends InputTestCase {
+public class SonyDualshock4ProUsbTest extends InputTestCase {
- public SonyDualshock4Test() {
- super(R.raw.sony_dualshock4_register);
+ // Simulates the behavior of PlayStation DualShock4 Pro gamepad (model CUH-ZCT2U)
+ public SonyDualshock4ProUsbTest() {
+ super(R.raw.sony_dualshock4pro_usb_register);
}
@Test
public void testAllKeys() {
- testInputEvents(R.raw.sony_dualshock4_keyeventtests);
+ testInputEvents(R.raw.sony_dualshock4_usb_keyeventtests);
}
@Test
public void testAllMotions() {
- testInputEvents(R.raw.sony_dualshock4_motioneventtests);
+ testInputEvents(R.raw.sony_dualshock4_usb_motioneventtests);
}
}
diff --git a/tests/tests/hardware/src/android/hardware/input/cts/tests/SonyDualshock4Test.java b/tests/tests/hardware/src/android/hardware/input/cts/tests/SonyDualshock4UsbTest.java
similarity index 69%
copy from tests/tests/hardware/src/android/hardware/input/cts/tests/SonyDualshock4Test.java
copy to tests/tests/hardware/src/android/hardware/input/cts/tests/SonyDualshock4UsbTest.java
index 409c84f..062dced 100644
--- a/tests/tests/hardware/src/android/hardware/input/cts/tests/SonyDualshock4Test.java
+++ b/tests/tests/hardware/src/android/hardware/input/cts/tests/SonyDualshock4UsbTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * 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.
@@ -26,19 +26,20 @@
@SmallTest
@RunWith(AndroidJUnit4.class)
-public class SonyDualshock4Test extends InputTestCase {
+public class SonyDualshock4UsbTest extends InputTestCase {
- public SonyDualshock4Test() {
- super(R.raw.sony_dualshock4_register);
+ // Simulates the behavior of PlayStation DualShock4 gamepad (model CUH-ZCT1U)
+ public SonyDualshock4UsbTest() {
+ super(R.raw.sony_dualshock4_usb_register);
}
@Test
public void testAllKeys() {
- testInputEvents(R.raw.sony_dualshock4_keyeventtests);
+ testInputEvents(R.raw.sony_dualshock4_usb_keyeventtests);
}
@Test
public void testAllMotions() {
- testInputEvents(R.raw.sony_dualshock4_motioneventtests);
+ testInputEvents(R.raw.sony_dualshock4_usb_motioneventtests);
}
}
diff --git a/tests/tests/keystore/src/android/keystore/cts/ImportWrappedKeyTest.java b/tests/tests/keystore/src/android/keystore/cts/ImportWrappedKeyTest.java
index ff9fc19..e967438 100644
--- a/tests/tests/keystore/src/android/keystore/cts/ImportWrappedKeyTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/ImportWrappedKeyTest.java
@@ -406,20 +406,13 @@
private KeyPair genKeyPair(String alias, boolean isStrongBoxBacked) throws Exception {
KeyPairGenerator kpg =
KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore");
-
- KeyGenParameterSpec.Builder builder =
- new KeyGenParameterSpec.Builder(alias, KeyProperties.PURPOSE_WRAP_KEY)
- .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP)
- .setBlockModes(KeyProperties.BLOCK_MODE_ECB)
- .setIsStrongBoxBacked(isStrongBoxBacked);
-
- if (isStrongBoxBacked) {
- builder.setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA1);
- } else {
- builder.setDigests(KeyProperties.DIGEST_SHA512, KeyProperties.DIGEST_SHA1);
- }
-
- kpg.initialize(builder.build());
+ kpg.initialize(
+ new KeyGenParameterSpec.Builder(alias, KeyProperties.PURPOSE_WRAP_KEY)
+ .setDigests(KeyProperties.DIGEST_SHA256)
+ .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP)
+ .setBlockModes(KeyProperties.BLOCK_MODE_ECB)
+ .setIsStrongBoxBacked(isStrongBoxBacked)
+ .build());
return kpg.generateKeyPair();
}
}
diff --git a/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java b/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java
index fc744e5..46592ca 100644
--- a/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java
@@ -253,7 +253,7 @@
try {
Certificate certificates[] = keyStore.getCertificateChain(keystoreAlias);
- verifyCertificateChain(certificates);
+ verifyCertificateChain(certificates, TestUtils.hasStrongBox(getContext()));
X509Certificate attestationCert = (X509Certificate) certificates[0];
checkDeviceLocked(new Attestation(attestationCert));
@@ -407,7 +407,7 @@
try {
Certificate certificates[] = keyStore.getCertificateChain(keystoreAlias);
- verifyCertificateChain(certificates);
+ verifyCertificateChain(certificates, TestUtils.hasStrongBox(getContext()));
X509Certificate attestationCert = (X509Certificate) certificates[0];
checkDeviceLocked(new Attestation(attestationCert));
@@ -509,7 +509,7 @@
try {
Certificate certificates[] = keyStore.getCertificateChain(keystoreAlias);
- verifyCertificateChain(certificates);
+ verifyCertificateChain(certificates, false /* expectStrongBox */);
X509Certificate attestationCert = (X509Certificate) certificates[0];
Attestation attestation = new Attestation(attestationCert);
@@ -563,7 +563,7 @@
try {
Certificate certificates[] = keyStore.getCertificateChain(keystoreAlias);
- verifyCertificateChain(certificates);
+ verifyCertificateChain(certificates, false /* expectStrongBox */);
X509Certificate attestationCert = (X509Certificate) certificates[0];
Attestation attestation = new Attestation(attestationCert);
@@ -1081,7 +1081,7 @@
keyPairGenerator.generateKeyPair();
}
- private void verifyCertificateChain(Certificate[] certChain)
+ private void verifyCertificateChain(Certificate[] certChain, boolean expectStrongBox)
throws GeneralSecurityException {
assertNotNull(certChain);
for (int i = 1; i < certChain.length; ++i) {
@@ -1112,14 +1112,15 @@
assertEquals(signedCertSubject, new X500Name("CN=Android Keystore Key"));
} else {
// Only strongbox implementations should have strongbox in the subject line
- assertFalse(x509CurrCert.getSubjectDN()
- .getName()
- .toLowerCase()
- .contains("strongbox"));
+ assertEquals(expectStrongBox, x509CurrCert.getSubjectDN()
+ .getName()
+ .toLowerCase()
+ .contains("strongbox"));
}
} catch (InvalidKeyException | CertificateException | NoSuchAlgorithmException
| NoSuchProviderException | SignatureException e) {
- throw new GeneralSecurityException("Failed to verify certificate "
+ throw new GeneralSecurityException("Using StrongBox: " + expectStrongBox + "\n"
+ + "Failed to verify certificate "
+ certChain[i - 1] + " with public key " + certChain[i].getPublicKey(), e);
}
}
diff --git a/tests/tests/keystore/src/android/keystore/cts/KeyPairGeneratorTest.java b/tests/tests/keystore/src/android/keystore/cts/KeyPairGeneratorTest.java
index 6353fed..40970f5 100644
--- a/tests/tests/keystore/src/android/keystore/cts/KeyPairGeneratorTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/KeyPairGeneratorTest.java
@@ -66,6 +66,7 @@
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.X509ExtendedKeyManager;
@@ -1812,11 +1813,23 @@
}
@Override
+ public String chooseEngineClientAlias(String[] keyType, Principal[] issuers,
+ SSLEngine engine) {
+ return "fake";
+ }
+
+ @Override
public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) {
return "fake";
}
@Override
+ public String chooseEngineServerAlias(String keyType, Principal[] issuers,
+ SSLEngine engine) {
+ return "fake";
+ }
+
+ @Override
public X509Certificate[] getCertificateChain(String alias) {
return chain;
}
diff --git a/tests/tests/keystore/src/android/keystore/cts/TestUtils.java b/tests/tests/keystore/src/android/keystore/cts/TestUtils.java
index 23886be..dcfcc85 100644
--- a/tests/tests/keystore/src/android/keystore/cts/TestUtils.java
+++ b/tests/tests/keystore/src/android/keystore/cts/TestUtils.java
@@ -827,36 +827,37 @@
}
static int getMaxSupportedPlaintextInputSizeBytes(String transformation, int keySizeBits) {
+ String encryptionPadding = getCipherEncryptionPadding(transformation);
+ int modulusSizeBytes = (keySizeBits + 7) / 8;
+ if (KeyProperties.ENCRYPTION_PADDING_NONE.equalsIgnoreCase(encryptionPadding)) {
+ return modulusSizeBytes - 1;
+ } else if (KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1.equalsIgnoreCase(
+ encryptionPadding)) {
+ return modulusSizeBytes - 11;
+ } else if (KeyProperties.ENCRYPTION_PADDING_RSA_OAEP.equalsIgnoreCase(
+ encryptionPadding)) {
+ String digest = getCipherDigest(transformation);
+ int digestOutputSizeBytes = (getDigestOutputSizeBits(digest) + 7) / 8;
+ return modulusSizeBytes - 2 * digestOutputSizeBytes - 2;
+ } else {
+ throw new IllegalArgumentException(
+ "Unsupported encryption padding scheme: " + encryptionPadding);
+ }
+
+ }
+
+ static int getMaxSupportedPlaintextInputSizeBytes(String transformation, Key key) {
String keyAlgorithm = getCipherKeyAlgorithm(transformation);
if (KeyProperties.KEY_ALGORITHM_AES.equalsIgnoreCase(keyAlgorithm)
|| KeyProperties.KEY_ALGORITHM_3DES.equalsIgnoreCase(keyAlgorithm)) {
return Integer.MAX_VALUE;
} else if (KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(keyAlgorithm)) {
- String encryptionPadding = getCipherEncryptionPadding(transformation);
- int modulusSizeBytes = (keySizeBits + 7) / 8;
- if (KeyProperties.ENCRYPTION_PADDING_NONE.equalsIgnoreCase(encryptionPadding)) {
- return modulusSizeBytes - 1;
- } else if (KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1.equalsIgnoreCase(
- encryptionPadding)) {
- return modulusSizeBytes - 11;
- } else if (KeyProperties.ENCRYPTION_PADDING_RSA_OAEP.equalsIgnoreCase(
- encryptionPadding)) {
- String digest = getCipherDigest(transformation);
- int digestOutputSizeBytes = (getDigestOutputSizeBits(digest) + 7) / 8;
- return modulusSizeBytes - 2 * digestOutputSizeBytes - 2;
- } else {
- throw new IllegalArgumentException(
- "Unsupported encryption padding scheme: " + encryptionPadding);
- }
+ return getMaxSupportedPlaintextInputSizeBytes(transformation, getKeySizeBits(key));
} else {
throw new IllegalArgumentException("Unsupported key algorithm: " + keyAlgorithm);
}
}
- static int getMaxSupportedPlaintextInputSizeBytes(String transformation, Key key) {
- return getMaxSupportedPlaintextInputSizeBytes(transformation, getKeySizeBits(key));
- }
-
static int getDigestOutputSizeBits(String digest) {
if (KeyProperties.DIGEST_NONE.equals(digest)) {
return -1;
diff --git a/tests/tests/libthermalndk/Android.bp b/tests/tests/libthermalndk/Android.bp
new file mode 100644
index 0000000..2b7d126
--- /dev/null
+++ b/tests/tests/libthermalndk/Android.bp
@@ -0,0 +1,38 @@
+// 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.
+
+android_test {
+ name: "CtsThermalTestCases",
+ defaults: ["cts_defaults"],
+ compile_multilib: "both",
+ static_libs: [
+ "compatibility-device-util-axt",
+ "ctstestrunner-axt",
+ ],
+ libs: [
+ "android.test.runner.stubs",
+ "android.test.base.stubs",
+ ],
+ jni_libs: [
+ "libctsthermal_jni",
+ ],
+ srcs: ["src/**/*.java"],
+ // Tag this module as a cts test artifact
+ test_suites: [
+ "cts",
+ "vts",
+ "general-tests",
+ ],
+ sdk_version: "test_current",
+}
diff --git a/tests/tests/libthermalndk/AndroidManifest.xml b/tests/tests/libthermalndk/AndroidManifest.xml
new file mode 100644
index 0000000..eb6eb22
--- /dev/null
+++ b/tests/tests/libthermalndk/AndroidManifest.xml
@@ -0,0 +1,31 @@
+<?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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.thermal.cts">
+
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.thermal.cts"
+ android:label="CTS Thermal tests of android.thermal" >
+ <meta-data
+ android:name="listener"
+ android:value="com.android.cts.runner.CtsTestRunListener" />
+ </instrumentation>
+</manifest>
diff --git a/tests/tests/libthermalndk/AndroidTest.xml b/tests/tests/libthermalndk/AndroidTest.xml
new file mode 100644
index 0000000..e4ab0ac
--- /dev/null
+++ b/tests/tests/libthermalndk/AndroidTest.xml
@@ -0,0 +1,29 @@
+<?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.
+-->
+<configuration description="Config for CTS Thermal test cases">
+ <option name="test-suite-tag" value="cts" />
+ <option name="config-descriptor:metadata" key="component" value="framework" />
+ <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+ <option name="config-descriptor:metadata" key="parameter" value="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="CtsThermalTestCases.apk" />
+ </target_preparer>
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+ <option name="package" value="android.thermal.cts" />
+ </test>
+</configuration>
diff --git a/tests/tests/libthermalndk/OWNERS b/tests/tests/libthermalndk/OWNERS
new file mode 100644
index 0000000..1c617ec
--- /dev/null
+++ b/tests/tests/libthermalndk/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 46788
+michaelwr@google.com
+lzye@google.com
diff --git a/tests/tests/libthermalndk/jni/Android.bp b/tests/tests/libthermalndk/jni/Android.bp
new file mode 100644
index 0000000..9f95e7f
--- /dev/null
+++ b/tests/tests/libthermalndk/jni/Android.bp
@@ -0,0 +1,31 @@
+// 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.
+
+cc_test_library {
+ name: "libctsthermal_jni",
+ srcs: [
+ "NativeThermalTest.cpp",
+ ],
+ shared_libs: [
+ "libandroid",
+ "liblog",
+ "libbase",
+ ],
+ stl: "libc++_static",
+ cflags: [
+ "-Werror",
+ "-Wall",
+ ],
+ gtest: false,
+}
diff --git a/tests/tests/libthermalndk/jni/NativeThermalTest.cpp b/tests/tests/libthermalndk/jni/NativeThermalTest.cpp
new file mode 100644
index 0000000..913a8ae
--- /dev/null
+++ b/tests/tests/libthermalndk/jni/NativeThermalTest.cpp
@@ -0,0 +1,286 @@
+/*
+ * 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "NativeThermalTest"
+
+#include <condition_variable>
+#include <jni.h>
+#include <mutex>
+#include <optional>
+#include <thread>
+#include <inttypes.h>
+#include <time.h>
+#include <unistd.h>
+#include <vector>
+
+#include <android/thermal.h>
+#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
+#include <android-base/thread_annotations.h>
+#include <log/log.h>
+#include <sys/stat.h>
+#include <utils/Errors.h>
+
+using namespace android;
+using namespace std::chrono_literals;
+using android::base::StringPrintf;
+
+struct AThermalTestContext {
+ AThermalManager *mThermalMgr;
+ std::mutex mMutex;
+ std::condition_variable mCv;
+ std::vector<AThermalStatus> mListenerStatus GUARDED_BY(mMutex);
+};
+
+static jclass gNativeThermalTest_class;
+static jmethodID gNativeThermalTest_thermalOverrideMethodID;
+
+int onStatusChange(void *data, AThermalStatus status) {
+ AThermalTestContext *ctx = static_cast<AThermalTestContext *>(data);
+ if (ctx == nullptr) {
+ return BAD_VALUE;
+ } else {
+ std::lock_guard<std::mutex> guard(ctx->mMutex);
+ ctx->mListenerStatus.push_back(status);
+ ctx->mCv.notify_all();
+ }
+ return OK;
+}
+
+static inline void setThermalStatusOverride(JNIEnv* env, jobject obj, int32_t level) {
+ env->CallVoidMethod(obj, gNativeThermalTest_thermalOverrideMethodID, level);
+}
+
+static inline jstring returnJString(JNIEnv *env, std::optional<std::string> result) {
+ if (result.has_value()) {
+ return env->NewStringUTF(result.value().c_str());
+ } else {
+ return env->NewStringUTF("");
+ }
+}
+
+static std::optional<std::string> testGetCurrentThermalStatus(
+ JNIEnv *env, jobject obj, int32_t level) {
+ AThermalTestContext ctx;
+
+ ctx.mThermalMgr = AThermal_acquireManager();
+ if (ctx.mThermalMgr == nullptr) {
+ return "AThermal_acquireManager failed";
+ }
+
+ setThermalStatusOverride(env, obj, level);
+ AThermalStatus thermalStatus = AThermal_getCurrentThermalStatus(ctx.mThermalMgr);
+ if (thermalStatus == ATHERMAL_STATUS_ERROR) {
+ return "getCurrentThermalStatus returns ATHERMAL_STATUS_ERROR";
+ }
+ // Verify the current thermal status is same as override
+ if (thermalStatus != static_cast<AThermalStatus>(level)) {
+ return StringPrintf("getCurrentThermalStatus %" PRId32 " != override %" PRId32 ".",
+ thermalStatus, level);
+ }
+
+ AThermal_releaseManager(ctx.mThermalMgr);
+ return std::nullopt;
+}
+
+static jstring nativeTestGetCurrentThermalStatus(JNIEnv *env, jobject obj, jint level) {
+ return returnJString(env, testGetCurrentThermalStatus(env, obj, static_cast<int32_t>(level)));
+}
+
+static std::optional<std::string> testRegisterThermalStatusListener(JNIEnv *env, jobject obj) {
+ AThermalTestContext ctx;
+ std::unique_lock<std::mutex> lock(ctx.mMutex);
+
+ ctx.mThermalMgr = AThermal_acquireManager();
+ if (ctx.mThermalMgr == nullptr) {
+ return "AThermal_acquireManager failed";
+ }
+
+ // Register a listener with valid callback
+ int ret = AThermal_registerThermalStatusListener(ctx.mThermalMgr, onStatusChange, &ctx);
+ if (ret != 0) {
+ return StringPrintf("AThermal_registerThermalStatusListener failed: %s",
+ strerror(ret));
+ }
+
+ // Expect the callback after registration
+ if (ctx.mCv.wait_for(lock, 1s) == std::cv_status::timeout) {
+ return "Listener callback should be called after registration";
+ }
+
+ // Verify the current thermal status is same as listener callback
+ auto thermalStatus = AThermal_getCurrentThermalStatus(ctx.mThermalMgr);
+ auto listenerStatus = ctx.mListenerStatus.back();
+ if (thermalStatus != listenerStatus) {
+ return StringPrintf("thermalStatus %" PRId32 " != Listener status %" PRId32 ".",
+ thermalStatus, listenerStatus);
+ }
+
+ // Change override level and verify the listener callback
+ for (int32_t level = ATHERMAL_STATUS_LIGHT; level <= ATHERMAL_STATUS_SHUTDOWN; level++) {
+ setThermalStatusOverride(env, obj, level);
+ if (ctx.mCv.wait_for(lock, 1s) == std::cv_status::timeout) {
+ return StringPrintf("Listener callback timeout at level %" PRId32, level);
+ }
+ auto overrideStatus = static_cast<AThermalStatus>(level);
+ auto listenerStatus = ctx.mListenerStatus.back();
+ if (listenerStatus != overrideStatus) {
+ return StringPrintf("Listener thermalStatus%" PRId32 " != override %" PRId32 ".",
+ listenerStatus, overrideStatus);
+ }
+ }
+
+ // Unregister listener
+ ret = AThermal_unregisterThermalStatusListener(ctx.mThermalMgr, onStatusChange, &ctx);
+ if (ret != 0) {
+ return StringPrintf("AThermal_unregisterThermalStatusListener failed: %s",
+ strerror(ret));
+ }
+
+ AThermal_releaseManager(ctx.mThermalMgr);
+ return std::nullopt;
+}
+
+static jstring nativeTestRegisterThermalStatusListener(JNIEnv *env, jobject obj) {
+ return returnJString(env, testRegisterThermalStatusListener(env, obj));
+}
+
+static std::optional<std::string> testThermalStatusRegisterNullListener() {
+ AThermalTestContext ctx;
+
+ ctx.mThermalMgr = AThermal_acquireManager();
+ if (ctx.mThermalMgr == nullptr) {
+ return StringPrintf("AThermal_acquireManager failed");
+ }
+
+ // Register a listener with null callback
+ int ret = AThermal_registerThermalStatusListener(ctx.mThermalMgr, nullptr, &ctx);
+ if (ret != EINVAL) {
+ return "AThermal_registerThermalStatusListener should fail with null callback";
+ }
+
+ // Register a listener with null data
+ ret = AThermal_registerThermalStatusListener(ctx.mThermalMgr, onStatusChange, &ctx);
+ if (ret != 0) {
+ return StringPrintf("AThermal_registerThermalStatusListener failed: %s",
+ strerror(ret));
+ }
+
+ // Unregister listener with null callback and null data
+ ret = AThermal_unregisterThermalStatusListener(ctx.mThermalMgr, nullptr, nullptr);
+ if (ret != EINVAL) {
+ return "AThermal_unregisterThermalStatusListener should fail with null listener";
+ }
+
+ AThermal_releaseManager(ctx.mThermalMgr);
+ return std::nullopt;
+}
+
+static jstring nativeTestThermalStatusRegisterNullListener(JNIEnv *env, jobject) {
+ return returnJString(env, testThermalStatusRegisterNullListener());
+}
+
+static std::optional<std::string> testThermalStatusListenerDoubleRegistration
+ (JNIEnv *env, jobject obj) {
+ AThermalTestContext ctx;
+ std::unique_lock<std::mutex> lock(ctx.mMutex);
+
+ ctx.mThermalMgr = AThermal_acquireManager();
+ if (ctx.mThermalMgr == nullptr) {
+ return "AThermal_acquireManager failed";
+ }
+
+ // Register a listener with valid callback
+ int ret = AThermal_registerThermalStatusListener(ctx.mThermalMgr, onStatusChange, &ctx);
+ if (ret != 0) {
+ return StringPrintf("AThermal_registerThermalStatusListener failed: %s",
+ strerror(ret));
+ }
+
+ // Register the listener again with same callback and data
+ ret = AThermal_registerThermalStatusListener(ctx.mThermalMgr, onStatusChange, &ctx);
+ if (ret != EINVAL) {
+ return "Register should fail as listener already registered";
+ }
+
+ // Register a listener with same callback but null data
+ ret = AThermal_registerThermalStatusListener(ctx.mThermalMgr, onStatusChange, nullptr);
+ if (ret != 0) {
+ return StringPrintf("Register listener with null data failed: %s", strerror(ret));
+ }
+
+ // Expect listener callback
+ if (ctx.mCv.wait_for(lock, 1s) == std::cv_status::timeout) {
+ return "Thermal listener callback timeout";
+ }
+
+ // Unregister listener
+ ret = AThermal_unregisterThermalStatusListener(ctx.mThermalMgr, onStatusChange, &ctx);
+ if (ret != 0) {
+ return StringPrintf("AThermal_unregisterThermalStatusListener failed: %s",
+ strerror(ret));
+ }
+
+ for (int32_t level = ATHERMAL_STATUS_LIGHT; level <= ATHERMAL_STATUS_SHUTDOWN; level++) {
+ setThermalStatusOverride(env, obj, level);
+ // Expect no listener callback
+ if (ctx.mCv.wait_for(lock, 1s) != std::cv_status::timeout) {
+ return "Thermal listener got callback after unregister.";
+ }
+ }
+
+ // Unregister listener already unregistered
+ ret = AThermal_unregisterThermalStatusListener(ctx.mThermalMgr, onStatusChange, &ctx);
+ if (ret != EINVAL) {
+ return "Unregister should fail with listener already unregistered";
+ }
+
+ AThermal_releaseManager(ctx.mThermalMgr);
+ return std::nullopt;
+}
+
+static jstring nativeTestThermalStatusListenerDoubleRegistration(JNIEnv *env, jobject obj) {
+ return returnJString(env, testThermalStatusListenerDoubleRegistration(env, obj));
+}
+
+extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void*) {
+ JNIEnv* env;
+ const JNINativeMethod methodTable[] = {
+ {"nativeTestGetCurrentThermalStatus", "(I)Ljava/lang/String;",
+ (void*)nativeTestGetCurrentThermalStatus},
+ {"nativeTestRegisterThermalStatusListener", "()Ljava/lang/String;",
+ (void*)nativeTestRegisterThermalStatusListener},
+ {"nativeTestThermalStatusRegisterNullListener", "()Ljava/lang/String;",
+ (void*)nativeTestThermalStatusRegisterNullListener},
+ {"nativeTestThermalStatusListenerDoubleRegistration", "()Ljava/lang/String;",
+ (void*)nativeTestThermalStatusListenerDoubleRegistration},
+ };
+ if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
+ return JNI_ERR;
+ }
+ gNativeThermalTest_class = env->FindClass("android/thermal/cts/NativeThermalTest");
+ gNativeThermalTest_thermalOverrideMethodID =
+ env->GetMethodID(gNativeThermalTest_class, "setOverrideStatus", "(I)V");
+ if (gNativeThermalTest_thermalOverrideMethodID == nullptr) {
+ return JNI_ERR;
+ }
+ if (env->RegisterNatives(gNativeThermalTest_class, methodTable,
+ sizeof(methodTable) / sizeof(JNINativeMethod)) != JNI_OK) {
+ return JNI_ERR;
+ }
+ return JNI_VERSION_1_6;
+}
diff --git a/tests/tests/libthermalndk/src/android/thermal/cts/NativeThermalTest.java b/tests/tests/libthermalndk/src/android/thermal/cts/NativeThermalTest.java
new file mode 100644
index 0000000..ab6d518
--- /dev/null
+++ b/tests/tests/libthermalndk/src/android/thermal/cts/NativeThermalTest.java
@@ -0,0 +1,126 @@
+/*
+ * 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.thermal.cts;
+
+import android.content.Context;
+import android.os.PowerManager;
+import android.support.test.uiautomator.UiDevice;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+import com.google.common.base.Strings;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+
+import static org.junit.Assert.fail;
+
+/**
+ * Tests native thermal API for get current thermal status, register and unregister
+ * thermal status listeners.
+ */
+@RunWith(AndroidJUnit4.class)
+public class NativeThermalTest {
+ private UiDevice mUiDevice;
+ private Executor mExec = Executors.newSingleThreadExecutor();
+
+ private native String nativeTestGetCurrentThermalStatus(int level);
+ private native String nativeTestRegisterThermalStatusListener();
+ private native String nativeTestThermalStatusRegisterNullListener();
+ private native String nativeTestThermalStatusListenerDoubleRegistration();
+
+ @Before
+ public void setUp() throws Exception {
+ mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ mUiDevice.executeShellCommand("cmd thermalservice reset");
+ }
+
+ /**
+ * Helper function to set override status
+ */
+ public void setOverrideStatus (int level) throws Exception {
+ mUiDevice.executeShellCommand("cmd thermalservice override-status " + level);
+ }
+
+ /**
+ * Confirm that we can get thermal status.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testGetCurrentThermalStatus() throws Exception {
+ for (int level = PowerManager.THERMAL_STATUS_NONE;
+ level < PowerManager.THERMAL_STATUS_SHUTDOWN; level++) {
+ final String failureMessage = nativeTestGetCurrentThermalStatus(level);
+ if (!Strings.isNullOrEmpty(failureMessage)) {
+ fail(failureMessage);
+ }
+ }
+ }
+
+ /**
+ * Confirm that we can register thermal status listener and get callback.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testRegisterThermalStatusListener() throws Exception {
+ final String failureMessage = nativeTestRegisterThermalStatusListener();
+ if (!Strings.isNullOrEmpty(failureMessage)) {
+ fail(failureMessage);
+ }
+ }
+
+ /**
+ * Confirm that register null thermal status listener fails with error.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testThermalStatusRegisterNullListener() throws Exception {
+ final String failureMessage = nativeTestThermalStatusRegisterNullListener();
+ if (!Strings.isNullOrEmpty(failureMessage)) {
+ fail(failureMessage);
+ }
+ }
+
+ /**
+ * Confirm that double register and unregister same listener fails with error.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testThermalStatusListenerDoubleRegistration() throws Exception {
+ final String failureMessage = nativeTestThermalStatusListenerDoubleRegistration();
+ if (!Strings.isNullOrEmpty(failureMessage)) {
+ fail(failureMessage);
+ }
+ }
+
+ static {
+ System.loadLibrary("ctsthermal_jni");
+ }
+}
diff --git a/tests/tests/media/AndroidManifest.xml b/tests/tests/media/AndroidManifest.xml
index a7727b1..1bec10d 100644
--- a/tests/tests/media/AndroidManifest.xml
+++ b/tests/tests/media/AndroidManifest.xml
@@ -143,7 +143,7 @@
android:foregroundServiceType="mediaProjection"
android:enabled="true">
</service>
- <service android:name=".SampleMediaRoute2ProviderService"
+ <service android:name=".StubMediaRoute2ProviderService"
android:exported="true">
<intent-filter>
<action android:name="android.media.MediaRoute2ProviderService" />
diff --git a/tests/tests/media/src/android/media/cts/AudioManagerTest.java b/tests/tests/media/src/android/media/cts/AudioManagerTest.java
index 90f517a..7e475d1 100644
--- a/tests/tests/media/src/android/media/cts/AudioManagerTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioManagerTest.java
@@ -37,7 +37,6 @@
import static android.media.AudioManager.VIBRATE_TYPE_RINGER;
import static android.provider.Settings.System.SOUND_EFFECTS_ENABLED;
-import android.app.ActivityManager;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.BroadcastReceiver;
@@ -114,8 +113,6 @@
mIsSingleVolume = mContext.getResources().getBoolean(
Resources.getSystem().getIdentifier("config_single_volume", "bool", "android"));
mSkipRingerTests = mUseFixedVolume || mIsTelevision || mIsSingleVolume;
- ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
- mSupportNotificationPolicyAccess = !am.isLowRamDevice();
// Store the original volumes that that they can be recovered in tearDown().
final int[] streamTypes = {
@@ -133,19 +130,18 @@
mOriginalStreamVolumes.put(streamType, mAudioManager.getStreamVolume(streamType));
}
- if (mSupportNotificationPolicyAccess) {
- try {
- Utils.toggleNotificationPolicyAccess(
- mContext.getPackageName(), getInstrumentation(), true);
- mOriginalNotificationPolicy = mNm.getNotificationPolicy();
- mOriginalZen = mNm.getCurrentInterruptionFilter();
- } finally {
- setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL);
- Utils.toggleNotificationPolicyAccess(
- mContext.getPackageName(), getInstrumentation(), false);
- }
+ try {
+ Utils.toggleNotificationPolicyAccess(
+ mContext.getPackageName(), getInstrumentation(), true);
+ mOriginalNotificationPolicy = mNm.getNotificationPolicy();
+ mOriginalZen = mNm.getCurrentInterruptionFilter();
+ } finally {
+ setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL);
+ Utils.toggleNotificationPolicyAccess(
+ mContext.getPackageName(), getInstrumentation(), false);
}
+
// Check original mirchrophone mute/unmute status
mDoNotCheckUnmute = false;
if (mAudioManager.isMicrophoneMute()) {
@@ -159,9 +155,6 @@
@Override
protected void tearDown() throws Exception {
- if (!mSupportNotificationPolicyAccess) {
- return;
- }
try {
Utils.toggleNotificationPolicyAccess(
mContext.getPackageName(), getInstrumentation(), true);
@@ -303,9 +296,6 @@
}
public void testCheckingZenModeBlockDoesNotRequireNotificationPolicyAccess() throws Exception {
- if (!mSupportNotificationPolicyAccess) {
- return;
- }
try {
// set zen mode to priority only, so playSoundEffect will check notification policy
Utils.toggleNotificationPolicyAccess(mContext.getPackageName(), getInstrumentation(),
@@ -396,7 +386,7 @@
}
public void testVibrateNotification() throws Exception {
- if (mUseFixedVolume || !mHasVibrator || !mSupportNotificationPolicyAccess) {
+ if (mUseFixedVolume || !mHasVibrator) {
return;
}
Utils.toggleNotificationPolicyAccess(
@@ -459,7 +449,7 @@
}
public void testVibrateRinger() throws Exception {
- if (mUseFixedVolume || !mHasVibrator || !mSupportNotificationPolicyAccess) {
+ if (mUseFixedVolume || !mHasVibrator) {
return;
}
Utils.toggleNotificationPolicyAccess(
@@ -523,9 +513,6 @@
}
public void testAccessRingMode() throws Exception {
- if (!mSupportNotificationPolicyAccess) {
- return;
- }
Utils.toggleNotificationPolicyAccess(
mContext.getPackageName(), getInstrumentation(), true);
mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
@@ -550,7 +537,7 @@
}
public void testSetRingerModePolicyAccess() throws Exception {
- if (mSkipRingerTests || !mSupportNotificationPolicyAccess) {
+ if (mSkipRingerTests) {
return;
}
// Apps without policy access cannot change silent -> normal or silent -> vibrate.
@@ -613,9 +600,6 @@
}
public void testVolume() throws Exception {
- if (!mSupportNotificationPolicyAccess) {
- return;
- }
Utils.toggleNotificationPolicyAccess(
mContext.getPackageName(), getInstrumentation(), true);
int volume, volumeDelta;
@@ -838,7 +822,7 @@
}
public void testMuteDndAffectedStreams() throws Exception {
- if (mSkipRingerTests || !mSupportNotificationPolicyAccess) {
+ if (mSkipRingerTests) {
return;
}
int[] streams = { AudioManager.STREAM_RING };
@@ -912,7 +896,7 @@
}
public void testMuteDndUnaffectedStreams() throws Exception {
- if (mSkipRingerTests || !mSupportNotificationPolicyAccess) {
+ if (mSkipRingerTests) {
return;
}
int[] streams = {
@@ -1006,7 +990,7 @@
}
public void testAdjustVolumeInTotalSilenceMode() throws Exception {
- if (mSkipRingerTests || !mSupportNotificationPolicyAccess) {
+ if (mSkipRingerTests) {
return;
}
try {
@@ -1027,7 +1011,7 @@
}
public void testAdjustVolumeInAlarmsOnlyMode() throws Exception {
- if (mSkipRingerTests || !mSupportNotificationPolicyAccess) {
+ if (mSkipRingerTests) {
return;
}
try {
@@ -1052,7 +1036,7 @@
}
public void testSetStreamVolumeInTotalSilenceMode() throws Exception {
- if (mSkipRingerTests || !mSupportNotificationPolicyAccess) {
+ if (mSkipRingerTests) {
return;
}
try {
@@ -1076,7 +1060,7 @@
}
public void testSetStreamVolumeInAlarmsOnlyMode() throws Exception {
- if (mSkipRingerTests || !mSupportNotificationPolicyAccess) {
+ if (mSkipRingerTests) {
return;
}
try {
@@ -1098,7 +1082,7 @@
}
public void testSetStreamVolumeInPriorityOnlyMode() throws Exception {
- if (mSkipRingerTests || !mSupportNotificationPolicyAccess) {
+ if (mSkipRingerTests) {
return;
}
Utils.toggleNotificationPolicyAccess(
@@ -1136,7 +1120,7 @@
}
public void testAdjustVolumeInPriorityOnly() throws Exception {
- if (mSkipRingerTests || !mSupportNotificationPolicyAccess) {
+ if (mSkipRingerTests) {
return;
}
@@ -1181,7 +1165,7 @@
}
public void testPriorityOnlyMuteAll() throws Exception {
- if (mSkipRingerTests || !mSupportNotificationPolicyAccess) {
+ if (mSkipRingerTests) {
return;
}
@@ -1216,7 +1200,7 @@
}
public void testPriorityOnlyMediaAllowed() throws Exception {
- if (mSkipRingerTests || !mSupportNotificationPolicyAccess) {
+ if (mSkipRingerTests) {
return;
}
Utils.toggleNotificationPolicyAccess(
@@ -1251,7 +1235,7 @@
}
public void testPriorityOnlySystemAllowed() throws Exception {
- if (mSkipRingerTests || !mSupportNotificationPolicyAccess) {
+ if (mSkipRingerTests) {
return;
}
@@ -1285,7 +1269,7 @@
}
public void testPriorityOnlySystemDisallowedWithRingerMuted() throws Exception {
- if (mSkipRingerTests || !mSupportNotificationPolicyAccess) {
+ if (mSkipRingerTests) {
return;
}
@@ -1322,7 +1306,7 @@
}
public void testPriorityOnlyAlarmsAllowed() throws Exception {
- if (mSkipRingerTests || !mSupportNotificationPolicyAccess) {
+ if (mSkipRingerTests) {
return;
}
@@ -1358,7 +1342,7 @@
}
public void testPriorityOnlyRingerAllowed() throws Exception {
- if (mSkipRingerTests || !mSupportNotificationPolicyAccess) {
+ if (mSkipRingerTests) {
return;
}
@@ -1394,7 +1378,7 @@
public void testPriorityOnlyChannelsCanBypassDnd() throws Exception {
final String NOTIFICATION_CHANNEL_ID = "test_id";
- if (mSkipRingerTests || !mSupportNotificationPolicyAccess) {
+ if (mSkipRingerTests) {
return;
}
diff --git a/tests/tests/media/src/android/media/cts/MediaCodecBlockModelTest.java b/tests/tests/media/src/android/media/cts/MediaCodecBlockModelTest.java
index 27f9ddc..7123d9c 100644
--- a/tests/tests/media/src/android/media/cts/MediaCodecBlockModelTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaCodecBlockModelTest.java
@@ -173,12 +173,16 @@
mExtractor.advance();
mSignaledEos = mExtractor.getSampleTrackIndex() == -1
|| timestampUs >= mLastBufferTimestampUs;
- codec.getQueueRequest(index).setLinearBlock(
- input.block,
- input.offset,
- written,
- timestampUs,
- mSignaledEos ? MediaCodec.BUFFER_FLAG_END_OF_STREAM : 0).queue();
+ codec.getQueueRequest(index)
+ .setLinearBlock(
+ input.block,
+ input.offset,
+ written,
+ null /* cryptoInfo */)
+ .setPresentationTimeUs(timestampUs)
+ .setFlags(
+ mSignaledEos ? MediaCodec.BUFFER_FLAG_END_OF_STREAM : 0)
+ .queue();
input.offset += written;
}
diff --git a/tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java b/tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java
index 05a3970..e5bf714 100644
--- a/tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java
@@ -45,11 +45,14 @@
import androidx.test.filters.SmallTest;
import com.android.compatibility.common.util.MediaUtils;
+import java.io.Closeable;
import java.io.File;
+import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
+import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -62,6 +65,7 @@
public class MediaMetadataRetrieverTest extends AndroidTestCase {
private static final String TAG = "MediaMetadataRetrieverTest";
private static final boolean SAVE_BITMAP_OUTPUT = false;
+ private static final String TEST_MEDIA_FILE = "retriever_test.3gp";
protected Resources mResources;
protected MediaMetadataRetriever mRetriever;
@@ -93,6 +97,10 @@
protected void tearDown() throws Exception {
super.tearDown();
mRetriever.release();
+ File file = new File(Environment.getExternalStorageDirectory(), TEST_MEDIA_FILE);
+ if (file.exists()) {
+ file.delete();
+ }
}
protected void setDataSourceFd(int resid) {
@@ -368,27 +376,23 @@
}
public void testSetDataSourcePath() {
- File outputFile = new File(Environment.getExternalStorageDirectory(), "retriever_test.3gp");
+ copyMeidaFile();
+ File file = new File(Environment.getExternalStorageDirectory(), TEST_MEDIA_FILE);
try {
- recordMedia(outputFile);
- mRetriever.setDataSource(outputFile.getAbsolutePath());
+ mRetriever.setDataSource(file.getAbsolutePath());
} catch (Exception ex) {
fail("Failed setting data source with path, caught exception:" + ex);
- } finally {
- outputFile.delete();
}
}
public void testSetDataSourceUri() {
- File outputFile = new File(Environment.getExternalStorageDirectory(), "retriever_test.3gp");
+ copyMeidaFile();
+ File file = new File(Environment.getExternalStorageDirectory(), TEST_MEDIA_FILE);
try {
- recordMedia(outputFile);
- Uri uri = Uri.parse(outputFile.getAbsolutePath());
+ Uri uri = Uri.parse(file.getAbsolutePath());
mRetriever.setDataSource(getContext(), uri);
} catch (Exception ex) {
fail("Failed setting data source with Uri, caught exception:" + ex);
- } finally {
- outputFile.delete();
}
}
@@ -1005,20 +1009,42 @@
}
}
- private void recordMedia(File outputFile) throws Exception {
- MediaRecorder mr = new MediaRecorder();
+ private void copyMeidaFile() {
+ InputStream inputStream = null;
+ FileOutputStream outputStream = null;
+ String outputPath = new File(
+ Environment.getExternalStorageDirectory(), TEST_MEDIA_FILE).getAbsolutePath();
try {
- mr.setAudioSource(MediaRecorder.AudioSource.MIC);
- mr.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
- mr.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
- mr.setOutputFile(outputFile.getAbsolutePath());
+ inputStream = getContext().getResources().openRawResource(R.raw.testvideo);
+ outputStream = new FileOutputStream(outputPath);
+ copy(inputStream, outputStream);
+ } catch (Exception e) {
- mr.prepare();
- mr.start();
- Thread.sleep(SLEEP_TIME);
- mr.stop();
- } finally {
- mr.release();
+ }finally {
+ closeQuietly(inputStream);
+ closeQuietly(outputStream);
+ }
+ }
+
+ private int copy(InputStream in, OutputStream out) throws IOException {
+ int total = 0;
+ byte[] buffer = new byte[8192];
+ int c;
+ while ((c = in.read(buffer)) != -1) {
+ total += c;
+ out.write(buffer, 0, c);
+ }
+ return total;
+ }
+
+ private void closeQuietly(Closeable closeable) {
+ if (closeable != null) {
+ try {
+ closeable.close();
+ } catch (RuntimeException rethrown) {
+ throw rethrown;
+ } catch (Exception ignored) {
+ }
}
}
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayerTest.java b/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
index b9d4873..3e547bb 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
@@ -15,7 +15,6 @@
*/
package android.media.cts;
-import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.AssetFileDescriptor;
@@ -827,8 +826,7 @@
int oldRingerMode = Integer.MIN_VALUE;
int oldVolume = Integer.MIN_VALUE;
try {
- if (am.getRingerMode() != AudioManager.RINGER_MODE_NORMAL
- && !ActivityManager.isLowRamDeviceStatic()) {
+ if (am.getRingerMode() != AudioManager.RINGER_MODE_NORMAL) {
Utils.toggleNotificationPolicyAccess(
mContext.getPackageName(), getInstrumentation(), true /* on */);
}
@@ -932,10 +930,8 @@
if (oldVolume != Integer.MIN_VALUE) {
am.setStreamVolume(AudioManager.STREAM_MUSIC, oldVolume, 0);
}
- if (!ActivityManager.isLowRamDeviceStatic()) {
- Utils.toggleNotificationPolicyAccess(
- mContext.getPackageName(), getInstrumentation(), false /* on == false */);
- }
+ Utils.toggleNotificationPolicyAccess(
+ mContext.getPackageName(), getInstrumentation(), false /* on == false */);
}
}
diff --git a/tests/tests/media/src/android/media/cts/MediaRoute2ProviderServiceTest.java b/tests/tests/media/src/android/media/cts/MediaRoute2ProviderServiceTest.java
index ec9e8b4..773aede 100644
--- a/tests/tests/media/src/android/media/cts/MediaRoute2ProviderServiceTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaRoute2ProviderServiceTest.java
@@ -17,12 +17,12 @@
package android.media.cts;
import static android.media.cts.MediaRouter2Test.releaseControllers;
-import static android.media.cts.SampleMediaRoute2ProviderService.FEATURE_SAMPLE;
-import static android.media.cts.SampleMediaRoute2ProviderService.FEATURE_SPECIAL;
-import static android.media.cts.SampleMediaRoute2ProviderService.ROUTE_ID1;
-import static android.media.cts.SampleMediaRoute2ProviderService.ROUTE_ID2;
-import static android.media.cts.SampleMediaRoute2ProviderService.ROUTE_ID4_TO_SELECT_AND_DESELECT;
-import static android.media.cts.SampleMediaRoute2ProviderService.ROUTE_ID5_TO_TRANSFER_TO;
+import static android.media.cts.StubMediaRoute2ProviderService.FEATURE_SAMPLE;
+import static android.media.cts.StubMediaRoute2ProviderService.FEATURE_SPECIAL;
+import static android.media.cts.StubMediaRoute2ProviderService.ROUTE_ID1;
+import static android.media.cts.StubMediaRoute2ProviderService.ROUTE_ID2;
+import static android.media.cts.StubMediaRoute2ProviderService.ROUTE_ID4_TO_SELECT_AND_DESELECT;
+import static android.media.cts.StubMediaRoute2ProviderService.ROUTE_ID5_TO_TRANSFER_TO;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -40,7 +40,7 @@
import android.media.MediaRouter2.TransferCallback;
import android.media.RouteDiscoveryPreference;
import android.media.RoutingSessionInfo;
-import android.media.cts.SampleMediaRoute2ProviderService.Proxy;
+import android.media.cts.StubMediaRoute2ProviderService.Proxy;
import android.os.Bundle;
import android.platform.test.annotations.AppModeFull;
import android.platform.test.annotations.LargeTest;
@@ -48,6 +48,8 @@
import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
+import com.android.compatibility.common.util.PollingCheck;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -64,14 +66,14 @@
import java.util.concurrent.TimeUnit;
@RunWith(AndroidJUnit4.class)
-@AppModeFull(reason = "The system should be able to bind to SampleMediaRoute2ProviderService")
+@AppModeFull(reason = "The system should be able to bind to StubMediaRoute2ProviderService")
@LargeTest
public class MediaRoute2ProviderServiceTest {
private static final String TAG = "MR2ProviderServiceTest";
Context mContext;
private MediaRouter2 mRouter2;
private Executor mExecutor;
- private SampleMediaRoute2ProviderService mServiceInstance;
+ private StubMediaRoute2ProviderService mService;
private static final int TIMEOUT_MS = 5000;
@@ -87,61 +89,68 @@
mContext = InstrumentationRegistry.getTargetContext();
mRouter2 = MediaRouter2.getInstance(mContext);
mExecutor = Executors.newSingleThreadExecutor();
- mServiceInstance = SampleMediaRoute2ProviderService.getInstance();
+
+ new PollingCheck(TIMEOUT_MS) {
+ @Override
+ protected boolean check() {
+ StubMediaRoute2ProviderService service =
+ StubMediaRoute2ProviderService.getInstance();
+ if (service != null) {
+ mService = service;
+ return true;
+ }
+ return false;
+ }
+ }.run();
}
@After
public void tearDown() throws Exception {
- if (mServiceInstance != null) {
- mServiceInstance.clear();
- mServiceInstance = null;
+ if (mService != null) {
+ mService.clear();
+ mService = null;
}
}
@Test
public void testGetSessionInfoAndGetAllSessionInfo() {
- SampleMediaRoute2ProviderService service = mServiceInstance;
- assertNotNull(service);
- assertEquals(0, service.getAllSessionInfo().size());
+ assertEquals(0, mService.getAllSessionInfo().size());
// Add a session
RoutingSessionInfo sessionInfo1 = new RoutingSessionInfo.Builder(
SESSION_ID_1, "" /* clientPackageName */)
.addSelectedRoute(ROUTE_ID1)
.build();
- service.notifySessionCreated(sessionInfo1, MediaRoute2ProviderService.REQUEST_ID_UNKNOWN);
- assertEquals(1, service.getAllSessionInfo().size());
- assertEquals(sessionInfo1, service.getAllSessionInfo().get(0));
- assertEquals(sessionInfo1, service.getSessionInfo(SESSION_ID_1));
+ mService.notifySessionCreated(sessionInfo1, MediaRoute2ProviderService.REQUEST_ID_NONE);
+ assertEquals(1, mService.getAllSessionInfo().size());
+ assertEquals(sessionInfo1, mService.getAllSessionInfo().get(0));
+ assertEquals(sessionInfo1, mService.getSessionInfo(SESSION_ID_1));
// Add another session
RoutingSessionInfo sessionInfo2 = new RoutingSessionInfo.Builder(
SESSION_ID_2, "" /* clientPackageName */)
.addSelectedRoute(ROUTE_ID2)
.build();
- service.notifySessionCreated(
- sessionInfo2, MediaRoute2ProviderService.REQUEST_ID_UNKNOWN);
- assertEquals(2, service.getAllSessionInfo().size());
- assertEquals(sessionInfo2, service.getSessionInfo(SESSION_ID_2));
+ mService.notifySessionCreated(
+ sessionInfo2, MediaRoute2ProviderService.REQUEST_ID_NONE);
+ assertEquals(2, mService.getAllSessionInfo().size());
+ assertEquals(sessionInfo2, mService.getSessionInfo(SESSION_ID_2));
// Remove the first session
- service.notifySessionReleased(SESSION_ID_1);
- assertNull(service.getSessionInfo(SESSION_ID_1));
- assertEquals(1, service.getAllSessionInfo().size());
- assertEquals(sessionInfo2, service.getAllSessionInfo().get(0));
- assertEquals(sessionInfo2, service.getSessionInfo(SESSION_ID_2));
+ mService.notifySessionReleased(SESSION_ID_1);
+ assertNull(mService.getSessionInfo(SESSION_ID_1));
+ assertEquals(1, mService.getAllSessionInfo().size());
+ assertEquals(sessionInfo2, mService.getAllSessionInfo().get(0));
+ assertEquals(sessionInfo2, mService.getSessionInfo(SESSION_ID_2));
// Remove the remaining session
- service.notifySessionReleased(SESSION_ID_2);
- assertEquals(0, service.getAllSessionInfo().size());
- assertNull(service.getSessionInfo(SESSION_ID_2));
+ mService.notifySessionReleased(SESSION_ID_2);
+ assertEquals(0, mService.getAllSessionInfo().size());
+ assertNull(mService.getSessionInfo(SESSION_ID_2));
}
@Test
public void testNotifyRoutesInvokesMediaRouter2RouteCallback() throws Exception {
- SampleMediaRoute2ProviderService service = mServiceInstance;
- assertNotNull(service);
-
final String routeId0 = "routeId0";
final String routeName0 = "routeName0";
final String routeId1 = "routeId1";
@@ -236,7 +245,7 @@
mRouter2.registerRouteCallback(mExecutor, routeCallback,
new RouteDiscoveryPreference.Builder(features, true).build());
try {
- service.notifyRoutes(routes);
+ mService.notifyRoutes(routes);
assertTrue(onRoutesAddedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
// Change the connection state of route2 in order to invoke onRoutesChanged()
@@ -244,12 +253,12 @@
.setConnectionState(newConnectionState)
.build();
routes.set(1, newRoute2);
- service.notifyRoutes(routes);
+ mService.notifyRoutes(routes);
assertTrue(onRoutesChangedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
// Now remove all the routes
routes.clear();
- service.notifyRoutes(routes);
+ mService.notifyRoutes(routes);
assertTrue(onRoutesRemovedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
} finally {
mRouter2.unregisterRouteCallback(routeCallback);
@@ -258,10 +267,8 @@
@Test
public void testSessionRelatedCallbacks() throws Exception {
- SampleMediaRoute2ProviderService service = mServiceInstance;
- assertNotNull(service);
- service.initializeRoutes();
- service.publishRoutes();
+ mService.initializeRoutes();
+ mService.publishRoutes();
List<String> featuresSample = Collections.singletonList(FEATURE_SAMPLE);
Map<String, MediaRoute2Info> routes = waitAndGetRoutes(featuresSample);
@@ -281,7 +288,7 @@
// Now test all session-related callbacks.
setProxy(new Proxy() {
@Override
- public void onCreateSession(String packageName, String routeId, long requestId,
+ public void onCreateSession(long requestId, String packageName, String routeId,
Bundle sessionHints) {
assertEquals(mContext.getPackageName(), packageName);
assertEquals(ROUTE_ID1, routeId);
@@ -295,65 +302,64 @@
.addSelectableRoute(ROUTE_ID4_TO_SELECT_AND_DESELECT)
.addTransferableRoute(ROUTE_ID5_TO_TRANSFER_TO)
.build();
- service.notifySessionCreated(info, requestId);
+ mService.notifySessionCreated(info, requestId);
onCreateSessionLatch.countDown();
}
@Override
- public void onSelectRoute(String sessionId, String routeId) {
+ public void onSelectRoute(long requestId, String sessionId, String routeId) {
assertEquals(SESSION_ID_1, sessionId);
assertEquals(ROUTE_ID4_TO_SELECT_AND_DESELECT, routeId);
- RoutingSessionInfo oldInfo = service.getSessionInfo(SESSION_ID_1);
+ RoutingSessionInfo oldInfo = mService.getSessionInfo(SESSION_ID_1);
RoutingSessionInfo newInfo = new RoutingSessionInfo.Builder(oldInfo)
.addSelectedRoute(ROUTE_ID4_TO_SELECT_AND_DESELECT)
.removeSelectableRoute(ROUTE_ID4_TO_SELECT_AND_DESELECT)
.addDeselectableRoute(ROUTE_ID4_TO_SELECT_AND_DESELECT)
.build();
- service.notifySessionUpdated(newInfo);
+ mService.notifySessionUpdated(newInfo);
onSelectRouteLatch.countDown();
}
@Override
- public void onDeselectRoute(String sessionId, String routeId) {
+ public void onDeselectRoute(long requestId, String sessionId, String routeId) {
assertEquals(SESSION_ID_1, sessionId);
assertEquals(ROUTE_ID4_TO_SELECT_AND_DESELECT, routeId);
- RoutingSessionInfo oldInfo = service.getSessionInfo(SESSION_ID_1);
+ RoutingSessionInfo oldInfo = mService.getSessionInfo(SESSION_ID_1);
RoutingSessionInfo newInfo = new RoutingSessionInfo.Builder(oldInfo)
.removeSelectedRoute(ROUTE_ID4_TO_SELECT_AND_DESELECT)
.addSelectableRoute(ROUTE_ID4_TO_SELECT_AND_DESELECT)
.removeDeselectableRoute(ROUTE_ID4_TO_SELECT_AND_DESELECT)
.build();
- service.notifySessionUpdated(newInfo);
+ mService.notifySessionUpdated(newInfo);
onDeselectRouteLatch.countDown();
}
@Override
- public void onTransferToRoute(String sessionId, String routeId) {
+ public void onTransferToRoute(long requestId, String sessionId, String routeId) {
assertEquals(SESSION_ID_1, sessionId);
assertEquals(ROUTE_ID5_TO_TRANSFER_TO, routeId);
- RoutingSessionInfo oldInfo = service.getSessionInfo(SESSION_ID_1);
+ RoutingSessionInfo oldInfo = mService.getSessionInfo(SESSION_ID_1);
RoutingSessionInfo newInfo = new RoutingSessionInfo.Builder(oldInfo)
.clearDeselectableRoutes()
.clearSelectedRoutes()
.clearDeselectableRoutes()
.addSelectedRoute(ROUTE_ID5_TO_TRANSFER_TO)
.build();
- service.notifySessionUpdated(newInfo);
+ mService.notifySessionUpdated(newInfo);
onTransferToRouteLatch.countDown();
}
@Override
- public void onReleaseSession(String sessionId) {
+ public void onReleaseSession(long requestId, String sessionId) {
assertEquals(SESSION_ID_1, sessionId);
- service.notifySessionReleased(sessionId);
+ mService.notifySessionReleased(sessionId);
onReleaseSessionLatch.countDown();
}
});
-
CountDownLatch onControllerCreatedLatch = new CountDownLatch(1);
CountDownLatch onControllerUpdatedForSelectLatch = new CountDownLatch(1);
CountDownLatch onControllerUpdatedForDeselectLatch = new CountDownLatch(1);
@@ -364,10 +370,7 @@
@Override
public void onTransferred(RoutingController oldController,
RoutingController newController) {
- // TODO: Make RoutingController#getOriginalId() as @TestApi and use it.
- if (newController != null
- && ROUTE_ID1.equals(newController
- .getSelectedRoutes().get(0).getOriginalId())) {
+ if (newController != null && SESSION_ID_1.equals(newController.getOriginalId())) {
controllers.add(newController);
onControllerCreatedLatch.countDown();
}
@@ -399,7 +402,7 @@
}
};
- // TODO: Remove this once the MediaRouter2 becomes always connected to the service.
+ // TODO: Remove this once the MediaRouter2 becomes always connected to the mService.
RouteCallback dummyCallback = new RouteCallback();
try {
mRouter2.registerRouteCallback(mExecutor, dummyCallback,
@@ -441,10 +444,8 @@
@Test
public void testNotifySessionReleased() throws Exception {
- SampleMediaRoute2ProviderService service = mServiceInstance;
- assertNotNull(service);
- service.initializeRoutes();
- service.publishRoutes();
+ mService.initializeRoutes();
+ mService.publishRoutes();
List<String> featuresSample = Collections.singletonList(FEATURE_SAMPLE);
Map<String, MediaRoute2Info> routes = waitAndGetRoutes(featuresSample);
@@ -454,7 +455,7 @@
CountDownLatch onCreateSessionLatch = new CountDownLatch(1);
setProxy(new Proxy() {
@Override
- public void onCreateSession(String packageName, String routeId, long requestId,
+ public void onCreateSession(long requestId, String packageName, String routeId,
Bundle sessionHints) {
assertEquals(mContext.getPackageName(), packageName);
assertEquals(ROUTE_ID1, routeId);
@@ -466,7 +467,7 @@
.addSelectableRoute(ROUTE_ID4_TO_SELECT_AND_DESELECT)
.addTransferableRoute(ROUTE_ID5_TO_TRANSFER_TO)
.build();
- service.notifySessionCreated(info, requestId);
+ mService.notifySessionCreated(info, requestId);
onCreateSessionLatch.countDown();
}
});
@@ -480,16 +481,14 @@
@Override
public void onTransferred(RoutingController oldController,
RoutingController newController) {
- // TODO: Make RoutingController#getOriginalId() as @TestApi and use it.
if (newController != null) {
- if (ROUTE_ID1.equals(newController
- .getSelectedRoutes().get(0).getOriginalId())) {
+ if (SESSION_ID_1.equals(newController.getOriginalId())) {
controllers.add(newController);
onControllerCreatedLatch.countDown();
}
} else {
- if (ROUTE_ID1.equals(oldController
- .getSelectedRoutes().get(0).getOriginalId())) {
+ // newController == null means that the oldController is released
+ if (SESSION_ID_1.equals(oldController.getOriginalId())) {
assertTrue(oldController.isReleased());
onControllerReleasedLatch.countDown();
}
@@ -497,7 +496,7 @@
}
};
- // TODO: Remove this once the MediaRouter2 becomes always connected to the service.
+ // TODO: Remove this once the MediaRouter2 becomes always connected to the mService.
RouteCallback dummyCallback = new RouteCallback();
try {
mRouter2.registerRouteCallback(mExecutor, dummyCallback,
@@ -509,7 +508,7 @@
assertTrue(onControllerCreatedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
assertFalse(controllers.isEmpty());
- service.notifySessionReleased(SESSION_ID_1);
+ mService.notifySessionReleased(SESSION_ID_1);
assertTrue(onControllerReleasedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
} finally {
mRouter2.unregisterRouteCallback(dummyCallback);
@@ -558,10 +557,10 @@
}
}
- void setProxy(SampleMediaRoute2ProviderService.Proxy proxy) {
- SampleMediaRoute2ProviderService instance = SampleMediaRoute2ProviderService.getInstance();
- if (instance != null) {
- instance.setProxy(proxy);
+ void setProxy(StubMediaRoute2ProviderService.Proxy proxy) {
+ StubMediaRoute2ProviderService service = mService;
+ if (service != null) {
+ service.setProxy(proxy);
}
}
diff --git a/tests/tests/media/src/android/media/cts/MediaRouter2Test.java b/tests/tests/media/src/android/media/cts/MediaRouter2Test.java
index c73a447..0c87a2a 100644
--- a/tests/tests/media/src/android/media/cts/MediaRouter2Test.java
+++ b/tests/tests/media/src/android/media/cts/MediaRouter2Test.java
@@ -18,14 +18,14 @@
import static android.content.Context.AUDIO_SERVICE;
import static android.media.MediaRoute2Info.PLAYBACK_VOLUME_VARIABLE;
-import static android.media.cts.SampleMediaRoute2ProviderService.FEATURES_SPECIAL;
-import static android.media.cts.SampleMediaRoute2ProviderService.FEATURE_SAMPLE;
-import static android.media.cts.SampleMediaRoute2ProviderService.ROUTE_ID1;
-import static android.media.cts.SampleMediaRoute2ProviderService.ROUTE_ID2;
-import static android.media.cts.SampleMediaRoute2ProviderService.ROUTE_ID3_SESSION_CREATION_FAILED;
-import static android.media.cts.SampleMediaRoute2ProviderService.ROUTE_ID4_TO_SELECT_AND_DESELECT;
-import static android.media.cts.SampleMediaRoute2ProviderService.ROUTE_ID5_TO_TRANSFER_TO;
-import static android.media.cts.SampleMediaRoute2ProviderService.ROUTE_ID_SPECIAL_FEATURE;
+import static android.media.cts.StubMediaRoute2ProviderService.FEATURES_SPECIAL;
+import static android.media.cts.StubMediaRoute2ProviderService.FEATURE_SAMPLE;
+import static android.media.cts.StubMediaRoute2ProviderService.ROUTE_ID1;
+import static android.media.cts.StubMediaRoute2ProviderService.ROUTE_ID2;
+import static android.media.cts.StubMediaRoute2ProviderService.ROUTE_ID3_SESSION_CREATION_FAILED;
+import static android.media.cts.StubMediaRoute2ProviderService.ROUTE_ID4_TO_SELECT_AND_DESELECT;
+import static android.media.cts.StubMediaRoute2ProviderService.ROUTE_ID5_TO_TRANSFER_TO;
+import static android.media.cts.StubMediaRoute2ProviderService.ROUTE_ID_SPECIAL_FEATURE;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -54,6 +54,8 @@
import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
+import com.android.compatibility.common.util.PollingCheck;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -70,7 +72,7 @@
import java.util.concurrent.TimeUnit;
@RunWith(AndroidJUnit4.class)
-@AppModeFull(reason = "The system should be able to bind to SampleMediaRoute2ProviderService")
+@AppModeFull(reason = "The system should be able to bind to StubMediaRoute2ProviderService")
@LargeTest
public class MediaRouter2Test {
private static final String TAG = "MR2Test";
@@ -78,7 +80,7 @@
private MediaRouter2 mRouter2;
private Executor mExecutor;
private AudioManager mAudioManager;
- private SampleMediaRoute2ProviderService mServiceInstance;
+ private StubMediaRoute2ProviderService mService;
private static final int TIMEOUT_MS = 5000;
private static final int WAIT_MS = 2000;
@@ -95,18 +97,27 @@
mExecutor = Executors.newSingleThreadExecutor();
mAudioManager = (AudioManager) mContext.getSystemService(AUDIO_SERVICE);
- mServiceInstance = SampleMediaRoute2ProviderService.getInstance();
- if (mServiceInstance != null) {
- mServiceInstance.initializeRoutes();
- mServiceInstance.publishRoutes();
- }
+ new PollingCheck(TIMEOUT_MS) {
+ @Override
+ protected boolean check() {
+ StubMediaRoute2ProviderService service =
+ StubMediaRoute2ProviderService.getInstance();
+ if (service != null) {
+ mService = service;
+ return true;
+ }
+ return false;
+ }
+ }.run();
+ mService.initializeRoutes();
+ mService.publishRoutes();
}
@After
public void tearDown() throws Exception {
- if (mServiceInstance != null) {
- mServiceInstance.clear();
- mServiceInstance = null;
+ if (mService != null) {
+ mService.clear();
+ mService = null;
}
}
@@ -351,7 +362,7 @@
assertTrue(createRouteMap(newController.getSelectedRoutes()).containsKey(
ROUTE_ID1));
- // The SampleMediaRoute2ProviderService is supposed to set control hints
+ // The StubMediaRoute2ProviderService is supposed to set control hints
// with the given controllerHints.
Bundle controlHints = newController.getControlHints();
assertNotNull(controlHints);
@@ -376,7 +387,7 @@
try {
mRouter2.registerTransferCallback(mExecutor, transferCallback);
- // The SampleMediaRoute2ProviderService supposed to set control hints
+ // The StubMediaRoute2ProviderService supposed to set control hints
// with the given creationSessionHints.
mRouter2.setOnGetControllerHintsListener(listener);
mRouter2.transferTo(route);
diff --git a/tests/tests/media/src/android/media/cts/RingtoneManagerTest.java b/tests/tests/media/src/android/media/cts/RingtoneManagerTest.java
index 3ff68c3..f305a74 100644
--- a/tests/tests/media/src/android/media/cts/RingtoneManagerTest.java
+++ b/tests/tests/media/src/android/media/cts/RingtoneManagerTest.java
@@ -70,8 +70,7 @@
mDefaultUri = RingtoneManager.getActualDefaultRingtoneUri(mContext,
RingtoneManager.TYPE_RINGTONE);
- if (mAudioManager.getRingerMode() == AudioManager.RINGER_MODE_SILENT
- && !ActivityManager.isLowRamDeviceStatic()) {
+ if (mAudioManager.getRingerMode() == AudioManager.RINGER_MODE_SILENT) {
try {
Utils.toggleNotificationPolicyAccess(
mContext.getPackageName(), getInstrumentation(), true);
@@ -87,19 +86,17 @@
@Override
protected void tearDown() throws Exception {
- if (!ActivityManager.isLowRamDeviceStatic()) {
- try {
- Utils.toggleNotificationPolicyAccess(
- mContext.getPackageName(), getInstrumentation(), true);
- // restore original ringer settings
- if (mAudioManager != null) {
- mAudioManager.setStreamVolume(AudioManager.STREAM_RING, mOriginalVolume,
- AudioManager.FLAG_ALLOW_RINGER_MODES);
- }
- } finally {
- Utils.toggleNotificationPolicyAccess(
- mContext.getPackageName(), getInstrumentation(), false);
+ try {
+ Utils.toggleNotificationPolicyAccess(
+ mContext.getPackageName(), getInstrumentation(), true);
+ // restore original ringer settings
+ if (mAudioManager != null) {
+ mAudioManager.setStreamVolume(AudioManager.STREAM_RING, mOriginalVolume,
+ AudioManager.FLAG_ALLOW_RINGER_MODES);
}
+ } finally {
+ Utils.toggleNotificationPolicyAccess(
+ mContext.getPackageName(), getInstrumentation(), false);
}
RingtoneManager.setActualDefaultRingtoneUri(mContext, RingtoneManager.TYPE_RINGTONE,
mDefaultUri);
diff --git a/tests/tests/media/src/android/media/cts/RingtoneTest.java b/tests/tests/media/src/android/media/cts/RingtoneTest.java
index c7ddbd8..ba289f3 100644
--- a/tests/tests/media/src/android/media/cts/RingtoneTest.java
+++ b/tests/tests/media/src/android/media/cts/RingtoneTest.java
@@ -16,8 +16,6 @@
package android.media.cts;
-import android.app.ActivityManager;
-import android.app.UiAutomation;
import android.content.Context;
import android.content.pm.PackageManager;
import android.media.AudioAttributes;
@@ -63,7 +61,7 @@
} else if (mAudioManager.getRingerMode() == AudioManager.RINGER_MODE_NORMAL) {
mAudioManager.setStreamVolume(AudioManager.STREAM_RING, maxVolume / 2,
AudioManager.FLAG_ALLOW_RINGER_MODES);
- } else if (!ActivityManager.isLowRamDeviceStatic()) {
+ } else {
try {
Utils.toggleNotificationPolicyAccess(
mContext.getPackageName(), getInstrumentation(), true);
@@ -101,7 +99,7 @@
if (mRingtone.isPlaying()) mRingtone.stop();
mRingtone.setStreamType(mOriginalStreamType);
}
- if (mAudioManager != null && !ActivityManager.isLowRamDeviceStatic()) {
+ if (mAudioManager != null) {
try {
Utils.toggleNotificationPolicyAccess(
mContext.getPackageName(), getInstrumentation(), true);
diff --git a/tests/tests/media/src/android/media/cts/SampleMediaRoute2ProviderService.java b/tests/tests/media/src/android/media/cts/StubMediaRoute2ProviderService.java
similarity index 88%
rename from tests/tests/media/src/android/media/cts/SampleMediaRoute2ProviderService.java
rename to tests/tests/media/src/android/media/cts/StubMediaRoute2ProviderService.java
index 4b51731..326adb0 100644
--- a/tests/tests/media/src/android/media/cts/SampleMediaRoute2ProviderService.java
+++ b/tests/tests/media/src/android/media/cts/StubMediaRoute2ProviderService.java
@@ -31,7 +31,6 @@
import android.os.Bundle;
import android.os.IBinder;
import android.text.TextUtils;
-import android.util.Log;
import java.lang.reflect.Method;
import java.util.ArrayList;
@@ -41,7 +40,7 @@
import javax.annotation.concurrent.GuardedBy;
-public class SampleMediaRoute2ProviderService extends MediaRoute2ProviderService {
+public class StubMediaRoute2ProviderService extends MediaRoute2ProviderService {
private static final String TAG = "SampleMR2ProviderSvc";
private static final Object sLock = new Object();
@@ -89,7 +88,7 @@
private int mNextSessionId = 1000;
@GuardedBy("sLock")
- private static SampleMediaRoute2ProviderService sInstance;
+ private static StubMediaRoute2ProviderService sInstance;
private Proxy mProxy;
public void initializeRoutes() {
@@ -140,7 +139,7 @@
mRoutes.put(variableVolumeRoute.getId(), variableVolumeRoute);
}
- public static SampleMediaRoute2ProviderService getInstance() {
+ public static StubMediaRoute2ProviderService getInstance() {
synchronized (sLock) {
return sInstance;
}
@@ -183,7 +182,7 @@
}
@Override
- public void onSetRouteVolume(String routeId, int volume) {
+ public void onSetRouteVolume(long requestId, String routeId, int volume) {
MediaRoute2Info route = mRoutes.get(routeId);
if (route == null) {
return;
@@ -196,7 +195,7 @@
}
@Override
- public void onSetSessionVolume(String sessionId, int volume) {
+ public void onSetSessionVolume(long requestId, String sessionId, int volume) {
RoutingSessionInfo sessionInfo = getSessionInfo(sessionId);
if (sessionInfo == null) {
return;
@@ -209,11 +208,11 @@
}
@Override
- public void onCreateSession(String packageName, String routeId, long requestId,
+ public void onCreateSession(long requestId, String packageName, String routeId,
@Nullable Bundle sessionHints) {
Proxy proxy = mProxy;
if (doesProxyOverridesMethod(proxy, "onCreateSession")) {
- proxy.onCreateSession(packageName, routeId, requestId, sessionHints);
+ proxy.onCreateSession(requestId, packageName, routeId, sessionHints);
return;
}
@@ -223,7 +222,7 @@
notifySessionCreationFailed(requestId);
return;
}
- maybeDeselectRoute(routeId);
+ maybeDeselectRoute(routeId, requestId);
final String sessionId = String.valueOf(mNextSessionId);
mNextSessionId++;
@@ -248,10 +247,10 @@
}
@Override
- public void onReleaseSession(String sessionId) {
+ public void onReleaseSession(long requestId, String sessionId) {
Proxy proxy = mProxy;
if (doesProxyOverridesMethod(proxy, "onReleaseSession")) {
- proxy.onReleaseSession(sessionId);
+ proxy.onReleaseSession(requestId, sessionId);
return;
}
@@ -286,10 +285,10 @@
}
@Override
- public void onSelectRoute(String sessionId, String routeId) {
+ public void onSelectRoute(long requestId, String sessionId, String routeId) {
Proxy proxy = mProxy;
if (doesProxyOverridesMethod(proxy, "onSelectRoute")) {
- proxy.onSelectRoute(sessionId, routeId);
+ proxy.onSelectRoute(requestId, sessionId, routeId);
return;
}
@@ -298,7 +297,7 @@
if (route == null || sessionInfo == null) {
return;
}
- maybeDeselectRoute(routeId);
+ maybeDeselectRoute(routeId, requestId);
mRoutes.put(routeId, new MediaRoute2Info.Builder(route)
.setClientPackageName(sessionInfo.getClientPackageName())
@@ -315,10 +314,10 @@
}
@Override
- public void onDeselectRoute(String sessionId, String routeId) {
+ public void onDeselectRoute(long requestId, String sessionId, String routeId) {
Proxy proxy = mProxy;
if (doesProxyOverridesMethod(proxy, "onDeselectRoute")) {
- proxy.onDeselectRoute(sessionId, routeId);
+ proxy.onDeselectRoute(requestId, sessionId, routeId);
return;
}
@@ -350,10 +349,10 @@
}
@Override
- public void onTransferToRoute(String sessionId, String routeId) {
+ public void onTransferToRoute(long requestId, String sessionId, String routeId) {
Proxy proxy = mProxy;
if (doesProxyOverridesMethod(proxy, "onTransferToRoute")) {
- proxy.onTransferToRoute(sessionId, routeId);
+ proxy.onTransferToRoute(requestId, sessionId, routeId);
return;
}
@@ -389,13 +388,13 @@
publishRoutes();
}
- void maybeDeselectRoute(String routeId) {
+ void maybeDeselectRoute(String routeId, long requestId) {
if (!mRouteIdToSessionId.containsKey(routeId)) {
return;
}
String sessionId = mRouteIdToSessionId.get(routeId);
- onDeselectRoute(sessionId, routeId);
+ onDeselectRoute(requestId, sessionId, routeId);
}
void publishRoutes() {
@@ -403,12 +402,15 @@
}
public static class Proxy {
- public void onCreateSession(@NonNull String packageName, @NonNull String routeId,
- long requestId, @Nullable Bundle sessionHints) {}
- public void onReleaseSession(@NonNull String sessionId) {}
- public void onSelectRoute(@NonNull String sessionId, @NonNull String routeId) {}
- public void onDeselectRoute(@NonNull String sessionId, @NonNull String routeId) {}
- public void onTransferToRoute(@NonNull String sessionId, @NonNull String routeId) {}
+ public void onCreateSession(long requestId, @NonNull String packageName,
+ @NonNull String routeId, @Nullable Bundle sessionHints) {}
+ public void onReleaseSession(long requestId, @NonNull String sessionId) {}
+ public void onSelectRoute(long requestId, @NonNull String sessionId,
+ @NonNull String routeId) {}
+ public void onDeselectRoute(long requestId, @NonNull String sessionId,
+ @NonNull String routeId) {}
+ public void onTransferToRoute(long requestId, @NonNull String sessionId,
+ @NonNull String routeId) {}
public void onDiscoveryPreferenceChanged(RouteDiscoveryPreference preference) {}
// TODO: Handle onSetRouteVolume() && onSetSessionVolume()
}
diff --git a/tests/tests/mediaparser/src/android/media/mediaparser/cts/MediaParserTest.java b/tests/tests/mediaparser/src/android/media/mediaparser/cts/MediaParserTest.java
index 818ce18..bdc7dfb 100644
--- a/tests/tests/mediaparser/src/android/media/mediaparser/cts/MediaParserTest.java
+++ b/tests/tests/mediaparser/src/android/media/mediaparser/cts/MediaParserTest.java
@@ -364,7 +364,7 @@
mediaParser.advance(mockInput);
if (expectedExtractorName != null) {
- assertThat(expectedExtractorName).isEqualTo(mediaParser.getExtractorName());
+ assertThat(expectedExtractorName).isEqualTo(mediaParser.getParserName());
// We are only checking that the extractor is the right one.
return;
}
diff --git a/tests/tests/nativemedia/aaudio/jni/test_aaudio_callback.cpp b/tests/tests/nativemedia/aaudio/jni/test_aaudio_callback.cpp
index 813b40c..4a89d69 100644
--- a/tests/tests/nativemedia/aaudio/jni/test_aaudio_callback.cpp
+++ b/tests/tests/nativemedia/aaudio/jni/test_aaudio_callback.cpp
@@ -55,17 +55,48 @@
return latencyMillis;
}
-using CbTestParams = std::tuple<aaudio_sharing_mode_t, int32_t, aaudio_performance_mode_t>;
+using CbTestParams = std::tuple<aaudio_sharing_mode_t, int32_t,
+ aaudio_performance_mode_t, int32_t, aaudio_format_t>;
enum {
PARAM_SHARING_MODE = 0,
PARAM_FRAMES_PER_CB,
- PARAM_PERF_MODE
+ PARAM_PERF_MODE,
+ PARAM_ALLOW_MMAP,
+ PARAM_AUDIO_FORMAT
};
+enum {
+ MMAP_NOT_ALLOWED,
+ MMAP_ALLOWED,
+};
+
+static const char* allowMMapToString(int allow) {
+ switch (allow) {
+ case MMAP_NOT_ALLOWED: return "NOTMMAP";
+ case MMAP_ALLOWED:
+ default:
+ return "MMAPOK";
+ }
+}
+
+static const char* audioFormatToString(aaudio_format_t format) {
+ switch (format) {
+ case AAUDIO_FORMAT_UNSPECIFIED: return "UNSP";
+ case AAUDIO_FORMAT_PCM_I16: return "I16";
+ case AAUDIO_FORMAT_PCM_FLOAT: return "FLT";
+ default:
+ return "BAD";
+ }
+}
+
static std::string getTestName(const ::testing::TestParamInfo<CbTestParams>& info) {
- return std::string() + sharingModeToString(std::get<PARAM_SHARING_MODE>(info.param)) +
- "__" + std::to_string(std::get<PARAM_FRAMES_PER_CB>(info.param)) +
- "__" + performanceModeToString(std::get<PARAM_PERF_MODE>(info.param));
+ return std::string()
+ + sharingModeToString(std::get<PARAM_SHARING_MODE>(info.param))
+ + "__" + std::to_string(std::get<PARAM_FRAMES_PER_CB>(info.param))
+ + "__" + performanceModeToString(std::get<PARAM_PERF_MODE>(info.param))
+ + "__" + allowMMapToString(std::get<PARAM_ALLOW_MMAP>(info.param))
+ + "__" + audioFormatToString(std::get<PARAM_AUDIO_FORMAT>(info.param))
+ ;
}
template<typename T>
@@ -143,11 +174,15 @@
}
void AAudioInputStreamCallbackTest::SetUp() {
+ aaudio_policy_t originalPolicy = AAUDIO_POLICY_AUTO;
+
mSetupSuccesful = false;
if (!deviceSupportsFeature(FEATURE_RECORDING)) return;
mHelper.reset(new InputStreamBuilderHelper(
std::get<PARAM_SHARING_MODE>(GetParam()),
- std::get<PARAM_PERF_MODE>(GetParam())));
+ std::get<PARAM_PERF_MODE>(GetParam()),
+ std::get<PARAM_AUDIO_FORMAT>(GetParam()))
+ );
mHelper->initBuilder();
int32_t framesPerDataCallback = std::get<PARAM_FRAMES_PER_CB>(GetParam());
@@ -158,7 +193,23 @@
AAudioStreamBuilder_setFramesPerDataCallback(builder(), framesPerDataCallback);
}
+ // Turn off MMap if requested.
+ int allowMMap = std::get<PARAM_ALLOW_MMAP>(GetParam()) == MMAP_ALLOWED;
+ if (AAudioExtensions::getInstance().isMMapSupported()) {
+ originalPolicy = AAudioExtensions::getInstance().getMMapPolicy();
+ AAudioExtensions::getInstance().setMMapEnabled(allowMMap);
+ }
+
mHelper->createAndVerifyStream(&mSetupSuccesful);
+
+ // Restore policy for next test.
+ if (AAudioExtensions::getInstance().isMMapSupported()) {
+ AAudioExtensions::getInstance().setMMapPolicy(originalPolicy);
+ }
+ if (!allowMMap) {
+ ASSERT_FALSE(AAudioExtensions::getInstance().isMMapUsed(mHelper->stream()));
+ }
+
}
// Test Reading from an AAudioStream using a Callback
@@ -166,12 +217,12 @@
if (!mSetupSuccesful) return;
const int32_t framesPerDataCallback = std::get<PARAM_FRAMES_PER_CB>(GetParam());
- const int32_t actualFramesPerDataCallback = AAudioStream_getFramesPerDataCallback(stream());
+ const int32_t streamFramesPerDataCallback = AAudioStream_getFramesPerDataCallback(stream());
if (framesPerDataCallback != AAUDIO_UNSPECIFIED) {
- ASSERT_EQ(framesPerDataCallback, actualFramesPerDataCallback);
+ ASSERT_EQ(framesPerDataCallback, streamFramesPerDataCallback);
}
- mCbData->reset(actualFramesPerDataCallback);
+ mCbData->reset(streamFramesPerDataCallback);
mHelper->startStream();
// See b/62090113. For legacy path, the device is only known after
@@ -189,8 +240,8 @@
sleep(1);
EXPECT_EQ(oldCallbackCount, mCbData->callbackCount); // expect not advancing
- if (framesPerDataCallback != AAUDIO_UNSPECIFIED) {
- ASSERT_EQ(framesPerDataCallback, mCbData->actualFramesPerCallback);
+ if (streamFramesPerDataCallback != AAUDIO_UNSPECIFIED) {
+ ASSERT_EQ(streamFramesPerDataCallback, mCbData->actualFramesPerCallback);
}
ASSERT_EQ(AAUDIO_OK, mCbData->callbackError);
@@ -201,16 +252,42 @@
std::make_tuple(
AAUDIO_SHARING_MODE_SHARED,
AAUDIO_UNSPECIFIED,
- AAUDIO_PERFORMANCE_MODE_NONE),
- // cb buffer size: arbitrary prime number < 192
- std::make_tuple(AAUDIO_SHARING_MODE_SHARED, 109, AAUDIO_PERFORMANCE_MODE_NONE),
+ AAUDIO_PERFORMANCE_MODE_NONE,
+ MMAP_ALLOWED,
+ AAUDIO_FORMAT_UNSPECIFIED),
+ // cb buffer size: arbitrary prime number < 96
+ std::make_tuple(AAUDIO_SHARING_MODE_SHARED, 67,
+ AAUDIO_PERFORMANCE_MODE_NONE, MMAP_ALLOWED,
+ AAUDIO_FORMAT_UNSPECIFIED),
+ std::make_tuple(AAUDIO_SHARING_MODE_SHARED, 67,
+ AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, MMAP_ALLOWED,
+ AAUDIO_FORMAT_UNSPECIFIED),
+ std::make_tuple(AAUDIO_SHARING_MODE_EXCLUSIVE, 67,
+ AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, MMAP_ALLOWED,
+ AAUDIO_FORMAT_UNSPECIFIED),
+ std::make_tuple(AAUDIO_SHARING_MODE_SHARED, 67,
+ AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, MMAP_NOT_ALLOWED,
+ AAUDIO_FORMAT_PCM_I16),
+ std::make_tuple(AAUDIO_SHARING_MODE_SHARED, 67,
+ AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, MMAP_NOT_ALLOWED,
+ AAUDIO_FORMAT_PCM_FLOAT),
// cb buffer size: arbitrary prime number > 192
- std::make_tuple(AAUDIO_SHARING_MODE_SHARED, 223, AAUDIO_PERFORMANCE_MODE_NONE),
+ std::make_tuple(AAUDIO_SHARING_MODE_SHARED, 223,
+ AAUDIO_PERFORMANCE_MODE_NONE, MMAP_ALLOWED,
+ AAUDIO_FORMAT_UNSPECIFIED),
// Recording in POWER_SAVING mode isn't supported, b/62291775.
std::make_tuple(
AAUDIO_SHARING_MODE_SHARED,
AAUDIO_UNSPECIFIED,
- AAUDIO_PERFORMANCE_MODE_LOW_LATENCY)),
+ AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
+ MMAP_ALLOWED,
+ AAUDIO_FORMAT_UNSPECIFIED),
+ std::make_tuple(
+ AAUDIO_SHARING_MODE_EXCLUSIVE,
+ AAUDIO_UNSPECIFIED,
+ AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
+ MMAP_ALLOWED,
+ AAUDIO_FORMAT_UNSPECIFIED)),
&getTestName);
@@ -224,7 +301,10 @@
// Callback function that fills the audio output buffer.
aaudio_data_callback_result_t AAudioOutputStreamCallbackTest::MyDataCallbackProc(
- AAudioStream *stream, void *userData, void *audioData, int32_t numFrames) {
+ AAudioStream *stream,
+ void *userData,
+ void *audioData,
+ int32_t numFrames) {
int32_t channelCount = AAudioStream_getChannelCount(stream);
int32_t numSamples = channelCount * numFrames;
if (AAudioStream_getFormat(stream) == AAUDIO_FORMAT_PCM_I16) {
@@ -247,7 +327,9 @@
if (!deviceSupportsFeature(FEATURE_PLAYBACK)) return;
mHelper.reset(new OutputStreamBuilderHelper(
std::get<PARAM_SHARING_MODE>(GetParam()),
- std::get<PARAM_PERF_MODE>(GetParam())));
+ std::get<PARAM_PERF_MODE>(GetParam()),
+ std::get<PARAM_AUDIO_FORMAT>(GetParam()))
+ );
mHelper->initBuilder();
int32_t framesPerDataCallback = std::get<PARAM_FRAMES_PER_CB>(GetParam());
@@ -259,6 +341,7 @@
}
mHelper->createAndVerifyStream(&mSetupSuccesful);
+
}
// Test Writing to an AAudioStream using a Callback
@@ -266,15 +349,15 @@
if (!mSetupSuccesful) return;
const int32_t framesPerDataCallback = std::get<PARAM_FRAMES_PER_CB>(GetParam());
- const int32_t actualFramesPerDataCallback = AAudioStream_getFramesPerDataCallback(stream());
+ const int32_t streamFramesPerDataCallback = AAudioStream_getFramesPerDataCallback(stream());
if (framesPerDataCallback != AAUDIO_UNSPECIFIED) {
- ASSERT_EQ(framesPerDataCallback, actualFramesPerDataCallback);
+ ASSERT_EQ(framesPerDataCallback, streamFramesPerDataCallback);
}
// Start/stop more than once to see if it fails after the first time.
// Write some data and measure the rate to see if the timing is OK.
for (int loopIndex = 0; loopIndex < 2; loopIndex++) {
- mCbData->reset(actualFramesPerDataCallback);
+ mCbData->reset(streamFramesPerDataCallback);
mHelper->startStream();
// See b/62090113. For legacy path, the device is only known after
@@ -297,8 +380,8 @@
sleep(1);
EXPECT_EQ(oldCallbackCount, mCbData->callbackCount); // expect not advancing
- if (framesPerDataCallback != AAUDIO_UNSPECIFIED) {
- ASSERT_EQ(framesPerDataCallback, mCbData->actualFramesPerCallback);
+ if (streamFramesPerDataCallback != AAUDIO_UNSPECIFIED) {
+ ASSERT_EQ(streamFramesPerDataCallback, mCbData->actualFramesPerCallback);
}
EXPECT_GE(mCbData->minLatency, 1); // Absurdly low
@@ -318,17 +401,39 @@
std::make_tuple(
AAUDIO_SHARING_MODE_SHARED,
AAUDIO_UNSPECIFIED,
- AAUDIO_PERFORMANCE_MODE_NONE),
- // cb buffer size: arbitrary prime number < 192
- std::make_tuple(AAUDIO_SHARING_MODE_SHARED, 109, AAUDIO_PERFORMANCE_MODE_NONE),
+ AAUDIO_PERFORMANCE_MODE_NONE,
+ MMAP_ALLOWED,
+ AAUDIO_FORMAT_UNSPECIFIED),
+ // cb buffer size: arbitrary prime number < 96
+ std::make_tuple(AAUDIO_SHARING_MODE_SHARED, 67, AAUDIO_PERFORMANCE_MODE_NONE, MMAP_ALLOWED,
+ AAUDIO_FORMAT_UNSPECIFIED),
+ std::make_tuple(AAUDIO_SHARING_MODE_SHARED, 67, AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, MMAP_ALLOWED,
+ AAUDIO_FORMAT_UNSPECIFIED),
+ std::make_tuple(AAUDIO_SHARING_MODE_EXCLUSIVE, 67, AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, MMAP_ALLOWED,
+ AAUDIO_FORMAT_UNSPECIFIED),
+ std::make_tuple(AAUDIO_SHARING_MODE_SHARED, 67, AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, MMAP_NOT_ALLOWED,
+ AAUDIO_FORMAT_PCM_I16),
+ std::make_tuple(AAUDIO_SHARING_MODE_SHARED, 67, AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, MMAP_NOT_ALLOWED,
+ AAUDIO_FORMAT_PCM_FLOAT),
// cb buffer size: arbitrary prime number > 192
- std::make_tuple(AAUDIO_SHARING_MODE_SHARED, 223, AAUDIO_PERFORMANCE_MODE_NONE),
+ std::make_tuple(AAUDIO_SHARING_MODE_SHARED, 223, AAUDIO_PERFORMANCE_MODE_NONE, MMAP_ALLOWED,
+ AAUDIO_FORMAT_UNSPECIFIED),
std::make_tuple(
AAUDIO_SHARING_MODE_SHARED,
AAUDIO_UNSPECIFIED,
- AAUDIO_PERFORMANCE_MODE_POWER_SAVING),
+ AAUDIO_PERFORMANCE_MODE_POWER_SAVING,
+ MMAP_ALLOWED,
+ AAUDIO_FORMAT_UNSPECIFIED),
std::make_tuple(
AAUDIO_SHARING_MODE_SHARED,
AAUDIO_UNSPECIFIED,
- AAUDIO_PERFORMANCE_MODE_LOW_LATENCY)),
+ AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
+ MMAP_ALLOWED,
+ AAUDIO_FORMAT_UNSPECIFIED),
+ std::make_tuple(
+ AAUDIO_SHARING_MODE_EXCLUSIVE,
+ AAUDIO_UNSPECIFIED,
+ AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
+ MMAP_ALLOWED,
+ AAUDIO_FORMAT_UNSPECIFIED)),
&getTestName);
diff --git a/tests/tests/nativemedia/aaudio/jni/test_aaudio_mmap.cpp b/tests/tests/nativemedia/aaudio/jni/test_aaudio_mmap.cpp
index fd67644..f08e1df 100644
--- a/tests/tests/nativemedia/aaudio/jni/test_aaudio_mmap.cpp
+++ b/tests/tests/nativemedia/aaudio/jni/test_aaudio_mmap.cpp
@@ -28,43 +28,9 @@
#include "test_aaudio.h"
#include "utils.h"
-/* These definitions are from aaudio/AAudioTesting.h */
-enum {
- AAUDIO_POLICY_NEVER = 1,
- AAUDIO_POLICY_AUTO,
- AAUDIO_POLICY_ALWAYS
-};
-typedef int32_t aaudio_policy_t;
-
-static aaudio_result_t (*s_setMMapPolicy)(aaudio_policy_t policy) = nullptr;
-static aaudio_policy_t (*s_getMMapPolicy)() = nullptr;
-
-/**
- * @return integer value or -1 on error
- */
-static int getSystemPropertyInt(const char *propName, int defaultValue) {
- char valueText[PROP_VALUE_MAX] = {'\0'};
- if (__system_property_get(propName, valueText) <= 0) {
- return defaultValue;
- }
- char *endptr = nullptr;
- int value = strtol(valueText, &endptr, 10);
- if (endptr == nullptr || *endptr != '\0') {
- __android_log_print(ANDROID_LOG_ERROR, LOG_TAG,
- "getSystemPropertyInt() - non-integer value = %s", valueText);
- return -1;
- } else {
- return value;
- }
-}
-
-static int getSystemMMapPolicy() {
- return getSystemPropertyInt("aaudio.mmap_policy", AAUDIO_UNSPECIFIED);
-}
-
// Test allowed values of policy.
TEST(test_aaudio_mmap, testCurrentPolicy) {
- aaudio_policy_t policy = getSystemMMapPolicy();
+ aaudio_policy_t policy = (aaudio_policy_t) AAudioExtensions::getMMapPolicyProperty();
// It must be one of these defined enum values.
EXPECT_TRUE(policy == AAUDIO_UNSPECIFIED
@@ -78,19 +44,6 @@
EXPECT_NE(AAUDIO_POLICY_ALWAYS, policy);
}
-// Link to test functions in shared library.
-static void loadMMapTestFunctions() {
- if (s_setMMapPolicy != nullptr) return; // already loaded
-
- void *handle;
- handle = dlopen("libaaudio.so", RTLD_NOW);
- EXPECT_NE(nullptr, handle);
- s_setMMapPolicy = (int (*)(int)) dlsym(handle, "AAudio_setMMapPolicy");
- EXPECT_NE(nullptr, s_setMMapPolicy);
- s_getMMapPolicy = (int (*)()) dlsym(handle, "AAudio_getMMapPolicy");
- EXPECT_NE(nullptr, s_getMMapPolicy);
-}
-
// An application should not be able to create an MMAP stream
// by enabling MMAP when the system "aaudio.mmap_policy" says not to.
TEST(test_aaudio_mmap, testElevatingMMapPolicy) {
@@ -98,12 +51,8 @@
AAudioStreamBuilder *builder = nullptr;
AAudioStream *stream = nullptr;
- aaudio_policy_t policy = getSystemMMapPolicy();
- bool mmapAllowed = (policy == AAUDIO_POLICY_AUTO || policy == AAUDIO_POLICY_ALWAYS);
+ bool mmapAllowed = AAudioExtensions::getInstance().isMMapSupported();
if (mmapAllowed) return;
- // Try to enable MMAP when not allowed.
-
- loadMMapTestFunctions();
EXPECT_EQ(AAUDIO_OK, AAudio_createStreamBuilder(&builder));
@@ -111,10 +60,10 @@
AAudioStreamBuilder_setPerformanceMode(builder, AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
// Force policy to create an MMAP stream or fail.
- aaudio_policy_t originalPolicy = s_getMMapPolicy();
- s_setMMapPolicy(AAUDIO_POLICY_ALWAYS); // try to enable MMAP mode
+ aaudio_policy_t originalPolicy = AAudioExtensions::getInstance().getMMapPolicy();
+ AAudioExtensions::getInstance().setMMapPolicy(AAUDIO_POLICY_ALWAYS); // try to enable MMAP mode
result = AAudioStreamBuilder_openStream(builder, &stream);
- s_setMMapPolicy(originalPolicy);
+ AAudioExtensions::getInstance().setMMapPolicy(originalPolicy);
// openStream should have failed.
EXPECT_NE(AAUDIO_OK, result);
diff --git a/tests/tests/nativemedia/aaudio/jni/utils.cpp b/tests/tests/nativemedia/aaudio/jni/utils.cpp
index d843614..a9ed984 100644
--- a/tests/tests/nativemedia/aaudio/jni/utils.cpp
+++ b/tests/tests/nativemedia/aaudio/jni/utils.cpp
@@ -149,7 +149,9 @@
ASSERT_LE(mActual.channelCount, 16); // TODO what is min/max?
mActual.dataFormat = AAudioStream_getFormat(mStream);
- ASSERT_EQ(AAUDIO_FORMAT_PCM_I16, mActual.dataFormat);
+ if (mRequested.dataFormat != AAUDIO_FORMAT_UNSPECIFIED) {
+ ASSERT_EQ(mRequested.dataFormat, mActual.dataFormat);
+ }
mActual.perfMode = AAudioStream_getPerformanceMode(mStream);
if (mRequested.perfMode != AAUDIO_PERFORMANCE_MODE_NONE
@@ -192,17 +194,20 @@
ASSERT_EQ(toState, state);
}
-
InputStreamBuilderHelper::InputStreamBuilderHelper(
- aaudio_sharing_mode_t requestedSharingMode, aaudio_performance_mode_t requestedPerfMode)
+ aaudio_sharing_mode_t requestedSharingMode,
+ aaudio_performance_mode_t requestedPerfMode,
+ aaudio_format_t requestedFormat)
: StreamBuilderHelper{AAUDIO_DIRECTION_INPUT,
- 48000, 1, AAUDIO_FORMAT_PCM_I16, requestedSharingMode, requestedPerfMode} {}
+ 48000, 1, requestedFormat, requestedSharingMode, requestedPerfMode} {}
OutputStreamBuilderHelper::OutputStreamBuilderHelper(
- aaudio_sharing_mode_t requestedSharingMode, aaudio_performance_mode_t requestedPerfMode)
+ aaudio_sharing_mode_t requestedSharingMode,
+ aaudio_performance_mode_t requestedPerfMode,
+ aaudio_format_t requestedFormat)
: StreamBuilderHelper{AAUDIO_DIRECTION_OUTPUT,
- 48000, 2, AAUDIO_FORMAT_PCM_I16, requestedSharingMode, requestedPerfMode} {}
+ 48000, 2, requestedFormat, requestedSharingMode, requestedPerfMode} {}
void OutputStreamBuilderHelper::initBuilder() {
StreamBuilderHelper::initBuilder();
@@ -215,3 +220,51 @@
ASSERT_GE(AAudioStream_getBufferCapacityInFrames(mStream), kBufferCapacityFrames);
}
}
+
+AAudioExtensions::AAudioExtensions()
+ : mMMapSupported(isPolicyEnabled(getMMapPolicyProperty()))
+ , mMMapExclusiveSupported(isPolicyEnabled(getIntegerProperty(
+ "aaudio.mmap_exclusive_policy", AAUDIO_POLICY_UNSPECIFIED))) {
+ loadLibrary();
+}
+
+int AAudioExtensions::getIntegerProperty(const char *name, int defaultValue) {
+ int result = defaultValue;
+ char valueText[PROP_VALUE_MAX] = {0};
+ if (__system_property_get(name, valueText) != 0) {
+ result = atoi(valueText);
+ }
+ return result;
+}
+
+// This should only be called once from the constructor.
+bool AAudioExtensions::loadLibrary() {
+ mLibHandle = dlopen(LIB_AAUDIO_NAME, 0);
+ if (mLibHandle == nullptr) {
+ //LOGI("%s() could not find " LIB_AAUDIO_NAME, __func__);
+ return false;
+ }
+
+ mAAudioStream_isMMap = (bool (*)(AAudioStream *stream))
+ dlsym(mLibHandle, FUNCTION_IS_MMAP);
+ if (mAAudioStream_isMMap == nullptr) {
+ //LOGI("%s() could not find " FUNCTION_IS_MMAP, __func__);
+ return false;
+ }
+
+ mAAudio_setMMapPolicy = (int32_t (*)(aaudio_policy_t policy))
+ dlsym(mLibHandle, FUNCTION_SET_MMAP_POLICY);
+ if (mAAudio_setMMapPolicy == nullptr) {
+ //LOGI("%s() could not find " FUNCTION_SET_MMAP_POLICY, __func__);
+ return false;
+ }
+
+ mAAudio_getMMapPolicy = (aaudio_policy_t (*)())
+ dlsym(mLibHandle, FUNCTION_GET_MMAP_POLICY);
+ if (mAAudio_getMMapPolicy == nullptr) {
+ //LOGI("%s() could not find " FUNCTION_GET_MMAP_POLICY, __func__);
+ return false;
+ }
+ mFunctionsLoaded = true;
+ return mFunctionsLoaded;
+}
\ No newline at end of file
diff --git a/tests/tests/nativemedia/aaudio/jni/utils.h b/tests/tests/nativemedia/aaudio/jni/utils.h
index 4211410..f14e04d 100644
--- a/tests/tests/nativemedia/aaudio/jni/utils.h
+++ b/tests/tests/nativemedia/aaudio/jni/utils.h
@@ -16,7 +16,9 @@
#ifndef CTS_MEDIA_TEST_AAUDIO_UTILS_H
#define CTS_MEDIA_TEST_AAUDIO_UTILS_H
+#include <dlfcn.h>
#include <map>
+#include <sys/system_properties.h>
#include <aaudio/AAudio.h>
@@ -88,14 +90,16 @@
public:
InputStreamBuilderHelper(
aaudio_sharing_mode_t requestedSharingMode,
- aaudio_performance_mode_t requestedPerfMode);
+ aaudio_performance_mode_t requestedPerfMode,
+ aaudio_format_t requestedFormat = AAUDIO_FORMAT_PCM_FLOAT);
};
class OutputStreamBuilderHelper : public StreamBuilderHelper {
public:
OutputStreamBuilderHelper(
aaudio_sharing_mode_t requestedSharingMode,
- aaudio_performance_mode_t requestedPerfMode);
+ aaudio_performance_mode_t requestedPerfMode,
+ aaudio_format_t requestedFormat = AAUDIO_FORMAT_PCM_I16);
void initBuilder();
void createAndVerifyStream(bool *success);
@@ -103,4 +107,91 @@
const int32_t kBufferCapacityFrames = 2000;
};
+
+#define LIB_AAUDIO_NAME "libaaudio.so"
+#define FUNCTION_IS_MMAP "AAudioStream_isMMapUsed"
+#define FUNCTION_SET_MMAP_POLICY "AAudio_setMMapPolicy"
+#define FUNCTION_GET_MMAP_POLICY "AAudio_getMMapPolicy"
+
+enum {
+ AAUDIO_POLICY_UNSPECIFIED = 0,
+/* These definitions are from aaudio/AAudioTesting.h */
+ AAUDIO_POLICY_NEVER = 1,
+ AAUDIO_POLICY_AUTO = 2,
+ AAUDIO_POLICY_ALWAYS = 3
+};
+typedef int32_t aaudio_policy_t;
+
+/**
+ * Call some AAudio test routines that are not part of the normal API.
+ */
+class AAudioExtensions {
+public:
+ AAudioExtensions();
+
+ static bool isPolicyEnabled(int32_t policy) {
+ return (policy == AAUDIO_POLICY_AUTO || policy == AAUDIO_POLICY_ALWAYS);
+ }
+
+ static AAudioExtensions &getInstance() {
+ static AAudioExtensions instance;
+ return instance;
+ }
+
+ static int getMMapPolicyProperty() {
+ return getIntegerProperty("aaudio.mmap_policy", AAUDIO_POLICY_UNSPECIFIED);
+ }
+
+ aaudio_policy_t getMMapPolicy() {
+ if (!mFunctionsLoaded) return -1;
+ return mAAudio_getMMapPolicy();
+ }
+
+ int32_t setMMapPolicy(aaudio_policy_t policy) {
+ if (!mFunctionsLoaded) return -1;
+ return mAAudio_setMMapPolicy(policy);
+ }
+
+ bool isMMapUsed(AAudioStream *aaudioStream) {
+ if (!mFunctionsLoaded) return false;
+ return mAAudioStream_isMMap(aaudioStream);
+ }
+
+ int32_t setMMapEnabled(bool enabled) {
+ return setMMapPolicy(enabled ? AAUDIO_POLICY_AUTO : AAUDIO_POLICY_NEVER);
+ }
+
+ bool isMMapEnabled() {
+ return isPolicyEnabled(mAAudio_getMMapPolicy());
+ }
+
+ bool isMMapSupported() const {
+ return mMMapSupported;
+ }
+
+ bool isMMapExclusiveSupported() const {
+ return mMMapExclusiveSupported;
+ }
+
+private:
+
+ static int getIntegerProperty(const char *name, int defaultValue);
+
+ /**
+ * Load some AAudio test functions.
+ * This should only be called once from the constructor.
+ * @return true if it succeeds
+ */
+ bool loadLibrary();
+
+ bool mFunctionsLoaded = false;
+ void *mLibHandle = nullptr;
+ bool (*mAAudioStream_isMMap)(AAudioStream *stream) = nullptr;
+ int32_t (*mAAudio_setMMapPolicy)(aaudio_policy_t policy) = nullptr;
+ aaudio_policy_t (*mAAudio_getMMapPolicy)() = nullptr;
+
+ const bool mMMapSupported;
+ const bool mMMapExclusiveSupported;
+};
+
#endif // CTS_MEDIA_TEST_AAUDIO_UTILS_H
diff --git a/tests/tests/ndef/OWNERS b/tests/tests/ndef/OWNERS
index 8ffbd10..d92b2ab 100644
--- a/tests/tests/ndef/OWNERS
+++ b/tests/tests/ndef/OWNERS
@@ -1,3 +1,5 @@
# Bug component: 48448
-rmojumder@google.com
+alisher@google.com
+jackcwyu@google.com
+georgekgchang@google.com
zachoverflow@google.com
diff --git a/tests/tests/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java b/tests/tests/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java
index e4c4b00..45b9d97 100644
--- a/tests/tests/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java
+++ b/tests/tests/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java
@@ -16,17 +16,15 @@
package android.net.wifi.cts;
-import android.content.Context;
+import static com.google.common.truth.Truth.assertThat;
+
import android.content.pm.PackageManager;
import android.net.wifi.WifiEnterpriseConfig;
import android.net.wifi.WifiEnterpriseConfig.Eap;
import android.net.wifi.WifiEnterpriseConfig.Phase2;
-import android.net.wifi.WifiManager;
import android.platform.test.annotations.AppModeFull;
import android.test.AndroidTestCase;
-import com.android.compatibility.common.util.SystemUtil;
-
import java.io.ByteArrayInputStream;
import java.security.KeyFactory;
import java.security.PrivateKey;
@@ -36,9 +34,7 @@
@AppModeFull(reason = "Cannot get WifiManager in instant app mode")
public class WifiEnterpriseConfigTest extends AndroidTestCase {
- private WifiManager mWifiManager;
- private static final String SSID = "\"TestSSID\"";
private static final String IDENTITY = "identity";
private static final String PASSWORD = "password";
private static final String SUBJECT_MATCH = "subjectmatch";
@@ -47,7 +43,11 @@
private static final String PLMN = "plmn";
private static final String REALM = "realm";
private static final String ANON_IDENTITY = "anonidentity";
- private static final int ENABLE_DELAY = 10000;
+ private static final String CERTIFICATE_ALIAS1 = "certificatealias1";
+ private static final String CERTIFICATE_ALIAS2 = "certificatealias2";
+ private static final String CA_PATH = "capath";
+ private static final String CLIENT_CERTIFICATE_ALIAS = "clientcertificatealias";
+ private static final String WAPI_CERT_SUITE = "wapicertsuite";
/*
* The keys and certificates below are generated with:
@@ -684,22 +684,6 @@
PackageManager.FEATURE_WIFI);
}
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- if(!hasWifi()) {
- return;
- }
- mWifiManager = (WifiManager) mContext
- .getSystemService(Context.WIFI_SERVICE);
- assertNotNull(mWifiManager);
- SystemUtil.runShellCommand("svc wifi enable");
- Thread.sleep(ENABLE_DELAY);
- if (hasWifi()) {
- assertTrue(mWifiManager.isWifiEnabled());
- }
- }
-
public void testSettersAndGetters() throws Exception {
if (!hasWifi()) {
return;
@@ -766,6 +750,7 @@
assertTrue(testClientCertChain.length == 2);
assertTrue(testClientCertChain[0] == testClientCert);
assertTrue(testClientCertChain[1] == cert1);
+ assertSame(clientKey, config.getClientPrivateKey());
config.setSubjectMatch(SUBJECT_MATCH);
assertTrue(config.getSubjectMatch().equals(SUBJECT_MATCH));
@@ -793,4 +778,122 @@
assertTrue(stringRepresentation.contains(identity));
assertFalse(stringRepresentation.contains(password));
}
+
+ public void testGetSetCaCertificateAliases() {
+ if (!hasWifi()) {
+ return;
+ }
+ WifiEnterpriseConfig config = new WifiEnterpriseConfig();
+
+ config.setCaCertificateAliases(null);
+ assertThat(config.getCaCertificateAliases()).isNull();
+
+ config.setCaCertificateAliases(new String[]{CERTIFICATE_ALIAS1});
+ assertThat(config.getCaCertificateAliases()).isEqualTo(new String[]{CERTIFICATE_ALIAS1});
+
+ config.setCaCertificateAliases(new String[]{CERTIFICATE_ALIAS1, CERTIFICATE_ALIAS2});
+ assertThat(config.getCaCertificateAliases())
+ .isEqualTo(new String[]{CERTIFICATE_ALIAS1, CERTIFICATE_ALIAS2});
+ }
+
+ public void testGetSetCaPath() {
+ if (!hasWifi()) {
+ return;
+ }
+ WifiEnterpriseConfig config = new WifiEnterpriseConfig();
+
+ config.setCaPath("");
+ assertThat(config.getCaPath()).isEmpty();
+
+ config.setCaPath(CA_PATH);
+ assertThat(config.getCaPath()).isEqualTo(CA_PATH);
+ }
+
+ public void testGetSetClientCertificateAlias() {
+ if (!hasWifi()) {
+ return;
+ }
+ WifiEnterpriseConfig config = new WifiEnterpriseConfig();
+
+ config.setClientCertificateAlias("");
+ assertThat(config.getClientCertificateAlias()).isEmpty();
+
+ config.setClientCertificateAlias(CLIENT_CERTIFICATE_ALIAS);
+ assertThat(config.getClientCertificateAlias()).isEqualTo(CLIENT_CERTIFICATE_ALIAS);
+ }
+
+ public void testGetSetOcsp() {
+ if (!hasWifi()) {
+ return;
+ }
+ WifiEnterpriseConfig config = new WifiEnterpriseConfig();
+
+ config.setOcsp(WifiEnterpriseConfig.OCSP_NONE);
+ assertThat(config.getOcsp()).isEqualTo(WifiEnterpriseConfig.OCSP_NONE);
+
+ config.setOcsp(WifiEnterpriseConfig.OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS);
+ assertThat(config.getOcsp())
+ .isEqualTo(WifiEnterpriseConfig.OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS);
+
+ try {
+ config.setOcsp(-1);
+ fail("WifiEnterpriseConfig.setOcsp(-1) did not throw an IllegalArgumentException!");
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public void testGetSetWapiCertSuite() {
+ if (!hasWifi()) {
+ return;
+ }
+ WifiEnterpriseConfig config = new WifiEnterpriseConfig();
+
+ config.setWapiCertSuite("");
+ assertThat(config.getWapiCertSuite()).isEmpty();
+
+ config.setWapiCertSuite(WAPI_CERT_SUITE);
+ assertThat(config.getWapiCertSuite()).isEqualTo(WAPI_CERT_SUITE);
+ }
+
+ public void testIsAuthenticationSimBased() {
+ if (!hasWifi()) {
+ return;
+ }
+ WifiEnterpriseConfig config = new WifiEnterpriseConfig();
+
+ config.setEapMethod(Eap.AKA);
+ assertThat(config.isAuthenticationSimBased()).isTrue();
+
+ config.setEapMethod(Eap.PWD);
+ assertThat(config.isAuthenticationSimBased()).isFalse();
+
+ config.setEapMethod(Eap.PEAP);
+ config.setPhase2Method(Phase2.SIM);
+ assertThat(config.isAuthenticationSimBased()).isTrue();
+
+ config.setEapMethod(Eap.PEAP);
+ config.setPhase2Method(Phase2.NONE);
+ assertThat(config.isAuthenticationSimBased()).isFalse();
+ }
+
+ public void testCopyConstructor() {
+ if (!hasWifi()) {
+ return;
+ }
+ WifiEnterpriseConfig config = new WifiEnterpriseConfig();
+ config.setEapMethod(Eap.WAPI_CERT);
+ config.setWapiCertSuite(WAPI_CERT_SUITE);
+ config.setOcsp(WifiEnterpriseConfig.OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS);
+ config.setCaPath(CA_PATH);
+ config.setPassword(PASSWORD);
+ config.setRealm(REALM);
+
+ WifiEnterpriseConfig copy = new WifiEnterpriseConfig(config);
+ assertThat(copy.getEapMethod()).isEqualTo(Eap.WAPI_CERT);
+ assertThat(copy.getWapiCertSuite()).isEqualTo(WAPI_CERT_SUITE);
+ assertThat(copy.getOcsp())
+ .isEqualTo(WifiEnterpriseConfig.OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS);
+ assertThat(copy.getCaPath()).isEqualTo(CA_PATH);
+ assertThat(copy.getPassword()).isEqualTo(PASSWORD);
+ assertThat(copy.getRealm()).isEqualTo(REALM);
+ }
}
diff --git a/tests/tests/net/src/android/net/wifi/cts/WifiInfoTest.java b/tests/tests/net/src/android/net/wifi/cts/WifiInfoTest.java
index d943231..6f94fea 100644
--- a/tests/tests/net/src/android/net/wifi/cts/WifiInfoTest.java
+++ b/tests/tests/net/src/android/net/wifi/cts/WifiInfoTest.java
@@ -16,11 +16,13 @@
package android.net.wifi.cts;
+import static com.google.common.truth.Truth.assertThat;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.net.wifi.ScanResult;
import android.net.wifi.SupplicantState;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
@@ -78,13 +80,13 @@
mContext.registerReceiver(mReceiver, mIntentFilter);
mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE);
- assertNotNull(mWifiManager);
+ assertThat(mWifiManager).isNotNull();
mWifiLock = mWifiManager.createWifiLock(TAG);
mWifiLock.acquire();
if (!mWifiManager.isWifiEnabled())
setWifiEnabled(true);
Thread.sleep(DURATION);
- assertTrue(mWifiManager.isWifiEnabled());
+ assertThat(mWifiManager.isWifiEnabled()).isTrue();
mMySync.expectedState = STATE_NULL;
}
@@ -123,31 +125,19 @@
// skip the test if WiFi is not supported
return;
}
+
+ // wait for Wifi to be connected
+ PollingCheck.check(
+ "Wifi not connected - Please ensure there is a saved network in range of this "
+ + "device",
+ 20000,
+ () -> mWifiManager.getConnectionInfo().getNetworkId() != -1);
+
// this test case should in Wifi environment
WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
- assertNotNull(wifiInfo);
- assertNotNull(wifiInfo.toString());
- SupplicantState.isValidState(wifiInfo.getSupplicantState());
- WifiInfo.getDetailedStateOf(SupplicantState.DISCONNECTED);
- String ssid = wifiInfo.getSSID();
- if (!ssid.startsWith("0x") && !ssid.equals(WifiManager.UNKNOWN_SSID)) {
- // Non-hex string should be quoted
- assertTrue(ssid.charAt(0) == '"');
- assertTrue(ssid.charAt(ssid.length() - 1) == '"');
- }
+ testWifiInfoPropertiesWhileConnected(wifiInfo);
- wifiInfo.getBSSID();
- wifiInfo.getFrequency();
- wifiInfo.getIpAddress();
- wifiInfo.getLinkSpeed();
- wifiInfo.getPasspointFqdn();
- wifiInfo.getPasspointProviderFriendlyName();
- wifiInfo.getTxLinkSpeedMbps();
- wifiInfo.getRxLinkSpeedMbps();
- wifiInfo.getRssi();
- wifiInfo.getHiddenSSID();
- wifiInfo.getMacAddress();
setWifiEnabled(false);
PollingCheck.check("getNetworkId not -1", 20000, new Callable<Boolean>() {
@@ -166,4 +156,55 @@
});
}
+ private void testWifiInfoPropertiesWhileConnected(WifiInfo wifiInfo) {
+ assertThat(wifiInfo).isNotNull();
+ assertThat(wifiInfo.toString()).isNotNull();
+ SupplicantState.isValidState(wifiInfo.getSupplicantState());
+ WifiInfo.getDetailedStateOf(SupplicantState.DISCONNECTED);
+ String ssid = wifiInfo.getSSID();
+ if (!ssid.startsWith("0x") && !ssid.equals(WifiManager.UNKNOWN_SSID)) {
+ // Non-hex string should be quoted
+ assertThat(ssid).startsWith("\"");
+ assertThat(ssid).endsWith("\"");
+ }
+
+ assertThat(wifiInfo.getBSSID()).isNotNull();
+ assertThat(wifiInfo.getFrequency()).isGreaterThan(0);
+ assertThat(wifiInfo.getMacAddress()).isNotNull();
+
+ wifiInfo.getRssi();
+ wifiInfo.getIpAddress();
+ wifiInfo.getHiddenSSID();
+ wifiInfo.getScore();
+
+ // null for saved networks
+ assertThat(wifiInfo.getRequestingPackageName()).isNull();
+ assertThat(wifiInfo.getPasspointFqdn()).isNull();
+ assertThat(wifiInfo.getPasspointProviderFriendlyName()).isNull();
+
+ // false for saved networks
+ assertThat(wifiInfo.isEphemeral()).isFalse();
+ assertThat(wifiInfo.isOsuAp()).isFalse();
+ assertThat(wifiInfo.isPasspointAp()).isFalse();
+
+ assertThat(wifiInfo.getWifiStandard()).isAnyOf(
+ ScanResult.WIFI_STANDARD_UNKNOWN,
+ ScanResult.WIFI_STANDARD_LEGACY,
+ ScanResult.WIFI_STANDARD_11N,
+ ScanResult.WIFI_STANDARD_11AC,
+ ScanResult.WIFI_STANDARD_11AX
+ );
+
+ assertThat(wifiInfo.getLostTxPacketsPerSecond()).isAtLeast(0.0);
+ assertThat(wifiInfo.getRetriedTxPacketsPerSecond()).isAtLeast(0.0);
+ assertThat(wifiInfo.getSuccessfulRxPacketsPerSecond()).isAtLeast(0.0);
+ assertThat(wifiInfo.getSuccessfulTxPacketsPerSecond()).isAtLeast(0.0);
+
+ // Can be -1 if link speed is unknown
+ assertThat(wifiInfo.getLinkSpeed()).isAtLeast(-1);
+ assertThat(wifiInfo.getTxLinkSpeedMbps()).isAtLeast(-1);
+ assertThat(wifiInfo.getRxLinkSpeedMbps()).isAtLeast(-1);
+ assertThat(wifiInfo.getMaxSupportedTxLinkSpeedMbps()).isAtLeast(-1);
+ assertThat(wifiInfo.getMaxSupportedRxLinkSpeedMbps()).isAtLeast(-1);
+ }
}
diff --git a/tests/tests/notificationlegacy/notificationlegacy20/src/android/app/notification/legacy20/cts/LegacyNotificationManager20Test.java b/tests/tests/notificationlegacy/notificationlegacy20/src/android/app/notification/legacy20/cts/LegacyNotificationManager20Test.java
index c64f07f..803f55e 100644
--- a/tests/tests/notificationlegacy/notificationlegacy20/src/android/app/notification/legacy20/cts/LegacyNotificationManager20Test.java
+++ b/tests/tests/notificationlegacy/notificationlegacy20/src/android/app/notification/legacy20/cts/LegacyNotificationManager20Test.java
@@ -16,14 +16,11 @@
package android.app.notification.legacy20.cts;
-import static android.content.pm.PackageManager.FEATURE_WATCH;
-
import static junit.framework.Assert.fail;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
-import android.app.ActivityManager;
import android.app.Instrumentation;
import android.app.Notification;
import android.app.NotificationChannel;
@@ -64,7 +61,6 @@
private PackageManager mPackageManager;
final String NOTIFICATION_CHANNEL_ID = "LegacyNotificationManagerTest";
private NotificationManager mNotificationManager;
- private ActivityManager mActivityManager;
private Context mContext;
private TestNotificationListener mListener;
@@ -78,7 +74,6 @@
Context.NOTIFICATION_SERVICE);
mNotificationManager.createNotificationChannel(new NotificationChannel(
NOTIFICATION_CHANNEL_ID, "name", NotificationManager.IMPORTANCE_DEFAULT));
- mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
mPackageManager = mContext.getPackageManager();
}
@@ -92,10 +87,6 @@
@Test
public void testNotificationListener_cancelNotifications() throws Exception {
- if (mActivityManager.isLowRamDevice() && !mPackageManager.hasSystemFeature(FEATURE_WATCH)) {
- return;
- }
-
toggleListenerAccess(TestNotificationListener.getId(),
InstrumentationRegistry.getInstrumentation(), true);
Thread.sleep(500); // wait for listener to be allowed
diff --git a/tests/tests/notificationlegacy/notificationlegacy27/src/android/app/notification/legacy/cts/ConditionProviderServiceTest.java b/tests/tests/notificationlegacy/notificationlegacy27/src/android/app/notification/legacy/cts/ConditionProviderServiceTest.java
index b999cfe..9049b3f 100644
--- a/tests/tests/notificationlegacy/notificationlegacy27/src/android/app/notification/legacy/cts/ConditionProviderServiceTest.java
+++ b/tests/tests/notificationlegacy/notificationlegacy27/src/android/app/notification/legacy/cts/ConditionProviderServiceTest.java
@@ -24,11 +24,8 @@
import static junit.framework.Assert.assertNull;
import static junit.framework.TestCase.fail;
-import static org.junit.Assume.assumeFalse;
-
import static java.lang.Thread.sleep;
-import android.app.ActivityManager;
import android.app.AutomaticZenRule;
import android.app.Instrumentation;
import android.app.NotificationManager;
@@ -62,7 +59,6 @@
private static String TAG = "CpsTest";
private NotificationManager mNm;
- private ActivityManager mActivityManager;
private Context mContext;
private ZenModeBroadcastReceiver mModeReceiver;
private IntentFilter mModeFilter;
@@ -71,9 +67,6 @@
@Before
public void setUp() throws Exception {
mContext = InstrumentationRegistry.getContext();
- mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
- assumeFalse(mActivityManager.isLowRamDevice());
-
toggleNotificationPolicyAccess(mContext.getPackageName(),
InstrumentationRegistry.getInstrumentation(), true);
LegacyConditionProviderService.requestRebind(LegacyConditionProviderService.getId());
@@ -114,10 +107,6 @@
@Test
public void testUnboundCPSMaintainsCondition_addsNewRule() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
-
// make sure service get bound
pollForConnection(SecondaryConditionProviderService.class, true);
@@ -147,10 +136,6 @@
@Test
public void testUnboundCPSMaintainsCondition_otherConditionChanges() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
-
// make sure both services get bound
pollForConnection(LegacyConditionProviderService.class, true);
pollForConnection(SecondaryConditionProviderService.class, true);
@@ -184,10 +169,6 @@
@Test
public void testUnboundCPSMaintainsCondition_otherProviderRuleChanges() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
-
// make sure both services get bound
pollForConnection(LegacyConditionProviderService.class, true);
pollForConnection(SecondaryConditionProviderService.class, true);
@@ -219,10 +200,6 @@
@Test
public void testRequestRebindWhenLostAccess() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
-
// make sure it gets bound
pollForConnection(LegacyConditionProviderService.class, true);
@@ -250,10 +227,6 @@
@Test
public void testRequestRebindWhenStillHasAccess() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
-
// make sure it gets bound
pollForConnection(LegacyConditionProviderService.class, true);
@@ -276,12 +249,6 @@
@Test
public void testMethodsExistAndDoNotThrow() throws Exception {
- // behavior is covered in cts verifier
-
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
-
// make sure it gets bound
pollForConnection(LegacyConditionProviderService.class, true);
diff --git a/tests/tests/notificationlegacy/notificationlegacy27/src/android/app/notification/legacy/cts/LegacyNotificationManagerTest.java b/tests/tests/notificationlegacy/notificationlegacy27/src/android/app/notification/legacy/cts/LegacyNotificationManagerTest.java
index f2960a6..f5606de 100644
--- a/tests/tests/notificationlegacy/notificationlegacy27/src/android/app/notification/legacy/cts/LegacyNotificationManagerTest.java
+++ b/tests/tests/notificationlegacy/notificationlegacy27/src/android/app/notification/legacy/cts/LegacyNotificationManagerTest.java
@@ -65,7 +65,6 @@
final String NOTIFICATION_CHANNEL_ID = "LegacyNotificationManagerTest";
private NotificationManager mNotificationManager;
- private ActivityManager mActivityManager;
private Context mContext;
private SecondaryNotificationListener mSecondaryListener;
@@ -82,7 +81,6 @@
Context.NOTIFICATION_SERVICE);
mNotificationManager.createNotificationChannel(new NotificationChannel(
NOTIFICATION_CHANNEL_ID, "name", NotificationManager.IMPORTANCE_DEFAULT));
- mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
}
@After
@@ -98,9 +96,6 @@
@Test
public void testPrePCannotToggleAlarmsAndMediaTest() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
toggleNotificationPolicyAccess(mContext.getPackageName(),
InstrumentationRegistry.getInstrumentation(), true);
@@ -141,9 +136,6 @@
@Test
public void testSetNotificationPolicy_preP_setOldFields() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
toggleNotificationPolicyAccess(mContext.getPackageName(),
InstrumentationRegistry.getInstrumentation(), true);
@@ -164,9 +156,6 @@
@Test
public void testSetNotificationPolicy_preP_setNewFields() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
toggleNotificationPolicyAccess(mContext.getPackageName(),
InstrumentationRegistry.getInstrumentation(), true);
@@ -187,9 +176,6 @@
@Test
public void testSuspendPackage() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
toggleListenerAccess(TestNotificationListener.getId(),
InstrumentationRegistry.getInstrumentation(), true);
Thread.sleep(500); // wait for listener to be allowed
@@ -222,9 +208,6 @@
@Test
public void testSuspendedPackageSendNotification() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
toggleListenerAccess(TestNotificationListener.getId(),
InstrumentationRegistry.getInstrumentation(), true);
Thread.sleep(500); // wait for listener to be allowed
@@ -255,9 +238,6 @@
@Test
public void testResetListenerHints_singleListener() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
toggleListenerAccess(TestNotificationListener.getId(),
InstrumentationRegistry.getInstrumentation(), true);
Thread.sleep(500); // wait for listener to be allowed
@@ -277,9 +257,6 @@
@Test
public void testResetListenerHints_multiListener() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
toggleListenerAccess(TestNotificationListener.getId(),
InstrumentationRegistry.getInstrumentation(), true);
toggleListenerAccess(SecondaryNotificationListener.getId(),
@@ -307,9 +284,6 @@
@Test
public void testSetNotificationPolicy_preP_setOldNewFields() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
toggleNotificationPolicyAccess(mContext.getPackageName(),
InstrumentationRegistry.getInstrumentation(), true);
diff --git a/tests/tests/notificationlegacy/notificationlegacy29/src/android/app/notification/legacy29/cts/NotificationAssistantServiceTest.java b/tests/tests/notificationlegacy/notificationlegacy29/src/android/app/notification/legacy29/cts/NotificationAssistantServiceTest.java
index 1747c17..a69c595 100644
--- a/tests/tests/notificationlegacy/notificationlegacy29/src/android/app/notification/legacy29/cts/NotificationAssistantServiceTest.java
+++ b/tests/tests/notificationlegacy/notificationlegacy29/src/android/app/notification/legacy29/cts/NotificationAssistantServiceTest.java
@@ -24,7 +24,6 @@
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.fail;
-import android.app.ActivityManager;
import android.app.Instrumentation;
import android.app.Notification;
import android.app.NotificationChannel;
@@ -43,6 +42,9 @@
import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
import junit.framework.Assert;
import org.junit.After;
@@ -57,9 +59,6 @@
import java.util.List;
import java.util.concurrent.TimeUnit;
-import androidx.test.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
-
@RunWith(AndroidJUnit4.class)
public class NotificationAssistantServiceTest {
@@ -71,7 +70,6 @@
private TestNotificationAssistant mNotificationAssistantService;
private TestNotificationListener mNotificationListenerService;
private NotificationManager mNotificationManager;
- private ActivityManager mActivityManager;
private StatusBarManager mStatusBarManager;
private Context mContext;
private UiAutomation mUi;
@@ -84,7 +82,6 @@
Context.NOTIFICATION_SERVICE);
mNotificationManager.createNotificationChannel(new NotificationChannel(
NOTIFICATION_CHANNEL_ID, "name", NotificationManager.IMPORTANCE_DEFAULT));
- mActivityManager = mContext.getSystemService(ActivityManager.class);
mStatusBarManager = (StatusBarManager) mContext.getSystemService(
Context.STATUS_BAR_SERVICE);
}
@@ -92,18 +89,14 @@
@After
public void tearDown() throws IOException {
if (mNotificationListenerService != null) mNotificationListenerService.resetData();
- if (!mActivityManager.isLowRamDevice()) {
- toggleListenerAccess(false);
- toggleAssistantAccess(false);
- }
+
+ toggleListenerAccess(false);
+ toggleAssistantAccess(false);
mUi.dropShellPermissionIdentity();
}
@Test
public void testOnNotificationEnqueued() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
toggleListenerAccess(true);
Thread.sleep(SLEEP_TIME);
@@ -138,9 +131,6 @@
@Test
public void testAdjustNotification_userSentimentKey() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
setUpListeners();
mUi.adoptShellPermissionIdentity("android.permission.STATUS_BAR_SERVICE");
@@ -172,9 +162,6 @@
@Test
public void testAdjustNotification_importanceKey() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
setUpListeners();
mUi.adoptShellPermissionIdentity("android.permission.STATUS_BAR_SERVICE");
@@ -205,9 +192,6 @@
@Test
public void testAdjustNotification_rankingScoreKey() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
setUpListeners();
try {
@@ -263,9 +247,6 @@
@Test
public void testAdjustNotification_smartActionKey() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
setUpListeners();
mUi.adoptShellPermissionIdentity("android.permission.STATUS_BAR_SERVICE");
@@ -313,9 +294,6 @@
@Test
public void testAdjustNotification_smartReplyKey() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
setUpListeners();
CharSequence smartReply = "Smart Reply!";
@@ -359,9 +337,6 @@
@Test
public void testAdjustNotification_importanceKey_notAllowed() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
setUpListeners();
mUi.adoptShellPermissionIdentity("android.permission.STATUS_BAR_SERVICE");
@@ -394,9 +369,6 @@
@Test
public void testAdjustNotification_rankingScoreKey_notAllowed() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
setUpListeners();
mUi.adoptShellPermissionIdentity("android.permission.STATUS_BAR_SERVICE");
@@ -442,9 +414,6 @@
@Test
public void testGetAllowedAssistantCapabilities_permission() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
toggleAssistantAccess(false);
try {
@@ -457,9 +426,6 @@
@Test
public void testGetAllowedAssistantCapabilities() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
toggleAssistantAccess(true);
Thread.sleep(SLEEP_TIME); // wait for assistant to be allowed
mNotificationAssistantService = TestNotificationAssistant.getInstance();
@@ -489,9 +455,6 @@
@Test
public void testOnActionInvoked_methodExists() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
setUpListeners();
final Intent intent = new Intent(Intent.ACTION_MAIN, Telephony.Threads.CONTENT_URI);
@@ -509,9 +472,6 @@
@Test
public void testOnNotificationDirectReplied_methodExists() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
setUpListeners();
// This method has to exist and the call cannot fail
mNotificationAssistantService.onNotificationDirectReplied("");
@@ -519,9 +479,6 @@
@Test
public void testOnNotificationExpansionChanged_methodExists() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
setUpListeners();
// This method has to exist and the call cannot fail
mNotificationAssistantService.onNotificationExpansionChanged("", true, true);
@@ -529,9 +486,6 @@
@Test
public void testOnNotificationVisibilityChanged() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
setUpListeners();
mUi.adoptShellPermissionIdentity("android.permission.EXPAND_STATUS_BAR");
@@ -560,9 +514,6 @@
@Test
public void testOnNotificationsSeen() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
setUpListeners();
mUi.adoptShellPermissionIdentity("android.permission.EXPAND_STATUS_BAR");
@@ -585,9 +536,6 @@
@Test
public void testOnPanelRevealedAndHidden() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
setUpListeners();
mUi.adoptShellPermissionIdentity("android.permission.EXPAND_STATUS_BAR");
@@ -609,9 +557,6 @@
@Test
public void testOnSuggestedReplySent_methodExists() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
setUpListeners();
// This method has to exist and the call cannot fail
mNotificationAssistantService.onSuggestedReplySent("", "",
diff --git a/tests/tests/notificationlegacy/notificationlegacy29/src/android/app/notification/legacy29/cts/NotificationManager29Test.java b/tests/tests/notificationlegacy/notificationlegacy29/src/android/app/notification/legacy29/cts/NotificationManager29Test.java
index 96c2b0d..5b70d19 100644
--- a/tests/tests/notificationlegacy/notificationlegacy29/src/android/app/notification/legacy29/cts/NotificationManager29Test.java
+++ b/tests/tests/notificationlegacy/notificationlegacy29/src/android/app/notification/legacy29/cts/NotificationManager29Test.java
@@ -17,7 +17,6 @@
package android.app.notification.legacy29.cts;
import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_ANYONE;
-import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_IMPORTANT;
import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_CONVERSATIONS;
import static junit.framework.Assert.assertEquals;
@@ -25,7 +24,6 @@
import static junit.framework.TestCase.assertNotNull;
import static junit.framework.TestCase.assertNull;
-import android.app.ActivityManager;
import android.app.Instrumentation;
import android.app.Notification;
import android.app.NotificationChannel;
@@ -61,7 +59,6 @@
final String NOTIFICATION_CHANNEL_ID = "LegacyNoManTest29";
private NotificationManager mNotificationManager;
private Context mContext;
- private ActivityManager mActivityManager;
@Before
public void setUp() throws Exception {
@@ -71,7 +68,6 @@
Context.NOTIFICATION_SERVICE);
mNotificationManager.createNotificationChannel(new NotificationChannel(
NOTIFICATION_CHANNEL_ID, "name", NotificationManager.IMPORTANCE_DEFAULT));
- mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
}
private void toggleNotificationPolicyAccess(String packageName,
@@ -158,9 +154,6 @@
@Test
public void testApi29CannotToggleConversationsTest() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
toggleNotificationPolicyAccess(mContext.getPackageName(),
InstrumentationRegistry.getInstrumentation(), true);
@@ -185,9 +178,6 @@
@Test
public void testApi29CannotToggleConversationsOffTest() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- return;
- }
toggleNotificationPolicyAccess(mContext.getPackageName(),
InstrumentationRegistry.getInstrumentation(), true);
diff --git a/tests/tests/os/AndroidManifest.xml b/tests/tests/os/AndroidManifest.xml
index 9639c0d..7c9ea67 100644
--- a/tests/tests/os/AndroidManifest.xml
+++ b/tests/tests/os/AndroidManifest.xml
@@ -47,6 +47,7 @@
<uses-permission android:name="android.permission.POWER_SAVER" />
<uses-permission android:name="android.permission.INSTALL_DYNAMIC_SYSTEM" />
<uses-permission android:name="android.permission.MANAGE_COMPANION_DEVICES" />
+ <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.os.cts.permission.TEST_GRANTED" />
<application
@@ -70,6 +71,8 @@
</intent-filter>
</activity>
+ <activity android:name="android.os.cts.SimpleTestActivity" />
+
<service
android:name="android.os.cts.ParcelFileDescriptorPeer$Red"
android:process=":red"
diff --git a/tests/tests/os/src/android/os/cts/SimpleTestActivity.java b/tests/tests/os/src/android/os/cts/SimpleTestActivity.java
new file mode 100644
index 0000000..4242315
--- /dev/null
+++ b/tests/tests/os/src/android/os/cts/SimpleTestActivity.java
@@ -0,0 +1,22 @@
+/*
+ * 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.os.cts;
+
+import android.app.Activity;
+
+public class SimpleTestActivity extends Activity {
+}
\ No newline at end of file
diff --git a/tests/tests/os/src/android/os/cts/StrictModeTest.java b/tests/tests/os/src/android/os/cts/StrictModeTest.java
index 2ffbbb7..1a4f0ef 100644
--- a/tests/tests/os/src/android/os/cts/StrictModeTest.java
+++ b/tests/tests/os/src/android/os/cts/StrictModeTest.java
@@ -16,17 +16,23 @@
package android.os.cts;
+import static android.content.Context.WINDOW_SERVICE;
+import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
+
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
+import android.hardware.display.DisplayManager;
import android.net.TrafficStats;
import android.net.Uri;
import android.os.IBinder;
@@ -51,6 +57,8 @@
import android.system.Os;
import android.system.OsConstants;
import android.util.Log;
+import android.view.Display;
+import android.view.WindowManager;
import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
@@ -610,6 +618,66 @@
}
}
+ @Test
+ public void testIncorrectContextUse_GetSystemService() throws Exception {
+ StrictMode.setVmPolicy(
+ new StrictMode.VmPolicy.Builder()
+ .detectIncorrectContextUse()
+ .penaltyLog()
+ .build());
+
+ inspectViolation(
+ () -> getContext().getApplicationContext().getSystemService(WindowManager.class),
+ info -> assertThat(info.getStackTrace()).contains(
+ "Tried to access visual service " + WINDOW_SERVICE));
+
+ final Display display = getContext().getSystemService(DisplayManager.class)
+ .getDisplay(DEFAULT_DISPLAY);
+ final Context visualContext = getContext().createDisplayContext(display)
+ .createWindowContext(TYPE_APPLICATION_OVERLAY, null /* options */);
+ assertNoViolation(() -> visualContext.getSystemService(WINDOW_SERVICE));
+
+ Intent intent = new Intent(InstrumentationRegistry.getInstrumentation().getTargetContext(),
+ SimpleTestActivity.class);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ final Activity activity = InstrumentationRegistry.getInstrumentation()
+ .startActivitySync(intent);
+ assertNoViolation(() -> activity.getSystemService(WINDOW_SERVICE));
+ }
+
+ @Test
+ public void testIncorrectContextUse_GetDisplay() throws Exception {
+ StrictMode.setVmPolicy(
+ new StrictMode.VmPolicy.Builder()
+ .detectIncorrectContextUse()
+ .penaltyLog()
+ .build());
+
+ final Display display = getContext().getSystemService(DisplayManager.class)
+ .getDisplay(DEFAULT_DISPLAY);
+
+ final Context displayContext = getContext().createDisplayContext(display);
+ assertNoViolation(displayContext::getDisplay);
+
+ final Context windowContext =
+ displayContext.createWindowContext(TYPE_APPLICATION_OVERLAY, null /* options */);
+ assertNoViolation(windowContext::getDisplay);
+
+ Intent intent = new Intent(InstrumentationRegistry.getInstrumentation().getTargetContext(),
+ SimpleTestActivity.class);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ final Activity activity = InstrumentationRegistry.getInstrumentation()
+ .startActivitySync(intent);
+ assertNoViolation(() -> activity.getDisplay());
+
+ try {
+ getContext().getApplicationContext().getDisplay();
+ } catch (UnsupportedOperationException e) {
+ return;
+ }
+ fail("Expected to get incorrect use exception from calling getDisplay() on Application");
+ }
+
private static void runWithRemoteServiceBound(Context context, Consumer<ISecondary> consumer)
throws ExecutionException, InterruptedException, RemoteException {
BlockingQueue<IBinder> binderHolder = new ArrayBlockingQueue<>(1);
diff --git a/tests/tests/permission2/res/raw/android_manifest.xml b/tests/tests/permission2/res/raw/android_manifest.xml
index ca29c2b..9bbc177 100644
--- a/tests/tests/permission2/res/raw/android_manifest.xml
+++ b/tests/tests/permission2/res/raw/android_manifest.xml
@@ -1197,6 +1197,15 @@
android:description="@string/permdesc_acceptHandovers"
android:protectionLevel="dangerous" />
+ <!-- Allows an application assigned to the Dialer role to be granted access to the telephony
+ call audio streams, both TX and RX.
+ <p>Protection level: signature|appop
+ -->
+ <permission android:name="android.permission.ACCESS_CALL_AUDIO"
+ android.label="@string/permlab_accessCallAudio"
+ android:description="@string/permdesc_accessCallAudio"
+ android:protectionLevel="signature|appop" />
+
<!-- ====================================================================== -->
<!-- Permissions for accessing the device microphone -->
<!-- ====================================================================== -->
@@ -2755,7 +2764,7 @@
<permission android:name="android.permission.READ_DEVICE_CONFIG"
android:protectionLevel="signature|preinstalled" />
- <!-- @SystemApi @hide Allows an application to monitor config settings access.
+ <!-- @hide Allows an application to monitor config settings access.
<p>Not for use by third-party applications. -->
<permission android:name="android.permission.MONITOR_DEVICE_CONFIG_ACCESS"
android:protectionLevel="signature"/>
diff --git a/tests/tests/secure_element/access_control/OWNERS b/tests/tests/secure_element/access_control/OWNERS
index 853b7c3..6c4d2b3 100644
--- a/tests/tests/secure_element/access_control/OWNERS
+++ b/tests/tests/secure_element/access_control/OWNERS
@@ -1,6 +1,5 @@
# Bug component: 456592
-zachoverflow@google.com
+alisher@google.com
jackcwyu@google.com
-tokuda@google.com
georgekgchang@google.com
-jimmychchang@google.com
+zachoverflow@google.com
diff --git a/tests/tests/secure_element/omapi/OWNERS b/tests/tests/secure_element/omapi/OWNERS
index 853b7c3..6c4d2b3 100644
--- a/tests/tests/secure_element/omapi/OWNERS
+++ b/tests/tests/secure_element/omapi/OWNERS
@@ -1,6 +1,5 @@
# Bug component: 456592
-zachoverflow@google.com
+alisher@google.com
jackcwyu@google.com
-tokuda@google.com
georgekgchang@google.com
-jimmychchang@google.com
+zachoverflow@google.com
diff --git a/tests/tests/slice/src/android/slice/cts/SliceBindingTest.java b/tests/tests/slice/src/android/slice/cts/SliceBindingTest.java
index 8a655cd..710ac94 100644
--- a/tests/tests/slice/src/android/slice/cts/SliceBindingTest.java
+++ b/tests/tests/slice/src/android/slice/cts/SliceBindingTest.java
@@ -28,6 +28,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.pm.PackageManager;
import android.graphics.drawable.Icon;
import android.net.Uri;
import android.os.Bundle;
@@ -54,9 +55,13 @@
private static final Uri BASE_URI = Uri.parse("content://android.slice.cts/");
private final Context mContext = InstrumentationRegistry.getContext();
private final SliceManager mSliceManager = mContext.getSystemService(SliceManager.class);
+ private boolean isSliceDisabled = mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_SLICES_DISABLED);
@Test
public void testProcess() {
+ if (isSliceDisabled) {
+ return;
+ }
sFlag = false;
mSliceManager.bindSlice(BASE_URI.buildUpon().appendPath("set_flag").build(),
Collections.emptySet());
@@ -71,6 +76,9 @@
@Test
public void testSliceUri() {
+ if (isSliceDisabled) {
+ return;
+ }
Slice s = mSliceManager.bindSlice(BASE_URI,
Collections.emptySet());
assertEquals(BASE_URI, s.getUri());
@@ -78,6 +86,9 @@
@Test
public void testSubSlice() {
+ if (isSliceDisabled) {
+ return;
+ }
Uri uri = BASE_URI.buildUpon().appendPath("subslice").build();
Slice s = mSliceManager.bindSlice(uri, Collections.emptySet());
assertEquals(uri, s.getUri());
@@ -93,6 +104,9 @@
@Test
public void testText() {
+ if (isSliceDisabled) {
+ return;
+ }
Uri uri = BASE_URI.buildUpon().appendPath("text").build();
Slice s = mSliceManager.bindSlice(uri,
Collections.emptySet());
@@ -107,6 +121,9 @@
@Test
public void testIcon() {
+ if (isSliceDisabled) {
+ return;
+ }
Uri uri = BASE_URI.buildUpon().appendPath("icon").build();
Slice s = mSliceManager.bindSlice(uri,
Collections.emptySet());
@@ -121,6 +138,9 @@
@Test
public void testAction() {
+ if (isSliceDisabled) {
+ return;
+ }
sFlag = false;
CountDownLatch latch = new CountDownLatch(1);
BroadcastReceiver receiver = new BroadcastReceiver() {
@@ -155,6 +175,9 @@
@Test
public void testInt() {
+ if (isSliceDisabled) {
+ return;
+ }
Uri uri = BASE_URI.buildUpon().appendPath("int").build();
Slice s = mSliceManager.bindSlice(uri, Collections.emptySet());
assertEquals(uri, s.getUri());
@@ -167,6 +190,9 @@
@Test
public void testTimestamp() {
+ if (isSliceDisabled) {
+ return;
+ }
Uri uri = BASE_URI.buildUpon().appendPath("timestamp").build();
Slice s = mSliceManager.bindSlice(uri,
Collections.emptySet());
@@ -180,6 +206,9 @@
@Test
public void testHints() {
+ if (isSliceDisabled) {
+ return;
+ }
// 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();
@@ -194,6 +223,9 @@
@Test
public void testHasHints() {
+ if (isSliceDisabled) {
+ return;
+ }
Uri uri = BASE_URI.buildUpon().appendPath("hints").build();
Slice s = mSliceManager.bindSlice(uri, Collections.emptySet());
@@ -203,6 +235,9 @@
@Test
public void testBundle() {
+ if (isSliceDisabled) {
+ return;
+ }
Uri uri = BASE_URI.buildUpon().appendPath("bundle").build();
Slice s = mSliceManager.bindSlice(uri, Collections.emptySet());
assertEquals(uri, s.getUri());
@@ -217,6 +252,9 @@
@Test
public void testGetDescendants() {
+ if (isSliceDisabled) {
+ return;
+ }
Collection<Uri> allUris = mSliceManager.getSliceDescendants(BASE_URI);
assertEquals(SliceProvider.PATHS.length, allUris.size());
Iterator<Uri> it = allUris.iterator();
@@ -230,6 +268,9 @@
@Test
public void testGetSliceSpec() {
+ if (isSliceDisabled) {
+ return;
+ }
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 69d8d80..1e5c718 100644
--- a/tests/tests/slice/src/android/slice/cts/SliceManagerTest.java
+++ b/tests/tests/slice/src/android/slice/cts/SliceManagerTest.java
@@ -30,6 +30,7 @@
import android.app.slice.SliceManager;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
@@ -54,9 +55,14 @@
private static final Uri BASE_URI = Uri.parse("content://android.slice.cts.local/main");
private final Context mContext = InstrumentationRegistry.getContext();
private final SliceManager mSliceManager = mContext.getSystemService(SliceManager.class);
+ private boolean isSliceDisabled = mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_SLICES_DISABLED);
+
@Before
public void setup() {
+ if (isSliceDisabled) {
+ return;
+ }
LocalSliceProvider.sProxy = mock(SliceProvider.class);
try {
mSliceManager.unpinSlice(BASE_URI);
@@ -66,6 +72,9 @@
@After
public void teardown() throws Exception {
+ if (isSliceDisabled) {
+ return;
+ }
try {
mSliceManager.unpinSlice(BASE_URI);
} catch (Exception e) {
@@ -74,6 +83,9 @@
@Test
public void testPinSlice() throws Exception {
+ if (isSliceDisabled) {
+ return;
+ }
mSliceManager.pinSlice(BASE_URI, Collections.emptySet());
verify(LocalSliceProvider.sProxy, timeout(2000)).onSlicePinned(eq(BASE_URI));
@@ -81,6 +93,9 @@
@Test
public void testUnpinSlice() throws Exception {
+ if (isSliceDisabled) {
+ return;
+ }
mSliceManager.pinSlice(BASE_URI, Collections.emptySet());
verify(LocalSliceProvider.sProxy, timeout(2000)).onSlicePinned(eq(BASE_URI));
@@ -92,6 +107,9 @@
@Test
public void testPinList() {
+ if (isSliceDisabled) {
+ return;
+ }
Uri uri = BASE_URI;
Uri longerUri = uri.buildUpon().appendPath("something").build();
try {
@@ -111,6 +129,9 @@
@Test
public void testMapIntentToUri() {
+ if (isSliceDisabled) {
+ return;
+ }
Intent intent = new Intent("android.slice.cts.action.TEST_ACTION");
intent.setPackage("android.slice.cts");
intent.putExtra("path", "intent");
@@ -127,6 +148,9 @@
@Test
public void testOnCreatePermissionSlice() {
+ if (isSliceDisabled) {
+ return;
+ }
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 5081943..c36e7c9 100644
--- a/tests/tests/slice/src/android/slice/cts/SlicePermissionsTest.java
+++ b/tests/tests/slice/src/android/slice/cts/SlicePermissionsTest.java
@@ -14,6 +14,7 @@
package android.slice.cts;
+import android.content.pm.PackageManager;
import static android.content.pm.PackageManager.PERMISSION_DENIED;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
@@ -42,9 +43,13 @@
private int mTestUid;
private int mTestPid;
private SliceManager mSliceManager;
+ private boolean isSliceDisabled = mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_SLICES_DISABLED);
@Before
public void setup() throws NameNotFoundException {
+ if(isSliceDisabled) {
+ return;
+ }
mSliceManager = mContext.getSystemService(SliceManager.class);
mTestPkg = mContext.getPackageName();
mTestUid = mContext.getPackageManager().getPackageUid(mTestPkg, 0);
@@ -53,11 +58,17 @@
@After
public void tearDown() {
+ if (isSliceDisabled) {
+ return;
+ }
mSliceManager.revokeSlicePermission(mTestPkg, BASE_URI);
}
@Test
public void testGrant() {
+ if (isSliceDisabled) {
+ return;
+ }
assertEquals(PERMISSION_DENIED,
mSliceManager.checkSlicePermission(BASE_URI, mTestPid, mTestUid));
@@ -69,6 +80,9 @@
@Test
public void testGrantParent() {
+ if (isSliceDisabled) {
+ return;
+ }
Uri uri = BASE_URI.buildUpon()
.appendPath("something")
.build();
@@ -84,6 +98,9 @@
@Test
public void testGrantParentExpands() {
+ if (isSliceDisabled) {
+ return;
+ }
Uri uri = BASE_URI.buildUpon()
.appendPath("something")
.build();
@@ -110,6 +127,9 @@
@Test
public void testGrantChild() {
+ if (isSliceDisabled) {
+ return;
+ }
Uri uri = BASE_URI.buildUpon()
.appendPath("something")
.build();
@@ -126,6 +146,9 @@
@Test
public void testRevoke() {
+ if (isSliceDisabled) {
+ return;
+ }
assertEquals(PERMISSION_DENIED,
mSliceManager.checkSlicePermission(BASE_URI, mTestPid, mTestUid));
@@ -142,6 +165,9 @@
@Test
public void testRevokeParent() {
+ if (isSliceDisabled) {
+ return;
+ }
Uri uri = BASE_URI.buildUpon()
.appendPath("something")
.build();
@@ -162,6 +188,9 @@
@Test
public void testRevokeChild() {
+ if (isSliceDisabled) {
+ return;
+ }
Uri uri = BASE_URI.buildUpon()
.appendPath("something")
.build();
diff --git a/tests/tests/systemui/OWNERS b/tests/tests/systemui/OWNERS
index 583baa0..22ceb12 100644
--- a/tests/tests/systemui/OWNERS
+++ b/tests/tests/systemui/OWNERS
@@ -1,4 +1,4 @@
-# Bug component: 136515
+# Bug component: 181502
evanlaird@google.com
felkachang@google.com
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 4423ed5..734d85f 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/CellInfoTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/CellInfoTest.java
@@ -798,8 +798,16 @@
wcdma.getDbm();
int asuLevel = wcdma.getAsuLevel();
- assertTrue("getAsuLevel() out of range 0..96, 255, asuLevel=" + asuLevel,
- asuLevel == 255 || (asuLevel >= 0 && asuLevel <= 96));
+ if (wcdma.getRscp() != CellInfo.UNAVAILABLE) {
+ assertTrue("getAsuLevel() out of range 0..96, 255), asuLevel=" + asuLevel,
+ asuLevel == 255 || (asuLevel >= 0 && asuLevel <= 96));
+ } else if (wcdma.getRssi() != CellInfo.UNAVAILABLE) {
+ assertTrue("getAsuLevel() out of range 0..31, 99), asuLevel=" + asuLevel,
+ asuLevel == 99 || (asuLevel >= 0 && asuLevel <= 31));
+ } else {
+ assertTrue("getAsuLevel() out of range 0..96, 255), asuLevel=" + asuLevel,
+ asuLevel == 255);
+ }
int level = wcdma.getLevel();
assertTrue("getLevel() out of range [0,4], level=" + level, level >= 0 && level <= 4);
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java b/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java
index b5f3417..dcdefb9 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java
@@ -167,7 +167,8 @@
@Test
public void testGetActiveSubscriptionInfoForIcc() throws Exception {
if (!isSupported()) return;
- SubscriptionInfo info = mSm.getActiveSubscriptionInfo(mSubId);
+ SubscriptionInfo info = ShellIdentityUtils.invokeMethodWithShellPermissions(mSm,
+ (sm) -> sm.getActiveSubscriptionInfo(mSubId));
assertNotNull(ShellIdentityUtils.invokeMethodWithShellPermissions(mSm,
(sm) -> sm.getActiveSubscriptionInfoForIcc(info.getIccId())));
}
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java b/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java
index 3583de9..de40198 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java
@@ -546,8 +546,6 @@
}
TelephonyManager.getDefaultRespondViaMessageApplication(getContext(), false);
- ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
- (tm) -> tm.getPhoneCapability());
}
@Test
diff --git a/tests/tests/text/Android.bp b/tests/tests/text/Android.bp
index f3d34bf..2909777 100644
--- a/tests/tests/text/Android.bp
+++ b/tests/tests/text/Android.bp
@@ -16,6 +16,7 @@
name: "CtsTextTestCases",
defaults: ["cts_defaults"],
sdk_version: "test_current",
+ stl: "c++_shared",
srcs: [
"src/**/*.java",
@@ -38,7 +39,7 @@
jni_libs: [
"libctstext_jni",
- "libc++",
+ "libnativehelper_compat_libc++",
],
// Include both the 32 and 64 bit versions of libctstext_jni, where
// applicable.
diff --git a/tests/tests/text/jni/Android.bp b/tests/tests/text/jni/Android.bp
index 8055f40..7821605 100644
--- a/tests/tests/text/jni/Android.bp
+++ b/tests/tests/text/jni/Android.bp
@@ -14,9 +14,10 @@
cc_library {
name: "libctstext_jni",
+ sdk_version: "current",
srcs: [
"CtsTextJniOnLoad.cpp",
"android_text_format_cts_NativeTimeFunctions.cpp",
],
- static_libs: ["libnativehelper"],
+ shared_libs: ["libnativehelper_compat_libc++"],
}
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java b/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
index 5980663..7419858 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
@@ -245,23 +245,30 @@
return;
}
- assertTrue(mSettings.getAllowFileAccess());
+ // TODO(b/148840827): Uncomment default value assertion when a new version of WebView
+ // where the change happened is dropped in master.
+ // assertFalse("File access should be off by default", mSettings.getAllowFileAccess());
+ mSettings.setAllowFileAccess(true);
+ assertTrue("Explicitly setting file access to true should work",
+ mSettings.getAllowFileAccess());
String fileUrl = TestHtmlConstants.getFileUrl(TestHtmlConstants.HELLO_WORLD_URL);
mOnUiThread.loadUrlAndWaitForCompletion(fileUrl);
- assertEquals(TestHtmlConstants.HELLO_WORLD_TITLE, mOnUiThread.getTitle());
+ assertEquals("Loading files on the file system should work with file access enabled",
+ TestHtmlConstants.HELLO_WORLD_TITLE, mOnUiThread.getTitle());
fileUrl = TestHtmlConstants.getFileUrl(TestHtmlConstants.BR_TAG_URL);
mSettings.setAllowFileAccess(false);
- assertFalse(mSettings.getAllowFileAccess());
+ assertFalse("Explicitly setting file access to false should work",
+ mSettings.getAllowFileAccess());
mOnUiThread.loadUrlAndWaitForCompletion(fileUrl);
- // android_asset URLs should still be loaded when even with file access
- // disabled.
- assertEquals(TestHtmlConstants.BR_TAG_TITLE, mOnUiThread.getTitle());
+ assertEquals(
+ "android_asset URLs should still be loaded when even with file access disabled",
+ TestHtmlConstants.BR_TAG_TITLE, mOnUiThread.getTitle());
- // Files on the file system should not be loaded.
mOnUiThread.loadUrlAndWaitForCompletion(TestHtmlConstants.LOCAL_FILESYSTEM_URL);
- assertEquals(TestHtmlConstants.WEBPAGE_NOT_AVAILABLE_TITLE, mOnUiThread.getTitle());
+ assertEquals("Files on the file system should not be loaded with file access disabled",
+ TestHtmlConstants.WEBPAGE_NOT_AVAILABLE_TITLE, mOnUiThread.getTitle());
}
public void testAccessCacheMode_defaultValue() throws Throwable {
@@ -1060,6 +1067,7 @@
writeFile("target.html", target);
mSettings.setJavaScriptEnabled(true);
+ mSettings.setAllowFileAccess(true);
// disable universal access from files
mSettings.setAllowUniversalAccessFromFileURLs(false);
mSettings.setAllowFileAccessFromFileURLs(enableXHR);