Snap for 6227479 from 0fb562077c998f1fa90b0e3be5436bb122bf9b3c to rvc-release
Change-Id: I252b428967ddd83dd32750c488a557edc252f6c3
diff --git a/apps/CameraITS/tests/scene4/test_multi_camera_alignment.py b/apps/CameraITS/tests/scene4/test_multi_camera_alignment.py
index 976bee0..75b7a5d 100644
--- a/apps/CameraITS/tests/scene4/test_multi_camera_alignment.py
+++ b/apps/CameraITS/tests/scene4/test_multi_camera_alignment.py
@@ -30,6 +30,7 @@
ALIGN_TOL = 0.01 # multiplied by sensor diagonal to convert to pixels
CIRCLE_RTOL = 0.1
GYRO_REFERENCE = 1
+LENS_FACING_BACK = 1 # 0: FRONT, 1: BACK, 2: EXTERNAL
UNDEFINED_REFERENCE = 2
NAME = os.path.basename(__file__).split('.')[0]
TRANS_REF_MATRIX = np.array([0, 0, 0])
@@ -333,7 +334,7 @@
its.caps.logical_multi_camera(props))
# Convert chart_distance for lens facing back
- if props['android.lens.facing']:
+ if props['android.lens.facing'] == LENS_FACING_BACK:
# API spec defines +z is pointing out from screen
print 'lens facing BACK'
chart_distance *= -1
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/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index 67eeeca..4f9cc0a9 100755
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -5423,4 +5423,17 @@
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/peripheralprofile/ProfileManager.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/peripheralprofile/ProfileManager.java
index a679c41..b62a986 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/peripheralprofile/ProfileManager.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/peripheralprofile/ProfileManager.java
@@ -47,6 +47,11 @@
private static final String mBuiltInprofiles =
"<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>" +
"<ProfileList Version=\"1.0.0\">" +
+ "<PeripheralProfile ProfileName=\"Google USB-C Headset\" ProfileDescription=\"Google USB-C Headset\" ProductName=\"USB-Audio - Pixel USB-C earbuds\">" +
+ "<OutputDevInfo ChanCounts=\"2\" ChanPosMasks=\"12\" ChanIndexMasks=\"3\" Encodings=\"4\" SampleRates=\"44100,48000\" />" +
+ "<InputDevInfo ChanCounts=\"1\" ChanPosMasks=\"16\" ChanIndexMasks=\"1\" Encodings=\"2\" SampleRates=\"44100,48000\" />" +
+ "<ButtonInfo HasBtnA=\"1\" HasBtnB=\"1\" HasBtnC=\"1\" HasBtnD=\"0\" />" +
+ "</PeripheralProfile>" +
"<PeripheralProfile ProfileName=\"AudioBox USB 96\" ProfileDescription=\"PreSonus AudioBox USB 96\" ProductName=\"USB-Audio - AudioBox USB 96\">" +
"<OutputDevInfo ChanCounts=\"2\" ChanPosMasks=\"12\" ChanIndexMasks=\"3\" Encodings=\"4\" SampleRates=\"44100,48000,88200,96000\"/>" +
"<InputDevInfo ChanCounts=\"1,2\" ChanPosMasks=\"12,16\" ChanIndexMasks=\"1,3\" Encodings=\"4\" SampleRates=\"44100,48000,88200,96000\"/>" +
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/CredentialEnrolledTests.java b/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/CredentialEnrolledTests.java
index 7730b17..473579f 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/CredentialEnrolledTests.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/CredentialEnrolledTests.java
@@ -59,10 +59,18 @@
final BiometricManager bm = getSystemService(BiometricManager.class);
final int biometricResult = bm.canAuthenticate(Authenticators.BIOMETRIC_WEAK);
- if (biometricResult != BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED) {
- showToastAndLog("Unexpected result: " + biometricResult +
- ". Please make sure the device does not have a biometric enrolled");
- return;
+ switch (biometricResult) {
+ case BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE:
+ case BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED:
+ // OK
+ break;
+ case BiometricManager.BIOMETRIC_SUCCESS:
+ showToastAndLog("Unexpected result: " + biometricResult +
+ ". Please make sure the device does not have a biometric enrolled");
+ return;
+ default:
+ showToastAndLog("Unexpected result: " + biometricResult);
+ return;
}
final int credentialResult = bm.canAuthenticate(Authenticators.DEVICE_CREDENTIAL);
diff --git a/hostsidetests/blobstore/Android.bp b/hostsidetests/blobstore/Android.bp
index 398aff8..aab448e 100644
--- a/hostsidetests/blobstore/Android.bp
+++ b/hostsidetests/blobstore/Android.bp
@@ -31,8 +31,8 @@
}
android_test_helper_app {
- name: "CtsBlobStoreHelperApp",
- srcs: ["test-apps/BlobStoreHelperApp/src/**/*.java"],
+ name: "CtsBlobStoreHostTestHelper",
+ srcs: ["test-apps/BlobStoreHostTestHelper/src/**/*.java"],
static_libs: [
"compatibility-device-util-axt",
"androidx.test.ext.junit",
@@ -41,7 +41,7 @@
"truth-prebuilt",
"testng",
],
- manifest : "test-apps/BlobStoreHelperApp/AndroidManifest.xml",
+ manifest : "test-apps/BlobStoreHostTestHelper/AndroidManifest.xml",
platform_apis: true,
// Tag this module as a cts test artifact
test_suites: [
diff --git a/hostsidetests/blobstore/AndroidTest.xml b/hostsidetests/blobstore/AndroidTest.xml
index eaa301d..b1b6d63 100644
--- a/hostsidetests/blobstore/AndroidTest.xml
+++ b/hostsidetests/blobstore/AndroidTest.xml
@@ -24,7 +24,7 @@
<option name="jar" value="CtsBlobStoreHostTestCases.jar" />
</test>
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
- <option name="test-file-name" value="CtsBlobStoreHelperApp.apk" />
+ <option name="test-file-name" value="CtsBlobStoreHostTestHelper.apk" />
<option name="cleanup-apks" value="true" />
</target_preparer>
</configuration>
diff --git a/hostsidetests/blobstore/src/com/android/cts/host/blob/BaseBlobStoreHostTest.java b/hostsidetests/blobstore/src/com/android/cts/host/blob/BaseBlobStoreHostTest.java
index 9e3701d..7d25f5d 100644
--- a/hostsidetests/blobstore/src/com/android/cts/host/blob/BaseBlobStoreHostTest.java
+++ b/hostsidetests/blobstore/src/com/android/cts/host/blob/BaseBlobStoreHostTest.java
@@ -27,6 +27,9 @@
import java.util.stream.Collectors;
abstract class BaseBlobStoreHostTest extends BaseHostJUnit4Test {
+ protected static final String TARGET_APK = "CtsBlobStoreHostTestHelper.apk";
+ protected static final String TARGET_PKG = "com.android.cts.device.blob";
+
private static final long TIMEOUT_BOOT_COMPLETE_MS = 120_000;
protected static final String KEY_SESSION_ID = "session";
diff --git a/hostsidetests/blobstore/src/com/android/cts/host/blob/BlobStoreMultiUserTest.java b/hostsidetests/blobstore/src/com/android/cts/host/blob/BlobStoreMultiUserTest.java
index 9f58c3e..d8cc1a0 100644
--- a/hostsidetests/blobstore/src/com/android/cts/host/blob/BlobStoreMultiUserTest.java
+++ b/hostsidetests/blobstore/src/com/android/cts/host/blob/BlobStoreMultiUserTest.java
@@ -31,8 +31,6 @@
@RunWith(DeviceJUnit4ClassRunner.class)
public class BlobStoreMultiUserTest extends BaseBlobStoreHostTest {
- private static final String TARGET_APK = "CtsBlobStoreHelperApp.apk";
- private static final String TARGET_PKG = "com.android.cts.blob.helper";
private static final String TEST_CLASS = TARGET_PKG + ".DataCleanupTest";
private int mPrimaryUserId;
diff --git a/hostsidetests/blobstore/src/com/android/cts/host/blob/DataCleanupTest.java b/hostsidetests/blobstore/src/com/android/cts/host/blob/DataCleanupTest.java
index 8a3efc8..291bc7c 100644
--- a/hostsidetests/blobstore/src/com/android/cts/host/blob/DataCleanupTest.java
+++ b/hostsidetests/blobstore/src/com/android/cts/host/blob/DataCleanupTest.java
@@ -24,8 +24,6 @@
@RunWith(DeviceJUnit4ClassRunner.class)
public class DataCleanupTest extends BaseBlobStoreHostTest {
- private static final String TARGET_APK = "CtsBlobStoreHelperApp.apk";
- private static final String TARGET_PKG = "com.android.cts.blob.helper";
private static final String TEST_CLASS = TARGET_PKG + ".DataCleanupTest";
@Test
diff --git a/hostsidetests/blobstore/src/com/android/cts/host/blob/DataPersistenceTest.java b/hostsidetests/blobstore/src/com/android/cts/host/blob/DataPersistenceTest.java
index 39f9b32..973ca8b 100644
--- a/hostsidetests/blobstore/src/com/android/cts/host/blob/DataPersistenceTest.java
+++ b/hostsidetests/blobstore/src/com/android/cts/host/blob/DataPersistenceTest.java
@@ -22,8 +22,6 @@
@RunWith(DeviceJUnit4ClassRunner.class)
public class DataPersistenceTest extends BaseBlobStoreHostTest {
- private static final String TARGET_APK = "CtsBlobStoreHelperApp.apk";
- private static final String TARGET_PKG = "com.android.cts.blob.helper";
private static final String TEST_CLASS = TARGET_PKG + ".DataPersistenceTest";
@Test
diff --git a/hostsidetests/blobstore/test-apps/BlobStoreHelperApp/AndroidManifest.xml b/hostsidetests/blobstore/test-apps/BlobStoreHostTestHelper/AndroidManifest.xml
similarity index 88%
rename from hostsidetests/blobstore/test-apps/BlobStoreHelperApp/AndroidManifest.xml
rename to hostsidetests/blobstore/test-apps/BlobStoreHostTestHelper/AndroidManifest.xml
index a649209..36e0a9b 100644
--- a/hostsidetests/blobstore/test-apps/BlobStoreHelperApp/AndroidManifest.xml
+++ b/hostsidetests/blobstore/test-apps/BlobStoreHostTestHelper/AndroidManifest.xml
@@ -15,12 +15,12 @@
* limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.cts.blob.helper">
+ package="com.android.cts.device.blob">
<application>
<uses-library android:name="android.test.runner" />
</application>
<instrumentation
android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="com.android.cts.blob.helper" />
+ android:targetPackage="com.android.cts.device.blob" />
</manifest>
\ No newline at end of file
diff --git a/hostsidetests/blobstore/test-apps/BlobStoreHelperApp/src/com/android/cts/blob/helper/DataCleanupTest.java b/hostsidetests/blobstore/test-apps/BlobStoreHostTestHelper/src/com/android/cts/device/blob/DataCleanupTest.java
similarity index 99%
rename from hostsidetests/blobstore/test-apps/BlobStoreHelperApp/src/com/android/cts/blob/helper/DataCleanupTest.java
rename to hostsidetests/blobstore/test-apps/BlobStoreHostTestHelper/src/com/android/cts/device/blob/DataCleanupTest.java
index 00467cd..5bb82b9 100644
--- a/hostsidetests/blobstore/test-apps/BlobStoreHelperApp/src/com/android/cts/blob/helper/DataCleanupTest.java
+++ b/hostsidetests/blobstore/test-apps/BlobStoreHostTestHelper/src/com/android/cts/device/blob/DataCleanupTest.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.cts.blob.helper;
+package com.android.cts.device.blob;
import static com.google.common.truth.Truth.assertThat;
diff --git a/hostsidetests/blobstore/test-apps/BlobStoreHelperApp/src/com/android/cts/blob/helper/DataPersistenceTest.java b/hostsidetests/blobstore/test-apps/BlobStoreHostTestHelper/src/com/android/cts/device/blob/DataPersistenceTest.java
similarity index 99%
rename from hostsidetests/blobstore/test-apps/BlobStoreHelperApp/src/com/android/cts/blob/helper/DataPersistenceTest.java
rename to hostsidetests/blobstore/test-apps/BlobStoreHostTestHelper/src/com/android/cts/device/blob/DataPersistenceTest.java
index 5cfd669..b4226a6 100644
--- a/hostsidetests/blobstore/test-apps/BlobStoreHelperApp/src/com/android/cts/blob/helper/DataPersistenceTest.java
+++ b/hostsidetests/blobstore/test-apps/BlobStoreHostTestHelper/src/com/android/cts/device/blob/DataPersistenceTest.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.cts.blob.helper;
+package com.android.cts.device.blob;
import static com.google.common.truth.Truth.assertThat;
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/DeviceOwner/src/com/android/cts/deviceowner/SecurityLoggingTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/SecurityLoggingTest.java
similarity index 83%
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..58a377e 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,16 +62,21 @@
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 android.util.Log;
import androidx.test.InstrumentationRegistry;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
+import junit.framework.AssertionFailedError;
+
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.KeyStore;
@@ -85,7 +90,8 @@
import javax.crypto.spec.SecretKeySpec;
-public class SecurityLoggingTest extends BaseDeviceOwnerTest {
+public class SecurityLoggingTest extends BaseDeviceAdminTest {
+ private static final String TAG = "SecurityLoggingTest";
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 +129,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 +176,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 +215,7 @@
*/
public void testRetrievingSecurityLogsThrowsSecurityException() {
try {
- mDevicePolicyManager.retrieveSecurityLogs(getWho());
+ mDevicePolicyManager.retrieveSecurityLogs(ADMIN_RECEIVER_COMPONENT);
fail("did not throw expected SecurityException");
} catch (SecurityException expected) {
}
@@ -220,7 +227,7 @@
*/
public void testRetrievingPreviousSecurityLogsThrowsSecurityException() {
try {
- mDevicePolicyManager.retrievePreRebootSecurityLogs(getWho());
+ mDevicePolicyManager.retrievePreRebootSecurityLogs(ADMIN_RECEIVER_COMPONENT);
fail("did not throw expected SecurityException");
} catch (SecurityException expected) {
}
@@ -236,6 +243,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 +275,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,15 +347,26 @@
// 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);
}
-
- verifySecurityLogs(events);
+ try {
+ verifySecurityLogs(events);
+ } catch (AssertionFailedError e) {
+ dumpSecurityLogs(events);
+ throw e;
+ }
return events;
}
+ private void dumpSecurityLogs(List<SecurityEvent> events) {
+ Log.d(TAG, "Security events dump:");
+ for (SecurityEvent event : events) {
+ Log.d(TAG, event.toString());
+ }
+ }
+
/**
* Test: check that there are no gaps between ids in two consecutive batches. Shared preference
* is used to store these numbers between test invocations.
@@ -470,9 +525,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 +535,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 +547,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 +602,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 +614,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 +625,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 +674,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 +715,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 +741,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 +756,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 +772,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/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
index 3878d10..8fd637b 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
@@ -24,22 +24,12 @@
import static org.junit.Assert.fail;
import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
-import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
-import com.android.ddmlib.testrunner.TestResult.TestStatus;
import com.android.tradefed.config.Option;
import com.android.tradefed.device.CollectingOutputReceiver;
import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.CollectingTestListener;
-import com.android.tradefed.result.FileInputStreamSource;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.result.TestDescription;
-import com.android.tradefed.result.TestResult;
-import com.android.tradefed.result.TestRunResult;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
-import com.android.tradefed.util.FileUtil;
-import com.android.tradefed.util.TarUtil;
import com.google.common.io.ByteStreams;
@@ -62,6 +52,7 @@
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
+import java.util.function.Predicate;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -75,7 +66,7 @@
public abstract class BaseDevicePolicyTest extends BaseHostJUnit4Test {
//The maximum time to wait for user to be unlocked.
- private static final long USER_UNLOCK_TIMEOUT_NANO = 30_000_000_000L;
+ private static final long USER_UNLOCK_TIMEOUT_SEC = 30;
private static final String USER_STATE_UNLOCKED = "RUNNING_UNLOCKED";
@Option(
name = "skip-device-admin-feature-check",
@@ -179,6 +170,7 @@
@Before
public void setUp() throws Exception {
assertNotNull(getBuild()); // ensure build has been set before test is run.
+ ensurePackageManagerReady();
mHasFeature = getDevice().getApiLevel() >= 21; /* Build.VERSION_CODES.L */
if (!mSkipDeviceAdminFeatureCheck) {
mHasFeature = mHasFeature && hasDeviceFeature("android.software.device_admin");
@@ -230,16 +222,27 @@
executeShellCommand("input keyevent KEYCODE_HOME");
}
- void waitForUserUnlock(int userId) throws Exception {
- final String command = String.format("am get-started-user-state %d", userId);
- final long deadline = System.nanoTime() + USER_UNLOCK_TIMEOUT_NANO;
- while (System.nanoTime() <= deadline) {
- if (getDevice().executeShellCommand(command).startsWith(USER_STATE_UNLOCKED)) {
- return;
+ /** If package manager is not available, e.g. after system crash, wait for it a little bit. */
+ private void ensurePackageManagerReady() throws Exception {
+ waitForOutput("Package manager didn't become available", "service check package",
+ s -> s.trim().equals("Service package: found"), 120 /* seconds */);
+ }
+
+ protected void waitForUserUnlock(int userId) throws Exception {
+ waitForOutput("User is not unlocked.",
+ String.format("am get-started-user-state %d", userId),
+ s -> s.startsWith(USER_STATE_UNLOCKED), USER_UNLOCK_TIMEOUT_SEC);
+ }
+
+ protected void waitForOutput(String message, String command, Predicate<String> predicate,
+ long timeoutSec) throws Exception {
+ final long deadline = System.nanoTime() + TimeUnit.SECONDS.toNanos(timeoutSec);
+ while (!predicate.test(getDevice().executeShellCommand(command))) {
+ if (System.nanoTime() > deadline) {
+ fail(message);
}
- Thread.sleep(100);
+ Thread.sleep(1000);
}
- fail("User is not unlocked.");
}
@After
@@ -1000,4 +1003,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 cdf5bd9..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;
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 4078c12..5716258 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/OrgOwnedProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/OrgOwnedProfileOwnerTest.java
@@ -31,13 +31,10 @@
import com.android.cts.devicepolicy.metrics.DevicePolicyEventWrapper;
import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.log.LogUtil;
import org.junit.Ignore;
import org.junit.Test;
-import java.util.concurrent.TimeUnit;
-
/**
* Tests for organization-owned Profile Owner.
*/
@@ -273,6 +270,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 +317,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 +413,7 @@
}
@Test
- public void testApplicationHidden() throws Exception {
+ public void testApplicationHiddenParent() throws Exception {
if (!mHasFeature) {
return;
}
@@ -476,22 +492,16 @@
}
}
- private void setupIme(int userId, String imeApk, String imePackage) throws Exception {
+ private void setupIme(int userId, String imeApk, String imeComponent) throws Exception {
installAppAsUser(imeApk, userId);
- // Wait until IMS service is registered by the system.
- final long deadline = System.nanoTime() + TimeUnit.SECONDS.toNanos(5);
- while (true) {
- final String availableImes = getDevice().executeShellCommand(
- String.format("ime list --user %d -s -a", userId));
- if (availableImes.contains(imePackage)) {
- break;
- }
- assertTrue("Failed waiting for IME to become available", System.nanoTime() < deadline);
- Thread.sleep(100);
- }
- executeShellCommand("ime enable " + imePackage);
- executeShellCommand("ime set " + imePackage);
+ // Wait until IMS service is registered by the system.
+ waitForOutput("Failed waiting for IME to become available",
+ String.format("ime list --user %d -s -a", userId),
+ s -> s.contains(imeComponent), 10 /* seconds */);
+
+ executeShellCommand("ime enable " + imeComponent);
+ executeShellCommand("ime set " + imeComponent);
}
@@ -532,17 +542,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/net/AndroidTest.xml b/hostsidetests/net/AndroidTest.xml
index 0452fc6..7cc0dd1 100644
--- a/hostsidetests/net/AndroidTest.xml
+++ b/hostsidetests/net/AndroidTest.xml
@@ -25,6 +25,7 @@
<target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
<option name="teardown-command" value="cmd power set-mode 0" />
<option name="teardown-command" value="cmd battery reset" />
+ <option name="teardown-command" value="cmd netpolicy stop-watching" />
</target_preparer>
<test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
diff --git a/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
index 529b640..69dd2ad 100644
--- a/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
+++ b/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
@@ -79,7 +79,6 @@
private static final String TEST_APP2_SERVICE_CLASS = TEST_APP2_PKG + ".MyForegroundService";
private static final int SLEEP_TIME_SEC = 1;
- private static final boolean DEBUG = true;
// Constants below must match values defined on app2's Common.java
private static final String MANIFEST_RECEIVER = "ManifestReceiver";
@@ -159,6 +158,7 @@
if (!mIsLocationOn) {
enableLocation();
}
+ executeShellCommand("cmd netpolicy start-watching " + mUid);
setAppIdle(false);
Log.i(TAG, "Apps status:\n"
@@ -167,6 +167,7 @@
}
protected void tearDown() throws Exception {
+ executeShellCommand("cmd netpolicy stop-watching");
if (!mIsLocationOn) {
disableLocation();
}
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/AtomTests.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/AtomTests.java
index fc1b57e..9c55177 100644
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/AtomTests.java
+++ b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/AtomTests.java
@@ -42,6 +42,7 @@
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
+import android.location.GnssStatus;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
@@ -270,6 +271,81 @@
}
@Test
+ public void testGpsStatus() {
+ Context context = InstrumentationRegistry.getContext();
+ final LocationManager locManager = context.getSystemService(LocationManager.class);
+
+ if (!locManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
+ Log.e(TAG, "GPS provider is not enabled");
+ return;
+ }
+
+ // Time out set to 85 seconds (5 seconds for sleep and a possible 85 seconds if TTFF takes
+ // max time which would be around 90 seconds.
+ // This is based on similar location cts test timeout values.
+ final int TIMEOUT_IN_MSEC = 85_000;
+ final int SLEEP_TIME_IN_MSEC = 5_000;
+ // TTFF could take up to 90 seconds, thus we need to wait till TTFF does occur if it does
+ // not occur in the first SLEEP_TIME_IN_MSEC
+ final CountDownLatch mLatchTtff = new CountDownLatch(1);
+
+ GnssStatus.Callback gnssStatusCallback = new GnssStatus.Callback() {
+ @Override
+ public void onStarted() {
+ Log.v(TAG, "Gnss Status Listener Started");
+ }
+
+ @Override
+ public void onStopped() {
+ Log.v(TAG, "Gnss Status Listener Stopped");
+ }
+
+ @Override
+ public void onFirstFix(int ttffMillis) {
+ Log.v(TAG, "Gnss Status Listener Received TTFF");
+ mLatchTtff.countDown();
+ }
+
+ @Override
+ public void onSatelliteStatusChanged(GnssStatus status) {
+ Log.v(TAG, "Gnss Status Listener Received Status Update");
+ }
+ };
+
+ boolean gnssStatusCallbackAdded = locManager.registerGnssStatusCallback(
+ gnssStatusCallback, new Handler(Looper.getMainLooper()));
+ if (!gnssStatusCallbackAdded) {
+ // Registration of GnssMeasurements listener has failed, this indicates a platform bug.
+ Log.e(TAG, "Failed to start gnss status callback");
+ }
+
+ final LocationListener locListener = new LocationListener() {
+ public void onLocationChanged(Location location) {
+ Log.v(TAG, "onLocationChanged: location has been obtained");
+ }
+ public void onProviderDisabled(String provider) {
+ Log.v(TAG, "onProviderDisabled " + provider);
+ }
+ public void onProviderEnabled(String provider) {
+ Log.v(TAG, "onProviderEnabled " + provider);
+ }
+ public void onStatusChanged(String provider, int status, Bundle extras) {
+ Log.v(TAG, "onStatusChanged " + provider + " " + status);
+ }
+ };
+
+ locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
+ 0,
+ 0 /* minDistance */,
+ locListener,
+ Looper.getMainLooper());
+ sleep(SLEEP_TIME_IN_MSEC);
+ waitForReceiver(context, TIMEOUT_IN_MSEC, mLatchTtff, null);
+ locManager.removeUpdates(locListener);
+ locManager.unregisterGnssStatusCallback(gnssStatusCallback);
+ }
+
+ @Test
public void testScreenBrightness() {
Context context = InstrumentationRegistry.getContext();
PowerManager pm = context.getSystemService(PowerManager.class);
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java b/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
index d94316d8..1d4b2d6 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
@@ -583,6 +583,69 @@
}
}
+ public void testGnssStats() throws Exception {
+ if (statsdDisabled()) {
+ return;
+ }
+
+ // Get GnssMetrics as a simple gauge metric.
+ StatsdConfig.Builder config = getPulledConfig();
+ addGaugeAtomWithDimensions(config, Atom.GNSS_STATS_FIELD_NUMBER, null);
+ uploadConfig(config);
+ Thread.sleep(WAIT_TIME_SHORT);
+
+ if (!hasFeature(FEATURE_LOCATION_GPS, true)) return;
+ // Whitelist this app against background location request throttling
+ String origWhitelist = getDevice().executeShellCommand(
+ "settings get global location_background_throttle_package_whitelist").trim();
+ getDevice().executeShellCommand(String.format(
+ "settings put global location_background_throttle_package_whitelist %s",
+ DEVICE_SIDE_TEST_PACKAGE));
+
+ try {
+ runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testGpsStatus");
+
+ Thread.sleep(WAIT_TIME_LONG);
+ // Trigger a pull and wait for new pull before killing the process.
+ setAppBreadcrumbPredicate();
+ Thread.sleep(WAIT_TIME_LONG);
+
+ // Assert about GnssMetrics for the test app.
+ List<Atom> atoms = getGaugeMetricDataList();
+
+ boolean found = false;
+ for (Atom atom : atoms) {
+ AtomsProto.GnssStats state = atom.getGnssStats();
+ found = true;
+ assertThat(state.getLocationReports()).isGreaterThan((long) 0);
+ assertThat(state.getLocationFailureReports()).isAtLeast((long) 0);
+ assertThat(state.getTimeToFirstFixReports()).isGreaterThan((long) 0);
+ assertThat(state.getTimeToFirstFixMilliS()).isGreaterThan((long) 0);
+ assertThat(state.getPositionAccuracyReports()).isGreaterThan((long) 0);
+ assertThat(state.getPositionAccuracyMeters()).isGreaterThan((long) 0);
+ assertThat(state.getTopFourAverageCn0Reports()).isGreaterThan((long) 0);
+ assertThat(state.getTopFourAverageCn0DbMhz()).isGreaterThan((long) 0);
+ assertThat(state.getL5TopFourAverageCn0Reports()).isAtLeast((long) 0);
+ assertThat(state.getL5TopFourAverageCn0DbMhz()).isAtLeast((long) 0);
+ assertThat(state.getSvStatusReports()).isGreaterThan((long) 0);
+ assertThat(state.getSvStatusReportsUsedInFix()).isGreaterThan((long) 0);
+ assertThat(state.getL5SvStatusReports()).isAtLeast((long) 0);
+ assertThat(state.getL5SvStatusReportsUsedInFix()).isAtLeast((long) 0);
+ }
+ assertWithMessage(String.format("Did not find a matching atom"))
+ .that(found).isTrue();
+ } finally {
+ if ("null".equals(origWhitelist) || "".equals(origWhitelist)) {
+ getDevice().executeShellCommand(
+ "settings delete global location_background_throttle_package_whitelist");
+ } else {
+ getDevice().executeShellCommand(String.format(
+ "settings put global location_background_throttle_package_whitelist %s",
+ origWhitelist));
+ }
+ }
+ }
+
public void testMediaCodecActivity() throws Exception {
if (statsdDisabled()) {
return;
diff --git a/tests/BlobStore/Android.bp b/tests/BlobStore/Android.bp
index c168eb6..0d51b2d 100644
--- a/tests/BlobStore/Android.bp
+++ b/tests/BlobStore/Android.bp
@@ -25,11 +25,35 @@
],
srcs: [
"src/**/*.java",
+ ":CtsBlobStoreTestsAidl",
],
test_suites: [
"cts",
"vts",
"general-tests",
],
- platform_apis: true,
+ sdk_version: "test_current"
+}
+
+android_test_helper_app {
+ name: "CtsBlobStoreTestHelper",
+ defaults: ["cts_defaults"],
+ srcs: [
+ "helper-app/src/**/*.java",
+ ":CtsBlobStoreTestsAidl"
+ ],
+ test_suites: [
+ "cts",
+ "vts",
+ "general-tests",
+ ],
+ manifest: "helper-app/AndroidManifest.xml",
+ sdk_version: "test_current"
+}
+
+filegroup {
+ name: "CtsBlobStoreTestsAidl",
+ srcs: [
+ "aidl/**/*.aidl",
+ ]
}
\ No newline at end of file
diff --git a/tests/BlobStore/AndroidTest.xml b/tests/BlobStore/AndroidTest.xml
index 98b9d86..42c6a67 100644
--- a/tests/BlobStore/AndroidTest.xml
+++ b/tests/BlobStore/AndroidTest.xml
@@ -22,6 +22,7 @@
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
<option name="test-file-name" value="CtsBlobStoreTestCases.apk" />
+ <option name="test-file-name" value="CtsBlobStoreTestHelper.apk" />
</target_preparer>
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="com.android.cts.blob" />
diff --git a/tests/BlobStore/aidl/com/android/cts/blob/ICommandReceiver.aidl b/tests/BlobStore/aidl/com/android/cts/blob/ICommandReceiver.aidl
new file mode 100644
index 0000000..86d2f18
--- /dev/null
+++ b/tests/BlobStore/aidl/com/android/cts/blob/ICommandReceiver.aidl
@@ -0,0 +1,27 @@
+/*
+ * 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.blob;
+
+import android.app.blob.BlobHandle;
+import android.app.usage.StorageStats;
+
+interface ICommandReceiver {
+ void acquireLease(in BlobHandle blobHandle);
+ void releaseLease(in BlobHandle blobHandle);
+
+ StorageStats queryStatsForPackage();
+ StorageStats queryStatsForUid();
+}
\ No newline at end of file
diff --git a/tests/BlobStore/helper-app/AndroidManifest.xml b/tests/BlobStore/helper-app/AndroidManifest.xml
new file mode 100644
index 0000000..5ad854f
--- /dev/null
+++ b/tests/BlobStore/helper-app/AndroidManifest.xml
@@ -0,0 +1,26 @@
+<?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="com.android.cts.blob.helper" >
+
+ <application>
+ <service android:name=".BlobStoreTestService" android:exported="true"/>
+ </application>
+
+</manifest>
+
diff --git a/tests/BlobStore/helper-app/src/com/android/cts/blob/helper/BlobStoreTestService.java b/tests/BlobStore/helper-app/src/com/android/cts/blob/helper/BlobStoreTestService.java
new file mode 100644
index 0000000..4694dc5
--- /dev/null
+++ b/tests/BlobStore/helper-app/src/com/android/cts/blob/helper/BlobStoreTestService.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.blob.helper;
+
+import static android.os.storage.StorageManager.UUID_DEFAULT;
+
+import android.app.Service;
+import android.app.blob.BlobHandle;
+import android.app.blob.BlobStoreManager;
+import android.app.usage.StorageStats;
+import android.app.usage.StorageStatsManager;
+import android.content.Intent;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.IBinder;
+import android.os.Process;
+
+import com.android.cts.blob.ICommandReceiver;
+
+import java.io.IOException;
+
+public class BlobStoreTestService extends Service {
+ @Override
+ public IBinder onBind(Intent intent) {
+ return new CommandReceiver();
+ }
+
+ private class CommandReceiver extends ICommandReceiver.Stub {
+ public void acquireLease(BlobHandle blobHandle) {
+ final BlobStoreManager blobStoreManager = getSystemService(
+ BlobStoreManager.class);
+ try {
+ blobStoreManager.acquireLease(blobHandle, "Test description");
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ public void releaseLease(BlobHandle blobHandle) {
+ final BlobStoreManager blobStoreManager = getSystemService(
+ BlobStoreManager.class);
+ try {
+ blobStoreManager.releaseLease(blobHandle);
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ public StorageStats queryStatsForPackage() {
+ final StorageStatsManager storageStatsManager = getSystemService(
+ StorageStatsManager.class);
+ try {
+ return storageStatsManager
+ .queryStatsForPackage(UUID_DEFAULT, getPackageName(), getUser());
+ } catch (IOException | NameNotFoundException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ public StorageStats queryStatsForUid() {
+ final StorageStatsManager storageStatsManager = getSystemService(
+ StorageStatsManager.class);
+ try {
+ return storageStatsManager
+ .queryStatsForUid(UUID_DEFAULT, Process.myUid());
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+ }
+}
diff --git a/tests/BlobStore/src/com/android/cts/blob/BlobStoreManagerTest.java b/tests/BlobStore/src/com/android/cts/blob/BlobStoreManagerTest.java
index ab76368..853f7ce 100644
--- a/tests/BlobStore/src/com/android/cts/blob/BlobStoreManagerTest.java
+++ b/tests/BlobStore/src/com/android/cts/blob/BlobStoreManagerTest.java
@@ -15,16 +15,29 @@
*/
package com.android.cts.blob;
+import static android.os.storage.StorageManager.UUID_DEFAULT;
+
+import static com.android.compatibility.common.util.SystemUtil.runShellCommand;
+
import static com.google.common.truth.Truth.assertThat;
import static org.testng.Assert.assertThrows;
import android.app.blob.BlobHandle;
import android.app.blob.BlobStoreManager;
+import android.app.usage.StorageStats;
+import android.app.usage.StorageStatsManager;
+import android.content.ComponentName;
import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.IBinder;
import android.os.ParcelFileDescriptor;
+import android.os.Process;
+import android.util.Log;
import com.android.cts.blob.R;
+import com.android.cts.blob.ICommandReceiver;
import com.android.utils.blob.DummyBlobData;
import org.junit.After;
@@ -34,7 +47,9 @@
import java.io.IOException;
import java.util.ArrayList;
+import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -42,8 +57,15 @@
@RunWith(AndroidJUnit4.class)
public class BlobStoreManagerTest {
+ private static final String TAG = "BlobStoreTest";
+
private static final long TIMEOUT_COMMIT_CALLBACK_SEC = 5;
+ private static final long TIMEOUT_BIND_SERVICE_SEC = 2;
+
+ private static final String HELPER_PKG = "com.android.cts.blob.helper";
+ private static final String HELPER_SERVICE = HELPER_PKG + ".BlobStoreTestService";
+
private Context mContext;
private BlobStoreManager mBlobStoreManager;
@@ -56,18 +78,17 @@
mContext = InstrumentationRegistry.getInstrumentation().getContext();
mBlobStoreManager = (BlobStoreManager) mContext.getSystemService(
Context.BLOB_STORE_SERVICE);
- mCreatedSessionIds.clear();
+ clearAllBlobsData();
}
@After
public void tearDown() {
- for (long sessionId : mCreatedSessionIds) {
- try {
- mBlobStoreManager.deleteSession(sessionId);
- } catch (Exception e) {
- // Ignore
- }
- }
+ clearAllBlobsData();
+ }
+
+ private void clearAllBlobsData() {
+ executeCmd("cmd blob_store clear-all-sessions");
+ executeCmd("cmd blob_store clear-all-blobs");
}
@Test
@@ -443,9 +464,199 @@
assertThrows(NullPointerException.class, () -> mBlobStoreManager.releaseLease(null));
}
+ @Test
+ public void testStorageAttributedToSelf() throws Exception {
+ final DummyBlobData blobData = new DummyBlobData(mContext);
+ blobData.prepare();
+ final long partialFileSize = 3373L;
+
+ final StorageStatsManager storageStatsManager = mContext.getSystemService(
+ StorageStatsManager.class);
+ StorageStats beforeStatsForPkg = storageStatsManager
+ .queryStatsForPackage(UUID_DEFAULT, mContext.getPackageName(), mContext.getUser());
+ StorageStats beforeStatsForUid = storageStatsManager
+ .queryStatsForUid(UUID_DEFAULT, Process.myUid());
+
+ // Create a session and write some data.
+ final long sessionId = createSession(blobData.getBlobHandle());
+ assertThat(sessionId).isGreaterThan(0L);
+ try (BlobStoreManager.Session session = mBlobStoreManager.openSession(sessionId)) {
+ blobData.writeToSession(session, 0, partialFileSize);
+ }
+
+ StorageStats afterStatsForPkg = storageStatsManager
+ .queryStatsForPackage(UUID_DEFAULT, mContext.getPackageName(), mContext.getUser());
+ StorageStats afterStatsForUid = storageStatsManager
+ .queryStatsForUid(UUID_DEFAULT, Process.myUid());
+
+ // 'partialFileSize' bytes were written, verify the size increase.
+ assertThat(afterStatsForPkg.getDataBytes() - beforeStatsForPkg.getDataBytes())
+ .isEqualTo(partialFileSize);
+ assertThat(afterStatsForUid.getDataBytes() - beforeStatsForUid.getDataBytes())
+ .isEqualTo(partialFileSize);
+
+ // Complete writing data.
+ final long totalFileSize = blobData.getFileSize();
+ try (BlobStoreManager.Session session = mBlobStoreManager.openSession(sessionId)) {
+ blobData.writeToSession(session, partialFileSize, totalFileSize - partialFileSize);
+ }
+
+ afterStatsForPkg = storageStatsManager
+ .queryStatsForPackage(UUID_DEFAULT, mContext.getPackageName(), mContext.getUser());
+ afterStatsForUid = storageStatsManager
+ .queryStatsForUid(UUID_DEFAULT, Process.myUid());
+
+ // 'totalFileSize' bytes were written so far, verify the size increase.
+ assertThat(afterStatsForPkg.getDataBytes() - beforeStatsForPkg.getDataBytes())
+ .isEqualTo(totalFileSize);
+ assertThat(afterStatsForUid.getDataBytes() - beforeStatsForUid.getDataBytes())
+ .isEqualTo(totalFileSize);
+
+ // Commit the session.
+ try (BlobStoreManager.Session session = mBlobStoreManager.openSession(sessionId)) {
+ blobData.writeToSession(session, partialFileSize, session.getSize() - partialFileSize);
+ final CompletableFuture<Integer> callback = new CompletableFuture<>();
+ session.commit(mContext.getMainExecutor(), callback::complete);
+ assertThat(callback.get(TIMEOUT_COMMIT_CALLBACK_SEC, TimeUnit.SECONDS))
+ .isEqualTo(0);
+ }
+
+ mBlobStoreManager.acquireLease(blobData.getBlobHandle(), R.string.test_desc);
+
+ afterStatsForPkg = storageStatsManager
+ .queryStatsForPackage(UUID_DEFAULT, mContext.getPackageName(), mContext.getUser());
+ afterStatsForUid = storageStatsManager
+ .queryStatsForUid(UUID_DEFAULT, Process.myUid());
+
+ // Session was committed but no one else is using it, verify the size increase stays
+ // the same as earlier.
+ assertThat(afterStatsForPkg.getDataBytes() - beforeStatsForPkg.getDataBytes())
+ .isEqualTo(totalFileSize);
+ assertThat(afterStatsForUid.getDataBytes() - beforeStatsForUid.getDataBytes())
+ .isEqualTo(totalFileSize);
+
+ mBlobStoreManager.releaseLease(blobData.getBlobHandle());
+
+ afterStatsForPkg = storageStatsManager
+ .queryStatsForPackage(UUID_DEFAULT, mContext.getPackageName(), mContext.getUser());
+ afterStatsForUid = storageStatsManager
+ .queryStatsForUid(UUID_DEFAULT, Process.myUid());
+
+ // No leases on the blob, so it should not be attributed.
+ assertThat(afterStatsForPkg.getDataBytes() - beforeStatsForPkg.getDataBytes())
+ .isEqualTo(0L);
+ assertThat(afterStatsForUid.getDataBytes() - beforeStatsForUid.getDataBytes())
+ .isEqualTo(0L);
+ }
+
+ @Test
+ public void testStorageAttribution_acquireLease() throws Exception {
+ final DummyBlobData blobData = new DummyBlobData(mContext);
+ blobData.prepare();
+
+ final StorageStatsManager storageStatsManager = mContext.getSystemService(
+ StorageStatsManager.class);
+ StorageStats beforeStatsForPkg = storageStatsManager
+ .queryStatsForPackage(UUID_DEFAULT, mContext.getPackageName(), mContext.getUser());
+ StorageStats beforeStatsForUid = storageStatsManager
+ .queryStatsForUid(UUID_DEFAULT, Process.myUid());
+
+ final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
+ try (BlobStoreManager.Session session = mBlobStoreManager.openSession(sessionId)) {
+ blobData.writeToSession(session);
+ session.allowPublicAccess();
+
+ final CompletableFuture<Integer> callback = new CompletableFuture<>();
+ session.commit(mContext.getMainExecutor(), callback::complete);
+ assertThat(callback.get(TIMEOUT_COMMIT_CALLBACK_SEC, TimeUnit.SECONDS))
+ .isEqualTo(0);
+ }
+
+ StorageStats afterStatsForPkg = storageStatsManager
+ .queryStatsForPackage(UUID_DEFAULT, mContext.getPackageName(), mContext.getUser());
+ StorageStats afterStatsForUid = storageStatsManager
+ .queryStatsForUid(UUID_DEFAULT, Process.myUid());
+
+ // No leases on the blob, so it should not be attributed.
+ assertThat(afterStatsForPkg.getDataBytes() - beforeStatsForPkg.getDataBytes())
+ .isEqualTo(0L);
+ assertThat(afterStatsForUid.getDataBytes() - beforeStatsForUid.getDataBytes())
+ .isEqualTo(0L);
+
+ final ICommandReceiver commandReceiver = bindToHelperService();
+
+ StorageStats beforeStatsForHelperPkg = commandReceiver.queryStatsForPackage();
+ StorageStats beforeStatsForHelperUid = commandReceiver.queryStatsForUid();
+
+ commandReceiver.acquireLease(blobData.getBlobHandle());
+
+ StorageStats afterStatsForHelperPkg = commandReceiver.queryStatsForPackage();
+ StorageStats afterStatsForHelperUid = commandReceiver.queryStatsForUid();
+
+ assertThat(afterStatsForHelperPkg.getDataBytes() - beforeStatsForHelperPkg.getDataBytes())
+ .isEqualTo(blobData.getFileSize());
+ assertThat(afterStatsForHelperUid.getDataBytes() - beforeStatsForHelperUid.getDataBytes())
+ .isEqualTo(blobData.getFileSize());
+
+ afterStatsForPkg = storageStatsManager
+ .queryStatsForPackage(UUID_DEFAULT, mContext.getPackageName(), mContext.getUser());
+ afterStatsForUid = storageStatsManager
+ .queryStatsForUid(UUID_DEFAULT, Process.myUid());
+
+ // There shouldn't be no change in stats for this package
+ assertThat(afterStatsForPkg.getDataBytes() - beforeStatsForPkg.getDataBytes())
+ .isEqualTo(0L);
+ assertThat(afterStatsForUid.getDataBytes() - beforeStatsForUid.getDataBytes())
+ .isEqualTo(0L);
+
+ commandReceiver.releaseLease(blobData.getBlobHandle());
+
+ afterStatsForHelperPkg = commandReceiver.queryStatsForPackage();
+ afterStatsForHelperUid = commandReceiver.queryStatsForUid();
+
+ // Lease is released, so it should not be attributed anymore.
+ assertThat(afterStatsForHelperPkg.getDataBytes() - beforeStatsForHelperPkg.getDataBytes())
+ .isEqualTo(0L);
+ assertThat(afterStatsForHelperUid.getDataBytes() - beforeStatsForHelperUid.getDataBytes())
+ .isEqualTo(0L);
+ }
+
+ private ICommandReceiver bindToHelperService() throws Exception {
+ final TestServiceConnection serviceConnection = new TestServiceConnection();
+ final Intent intent = new Intent()
+ .setComponent(new ComponentName(HELPER_PKG, HELPER_SERVICE));
+ mContext.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
+ return ICommandReceiver.Stub.asInterface(serviceConnection.getService());
+ }
+
+ private class TestServiceConnection implements ServiceConnection {
+ private BlockingQueue<IBinder> mBlockingQueue = new LinkedBlockingQueue<>();
+
+ public void onServiceConnected(ComponentName componentName, IBinder service) {
+ Log.i(TAG, "Service got connected: " + componentName);
+ mBlockingQueue.offer(service);
+ }
+
+ public void onServiceDisconnected(ComponentName componentName) {
+ Log.e(TAG, "Service got disconnected: " + componentName);
+ }
+
+ public IBinder getService() throws Exception {
+ final IBinder service = mBlockingQueue.poll(TIMEOUT_BIND_SERVICE_SEC,
+ TimeUnit.SECONDS);
+ return service;
+ }
+ }
+
private long createSession(BlobHandle blobHandle) throws Exception {
final long sessionId = mBlobStoreManager.createSession(blobHandle);
mCreatedSessionIds.add(sessionId);
return sessionId;
}
+
+ private String executeCmd(String cmd) {
+ final String result = runShellCommand(cmd).trim();
+ Log.d(TAG, "Output of <" + cmd + ">: <" + result + ">");
+ return result;
+ }
}
diff --git a/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java b/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java
index 9603ec7..c1a02ab2 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());
}
}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/CannedFillResponse.java b/tests/autofillservice/src/android/autofillservice/cts/CannedFillResponse.java
index c2094c0..cd099d7 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/CannedFillResponse.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/CannedFillResponse.java
@@ -827,8 +827,6 @@
return this;
}
-
-
/**
* Sets the view to present the response in the UI.
*/
@@ -853,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/UiBot.java b/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
index 15386b0..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;
@@ -262,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.
@@ -335,12 +344,25 @@
return picker;
}
+ /**
+ * 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);
diff --git a/tests/autofillservice/src/android/autofillservice/cts/inline/InlineLoginActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineLoginActivityTest.java
index 284d549..39139eb 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/inline/InlineLoginActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineLoginActivityTest.java
@@ -22,6 +22,7 @@
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;
@@ -40,7 +41,6 @@
import android.autofillservice.cts.InstrumentedAutoFillService;
import android.os.Process;
import android.service.autofill.FillContext;
-import android.support.test.uiautomator.UiObject2;
import com.android.compatibility.common.util.RetryableException;
import com.android.cts.mockime.ImeEventStream;
@@ -60,29 +60,14 @@
}
@Test
- public void testAutofill_oneDataset() throws Exception {
+ public void testAutofill_noDataset() throws Exception {
// Set service.
enableService();
final MockImeSession mockImeSession = sMockImeSessionRule.getMockImeSession();
assumeTrue("MockIME not available", mockImeSession != null);
- // Set expectations.
- String expectedHeader = null, expectedFooter = null;
-
- final CannedFillResponse.Builder builder = new CannedFillResponse.Builder()
- .addDataset(new CannedFillResponse.CannedDataset.Builder()
- .setField(ID_USERNAME, "dude")
- .setField(ID_PASSWORD, "sweet")
- .setPresentation(createPresentation("The Dude"))
- .setInlinePresentation(createInlinePresentation("The Dude"))
- .build());
-
- sReplier.addResponse(builder.build());
- mActivity.expectAutoFill("dude", "sweet");
-
- // Dynamically set password to make sure it's sanitized.
- mActivity.onPassword((v) -> v.setText("I AM GROOT"));
+ sReplier.addResponse(CannedFillResponse.NO_RESPONSE);
final ImeEventStream stream = mockImeSession.openEventStream();
mockImeSession.callRequestShowSelf(0);
@@ -95,65 +80,50 @@
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");
- }
+ sReplier.getNextFillRequest();
- final UiObject2 suggestionStrip = mUiBot.assertSuggestionStrip(1);
- mUiBot.selectSuggestion(0);
+ mUiBot.assertNoSuggestionStripEver();
+ mUiBot.assertNoDatasetsEver();
- // Check the results.
- mActivity.assertAutoFilled();
-
- // Sanity checks.
-
- // 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();
+ waitUntilDisconnected();
}
@Test
- public void testAutofill_twoDatasets() throws Exception {
+ 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);
- // Set expectations.
- String expectedHeader = null, expectedFooter = null;
-
- final CannedFillResponse.Builder builder = new CannedFillResponse.Builder()
- .addDataset(new CannedFillResponse.CannedDataset.Builder()
- .setField(ID_USERNAME, "dude")
- .setField(ID_PASSWORD, "sweet")
- .setPresentation(createPresentation("The Dude"))
- .setInlinePresentation(createInlinePresentation("The Dude"))
- .build())
- .addDataset(new CannedFillResponse.CannedDataset.Builder()
- .setField(ID_USERNAME, "test")
- .setField(ID_PASSWORD, "tweet")
- .setPresentation(createPresentation("Second Dude"))
- .setInlinePresentation(createInlinePresentation("Second Dude"))
- .build());
+ 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("test", "tweet");
+ mActivity.expectAutoFill("dude" + selectedDatasetIndex, "sweet" + selectedDatasetIndex);
// Dynamically set password to make sure it's sanitized.
mActivity.onPassword((v) -> v.setText("I AM GROOT"));
@@ -178,14 +148,14 @@
throw new RetryableException("Retry inline test");
}
- mUiBot.assertSuggestionStrip(2);
- mUiBot.selectSuggestion(1);
+ mUiBot.assertSuggestionStrip(numDatasets);
+ mUiBot.assertNoDatasetsEver();
+
+ mUiBot.selectSuggestion(selectedDatasetIndex);
// Check the results.
mActivity.assertAutoFilled();
- // Sanity checks.
-
// Make sure input was sanitized.
final InstrumentedAutoFillService.FillRequest request = sReplier.getNextFillRequest();
assertWithMessage("CancelationSignal is null").that(request.cancellationSignal).isNotNull();
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 990cf31..19223b0 100644
--- a/tests/camera/src/android/hardware/camera2/cts/CameraManagerTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/CameraManagerTest.java
@@ -572,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);
}
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/AndroidManifest.xml b/tests/framework/base/windowmanager/AndroidManifest.xml
index 0f8da29..c95ae9c 100644
--- a/tests/framework/base/windowmanager/AndroidManifest.xml
+++ b/tests/framework/base/windowmanager/AndroidManifest.xml
@@ -27,7 +27,7 @@
<uses-permission android:name="android.permission.STOP_APP_SWITCHES" />
<uses-permission android:name="android.permission.CAPTURE_VIDEO_OUTPUT" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+ <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<application android:label="CtsWindowManagerDeviceTestCases"
android:requestLegacyExternalStorage="true">
diff --git a/tests/framework/base/windowmanager/app/src/android/server/wm/app/BroadcastReceiverActivity.java b/tests/framework/base/windowmanager/app/src/android/server/wm/app/BroadcastReceiverActivity.java
index b3ab326..26c5b3a 100644
--- a/tests/framework/base/windowmanager/app/src/android/server/wm/app/BroadcastReceiverActivity.java
+++ b/tests/framework/base/windowmanager/app/src/android/server/wm/app/BroadcastReceiverActivity.java
@@ -41,6 +41,7 @@
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
+import android.view.WindowInsets;
import java.lang.ref.WeakReference;
@@ -73,14 +74,13 @@
view.setLayoutParams(new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
- view.setOnApplyWindowInsetsListener((v, insets) -> {
- final boolean cutoutExists = (insets.getDisplayCutout() != null);
- Log.i(TAG, "cutout=" + cutoutExists);
- TestJournalProvider.putExtras(BroadcastReceiverActivity.this,
- bundle -> bundle.putBoolean(EXTRA_CUTOUT_EXISTS, cutoutExists));
- return insets;
- });
setContentView(view);
+
+ WindowInsets insets = getWindowManager().getCurrentWindowMetrics().getWindowInsets();
+ final boolean cutoutExists = (insets.getDisplayCutout() != null);
+ Log.i(TAG, "cutout=" + cutoutExists);
+ TestJournalProvider.putExtras(BroadcastReceiverActivity.this,
+ bundle -> bundle.putBoolean(EXTRA_CUTOUT_EXISTS, cutoutExists));
}
@Override
diff --git a/tests/framework/base/windowmanager/intent_tests/forResult/single-instance_for-result.json b/tests/framework/base/windowmanager/intent_tests/forResult/single-instance_for-result.json
new file mode 100644
index 0000000..78fe375
--- /dev/null
+++ b/tests/framework/base/windowmanager/intent_tests/forResult/single-instance_for-result.json
@@ -0,0 +1,66 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "package": "android.server.wm.cts",
+ "startForResult": false
+ }
+ ],
+ "act": [
+ {
+ "flags": "",
+ "class": "android.server.wm.intent.Activities$SingleInstanceActivity",
+ "package": "android.server.wm.cts",
+ "startForResult": true
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity"
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleInstanceActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleInstanceActivity"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/windowmanager/intent_tests/forResult/single-top_for-result.json b/tests/framework/base/windowmanager/intent_tests/forResult/single-top_for-result.json
new file mode 100644
index 0000000..a288a9e
--- /dev/null
+++ b/tests/framework/base/windowmanager/intent_tests/forResult/single-top_for-result.json
@@ -0,0 +1,54 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.wm.intent.Activities$SingleTopActivity",
+ "package": "android.server.wm.cts",
+ "startForResult": false
+ }
+ ],
+ "act": [
+ {
+ "flags": "",
+ "class": "android.server.wm.intent.Activities$SingleTopActivity",
+ "package": "android.server.wm.cts",
+ "startForResult": true
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleTopActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleTopActivity"
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleTopActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleTopActivity"
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/windowmanager/intent_tests/forResult/test-2.json b/tests/framework/base/windowmanager/intent_tests/forResult/test-2.json
index 6e97377..a80e56b 100644
--- a/tests/framework/base/windowmanager/intent_tests/forResult/test-2.json
+++ b/tests/framework/base/windowmanager/intent_tests/forResult/test-2.json
@@ -43,10 +43,6 @@
{
"name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
"state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
}
]
}
diff --git a/tests/framework/base/windowmanager/intent_tests/forResult/test-4.json b/tests/framework/base/windowmanager/intent_tests/forResult/test-4.json
index 2ed6023..a288a9e 100644
--- a/tests/framework/base/windowmanager/intent_tests/forResult/test-4.json
+++ b/tests/framework/base/windowmanager/intent_tests/forResult/test-4.json
@@ -43,10 +43,6 @@
{
"name": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleTopActivity",
"state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleTopActivity",
- "state": "STOPPED"
}
]
}
diff --git a/tests/framework/base/windowmanager/intent_tests/newTask/test-15.json b/tests/framework/base/windowmanager/intent_tests/newTask/test-15.json
index 33419d6..be49412 100644
--- a/tests/framework/base/windowmanager/intent_tests/newTask/test-15.json
+++ b/tests/framework/base/windowmanager/intent_tests/newTask/test-15.json
@@ -43,15 +43,23 @@
{
"name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
"state": "RESUMED"
- },
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
{
"name": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleInstanceActivity",
"state": "STOPPED"
}
]
}
- ],
- "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
+ ]
}
]
}
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/ConfigChangeTests.java b/tests/framework/base/windowmanager/src/android/server/wm/ConfigChangeTests.java
index f87fad9..edc6f9d 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/ConfigChangeTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/ConfigChangeTests.java
@@ -16,9 +16,9 @@
package android.server.wm;
-import static android.server.wm.WindowManagerState.STATE_RESUMED;
import static android.server.wm.StateLogger.log;
import static android.server.wm.StateLogger.logE;
+import static android.server.wm.WindowManagerState.STATE_RESUMED;
import static android.server.wm.app.Components.FONT_SCALE_ACTIVITY;
import static android.server.wm.app.Components.FONT_SCALE_NO_RELAUNCH_ACTIVITY;
import static android.server.wm.app.Components.FontScaleActivity.EXTRA_FONT_ACTIVITY_DPI;
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 8cf1b47..f8f714c 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayTestBase.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayTestBase.java
@@ -56,6 +56,7 @@
import android.server.wm.CommandSession.ActivitySession;
import android.server.wm.CommandSession.ActivitySessionClient;
import android.server.wm.settings.SettingsSession;
+import android.util.DisplayMetrics;
import android.util.Pair;
import android.util.Size;
import android.view.WindowManager;
@@ -168,10 +169,12 @@
@Nullable
final Integer overrideDensity;
+ final int mDisplayId;
+
/** Get physical and override display metrics from WM for specified display. */
public static ReportedDisplayMetrics getDisplayMetrics(int displayId) {
return new ReportedDisplayMetrics(executeShellCommand(WM_SIZE + " -d " + displayId)
- + executeShellCommand(WM_DENSITY + " -d " + displayId));
+ + executeShellCommand(WM_DENSITY + " -d " + displayId), displayId);
}
void setDisplayMetrics(final Size size, final int density) {
@@ -193,11 +196,12 @@
}
private void setSize(final Size size) {
- executeShellCommand(WM_SIZE + " " + size.getWidth() + "x" + size.getHeight());
+ executeShellCommand(
+ WM_SIZE + " " + size.getWidth() + "x" + size.getHeight() + " -d " + mDisplayId);
}
private void setDensity(final int density) {
- executeShellCommand(WM_DENSITY + " " + density);
+ executeShellCommand(WM_DENSITY + " " + density + " -d " + mDisplayId);
}
/** Get display size that WM operates with. */
@@ -210,7 +214,8 @@
return overrideDensity != null ? overrideDensity : physicalDensity;
}
- private ReportedDisplayMetrics(final String lines) {
+ private ReportedDisplayMetrics(final String lines, int displayId) {
+ mDisplayId = displayId;
Matcher matcher = PHYSICAL_SIZE.matcher(lines);
assertTrue("Physical display size must be reported", matcher.find());
log(matcher.group());
@@ -258,6 +263,16 @@
return ReportedDisplayMetrics.getDisplayMetrics(mDisplayId);
}
+ void changeDisplayMetrics(double sizeRatio, double densityRatio) {
+ final Size originalSize = mInitialDisplayMetrics.physicalSize;
+ final int density = mInitialDisplayMetrics.physicalDensity;
+
+ final Size overrideSize = new Size((int)(originalSize.getWidth() * sizeRatio),
+ (int)(originalSize.getHeight() * sizeRatio));
+ final int overrideDensity = (int)(density * densityRatio);
+ overrideDisplayMetrics(overrideSize, overrideDensity);
+ }
+
void overrideDisplayMetrics(final Size size, final int density) {
mInitialDisplayMetrics.setDisplayMetrics(size, density);
}
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/WindowContextTests.java b/tests/framework/base/windowmanager/src/android/server/wm/WindowContextTests.java
new file mode 100644
index 0000000..e9bebce
--- /dev/null
+++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowContextTests.java
@@ -0,0 +1,77 @@
+/*
+ * 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.server.wm;
+
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
+
+import static org.junit.Assert.assertEquals;
+
+import android.app.Instrumentation;
+import android.content.Context;
+import android.hardware.display.DisplayManager;
+import android.platform.test.annotations.Presubmit;
+import android.util.DisplayMetrics;
+import android.view.Display;
+import android.view.View;
+import android.view.WindowManager;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import org.junit.Test;
+
+@Presubmit
+public class WindowContextTests extends MultiDisplayTestBase {
+ private Instrumentation mInstrumentation = InstrumentationRegistry.getInstrumentation();
+ private Context mContext = mInstrumentation.getTargetContext();
+ private DisplayManager mDisplayManager = mContext.getSystemService(DisplayManager.class);
+
+ @Test
+ public void testWindowContextConfigChanges() {
+ final WindowManagerState.DisplayContent display = createManagedVirtualDisplaySession()
+ .setSimulateDisplay(true).createDisplay();
+ final Context windowContext = createWindowContext(display.mId);
+ mInstrumentation.runOnMainSync(() -> {
+ final View view = new View(windowContext);
+ WindowManager wm = windowContext.getSystemService(WindowManager.class);
+ wm.addView(view, new WindowManager.LayoutParams(TYPE_APPLICATION_OVERLAY));
+ });
+ mWmState.computeState();
+
+ final DisplayMetricsSession displayMetricsSession =
+ createManagedDisplayMetricsSession(display.mId);
+
+ displayMetricsSession.changeDisplayMetrics(1.2 /* sizeRatio */, 1.1 /* densityRatio */);
+
+ mWmState.computeState();
+
+ assertDisplayMetricsEquals(displayMetricsSession.getDisplayMetrics(),
+ windowContext.getResources().getDisplayMetrics());
+ }
+
+ private Context createWindowContext(int displayId) {
+ final Display display = mDisplayManager.getDisplay(displayId);
+ return mContext.createDisplayContext(display).createWindowContext(TYPE_APPLICATION_OVERLAY,
+ null /* options */);
+ }
+
+ private void assertDisplayMetricsEquals(ReportedDisplayMetrics expectedMetrics,
+ DisplayMetrics actualMetrics) {
+ assertEquals(expectedMetrics.getSize().getWidth(), actualMetrics.widthPixels);
+ assertEquals(expectedMetrics.getSize().getHeight(), actualMetrics.heightPixels);
+ assertEquals(expectedMetrics.getDensity(), actualMetrics.densityDpi);
+ }
+}
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/WindowMetricsTests.java b/tests/framework/base/windowmanager/src/android/server/wm/WindowMetricsTests.java
index 958279a..1b04e13 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/WindowMetricsTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowMetricsTests.java
@@ -18,11 +18,16 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeFalse;
import android.app.Activity;
+import android.graphics.Insets;
+import android.graphics.Point;
import android.os.Bundle;
import android.platform.test.annotations.Presubmit;
import android.util.Size;
+import android.view.Display;
+import android.view.DisplayCutout;
import android.view.View;
import android.view.WindowInsets;
import android.view.WindowMetrics;
@@ -34,14 +39,23 @@
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+/**
+ * Tests that verify the behavior of {@link WindowMetrics} and {@link android.app.WindowContext} API
+ *
+ * Build/Install/Run:
+ * atest CtsWindowManagerDeviceTestCases:WindowMetricsTests
+ */
@Presubmit
public class WindowMetricsTests extends WindowManagerTestBase {
- ActivityTestRule<MetricsActivity> mMetricsActivity =
+ private ActivityTestRule<MetricsActivity> mMetricsActivity =
new ActivityTestRule<>(MetricsActivity.class);
@Test
- public void test_metrics() {
+ public void testMetricsSanity() {
+ // TODO(b/149668895): handle device with cutout.
+ assumeFalse(hasDisplayCutout());
+
final MetricsActivity activity = mMetricsActivity.launchActivity(null);
activity.waitForLayout();
@@ -57,7 +71,58 @@
activity.mOnCreateCurrentMetrics.getWindowInsets().getStableInsets());
assertEquals(activity.mOnLayoutInsets.getDisplayCutout(),
activity.mOnCreateCurrentMetrics.getWindowInsets().getDisplayCutout());
+ }
+ @Test
+ public void testMetricsMatchesDisplay() {
+ final MetricsActivity activity = mMetricsActivity.launchActivity(null);
+ activity.waitForLayout();
+
+ final Display display = activity.getDisplay();
+
+ // Check window size
+ final Point displaySize = new Point();
+ display.getSize(displaySize);
+ final WindowMetrics windowMetrics = activity.getWindowManager().getCurrentWindowMetrics();
+ final Size size = getLegacySize(windowMetrics);
+ assertEquals("Reported display width must match window width",
+ displaySize.x, size.getWidth());
+ assertEquals("Reported display height must match window height",
+ displaySize.y, size.getHeight());
+
+ // Check max window size
+ final Point realDisplaySize = new Point();
+ display.getRealSize(realDisplaySize);
+ final WindowMetrics maxWindowMetrics = activity.getWindowManager()
+ .getMaximumWindowMetrics();
+ assertEquals("Reported real display width must match max window size",
+ realDisplaySize.x, maxWindowMetrics.getSize().getWidth());
+ assertEquals("Reported real display height must match max window size",
+ realDisplaySize.y, maxWindowMetrics.getSize().getHeight());
+ }
+
+ private static Size getLegacySize(WindowMetrics windowMetrics) {
+ WindowInsets windowInsets = windowMetrics.getWindowInsets();
+ final Insets insetsWithCutout = getProperInsetsWithCutout(windowInsets.getStableInsets(),
+ windowInsets.getDisplayCutout());
+ final int insetsInWidth = insetsWithCutout.left + insetsWithCutout.right;
+ final int insetsInHeight = insetsWithCutout.top + insetsWithCutout.bottom;
+
+ Size size = windowMetrics.getSize();
+ return new Size(size.getWidth() - insetsInWidth, size.getHeight() - insetsInHeight);
+ }
+
+ private static Insets getProperInsetsWithCutout(Insets stableInsets, DisplayCutout cutout) {
+ final Insets excludingStatusBar = Insets.of(stableInsets.left, 0,
+ stableInsets.right, stableInsets.bottom);
+ if (cutout == null) {
+ return excludingStatusBar;
+ } else {
+ final Insets unionInsetsWithCutout = Insets.max(excludingStatusBar,
+ Insets.of(cutout.getSafeInsetLeft(), cutout.getSafeInsetTop(),
+ cutout.getSafeInsetRight(), cutout.getSafeInsetBottom()));
+ return unionInsetsWithCutout;
+ }
}
public static class MetricsActivity extends Activity implements View.OnLayoutChangeListener {
@@ -78,7 +143,6 @@
getWindow().getDecorView().addOnLayoutChangeListener(this);
}
-
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft,
int oldTop, int oldRight, int oldBottom) {
@@ -88,7 +152,7 @@
mLayoutLatch.countDown();
}
- public void waitForLayout() {
+ void waitForLayout() {
try {
assertTrue("timed out waiting for activity to layout",
mLayoutLatch.await(4, TimeUnit.SECONDS));
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/intent/Activities.java b/tests/framework/base/windowmanager/src/android/server/wm/intent/Activities.java
index 9ba003c..e4cb869 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/intent/Activities.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/intent/Activities.java
@@ -17,6 +17,7 @@
package android.server.wm.intent;
import android.app.Activity;
+import android.os.Bundle;
/**
* A collection of activities with various launch modes used in the intent tests.
@@ -27,60 +28,68 @@
*/
public class Activities {
- public static class TrackerActivity extends Activity {
+ private static class BaseActivity extends Activity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setTitle(getClass().getSimpleName());
+ }
}
- public static class RegularActivity extends Activity {
+ public static class TrackerActivity extends BaseActivity {
}
- public static class SingleTopActivity extends Activity {
+ public static class RegularActivity extends BaseActivity {
}
- public static class SingleInstanceActivity extends Activity {
+ public static class SingleTopActivity extends BaseActivity {
}
- public static class SingleInstanceActivity2 extends Activity {
+ public static class SingleInstanceActivity extends BaseActivity {
}
- public static class SingleTaskActivity extends Activity {
+ public static class SingleInstanceActivity2 extends BaseActivity {
}
- public static class SingleTaskActivity2 extends Activity {
+ public static class SingleTaskActivity extends BaseActivity {
}
- public static class TaskAffinity1Activity extends Activity {
+ public static class SingleTaskActivity2 extends BaseActivity {
}
- public static class TaskAffinity1Activity2 extends Activity {
+ public static class TaskAffinity1Activity extends BaseActivity {
}
- public static class TaskAffinity2Activity extends Activity {
+ public static class TaskAffinity1Activity2 extends BaseActivity {
}
- public static class TaskAffinity3Activity extends Activity {
+ public static class TaskAffinity2Activity extends BaseActivity {
}
- public static class ClearTaskOnLaunchActivity extends Activity {
+ public static class TaskAffinity3Activity extends BaseActivity {
}
- public static class DocumentLaunchIntoActivity extends Activity {
+ public static class ClearTaskOnLaunchActivity extends BaseActivity {
}
- public static class DocumentLaunchAlwaysActivity extends Activity {
+ public static class DocumentLaunchIntoActivity extends BaseActivity {
}
- public static class DocumentLaunchNeverActivity extends Activity {
+ public static class DocumentLaunchAlwaysActivity extends BaseActivity {
}
- public static class NoHistoryActivity extends Activity {
+ public static class DocumentLaunchNeverActivity extends BaseActivity {
}
- public static class LauncherActivity extends Activity {
+ public static class NoHistoryActivity extends BaseActivity {
}
- public static class RelinquishTaskIdentityActivity extends Activity {
+ public static class LauncherActivity extends BaseActivity {
}
- public static class TaskAffinity1RelinquishTaskIdentityActivity extends Activity {
+ public static class RelinquishTaskIdentityActivity extends BaseActivity {
+ }
+
+ public static class TaskAffinity1RelinquishTaskIdentityActivity extends BaseActivity {
}
}
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/intent/LaunchRunner.java b/tests/framework/base/windowmanager/src/android/server/wm/intent/LaunchRunner.java
index 9e1d67a..950047d 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/intent/LaunchRunner.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/intent/LaunchRunner.java
@@ -264,6 +264,11 @@
if (activity == null) {
return activityContext;
+ } else if (startForResult && activityContext == activity) {
+ // The result might have send back to caller activity and forced the caller activity
+ // to resumed again, before the started activity actually resumed. Just wait for idle
+ // for that case.
+ getInstrumentation().waitForIdleSync();
} else {
waitAndAssertActivityLaunched(activity, intent);
}
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 ecbe048..6142b9e 100644
--- a/tests/inputmethod/mockime/src/com/android/cts/mockime/MockIme.java
+++ b/tests/inputmethod/mockime/src/com/android/cts/mockime/MockIme.java
@@ -43,7 +43,6 @@
import android.util.TypedValue;
import android.view.Gravity;
import android.view.KeyEvent;
-import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
@@ -64,7 +63,6 @@
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;
-import android.widget.Toast;
import androidx.annotation.AnyThread;
import androidx.annotation.CallSuper;
@@ -75,6 +73,7 @@
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;
@@ -637,7 +636,7 @@
@GuardedBy("this")
private boolean mSuggestionViewVisible = false;
- public InlineSuggestionsRequest onCreateInlineSuggestionsRequest() {
+ 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),
@@ -694,21 +693,30 @@
Log.d(TAG, "updateSuggestionViews() called on " + suggestionViews.length + " views");
mSuggestionViews = Arrays.asList(suggestionViews);
mSuggestionViewSizes = Arrays.asList(sizes);
- updateInlineSuggestionVisibility(true, true);
+ final boolean visible = !mSuggestionViews.isEmpty();
+ updateInlineSuggestionVisibility(visible, true);
onSuggestionViewUpdated();
}
private void onInlineSuggestionsResponseInternal(InlineSuggestionsResponse response) {
- Log.d(TAG, "onInlineSuggestionsResponseInternal() called. Suggestion="
- + response.getInlineSuggestions().size());
-
+ 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++) {
+ for (int i = 0; i < totalSuggestionsCount; i++) {
final int index = i;
InlineSuggestion inlineSuggestion = inlineSuggestions.get(index);
Size size = inlineSuggestion.getInfo().getPresentationSpec().getMaxSize();
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/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/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/keystore/src/android/keystore/cts/DesCipherPerformanceTest.java b/tests/tests/keystore/src/android/keystore/cts/DesCipherPerformanceTest.java
index 5d9d7aa..527dee5 100644
--- a/tests/tests/keystore/src/android/keystore/cts/DesCipherPerformanceTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/DesCipherPerformanceTest.java
@@ -18,8 +18,6 @@
import android.security.keystore.KeyProperties;
-import org.junit.Test;
-
import java.security.AlgorithmParameters;
import javax.crypto.Cipher;
@@ -31,18 +29,30 @@
final int[] TEST_MESSAGE_SIZES = {1 << 6, 1 << 10, 1 << 17};
public void testDESede_CBC_NoPadding() throws Exception {
+ if (!TestUtils.supports3DES()) {
+ return;
+ }
testDesCipher("DESede/CBC/NoPadding", SUPPORTED_DES_KEY_SIZES, TEST_MESSAGE_SIZES);
}
public void testDESede_CBC_PKCS7Padding() throws Exception {
+ if (!TestUtils.supports3DES()) {
+ return;
+ }
testDesCipher("DESede/CBC/PKCS7Padding", SUPPORTED_DES_KEY_SIZES, TEST_MESSAGE_SIZES);
}
public void testDESede_ECB_NoPadding() throws Exception {
+ if (!TestUtils.supports3DES()) {
+ return;
+ }
testDesCipher("DESede/ECB/NoPadding", SUPPORTED_DES_KEY_SIZES, TEST_MESSAGE_SIZES);
}
public void testDESede_ECB_PKCS7Padding() throws Exception {
+ if (!TestUtils.supports3DES()) {
+ return;
+ }
testDesCipher("DESede/ECB/PKCS7Padding", SUPPORTED_DES_KEY_SIZES, TEST_MESSAGE_SIZES);
}
diff --git a/tests/tests/keystore/src/android/keystore/cts/DesKeyGenPerformanceTest.java b/tests/tests/keystore/src/android/keystore/cts/DesKeyGenPerformanceTest.java
index 195d573..0d9d627 100644
--- a/tests/tests/keystore/src/android/keystore/cts/DesKeyGenPerformanceTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/DesKeyGenPerformanceTest.java
@@ -18,13 +18,14 @@
import android.security.keystore.KeyProperties;
-import org.junit.Test;
-
public class DesKeyGenPerformanceTest extends PerformanceTestBase {
final int[] SUPPORTED_DES_KEY_SIZES = {168};
public void testDesKeyGen() throws Exception {
+ if (!TestUtils.supports3DES()) {
+ return;
+ }
for (int keySize : SUPPORTED_DES_KEY_SIZES) {
measure(
new KeystoreSecretKeyGenMeasurable(
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/hostsidetests/blobstore/test-apps/BlobStoreHelperApp/AndroidManifest.xml b/tests/tests/libthermalndk/AndroidManifest.xml
similarity index 68%
copy from hostsidetests/blobstore/test-apps/BlobStoreHelperApp/AndroidManifest.xml
copy to tests/tests/libthermalndk/AndroidManifest.xml
index a649209..eb6eb22 100644
--- a/hostsidetests/blobstore/test-apps/BlobStoreHelperApp/AndroidManifest.xml
+++ b/tests/tests/libthermalndk/AndroidManifest.xml
@@ -14,13 +14,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
-->
+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.cts.blob.helper">
+ package="android.thermal.cts">
+
<application>
<uses-library android:name="android.test.runner" />
</application>
-
- <instrumentation
- android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="com.android.cts.blob.helper" />
-</manifest>
\ No newline at end of file
+ <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/MediaCodecTest.java b/tests/tests/media/src/android/media/cts/MediaCodecTest.java
index 90125d0..193345a 100644
--- a/tests/tests/media/src/android/media/cts/MediaCodecTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaCodecTest.java
@@ -2532,4 +2532,104 @@
}
}
}
+
+ /**
+ * Test if flushing early in the playback does not prevent client from getting the
+ * latest configuration. Empirically, this happens most often when the
+ * codec is flushed after the first buffer is queued, so this test walks
+ * through the scenario.
+ */
+ public void testFlushAfterFirstBuffer() throws Exception {
+ for (int i = 0; i < 100; ++i) {
+ doFlushAfterFirstBuffer();
+ }
+ }
+
+ private void doFlushAfterFirstBuffer() throws Exception {
+ MediaExtractor extractor = null;
+ MediaCodec codec = null;
+
+ try {
+ MediaFormat newFormat = null;
+ extractor = getMediaExtractorForMimeType(
+ R.raw.noise_2ch_48khz_aot29_dr_sbr_sig2_mp4, "audio/");
+ int trackIndex = extractor.getSampleTrackIndex();
+ MediaFormat format = extractor.getTrackFormat(trackIndex);
+ codec = createCodecByType(
+ format.getString(MediaFormat.KEY_MIME), false /* isEncoder */);
+ codec.configure(format, null, null, 0);
+ codec.start();
+ int firstInputIndex = codec.dequeueInputBuffer(0);
+ while (firstInputIndex == MediaCodec.INFO_TRY_AGAIN_LATER) {
+ firstInputIndex = codec.dequeueInputBuffer(5000);
+ }
+ assertTrue(firstInputIndex >= 0);
+ extractor.readSampleData(codec.getInputBuffer(firstInputIndex), 0);
+ codec.queueInputBuffer(
+ firstInputIndex, 0, Math.toIntExact(extractor.getSampleSize()),
+ extractor.getSampleTime(), extractor.getSampleFlags());
+ // Don't advance, so the first buffer will be read again after flush
+ codec.flush();
+ ByteBuffer csd = format.getByteBuffer("csd-0");
+ MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
+ // We don't need to decode many frames
+ int numFrames = 10;
+ boolean eos = false;
+ while (!eos) {
+ if (numFrames > 0) {
+ int inputIndex = codec.dequeueInputBuffer(0);
+ if (inputIndex == MediaCodec.INFO_TRY_AGAIN_LATER) {
+ inputIndex = codec.dequeueInputBuffer(5000);
+ }
+ if (inputIndex >= 0) {
+ ByteBuffer inputBuffer = codec.getInputBuffer(inputIndex);
+ if (csd != null) {
+ inputBuffer.clear();
+ inputBuffer.put(csd);
+ codec.queueInputBuffer(
+ inputIndex, 0, inputBuffer.position(), 0,
+ MediaCodec.BUFFER_FLAG_CODEC_CONFIG);
+ csd = null;
+ } else {
+ int size = extractor.readSampleData(inputBuffer, 0);
+ if (size <= 0) {
+ break;
+ }
+ int flags = extractor.getSampleFlags();
+ --numFrames;
+ if (numFrames <= 0) {
+ flags |= MediaCodec.BUFFER_FLAG_END_OF_STREAM;
+ }
+ codec.queueInputBuffer(
+ inputIndex, 0, size, extractor.getSampleTime(), flags);
+ extractor.advance();
+ }
+ }
+ }
+
+ int outputIndex = codec.dequeueOutputBuffer(bufferInfo, 0);
+ if (outputIndex == MediaCodec.INFO_TRY_AGAIN_LATER) {
+ outputIndex = codec.dequeueOutputBuffer(bufferInfo, 5000);
+ }
+ if (outputIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
+ newFormat = codec.getOutputFormat();
+ } else if (outputIndex >= 0) {
+ if ((bufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
+ eos = true;
+ }
+ codec.releaseOutputBuffer(outputIndex, false);
+ }
+ }
+ assertNotNull(newFormat);
+ assertEquals(48000, newFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE));
+ } finally {
+ if (extractor != null) {
+ extractor.release();
+ }
+ if (codec != null) {
+ codec.stop();
+ codec.release();
+ }
+ }
+ }
}
diff --git a/tests/tests/media/src/android/media/cts/MediaRoute2ProviderServiceTest.java b/tests/tests/media/src/android/media/cts/MediaRoute2ProviderServiceTest.java
index 98f92d9..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;
@@ -66,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 mService;
+ private StubMediaRoute2ProviderService mService;
private static final int TIMEOUT_MS = 5000;
@@ -93,8 +93,8 @@
new PollingCheck(TIMEOUT_MS) {
@Override
protected boolean check() {
- SampleMediaRoute2ProviderService service =
- SampleMediaRoute2ProviderService.getInstance();
+ StubMediaRoute2ProviderService service =
+ StubMediaRoute2ProviderService.getInstance();
if (service != null) {
mService = service;
return true;
@@ -121,7 +121,7 @@
SESSION_ID_1, "" /* clientPackageName */)
.addSelectedRoute(ROUTE_ID1)
.build();
- mService.notifySessionCreated(sessionInfo1, MediaRoute2ProviderService.REQUEST_ID_UNKNOWN);
+ 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));
@@ -132,7 +132,7 @@
.addSelectedRoute(ROUTE_ID2)
.build();
mService.notifySessionCreated(
- sessionInfo2, MediaRoute2ProviderService.REQUEST_ID_UNKNOWN);
+ sessionInfo2, MediaRoute2ProviderService.REQUEST_ID_NONE);
assertEquals(2, mService.getAllSessionInfo().size());
assertEquals(sessionInfo2, mService.getSessionInfo(SESSION_ID_2));
@@ -288,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);
@@ -307,7 +307,7 @@
}
@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);
@@ -322,7 +322,7 @@
}
@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);
@@ -337,7 +337,7 @@
}
@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);
@@ -353,7 +353,7 @@
}
@Override
- public void onReleaseSession(String sessionId) {
+ public void onReleaseSession(long requestId, String sessionId) {
assertEquals(SESSION_ID_1, sessionId);
mService.notifySessionReleased(sessionId);
onReleaseSessionLatch.countDown();
@@ -455,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);
@@ -557,8 +557,8 @@
}
}
- void setProxy(SampleMediaRoute2ProviderService.Proxy proxy) {
- SampleMediaRoute2ProviderService service = mService;
+ 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 b97e156..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;
@@ -72,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";
@@ -80,7 +80,7 @@
private MediaRouter2 mRouter2;
private Executor mExecutor;
private AudioManager mAudioManager;
- private SampleMediaRoute2ProviderService mService;
+ private StubMediaRoute2ProviderService mService;
private static final int TIMEOUT_MS = 5000;
private static final int WAIT_MS = 2000;
@@ -100,8 +100,8 @@
new PollingCheck(TIMEOUT_MS) {
@Override
protected boolean check() {
- SampleMediaRoute2ProviderService service =
- SampleMediaRoute2ProviderService.getInstance();
+ StubMediaRoute2ProviderService service =
+ StubMediaRoute2ProviderService.getInstance();
if (service != null) {
mService = service;
return true;
@@ -362,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);
@@ -387,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/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/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/cts/DnsResolverTest.java b/tests/tests/net/src/android/net/cts/DnsResolverTest.java
index c32a7a0..1cc49f9 100644
--- a/tests/tests/net/src/android/net/cts/DnsResolverTest.java
+++ b/tests/tests/net/src/android/net/cts/DnsResolverTest.java
@@ -86,7 +86,7 @@
static final int CANCEL_RETRY_TIMES = 5;
static final int QUERY_TIMES = 10;
static final int NXDOMAIN = 3;
- static final int PRIVATE_DNS_SETTING_TIMEOUT_MS = 2_000;
+ static final int PRIVATE_DNS_SETTING_TIMEOUT_MS = 6_000;
private ContentResolver mCR;
private ConnectivityManager mCM;
@@ -122,10 +122,15 @@
mOldDnsSpecifier = Settings.Global.getString(mCR, Settings.Global.PRIVATE_DNS_SPECIFIER);
}
- private void restorePrivateDnsSetting() {
+ private void restorePrivateDnsSetting() throws InterruptedException {
// restore private DNS setting
Settings.Global.putString(mCR, Settings.Global.PRIVATE_DNS_MODE, mOldMode);
- Settings.Global.putString(mCR, Settings.Global.PRIVATE_DNS_SPECIFIER, mOldDnsSpecifier);
+ if ("hostname".equals(mOldMode)) {
+ Settings.Global.putString(
+ mCR, Settings.Global.PRIVATE_DNS_SPECIFIER, mOldDnsSpecifier);
+ mCtsNetUtils.awaitPrivateDnsSetting("restorePrivateDnsSetting timeout",
+ mCM.getActiveNetwork(), mOldDnsSpecifier, PRIVATE_DNS_SETTING_TIMEOUT_MS, true);
+ }
}
private static String byteArrayToHexString(byte[] bytes) {
@@ -203,6 +208,7 @@
private final CancellationSignal mCancelSignal;
private int mRcode;
private DnsAnswer mDnsAnswer;
+ private String mErrorMsg = null;
VerifyCancelCallback(@NonNull String msg, @Nullable CancellationSignal cancel) {
mMsg = msg;
@@ -228,14 +234,18 @@
@Override
public void onAnswer(@NonNull byte[] answer, int rcode) {
if (mCancelSignal != null && mCancelSignal.isCanceled()) {
- fail(mMsg + " should not have returned any answers");
+ mErrorMsg = mMsg + " should not have returned any answers";
+ mLatch.countDown();
+ return;
}
mRcode = rcode;
try {
mDnsAnswer = new DnsAnswer(answer);
} catch (ParseException | DnsParseException e) {
- fail(mMsg + e.getMessage());
+ mErrorMsg = mMsg + e.getMessage();
+ mLatch.countDown();
+ return;
}
Log.d(TAG, "Reported blob: " + byteArrayToHexString(answer));
mLatch.countDown();
@@ -243,10 +253,12 @@
@Override
public void onError(@NonNull DnsResolver.DnsException error) {
- fail(mMsg + error.getMessage());
+ mErrorMsg = mMsg + error.getMessage();
+ mLatch.countDown();
}
private void assertValidAnswer() {
+ assertNull(mErrorMsg);
assertNotNull(mMsg + " No valid answer", mDnsAnswer);
assertEquals(mMsg + " Unexpected error: reported rcode" + mRcode +
" blob's rcode " + mDnsAnswer.getRcode(), mRcode, mDnsAnswer.getRcode());
@@ -402,20 +414,18 @@
public void doTestRawQueryNXDomainWithPrivateDns(Executor executor)
throws InterruptedException {
final String msg = "RawQuery " + TEST_NX_DOMAIN + " with private DNS";
-
// Enable private DNS strict mode and set server to dns.google before doing NxDomain test.
// b/144521720
Settings.Global.putString(mCR, Settings.Global.PRIVATE_DNS_MODE, "hostname");
Settings.Global.putString(mCR,
Settings.Global.PRIVATE_DNS_SPECIFIER, GOOGLE_PRIVATE_DNS_SERVER);
-
for (Network network : getTestableNetworks()) {
final Network networkForPrivateDns =
(network != null) ? network : mCM.getActiveNetwork();
assertNotNull("Can't find network to await private DNS on", networkForPrivateDns);
mCtsNetUtils.awaitPrivateDnsSetting(msg + " wait private DNS setting timeout",
networkForPrivateDns, GOOGLE_PRIVATE_DNS_SERVER,
- PRIVATE_DNS_SETTING_TIMEOUT_MS);
+ PRIVATE_DNS_SETTING_TIMEOUT_MS, true);
final VerifyCancelCallback callback = new VerifyCancelCallback(msg);
mDns.rawQuery(network, TEST_NX_DOMAIN, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP,
executor, null, callback);
@@ -508,6 +518,7 @@
private final String mMsg;
private final List<InetAddress> mAnswers;
private final CancellationSignal mCancelSignal;
+ private String mErrorMsg = null;
VerifyCancelInetAddressCallback(@NonNull String msg, @Nullable CancellationSignal cancel) {
this.mMsg = msg;
@@ -541,10 +552,16 @@
return false;
}
+ public void assertNoError() {
+ assertNull(mErrorMsg);
+ }
+
@Override
public void onAnswer(@NonNull List<InetAddress> answerList, int rcode) {
if (mCancelSignal != null && mCancelSignal.isCanceled()) {
- fail(mMsg + " should not have returned any answers");
+ mErrorMsg = mMsg + " should not have returned any answers";
+ mLatch.countDown();
+ return;
}
for (InetAddress addr : answerList) {
Log.d(TAG, "Reported addr: " + addr.toString());
@@ -556,7 +573,7 @@
@Override
public void onError(@NonNull DnsResolver.DnsException error) {
- fail(mMsg + error.getMessage());
+ mErrorMsg = mMsg + error.getMessage();
}
}
@@ -601,6 +618,7 @@
assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.",
callback.waitForAnswer());
+ callback.assertNoError();
assertTrue(msg + " returned 0 results", !callback.isAnswerEmpty());
}
}
@@ -644,6 +662,7 @@
assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.",
callback.waitForAnswer());
+ callback.assertNoError();
assertTrue(msg + " returned 0 results", !callback.isAnswerEmpty());
assertTrue(msg + " returned Ipv6 results", !callback.hasIpv6Answer());
}
@@ -659,6 +678,7 @@
assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.",
callback.waitForAnswer());
+ callback.assertNoError();
assertTrue(msg + " returned 0 results", !callback.isAnswerEmpty());
assertTrue(msg + " returned Ipv4 results", !callback.hasIpv4Answer());
}
@@ -671,7 +691,6 @@
Settings.Global.putString(mCR, Settings.Global.PRIVATE_DNS_MODE, "hostname");
Settings.Global.putString(mCR,
Settings.Global.PRIVATE_DNS_SPECIFIER, INVALID_PRIVATE_DNS_SERVER);
-
final String msg = "Test PrivateDnsBypass " + TEST_DOMAIN;
for (Network network : testNetworks) {
// This test cannot be ran with null network because we need to explicitly pass a
@@ -680,7 +699,7 @@
// wait for private DNS setting propagating
mCtsNetUtils.awaitPrivateDnsSetting(msg + " wait private DNS setting timeout",
- network, INVALID_PRIVATE_DNS_SERVER, PRIVATE_DNS_SETTING_TIMEOUT_MS);
+ network, INVALID_PRIVATE_DNS_SERVER, PRIVATE_DNS_SETTING_TIMEOUT_MS, false);
final CountDownLatch latch = new CountDownLatch(1);
final DnsResolver.Callback<List<InetAddress>> errorCallback =
@@ -712,6 +731,7 @@
assertTrue(msg + " bypass private DNS round. No answer after " + TIMEOUT_MS + "ms.",
callback.waitForAnswer());
+ callback.assertNoError();
assertTrue(msg + " returned 0 results", !callback.isAnswerEmpty());
// To ensure private DNS bypass still work even if passing null network.
@@ -724,6 +744,7 @@
assertTrue(msg + " with null network bypass private DNS round. No answer after " +
TIMEOUT_MS + "ms.", callbackWithNullNetwork.waitForAnswer());
+ callbackWithNullNetwork.assertNoError();
assertTrue(msg + " with null network returned 0 results",
!callbackWithNullNetwork.isAnswerEmpty());
@@ -745,6 +766,7 @@
assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.",
callback.waitForAnswer());
+ callback.assertNoError();
assertTrue(msg + " returned 0 results", !callback.isAnswerEmpty());
assertTrue(msg + " returned " + (queryV6 ? "Ipv4" : "Ipv6") + " results",
queryV6 ? !callback.hasIpv4Answer() : !callback.hasIpv6Answer());
diff --git a/tests/tests/net/src/android/net/cts/MultinetworkApiTest.java b/tests/tests/net/src/android/net/cts/MultinetworkApiTest.java
index 766c55e..f123187 100644
--- a/tests/tests/net/src/android/net/cts/MultinetworkApiTest.java
+++ b/tests/tests/net/src/android/net/cts/MultinetworkApiTest.java
@@ -245,7 +245,7 @@
for (Network network : getTestableNetworks()) {
// Wait for private DNS setting to propagate.
mCtsNetUtils.awaitPrivateDnsSetting("NxDomain test wait private DNS setting timeout",
- network, GOOGLE_PRIVATE_DNS_SERVER, PRIVATE_DNS_SETTING_TIMEOUT_MS);
+ network, GOOGLE_PRIVATE_DNS_SERVER, PRIVATE_DNS_SETTING_TIMEOUT_MS, true);
runResNnxDomainCheck(network.getNetworkHandle());
}
} finally {
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/net/util/java/android/net/cts/util/CtsNetUtils.java b/tests/tests/net/util/java/android/net/cts/util/CtsNetUtils.java
index f0c34e3..6214f89 100644
--- a/tests/tests/net/util/java/android/net/cts/util/CtsNetUtils.java
+++ b/tests/tests/net/util/java/android/net/cts/util/CtsNetUtils.java
@@ -56,6 +56,7 @@
private static final String TAG = CtsNetUtils.class.getSimpleName();
private static final int DURATION = 10000;
private static final int SOCKET_TIMEOUT_MS = 2000;
+ private static final int PRIVATE_DNS_PROBE_MS = 1_000;
public static final int HTTP_PORT = 80;
public static final String TEST_HOST = "connectivitycheck.gstatic.com";
@@ -246,12 +247,16 @@
}
public void awaitPrivateDnsSetting(@NonNull String msg, @NonNull Network network,
- @NonNull String server, int timeoutMs) throws InterruptedException {
+ @NonNull String server, int timeoutMs,
+ boolean requiresValidatedServers) throws InterruptedException {
CountDownLatch latch = new CountDownLatch(1);
NetworkRequest request = new NetworkRequest.Builder().clearCapabilities().build();
NetworkCallback callback = new NetworkCallback() {
@Override
public void onLinkPropertiesChanged(Network n, LinkProperties lp) {
+ if (requiresValidatedServers && lp.getValidatedPrivateDnsServers().isEmpty()) {
+ return;
+ }
if (network.equals(n) && server.equals(lp.getPrivateDnsServerName())) {
latch.countDown();
}
@@ -260,6 +265,18 @@
mCm.registerNetworkCallback(request, callback);
assertTrue(msg, latch.await(timeoutMs, TimeUnit.MILLISECONDS));
mCm.unregisterNetworkCallback(callback);
+ // Wait some time for NetworkMonitor's private DNS probe to complete. If we do not do
+ // this, then the test could complete before the NetworkMonitor private DNS probe
+ // completes. This would result in tearDown disabling private DNS, and the NetworkMonitor
+ // private DNS probe getting stuck because there are no longer any private DNS servers to
+ // query. This then results in the next test not being able to change the private DNS
+ // setting within the timeout, because the NetworkMonitor thread is blocked in the
+ // private DNS probe. There is no way to know when the probe has completed: because the
+ // network is likely already validated, there is no callback that we can listen to, so
+ // just sleep.
+ if (requiresValidatedServers) {
+ Thread.sleep(PRIVATE_DNS_PROBE_MS);
+ }
}
/**
diff --git a/tests/tests/packageinstaller/adminpackageinstaller/AndroidManifest.xml b/tests/tests/packageinstaller/adminpackageinstaller/AndroidManifest.xml
index 6eabfb0..3867e9f 100755
--- a/tests/tests/packageinstaller/adminpackageinstaller/AndroidManifest.xml
+++ b/tests/tests/packageinstaller/adminpackageinstaller/AndroidManifest.xml
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
+<?xml version="1.0" encoding="utf-8"?> <!-- 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.
@@ -18,6 +17,7 @@
package="android.packageinstaller.admin.cts" >
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
+ <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
<application android:label="Cts Admin Package Installer Test" android:testOnly="true">
<uses-library android:name="android.test.runner"/>
diff --git a/tests/tests/packageinstaller/install/AndroidManifest.xml b/tests/tests/packageinstaller/install/AndroidManifest.xml
index eeef252..4ece1a9 100644
--- a/tests/tests/packageinstaller/install/AndroidManifest.xml
+++ b/tests/tests/packageinstaller/install/AndroidManifest.xml
@@ -18,6 +18,7 @@
package="android.packageinstaller.install.cts" >
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
+ <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
<application android:label="Cts Package Installer Tests">
<uses-library android:name="android.test.runner" />
diff --git a/tests/tests/packageinstaller/nopermission/AndroidManifest.xml b/tests/tests/packageinstaller/nopermission/AndroidManifest.xml
index 321066c..08a7db1 100755
--- a/tests/tests/packageinstaller/nopermission/AndroidManifest.xml
+++ b/tests/tests/packageinstaller/nopermission/AndroidManifest.xml
@@ -17,6 +17,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.packageinstaller.nopermission.cts" >
+ <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
+
<application>
<uses-library android:name="android.test.runner" />
diff --git a/tests/tests/permission2/res/raw/android_manifest.xml b/tests/tests/permission2/res/raw/android_manifest.xml
index 09f31d9..9bbc177 100644
--- a/tests/tests/permission2/res/raw/android_manifest.xml
+++ b/tests/tests/permission2/res/raw/android_manifest.xml
@@ -2764,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/provider/src/android/provider/cts/media/MediaStore_FilesTest.java b/tests/tests/provider/src/android/provider/cts/media/MediaStore_FilesTest.java
index 061fe38..7228c7c 100644
--- a/tests/tests/provider/src/android/provider/cts/media/MediaStore_FilesTest.java
+++ b/tests/tests/provider/src/android/provider/cts/media/MediaStore_FilesTest.java
@@ -116,9 +116,9 @@
assertEquals(1, mResolver.update(fileUri, values, null, null));
assertStringColumn(fileUri, MediaColumns.DATA, updatedPath);
- // check that inserting a duplicate entry fails
+ // check that inserting a duplicate entry updates previous entry.
Uri foo = mResolver.insert(allFilesUri, values);
- assertNull(foo);
+ assertEquals(foo, fileUri);
// Delete the file and observe that the file count decreased.
assertEquals(1, mResolver.delete(fileUri, null, null));
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/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..74198582 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);