Merge "CameraITS: Show CameraITS app in Folded state." into android13-tests-dev
diff --git a/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py b/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py
index 974fc24..7283f20 100644
--- a/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py
+++ b/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py
@@ -234,6 +234,8 @@
raw_avlb = camera_properties_utils.raw16(props)
debug = self.debug_mode
+ # Converge 3A.
+ cam.do_3a()
req = capture_request_utils.auto_capture_request()
# If raw available, use as ground truth.
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index e8994f5..6d11ea5 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -18,7 +18,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.cts.verifier"
android:versionCode="5"
- android:versionName="13_r3">
+ android:versionName="13_r4">
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="33"/>
@@ -2085,7 +2085,7 @@
<category android:name="android.cts.intent.category.MANUAL_TEST" />
</intent-filter>
<meta-data android:name="test_category" android:value="@string/test_category_hardware" />
- <meta-data android:name="test_required_features" android:value="android.hardware.nfc" />
+ <meta-data android:name="test_applicable_features" android:value="android.hardware.nfc:android.hardware.nfc.hce" />
<meta-data android:name="display_mode"
android:value="multi_display_mode" />
<meta-data android:name="NonApiTest" android:value="Helper class. List test activities" />
diff --git a/apps/CtsVerifier/res/layout/logcat_read_logs.xml b/apps/CtsVerifier/res/layout/logcat_read_logs.xml
index e7cf4ab..db48502 100644
--- a/apps/CtsVerifier/res/layout/logcat_read_logs.xml
+++ b/apps/CtsVerifier/res/layout/logcat_read_logs.xml
@@ -14,40 +14,43 @@
~ See the License for the specific language governing permissions and
~ limitations under the License
-->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ style="@style/RootLayoutPadding"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- android:padding="10dip"
->
+ android:layout_height="match_parent">
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textAppearance="?android:attr/textAppearanceLarge"
- android:text="Test should be executed at least 2 minutes apart"
- android:id="@+id/run_read_logs_title"
- android:layout_margin="2dp"
- android:textSize="14sp"
- android:textStyle="bold"
- />
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
- <Button android:id="@+id/run_read_logs_fg_allow_btn"
- android:text="@string/read_logs_fg_allow_text"
- android:layout_marginBottom="20dp"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceLarge"
+ android:text="Test should be executed at least 2 minutes apart"
+ android:id="@+id/run_read_logs_title"
+ android:layout_margin="2dp"
+ android:textSize="14sp"
+ android:textStyle="bold"
+ />
- <Button android:id="@+id/run_read_logs_fg_deny_btn"
- android:text="@string/read_logs_fg_deny_text"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
+ <Button android:id="@+id/run_read_logs_fg_allow_btn"
+ android:text="@string/read_logs_fg_allow_text"
+ android:layout_marginBottom="20dp"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
- <include android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_alignParentBottom="true"
- layout="@layout/pass_fail_buttons"
- />
+ <Button android:id="@+id/run_read_logs_fg_deny_btn"
+ android:text="@string/read_logs_fg_deny_text"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
-</LinearLayout>
+ <include android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentBottom="true"
+ layout="@layout/pass_fail_buttons"
+ />
+ </LinearLayout>
+</ScrollView>
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index 9b4641f..a0dd36c 100644
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -5465,6 +5465,8 @@
<string name="audio_general_pass">PASS</string>
<string name="audio_general_fail">FAIL</string>
<string name="audio_general_not_tested">Not Tested</string>
+ <string name="audio_general_not_required">Please Test If Supported</string>
+ <string name="audio_general_required">Required</string>
<string name="audio_general_Input">Input</string>
<string name="audio_general_Output">Output</string>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioLoopbackLatencyActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioLoopbackLatencyActivity.java
index 413734b..2e5046a 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioLoopbackLatencyActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioLoopbackLatencyActivity.java
@@ -86,6 +86,8 @@
String mPassString;
String mFailString;
String mNotTestedString;
+ String mNotRequiredString;
+ String mRequiredString;
// These flags determine the maximum allowed latency
private boolean mClaimsProAudio;
@@ -281,6 +283,7 @@
// Speaker/Mic Path
mTestSpecs[TESTROUTE_DEVICE] =
new TestSpec(TESTROUTE_DEVICE, CONFIDENCE_THRESHOLD_AMBIENT);
+ mTestSpecs[TESTROUTE_DEVICE].mRouteAvailable = true; // Always
// Analog Jack Path
mTestSpecs[TESTROUTE_ANALOG_JACK] =
@@ -296,7 +299,9 @@
mNoString = resources.getString(R.string.audio_general_no);
mPassString = resources.getString(R.string.audio_general_pass);
mFailString = resources.getString(R.string.audio_general_fail);
- mNotTestedString = resources.getString(R.string.audio_general_not_tested) + " ";
+ mNotTestedString = resources.getString(R.string.audio_general_not_tested);
+ mNotRequiredString = resources.getString(R.string.audio_general_not_required);
+ mRequiredString = resources.getString(R.string.audio_general_required);
// Pro Audio
((TextView) findViewById(R.id.audio_loopback_pro_audio)).setText(
@@ -342,6 +347,8 @@
connectLoopbackUI();
enableStartButtons(true);
+
+ handleTestCompletion(false);
}
//
@@ -632,14 +639,14 @@
mTestPhase++;
if (mTestPhase >= NUM_TEST_PHASES) {
- handleTestCompletion();
+ handleTestCompletion(true);
} else {
startTestPhase();
}
}
}
- private void handleTestCompletion() {
+ private void handleTestCompletion(boolean showResult) {
TestSpec testSpec = mTestSpecs[mTestRoute];
testSpec.handleTestCompletion();
@@ -657,13 +664,13 @@
LoopbackLatencyRequirements requirements = new LoopbackLatencyRequirements();
boolean pass = isReportLogOkToPass()
&& requirements.evaluate(mClaimsProAudio,
- Build.VERSION.MEDIA_PERFORMANCE_CLASS,
- mTestSpecs[TESTROUTE_DEVICE].isMeasurementValid()
- ? mTestSpecs[TESTROUTE_DEVICE].mMeanLatencyMS : 0.0,
- mTestSpecs[TESTROUTE_ANALOG_JACK].isMeasurementValid()
- ? mTestSpecs[TESTROUTE_ANALOG_JACK].mMeanLatencyMS : 0.0,
- mTestSpecs[TESTROUTE_USB].isMeasurementValid()
- ? mTestSpecs[TESTROUTE_USB].mMeanLatencyMS : 0.0);
+ Build.VERSION.MEDIA_PERFORMANCE_CLASS,
+ mTestSpecs[TESTROUTE_DEVICE].isMeasurementValid()
+ ? mTestSpecs[TESTROUTE_DEVICE].mMeanLatencyMS : 0.0,
+ mTestSpecs[TESTROUTE_ANALOG_JACK].isMeasurementValid()
+ ? mTestSpecs[TESTROUTE_ANALOG_JACK].mMeanLatencyMS : 0.0,
+ mTestSpecs[TESTROUTE_USB].isMeasurementValid()
+ ? mTestSpecs[TESTROUTE_USB].mMeanLatencyMS : 0.0);
getPassButton().setEnabled(pass);
@@ -672,6 +679,9 @@
sb.append(getResources().getString(R.string.audio_general_reportlogtest) + "\n");
}
sb.append(requirements.getResultsString());
+ if (showResult) {
+ sb.append("\n" + (pass ? mPassString : mFailString));
+ }
mTestStatusText.setText(sb.toString());
showWait(false);
@@ -694,16 +704,16 @@
case NativeAnalyzerThread.NATIVE_AUDIO_THREAD_MESSAGE_OPEN_ERROR:
Log.v(TAG,"got message native rec can't start!!");
mTestStatusText.setText("Test Error opening streams.");
- handleTestCompletion();
+ handleTestCompletion(true);
break;
case NativeAnalyzerThread.NATIVE_AUDIO_THREAD_MESSAGE_REC_ERROR:
Log.v(TAG,"got message native rec can't start!!");
mTestStatusText.setText("Test Error while recording.");
- handleTestCompletion();
+ handleTestCompletion(true);
break;
case NativeAnalyzerThread.NATIVE_AUDIO_THREAD_MESSAGE_REC_COMPLETE_ERRORS:
mTestStatusText.setText("Test FAILED due to errors.");
- handleTestCompletion();
+ handleTestCompletion(true);
break;
case NativeAnalyzerThread.NATIVE_AUDIO_THREAD_MESSAGE_ANALYZING:
mTestStatusText.setText(String.format("[phase: %d] - Analyzing ...",
@@ -753,6 +763,10 @@
double deviceLatency,
double analogLatency,
double usbLatency) {
+
+ // Required to test the Mic/Speaker path
+ boolean internalPathRun = deviceLatency != LATENCY_NOT_MEASURED;
+
// All devices must be under the basic limit.
boolean basicPass = checkLatency(deviceLatency, LATENCY_BASIC)
&& checkLatency(analogLatency, LATENCY_BASIC)
@@ -783,7 +797,11 @@
}
boolean pass =
- basicPass && mpcAtLeastOnePass && proAudioAtLeastOnePass && proAudioLimitsPass;
+ internalPathRun &&
+ basicPass &&
+ mpcAtLeastOnePass &&
+ proAudioAtLeastOnePass &&
+ proAudioLimitsPass;
// Build the results explanation
StringBuilder sb = new StringBuilder();
@@ -796,19 +814,17 @@
}
sb.append(" ");
- sb.append("Speaker/Mic: " + (deviceLatency != LATENCY_NOT_MEASURED
+ sb.append("\nSpeaker/Mic: " + (deviceLatency != LATENCY_NOT_MEASURED
? String.format("%.2fms ", deviceLatency)
- : mNotTestedString));
- sb.append("Headset: " + (analogLatency != LATENCY_NOT_MEASURED
+ : (mNotTestedString + " - " + mRequiredString)));
+ sb.append("\nHeadset: " + (analogLatency != LATENCY_NOT_MEASURED
? String.format("%.2fms ", analogLatency)
- : mNotTestedString));
- sb.append("USB: " + (usbLatency != LATENCY_NOT_MEASURED
+ : (mNotTestedString + " - " + mNotRequiredString)));
+ sb.append("\nUSB: " + (usbLatency != LATENCY_NOT_MEASURED
? String.format("%.2fms ", usbLatency)
- : mNotTestedString));
+ : (mNotTestedString + " - " + mNotRequiredString)));
sb.append(supplementalText);
-
- sb.append(pass ? mPassString : mFailString);
mResultsString = sb.toString();
return pass;
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioTap2ToneActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioTap2ToneActivity.java
index 8ff2358..cf09a74 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioTap2ToneActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioTap2ToneActivity.java
@@ -16,6 +16,11 @@
package com.android.cts.verifier.audio;
+import static com.android.cts.verifier.TestListActivity.sCurrentDisplayMode;
+import static com.android.cts.verifier.TestListAdapter.setTestNameSuffix;
+
+import android.mediapc.cts.common.PerformanceClassEvaluator;
+
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
@@ -46,6 +51,7 @@
import org.hyphonate.megaaudio.recorder.AudioSinkProvider;
import org.hyphonate.megaaudio.recorder.sinks.AppCallback;
import org.hyphonate.megaaudio.recorder.sinks.AppCallbackAudioSinkProvider;
+import org.junit.rules.TestName;
/**
* CtsVerifier test to measure tap-to-tone latency.
@@ -144,6 +150,8 @@
private static final String KEY_LATENCY_AVE = "latency_max_";
private static final String KEY_LATENCY_NUM_MEASUREMENTS = "latency_num_measurements_";
+ public final TestName testName = new TestName();
+
@Override
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.audio_tap2tone_activity);
@@ -505,6 +513,54 @@
super.setTestResultAndFinish(passed);
}
+ private void reportTestResultForApi(int api) {
+ CtsVerifierReportLog reportLog = getReportLog();
+ reportLog.addValue(
+ KEY_LATENCY_MIN + api,
+ mLatencyMin[api],
+ ResultType.NEUTRAL,
+ ResultUnit.NONE);
+ reportLog.addValue(
+ KEY_LATENCY_MAX + api,
+ mLatencyMax[api],
+ ResultType.NEUTRAL,
+ ResultUnit.NONE);
+ reportLog.addValue(
+ KEY_LATENCY_AVE + api,
+ mLatencyAve[api],
+ ResultType.NEUTRAL,
+ ResultUnit.NONE);
+ reportLog.addValue(
+ KEY_LATENCY_NUM_MEASUREMENTS + api,
+ mNumMeasurements[api],
+ ResultType.NEUTRAL,
+ ResultUnit.NONE);
+ }
+
+ /** Records perf class results and returns if mpc is met */
+ private void recordPerfClassResults() {
+ PerformanceClassEvaluator pce = new PerformanceClassEvaluator(testName);
+ PerformanceClassEvaluator.AudioTap2ToneLatencyRequirement r5_6__h_1_1 =
+ pce.addR5_6__H_1_1();
+
+ r5_6__h_1_1.setNativeLatency(mLatencyAve[TEST_API_NATIVE]);
+ r5_6__h_1_1.setJavaLatency(mLatencyAve[TEST_API_JAVA]);
+
+ pce.submitAndVerify();
+ }
+
+ @Override
+ public void recordTestResults() {
+ Log.i(TAG, "recordTestResults()");
+
+ reportTestResultForApi(TEST_API_NATIVE);
+ reportTestResultForApi(TEST_API_JAVA);
+
+ getReportLog().submit();
+
+ recordPerfClassResults();
+ }
+
//
// AppCallback overrides
//
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsTestActivity.java
index 692538a..9f43e85 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsTestActivity.java
@@ -392,7 +392,7 @@
// Save MPC info once both front primary and rear primary data are collected.
if (mExecutedMpcTests.size() == 4) {
- mPce.submit();
+ mPce.submitAndVerify();
}
return true;
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/NfcTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/NfcTestActivity.java
index 4cc0da8..a0eb2ea 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/NfcTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/NfcTestActivity.java
@@ -54,19 +54,23 @@
ArrayTestListAdapter adapter = new ArrayTestListAdapter(this);
- adapter.add(TestListItem.newCategory(this, R.string.nfc_tag_verification));
- adapter.add(TestListItem.newTest(this, R.string.nfc_ndef,
- NDEF_ID, getTagIntent(Ndef.class), null));
- if (getPackageManager().hasSystemFeature(FEATURE_NFC_MIFARE)) {
- adapter.add(TestListItem.newTest(this, R.string.nfc_mifare_ultralight,
- MIFARE_ULTRALIGHT_ID, getTagIntent(MifareUltralight.class), null));
+ if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_NFC)) {
+ adapter.add(TestListItem.newCategory(this, R.string.nfc_tag_verification));
+ adapter.add(TestListItem.newTest(this, R.string.nfc_ndef,
+ NDEF_ID, getTagIntent(Ndef.class), null));
+ if (getPackageManager().hasSystemFeature(FEATURE_NFC_MIFARE)) {
+ adapter.add(TestListItem.newTest(this, R.string.nfc_mifare_ultralight,
+ MIFARE_ULTRALIGHT_ID, getTagIntent(MifareUltralight.class), null));
+ }
}
if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION)) {
adapter.add(TestListItem.newCategory(this, R.string.nfc_hce));
- adapter.add(TestListItem.newTest(this, R.string.nfc_hce_reader_tests,
- HceReaderTestActivity.class.getName(),
- new Intent(this, HceReaderTestActivity.class), null));
+ if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_NFC)) {
+ adapter.add(TestListItem.newTest(this, R.string.nfc_hce_reader_tests,
+ HceReaderTestActivity.class.getName(),
+ new Intent(this, HceReaderTestActivity.class), null));
+ }
adapter.add(TestListItem.newTest(this, R.string.nfc_hce_emulator_tests,
HceEmulatorTestActivity.class.getName(),
new Intent(this, HceEmulatorTestActivity.class), null));
@@ -74,9 +78,11 @@
if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION_NFCF)) {
adapter.add(TestListItem.newCategory(this, R.string.nfc_hce_f));
- adapter.add(TestListItem.newTest(this, R.string.nfc_hce_f_reader_tests,
- HceFReaderTestActivity.class.getName(),
- new Intent(this, HceFReaderTestActivity.class), null));
+ if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_NFC)) {
+ adapter.add(TestListItem.newTest(this, R.string.nfc_hce_f_reader_tests,
+ HceFReaderTestActivity.class.getName(),
+ new Intent(this, HceFReaderTestActivity.class), null));
+ }
adapter.add(TestListItem.newTest(this, R.string.nfc_hce_f_emulator_tests,
HceFEmulatorTestActivity.class.getName(),
new Intent(this, HceFEmulatorTestActivity.class), null));
@@ -84,9 +90,11 @@
if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_NFC_OFF_HOST_CARD_EMULATION_UICC)) {
adapter.add(TestListItem.newCategory(this, R.string.nfc_offhost_uicc));
- adapter.add(TestListItem.newTest(this, R.string.nfc_offhost_uicc_reader_tests,
- OffhostUiccReaderTestActivity.class.getName(),
- new Intent(this, OffhostUiccReaderTestActivity.class), null));
+ if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_NFC)) {
+ adapter.add(TestListItem.newTest(this, R.string.nfc_offhost_uicc_reader_tests,
+ OffhostUiccReaderTestActivity.class.getName(),
+ new Intent(this, OffhostUiccReaderTestActivity.class), null));
+ }
adapter.add(TestListItem.newTest(this, R.string.nfc_offhost_uicc_emulator_tests,
OffhostUiccEmulatorTestActivity.class.getName(),
new Intent(this, OffhostUiccEmulatorTestActivity.class), null));
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/security/FingerprintBoundKeysTest.java b/apps/CtsVerifier/src/com/android/cts/verifier/security/FingerprintBoundKeysTest.java
index b804b45..a0f5bd0 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/security/FingerprintBoundKeysTest.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/security/FingerprintBoundKeysTest.java
@@ -24,6 +24,8 @@
import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
+import android.hardware.biometrics.BiometricManager;
+import android.hardware.biometrics.BiometricManager.Authenticators;
import android.hardware.fingerprint.FingerprintManager;
import android.os.Bundle;
import android.os.CancellationSignal;
@@ -70,6 +72,8 @@
protected boolean useStrongBox;
+ private BiometricManager mBiometricManager;
+
private FingerprintManager mFingerprintManager;
private KeyguardManager mKeyguardManager;
private FingerprintAuthDialogFragment mFingerprintDialog;
@@ -92,6 +96,10 @@
getPassButton().setEnabled(false);
requestPermissions(new String[]{Manifest.permission.USE_BIOMETRIC},
BIOMETRIC_REQUEST_PERMISSION_CODE);
+
+ mBiometricManager = getSystemService(BiometricManager.class);
+
+ checkBiometricStrength();
}
@Override
@@ -134,6 +142,28 @@
}
}
+ private void checkBiometricStrength()
+ {
+ if (!hasStrongBiometrics())
+ {
+ // Disable the start button
+ Button startTestButton = findViewById(R.id.sec_start_test_button);
+ startTestButton.setEnabled(false);
+
+ // Show a message that STRONG Biometrics is not supported and user can
+ // pass the test.
+ showToast("Device does not support STRONG Biometric level of authentication.");
+
+ // Allow to pass the test
+ getPassButton().setEnabled(true);
+ }
+ }
+
+ private boolean hasStrongBiometrics() {
+ return mBiometricManager.canAuthenticate(Authenticators.BIOMETRIC_STRONG)
+ != BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE;
+ }
+
protected void startTest() {
createKey(false /* hasValidityDuration */);
prepareEncrypt();
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/TvInputDiscoveryTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/TvInputDiscoveryTestActivity.java
index 4f68e8b..6b3bbe0 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/tv/TvInputDiscoveryTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/TvInputDiscoveryTestActivity.java
@@ -47,7 +47,6 @@
private View mTuneToChannelItem;
private View mVerifyTuneItem;
private View mVerifyOverlayViewItem;
- private View mVerifyGlobalSearchItem;
private View mVerifyOverlayViewSizeChanged;
private View mGoToEpgItem;
private View mVerifyEpgItem;
@@ -57,7 +56,6 @@
private View mSupportThirdPartyInputNoItem;
private boolean mTuneVerified;
private boolean mOverlayViewVerified;
- private boolean mGlobalSearchVerified;
private boolean mOverlayViewSizeChangedVerified;
@Override
@@ -130,7 +128,7 @@
goToNextState(postTarget, failCallback);
}
});
- verifyGlobalSearch(postTarget, failCallback);
+ // TODO: handle GLOBAL_SEARCH permission and verify global search
startActivity(TV_APP_INTENT);
} else if (containsButton(mGoToEpgItem, v)) {
startActivity(EPG_INTENT);
@@ -168,8 +166,6 @@
R.string.tv_input_discover_test_verify_overlay_view);
mVerifyOverlayViewSizeChanged = createAndAttachAutoItem(
R.string.tv_input_discover_test_verify_size_changed);
- mVerifyGlobalSearchItem = createAndAttachAutoItem(
- R.string.tv_input_discover_test_verify_global_search);
mGoToEpgItem = createAndAttachUserItem(R.string.tv_input_discover_test_go_to_epg,
R.string.tv_launch_epg, this);
mVerifyEpgItem = createAndAttachUserItem(R.string.tv_input_discover_test_verify_epg,
@@ -187,38 +183,9 @@
}
private void goToNextState(View postTarget, Runnable failCallback) {
- if (mTuneVerified && mOverlayViewVerified
- && mGlobalSearchVerified && mOverlayViewSizeChangedVerified) {
+ if (mTuneVerified && mOverlayViewVerified && mOverlayViewSizeChangedVerified) {
postTarget.removeCallbacks(failCallback);
setButtonEnabled(mGoToEpgItem, true);
}
}
-
- private void verifyGlobalSearch(final View postTarget, final Runnable failCallback) {
- new AsyncTask<Void, Void, Boolean>() {
- @Override
- protected Boolean doInBackground(Void... params) {
- Context context = TvInputDiscoveryTestActivity.this;
- for (SearchableInfo info : SearchUtil.getSearchableInfos(context)) {
- if (SearchUtil.verifySearchResult(context, info,
- MockTvInputSetupActivity.CHANNEL_NAME,
- MockTvInputSetupActivity.PROGRAM_TITLE)
- && SearchUtil.verifySearchResult(context, info,
- MockTvInputSetupActivity.PROGRAM_TITLE,
- MockTvInputSetupActivity.PROGRAM_TITLE)) {
- return true;
- }
- }
- return false;
- }
-
- @Override
- protected void onPostExecute(Boolean result) {
- super.onPostExecute(result);
- setPassState(mVerifyGlobalSearchItem, result);
- mGlobalSearchVerified = result;
- goToNextState(postTarget, failCallback);
- }
- }.execute();
- }
}
diff --git a/hostsidetests/graphics/framerateoverride/app/src/com/android/cts/graphics/framerateoverride/FrameRateOverrideTest.java b/hostsidetests/graphics/framerateoverride/app/src/com/android/cts/graphics/framerateoverride/FrameRateOverrideTest.java
index af0d156..6b79ac1 100644
--- a/hostsidetests/graphics/framerateoverride/app/src/com/android/cts/graphics/framerateoverride/FrameRateOverrideTest.java
+++ b/hostsidetests/graphics/framerateoverride/app/src/com/android/cts/graphics/framerateoverride/FrameRateOverrideTest.java
@@ -134,20 +134,30 @@
if (!SurfaceFlingerProperties.enable_frame_rate_override().orElse(false)) {
return modesToTest;
}
+
+ List<Display.Mode> modesWithSameResolution = new ArrayList<>();
+ Display.Mode currentMode = mActivityRule.getActivity().getDisplay().getMode();
+ final long currentDisplayHeight = currentMode.getPhysicalHeight();
+ final long currentDisplayWidth = currentMode.getPhysicalWidth();
+
Display.Mode[] modes = mActivityRule.getActivity().getDisplay().getSupportedModes();
for (Display.Mode mode : modes) {
- for (Display.Mode otherMode : modes) {
+ if (mode.getPhysicalHeight() == currentDisplayHeight
+ && mode.getPhysicalWidth() == currentDisplayWidth) {
+ modesWithSameResolution.add(mode);
+ }
+ }
+
+ for (Display.Mode mode : modesWithSameResolution) {
+ for (Display.Mode otherMode : modesWithSameResolution) {
if (mode.getModeId() == otherMode.getModeId()) {
continue;
}
- if (mode.getPhysicalHeight() != otherMode.getPhysicalHeight()
- || mode.getPhysicalWidth() != otherMode.getPhysicalWidth()) {
- continue;
- }
-
+ // only add if this refresh rate is a multiple of the other
if (areEqual(mode.getRefreshRate(), 2 * otherMode.getRefreshRate())) {
modesToTest.add(mode);
+ continue;
}
}
}
diff --git a/hostsidetests/graphics/framerateoverride/app/src/com/android/cts/graphics/framerateoverride/FrameRateOverrideTestActivity.java b/hostsidetests/graphics/framerateoverride/app/src/com/android/cts/graphics/framerateoverride/FrameRateOverrideTestActivity.java
index c54ae79..3c218b9 100644
--- a/hostsidetests/graphics/framerateoverride/app/src/com/android/cts/graphics/framerateoverride/FrameRateOverrideTestActivity.java
+++ b/hostsidetests/graphics/framerateoverride/app/src/com/android/cts/graphics/framerateoverride/FrameRateOverrideTestActivity.java
@@ -429,7 +429,7 @@
@Override
public void testFrameRateOverrideBehavior(FrameRateObserver frameRateObserver,
float initialRefreshRate) throws InterruptedException {
- Log.i(TAG, "Staring testFrameRateOverride");
+ Log.i(TAG, "Starting testFrameRateOverride");
float halfFrameRate = initialRefreshRate / 2;
waitForRefreshRateChange(initialRefreshRate);
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiCecClientWrapper.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiCecClientWrapper.java
index ad8e506..5f445d4 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiCecClientWrapper.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiCecClientWrapper.java
@@ -795,7 +795,7 @@
throw new CecClientWrapperException(ErrorCodes.CecMessageNotFound, expectedMessage.name());
}
- public void checkNoMessagesSentFromDevice(int timeoutMillis)
+ public void checkNoMessagesSentFromDevice(int timeoutMillis, List<CecOperand> excludeOperands)
throws CecClientWrapperException {
checkCecClient();
long startTime = System.currentTimeMillis();
@@ -810,6 +810,10 @@
if (mInputConsole.ready()) {
String line = mInputConsole.readLine();
if (pattern.matcher(line).matches()) {
+ CecOperand operand = CecMessage.getOperand(line);
+ if(excludeOperands.contains(operand)){
+ continue;
+ }
CLog.v("Found unexpected message in " + line);
throw new CecClientWrapperException(
ErrorCodes.CecMessageFound,
@@ -827,6 +831,12 @@
}
}
+ public void checkNoMessagesSentFromDevice(int timeoutMillis)
+ throws CecClientWrapperException {
+ List<CecOperand> excludeOperands = new ArrayList<>();
+ checkNoMessagesSentFromDevice(timeoutMillis, excludeOperands);
+ }
+
/**
* Looks for the CEC message incorrectMessage sent to CEC device toDevice on the cec-client
* communication channel and throws an CecClientWrapperException if it finds the line that
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecGeneralProtocolTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecGeneralProtocolTest.java
index 862fcbe..19d2c75 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecGeneralProtocolTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecGeneralProtocolTest.java
@@ -27,11 +27,15 @@
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.RuleChain;
import org.junit.runner.RunWith;
+import java.util.ArrayList;
+import java.util.List;
+
/** HDMI CEC 2.0 general protocol tests */
@RunWith(DeviceJUnit4ClassRunner.class)
public final class HdmiCecGeneralProtocolTest extends BaseHdmiCecCtsTest {
@@ -51,30 +55,34 @@
@Test
public void cect_4_2_2_ignoreMessagesFromAddressF() throws Exception {
setCec20();
- sendMessageAndVerifyNoMessageSentFromDevice(CecOperand.GIVE_TUNER_DEVICE_STATUS, "01");
+ // get cec reinit messages
+ hdmiCecClient.getAllMessages(mDutLogicalAddresses,
+ HdmiCecConstants.TIMEOUT_CEC_REINIT_SECONDS);
+
+ sendMessageAndVerifyNoMessageSentFromDevice(CecOperand.GIVE_TUNER_DEVICE_STATUS, ":01");
sendMessageAndVerifyNoMessageSentFromDevice(CecOperand.RECORD_ON);
sendMessageAndVerifyNoMessageSentFromDevice(CecOperand.RECORD_OFF);
sendMessageAndVerifyNoMessageSentFromDevice(CecOperand.RECORD_TV_SCREEN);
- sendMessageAndVerifyNoMessageSentFromDevice(CecOperand.GIVE_DECK_STATUS, "01");
+ sendMessageAndVerifyNoMessageSentFromDevice(CecOperand.GIVE_DECK_STATUS, ":01");
sendMessageAndVerifyNoMessageSentFromDevice(
- CecOperand.CLEAR_ANALOG_TIMER, "02:02:02:02:02:02:00:00:00:02:00");
+ CecOperand.CLEAR_ANALOG_TIMER, ":02:02:02:02:02:02:00:00:00:02:00");
sendMessageAndVerifyNoMessageSentFromDevice(
- CecOperand.SET_ANALOG_TIMER, "02:02:02:02:02:02:00:00:00:02:00");
- sendMessageAndVerifyNoMessageSentFromDevice(CecOperand.PLAY, "05");
- sendMessageAndVerifyNoMessageSentFromDevice(CecOperand.DECK_CONTROL, "01");
+ CecOperand.SET_ANALOG_TIMER, ":02:02:02:02:02:02:00:00:00:02:00");
+ sendMessageAndVerifyNoMessageSentFromDevice(CecOperand.PLAY, ":05");
+ sendMessageAndVerifyNoMessageSentFromDevice(CecOperand.DECK_CONTROL, ":01");
sendMessageAndVerifyNoMessageSentFromDevice(CecOperand.GIVE_OSD_NAME);
sendMessageAndVerifyNoMessageSentFromDevice(CecOperand.GIVE_AUDIO_STATUS);
sendMessageAndVerifyNoMessageSentFromDevice(CecOperand.GIVE_SYSTEM_AUDIO_MODE_STATUS);
- sendMessageAndVerifyNoMessageSentFromDevice(CecOperand.VENDOR_COMMAND, "00:01");
- sendMessageAndVerifyNoMessageSentFromDevice(CecOperand.MENU_REQUEST, "00");
+ sendMessageAndVerifyNoMessageSentFromDevice(CecOperand.VENDOR_COMMAND, ":00:01");
+ sendMessageAndVerifyNoMessageSentFromDevice(CecOperand.MENU_REQUEST, ":00");
sendMessageAndVerifyNoMessageSentFromDevice(CecOperand.GIVE_POWER_STATUS);
sendMessageAndVerifyNoMessageSentFromDevice(
- CecOperand.SET_DIGITAL_TIMER, "02:02:02:02:02:02:00:00:00:02:00");
+ CecOperand.SET_DIGITAL_TIMER, ":02:02:02:02:02:02:00:00:00:02:00");
sendMessageAndVerifyNoMessageSentFromDevice(
- CecOperand.CLEAR_DIGITAL_TIMER, "02:02:02:02:02:02:00:00:00:02:00");
+ CecOperand.CLEAR_DIGITAL_TIMER, ":02:02:02:02:02:02:00:00:00:02:00");
sendMessageAndVerifyNoMessageSentFromDevice(CecOperand.GET_CEC_VERSION);
sendMessageAndVerifyNoMessageSentFromDevice(
- CecOperand.CLEAR_EXTERNAL_TIMER, "02:02:02:02:02:02:00:10:02");
+ CecOperand.CLEAR_EXTERNAL_TIMER, ":02:02:02:02:02:02:00:10:02");
sendMessageAndVerifyNoMessageSentFromDevice(CecOperand.REQUEST_SHORT_AUDIO_DESCRIPTOR);
sendMessageAndVerifyNoMessageSentFromDevice(CecOperand.INITIATE_ARC);
sendMessageAndVerifyNoMessageSentFromDevice(CecOperand.REQUEST_ARC_INITIATION);
@@ -85,10 +93,17 @@
public void sendMessageAndVerifyNoMessageSentFromDevice(CecOperand message, String params)
throws Exception {
+ // DeviceDiscoveryAction will send GIVE_OSD_NAME and GIVE_DEVICE_VENDOR_ID
+ // HotplugDetectionAction will send GIVE_PHYSICAL_ADDRESS
+ List<CecOperand> excludeOperands = new ArrayList<>();
+ excludeOperands.add(CecOperand.GIVE_PHYSICAL_ADDRESS);
+ excludeOperands.add(CecOperand.GIVE_DEVICE_VENDOR_ID);
+ excludeOperands.add(CecOperand.GIVE_OSD_NAME);
+
hdmiCecClient.sendCecMessage(message, params);
// Default timeout for the incoming command to arrive in response to a request is 2 secs
// Thus test ensures no messages are sent from DUT for a spacing of 3 secs
- hdmiCecClient.checkNoMessagesSentFromDevice(3000);
+ hdmiCecClient.checkNoMessagesSentFromDevice(3000, excludeOperands);
}
public void sendMessageAndVerifyNoMessageSentFromDevice(CecOperand message) throws Exception {
@@ -105,6 +120,16 @@
* ignore the last byte of the parameter and treat it as {@code <UCP>[KEYCODE_DPAD_UP]}
*/
@Test
+ @Ignore("b/259002142, b/264510905")
+ /**
+ * TODO: b/259002142, b/264510905
+ *
+ * 1. implement the behavior that the current test is testing
+ * (i.e. ignore additional parameters in <User Control Pressed> messages)
+ *
+ * 2. implement the tests as they are proposed by the HDMI forum and validate that they are
+ * passing with the current implementation of the behavior
+ */
public void cect_hf_ignoreAdditionalParams() throws Exception {
setCec20();
RemoteControlPassthrough.checkUserControlPressAndReleaseWithAdditionalParams(
diff --git a/hostsidetests/media/Android.bp b/hostsidetests/media/Android.bp
index 7f174a2..02d666c 100644
--- a/hostsidetests/media/Android.bp
+++ b/hostsidetests/media/Android.bp
@@ -41,6 +41,11 @@
"cts-host-utils",
"cts-statsd-atom-host-test-utils",
],
+ data: [
+ ":CtsMediaMetricsHostTestApp",
+ ":CtsMediaSessionHostTestApp",
+ ":CtsMediaSessionTestHelper",
+ ],
}
filegroup {
diff --git a/hostsidetests/media/app/MediaMetricsTest/Android.bp b/hostsidetests/media/app/MediaMetricsTest/Android.bp
index ebab6b4..6278f36 100644
--- a/hostsidetests/media/app/MediaMetricsTest/Android.bp
+++ b/hostsidetests/media/app/MediaMetricsTest/Android.bp
@@ -50,6 +50,7 @@
],
static_libs: [
"androidx.test.rules",
+ "collector-device-lib",
"compatibility-device-util-axt",
"truth-prebuilt",
],
diff --git a/hostsidetests/media/app/MediaMetricsTest/src/android/media/metrics/cts/MediaMetricsAtomHostSideTests.java b/hostsidetests/media/app/MediaMetricsTest/src/android/media/metrics/cts/MediaMetricsAtomHostSideTests.java
index 8c91c5b..3d0edfc 100644
--- a/hostsidetests/media/app/MediaMetricsTest/src/android/media/metrics/cts/MediaMetricsAtomHostSideTests.java
+++ b/hostsidetests/media/app/MediaMetricsTest/src/android/media/metrics/cts/MediaMetricsAtomHostSideTests.java
@@ -19,6 +19,7 @@
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
+import android.device.collectors.util.SendToInstrumentation;
import android.media.metrics.BundleSession;
import android.media.metrics.EditingSession;
import android.media.metrics.LogSessionId;
@@ -44,10 +45,6 @@
import org.junit.Test;
import org.junit.runner.RunWith;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-
@RunWith(AndroidJUnit4.class)
public class MediaMetricsAtomHostSideTests {
private static final String TAG = "MediaMetricsAtomHostSideTests";
@@ -300,7 +297,7 @@
.setNetworkBytesRead(102400)
.setLocalBytesRead(2000)
.setNetworkTransferDurationMillis(6000)
- .setDrmSessionId(new byte[] {2, 3, 3, 10})
+ .setDrmSessionId(new byte[]{2, 3, 3, 10})
.setMetricsBundle(new Bundle())
.addExperimentId(123)
.build();
@@ -443,7 +440,7 @@
.setNetworkBytesRead(102400)
.setLocalBytesRead(2000)
.setNetworkTransferDurationMillis(6000)
- .setDrmSessionId(new byte[] {2, 3, 3, 10})
+ .setDrmSessionId(new byte[]{2, 3, 3, 10})
.setMetricsBundle(new Bundle())
.addExperimentId(123)
.build();
@@ -507,7 +504,7 @@
.setNetworkBytesRead(102400)
.setLocalBytesRead(2000)
.setNetworkTransferDurationMillis(6000)
- .setDrmSessionId(new byte[] {2, 3, 3, 10})
+ .setDrmSessionId(new byte[]{2, 3, 3, 10})
.setMetricsBundle(new Bundle())
.addExperimentId(123)
.build();
@@ -540,16 +537,11 @@
@Test
public native void testAAudioLegacyInputStream();
- private void writeSessionIdToFile(String stringId) throws IOException {
- // TODO(b/259258249): Name session id after the test.
- Context context = InstrumentationRegistry.getInstrumentation().getContext();
+ private void writeSessionIdToFile(String stringId) {
Log.i(TAG, "log_session_id=" + stringId);
- File logDir = context.getExternalFilesDir(null);
- File logFile = new File(logDir, "log_session_id.txt");
- logFile.createNewFile();
- FileWriter fw = new FileWriter(logFile.getAbsolutePath());
- fw.write(stringId);
- fw.close();
- Log.i(TAG, "Logged to " + logFile.getAbsolutePath());
+ Bundle b = new Bundle();
+ // TODO(b/265311058): use a common constant for metrics keys.
+ b.putString("log_session_id", stringId);
+ SendToInstrumentation.sendBundle(InstrumentationRegistry.getInstrumentation(), b);
}
}
diff --git a/hostsidetests/media/src/android/media/metrics/cts/MediaMetricsAtomTests.java b/hostsidetests/media/src/android/media/metrics/cts/MediaMetricsAtomTests.java
index fe2ac25..77cc851 100644
--- a/hostsidetests/media/src/android/media/metrics/cts/MediaMetricsAtomTests.java
+++ b/hostsidetests/media/src/android/media/metrics/cts/MediaMetricsAtomTests.java
@@ -24,23 +24,38 @@
import android.cts.statsdatom.lib.DeviceUtils;
import android.cts.statsdatom.lib.ReportUtils;
+import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
import com.android.os.AtomsProto;
import com.android.os.StatsLog;
import com.android.tradefed.build.IBuildInfo;
import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.log.LogUtil;
+import com.android.tradefed.metrics.proto.MetricMeasurement;
+import com.android.tradefed.result.CollectingTestListener;
+import com.android.tradefed.result.TestDescription;
+import com.android.tradefed.result.TestResult;
+import com.android.tradefed.result.TestRunResult;
import com.android.tradefed.testtype.DeviceTestCase;
import com.android.tradefed.testtype.IBuildReceiver;
import com.google.common.truth.Correspondence;
import java.util.Arrays;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
public class MediaMetricsAtomTests extends DeviceTestCase implements IBuildReceiver {
+
+ private static final String TEST_RUNNER = "androidx.test.runner.AndroidJUnitRunner";
private static final String TAG = "MediaMetricsAtomTests";
public static final String TEST_APK = "CtsMediaMetricsHostTestApp.apk";
public static final String TEST_PKG = "android.media.metrics.cts";
@@ -75,9 +90,9 @@
public void testPlaybackStateEvent_default() throws Exception {
ConfigUtils.uploadConfigForPushedAtom(getDevice(), TEST_PKG,
AtomsProto.Atom.MEDIA_PLAYBACK_STATE_CHANGED_FIELD_NUMBER);
- DeviceUtils.runDeviceTests(getDevice(), TEST_PKG,
+ runDeviceTests(getDevice(), TEST_PKG,
"android.media.metrics.cts.MediaMetricsAtomHostSideTests",
- "testPlaybackStateEvent_default");
+ "testPlaybackStateEvent_default", new LogSessionIdListener());
Thread.sleep(AtomTestUtils.WAIT_TIME_LONG);
List<StatsLog.EventMetricData> data = ReportUtils.getEventMetricDataList(getDevice());
@@ -93,9 +108,9 @@
public void testPlaybackStateEvent() throws Exception {
ConfigUtils.uploadConfigForPushedAtom(getDevice(), TEST_PKG,
AtomsProto.Atom.MEDIA_PLAYBACK_STATE_CHANGED_FIELD_NUMBER);
- DeviceUtils.runDeviceTests(getDevice(), TEST_PKG,
+ runDeviceTests(getDevice(), TEST_PKG,
"android.media.metrics.cts.MediaMetricsAtomHostSideTests",
- "testPlaybackStateEvent");
+ "testPlaybackStateEvent", new LogSessionIdListener());
Thread.sleep(AtomTestUtils.WAIT_TIME_LONG);
List<StatsLog.EventMetricData> data = ReportUtils.getEventMetricDataList(getDevice());
@@ -112,9 +127,9 @@
public void testBundleSessionPlaybackStateEvent() throws Exception {
ConfigUtils.uploadConfigForPushedAtom(getDevice(), TEST_PKG,
AtomsProto.Atom.MEDIA_PLAYBACK_STATE_CHANGED_FIELD_NUMBER);
- DeviceUtils.runDeviceTests(getDevice(), TEST_PKG,
+ runDeviceTests(getDevice(), TEST_PKG,
"android.media.metrics.cts.MediaMetricsAtomHostSideTests",
- "testBundleSessionPlaybackStateEvent");
+ "testBundleSessionPlaybackStateEvent", new LogSessionIdListener());
Thread.sleep(AtomTestUtils.WAIT_TIME_LONG);
List<StatsLog.EventMetricData> data = ReportUtils.getEventMetricDataList(getDevice());
@@ -131,9 +146,9 @@
public void testPlaybackErrorEvent_default() throws Exception {
ConfigUtils.uploadConfigForPushedAtom(getDevice(), TEST_PKG,
AtomsProto.Atom.MEDIA_PLAYBACK_ERROR_REPORTED_FIELD_NUMBER);
- DeviceUtils.runDeviceTests(getDevice(), TEST_PKG,
+ runDeviceTests(getDevice(), TEST_PKG,
"android.media.metrics.cts.MediaMetricsAtomHostSideTests",
- "testPlaybackErrorEvent_default");
+ "testPlaybackErrorEvent_default", new LogSessionIdListener());
Thread.sleep(AtomTestUtils.WAIT_TIME_LONG);
List<StatsLog.EventMetricData> data = ReportUtils.getEventMetricDataList(getDevice());
@@ -154,9 +169,9 @@
public void testPlaybackErrorEvent() throws Exception {
ConfigUtils.uploadConfigForPushedAtom(getDevice(), TEST_PKG,
AtomsProto.Atom.MEDIA_PLAYBACK_ERROR_REPORTED_FIELD_NUMBER);
- DeviceUtils.runDeviceTests(getDevice(), TEST_PKG,
+ runDeviceTests(getDevice(), TEST_PKG,
"android.media.metrics.cts.MediaMetricsAtomHostSideTests",
- "testPlaybackErrorEvent");
+ "testPlaybackErrorEvent", new LogSessionIdListener());
Thread.sleep(AtomTestUtils.WAIT_TIME_LONG);
List<StatsLog.EventMetricData> data = ReportUtils.getEventMetricDataList(getDevice());
@@ -177,9 +192,9 @@
public void testTrackChangeEvent_default() throws Exception {
ConfigUtils.uploadConfigForPushedAtom(getDevice(), TEST_PKG,
AtomsProto.Atom.MEDIA_PLAYBACK_TRACK_CHANGED_FIELD_NUMBER);
- DeviceUtils.runDeviceTests(getDevice(), TEST_PKG,
+ runDeviceTests(getDevice(), TEST_PKG,
"android.media.metrics.cts.MediaMetricsAtomHostSideTests",
- "testTrackChangeEvent_default");
+ "testTrackChangeEvent_default", new LogSessionIdListener());
Thread.sleep(AtomTestUtils.WAIT_TIME_LONG);
List<StatsLog.EventMetricData> data = ReportUtils.getEventMetricDataList(getDevice());
@@ -206,9 +221,9 @@
public void testTrackChangeEvent_text() throws Exception {
ConfigUtils.uploadConfigForPushedAtom(getDevice(), TEST_PKG,
AtomsProto.Atom.MEDIA_PLAYBACK_TRACK_CHANGED_FIELD_NUMBER);
- DeviceUtils.runDeviceTests(getDevice(), TEST_PKG,
+ runDeviceTests(getDevice(), TEST_PKG,
"android.media.metrics.cts.MediaMetricsAtomHostSideTests",
- "testTrackChangeEvent_text");
+ "testTrackChangeEvent_text", new LogSessionIdListener());
Thread.sleep(AtomTestUtils.WAIT_TIME_LONG);
List<StatsLog.EventMetricData> data = ReportUtils.getEventMetricDataList(getDevice());
@@ -233,9 +248,9 @@
public void testTrackChangeEvent_audio() throws Exception {
ConfigUtils.uploadConfigForPushedAtom(getDevice(), TEST_PKG,
AtomsProto.Atom.MEDIA_PLAYBACK_TRACK_CHANGED_FIELD_NUMBER);
- DeviceUtils.runDeviceTests(getDevice(), TEST_PKG,
+ runDeviceTests(getDevice(), TEST_PKG,
"android.media.metrics.cts.MediaMetricsAtomHostSideTests",
- "testTrackChangeEvent_audio");
+ "testTrackChangeEvent_audio", new LogSessionIdListener());
Thread.sleep(AtomTestUtils.WAIT_TIME_LONG);
List<StatsLog.EventMetricData> data = ReportUtils.getEventMetricDataList(getDevice());
@@ -262,9 +277,9 @@
public void testTrackChangeEvent_video() throws Exception {
ConfigUtils.uploadConfigForPushedAtom(getDevice(), TEST_PKG,
AtomsProto.Atom.MEDIA_PLAYBACK_TRACK_CHANGED_FIELD_NUMBER);
- DeviceUtils.runDeviceTests(getDevice(), TEST_PKG,
+ runDeviceTests(getDevice(), TEST_PKG,
"android.media.metrics.cts.MediaMetricsAtomHostSideTests",
- "testTrackChangeEvent_video");
+ "testTrackChangeEvent_video", new LogSessionIdListener());
Thread.sleep(AtomTestUtils.WAIT_TIME_LONG);
List<StatsLog.EventMetricData> data = ReportUtils.getEventMetricDataList(getDevice());
@@ -292,9 +307,9 @@
public void testNetworkEvent_default() throws Exception {
ConfigUtils.uploadConfigForPushedAtom(getDevice(), TEST_PKG,
AtomsProto.Atom.MEDIA_NETWORK_INFO_CHANGED_FIELD_NUMBER);
- DeviceUtils.runDeviceTests(getDevice(), TEST_PKG,
+ runDeviceTests(getDevice(), TEST_PKG,
"android.media.metrics.cts.MediaMetricsAtomHostSideTests",
- "testNetworkEvent_default");
+ "testNetworkEvent_default", new LogSessionIdListener());
Thread.sleep(AtomTestUtils.WAIT_TIME_LONG);
List<StatsLog.EventMetricData> data = ReportUtils.getEventMetricDataList(getDevice());
@@ -311,8 +326,9 @@
public void testNetworkEvent() throws Exception {
ConfigUtils.uploadConfigForPushedAtom(getDevice(), TEST_PKG,
AtomsProto.Atom.MEDIA_NETWORK_INFO_CHANGED_FIELD_NUMBER);
- DeviceUtils.runDeviceTests(getDevice(), TEST_PKG,
- "android.media.metrics.cts.MediaMetricsAtomHostSideTests", "testNetworkEvent");
+ runDeviceTests(getDevice(), TEST_PKG,
+ "android.media.metrics.cts.MediaMetricsAtomHostSideTests", "testNetworkEvent",
+ new LogSessionIdListener());
Thread.sleep(AtomTestUtils.WAIT_TIME_LONG);
List<StatsLog.EventMetricData> data = ReportUtils.getEventMetricDataList(getDevice());
@@ -329,9 +345,9 @@
public void testPlaybackMetrics_default() throws Exception {
ConfigUtils.uploadConfigForPushedAtom(getDevice(), TEST_PKG,
AtomsProto.Atom.MEDIAMETRICS_PLAYBACK_REPORTED_FIELD_NUMBER);
- DeviceUtils.runDeviceTests(getDevice(), TEST_PKG,
+ runDeviceTests(getDevice(), TEST_PKG,
"android.media.metrics.cts.MediaMetricsAtomHostSideTests",
- "testPlaybackMetrics_default");
+ "testPlaybackMetrics_default", new LogSessionIdListener());
Thread.sleep(AtomTestUtils.WAIT_TIME_LONG);
List<StatsLog.EventMetricData> data = ReportUtils.getEventMetricDataList(getDevice());
@@ -364,8 +380,9 @@
public void testPlaybackMetrics() throws Exception {
ConfigUtils.uploadConfigForPushedAtom(getDevice(), TEST_PKG,
AtomsProto.Atom.MEDIAMETRICS_PLAYBACK_REPORTED_FIELD_NUMBER);
- DeviceUtils.runDeviceTests(getDevice(), TEST_PKG,
- "android.media.metrics.cts.MediaMetricsAtomHostSideTests", "testPlaybackMetrics");
+ runDeviceTests(getDevice(), TEST_PKG,
+ "android.media.metrics.cts.MediaMetricsAtomHostSideTests", "testPlaybackMetrics",
+ new LogSessionIdListener());
Thread.sleep(AtomTestUtils.WAIT_TIME_LONG);
List<StatsLog.EventMetricData> data = ReportUtils.getEventMetricDataList(getDevice());
@@ -400,8 +417,9 @@
public void testSessionId() throws Exception {
ConfigUtils.uploadConfigForPushedAtom(getDevice(), TEST_PKG,
AtomsProto.Atom.MEDIAMETRICS_PLAYBACK_REPORTED_FIELD_NUMBER);
- DeviceUtils.runDeviceTests(getDevice(), TEST_PKG,
- "android.media.metrics.cts.MediaMetricsAtomHostSideTests", "testSessionId");
+ runDeviceTests(getDevice(), TEST_PKG,
+ "android.media.metrics.cts.MediaMetricsAtomHostSideTests", "testSessionId",
+ new LogSessionIdListener());
Thread.sleep(AtomTestUtils.WAIT_TIME_LONG);
List<StatsLog.EventMetricData> data = ReportUtils.getEventMetricDataList(getDevice());
@@ -411,8 +429,9 @@
public void testRecordingSession() throws Exception {
ConfigUtils.uploadConfigForPushedAtom(getDevice(), TEST_PKG,
AtomsProto.Atom.MEDIAMETRICS_PLAYBACK_REPORTED_FIELD_NUMBER);
- DeviceUtils.runDeviceTests(getDevice(), TEST_PKG,
- "android.media.metrics.cts.MediaMetricsAtomHostSideTests", "testRecordingSession");
+ runDeviceTests(getDevice(), TEST_PKG,
+ "android.media.metrics.cts.MediaMetricsAtomHostSideTests", "testRecordingSession",
+ new LogSessionIdListener());
Thread.sleep(AtomTestUtils.WAIT_TIME_LONG);
List<StatsLog.EventMetricData> data = ReportUtils.getEventMetricDataList(getDevice());
@@ -422,8 +441,9 @@
public void testEditingSession() throws Exception {
ConfigUtils.uploadConfigForPushedAtom(getDevice(), TEST_PKG,
AtomsProto.Atom.MEDIAMETRICS_PLAYBACK_REPORTED_FIELD_NUMBER);
- DeviceUtils.runDeviceTests(getDevice(), TEST_PKG,
- "android.media.metrics.cts.MediaMetricsAtomHostSideTests", "testEditingSession");
+ runDeviceTests(getDevice(), TEST_PKG,
+ "android.media.metrics.cts.MediaMetricsAtomHostSideTests", "testEditingSession",
+ new LogSessionIdListener());
Thread.sleep(AtomTestUtils.WAIT_TIME_LONG);
List<StatsLog.EventMetricData> data = ReportUtils.getEventMetricDataList(getDevice());
@@ -433,9 +453,9 @@
public void testTranscodingSession() throws Exception {
ConfigUtils.uploadConfigForPushedAtom(getDevice(), TEST_PKG,
AtomsProto.Atom.MEDIAMETRICS_PLAYBACK_REPORTED_FIELD_NUMBER);
- DeviceUtils.runDeviceTests(getDevice(), TEST_PKG,
+ runDeviceTests(getDevice(), TEST_PKG,
"android.media.metrics.cts.MediaMetricsAtomHostSideTests",
- "testTranscodingSession");
+ "testTranscodingSession", new LogSessionIdListener());
Thread.sleep(AtomTestUtils.WAIT_TIME_LONG);
List<StatsLog.EventMetricData> data = ReportUtils.getEventMetricDataList(getDevice());
@@ -445,8 +465,9 @@
public void testBundleSession() throws Exception {
ConfigUtils.uploadConfigForPushedAtom(getDevice(), TEST_PKG,
AtomsProto.Atom.MEDIAMETRICS_PLAYBACK_REPORTED_FIELD_NUMBER);
- DeviceUtils.runDeviceTests(getDevice(), TEST_PKG,
- "android.media.metrics.cts.MediaMetricsAtomHostSideTests", "testBundleSession");
+ runDeviceTests(getDevice(), TEST_PKG,
+ "android.media.metrics.cts.MediaMetricsAtomHostSideTests", "testBundleSession",
+ new LogSessionIdListener());
Thread.sleep(AtomTestUtils.WAIT_TIME_LONG);
List<StatsLog.EventMetricData> data = ReportUtils.getEventMetricDataList(getDevice());
@@ -456,11 +477,14 @@
public void testAppBlocklist() throws Exception {
ConfigUtils.uploadConfigForPushedAtom(getDevice(), TEST_PKG,
AtomsProto.Atom.MEDIA_PLAYBACK_STATE_CHANGED_FIELD_NUMBER);
- DeviceUtils.runDeviceTests(getDevice(), TEST_PKG,
- "android.media.metrics.cts.MediaMetricsAtomHostSideTests", "testAppBlocklist");
+ LogSessionIdListener listener = new LogSessionIdListener();
+ runDeviceTests(getDevice(),
+ TEST_PKG,
+ "android.media.metrics.cts.MediaMetricsAtomHostSideTests", "testAppBlocklist",
+ listener);
+ String logSessionId = listener.getLogSessionId();
Thread.sleep(AtomTestUtils.WAIT_TIME_LONG);
- String logSessionId = getLogSessionId();
assertWithMessage("log session id").that(logSessionId).isNotEmpty();
List<StatsLog.EventMetricData> data = ReportUtils.getEventMetricDataList(getDevice());
List<AtomsProto.MediametricsPlaybackReported> playbackReportedList = toMyAtoms(data,
@@ -474,13 +498,14 @@
public void testAttributionBlocklist() throws Exception {
ConfigUtils.uploadConfigForPushedAtom(getDevice(), TEST_PKG,
AtomsProto.Atom.MEDIAMETRICS_PLAYBACK_REPORTED_FIELD_NUMBER);
- DeviceUtils.runDeviceTests(getDevice(), TEST_PKG,
+ LogSessionIdListener listener = new LogSessionIdListener();
+ runDeviceTests(getDevice(), TEST_PKG,
"android.media.metrics.cts.MediaMetricsAtomHostSideTests",
- "testAttributionBlocklist");
+ "testAttributionBlocklist", listener);
+ String logSessionId = listener.getLogSessionId();
Thread.sleep(AtomTestUtils.WAIT_TIME_LONG);
List<StatsLog.EventMetricData> data = ReportUtils.getEventMetricDataList(getDevice());
- String logSessionId = getLogSessionId();
assertWithMessage("log session id").that(logSessionId).isNotEmpty();
List<AtomsProto.MediametricsPlaybackReported> playbackReportedList = toMyAtoms(data,
AtomsProto.Atom::getMediametricsPlaybackReported);
@@ -511,12 +536,14 @@
public void testAppAllowlist() throws Exception {
ConfigUtils.uploadConfigForPushedAtom(getDevice(), TEST_PKG,
AtomsProto.Atom.MEDIA_PLAYBACK_STATE_CHANGED_FIELD_NUMBER);
- DeviceUtils.runDeviceTests(getDevice(), TEST_PKG,
- "android.media.metrics.cts.MediaMetricsAtomHostSideTests", "testAppAllowlist");
+ LogSessionIdListener listener = new LogSessionIdListener();
+ runDeviceTests(getDevice(), TEST_PKG,
+ "android.media.metrics.cts.MediaMetricsAtomHostSideTests",
+ "testAppAllowlist", listener);
+ String logSessionId = listener.getLogSessionId();
Thread.sleep(AtomTestUtils.WAIT_TIME_LONG);
List<StatsLog.EventMetricData> data = ReportUtils.getEventMetricDataList(getDevice());
- String logSessionId = getLogSessionId();
assertWithMessage("log session id").that(logSessionId).isNotEmpty();
List<AtomsProto.MediaPlaybackStateChanged> stateChangedList = toMyAtoms(data,
AtomsProto.Atom::getMediaPlaybackStateChanged);
@@ -533,13 +560,14 @@
public void testAttributionAllowlist() throws Exception {
ConfigUtils.uploadConfigForPushedAtom(getDevice(), TEST_PKG,
AtomsProto.Atom.MEDIAMETRICS_PLAYBACK_REPORTED_FIELD_NUMBER);
- DeviceUtils.runDeviceTests(getDevice(), TEST_PKG,
+ LogSessionIdListener listener = new LogSessionIdListener();
+ runDeviceTests(getDevice(), TEST_PKG,
"android.media.metrics.cts.MediaMetricsAtomHostSideTests",
- "testAttributionAllowlist");
+ "testAttributionAllowlist", listener);
+ String logSessionId = listener.getLogSessionId();
Thread.sleep(AtomTestUtils.WAIT_TIME_LONG);
List<StatsLog.EventMetricData> data = ReportUtils.getEventMetricDataList(getDevice());
- String logSessionId = getLogSessionId();
assertWithMessage("log session id").that(logSessionId).isNotEmpty();
List<AtomsProto.MediametricsPlaybackReported> playbackReportedList = toMyAtoms(data,
AtomsProto.Atom::getMediametricsPlaybackReported);
@@ -595,8 +623,9 @@
ConfigUtils.uploadConfigForPushedAtom(getDevice(), DeviceUtils.STATSD_ATOM_TEST_PKG,
AtomsProto.Atom.MEDIAMETRICS_AAUDIOSTREAM_REPORTED_FIELD_NUMBER);
- DeviceUtils.runDeviceTests(getDevice(), TEST_PKG,
- "android.media.metrics.cts.MediaMetricsAtomHostSideTests", testFunctionName);
+ runDeviceTests(getDevice(), TEST_PKG,
+ "android.media.metrics.cts.MediaMetricsAtomHostSideTests", testFunctionName,
+ new LogSessionIdListener());
Thread.sleep(AtomTestUtils.WAIT_TIME_LONG);
validateAAudioStreamAtom(direction);
@@ -650,17 +679,86 @@
"testAAudioLegacyOutputStream");
}
- private String getLogSessionId() throws DeviceNotAvailableException {
- // TODO(b/259258249): Name session id file after the test.
- String logSessionId = getDevice().pullFileContents(
- "/storage/emulated/0/Android/data/android.media.metrics"
- + ".cts/files/log_session_id" + ".txt");
- return logSessionId;
- }
-
private static <T> List<T> toMyAtoms(List<StatsLog.EventMetricData> data,
Function<AtomsProto.Atom, T> mapper) {
return data.stream().map(StatsLog.EventMetricData::getAtom).map(mapper).collect(
Collectors.toUnmodifiableList());
}
+
+ // TODO(b/265208340): update DeviceUtils to accept listeners.
+
+ /**
+ * Runs device side tests.
+ *
+ * @param device Can be retrieved by running getDevice() in a class that extends
+ * DeviceTestCase
+ * @param pkgName Test package name, such as "com.android.server.cts.statsdatom"
+ * @param testClassName Test class name which can either be a fully qualified name or "." + a
+ * class name; if null, all test in the package will be run
+ * @param testMethodName Test method name; if null, all tests in class or package will be run
+ * @return {@link TestRunResult} of this invocation
+ */
+ @Nonnull
+ private static TestRunResult runDeviceTests(ITestDevice device, String pkgName,
+ @Nullable String testClassName, @Nullable String testMethodName,
+ LogSessionIdListener listener)
+ throws DeviceNotAvailableException {
+ if (testClassName != null && testClassName.startsWith(".")) {
+ testClassName = pkgName + testClassName;
+ }
+
+ RemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(
+ pkgName, TEST_RUNNER, device.getIDevice());
+ if (testClassName != null && testMethodName != null) {
+ testRunner.setMethodName(testClassName, testMethodName);
+ } else if (testClassName != null) {
+ testRunner.setClassName(testClassName);
+ }
+
+ assertThat(device.runInstrumentationTests(testRunner, listener)).isTrue();
+
+ final TestRunResult result = listener.getCurrentRunResults();
+ if (result.isRunFailure()) {
+ throw new Error("Failed to successfully run device tests for "
+ + result.getName() + ": " + result.getRunFailureMessage());
+ }
+ if (result.getNumTests() == 0) {
+ throw new Error("No tests were run on the device");
+ }
+ if (result.hasFailedTests()) {
+ StringBuilder errorBuilder = new StringBuilder("On-device tests failed:\n");
+ for (Map.Entry<TestDescription, TestResult> resultEntry :
+ result.getTestResults().entrySet()) {
+ if (!resultEntry.getValue().getStatus().equals(
+ com.android.ddmlib.testrunner.TestResult.TestStatus.PASSED)) {
+ errorBuilder.append(resultEntry.getKey().toString());
+ errorBuilder.append(":\n");
+ errorBuilder.append(resultEntry.getValue().getStackTrace());
+ }
+ }
+ throw new AssertionError(errorBuilder.toString());
+ }
+
+ return result;
+ }
+
+ private static final class LogSessionIdListener extends CollectingTestListener {
+
+ @Nullable
+ private String mLogSessionId;
+
+ @Nullable
+ public String getLogSessionId() {
+ return mLogSessionId;
+ }
+
+ @Override
+ public void testEnded(TestDescription test, long endTime,
+ HashMap<String, MetricMeasurement.Metric> testMetrics) {
+ super.testEnded(test, endTime, testMetrics);
+ LogUtil.CLog.i("testEnded MetricMeasurement.Metric " + testMetrics);
+ // TODO(b/265311058): use a common constant for metrics keys.
+ mLogSessionId = testMetrics.get("log_session_id").getMeasurements().getSingleString();
+ }
+ }
}
diff --git a/hostsidetests/statsdatom/src/android/cts/statsdatom/statsd/HostAtomTests.java b/hostsidetests/statsdatom/src/android/cts/statsdatom/statsd/HostAtomTests.java
index 8b6f991..aa748e5 100644
--- a/hostsidetests/statsdatom/src/android/cts/statsdatom/statsd/HostAtomTests.java
+++ b/hostsidetests/statsdatom/src/android/cts/statsdatom/statsd/HostAtomTests.java
@@ -339,6 +339,7 @@
public void testBatterySaverModeStateChangedAtom() throws Exception {
if (DeviceUtils.hasFeature(getDevice(), FEATURE_TWM)) return;
if (DeviceUtils.hasFeature(getDevice(), FEATURE_AUTOMOTIVE)) return;
+ if (DeviceUtils.hasFeature(getDevice(), FEATURE_WATCH)) return;
// Setup, turn off battery saver.
turnBatterySaverOff();
DeviceUtils.flushBatteryStatsHandlers(getDevice());
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/BatteryConstraintTest.java b/tests/JobScheduler/src/android/jobscheduler/cts/BatteryConstraintTest.java
index f6ff23f..e26f8b4 100644
--- a/tests/JobScheduler/src/android/jobscheduler/cts/BatteryConstraintTest.java
+++ b/tests/JobScheduler/src/android/jobscheduler/cts/BatteryConstraintTest.java
@@ -24,6 +24,7 @@
import android.os.BatteryManager;
import android.provider.Settings;
import android.util.Log;
+import android.content.res.Resources;
import com.android.compatibility.common.util.SystemUtil;
@@ -41,6 +42,7 @@
public static final int BATTERY_JOB_ID = BatteryConstraintTest.class.hashCode();
private JobInfo.Builder mBuilder;
+ private int mLowBatteryWarningLevel = 15;
/**
* Record of the previous state of power save mode trigger level to reset it after the test
* finishes.
@@ -51,6 +53,9 @@
public void setUp() throws Exception {
super.setUp();
+ mLowBatteryWarningLevel = Resources.getSystem().getInteger(
+ Resources.getSystem().getIdentifier(
+ "config_lowBatteryWarningLevel", "integer", "android"));
// Disable power save mode as some devices may turn off Android when power save mode is
// enabled, causing the test to fail.
mPreviousLowPowerTriggerLevel = Settings.Global.getInt(getContext().getContentResolver(),
@@ -253,7 +258,7 @@
return;
}
- setBatteryState(false, 5);
+ setBatteryState(false, mLowBatteryWarningLevel);
// setBatteryState() waited for the charging/not-charging state to formally settle,
// but battery level reporting lags behind that. wait a moment to let that happen
// before proceeding.
@@ -288,8 +293,8 @@
kTestEnvironment.awaitExecution());
// And check that the job is stopped if battery goes low again.
- setBatteryState(false, 5);
- setBatteryState(false, 4);
+ setBatteryState(false, mLowBatteryWarningLevel);
+ setBatteryState(false, mLowBatteryWarningLevel - 1);
Thread.sleep(2_000);
verifyChargingState(false);
verifyBatteryNotLowState(false);
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/ConnectivityConstraintTest.java b/tests/JobScheduler/src/android/jobscheduler/cts/ConnectivityConstraintTest.java
index 00d7517..7b0d261 100644
--- a/tests/JobScheduler/src/android/jobscheduler/cts/ConnectivityConstraintTest.java
+++ b/tests/JobScheduler/src/android/jobscheduler/cts/ConnectivityConstraintTest.java
@@ -18,48 +18,25 @@
import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
-import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
-import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
-import static com.android.compatibility.common.util.TestUtils.waitUntil;
-
-import android.Manifest;
import android.annotation.TargetApi;
import android.app.job.JobInfo;
import android.app.job.JobParameters;
import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
import android.content.pm.PackageManager;
-import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
-import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
import android.platform.test.annotations.RequiresDevice;
import android.provider.Settings;
import android.util.Log;
import com.android.compatibility.common.util.AppStandbyUtils;
import com.android.compatibility.common.util.BatteryUtils;
-import com.android.compatibility.common.util.CallbackAsserter;
-import com.android.compatibility.common.util.ShellIdentityUtils;
import com.android.compatibility.common.util.SystemUtil;
-import junit.framework.AssertionFailedError;
-
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
/**
* Schedules jobs with the {@link android.app.job.JobScheduler} that have network connectivity
* constraints.
@@ -70,18 +47,13 @@
@RequiresDevice // Emulators don't always have access to wifi/network
public class ConnectivityConstraintTest extends BaseJobSchedulerTest {
private static final String TAG = "ConnectivityConstraintTest";
- private static final String RESTRICT_BACKGROUND_GET_CMD =
- "cmd netpolicy get restrict-background";
- private static final String RESTRICT_BACKGROUND_ON_CMD =
- "cmd netpolicy set restrict-background true";
- private static final String RESTRICT_BACKGROUND_OFF_CMD =
- "cmd netpolicy set restrict-background false";
/** Unique identifier for the job scheduled by this suite of tests. */
public static final int CONNECTIVITY_JOB_ID = ConnectivityConstraintTest.class.hashCode();
/** Wait this long before timing out the test. */
private static final long DEFAULT_TIMEOUT_MILLIS = 30000L; // 30 seconds.
+ private NetworkingHelper mNetworkingHelper;
private WifiManager mWifiManager;
private ConnectivityManager mCm;
@@ -89,21 +61,8 @@
private boolean mHasWifi;
/** Whether the device running these tests supports telephony. */
private boolean mHasTelephony;
- /** Whether the device running these tests supports ethernet. */
- private boolean mHasEthernet;
- /** Track whether WiFi was enabled in case we turn it off. */
- private boolean mInitialWiFiState;
- /** Track initial WiFi metered state. */
- private String mInitialWiFiMeteredState;
- private String mInitialWiFiSSID;
- /** Track whether restrict background policy was enabled in case we turn it off. */
- private boolean mInitialRestrictBackground;
- /** Track whether airplane mode was enabled in case we toggle it. */
- private boolean mInitialAirplaneMode;
/** Track whether the restricted bucket was enabled in case we toggle it. */
private String mInitialRestrictedBucketEnabled;
- /** Track the location mode in case we change it. */
- private String mInitialLocationMode;
private JobInfo.Builder mBuilder;
@@ -115,30 +74,20 @@
mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE);
mCm = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
+ mNetworkingHelper = new NetworkingHelper(getInstrumentation(), getContext());
PackageManager packageManager = mContext.getPackageManager();
mHasWifi = packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI);
mHasTelephony = packageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
- mHasEthernet = packageManager.hasSystemFeature(PackageManager.FEATURE_ETHERNET);
mBuilder = new JobInfo.Builder(CONNECTIVITY_JOB_ID, kJobServiceComponent);
- mInitialLocationMode = Settings.Secure.getString(mContext.getContentResolver(),
- Settings.Secure.LOCATION_MODE);
if (mHasWifi) {
- mInitialWiFiState = mWifiManager.isWifiEnabled();
- ensureSavedWifiNetwork(mWifiManager);
- setWifiState(true, mCm, mWifiManager);
- mInitialWiFiSSID = getWifiSSID();
- mInitialWiFiMeteredState = getWifiMeteredStatus(mInitialWiFiSSID);
+ mNetworkingHelper.ensureSavedWifiNetwork();
}
- mInitialRestrictBackground = SystemUtil
- .runShellCommand(getInstrumentation(), RESTRICT_BACKGROUND_GET_CMD)
- .contains("enabled");
mInitialRestrictedBucketEnabled = Settings.Global.getString(mContext.getContentResolver(),
Settings.Global.ENABLE_RESTRICTED_BUCKET);
setDataSaverEnabled(false);
- mInitialAirplaneMode = isAirplaneModeOn();
- setAirplaneMode(false);
+ mNetworkingHelper.setAllNetworksEnabled(true);
// Force the test app out of the never bucket.
SystemUtil.runShellCommand("am set-standby-bucket "
+ TestAppInterface.TEST_APP_PACKAGE + " rare");
@@ -153,31 +102,12 @@
BatteryUtils.runDumpsysBatteryReset();
- // Restore initial restrict background data usage policy
- setDataSaverEnabled(mInitialRestrictBackground);
-
// Restore initial restricted bucket setting.
Settings.Global.putString(mContext.getContentResolver(),
Settings.Global.ENABLE_RESTRICTED_BUCKET, mInitialRestrictedBucketEnabled);
// Ensure that we leave WiFi in its previous state.
- if (mHasWifi) {
- setWifiMeteredState(mInitialWiFiSSID, mInitialWiFiMeteredState);
- if (mWifiManager.isWifiEnabled() != mInitialWiFiState) {
- try {
- setWifiState(mInitialWiFiState, mCm, mWifiManager);
- } catch (AssertionFailedError e) {
- // Don't fail the test just because wifi state wasn't set in tearDown.
- Log.e(TAG, "Failed to return wifi state to " + mInitialWiFiState, e);
- }
- }
- }
-
- // Restore initial airplane mode status. Do it after setting wifi in case wifi was
- // originally metered.
- setAirplaneMode(mInitialAirplaneMode);
-
- setLocationMode(mInitialLocationMode);
+ mNetworkingHelper.tearDown();
super.tearDown();
}
@@ -585,7 +515,7 @@
}
public void testJobParametersNetwork() throws Exception {
- setAirplaneMode(false);
+ mNetworkingHelper.setAllNetworksEnabled(true);
// Everything good.
final NetworkRequest nr = new NetworkRequest.Builder()
@@ -608,7 +538,7 @@
if (!hasEthernetConnection()) {
// Deadline passed with no network satisfied.
- setAirplaneMode(true);
+ mNetworkingHelper.setAllNetworksEnabled(false);
ji = mBuilder
.setRequiredNetwork(nr)
.setOverrideDeadline(0)
@@ -624,7 +554,7 @@
}
// No network requested
- setAirplaneMode(false);
+ mNetworkingHelper.setAllNetworksEnabled(true);
ji = mBuilder.setRequiredNetwork(null).build();
kTestEnvironment.setExpectedExecutions(1);
mJobScheduler.schedule(ji);
@@ -875,149 +805,25 @@
}
private boolean hasEthernetConnection() {
- if (!mHasEthernet) return false;
- Network[] networks = mCm.getAllNetworks();
- for (Network network : networks) {
- if (mCm.getNetworkCapabilities(network).hasTransport(TRANSPORT_ETHERNET)) {
- return true;
- }
- }
- return false;
- }
-
- private String unquoteSSID(String ssid) {
- // SSID is returned surrounded by quotes if it can be decoded as UTF-8.
- // Otherwise it's guaranteed not to start with a quote.
- if (ssid.charAt(0) == '"') {
- return ssid.substring(1, ssid.length() - 1);
- } else {
- return ssid;
- }
- }
-
- private String getWifiSSID() throws Exception {
- // Location needs to be enabled to get the WiFi information.
- setLocationMode(String.valueOf(Settings.Secure.LOCATION_MODE_ON));
- final AtomicReference<String> ssid = new AtomicReference<>();
- SystemUtil.runWithShellPermissionIdentity(() -> {
- ssid.set(mWifiManager.getConnectionInfo().getSSID());
- }, Manifest.permission.ACCESS_FINE_LOCATION);
- return unquoteSSID(ssid.get());
- }
-
- private void setLocationMode(String mode) throws Exception {
- Settings.Secure.putString(mContext.getContentResolver(),
- Settings.Secure.LOCATION_MODE, mode);
- final LocationManager locationManager = mContext.getSystemService(LocationManager.class);
- final boolean wantEnabled = !String.valueOf(Settings.Secure.LOCATION_MODE_OFF).equals(mode);
- waitUntil("Location " + (wantEnabled ? "not enabled" : "still enabled"),
- () -> wantEnabled == locationManager.isLocationEnabled());
- }
-
- // Returns "true", "false" or "none"
- private String getWifiMeteredStatus(String ssid) {
- // Interestingly giving the SSID as an argument to list wifi-networks
- // only works iff the network in question has the "false" policy.
- // Also unfortunately runShellCommand does not pass the command to the interpreter
- // so it's not possible to | grep the ssid.
- final String command = "cmd netpolicy list wifi-networks";
- final String policyString = SystemUtil.runShellCommand(command);
-
- final Matcher m = Pattern.compile("^" + ssid + ";(true|false|none)$",
- Pattern.MULTILINE | Pattern.UNIX_LINES).matcher(policyString);
- if (!m.find()) {
- fail("Unexpected format from cmd netpolicy (when looking for " + ssid + "): "
- + policyString);
- }
- return m.group(1);
+ return mNetworkingHelper.hasEthernetConnection();
}
private void setWifiMeteredState(boolean metered) throws Exception {
- if (metered) {
- // Make sure unmetered cellular networks don't interfere.
- setAirplaneMode(true);
- setWifiState(true, mCm, mWifiManager);
- }
- final String ssid = getWifiSSID();
- setWifiMeteredState(ssid, metered ? "true" : "false");
- }
-
- // metered should be "true", "false" or "none"
- private void setWifiMeteredState(String ssid, String metered) throws Exception {
- if (metered.equals(getWifiMeteredStatus(ssid))) {
- return;
- }
- SystemUtil.runShellCommand("cmd netpolicy set metered-network " + ssid + " " + metered);
- assertEquals(getWifiMeteredStatus(ssid), metered);
+ mNetworkingHelper.setWifiMeteredState(metered);
}
/**
* Ensure WiFi is enabled, and block until we've verified that we are in fact connected.
*/
private void connectToWifi() throws Exception {
- setWifiState(true, mCm, mWifiManager);
+ mNetworkingHelper.setWifiState(true);
}
/**
* Ensure WiFi is disabled, and block until we've verified that we are in fact disconnected.
*/
private void disconnectFromWifi() throws Exception {
- setWifiState(false, mCm, mWifiManager);
- }
-
- /** Ensures that the device has a wifi network saved. */
- static void ensureSavedWifiNetwork(WifiManager wifiManager) {
- final List<WifiConfiguration> savedNetworks =
- ShellIdentityUtils.invokeMethodWithShellPermissions(
- wifiManager, WifiManager::getConfiguredNetworks);
- assertFalse("Need at least one saved wifi network", savedNetworks.isEmpty());
- }
-
- /**
- * Set Wifi connection to specific state, and block until we've verified
- * that we are in the state.
- * Taken from {@link android.net.http.cts.ApacheHttpClientTest}.
- */
- static void setWifiState(final boolean enable,
- final ConnectivityManager cm, final WifiManager wm) throws Exception {
- if (enable != isWiFiConnected(cm, wm)) {
- NetworkRequest nr = new NetworkRequest.Builder().clearCapabilities().build();
- NetworkCapabilities nc = new NetworkCapabilities.Builder()
- .addTransportType(TRANSPORT_WIFI)
- .build();
- NetworkTracker tracker = new NetworkTracker(nc, enable, cm);
- cm.registerNetworkCallback(nr, tracker);
-
- if (enable) {
- SystemUtil.runShellCommand("svc wifi enable");
- waitUntil("Failed to enable Wifi", 30 /* seconds */, () -> wm.isWifiEnabled());
- //noinspection deprecation
- SystemUtil.runWithShellPermissionIdentity(wm::reconnect,
- android.Manifest.permission.NETWORK_SETTINGS);
- } else {
- SystemUtil.runShellCommand("svc wifi disable");
- }
-
- tracker.waitForStateChange();
-
- assertTrue("Wifi must be " + (enable ? "connected to" : "disconnected from")
- + " an access point for this test.",
- enable == isWiFiConnected(cm, wm));
-
- cm.unregisterNetworkCallback(tracker);
- }
- }
-
- static boolean isWiFiConnected(final ConnectivityManager cm, final WifiManager wm) {
- if (!wm.isWifiEnabled()) {
- return false;
- }
- final Network network = cm.getActiveNetwork();
- if (network == null) {
- return false;
- }
- final NetworkCapabilities networkCapabilities = cm.getNetworkCapabilities(network);
- return networkCapabilities != null && networkCapabilities.hasTransport(TRANSPORT_WIFI);
+ mNetworkingHelper.setWifiState(false);
}
/**
@@ -1029,13 +835,14 @@
* @see #checkDeviceSupportsMobileData()
*/
private void disconnectWifiToConnectToMobile() throws Exception {
- setAirplaneMode(false);
+ mNetworkingHelper.setAllNetworksEnabled(true);
if (mHasWifi && mWifiManager.isWifiEnabled()) {
NetworkRequest nr = new NetworkRequest.Builder().clearCapabilities().build();
NetworkCapabilities nc = new NetworkCapabilities.Builder()
.addTransportType(TRANSPORT_CELLULAR)
.build();
- NetworkTracker tracker = new NetworkTracker(nc, true, mCm);
+ NetworkingHelper.NetworkTracker tracker =
+ new NetworkingHelper.NetworkTracker(nc, true, mCm);
mCm.registerNetworkCallback(nr, tracker);
disconnectFromWifi();
@@ -1052,107 +859,6 @@
* If the policy is on, it interferes with tests that relies on metered connection.
*/
private void setDataSaverEnabled(boolean enabled) throws Exception {
- SystemUtil.runShellCommand(getInstrumentation(),
- enabled ? RESTRICT_BACKGROUND_ON_CMD : RESTRICT_BACKGROUND_OFF_CMD);
- }
-
- private boolean isAirplaneModeOn() throws Exception {
- final String output = SystemUtil.runShellCommand(getInstrumentation(),
- "cmd connectivity airplane-mode").trim();
- return "enabled".equals(output);
- }
-
- private void setAirplaneMode(boolean on) throws Exception {
- if (isAirplaneModeOn() == on) {
- return;
- }
- final CallbackAsserter airplaneModeBroadcastAsserter = CallbackAsserter.forBroadcast(
- new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED));
- SystemUtil.runShellCommand(getInstrumentation(),
- "cmd connectivity airplane-mode " + (on ? "enable" : "disable"));
- airplaneModeBroadcastAsserter.assertCalled("Didn't get airplane mode changed broadcast",
- 15 /* 15 seconds */);
- waitUntil("Networks didn't change to " + (!on ? " on" : " off"), 60 /* seconds */,
- () -> {
- if (on) {
- return mCm.getActiveNetwork() == null
- && (!mHasWifi || !isWiFiConnected(mCm, mWifiManager));
- } else {
- return mCm.getActiveNetwork() != null;
- }
- });
- // Wait some time for the network changes to propagate. Can't use
- // waitUntil(isAirplaneModeOn() == on) because the response quickly gives the new
- // airplane mode status even though the network changes haven't propagated all the way to
- // JobScheduler.
- Thread.sleep(5000);
- }
-
- private static class NetworkTracker extends ConnectivityManager.NetworkCallback {
- private static final int MSG_CHECK_ACTIVE_NETWORK = 1;
- private final ConnectivityManager mCm;
-
- private final CountDownLatch mReceiveLatch = new CountDownLatch(1);
-
- private final NetworkCapabilities mExpectedCapabilities;
-
- private final boolean mExpectedConnected;
-
- private final Handler mHandler = new Handler(Looper.getMainLooper()) {
- @Override
- public void handleMessage(Message msg) {
- if (msg.what == MSG_CHECK_ACTIVE_NETWORK) {
- checkActiveNetwork();
- }
- }
- };
-
- private NetworkTracker(NetworkCapabilities expectedCapabilities, boolean expectedConnected,
- ConnectivityManager cm) {
- mExpectedCapabilities = expectedCapabilities;
- mExpectedConnected = expectedConnected;
- mCm = cm;
- }
-
- @Override
- public void onAvailable(Network network) {
- // Available doesn't mean it's the active network. We need to check that separately.
- checkActiveNetwork();
- }
-
- @Override
- public void onLost(Network network) {
- checkActiveNetwork();
- }
-
- boolean waitForStateChange() throws InterruptedException {
- checkActiveNetwork();
- return mReceiveLatch.await(60, TimeUnit.SECONDS);
- }
-
- private void checkActiveNetwork() {
- mHandler.removeMessages(MSG_CHECK_ACTIVE_NETWORK);
- if (mReceiveLatch.getCount() == 0) {
- return;
- }
-
- Network activeNetwork = mCm.getActiveNetwork();
- if (mExpectedConnected) {
- if (activeNetwork != null && mExpectedCapabilities.satisfiedByNetworkCapabilities(
- mCm.getNetworkCapabilities(activeNetwork))) {
- mReceiveLatch.countDown();
- } else {
- mHandler.sendEmptyMessageDelayed(MSG_CHECK_ACTIVE_NETWORK, 5000);
- }
- } else {
- if (activeNetwork == null
- || !mExpectedCapabilities.satisfiedByNetworkCapabilities(
- mCm.getNetworkCapabilities(activeNetwork))) {
- mReceiveLatch.countDown();
- } else {
- mHandler.sendEmptyMessageDelayed(MSG_CHECK_ACTIVE_NETWORK, 5000);
- }
- }
- }
+ mNetworkingHelper.setDataSaverEnabled(enabled);
}
}
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/JobThrottlingTest.java b/tests/JobScheduler/src/android/jobscheduler/cts/JobThrottlingTest.java
index ddbb4aa..7cc1576 100644
--- a/tests/JobScheduler/src/android/jobscheduler/cts/JobThrottlingTest.java
+++ b/tests/JobScheduler/src/android/jobscheduler/cts/JobThrottlingTest.java
@@ -18,23 +18,17 @@
import static android.app.job.JobInfo.NETWORK_TYPE_ANY;
import static android.app.job.JobInfo.NETWORK_TYPE_NONE;
-import static android.jobscheduler.cts.ConnectivityConstraintTest.ensureSavedWifiNetwork;
-import static android.jobscheduler.cts.ConnectivityConstraintTest.isWiFiConnected;
-import static android.jobscheduler.cts.ConnectivityConstraintTest.setWifiState;
import static android.jobscheduler.cts.TestAppInterface.TEST_APP_PACKAGE;
import static android.os.PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED;
import static com.android.compatibility.common.util.TestUtils.waitUntil;
-import static junit.framework.Assert.fail;
-
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeTrue;
-import android.Manifest;
import android.app.AppOpsManager;
import android.app.job.JobInfo;
import android.app.job.JobParameters;
@@ -44,9 +38,6 @@
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.jobscheduler.cts.jobtestapp.TestJobSchedulerReceiver;
-import android.location.LocationManager;
-import android.net.ConnectivityManager;
-import android.net.wifi.WifiManager;
import android.os.PowerManager;
import android.os.SystemClock;
import android.os.Temperature;
@@ -64,23 +55,14 @@
import com.android.compatibility.common.util.AppOpsUtils;
import com.android.compatibility.common.util.AppStandbyUtils;
import com.android.compatibility.common.util.BatteryUtils;
-import com.android.compatibility.common.util.CallbackAsserter;
import com.android.compatibility.common.util.DeviceConfigStateHelper;
-import com.android.compatibility.common.util.SystemUtil;
import com.android.compatibility.common.util.ThermalUtils;
-import junit.framework.AssertionFailedError;
-
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import java.io.IOException;
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
/**
* Tests related to job throttling -- device idle, app standby and battery saver.
*/
@@ -106,22 +88,15 @@
private Context mContext;
private UiDevice mUiDevice;
+ private NetworkingHelper mNetworkingHelper;
private PowerManager mPowerManager;
private int mTestJobId;
private int mTestPackageUid;
private boolean mDeviceInDoze;
private boolean mDeviceIdleEnabled;
private boolean mAppStandbyEnabled;
- private WifiManager mWifiManager;
- private ConnectivityManager mCm;
- /** Whether the device running these tests supports WiFi. */
- private boolean mHasWifi;
- /** Track whether WiFi was enabled in case we turn it off. */
- private boolean mInitialWiFiState;
- private boolean mInitialAirplaneModeState;
private String mInitialDisplayTimeout;
private String mInitialRestrictedBucketEnabled;
- private String mInitialLocationMode;
private String mInitialBatteryStatsConstants;
private boolean mAutomotiveDevice;
private boolean mLeanbackOnly;
@@ -154,6 +129,8 @@
public void setUp() throws Exception {
mContext = InstrumentationRegistry.getTargetContext();
mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+ mNetworkingHelper =
+ new NetworkingHelper(InstrumentationRegistry.getInstrumentation(), mContext);
mPowerManager = mContext.getSystemService(PowerManager.class);
mDeviceInDoze = mPowerManager.isDeviceIdleMode();
mTestPackageUid = mContext.getPackageManager().getPackageUid(TEST_APP_PACKAGE, 0);
@@ -171,11 +148,6 @@
} else {
Log.w(TAG, "App standby not enabled on test device");
}
- mWifiManager = mContext.getSystemService(WifiManager.class);
- mCm = mContext.getSystemService(ConnectivityManager.class);
- mHasWifi = mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI);
- mInitialWiFiState = mWifiManager.isWifiEnabled();
- mInitialAirplaneModeState = isAirplaneModeOn();
mInitialRestrictedBucketEnabled = Settings.Global.getString(mContext.getContentResolver(),
Settings.Global.ENABLE_RESTRICTED_BUCKET);
mInitialBatteryStatsConstants = Settings.Global.getString(mContext.getContentResolver(),
@@ -183,8 +155,6 @@
// Make sure ACTION_CHARGING is sent immediately.
Settings.Global.putString(mContext.getContentResolver(),
Settings.Global.BATTERY_STATS_CONSTANTS, "battery_charged_delay_ms=0");
- mInitialLocationMode = Settings.Secure.getString(mContext.getContentResolver(),
- Settings.Secure.LOCATION_MODE);
// Make sure test jobs can run regardless of bucket.
mDeviceConfigStateHelper =
new DeviceConfigStateHelper(DeviceConfig.NAMESPACE_JOB_SCHEDULER);
@@ -603,7 +573,7 @@
mDeviceConfigStateHelper.set("qc_timing_session_coalescing_duration_ms", "0");
mDeviceConfigStateHelper.set("qc_max_session_count_restricted", "0");
- setAirplaneMode(true);
+ mNetworkingHelper.setAllNetworksEnabled(false);
setScreenState(true);
setChargingState(false);
@@ -634,9 +604,9 @@
assumeTrue("app standby not enabled", mAppStandbyEnabled);
assumeFalse("not testable in automotive device", mAutomotiveDevice);
assumeFalse("not testable in leanback device", mLeanbackOnly);
-
- assumeTrue(mHasWifi);
- ensureSavedWifiNetwork(mWifiManager);
+ assumeFalse("not testable, since ethernet is connected", hasEthernetConnection());
+ assumeTrue(mNetworkingHelper.hasWifiFeature());
+ mNetworkingHelper.ensureSavedWifiNetwork();
setRestrictedBucketEnabled(true);
@@ -644,7 +614,7 @@
mDeviceConfigStateHelper.set("qc_timing_session_coalescing_duration_ms", "0");
mDeviceConfigStateHelper.set("qc_max_session_count_restricted", "0");
- setAirplaneMode(true);
+ mNetworkingHelper.setAllNetworksEnabled(false);
setScreenState(true);
setChargingState(false);
@@ -673,9 +643,8 @@
assertFalse("New job started in RESTRICTED bucket", mTestAppInterface.awaitJobStart(3_000));
// Add network
- setAirplaneMode(false);
- setWifiState(true, mCm, mWifiManager);
- setWifiMeteredState(false);
+ mNetworkingHelper.setAllNetworksEnabled(true);
+ mNetworkingHelper.setWifiMeteredState(false);
runJob();
assertTrue("New job didn't start in RESTRICTED bucket",
mTestAppInterface.awaitJobStart(5_000));
@@ -978,8 +947,8 @@
assumeFalse("not testable in automotive device", mAutomotiveDevice);
assumeFalse("not testable in leanback device", mLeanbackOnly);
- assumeTrue(mHasWifi);
- ensureSavedWifiNetwork(mWifiManager);
+ assumeTrue(mNetworkingHelper.hasWifiFeature());
+ mNetworkingHelper.ensureSavedWifiNetwork();
setRestrictedBucketEnabled(true);
setTestPackageStandbyBucket(Bucket.RESTRICTED);
@@ -989,9 +958,8 @@
mDeviceConfigStateHelper.set("qc_max_session_count_restricted", "0");
// Satisfy all additional constraints.
- setAirplaneMode(false);
- setWifiState(true, mCm, mWifiManager);
- setWifiMeteredState(false);
+ mNetworkingHelper.setAllNetworksEnabled(true);
+ mNetworkingHelper.setWifiMeteredState(false);
setChargingState(true);
BatteryUtils.runDumpsysBatterySetLevel(100);
setScreenState(false);
@@ -1004,13 +972,12 @@
runJob();
assertTrue("New job didn't start in RESTRICTED bucket",
mTestAppInterface.awaitJobStart(DEFAULT_WAIT_TIMEOUT));
- setAirplaneMode(true);
+ mNetworkingHelper.setAllNetworksEnabled(false);
assertTrue("New job didn't stop when connectivity dropped",
mTestAppInterface.awaitJobStop(DEFAULT_WAIT_TIMEOUT));
assertEquals(JobParameters.STOP_REASON_CONSTRAINT_CONNECTIVITY,
mTestAppInterface.getLastParams().getStopReason());
- setAirplaneMode(false);
- setWifiState(true, mCm, mWifiManager);
+ mNetworkingHelper.setAllNetworksEnabled(true);
// Idle
mTestAppInterface.scheduleJob(false, NETWORK_TYPE_ANY, false);
@@ -1195,23 +1162,12 @@
Settings.Global.BATTERY_STATS_CONSTANTS, mInitialBatteryStatsConstants);
removeTestAppFromTempWhitelist();
- // Ensure that we leave WiFi in its previous state.
- if (mHasWifi && mWifiManager.isWifiEnabled() != mInitialWiFiState) {
- try {
- setWifiState(mInitialWiFiState, mCm, mWifiManager);
- } catch (AssertionFailedError e) {
- // Don't fail the test just because wifi state wasn't set in tearDown.
- Log.e(TAG, "Failed to return wifi state to " + mInitialWiFiState, e);
- }
- }
+ mNetworkingHelper.tearDown();
mDeviceConfigStateHelper.restoreOriginalValues();
mActivityManagerDeviceConfigStateHelper.restoreOriginalValues();
Settings.Global.putString(mContext.getContentResolver(),
Settings.Global.ENABLE_RESTRICTED_BUCKET, mInitialRestrictedBucketEnabled);
- if (isAirplaneModeOn() != mInitialAirplaneModeState) {
- setAirplaneMode(mInitialAirplaneModeState);
- }
- setLocationMode(mInitialLocationMode);
+
mUiDevice.executeShellCommand(
"cmd jobscheduler reset-execution-quota -u " + UserHandle.myUserId()
+ " " + TEST_APP_PACKAGE);
@@ -1367,110 +1323,8 @@
+ " -u " + UserHandle.myUserId() + " " + TEST_APP_PACKAGE + " " + mTestJobId);
}
- private boolean isAirplaneModeOn() throws IOException {
- final String output =
- mUiDevice.executeShellCommand("cmd connectivity airplane-mode").trim();
- return "enabled".equals(output);
- }
-
- private void setAirplaneMode(boolean on) throws Exception {
- final CallbackAsserter airplaneModeBroadcastAsserter = CallbackAsserter.forBroadcast(
- new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED));
- mUiDevice.executeShellCommand(
- "cmd connectivity airplane-mode " + (on ? "enable" : "disable"));
- airplaneModeBroadcastAsserter.assertCalled("Didn't get airplane mode changed broadcast",
- 15 /* 15 seconds */);
- if (!on && mHasWifi) {
- // Force wifi to connect ASAP.
- mUiDevice.executeShellCommand("svc wifi enable");
- waitUntil("Failed to enable Wifi", 30 /* seconds */,
- () -> {
- return mWifiManager.isWifiEnabled();
- });
- //noinspection deprecation
- SystemUtil.runWithShellPermissionIdentity(mWifiManager::reconnect,
- android.Manifest.permission.NETWORK_SETTINGS);
- }
- waitUntil("Networks didn't change to " + (!on ? "on" : "off"), 60 /* seconds */,
- () -> {
- if (on) {
- return mCm.getActiveNetwork() == null
- && (!mHasWifi || !isWiFiConnected(mCm, mWifiManager));
- } else {
- return mCm.getActiveNetwork() != null;
- }
- });
- // Wait some time for the network changes to propagate. Can't use
- // waitUntil(isAirplaneModeOn() == on) because the response quickly gives the new
- // airplane mode status even though the network changes haven't propagated all the way to
- // JobScheduler.
- Thread.sleep(5000);
- }
-
- private static String unquoteSSID(String ssid) {
- // SSID is returned surrounded by quotes if it can be decoded as UTF-8.
- // Otherwise it's guaranteed not to start with a quote.
- if (ssid.charAt(0) == '"') {
- return ssid.substring(1, ssid.length() - 1);
- } else {
- return ssid;
- }
- }
-
- private String getWifiSSID() throws Exception {
- // Location needs to be enabled to get the WiFi information.
- setLocationMode(String.valueOf(Settings.Secure.LOCATION_MODE_ON));
- final AtomicReference<String> ssid = new AtomicReference<>();
- SystemUtil.runWithShellPermissionIdentity(() -> {
- ssid.set(mWifiManager.getConnectionInfo().getSSID());
- }, Manifest.permission.ACCESS_FINE_LOCATION);
- return unquoteSSID(ssid.get());
- }
-
- private void setLocationMode(String mode) throws Exception {
- Settings.Secure.putString(mContext.getContentResolver(),
- Settings.Secure.LOCATION_MODE, mode);
- final LocationManager locationManager = mContext.getSystemService(LocationManager.class);
- final boolean wantEnabled = !String.valueOf(Settings.Secure.LOCATION_MODE_OFF).equals(mode);
- waitUntil("Location " + (wantEnabled ? "not enabled" : "still enabled"),
- () -> wantEnabled == locationManager.isLocationEnabled());
- }
-
- // Returns "true", "false" or "none"
- private String getWifiMeteredStatus(String ssid) {
- // Interestingly giving the SSID as an argument to list wifi-networks
- // only works iff the network in question has the "false" policy.
- // Also unfortunately runShellCommand does not pass the command to the interpreter
- // so it's not possible to | grep the ssid.
- final String command = "cmd netpolicy list wifi-networks";
- final String policyString = SystemUtil.runShellCommand(command);
-
- final Matcher m = Pattern.compile("^" + ssid + ";(true|false|none)$",
- Pattern.MULTILINE | Pattern.UNIX_LINES).matcher(policyString);
- if (!m.find()) {
- fail("Unexpected format from cmd netpolicy (when looking for " + ssid + "): "
- + policyString);
- }
- return m.group(1);
- }
-
- private void setWifiMeteredState(boolean metered) throws Exception {
- if (metered) {
- // Make sure unmetered cellular networks don't interfere.
- setAirplaneMode(true);
- setWifiState(true, mCm, mWifiManager);
- }
- final String ssid = getWifiSSID();
- setWifiMeteredState(ssid, metered ? "true" : "false");
- }
-
- // metered should be "true", "false" or "none"
- private void setWifiMeteredState(String ssid, String metered) {
- if (metered.equals(getWifiMeteredStatus(ssid))) {
- return;
- }
- SystemUtil.runShellCommand("cmd netpolicy set metered-network " + ssid + " " + metered);
- assertEquals(getWifiMeteredStatus(ssid), metered);
+ private boolean hasEthernetConnection() {
+ return mNetworkingHelper.hasEthernetConnection();
}
private String getJobState() throws Exception {
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/NetworkingHelper.java b/tests/JobScheduler/src/android/jobscheduler/cts/NetworkingHelper.java
new file mode 100644
index 0000000..1402975
--- /dev/null
+++ b/tests/JobScheduler/src/android/jobscheduler/cts/NetworkingHelper.java
@@ -0,0 +1,432 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.jobscheduler.cts;
+
+import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
+import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
+
+import static com.android.compatibility.common.util.TestUtils.waitUntil;
+
+import static junit.framework.Assert.fail;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+import android.Manifest;
+import android.annotation.NonNull;
+import android.app.Instrumentation;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.location.LocationManager;
+import android.net.ConnectivityManager;
+import android.net.Network;
+import android.net.NetworkCapabilities;
+import android.net.NetworkRequest;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiManager;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.provider.Settings;
+import android.util.Log;
+
+import com.android.compatibility.common.util.CallbackAsserter;
+import com.android.compatibility.common.util.ShellIdentityUtils;
+import com.android.compatibility.common.util.SystemUtil;
+
+import junit.framework.AssertionFailedError;
+
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class NetworkingHelper {
+ private static final String TAG = "JsNetworkingUtils";
+
+ private static final String RESTRICT_BACKGROUND_GET_CMD =
+ "cmd netpolicy get restrict-background";
+ private static final String RESTRICT_BACKGROUND_ON_CMD =
+ "cmd netpolicy set restrict-background true";
+ private static final String RESTRICT_BACKGROUND_OFF_CMD =
+ "cmd netpolicy set restrict-background false";
+
+ private final Context mContext;
+ private final Instrumentation mInstrumentation;
+
+ private final ConnectivityManager mConnectivityManager;
+ private final WifiManager mWifiManager;
+
+ /** Whether the device running these tests supports WiFi. */
+ private final boolean mHasWifi;
+ /** Whether the device running these tests supports ethernet. */
+ private final boolean mHasEthernet;
+ /** Whether the device running these tests supports telephony. */
+ private final boolean mHasTelephony;
+
+ private final boolean mInitialAirplaneModeState;
+ private final boolean mInitialDataSaverState;
+ private final String mInitialLocationMode;
+ private final boolean mInitialWiFiState;
+ private String mInitialWiFiMeteredState;
+ private String mInitialWiFiSSID;
+
+ NetworkingHelper(@NonNull Instrumentation instrumentation, @NonNull Context context)
+ throws Exception {
+ mContext = context;
+ mInstrumentation = instrumentation;
+
+ mConnectivityManager = context.getSystemService(ConnectivityManager.class);
+ mWifiManager = context.getSystemService(WifiManager.class);
+
+ PackageManager packageManager = mContext.getPackageManager();
+ mHasWifi = packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI);
+ mHasEthernet = packageManager.hasSystemFeature(PackageManager.FEATURE_ETHERNET);
+ mHasTelephony = packageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
+
+ mInitialAirplaneModeState = isAirplaneModeOn();
+ mInitialDataSaverState = isDataSaverEnabled();
+ mInitialLocationMode = Settings.Secure.getString(
+ mContext.getContentResolver(), Settings.Secure.LOCATION_MODE);
+ mInitialWiFiState = mHasWifi && isWifiEnabled();
+ }
+
+ /** Ensures that the device has a wifi network saved. */
+ void ensureSavedWifiNetwork() throws Exception {
+ if (!mHasWifi) {
+ return;
+ }
+ final List<WifiConfiguration> savedNetworks =
+ ShellIdentityUtils.invokeMethodWithShellPermissions(
+ mWifiManager, WifiManager::getConfiguredNetworks);
+ assertFalse("Need at least one saved wifi network", savedNetworks.isEmpty());
+
+ setWifiState(true);
+ if (mInitialWiFiSSID == null) {
+ mInitialWiFiSSID = getWifiSSID();
+ mInitialWiFiMeteredState = getWifiMeteredStatus(mInitialWiFiSSID);
+ }
+ }
+
+ // Returns "true", "false", or "none".
+ private String getWifiMeteredStatus(String ssid) {
+ // Interestingly giving the SSID as an argument to list wifi-networks
+ // only works iff the network in question has the "false" policy.
+ // Also unfortunately runShellCommand does not pass the command to the interpreter
+ // so it's not possible to | grep the ssid.
+ final String command = "cmd netpolicy list wifi-networks";
+ final String policyString = SystemUtil.runShellCommand(command);
+
+ final Matcher m = Pattern.compile(ssid + ";(true|false|none)",
+ Pattern.MULTILINE | Pattern.UNIX_LINES).matcher(policyString);
+ if (!m.find()) {
+ fail("Unexpected format from cmd netpolicy (when looking for " + ssid + "): "
+ + policyString);
+ }
+ return m.group(1);
+ }
+
+ @NonNull
+ private String getWifiSSID() throws Exception {
+ // Location needs to be enabled to get the WiFi information.
+ setLocationMode(String.valueOf(Settings.Secure.LOCATION_MODE_ON));
+ final AtomicReference<String> ssid = new AtomicReference<>();
+ SystemUtil.runWithShellPermissionIdentity(
+ () -> ssid.set(mWifiManager.getConnectionInfo().getSSID()),
+ Manifest.permission.ACCESS_FINE_LOCATION);
+ return unquoteSSID(ssid.get());
+ }
+
+ boolean hasEthernetConnection() {
+ if (!mHasEthernet) return false;
+ Network[] networks = mConnectivityManager.getAllNetworks();
+ for (Network network : networks) {
+ if (mConnectivityManager.getNetworkCapabilities(network)
+ .hasTransport(TRANSPORT_ETHERNET)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ boolean hasWifiFeature() {
+ return mHasWifi;
+ }
+
+ boolean isAirplaneModeOn() throws Exception {
+ final String output = SystemUtil.runShellCommand(mInstrumentation,
+ "cmd connectivity airplane-mode").trim();
+ return "enabled".equals(output);
+ }
+
+ boolean isDataSaverEnabled() throws Exception {
+ return SystemUtil
+ .runShellCommand(mInstrumentation, RESTRICT_BACKGROUND_GET_CMD)
+ .contains("enabled");
+ }
+
+ boolean isWiFiConnected() {
+ if (!mWifiManager.isWifiEnabled()) {
+ return false;
+ }
+ final Network network = mConnectivityManager.getActiveNetwork();
+ if (network == null) {
+ return false;
+ }
+ final NetworkCapabilities networkCapabilities =
+ mConnectivityManager.getNetworkCapabilities(network);
+ return networkCapabilities != null && networkCapabilities.hasTransport(TRANSPORT_WIFI);
+ }
+
+ boolean isWifiEnabled() {
+ return mWifiManager.isWifiEnabled();
+ }
+
+ /**
+ * Tries to set all network statuses to {@code enabled}.
+ * However, this does not support ethernet connections.
+ * Confirm that {@link #hasEthernetConnection()} returns false before relying on this.
+ */
+ void setAllNetworksEnabled(boolean enabled) throws Exception {
+ if (mHasWifi) {
+ setWifiState(enabled);
+ }
+ setAirplaneMode(!enabled);
+ }
+
+ void setAirplaneMode(boolean on) throws Exception {
+ if (isAirplaneModeOn() == on) {
+ return;
+ }
+ final CallbackAsserter airplaneModeBroadcastAsserter = CallbackAsserter.forBroadcast(
+ new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED));
+ SystemUtil.runShellCommand(mInstrumentation,
+ "cmd connectivity airplane-mode " + (on ? "enable" : "disable"));
+ airplaneModeBroadcastAsserter.assertCalled("Didn't get airplane mode changed broadcast",
+ 15 /* 15 seconds */);
+ if (!on && mHasWifi) {
+ // Try to trigger some network connection.
+ setWifiState(true);
+ }
+ waitUntil("Airplane mode didn't change to " + (on ? " on" : " off"), 60 /* seconds */,
+ () -> {
+ // Airplane mode only affects the cellular network. If the device doesn't
+ // support cellular, then we can only check that the airplane mode toggle is on.
+ if (!mHasTelephony) {
+ return on == isAirplaneModeOn();
+ }
+ if (on) {
+ Network[] networks = mConnectivityManager.getAllNetworks();
+ for (Network network : networks) {
+ if (mConnectivityManager.getNetworkCapabilities(network)
+ .hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
+ return false;
+ }
+ }
+ return true;
+ } else {
+ return mConnectivityManager.getActiveNetwork() != null;
+ }
+ });
+ // Wait some time for the network changes to propagate. Can't use
+ // waitUntil(isAirplaneModeOn() == on) because the response quickly gives the new
+ // airplane mode status even though the network changes haven't propagated all the way to
+ // JobScheduler.
+ Thread.sleep(5000);
+ }
+
+ /**
+ * Ensures that restrict background data usage policy is turned off.
+ * If the policy is on, it interferes with tests that relies on metered connection.
+ */
+ void setDataSaverEnabled(boolean enabled) throws Exception {
+ SystemUtil.runShellCommand(mInstrumentation,
+ enabled ? RESTRICT_BACKGROUND_ON_CMD : RESTRICT_BACKGROUND_OFF_CMD);
+ }
+
+ private void setLocationMode(String mode) throws Exception {
+ Settings.Secure.putString(mContext.getContentResolver(),
+ Settings.Secure.LOCATION_MODE, mode);
+ final LocationManager locationManager = mContext.getSystemService(LocationManager.class);
+ final boolean wantEnabled = !String.valueOf(Settings.Secure.LOCATION_MODE_OFF).equals(mode);
+ waitUntil("Location " + (wantEnabled ? "not enabled" : "still enabled"),
+ () -> wantEnabled == locationManager.isLocationEnabled());
+ }
+
+ void setWifiMeteredState(boolean metered) throws Exception {
+ if (metered) {
+ // Make sure unmetered cellular networks don't interfere.
+ setAirplaneMode(true);
+ setWifiState(true);
+ }
+ final String ssid = getWifiSSID();
+ setWifiMeteredState(ssid, metered ? "true" : "false");
+ }
+
+ // metered should be "true", "false" or "none"
+ private void setWifiMeteredState(String ssid, String metered) {
+ if (metered.equals(getWifiMeteredStatus(ssid))) {
+ return;
+ }
+ SystemUtil.runShellCommand("cmd netpolicy set metered-network " + ssid + " " + metered);
+ assertEquals(getWifiMeteredStatus(ssid), metered);
+ }
+
+ /**
+ * Set Wifi connection to specific state, and block until we've verified
+ * that we are in the state.
+ * Taken from {@link android.net.http.cts.ApacheHttpClientTest}.
+ */
+ void setWifiState(final boolean enable) throws Exception {
+ if (enable != isWiFiConnected()) {
+ NetworkRequest nr = new NetworkRequest.Builder().clearCapabilities().build();
+ NetworkCapabilities nc = new NetworkCapabilities.Builder()
+ .addTransportType(TRANSPORT_WIFI)
+ .build();
+ NetworkTracker tracker = new NetworkTracker(nc, enable, mConnectivityManager);
+ mConnectivityManager.registerNetworkCallback(nr, tracker);
+
+ if (enable) {
+ SystemUtil.runShellCommand("svc wifi enable");
+ waitUntil("Failed to enable Wifi", 30 /* seconds */,
+ this::isWifiEnabled);
+ //noinspection deprecation
+ SystemUtil.runWithShellPermissionIdentity(mWifiManager::reconnect,
+ android.Manifest.permission.NETWORK_SETTINGS);
+ } else {
+ SystemUtil.runShellCommand("svc wifi disable");
+ }
+
+ tracker.waitForStateChange();
+
+ assertEquals("Wifi must be " + (enable ? "connected to" : "disconnected from")
+ + " an access point for this test.", enable, isWiFiConnected());
+
+ mConnectivityManager.unregisterNetworkCallback(tracker);
+ }
+ }
+
+ void tearDown() throws Exception {
+ // Restore initial restrict background data usage policy
+ setDataSaverEnabled(mInitialDataSaverState);
+
+ // Ensure that we leave WiFi in its previous state.
+ if (mHasWifi) {
+ if (mInitialWiFiSSID != null) {
+ setWifiMeteredState(mInitialWiFiSSID, mInitialWiFiMeteredState);
+ }
+ if (mWifiManager.isWifiEnabled() != mInitialWiFiState) {
+ try {
+ setWifiState(mInitialWiFiState);
+ } catch (AssertionFailedError e) {
+ // Don't fail the test just because wifi state wasn't set in tearDown.
+ Log.e(TAG, "Failed to return wifi state to " + mInitialWiFiState, e);
+ }
+ }
+ }
+
+ // Restore initial airplane mode status. Do it after setting wifi in case wifi was
+ // originally metered.
+ if (isAirplaneModeOn() != mInitialAirplaneModeState) {
+ setAirplaneMode(mInitialAirplaneModeState);
+ }
+
+ setLocationMode(mInitialLocationMode);
+ }
+
+ private String unquoteSSID(String ssid) {
+ // SSID is returned surrounded by quotes if it can be decoded as UTF-8.
+ // Otherwise it's guaranteed not to start with a quote.
+ if (ssid.charAt(0) == '"') {
+ return ssid.substring(1, ssid.length() - 1);
+ } else {
+ return ssid;
+ }
+ }
+
+ static class NetworkTracker extends ConnectivityManager.NetworkCallback {
+ private static final int MSG_CHECK_ACTIVE_NETWORK = 1;
+ private final ConnectivityManager mConnectivityManager;
+
+ private final CountDownLatch mReceiveLatch = new CountDownLatch(1);
+
+ private final NetworkCapabilities mExpectedCapabilities;
+
+ private final boolean mExpectedConnected;
+
+ private final Handler mHandler = new Handler(Looper.getMainLooper()) {
+ @Override
+ public void handleMessage(Message msg) {
+ if (msg.what == MSG_CHECK_ACTIVE_NETWORK) {
+ checkActiveNetwork();
+ }
+ }
+ };
+
+ NetworkTracker(NetworkCapabilities expectedCapabilities, boolean expectedConnected,
+ ConnectivityManager cm) {
+ mExpectedCapabilities = expectedCapabilities;
+ mExpectedConnected = expectedConnected;
+ mConnectivityManager = cm;
+ }
+
+ @Override
+ public void onAvailable(Network network) {
+ // Available doesn't mean it's the active network. We need to check that separately.
+ checkActiveNetwork();
+ }
+
+ @Override
+ public void onLost(Network network) {
+ checkActiveNetwork();
+ }
+
+ boolean waitForStateChange() throws InterruptedException {
+ checkActiveNetwork();
+ return mReceiveLatch.await(60, TimeUnit.SECONDS);
+ }
+
+ private void checkActiveNetwork() {
+ mHandler.removeMessages(MSG_CHECK_ACTIVE_NETWORK);
+ if (mReceiveLatch.getCount() == 0) {
+ return;
+ }
+
+ Network activeNetwork = mConnectivityManager.getActiveNetwork();
+ if (mExpectedConnected) {
+ if (activeNetwork != null && mExpectedCapabilities.satisfiedByNetworkCapabilities(
+ mConnectivityManager.getNetworkCapabilities(activeNetwork))) {
+ mReceiveLatch.countDown();
+ } else {
+ mHandler.sendEmptyMessageDelayed(MSG_CHECK_ACTIVE_NETWORK, 5000);
+ }
+ } else {
+ if (activeNetwork == null
+ || !mExpectedCapabilities.satisfiedByNetworkCapabilities(
+ mConnectivityManager.getNetworkCapabilities(activeNetwork))) {
+ mReceiveLatch.countDown();
+ } else {
+ mHandler.sendEmptyMessageDelayed(MSG_CHECK_ACTIVE_NETWORK, 5000);
+ }
+ }
+ }
+ }
+}
diff --git a/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerBaseTest.java b/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerBaseTest.java
index 79d4b2b..197fbd5 100644
--- a/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerBaseTest.java
+++ b/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerBaseTest.java
@@ -20,13 +20,12 @@
import android.app.Instrumentation;
import android.content.Context;
import android.content.Intent;
-import android.provider.DeviceConfig;
+import android.content.pm.PackageManager;
import androidx.test.InstrumentationRegistry;
import androidx.test.uiautomator.UiDevice;
-import com.android.modules.utils.build.SdkLevel;
-
+import org.junit.Assume;
import org.junit.Before;
/**
@@ -42,6 +41,8 @@
@Before
public void setUp() throws Exception {
+ Assume.assumeTrue(isHardwareSupported());
+
final Instrumentation inst = InstrumentationRegistry.getInstrumentation();
mDevice = UiDevice.getInstance(inst);
@@ -63,4 +64,15 @@
mActivity.clearResult();
mDevice.waitForIdle();
}
+
+ private static boolean isHardwareSupported() {
+ final Instrumentation inst = InstrumentationRegistry.getInstrumentation();
+ // These UI tests are not optimised for Watches, TVs, Auto;
+ // IoT devices do not have a UI to run these UI tests
+ PackageManager pm = inst.getContext().getPackageManager();
+ return !pm.hasSystemFeature(pm.FEATURE_EMBEDDED)
+ && !pm.hasSystemFeature(pm.FEATURE_WATCH)
+ && !pm.hasSystemFeature(pm.FEATURE_LEANBACK)
+ && !pm.hasSystemFeature(pm.FEATURE_AUTOMOTIVE);
+ }
}
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDispatchTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDispatchTest.java
index f0e3b67..d23e211 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDispatchTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDispatchTest.java
@@ -25,7 +25,6 @@
import static android.accessibilityservice.cts.utils.GestureUtils.IS_ACTION_POINTER_UP;
import static android.accessibilityservice.cts.utils.GestureUtils.IS_ACTION_UP;
import static android.accessibilityservice.cts.utils.GestureUtils.add;
-import static android.accessibilityservice.cts.utils.GestureUtils.ceil;
import static android.accessibilityservice.cts.utils.GestureUtils.click;
import static android.accessibilityservice.cts.utils.GestureUtils.diff;
import static android.accessibilityservice.cts.utils.GestureUtils.dispatchGesture;
@@ -56,11 +55,11 @@
import android.accessibilityservice.cts.activities.AccessibilityTestActivity;
import android.app.Instrumentation;
import android.app.UiAutomation;
-import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Matrix;
import android.graphics.Path;
import android.graphics.PointF;
+import android.graphics.Rect;
import android.os.Bundle;
import android.os.SystemClock;
import android.platform.test.annotations.AppModeFull;
@@ -69,7 +68,6 @@
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
-import android.view.WindowManager;
import android.widget.TextView;
import androidx.test.rule.ActivityTestRule;
@@ -88,8 +86,6 @@
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
-import android.graphics.Rect;
-
/**
* Verify that gestures dispatched from an accessibility service show up in the current UI
*/
@@ -196,7 +192,8 @@
// Verify other MotionEvent fields in this test to make sure they get initialized.
assertEquals(0, clickDown.getActionIndex());
assertEquals(VIRTUAL_KEYBOARD, clickDown.getDeviceId());
- assertEquals(MotionEvent.FLAG_IS_ACCESSIBILITY_EVENT, clickDown.getFlags());
+ assertEquals(MotionEvent.FLAG_IS_ACCESSIBILITY_EVENT,
+ clickDown.getFlags() & MotionEvent.FLAG_IS_ACCESSIBILITY_EVENT);
assertEquals(0, clickDown.getEdgeFlags());
assertEquals(1F, clickDown.getXPrecision(), 0F);
assertEquals(1F, clickDown.getYPrecision(), 0F);
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowReportingTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowReportingTest.java
index 49dfb93..3461e6a 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowReportingTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowReportingTest.java
@@ -16,6 +16,7 @@
package android.accessibilityservice.cts;
+import static android.accessibilityservice.cts.utils.AccessibilityEventFilterUtils.filterWaitForAll;
import static android.accessibilityservice.cts.utils.AccessibilityEventFilterUtils.filterWindowsChangeTypesAndWindowTitle;
import static android.accessibilityservice.cts.utils.AccessibilityEventFilterUtils.filterWindowsChangedWithChangeTypes;
import static android.accessibilityservice.cts.utils.ActivityLaunchUtils.findWindowByTitle;
@@ -431,15 +432,21 @@
intent.setAction(NotTouchableWindowTestActivity.ADD_WINDOW);
try {
- // Waits for the not-touchable activity is covered by the untrusted window.
- sUiAutomation.executeAndWaitForEvent(() -> sInstrumentation.runOnMainSync(
- () -> sInstrumentation.getContext().sendBroadcast(intent)),
- (event) -> {
- final AccessibilityWindowInfo notTouchableWindow =
- findWindowByTitle(sUiAutomation,
- NotTouchableWindowTestActivity.TITLE);
- return notTouchableWindow == null;
- }, TIMEOUT_ASYNC_PROCESSING);
+ // Waits for two events, whose order is nondeterministic:
+ // (1) the test activity is covered by the untrusted non-touchable window.
+ // (2) the untrusted non-touchable window is added.
+ sendIntentAndWaitForEvent(intent,
+ filterWaitForAll(
+ event -> {
+ final AccessibilityWindowInfo coveredWindow =
+ findWindowByTitle(sUiAutomation,
+ NotTouchableWindowTestActivity.TITLE);
+ return coveredWindow == null;
+ },
+ filterWindowsChangeTypesAndWindowTitle(sUiAutomation,
+ WINDOWS_CHANGE_ADDED,
+ NotTouchableWindowTestActivity.NON_TOUCHABLE_WINDOW_TITLE)
+ ));
} finally {
intent.setAction(NotTouchableWindowTestActivity.REMOVE_WINDOW);
sendIntentAndWaitForEvent(intent,
@@ -468,7 +475,7 @@
sendIntentAndWaitForEvent(intent,
filterWindowsChangeTypesAndWindowTitle(sUiAutomation,
WINDOWS_CHANGE_ADDED,
- NotTouchableWindowTestActivity.NON_TOUCHABLE_WINDOW_TITLE.toString())
+ NotTouchableWindowTestActivity.NON_TOUCHABLE_WINDOW_TITLE)
);
}, Manifest.permission.INTERNAL_SYSTEM_WINDOW);
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/activities/NotTouchableWindowTestActivity.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/activities/NotTouchableWindowTestActivity.java
index 9aca75f..e2bd5c2 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/activities/NotTouchableWindowTestActivity.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/activities/NotTouchableWindowTestActivity.java
@@ -71,9 +71,9 @@
private BroadcastReceiver mBroadcastReceiver = new CommandReceiver();
- public static final CharSequence TITLE =
+ public static final String TITLE =
"NotTouchableWindowTestActivity";
- public static final CharSequence NON_TOUCHABLE_WINDOW_TITLE =
+ public static final String NON_TOUCHABLE_WINDOW_TITLE =
"android.accessibilityservice.cts.activities.NON_TOUCHABLE_WINDOW_TITLE";
public static final String ADD_WINDOW =
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/utils/AccessibilityEventFilterUtils.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/utils/AccessibilityEventFilterUtils.java
index 57d1103..01e484e 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/utils/AccessibilityEventFilterUtils.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/utils/AccessibilityEventFilterUtils.java
@@ -27,6 +27,8 @@
import org.hamcrest.Description;
import org.hamcrest.TypeSafeMatcher;
+import java.util.Arrays;
+import java.util.LinkedList;
import java.util.List;
import java.util.function.BiPredicate;
@@ -79,6 +81,25 @@
new WindowIdMatcher(windowId))::matches;
}
+ /**
+ * Creates an {@link AccessibilityEventFilter} that returns {@code true} once all the given
+ * filters return {@code true} for any event.
+ * Each given filters are invoked on every AccessibilityEvent until it returns {@code true}.
+ * After all filters return {@code true} once, the created filter returns {@code true} forever.
+ */
+ public static AccessibilityEventFilter filterWaitForAll(AccessibilityEventFilter... filters) {
+ return new AccessibilityEventFilter() {
+ private final List<AccessibilityEventFilter> mUnresolved =
+ new LinkedList<>(Arrays.asList(filters));
+
+ @Override
+ public boolean accept(AccessibilityEvent event) {
+ mUnresolved.removeIf(filter -> filter.accept(event));
+ return mUnresolved.isEmpty();
+ }
+ };
+ }
+
public static class AccessibilityEventTypeMatcher extends TypeSafeMatcher<AccessibilityEvent> {
private int mType;
diff --git a/tests/app/src/android/app/cts/ActivityManagerProcessStateTest.java b/tests/app/src/android/app/cts/ActivityManagerProcessStateTest.java
index 9409b25..ed7c72a 100644
--- a/tests/app/src/android/app/cts/ActivityManagerProcessStateTest.java
+++ b/tests/app/src/android/app/cts/ActivityManagerProcessStateTest.java
@@ -79,10 +79,14 @@
import com.android.compatibility.common.util.AmMonitor;
import com.android.compatibility.common.util.SystemUtil;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;
@@ -190,6 +194,22 @@
}
}
+ @After
+ public void tearDown() throws Exception {
+ // Stop all the packages
+ final List<String> allPackageNames = new ArrayList<>();
+ allPackageNames.addAll(Arrays.asList(PACKAGE_NAMES));
+ allPackageNames.add(SIMPLE_PACKAGE_NAME);
+ allPackageNames.add(CANT_SAVE_STATE_1_PACKAGE_NAME);
+ allPackageNames.add(CANT_SAVE_STATE_2_PACKAGE_NAME);
+ final ActivityManager am = mContext.getSystemService(ActivityManager.class);
+ for (final String pkgName : allPackageNames) {
+ SystemUtil.runWithShellPermissionIdentity(() -> {
+ am.forceStopPackage(pkgName);
+ });
+ }
+ }
+
/**
* Drain the ordered broadcast queue, it'll be useful when the test runs in secondary user
* which is just created prior to the testing, the ordered broadcast queue could be clogged.
diff --git a/tests/app/src/android/app/cts/NotificationTemplateTest.kt b/tests/app/src/android/app/cts/NotificationTemplateTest.kt
index ff8bf56..f7edaf7 100644
--- a/tests/app/src/android/app/cts/NotificationTemplateTest.kt
+++ b/tests/app/src/android/app/cts/NotificationTemplateTest.kt
@@ -16,7 +16,6 @@
package android.app.cts
import android.R
-import android.app.ActivityManager
import android.app.Notification
import android.app.PendingIntent
import android.app.Person
@@ -36,8 +35,8 @@
import androidx.test.filters.SmallTest
import com.android.compatibility.common.util.CddTest
import com.google.common.truth.Truth.assertThat
-import kotlin.math.min
import kotlin.test.assertFailsWith
+import org.junit.Assume
class NotificationTemplateTest : NotificationTemplateTestBase() {
@@ -144,11 +143,7 @@
}
fun testWideIcon_inBigPicture_cappedTo16By9() {
- if (isPlatformAutomotive()) {
- Log.i(TAG, "Skipping: testWideIcon_inBigPicture_cappedTo16By9" +
- " - BigPictureStyle is not supported in automotive.")
- return
- }
+ skipIfPlatformDoesNotSupportNotificationStyles()
val picture = createBitmap(40, 30)
val icon = createBitmap(200, 100)
val views = Notification.Builder(mContext, NOTIFICATION_CHANNEL_ID)
@@ -166,11 +161,7 @@
}
fun testWideIcon_inBigPicture_canShowExact4By3() {
- if (isPlatformAutomotive()) {
- Log.i(TAG, "Skipping: testWideIcon_inBigPicture_canShowExact4By3" +
- " - BigPictureStyle is not supported in automotive.")
- return
- }
+ skipIfPlatformDoesNotSupportNotificationStyles()
val picture = createBitmap(40, 30)
val icon = createBitmap(400, 300)
val views = Notification.Builder(mContext, NOTIFICATION_CHANNEL_ID)
@@ -188,11 +179,7 @@
}
fun testWideIcon_inBigPicture_neverNarrowerThanSquare() {
- if (isPlatformAutomotive()) {
- Log.i(TAG, "Skipping: testWideIcon_inBigPicture_neverNarrowerThanSquare" +
- " - BigPictureStyle is not supported in automotive.")
- return
- }
+ skipIfPlatformDoesNotSupportNotificationStyles()
val picture = createBitmap(40, 30)
val icon = createBitmap(200, 300)
val views = Notification.Builder(mContext, NOTIFICATION_CHANNEL_ID)
@@ -254,11 +241,7 @@
}
fun testBigPictureStyle_populatesExtrasCompatibly() {
- if (isPlatformAutomotive()) {
- Log.i(TAG, "Skipping: testBigPictureStyle_populatesExtrasCompatibly" +
- " - BigPictureStyle is not supported in automotive.")
- return
- }
+ skipIfPlatformDoesNotSupportNotificationStyles()
val bitmap = createBitmap(40, 30)
val uri = Uri.parse("content://android.app.stubs.assets/picture_400_by_300.png")
val iconWithUri = Icon.createWithContentUri(uri)
@@ -272,7 +255,7 @@
style.bigPicture(bitmap)
builder.build().let {
assertThat(it.extras.getParcelable<Bitmap>(Notification.EXTRA_PICTURE)
- !!.sameAs(bitmap)).isTrue()
+ !!.sameAs(bitmap)).isTrue()
assertThat(it.extras.get(Notification.EXTRA_PICTURE_ICON)).isNull()
}
@@ -286,18 +269,15 @@
style.bigPicture(iconWithBitmap)
builder.build().let {
assertThat(it.extras.getParcelable<Bitmap>(Notification.EXTRA_PICTURE)
- !!.sameAs(bitmap)).isTrue()
+ !!.sameAs(bitmap)).isTrue()
assertThat(it.extras.get(Notification.EXTRA_PICTURE_ICON)).isNull()
}
}
@CddTest(requirement = "3.8.3.1/C-2-1")
fun testBigPictureStyle_bigPictureUriIcon() {
- if (isPlatformAutomotive()) {
- Log.i(TAG, "Skipping: testBigPictureStyle_bigPictureUriIcon" +
- " - BigPictureStyle is not supported in automotive.")
- return
- }
+ skipIfPlatformDoesNotSupportNotificationStyles()
+
val pictureUri = Uri.parse("content://android.app.stubs.assets/picture_400_by_300.png")
val pictureIcon = Icon.createWithContentUri(pictureUri)
val builder = Notification.Builder(mContext, NOTIFICATION_CHANNEL_ID)
@@ -307,28 +287,16 @@
checkViews(builder.createBigContentView()) {
val pictureView = requireViewByIdName<ImageView>("big_picture")
assertThat(pictureView.visibility).isEqualTo(View.VISIBLE)
-
- var expectedWidth = min(400, bigPictureWidth())
- var expectedHeight = min(300, bigPictureWidth() * 3 / 4)
- // It's possible that big picture width is configured smaller than we expect here.
- // In that situation, we need to flip the expected size.
- if (bigPictureHeight() < expectedHeight) {
- expectedHeight = bigPictureHeight()
- expectedWidth = bigPictureHeight() * 4 / 3
- }
-
- assertThat(pictureView.drawable.intrinsicWidth).isEqualTo(expectedWidth)
- assertThat(pictureView.drawable.intrinsicHeight).isEqualTo(expectedHeight)
+ assertThat(pictureView.width.toFloat())
+ .isWithin(1f)
+ .of((pictureView.height * 4 / 3).toFloat())
+ assertThat(pictureView.scaleType).isEqualTo(ImageView.ScaleType.CENTER_CROP)
}
}
@CddTest(requirement = "3.8.3.1/C-2-1")
fun testPromoteBigPicture_withBigPictureUriIcon() {
- if (isPlatformAutomotive()) {
- Log.i(TAG, "Skipping: testPromoteBigPicture_withBigPictureUriIcon" +
- " - BigPictureStyle is not supported in automotive.")
- return
- }
+ skipIfPlatformDoesNotSupportNotificationStyles()
val pictureUri = Uri.parse("content://android.app.stubs.assets/picture_800_by_600.png")
val pictureIcon = Icon.createWithContentUri(pictureUri)
val builder = Notification.Builder(mContext, NOTIFICATION_CHANNEL_ID)
@@ -343,17 +311,13 @@
assertThat(iconView.width.toFloat())
.isWithin(1f)
.of((iconView.height * 4 / 3).toFloat())
- assertThat(iconView.drawable.intrinsicWidth).isEqualTo(rightIconSize())
- assertThat(iconView.drawable.intrinsicHeight).isEqualTo(rightIconSize() * 3 / 4)
+ assertThat(iconView.scaleType).isEqualTo(ImageView.ScaleType.CENTER_CROP)
}
}
fun testPromoteBigPicture_withoutLargeIcon() {
- if (isPlatformAutomotive()) {
- Log.i(TAG, "Skipping: testPromoteBigPicture_withoutLargeIcon" +
- " - BigPictureStyle is not supported in automotive.")
- return
- }
+ skipIfPlatformDoesNotSupportNotificationStyles()
+
val picture = createBitmap(40, 30)
val builder = Notification.Builder(mContext, NOTIFICATION_CHANNEL_ID)
.setSmallIcon(R.drawable.ic_media_play)
@@ -367,8 +331,7 @@
assertThat(iconView.width.toFloat())
.isWithin(1f)
.of((iconView.height * 4 / 3).toFloat())
- assertThat(iconView.drawable.intrinsicWidth).isEqualTo(40)
- assertThat(iconView.drawable.intrinsicHeight).isEqualTo(30)
+ assertThat(iconView.scaleType).isEqualTo(ImageView.ScaleType.CENTER_CROP)
}
checkIconView(builder.createBigContentView()) { iconView ->
assertThat(iconView.visibility).isEqualTo(View.GONE)
@@ -376,11 +339,8 @@
}
fun testPromoteBigPicture_withLargeIcon() {
- if (isPlatformAutomotive()) {
- Log.i(TAG, "Skipping: testPromoteBigPicture_withLargeIcon" +
- " - BigPictureStyle is not supported in automotive.")
- return
- }
+ skipIfPlatformDoesNotSupportNotificationStyles()
+
val picture = createBitmap(40, 30)
val icon = createBitmap(80, 65)
val builder = Notification.Builder(mContext, NOTIFICATION_CHANNEL_ID)
@@ -392,37 +352,26 @@
.showBigPictureWhenCollapsed(true)
)
- // At really high densities the size of rendered icon can dip below the
- // tested size - we allow rendering of smaller icon with the same
- // aspect ratio then.
- val expectedIconWidth = minOf(rightIconSize(), 80)
- val expectedIconHeight = minOf(rightIconSize() * 65 / 80, 65)
-
checkIconView(builder.createContentView()) { iconView ->
assertThat(iconView.visibility).isEqualTo(View.VISIBLE)
assertThat(iconView.width.toFloat())
.isWithin(1f)
.of((iconView.height * 4 / 3).toFloat())
- assertThat(iconView.drawable.intrinsicWidth).isEqualTo(40)
- assertThat(iconView.drawable.intrinsicHeight).isEqualTo(30)
+ assertThat(iconView.scaleType).isEqualTo(ImageView.ScaleType.CENTER_CROP)
}
checkIconView(builder.createBigContentView()) { iconView ->
assertThat(iconView.visibility).isEqualTo(View.VISIBLE)
assertThat(iconView.width.toFloat())
.isWithin(1f)
.of((iconView.height * 80 / 65).toFloat())
- assertThat(iconView.drawable.intrinsicWidth).isEqualTo(expectedIconWidth)
- assertThat(iconView.drawable.intrinsicHeight).isEqualTo(expectedIconHeight)
+ assertThat(iconView.scaleType).isEqualTo(ImageView.ScaleType.CENTER_CROP)
}
}
@CddTest(requirement = "3.8.3.1/C-2-1")
fun testPromoteBigPicture_withBigLargeIcon() {
- if (isPlatformAutomotive()) {
- Log.i(TAG, "Skipping: testPromoteBigPicture_withBigLargeIcon" +
- " - BigPictureStyle is not supported in automotive.")
- return
- }
+ skipIfPlatformDoesNotSupportNotificationStyles()
+
val picture = createBitmap(40, 30)
val inputWidth = 400
val inputHeight = 300
@@ -436,36 +385,28 @@
.showBigPictureWhenCollapsed(true)
)
- val expectedIconWidth = minOf(rightIconSize(), inputWidth)
- val expectedIconHeight = minOf(rightIconSize() * inputHeight / inputWidth, inputHeight)
-
checkIconView(builder.createContentView()) { iconView ->
assertThat(iconView.visibility).isEqualTo(View.VISIBLE)
assertThat(iconView.width.toFloat())
.isWithin(1f)
.of((iconView.height * 4 / 3).toFloat())
- assertThat(iconView.drawable.intrinsicWidth).isEqualTo(40)
- assertThat(iconView.drawable.intrinsicHeight).isEqualTo(30)
+ assertThat(iconView.scaleType).isEqualTo(ImageView.ScaleType.CENTER_CROP)
}
checkIconView(builder.createBigContentView()) { iconView ->
assertThat(iconView.visibility).isEqualTo(View.VISIBLE)
assertThat(iconView.width.toFloat())
.isWithin(1f)
.of((iconView.height * 4 / 3).toFloat())
- assertThat(iconView.drawable.intrinsicWidth).isEqualTo(expectedIconWidth)
- assertThat(iconView.drawable.intrinsicHeight).isEqualTo(expectedIconHeight)
+ assertThat(iconView.scaleType).isEqualTo(ImageView.ScaleType.CENTER_CROP)
}
assertThat(builder.build().extras.getParcelable<Bitmap>(Notification.EXTRA_PICTURE)
- !!.sameAs(picture)).isTrue()
+ !!.sameAs(picture)).isTrue()
}
@CddTest(requirement = "3.8.3.1/C-2-1")
fun testBigPicture_withBigLargeIcon_withContentUri() {
- if (isPlatformAutomotive()) {
- Log.i(TAG, "Skipping: testBigPicture_withBigLargeIcon_withContentUri" +
- " - BigPictureStyle is not supported in automotive.")
- return
- }
+ skipIfPlatformDoesNotSupportNotificationStyles()
+
val iconUri = Uri.parse("content://android.app.stubs.assets/picture_800_by_600.png")
val icon = Icon.createWithContentUri(iconUri)
val builder = Notification.Builder(mContext, NOTIFICATION_CHANNEL_ID)
@@ -477,9 +418,7 @@
assertThat(iconView.width.toFloat())
.isWithin(1f)
.of((iconView.height * 4 / 3).toFloat())
-
- assertThat(iconView.drawable.intrinsicWidth).isEqualTo(rightIconSize())
- assertThat(iconView.drawable.intrinsicHeight).isEqualTo(rightIconSize() * 3 / 4)
+ assertThat(iconView.scaleType).isEqualTo(ImageView.ScaleType.CENTER_CROP)
}
}
@@ -864,39 +803,15 @@
PendingIntent.getBroadcast(mContext, 0, Intent("test"), PendingIntent.FLAG_IMMUTABLE)
}
- private fun rightIconSize(): Int {
- return mContext.resources.getDimensionPixelSize(getAndroidRDimen(
- if (isLowRamDevice()) {
- "notification_right_icon_size_low_ram"
- } else {
- "notification_right_icon_size"
- }))
- }
-
- private fun bigPictureWidth(): Int {
- return mContext.resources.getDimensionPixelSize(getAndroidRDimen(
- if (isLowRamDevice()) {
- "notification_big_picture_max_width_low_ram"
- } else {
- "notification_big_picture_max_width"
- }))
- }
-
- private fun bigPictureHeight(): Int {
- return mContext.resources.getDimensionPixelSize(getAndroidRDimen(
- if (isLowRamDevice()) {
- "notification_big_picture_max_width_low_ram"
- } else {
- "notification_big_picture_max_width"
- }))
- }
-
- private fun isLowRamDevice(): Boolean {
- return mContext.getSystemService(ActivityManager::class.java).isLowRamDevice()
- }
-
- private fun isPlatformAutomotive(): Boolean {
- return mContext.packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)
+ /**
+ * Assume that we're running on the platform that supports styled notifications.
+ *
+ * If the current platform does not support notification styles, skip this test without failure.
+ */
+ private fun skipIfPlatformDoesNotSupportNotificationStyles() {
+ Assume.assumeFalse("Current platform does not support notification styles.",
+ mContext.packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE) ||
+ mContext.packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK))
}
companion object {
diff --git a/tests/camera/src/android/hardware/camera2/cts/CameraManagerTest.java b/tests/camera/src/android/hardware/camera2/cts/CameraManagerTest.java
index 18d4904..2c88064 100644
--- a/tests/camera/src/android/hardware/camera2/cts/CameraManagerTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/CameraManagerTest.java
@@ -669,18 +669,23 @@
}
private <T> void verifyAvailabilityCbsReceived(HashSet<T> expectedCameras,
- LinkedBlockingQueue<T> queue, LinkedBlockingQueue<T> otherQueue,
+ LinkedBlockingQueue<T> expectedEventQueue, LinkedBlockingQueue<T> unExpectedEventQueue,
boolean available) throws Exception {
while (expectedCameras.size() > 0) {
- T id = queue.poll(AVAILABILITY_TIMEOUT_MS,
+ T id = expectedEventQueue.poll(AVAILABILITY_TIMEOUT_MS,
java.util.concurrent.TimeUnit.MILLISECONDS);
assertTrue("Did not receive initial " + (available ? "available" : "unavailable")
+ " notices for some cameras", id != null);
+ assertTrue("Received initial " + (available ? "available" : "unavailable")
+ + " notice for wrong camera " + id, expectedCameras.contains(id));
expectedCameras.remove(id);
}
- // Verify no unavailable/available cameras were reported
- assertTrue("Some camera devices are initially " + (available ? "unavailable" : "available"),
- otherQueue.size() == 0);
+ // Verify no unexpected unavailable/available cameras were reported
+ if (unExpectedEventQueue != null) {
+ assertTrue("Received unexpected initial "
+ + (available ? "unavailable" : "available"),
+ unExpectedEventQueue.size() == 0);
+ }
}
private void verifySingleAvailabilityCbsReceived(LinkedBlockingQueue<String> expectedEventQueue,
@@ -781,15 +786,15 @@
verifyAvailabilityCbsReceived(expectedAvailableCameras, availableEventQueue,
unavailableEventQueue, true /*available*/);
+ // Clear physical camera callback queue in case the initial state of certain physical
+ // cameras are unavailable.
+ unavailablePhysicalCamEventQueue.clear();
+
// Verify transitions for individual cameras
for (String id : cameras) {
MockStateCallback mockListener = MockStateCallback.mock();
mCameraListener = new BlockingStateCallback(mockListener);
- // Clear logical camera callback queue in case the initial state of certain physical
- // cameras are unavailable.
- unavailablePhysicalCamEventQueue.clear();
-
if (useExecutor) {
mCameraManager.openCamera(id, executor, mCameraListener);
} else {
@@ -843,8 +848,13 @@
expectedLogicalCameras = new HashSet<Pair<String, String>>(relatedLogicalCameras);
verifyAvailabilityCbsReceived(expectedLogicalCameras,
- availablePhysicalCamEventQueue, unavailablePhysicalCamEventQueue,
+ availablePhysicalCamEventQueue,
+ null /*unExpectedEventQueue*/,
true /*available*/);
+
+ // Clear physical camera callback queue in case the initial state of certain physical
+ // cameras are unavailable.
+ unavailablePhysicalCamEventQueue.clear();
}
// Verify that we can unregister the listener and see no more events
@@ -938,6 +948,8 @@
verifySingleAvailabilityCbsReceived(onCameraClosedEventQueue,
onCameraOpenedEventQueue, cameras[0], "onCameraClosed", "onCameraOpened");
+
+ mCameraManager.unregisterAvailabilityCallback(ac);
}
} // testCameraManagerListenerCallbacks
diff --git a/tests/devicepolicy/src/android/devicepolicy/cts/DevicePolicyManagementRoleHolderTest.java b/tests/devicepolicy/src/android/devicepolicy/cts/DevicePolicyManagementRoleHolderTest.java
index 1c35d48..f85d895 100644
--- a/tests/devicepolicy/src/android/devicepolicy/cts/DevicePolicyManagementRoleHolderTest.java
+++ b/tests/devicepolicy/src/android/devicepolicy/cts/DevicePolicyManagementRoleHolderTest.java
@@ -148,25 +148,29 @@
UserHandle profile = null;
String roleHolderPackageName = null;
try (TestAppInstance roleHolderApp = sRoleHolderApp.install()) {
- roleHolderPackageName = roleHolderApp.packageName();
- TestApis.devicePolicy().setDevicePolicyManagementRoleHolder(roleHolderPackageName);
+ try {
+ roleHolderPackageName = roleHolderApp.packageName();
+ TestApis.devicePolicy().setDevicePolicyManagementRoleHolder(roleHolderPackageName);
- profile = sDevicePolicyManager.createAndProvisionManagedProfile(
- MANAGED_PROFILE_PROVISIONING_PARAMS);
+ profile = sDevicePolicyManager.createAndProvisionManagedProfile(
+ MANAGED_PROFILE_PROVISIONING_PARAMS);
- UserReference userReference = UserReference.of(profile);
- Poll.forValue(() -> TestApis.packages().installedForUser(userReference))
- .toMeet(packages -> packages.contains(Package.of(roleHolderApp.packageName())))
- .errorOnFail("Role holder package not installed on the managed profile.")
- .await();
+ UserReference userReference = UserReference.of(profile);
+ Poll.forValue(() -> TestApis.packages().installedForUser(userReference))
+ .toMeet(packages -> packages.contains(
+ Package.of(roleHolderApp.packageName())))
+ .errorOnFail("Role holder package not installed on the managed profile.")
+ .await();
+ } finally {
+ if (roleHolderPackageName != null) {
+ TestApis.devicePolicy()
+ .unsetDevicePolicyManagementRoleHolder(roleHolderPackageName);
+ }
+ }
} finally {
if (profile != null) {
TestApis.users().find(profile).remove();
}
- if (roleHolderPackageName != null) {
- TestApis.devicePolicy()
- .unsetDevicePolicyManagementRoleHolder(roleHolderPackageName);
- }
}
}
@@ -182,29 +186,33 @@
UserHandle managedUser = null;
String roleHolderPackageName = null;
try (TestAppInstance roleHolderApp = sRoleHolderApp.install()) {
- roleHolderPackageName = roleHolderApp.packageName();
- TestApis.devicePolicy().setDevicePolicyManagementRoleHolder(roleHolderPackageName);
+ try {
+ roleHolderPackageName = roleHolderApp.packageName();
+ TestApis.devicePolicy().setDevicePolicyManagementRoleHolder(roleHolderPackageName);
- managedUser = sDeviceState.dpc().devicePolicyManager().createAndManageUser(
- RemoteDpc.DPC_COMPONENT_NAME,
- MANAGED_USER_NAME,
- RemoteDpc.DPC_COMPONENT_NAME,
- /* adminExtras= */ null,
- /* flags= */ 0);
+ managedUser = sDeviceState.dpc().devicePolicyManager().createAndManageUser(
+ RemoteDpc.DPC_COMPONENT_NAME,
+ MANAGED_USER_NAME,
+ RemoteDpc.DPC_COMPONENT_NAME,
+ /* adminExtras= */ null,
+ /* flags= */ 0);
- UserReference userReference = UserReference.of(managedUser);
- Poll.forValue(() -> TestApis.packages().installedForUser(userReference))
- .toMeet(packages -> packages.contains(Package.of(roleHolderApp.packageName())))
- .errorOnFail("Role holder package not installed on the managed user.")
- .await();
+ UserReference userReference = UserReference.of(managedUser);
+ Poll.forValue(() -> TestApis.packages().installedForUser(userReference))
+ .toMeet(packages -> packages.contains(
+ Package.of(roleHolderApp.packageName())))
+ .errorOnFail("Role holder package not installed on the managed user.")
+ .await();
+ } finally {
+ if (roleHolderPackageName != null) {
+ TestApis.devicePolicy()
+ .unsetDevicePolicyManagementRoleHolder(roleHolderPackageName);
+ }
+ }
} finally {
if (managedUser != null) {
TestApis.users().find(managedUser).remove();
}
- if (roleHolderPackageName != null) {
- TestApis.devicePolicy()
- .unsetDevicePolicyManagementRoleHolder(roleHolderPackageName);
- }
}
}
@@ -218,20 +226,22 @@
public void profileRemoved_roleHolderReceivesBroadcast() throws Exception {
String roleHolderPackageName = null;
try (TestAppInstance roleHolderApp = sRoleHolderApp.install()) {
- roleHolderPackageName = roleHolderApp.packageName();
- TestApis.devicePolicy().setDevicePolicyManagementRoleHolder(roleHolderPackageName);
- UserHandle profile = sDevicePolicyManager.createAndProvisionManagedProfile(
- MANAGED_PROFILE_PROVISIONING_PARAMS);
+ try {
+ roleHolderPackageName = roleHolderApp.packageName();
+ TestApis.devicePolicy().setDevicePolicyManagementRoleHolder(roleHolderPackageName);
+ UserHandle profile = sDevicePolicyManager.createAndProvisionManagedProfile(
+ MANAGED_PROFILE_PROVISIONING_PARAMS);
- TestApis.users().find(profile).remove();
+ TestApis.users().find(profile).remove();
- EventLogsSubject.assertThat(roleHolderApp.events().broadcastReceived()
- .whereIntent().action().isEqualTo(ACTION_MANAGED_PROFILE_REMOVED))
- .eventOccurred();
- } finally {
- if (roleHolderPackageName != null) {
- TestApis.devicePolicy().unsetDevicePolicyManagementRoleHolder(
- roleHolderPackageName);
+ EventLogsSubject.assertThat(roleHolderApp.events().broadcastReceived()
+ .whereIntent().action().isEqualTo(ACTION_MANAGED_PROFILE_REMOVED))
+ .eventOccurred();
+ } finally {
+ if (roleHolderPackageName != null) {
+ TestApis.devicePolicy().unsetDevicePolicyManagementRoleHolder(
+ roleHolderPackageName);
+ }
}
}
}
@@ -246,20 +256,23 @@
public void profilePaused_roleHolderReceivesBroadcast() throws Exception {
String roleHolderPackageName = null;
try (TestAppInstance roleHolderApp = sRoleHolderApp.install()) {
- roleHolderPackageName = roleHolderApp.packageName();
- TestApis.devicePolicy().setDevicePolicyManagementRoleHolder(roleHolderPackageName);
- UserHandle profile = sDevicePolicyManager.createAndProvisionManagedProfile(
- MANAGED_PROFILE_PROVISIONING_PARAMS);
+ try {
+ roleHolderPackageName = roleHolderApp.packageName();
+ TestApis.devicePolicy().setDevicePolicyManagementRoleHolder(roleHolderPackageName);
+ UserHandle profile = sDevicePolicyManager.createAndProvisionManagedProfile(
+ MANAGED_PROFILE_PROVISIONING_PARAMS);
- TestApis.users().find(profile).setQuietMode(true);
+ TestApis.users().find(profile).setQuietMode(true);
- EventLogsSubject.assertThat(roleHolderApp.events().broadcastReceived()
- .whereIntent().action().isEqualTo(ACTION_MANAGED_PROFILE_UNAVAILABLE))
- .eventOccurred();
- } finally {
- if (roleHolderPackageName != null) {
- TestApis.devicePolicy().unsetDevicePolicyManagementRoleHolder(
- roleHolderPackageName);
+ EventLogsSubject.assertThat(roleHolderApp.events().broadcastReceived()
+ .whereIntent().action().isEqualTo(
+ ACTION_MANAGED_PROFILE_UNAVAILABLE))
+ .eventOccurred();
+ } finally {
+ if (roleHolderPackageName != null) {
+ TestApis.devicePolicy().unsetDevicePolicyManagementRoleHolder(
+ roleHolderPackageName);
+ }
}
}
}
@@ -274,21 +287,23 @@
public void profileStarted_roleHolderReceivesBroadcast() throws Exception {
String roleHolderPackageName = null;
try (TestAppInstance roleHolderApp = sRoleHolderApp.install()) {
- roleHolderPackageName = roleHolderApp.packageName();
- TestApis.devicePolicy().setDevicePolicyManagementRoleHolder(roleHolderPackageName);
- UserHandle profile = sDevicePolicyManager.createAndProvisionManagedProfile(
- MANAGED_PROFILE_PROVISIONING_PARAMS);
- TestApis.users().find(profile).setQuietMode(true);
+ try {
+ roleHolderPackageName = roleHolderApp.packageName();
+ TestApis.devicePolicy().setDevicePolicyManagementRoleHolder(roleHolderPackageName);
+ UserHandle profile = sDevicePolicyManager.createAndProvisionManagedProfile(
+ MANAGED_PROFILE_PROVISIONING_PARAMS);
+ TestApis.users().find(profile).setQuietMode(true);
- TestApis.users().find(profile).setQuietMode(false);
+ TestApis.users().find(profile).setQuietMode(false);
- EventLogsSubject.assertThat(roleHolderApp.events().broadcastReceived()
- .whereIntent().action().isEqualTo(ACTION_MANAGED_PROFILE_AVAILABLE))
- .eventOccurred();
- } finally {
- if (roleHolderPackageName != null) {
- TestApis.devicePolicy().unsetDevicePolicyManagementRoleHolder(
- roleHolderPackageName);
+ EventLogsSubject.assertThat(roleHolderApp.events().broadcastReceived()
+ .whereIntent().action().isEqualTo(ACTION_MANAGED_PROFILE_AVAILABLE))
+ .eventOccurred();
+ } finally {
+ if (roleHolderPackageName != null) {
+ TestApis.devicePolicy().unsetDevicePolicyManagementRoleHolder(
+ roleHolderPackageName);
+ }
}
}
}
diff --git a/tests/filesystem/src/android/filesystem/cts/RandomRWTest.java b/tests/filesystem/src/android/filesystem/cts/RandomRWTest.java
index 5598d3f..66d1e02 100644
--- a/tests/filesystem/src/android/filesystem/cts/RandomRWTest.java
+++ b/tests/filesystem/src/android/filesystem/cts/RandomRWTest.java
@@ -21,6 +21,7 @@
import android.os.Environment;
import android.mediapc.cts.common.Utils;
+import android.mediapc.cts.common.PerformanceClassEvaluator;
import androidx.test.runner.AndroidJUnit4;
@@ -30,7 +31,9 @@
import static org.junit.Assert.assertTrue;
import org.junit.After;
+import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.TestName;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
@@ -38,19 +41,9 @@
private static final String DIR_RANDOM_WR = "RANDOM_WR";
private static final String DIR_RANDOM_RD = "RANDOM_RD";
private static final String REPORT_LOG_NAME = "CtsFileSystemTestCases";
- private static final double MIN_READ_MBPS;
- private static final double MIN_WRITE_MBPS;
- static {
- if (Utils.isRPerfClass()) {
- MIN_READ_MBPS = 25;
- MIN_WRITE_MBPS = 10;
- } else {
- // Performance class Build.VERSION_CODES.S and beyond
- MIN_READ_MBPS = 40;
- MIN_WRITE_MBPS = 10;
- }
- }
+ @Rule
+ public final TestName mTestName = new TestName();
@After
public void tearDown() throws Exception {
@@ -58,7 +51,7 @@
FileUtil.removeFileOrDir(getContext(), DIR_RANDOM_RD);
}
- @CddTest(requirement="8.2")
+ @CddTest(requirements = {"8.2/H-1-4"})
@Test
public void testRandomRead() throws Exception {
final int READ_BUFFER_SIZE = 4 * 1024;
@@ -72,14 +65,18 @@
double mbps = FileUtil.doRandomReadTest(getContext(), DIR_RANDOM_RD, report, fileSize,
READ_BUFFER_SIZE);
report.submit(getInstrumentation());
- if (Utils.isPerfClass()) {
- assertTrue("measured " + mbps + " is less than target (" + MIN_READ_MBPS + " MBPS)",
- mbps >= MIN_READ_MBPS);
- }
+
+ PerformanceClassEvaluator pce = new PerformanceClassEvaluator(this.mTestName);
+ PerformanceClassEvaluator.FileSystemRequirement r8_2__H_1_4 = pce.addR8_2__H_1_4();
+ PerformanceClassEvaluator.FileSystemRequirement r8_2__H_2_4 = pce.addR8_2__H_2_4();
+ r8_2__H_1_4.setFilesystemIoRate(mbps);
+ r8_2__H_2_4.setFilesystemIoRate(mbps);
+
+ pce.submitAndCheck();
}
// It is taking too long in some device, and thus cannot run multiple times
- @CddTest(requirement="8.2")
+ @CddTest(requirements = {"8.2/H-1-2"})
@Test
public void testRandomUpdate() throws Exception {
final int WRITE_BUFFER_SIZE = 4 * 1024;
@@ -98,10 +95,13 @@
WRITE_BUFFER_SIZE);
}
report.submit(getInstrumentation());
- if (Utils.isPerfClass()) {
- // for performance class devices we must be able to write 256MB
- assertTrue("measured " + mbps + " is less than target (" + MIN_WRITE_MBPS + " MBPS)",
- mbps >= MIN_WRITE_MBPS);
- }
+
+ PerformanceClassEvaluator pce = new PerformanceClassEvaluator(this.mTestName);
+ PerformanceClassEvaluator.FileSystemRequirement r8_2__H_1_2 = pce.addR8_2__H_1_2();
+ PerformanceClassEvaluator.FileSystemRequirement r8_2__H_2_2 = pce.addR8_2__H_2_2();
+ r8_2__H_1_2.setFilesystemIoRate(mbps);
+ r8_2__H_2_2.setFilesystemIoRate(mbps);
+
+ pce.submitAndCheck();
}
}
diff --git a/tests/filesystem/src/android/filesystem/cts/SequentialRWTest.java b/tests/filesystem/src/android/filesystem/cts/SequentialRWTest.java
index e535bc9..1beb91a 100644
--- a/tests/filesystem/src/android/filesystem/cts/SequentialRWTest.java
+++ b/tests/filesystem/src/android/filesystem/cts/SequentialRWTest.java
@@ -18,6 +18,7 @@
import android.util.Log;
import android.mediapc.cts.common.Utils;
+import android.mediapc.cts.common.PerformanceClassEvaluator;
import static androidx.test.InstrumentationRegistry.getContext;
import static androidx.test.InstrumentationRegistry.getInstrumentation;
@@ -35,7 +36,9 @@
import static org.junit.Assert.assertTrue;
import org.junit.After;
+import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.TestName;
import org.junit.runner.RunWith;
import java.io.File;
@@ -51,19 +54,9 @@
private static final String DIR_SEQ_RD = "SEQ_RD";
private static final String REPORT_LOG_NAME = "CtsFileSystemTestCases";
private static final int BUFFER_SIZE = 10 * 1024 * 1024;
- private static final double MIN_READ_MBPS;
- private static final double MIN_WRITE_MBPS;
- static {
- if (Utils.isRPerfClass()) {
- MIN_READ_MBPS = 200;
- MIN_WRITE_MBPS = 100;
- } else {
- // Performance class Build.VERSION_CODES.S and beyond
- MIN_READ_MBPS = 250;
- MIN_WRITE_MBPS = 125;
- }
- }
+ @Rule
+ public final TestName mTestName = new TestName();
@After
public void tearDown() throws Exception {
@@ -72,7 +65,7 @@
FileUtil.removeFileOrDir(getContext(), DIR_SEQ_RD);
}
- @CddTest(requirement="8.2")
+ @CddTest(requirements = {"8.2/H-1-1"})
@Test
public void testSingleSequentialWrite() throws Exception {
final long fileSize = FileUtil.getFileSizeExceedingMemory(getContext(), BUFFER_SIZE);
@@ -105,10 +98,13 @@
Log.v(TAG, "sequential write " + stat.mAverage + " MBPS");
report.submit(getInstrumentation());
- if (Utils.isPerfClass()) {
- assertTrue("measured " + stat.mAverage + " is less than target (" + MIN_WRITE_MBPS +
- " MBPS)", stat.mAverage >= MIN_WRITE_MBPS);
- }
+ PerformanceClassEvaluator pce = new PerformanceClassEvaluator(this.mTestName);
+ PerformanceClassEvaluator.FileSystemRequirement r8_2__H_1_1 = pce.addR8_2__H_1_1();
+ PerformanceClassEvaluator.FileSystemRequirement r8_2__H_2_1 = pce.addR8_2__H_2_1();
+ r8_2__H_1_1.setFilesystemIoRate(stat.mAverage);
+ r8_2__H_2_1.setFilesystemIoRate(stat.mAverage);
+
+ pce.submitAndCheck();
}
@Test
@@ -124,7 +120,7 @@
NUMBER_REPETITION, REPORT_LOG_NAME, streamName);
}
- @CddTest(requirement="8.2")
+ @CddTest(requirements = {"8.2/H-1-3"})
@Test
public void testSingleSequentialRead() throws Exception {
final long fileSize = FileUtil.getFileSizeExceedingMemory(getContext(), BUFFER_SIZE);
@@ -167,9 +163,12 @@
Log.v(TAG, "sequential read " + stat.mAverage + " MBPS");
report.submit(getInstrumentation());
- if (Utils.isPerfClass()) {
- assertTrue("measured " + stat.mAverage + " is less than target (" + MIN_READ_MBPS +
- " MBPS)", stat.mAverage >= MIN_READ_MBPS);
- }
+ PerformanceClassEvaluator pce = new PerformanceClassEvaluator(this.mTestName);
+ PerformanceClassEvaluator.FileSystemRequirement r8_2__H_1_3 = pce.addR8_2__H_1_3();
+ PerformanceClassEvaluator.FileSystemRequirement r8_2__H_2_3 = pce.addR8_2__H_2_3();
+ r8_2__H_1_3.setFilesystemIoRate(stat.mAverage);
+ r8_2__H_2_3.setFilesystemIoRate(stat.mAverage);
+
+ pce.submitAndCheck();
}
}
diff --git a/tests/framework/base/biometrics/OWNERS b/tests/framework/base/biometrics/OWNERS
index 95749d0..fbd1d59 100644
--- a/tests/framework/base/biometrics/OWNERS
+++ b/tests/framework/base/biometrics/OWNERS
@@ -5,3 +5,4 @@
jaggies@google.com
jbolinger@google.com
joshmccloskey@google.com
+jeffpu@google.com
diff --git a/tests/framework/base/biometrics/src/android/server/biometrics/BiometricTestBase.java b/tests/framework/base/biometrics/src/android/server/biometrics/BiometricTestBase.java
index 1bb7eea..fa05e86 100644
--- a/tests/framework/base/biometrics/src/android/server/biometrics/BiometricTestBase.java
+++ b/tests/framework/base/biometrics/src/android/server/biometrics/BiometricTestBase.java
@@ -523,6 +523,13 @@
mInstrumentation.waitForIdleSync();
Utils.waitForBusySensor(sensorId, this::getSensorStates);
+ //Wait for enrollment operation in biometrics sensor to be complete before
+ //retrieving enrollment results. The operation takes a little time especically
+ //on Cutterfish where multiple biometric operations must be completed during
+ //the enrollent
+ //TODO(b/217275524)
+ Thread.sleep(200);
+
session.finishEnroll(userId);
mInstrumentation.waitForIdleSync();
Utils.waitForIdleService(this::getSensorStates);
diff --git a/tests/framework/base/windowmanager/jetpack/Android.bp b/tests/framework/base/windowmanager/jetpack/Android.bp
index 5771a28..1ab377f 100644
--- a/tests/framework/base/windowmanager/jetpack/Android.bp
+++ b/tests/framework/base/windowmanager/jetpack/Android.bp
@@ -32,6 +32,21 @@
}
android_library_import {
+ name: "cts_window-extensions-core_nodeps",
+ aars: ["window-extensions-core-release.aar"],
+ sdk_version: "current",
+}
+
+java_library {
+ name: "cts_window-extensions-core",
+ sdk_version: "current",
+ static_libs: [
+ "cts_window-extensions-core_nodeps",
+ ],
+ installable: false,
+}
+
+android_library_import {
name: "cts_window-sidecar_nodeps",
aars: ["window-sidecar-release.aar"],
sdk_version: "current",
@@ -49,11 +64,12 @@
java_library {
name: "cts_window_jetpack_utils",
srcs: [
- "src/android/server/wm/jetpack/utils/**/*.java"
+ "src/android/server/wm/jetpack/utils/**/*.java",
],
static_libs: [
"compatibility-device-util-axt",
"cts_window-extensions",
+ "cts_window-extensions-core",
"cts_window-sidecar",
],
sdk_version: "test_current",
@@ -71,6 +87,7 @@
"platform-test-annotations",
"cts_window-sidecar",
"cts_window-extensions",
+ "cts_window-extensions-core",
],
libs: [
"android.test.base",
diff --git a/tests/framework/base/windowmanager/jetpack/SignedApp/src/android/server/wm/jetpack/signed/SignedEmbeddingActivity.java b/tests/framework/base/windowmanager/jetpack/SignedApp/src/android/server/wm/jetpack/signed/SignedEmbeddingActivity.java
index b332543..66e856d 100644
--- a/tests/framework/base/windowmanager/jetpack/SignedApp/src/android/server/wm/jetpack/signed/SignedEmbeddingActivity.java
+++ b/tests/framework/base/windowmanager/jetpack/SignedApp/src/android/server/wm/jetpack/signed/SignedEmbeddingActivity.java
@@ -18,6 +18,7 @@
import static android.server.wm.jetpack.utils.ActivityEmbeddingUtil.DEFAULT_SPLIT_RATIO;
import static android.server.wm.jetpack.utils.ActivityEmbeddingUtil.EMBEDDED_ACTIVITY_ID;
+import static android.server.wm.jetpack.utils.ActivityEmbeddingUtil.createSplitPairRuleBuilderWithJava8Predicate;
import static android.server.wm.jetpack.utils.ActivityEmbeddingUtil.createWildcardSplitPairRule;
import static android.server.wm.jetpack.utils.ActivityEmbeddingUtil.startActivityCrossUidInSplit;
import static android.server.wm.jetpack.utils.ExtensionUtil.assumeExtensionSupportedDevice;
@@ -85,7 +86,7 @@
TestValueCountConsumer<List<SplitInfo>> splitInfoConsumer = new TestValueCountConsumer<>();
embeddingComponent.setSplitInfoCallback(splitInfoConsumer);
- SplitPairRule splitPairRule = new SplitPairRule.Builder(
+ SplitPairRule splitPairRule = createSplitPairRuleBuilderWithJava8Predicate(
activityActivityPair -> true /* activityActivityPredicate */,
activityIntentPair -> true /* activityIntentPredicate */,
parentWindowMetrics -> true /* parentWindowMetricsPredicate */)
diff --git a/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/ActivityEmbeddingBoundsTests.java b/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/ActivityEmbeddingBoundsTests.java
index 46d3fa8..18fe90e 100644
--- a/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/ActivityEmbeddingBoundsTests.java
+++ b/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/ActivityEmbeddingBoundsTests.java
@@ -19,6 +19,7 @@
import static android.server.wm.jetpack.utils.ActivityEmbeddingUtil.DEFAULT_SPLIT_RATIO;
import static android.server.wm.jetpack.utils.ActivityEmbeddingUtil.UNEVEN_CONTAINERS_DEFAULT_SPLIT_RATIO;
import static android.server.wm.jetpack.utils.ActivityEmbeddingUtil.assertValidSplit;
+import static android.server.wm.jetpack.utils.ActivityEmbeddingUtil.createSplitPairRuleBuilderWithJava8Predicate;
import static android.server.wm.jetpack.utils.ActivityEmbeddingUtil.startActivityAndVerifySplit;
import static android.server.wm.jetpack.utils.ActivityEmbeddingUtil.waitAndAssertNotVisible;
import static android.server.wm.jetpack.utils.ActivityEmbeddingUtil.waitForFillsTask;
@@ -71,7 +72,7 @@
// Set split pair rule such that if the parent width is any smaller than it is now, then
// the parent cannot support a split.
final int originalTaskWidth = getTaskWidth();
- final SplitPairRule splitPairRule = new SplitPairRule.Builder(
+ final SplitPairRule splitPairRule = createSplitPairRuleBuilderWithJava8Predicate(
activityActivityPair -> true /* activityPairPredicate */,
activityIntentPair -> true /* activityIntentPredicate */,
parentWindowMetrics -> parentWindowMetrics.getBounds().width() >= originalTaskWidth)
@@ -173,7 +174,7 @@
final float activityBCSplitRatio = 0.85f;
// Create a split rule for activity A and activity B where the split ratio is 0.37.
- final SplitPairRule splitPairRuleAB = new SplitPairRule.Builder(
+ final SplitPairRule splitPairRuleAB = createSplitPairRuleBuilderWithJava8Predicate(
activityActivityPair -> false /* activityPairPredicate */,
activityIntentPair -> matchesActivityIntentPair(activityIntentPair, activityAId,
activityBId) /* activityIntentPredicate */,
@@ -181,7 +182,7 @@
.setSplitRatio(activityABSplitRatio).build();
// Create a split rule for activity B and activity C where the split ratio is 0.65.
- final SplitPairRule splitPairRuleBC = new SplitPairRule.Builder(
+ final SplitPairRule splitPairRuleBC = createSplitPairRuleBuilderWithJava8Predicate(
activityActivityPair -> false /* activityPairPredicate */,
activityIntentPair -> matchesActivityIntentPair(activityIntentPair, activityBId,
activityCId) /* activityIntentPredicate */,
@@ -209,7 +210,8 @@
}
private SplitPairRule createUnevenWidthSplitPairRule(int layoutDir) {
- return new SplitPairRule.Builder(activityActivityPair -> true /* activityPairPredicate */,
+ return createSplitPairRuleBuilderWithJava8Predicate(
+ activityActivityPair -> true /* activityPairPredicate */,
activityIntentPair -> true /* activityIntentPredicate */,
parentWindowMetrics -> true /* parentWindowMetricsPredicate */)
.setSplitRatio(UNEVEN_CONTAINERS_DEFAULT_SPLIT_RATIO)
diff --git a/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/ExtensionWindowLayoutComponentTest.java b/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/ExtensionWindowLayoutComponentTest.java
index 7162a442..c2752e6 100644
--- a/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/ExtensionWindowLayoutComponentTest.java
+++ b/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/ExtensionWindowLayoutComponentTest.java
@@ -39,10 +39,9 @@
import static org.junit.Assume.assumeNotNull;
import android.graphics.Rect;
-import android.platform.test.annotations.Presubmit;
import android.server.wm.jetpack.utils.TestActivity;
import android.server.wm.jetpack.utils.TestConfigChangeHandlingActivity;
-import android.server.wm.jetpack.utils.TestValueCountConsumer;
+import android.server.wm.jetpack.utils.TestValueCountJavaConsumer;
import android.server.wm.jetpack.utils.WindowManagerJetpackTestBase;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -104,8 +103,8 @@
// Create the callback, onWindowLayoutChanged should only be called twice in this
// test, not the third time when the orientation will change because the listener will be
// removed.
- TestValueCountConsumer<WindowLayoutInfo> windowLayoutInfoConsumer =
- new TestValueCountConsumer<>();
+ TestValueCountJavaConsumer<WindowLayoutInfo> windowLayoutInfoConsumer =
+ new TestValueCountJavaConsumer<>();
windowLayoutInfoConsumer.setCount(2);
// Add window layout listener for mWindowToken - onWindowLayoutChanged should be called
@@ -129,8 +128,8 @@
@Test
public void testWindowLayoutComponent_WindowLayoutInfoListener() {
- TestValueCountConsumer<WindowLayoutInfo> windowLayoutInfoConsumer =
- new TestValueCountConsumer<>();
+ TestValueCountJavaConsumer<WindowLayoutInfo> windowLayoutInfoConsumer =
+ new TestValueCountJavaConsumer<>();
// Test that adding and removing callback succeeds
mWindowLayoutComponent.addWindowLayoutInfoListener(mActivity, windowLayoutInfoConsumer);
mWindowLayoutComponent.removeWindowLayoutInfoListener(windowLayoutInfoConsumer);
diff --git a/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/utils/ActivityEmbeddingUtil.java b/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/utils/ActivityEmbeddingUtil.java
index 477cc8d..aeb1cbf 100644
--- a/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/utils/ActivityEmbeddingUtil.java
+++ b/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/utils/ActivityEmbeddingUtil.java
@@ -43,6 +43,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.window.extensions.core.util.function.Predicate;
import androidx.window.extensions.embedding.ActivityEmbeddingComponent;
import androidx.window.extensions.embedding.SplitInfo;
import androidx.window.extensions.embedding.SplitPairRule;
@@ -54,7 +55,6 @@
import java.util.Collections;
import java.util.List;
import java.util.Objects;
-import java.util.function.Predicate;
/**
* Utility class for activity embedding tests.
@@ -69,18 +69,17 @@
@NonNull
public static SplitPairRule createWildcardSplitPairRule(boolean shouldClearTop) {
- // Any activity be split with any activity
- final Predicate<Pair<Activity, Activity>> activityPairPredicate =
- activityActivityPair -> true;
- // Any activity can launch any split intent
- final Predicate<Pair<Activity, Intent>> activityIntentPredicate =
- activityIntentPair -> true;
- // Allow any parent bounds to show the split containers side by side
- Predicate<WindowMetrics> parentWindowMetricsPredicate = windowMetrics -> true;
// Build the split pair rule
- return new SplitPairRule.Builder(activityPairPredicate,
- activityIntentPredicate, parentWindowMetricsPredicate).setSplitRatio(
- DEFAULT_SPLIT_RATIO).setShouldClearTop(shouldClearTop).build();
+ return createSplitPairRuleBuilderWithJava8Predicate(
+ // Any activity be split with any activity
+ activityActivityPair -> true,
+ // Any activity can launch any split intent
+ activityIntentPair -> true,
+ // Allow any parent bounds to show the split containers side by side
+ windowMetrics -> true)
+ .setSplitRatio(DEFAULT_SPLIT_RATIO)
+ .setShouldClearTop(shouldClearTop)
+ .build();
}
@NonNull
@@ -93,18 +92,16 @@
@NonNull
public static SplitPairRule.Builder createWildcardSplitPairRuleBuilderWithPrimaryActivityClass(
Class<? extends Activity> activityClass, boolean shouldClearTop) {
- // The specified activity be split any activity
- final Predicate<Pair<Activity, Activity>> activityPairPredicate =
- activityActivityPair -> activityActivityPair.first.getClass().equals(activityClass);
- // The specified activity can launch any split intent
- final Predicate<Pair<Activity, Intent>> activityIntentPredicate =
- activityIntentPair -> activityIntentPair.first.getClass().equals(activityClass);
- // Allow any parent bounds to show the split containers side by side
- Predicate<WindowMetrics> parentWindowMetricsPredicate = windowMetrics -> true;
// Build the split pair rule
- return new SplitPairRule.Builder(activityPairPredicate,
- activityIntentPredicate, parentWindowMetricsPredicate).setSplitRatio(
- DEFAULT_SPLIT_RATIO).setShouldClearTop(shouldClearTop);
+ return createSplitPairRuleBuilderWithJava8Predicate(
+ // The specified activity be split any activity
+ activityActivityPair -> activityActivityPair.first.getClass().equals(activityClass),
+ // The specified activity can launch any split intent
+ activityIntentPair -> activityIntentPair.first.getClass().equals(activityClass),
+ // Allow any parent bounds to show the split containers side by side
+ windowMetrics -> true)
+ .setSplitRatio(DEFAULT_SPLIT_RATIO)
+ .setShouldClearTop(shouldClearTop);
}
@NonNull
@@ -112,6 +109,24 @@
return createWildcardSplitPairRule(false /* shouldClearTop */);
}
+ /**
+ * A wrapper to create {@link SplitPairRule} builder with Java 8 Predicate to prevent ambiguous
+ * issue when using lambda expressions.
+ * <p>
+ * It should only be used if
+ * {@link #createSplitPairRuleBuilder(Predicate, Predicate, Predicate)} cannot be called prior
+ * to {@link ExtensionUtil#EXTENSION_VERSION_2}.
+ */
+ @NonNull
+ public static SplitPairRule.Builder createSplitPairRuleBuilderWithJava8Predicate(
+ @NonNull java.util.function.Predicate<Pair<Activity, Activity>> activitiesPairPredicate,
+ @NonNull java.util.function.Predicate<Pair<Activity, Intent>>
+ activityIntentPairPredicate,
+ @NonNull java.util.function.Predicate<WindowMetrics> windowMetricsPredicate) {
+ return new SplitPairRule.Builder(activitiesPairPredicate, activityIntentPairPredicate,
+ windowMetricsPredicate);
+ }
+
public static TestActivity startActivityAndVerifyNotSplit(
@NonNull Activity activityLaunchingFrom) {
final String secondActivityId = "secondActivityId";
diff --git a/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/utils/ExtensionUtil.java b/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/utils/ExtensionUtil.java
index a3e682b..f7b352f 100644
--- a/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/utils/ExtensionUtil.java
+++ b/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/utils/ExtensionUtil.java
@@ -114,8 +114,8 @@
if (windowLayoutComponent == null) {
return null;
}
- TestValueCountConsumer<WindowLayoutInfo> windowLayoutInfoConsumer =
- new TestValueCountConsumer<>();
+ TestValueCountJavaConsumer<WindowLayoutInfo> windowLayoutInfoConsumer =
+ new TestValueCountJavaConsumer<>();
windowLayoutComponent.addWindowLayoutInfoListener(activity, windowLayoutInfoConsumer);
return windowLayoutInfoConsumer.waitAndGet();
}
diff --git a/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/utils/TestValueCountConsumer.java b/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/utils/TestValueCountConsumer.java
index 4ebeac4..10fe6fc 100644
--- a/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/utils/TestValueCountConsumer.java
+++ b/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/utils/TestValueCountConsumer.java
@@ -17,14 +17,18 @@
package android.server.wm.jetpack.utils;
import androidx.annotation.Nullable;
+import androidx.window.extensions.core.util.function.Consumer;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
-import java.util.function.Consumer;
/**
* Consumer that provides a simple way to wait for a specific count of values to be received within
* a timeout and then return the last value.
+ *
+ * It requires the vendor API version at least {@link ExtensionUtil#EXTENSION_VERSION_2} because
+ * it uses extensions core version of {@link Consumer} instead of
+ * {@link java.util.function.Consumer Java 8 version Consumer}.
*/
public class TestValueCountConsumer<T> implements Consumer<T> {
diff --git a/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/utils/TestValueCountJavaConsumer.java b/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/utils/TestValueCountJavaConsumer.java
new file mode 100644
index 0000000..19776cb
--- /dev/null
+++ b/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/utils/TestValueCountJavaConsumer.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.server.wm.jetpack.utils;
+
+import androidx.annotation.Nullable;
+
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
+
+/**
+ * Consumer that provides a simple way to wait for a specific count of values to be received within
+ * a timeout and then return the last value.
+ * <p>
+ * Note that this class should only be used if {@link TestValueCountConsumer} can not be used prior
+ * to {@link ExtensionUtil#EXTENSION_VERSION_2}.
+ */
+public class TestValueCountJavaConsumer<T> implements Consumer<T> {
+
+ private static final long TIMEOUT_MS = 3000;
+ private static final int DEFAULT_COUNT = 1;
+ private int mCount = DEFAULT_COUNT;
+ private LinkedBlockingQueue<T> mLinkedBlockingQueue;
+ private T mLastReportedValue;
+
+ public TestValueCountJavaConsumer() {
+ mLinkedBlockingQueue = new LinkedBlockingQueue<>();
+ }
+
+ @Override
+ public void accept(T value) {
+ // Asynchronously offer value to queue
+ mLinkedBlockingQueue.offer(value);
+ }
+
+ public void setCount(int count) {
+ mCount = count;
+ }
+
+ @Nullable
+ public T waitAndGet() throws InterruptedException {
+ T value = null;
+ for (int i = 0; i < mCount; i++) {
+ value = mLinkedBlockingQueue.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS);
+ }
+ mLastReportedValue = value;
+ return value;
+ }
+
+ // Doesn't change the count.
+ public void clearQueue() {
+ mLinkedBlockingQueue.clear();
+ }
+
+ @Nullable
+ public T getLastReportedValue() {
+ return mLastReportedValue;
+ }
+}
diff --git a/tests/framework/base/windowmanager/jetpack/window-extensions-core-release.aar b/tests/framework/base/windowmanager/jetpack/window-extensions-core-release.aar
new file mode 100644
index 0000000..96ff840
--- /dev/null
+++ b/tests/framework/base/windowmanager/jetpack/window-extensions-core-release.aar
Binary files differ
diff --git a/tests/framework/base/windowmanager/jetpack/window-extensions-release.aar b/tests/framework/base/windowmanager/jetpack/window-extensions-release.aar
index 6fc9a67..367e3b9 100644
--- a/tests/framework/base/windowmanager/jetpack/window-extensions-release.aar
+++ b/tests/framework/base/windowmanager/jetpack/window-extensions-release.aar
Binary files differ
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/AspectRatioTests.java b/tests/framework/base/windowmanager/src/android/server/wm/AspectRatioTests.java
index 38b3ed7..a8e8c07 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/AspectRatioTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/AspectRatioTests.java
@@ -16,6 +16,7 @@
package android.server.wm;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.server.wm.app.Components.MAX_ASPECT_RATIO_ACTIVITY;
import static android.server.wm.app.Components.MAX_ASPECT_RATIO_RESIZABLE_ACTIVITY;
import static android.server.wm.app.Components.MAX_ASPECT_RATIO_UNSET_ACTIVITY;
@@ -52,7 +53,7 @@
@Test
public void testMaxAspectRatio() {
// Activity has a maxAspectRatio, assert that the actual ratio is less than that.
- runAspectRatioTest(MAX_ASPECT_RATIO_ACTIVITY,
+ runAspectRatioTest(MAX_ASPECT_RATIO_ACTIVITY, WINDOWING_MODE_FULLSCREEN,
(actual, displayId, activitySize, displaySize) -> {
assertThat(actual, lessThanOrEqualTo(MAX_ASPECT_RATIO));
});
@@ -61,7 +62,7 @@
@Test
public void testMetaDataMaxAspectRatio() {
// Activity has a maxAspectRatio, assert that the actual ratio is less than that.
- runAspectRatioTest(META_DATA_MAX_ASPECT_RATIO_ACTIVITY,
+ runAspectRatioTest(META_DATA_MAX_ASPECT_RATIO_ACTIVITY, WINDOWING_MODE_FULLSCREEN,
(actual, displayId, activitySize, displaySize) -> {
assertThat(actual, lessThanOrEqualTo(MAX_ASPECT_RATIO));
});
@@ -70,7 +71,7 @@
@Test
public void testMaxAspectRatioResizeableActivity() {
// Since this activity is resizeable, its max aspect ratio should be ignored.
- runAspectRatioTest(MAX_ASPECT_RATIO_RESIZABLE_ACTIVITY,
+ runAspectRatioTest(MAX_ASPECT_RATIO_RESIZABLE_ACTIVITY, WINDOWING_MODE_FULLSCREEN,
(actual, displayId, activitySize, displaySize) -> {
// TODO(b/69982434): Add ability to get native aspect ratio non-default display.
assumeThat(displayId, is(Display.DEFAULT_DISPLAY));
@@ -85,7 +86,7 @@
public void testMaxAspectRatioUnsetActivity() {
// Since this activity didn't set an explicit maxAspectRatio, there should be no such
// ratio enforced.
- runAspectRatioTest(MAX_ASPECT_RATIO_UNSET_ACTIVITY,
+ runAspectRatioTest(MAX_ASPECT_RATIO_UNSET_ACTIVITY, WINDOWING_MODE_FULLSCREEN,
(actual, displayId, activitySize, displaySize) -> {
// TODO(b/69982434): Add ability to get native aspect ratio non-default display.
assumeThat(displayId, is(Display.DEFAULT_DISPLAY));
@@ -98,7 +99,7 @@
@Test
public void testMinAspectRatio() {
// Activity has a minAspectRatio, assert the ratio is at least that.
- runAspectRatioTest(MIN_ASPECT_RATIO_ACTIVITY,
+ runAspectRatioTest(MIN_ASPECT_RATIO_ACTIVITY, WINDOWING_MODE_FULLSCREEN,
(actual, displayId, activitySize, displaySize) -> {
assertThat(actual, greaterThanOrEqualToInexact(MIN_ASPECT_RATIO));
});
@@ -108,7 +109,7 @@
public void testMinAspectRatioUnsetActivity() {
// Since this activity didn't set an explicit minAspectRatio, there should be no such
// ratio enforced.
- runAspectRatioTest(MIN_ASPECT_RATIO_UNSET_ACTIVITY,
+ runAspectRatioTest(MIN_ASPECT_RATIO_UNSET_ACTIVITY, WINDOWING_MODE_FULLSCREEN,
(actual, displayId, activitySize, displaySize) -> {
// TODO(b/69982434): Add ability to get native aspect ratio non-default display.
assumeThat(displayId, is(Display.DEFAULT_DISPLAY));
@@ -121,7 +122,7 @@
@Test
public void testMinAspectLandscapeActivity() {
// Activity has requested a fixed orientation, assert the orientation is that.
- runAspectRatioTest(MIN_ASPECT_RATIO_LANDSCAPE_ACTIVITY,
+ runAspectRatioTest(MIN_ASPECT_RATIO_LANDSCAPE_ACTIVITY, WINDOWING_MODE_FULLSCREEN,
(actual, displayId, activitySize, displaySize) -> {
assertThat(activitySize.x, greaterThan(activitySize.y));
// Since activities must fit within the bounds of the display and they should respect
@@ -140,7 +141,7 @@
@Test
public void testMinAspectPortraitActivity() {
- runAspectRatioTest(MIN_ASPECT_RATIO_PORTRAIT_ACTIVITY,
+ runAspectRatioTest(MIN_ASPECT_RATIO_PORTRAIT_ACTIVITY, WINDOWING_MODE_FULLSCREEN,
(actual, displayId, activitySize, displaySize) -> {
assertThat(activitySize.y, greaterThan(activitySize.x));
// Since activities must fit within the bounds of the display and they should respect
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/AspectRatioTestsBase.java b/tests/framework/base/windowmanager/src/android/server/wm/AspectRatioTestsBase.java
index 459ff76..117a26d 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/AspectRatioTestsBase.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/AspectRatioTestsBase.java
@@ -45,9 +45,9 @@
void assertAspectRatio(float actual, int displayId, Point activitySize, Point displaySize);
}
- void runAspectRatioTest(final ComponentName componentName,
+ void runAspectRatioTest(final ComponentName componentName, int windowingMode,
final AssertAspectRatioCallback callback) {
- launchActivity(componentName);
+ launchActivity(componentName, windowingMode);
mWmState.computeState();
final int displayId = mWmState.getDisplayByActivity(componentName);
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/DisplayAreaPolicyTests.java b/tests/framework/base/windowmanager/src/android/server/wm/DisplayAreaPolicyTests.java
index 7dd3d2b..8101a41 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/DisplayAreaPolicyTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/DisplayAreaPolicyTests.java
@@ -58,16 +58,12 @@
}
/**
- * DisplayContent should have feature id of FEATURE_ROOT. It should be organized.
+ * DisplayContent should have feature id of FEATURE_ROOT.
*/
@Test
public void testDisplayContent() {
for (DisplayContent displayContent : mDisplays) {
assertThat(displayContent.getFeatureId()).isEqualTo(FEATURE_ROOT);
- // DisplayAreaOrganizerController registers the organizer for the trusted displays only.
- if (isTrustedDisplay(displayContent)) {
- assertThat(displayContent.isOrganized()).isTrue();
- }
}
}
diff --git a/tests/inputmethod/src/android/view/inputmethod/cts/ImeInsetsControllerTest.java b/tests/inputmethod/src/android/view/inputmethod/cts/ImeInsetsControllerTest.java
index 95eaa02..0fa0307 100644
--- a/tests/inputmethod/src/android/view/inputmethod/cts/ImeInsetsControllerTest.java
+++ b/tests/inputmethod/src/android/view/inputmethod/cts/ImeInsetsControllerTest.java
@@ -164,8 +164,8 @@
CountDownLatch insetsLatch = new CountDownLatch(1);
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
editText.setOnApplyWindowInsetsListener((v, insets) -> {
- insetsLatch.countDown();
lastInsets[0] = insets;
+ insetsLatch.countDown();
return CONSUMED;
});
animController[0].finish(true);
diff --git a/tests/inputmethod/src/android/view/inputmethod/cts/KeyboardVisibilityControlTest.java b/tests/inputmethod/src/android/view/inputmethod/cts/KeyboardVisibilityControlTest.java
index 2e2516a..10d5bda 100644
--- a/tests/inputmethod/src/android/view/inputmethod/cts/KeyboardVisibilityControlTest.java
+++ b/tests/inputmethod/src/android/view/inputmethod/cts/KeyboardVisibilityControlTest.java
@@ -835,7 +835,8 @@
final ImeEventStream stream = imeSession.openEventStream();
final String marker = getTestMarker();
final AtomicReference<EditText> editorRef = new AtomicReference<>();
- TestActivity.startSync(activity -> {
+ new TestActivity.Starter().withWindowingMode(
+ WINDOWING_MODE_FULLSCREEN).startSync(activity -> {
final LinearLayout layout = new LinearLayout(activity);
layout.setOrientation(LinearLayout.VERTICAL);
layout.setGravity(Gravity.BOTTOM);
diff --git a/tests/location/location_fine/src/android/location/cts/fine/LocationManagerFineTest.java b/tests/location/location_fine/src/android/location/cts/fine/LocationManagerFineTest.java
index b741a2e..bc2a2a8 100644
--- a/tests/location/location_fine/src/android/location/cts/fine/LocationManagerFineTest.java
+++ b/tests/location/location_fine/src/android/location/cts/fine/LocationManagerFineTest.java
@@ -22,6 +22,7 @@
import static android.app.AppOpsManager.OPSTR_MONITOR_LOCATION;
import static android.content.pm.PackageManager.FEATURE_AUTOMOTIVE;
import static android.content.pm.PackageManager.FEATURE_TELEVISION;
+import static android.content.pm.PackageManager.FEATURE_WATCH;
import static android.location.LocationManager.EXTRA_PROVIDER_ENABLED;
import static android.location.LocationManager.EXTRA_PROVIDER_NAME;
import static android.location.LocationManager.FUSED_PROVIDER;
@@ -754,10 +755,12 @@
}
@Test
+ @AppModeFull(reason = "Instant apps can't access ACTION_BATTERY_CHANGED intent")
public void testRequestLocationUpdates_BatterySaver_GpsDisabledScreenOff() throws Exception {
- // battery saver is unsupported on auto and tv
+ // battery saver is unsupported on auto, tv and watch
assumeFalse(mContext.getPackageManager().hasSystemFeature(FEATURE_AUTOMOTIVE));
assumeFalse(mContext.getPackageManager().hasSystemFeature(FEATURE_TELEVISION));
+ assumeFalse(mContext.getPackageManager().hasSystemFeature(FEATURE_WATCH));
assumeTrue(BatteryUtils.isBatterySaverSupported());
PowerManager powerManager = Objects.requireNonNull(
@@ -816,10 +819,12 @@
}
@Test
+ @AppModeFull(reason = "Instant apps can't access ACTION_BATTERY_CHANGED intent")
public void testRequestLocationUpdates_BatterySaver_AllDisabledScreenOff() throws Exception {
- // battery saver is unsupported on auto and tv
+ // battery saver is unsupported on auto, tv and watch
assumeFalse(mContext.getPackageManager().hasSystemFeature(FEATURE_AUTOMOTIVE));
assumeFalse(mContext.getPackageManager().hasSystemFeature(FEATURE_TELEVISION));
+ assumeFalse(mContext.getPackageManager().hasSystemFeature(FEATURE_WATCH));
assumeTrue(BatteryUtils.isBatterySaverSupported());
PowerManager powerManager = Objects.requireNonNull(
@@ -859,10 +864,12 @@
}
@Test
+ @AppModeFull(reason = "Instant apps can't access ACTION_BATTERY_CHANGED intent")
public void testRequestLocationUpdates_BatterySaver_ThrottleScreenOff() throws Exception {
- // battery saver is unsupported on auto and tv
+ // battery saver is unsupported on auto, tv and watch
assumeFalse(mContext.getPackageManager().hasSystemFeature(FEATURE_AUTOMOTIVE));
assumeFalse(mContext.getPackageManager().hasSystemFeature(FEATURE_TELEVISION));
+ assumeFalse(mContext.getPackageManager().hasSystemFeature(FEATURE_WATCH));
assumeTrue(BatteryUtils.isBatterySaverSupported());
PowerManager powerManager = Objects.requireNonNull(
diff --git a/tests/mediapc/AndroidTest.xml b/tests/mediapc/AndroidTest.xml
index f4632df..cd882f8 100644
--- a/tests/mediapc/AndroidTest.xml
+++ b/tests/mediapc/AndroidTest.xml
@@ -31,7 +31,7 @@
</target_preparer>
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.MediaPreparer">
<option name="push-all" value="true" />
- <option name="media-folder-name" value="CtsMediaPerformanceClassTestCases-1.3" />
+ <option name="media-folder-name" value="CtsMediaPerformanceClassTestCases-1.4" />
<option name="dynamic-config-module" value="CtsMediaPerformanceClassTestCases" />
</target_preparer>
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
diff --git a/tests/mediapc/DynamicConfig.xml b/tests/mediapc/DynamicConfig.xml
index 739fb52..c1564ba 100644
--- a/tests/mediapc/DynamicConfig.xml
+++ b/tests/mediapc/DynamicConfig.xml
@@ -1,6 +1,6 @@
<dynamicConfig>
<entry key="media_files_url">
- <value>https://storage.googleapis.com/android_media/cts/tests/mediapc/CtsMediaPerformanceClassTestCases-1.3.zip</value>
+ <value>https://storage.googleapis.com/android_media/cts/tests/mediapc/CtsMediaPerformanceClassTestCases-1.4.zip</value>
</entry>
</dynamicConfig>
diff --git a/tests/mediapc/README.md b/tests/mediapc/README.md
index eedb9bc..fdf445e 100644
--- a/tests/mediapc/README.md
+++ b/tests/mediapc/README.md
@@ -1,7 +1,7 @@
## Media Performance Class CTS Tests
Current folder comprises of files necessary for testing media performance class.
-The test vectors used by the test suite is available at [link](https://storage.googleapis.com/android_media/cts/tests/mediapc/CtsMediaPerformanceClassTestCases-1.3.zip) and is downloaded automatically while running tests. Manual installation of these can be done using copy_media.sh script in this directory.
+The test vectors used by the test suite is available at [link](https://storage.googleapis.com/android_media/cts/tests/mediapc/CtsMediaPerformanceClassTestCases-1.4.zip) and is downloaded automatically while running tests. Manual installation of these can be done using copy_media.sh script in this directory.
### Commands
#### To run all tests in CtsMediaPerformanceClassTestCases
diff --git a/tests/mediapc/common/Android.bp b/tests/mediapc/common/Android.bp
index 663dabc..02fd714 100644
--- a/tests/mediapc/common/Android.bp
+++ b/tests/mediapc/common/Android.bp
@@ -25,7 +25,8 @@
"compatibility-device-util-axt",
"android.test.base",
"auto_value_annotations",
- "guava"
+ "guava",
+ "cts-verifier-framework",
],
plugins: ["auto_value_plugin"],
}
@@ -35,7 +36,7 @@
compile_multilib: "both",
static_libs: [
"compatibility-device-util-axt",
- "MediaPerformanceClassCommon"
+ "MediaPerformanceClassCommon",
],
platform_apis: true,
srcs: ["tests/src/**/*.java"],
diff --git a/tests/mediapc/common/src/android/mediapc/cts/common/PerformanceClassEvaluator.java b/tests/mediapc/common/src/android/mediapc/cts/common/PerformanceClassEvaluator.java
index 6cda76b..1e803c2 100644
--- a/tests/mediapc/common/src/android/mediapc/cts/common/PerformanceClassEvaluator.java
+++ b/tests/mediapc/common/src/android/mediapc/cts/common/PerformanceClassEvaluator.java
@@ -23,6 +23,12 @@
import android.hardware.camera2.CameraMetadata;
import android.media.MediaFormat;
import android.os.Build;
+import android.util.Log;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.compatibility.common.util.DeviceReportLog;
+import com.android.cts.verifier.CtsVerifierReportLog;
import com.google.common.base.Preconditions;
@@ -202,6 +208,131 @@
}
}
+ // used for requirements [8.2/H-1-1], [8.2/H-1-2], [8.2/H-1-3], [8.2/H-1-4]
+ public static class FileSystemRequirement extends Requirement {
+
+ private static final String TAG = FileSystemRequirement.class.getSimpleName();
+
+ private FileSystemRequirement(String id, RequiredMeasurement<?>... reqs) {
+ super(id, reqs);
+ }
+ /**
+ * Set the Filesystem I/O Rate in MB/s.
+ */
+ public void setFilesystemIoRate(double filesystemIoRate) {
+ this.setMeasuredValue(RequirementConstants.FILESYSTEM_IO_RATE, filesystemIoRate);
+ }
+
+ /**
+ * [8.2/H-1-1] MUST ensure a sequential write performance of at least 100(R) / 125(S &
+ * above) MB/s.
+ */
+ public static FileSystemRequirement createR8_2__H_1_1() {
+ RequiredMeasurement<Double> filesystem_io_rate = RequiredMeasurement
+ .<Double>builder().setId(RequirementConstants.FILESYSTEM_IO_RATE)
+ .setPredicate(RequirementConstants.DOUBLE_GTE)
+ .addRequiredValue(Build.VERSION_CODES.R, 100.0)
+ .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 125.0)
+ .build();
+
+ return new FileSystemRequirement(RequirementConstants.R8_2__H_1_1, filesystem_io_rate);
+ }
+
+ /**
+ * [8.2/H-2-1] MUST ensure a sequential write performance of at least 125 MB/s.
+ */
+ public static FileSystemRequirement createR8_2__H_2_1() {
+ RequiredMeasurement<Double> filesystem_io_rate = RequiredMeasurement
+ .<Double>builder().setId(RequirementConstants.FILESYSTEM_IO_RATE)
+ .setPredicate(RequirementConstants.DOUBLE_GTE)
+ .addRequiredValue(Build.VERSION_CODES.S, 125.0)
+ .build();
+
+ return new FileSystemRequirement(RequirementConstants.R8_2__H_2_1, filesystem_io_rate);
+ }
+
+ /**
+ * [8.2/H-1-2] MUST ensure a random write performance of at least 10 MB/s
+ */
+ public static FileSystemRequirement createR8_2__H_1_2() {
+ RequiredMeasurement<Double> filesystem_io_rate = RequiredMeasurement
+ .<Double>builder().setId(RequirementConstants.FILESYSTEM_IO_RATE)
+ .setPredicate(RequirementConstants.DOUBLE_GTE)
+ .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 10.0)
+ .build();
+
+ return new FileSystemRequirement(RequirementConstants.R8_2__H_1_2, filesystem_io_rate);
+ }
+
+ /**
+ * [8.2/H-2-2] MUST ensure a random write performance of at least 10 MB/s.
+ */
+ public static FileSystemRequirement createR8_2__H_2_2() {
+ RequiredMeasurement<Double> filesystem_io_rate = RequiredMeasurement
+ .<Double>builder().setId(RequirementConstants.FILESYSTEM_IO_RATE)
+ .setPredicate(RequirementConstants.DOUBLE_GTE)
+ .addRequiredValue(Build.VERSION_CODES.S, 10.0)
+ .build();
+
+ return new FileSystemRequirement(RequirementConstants.R8_2__H_2_2, filesystem_io_rate);
+ }
+
+ /**
+ * [8.2/H-1-3] MUST ensure a sequential read performance of at least 200(R) / 250(S &
+ * above) MB/s.
+ */
+ public static FileSystemRequirement createR8_2__H_1_3() {
+ RequiredMeasurement<Double> filesystem_io_rate = RequiredMeasurement
+ .<Double>builder().setId(RequirementConstants.FILESYSTEM_IO_RATE)
+ .setPredicate(RequirementConstants.DOUBLE_GTE)
+ .addRequiredValue(Build.VERSION_CODES.R, 200.0)
+ .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 250.0)
+ .build();
+
+ return new FileSystemRequirement(RequirementConstants.R8_2__H_1_3, filesystem_io_rate);
+ }
+
+ /**
+ * [8.2/H-2-3] MUST ensure a sequential read performance of at least 250 MB/s.
+ */
+ public static FileSystemRequirement createR8_2__H_2_3() {
+ RequiredMeasurement<Double> filesystem_io_rate = RequiredMeasurement
+ .<Double>builder().setId(RequirementConstants.FILESYSTEM_IO_RATE)
+ .setPredicate(RequirementConstants.DOUBLE_GTE)
+ .addRequiredValue(Build.VERSION_CODES.S, 250.0)
+ .build();
+
+ return new FileSystemRequirement(RequirementConstants.R8_2__H_2_3, filesystem_io_rate);
+ }
+
+ /**
+ * [8.2/H-1-4] MUST ensure a random read performance of at least 25(R) / 40(S & above) MB/s.
+ */
+ public static FileSystemRequirement createR8_2__H_1_4() {
+ RequiredMeasurement<Double> filesystem_io_rate = RequiredMeasurement
+ .<Double>builder().setId(RequirementConstants.FILESYSTEM_IO_RATE)
+ .setPredicate(RequirementConstants.DOUBLE_GTE)
+ .addRequiredValue(Build.VERSION_CODES.R, 25.0)
+ .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 40.0)
+ .build();
+
+ return new FileSystemRequirement(RequirementConstants.R8_2__H_1_4, filesystem_io_rate);
+ }
+
+ /**
+ * [8.2/H-2-4] MUST ensure a random read performance of at least 40 MB/s.
+ */
+ public static FileSystemRequirement createR8_2__H_2_4() {
+ RequiredMeasurement<Double> filesystem_io_rate = RequiredMeasurement
+ .<Double>builder().setId(RequirementConstants.FILESYSTEM_IO_RATE)
+ .setPredicate(RequirementConstants.DOUBLE_GTE)
+ .addRequiredValue(Build.VERSION_CODES.S, 40.0)
+ .build();
+
+ return new FileSystemRequirement(RequirementConstants.R8_2__H_2_4, filesystem_io_rate);
+ }
+ }
+
public static class CodecInitLatencyRequirement extends Requirement {
private static final String TAG = CodecInitLatencyRequirement.class.getSimpleName();
@@ -550,6 +681,42 @@
}
/**
+ * Helper method used to create ConcurrentCodecRequirements, builds and fills out the
+ * a requirement for tests ran with a resolution of 720p
+ */
+ private static ConcurrentCodecRequirement create720p(String requirementId,
+ RequiredMeasurement<?> measure) {
+ RequiredMeasurement<Integer> testResolution = RequiredMeasurement.<Integer>builder()
+ .setId(RequirementConstants.TEST_RESOLUTION)
+ .setPredicate(RequirementConstants.INTEGER_EQ)
+ .addRequiredValue(Build.VERSION_CODES.R, 720)
+ .build();
+
+ ConcurrentCodecRequirement req = new ConcurrentCodecRequirement(requirementId, measure,
+ testResolution);
+ req.setMeasuredValue(RequirementConstants.TEST_RESOLUTION, 720);
+ return req;
+ }
+
+ /**
+ * Helper method used to create ConcurrentCodecRequirements, builds and fills out the
+ * a requirement for tests ran with a resolution of 1080p
+ */
+ private static ConcurrentCodecRequirement create1080p(String requirementId,
+ RequiredMeasurement<?> measure) {
+ RequiredMeasurement<Integer> testResolution = RequiredMeasurement.<Integer>builder()
+ .setId(RequirementConstants.TEST_RESOLUTION)
+ .setPredicate(RequirementConstants.INTEGER_EQ)
+ .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 1080)
+ .build();
+
+ ConcurrentCodecRequirement req = new ConcurrentCodecRequirement(requirementId, measure,
+ testResolution);
+ req.setMeasuredValue(RequirementConstants.TEST_RESOLUTION, 1080);
+ return req;
+ }
+
+ /**
* [2.2.7.1/5.1/H-1-1] MUST advertise the maximum number of hardware video decoder
* sessions that can be run concurrently in any codec combination via the
* CodecCapabilities.getMaxSupportedInstances() and VideoCapabilities
@@ -568,7 +735,7 @@
resolution))
.build();
- return new ConcurrentCodecRequirement(RequirementConstants.R5_1__H_1_1, maxInstances);
+ return create720p(RequirementConstants.R5_1__H_1_1, maxInstances);
}
/**
@@ -584,7 +751,7 @@
.addRequiredValue(Build.VERSION_CODES.TIRAMISU, 6)
.build();
- return new ConcurrentCodecRequirement(RequirementConstants.R5_1__H_1_1, maxInstances);
+ return create1080p(RequirementConstants.R5_1__H_1_1, maxInstances);
}
/**
@@ -603,8 +770,7 @@
getReqMinConcurrentFps(Build.VERSION_CODES.S, mimeType1, mimeType2, resolution))
.build();
- return new ConcurrentCodecRequirement(RequirementConstants.R5_1__H_1_2,
- reqConcurrentFps);
+ return create720p(RequirementConstants.R5_1__H_1_2, reqConcurrentFps);
}
/**
@@ -619,8 +785,7 @@
.addRequiredValue(Build.VERSION_CODES.TIRAMISU, 6 * FPS_30_TOLERANCE)
.build();
- return new ConcurrentCodecRequirement(RequirementConstants.R5_1__H_1_2,
- reqConcurrentFps);
+ return create1080p(RequirementConstants.R5_1__H_1_2, reqConcurrentFps);
}
/**
@@ -642,7 +807,7 @@
resolution))
.build();
- return new ConcurrentCodecRequirement(RequirementConstants.R5_1__H_1_3, maxInstances);
+ return create720p(RequirementConstants.R5_1__H_1_3, maxInstances);
}
/**
@@ -658,7 +823,7 @@
.addRequiredValue(Build.VERSION_CODES.TIRAMISU, 6)
.build();
- return new ConcurrentCodecRequirement(RequirementConstants.R5_1__H_1_3, maxInstances);
+ return create1080p(RequirementConstants.R5_1__H_1_3, maxInstances);
}
/**
@@ -675,8 +840,7 @@
.addRequiredValue(Build.VERSION_CODES.S, 0.0)
.build();
- return new ConcurrentCodecRequirement(RequirementConstants.R5_1__H_1_4,
- reqConcurrentFps);
+ return create720p(RequirementConstants.R5_1__H_1_4, reqConcurrentFps);
}
/**
@@ -692,8 +856,7 @@
.addRequiredValue(Build.VERSION_CODES.TIRAMISU, 0.0)
.build();
- return new ConcurrentCodecRequirement(RequirementConstants.R5_1__H_1_4,
- reqConcurrentFps);
+ return create1080p(RequirementConstants.R5_1__H_1_4, reqConcurrentFps);
}
/**
@@ -715,7 +878,7 @@
resolution))
.build();
- return new ConcurrentCodecRequirement(RequirementConstants.R5_1__H_1_5, maxInstances);
+ return create720p(RequirementConstants.R5_1__H_1_5, maxInstances);
}
/**
@@ -731,7 +894,7 @@
.addRequiredValue(Build.VERSION_CODES.TIRAMISU, 6)
.build();
- return new ConcurrentCodecRequirement(RequirementConstants.R5_1__H_1_5, maxInstances);
+ return create1080p(RequirementConstants.R5_1__H_1_5, maxInstances);
}
/**
@@ -753,8 +916,7 @@
/ 2)
.build();
- return new ConcurrentCodecRequirement(RequirementConstants.R5_1__H_1_6,
- reqConcurrentFps);
+ return create720p(RequirementConstants.R5_1__H_1_6, reqConcurrentFps);
}
/**
@@ -770,8 +932,7 @@
.addRequiredValue(Build.VERSION_CODES.TIRAMISU, 6 * FPS_30_TOLERANCE / 2)
.build();
- return new ConcurrentCodecRequirement(RequirementConstants.R5_1__H_1_6,
- reqConcurrentFps);
+ return create1080p(RequirementConstants.R5_1__H_1_6, reqConcurrentFps);
}
/**
@@ -786,8 +947,7 @@
.addRequiredValue(Build.VERSION_CODES.TIRAMISU, 2 * FPS_30_TOLERANCE)
.build();
- return new ConcurrentCodecRequirement(RequirementConstants.R5_1__H_1_9,
- reqConcurrentFps);
+ return create1080p(RequirementConstants.R5_1__H_1_9, reqConcurrentFps);
}
/**
@@ -803,8 +963,7 @@
.addRequiredValue(Build.VERSION_CODES.TIRAMISU, 4 * FPS_30_TOLERANCE)
.build();
- return new ConcurrentCodecRequirement(RequirementConstants.R5_1__H_1_10,
- reqConcurrentFps);
+ return create1080p(RequirementConstants.R5_1__H_1_10, reqConcurrentFps);
}
}
@@ -1341,6 +1500,46 @@
}
}
+ public static class AudioTap2ToneLatencyRequirement extends Requirement {
+ private static final String TAG = AudioTap2ToneLatencyRequirement.class.getSimpleName();
+
+ private AudioTap2ToneLatencyRequirement(String id, RequiredMeasurement<?> ... reqs) {
+ super(id, reqs);
+ }
+
+ public void setNativeLatency(double latency) {
+ this.setMeasuredValue(RequirementConstants.API_NATIVE_LATENCY, latency);
+ }
+
+ public void setJavaLatency(double latency) {
+ this.setMeasuredValue(RequirementConstants.API_JAVA_LATENCY, latency);
+ }
+
+ public static AudioTap2ToneLatencyRequirement createR5_6__H_1_1() {
+ RequiredMeasurement<Double> apiNativeLatency = RequiredMeasurement
+ .<Double>builder()
+ .setId(RequirementConstants.API_NATIVE_LATENCY)
+ .setPredicate(RequirementConstants.DOUBLE_LTE)
+ .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 80.0)
+ .addRequiredValue(Build.VERSION_CODES.S, 100.0)
+ .addRequiredValue(Build.VERSION_CODES.R, 100.0)
+ .build();
+ RequiredMeasurement<Double> apiJavaLatency = RequiredMeasurement
+ .<Double>builder()
+ .setId(RequirementConstants.API_JAVA_LATENCY)
+ .setPredicate(RequirementConstants.DOUBLE_LTE)
+ .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 80.0)
+ .addRequiredValue(Build.VERSION_CODES.S, 100.0)
+ .addRequiredValue(Build.VERSION_CODES.R, 100.0)
+ .build();
+
+ return new AudioTap2ToneLatencyRequirement(
+ RequirementConstants.R5_6__H_1_1,
+ apiNativeLatency,
+ apiJavaLatency);
+ }
+ }
+
public <R extends Requirement> R addRequirement(R req) {
if (!this.mRequirements.add(req)) {
throw new IllegalStateException("Requirement " + req.id() + " already added");
@@ -1374,6 +1573,38 @@
return this.<MemoryRequirement>addRequirement(MemoryRequirement.createR7_6_1__H_2_1());
}
+ public FileSystemRequirement addR8_2__H_1_1() {
+ return this.addRequirement(FileSystemRequirement.createR8_2__H_1_1());
+ }
+
+ public FileSystemRequirement addR8_2__H_2_1() {
+ return this.addRequirement(FileSystemRequirement.createR8_2__H_2_1());
+ }
+
+ public FileSystemRequirement addR8_2__H_1_2() {
+ return this.addRequirement(FileSystemRequirement.createR8_2__H_1_2());
+ }
+
+ public FileSystemRequirement addR8_2__H_2_2() {
+ return this.addRequirement(FileSystemRequirement.createR8_2__H_2_2());
+ }
+
+ public FileSystemRequirement addR8_2__H_1_3() {
+ return this.addRequirement(FileSystemRequirement.createR8_2__H_1_3());
+ }
+
+ public FileSystemRequirement addR8_2__H_2_3() {
+ return this.addRequirement(FileSystemRequirement.createR8_2__H_2_3());
+ }
+
+ public FileSystemRequirement addR8_2__H_1_4() {
+ return this.addRequirement(FileSystemRequirement.createR8_2__H_1_4());
+ }
+
+ public FileSystemRequirement addR8_2__H_2_4() {
+ return this.addRequirement(FileSystemRequirement.createR8_2__H_2_4());
+ }
+
public FrameDropRequirement addR5_3__H_1_1_R() {
return this.addRequirement(FrameDropRequirement.createR5_3__H_1_1_R());
}
@@ -1540,21 +1771,51 @@
return this.addRequirement(StreamUseCaseRequirement.createStreamUseCaseReq());
}
+ public AudioTap2ToneLatencyRequirement addR5_6__H_1_1() {
+ return this.addRequirement(AudioTap2ToneLatencyRequirement.createR5_6__H_1_1());
+ }
+
+ private enum SubmitType {
+ TRADEFED, VERIFIER
+ }
+
public void submitAndCheck() {
- boolean perfClassMet = submit();
+ boolean perfClassMet = submit(SubmitType.TRADEFED);
// check performance class
assumeTrue("Build.VERSION.MEDIA_PERFORMANCE_CLASS is not declared", Utils.isPerfClass());
assertThat(perfClassMet).isTrue();
}
- public boolean submit() {
+ public void submitAndVerify() {
+ boolean perfClassMet = submit(SubmitType.VERIFIER);
+
+ if (!perfClassMet && Utils.isPerfClass()) {
+ Log.w(TAG, "Device did not meet specified performance class: " + Utils.getPerfClass());
+ }
+ }
+
+ private boolean submit(SubmitType type) {
boolean perfClassMet = true;
for (Requirement req: this.mRequirements) {
- perfClassMet &= req.writeLogAndCheck(this.mTestName);
+ switch (type) {
+ case VERIFIER:
+ CtsVerifierReportLog verifierLog = new CtsVerifierReportLog(
+ RequirementConstants.REPORT_LOG_NAME, req.id());
+ perfClassMet &= req.writeLogAndCheck(verifierLog, this.mTestName);
+ verifierLog.submit();
+ break;
+
+ case TRADEFED:
+ default:
+ DeviceReportLog tradefedLog = new DeviceReportLog(
+ RequirementConstants.REPORT_LOG_NAME, req.id());
+ perfClassMet &= req.writeLogAndCheck(tradefedLog, this.mTestName);
+ tradefedLog.submit(InstrumentationRegistry.getInstrumentation());
+ break;
+ }
}
this.mRequirements.clear(); // makes sure report isn't submitted twice
return perfClassMet;
}
-
}
diff --git a/tests/mediapc/common/src/android/mediapc/cts/common/RequiredMeasurement.java b/tests/mediapc/common/src/android/mediapc/cts/common/RequiredMeasurement.java
index f89cb28..777a8f2 100644
--- a/tests/mediapc/common/src/android/mediapc/cts/common/RequiredMeasurement.java
+++ b/tests/mediapc/common/src/android/mediapc/cts/common/RequiredMeasurement.java
@@ -16,9 +16,10 @@
package android.mediapc.cts.common;
-import com.android.compatibility.common.util.DeviceReportLog;
+import com.android.compatibility.common.util.ReportLog;
import com.android.compatibility.common.util.ResultType;
import com.android.compatibility.common.util.ResultUnit;
+
import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableMap;
@@ -113,7 +114,7 @@
+ "\n\tExpected Values: " + this.expectedValues();
}
- public void writeValue(DeviceReportLog log) throws IllegalStateException {
+ public void writeValue(ReportLog log) throws IllegalStateException {
if (!this.measuredValueSet) {
throw new IllegalStateException("measured value not set for required measurement "
diff --git a/tests/mediapc/common/src/android/mediapc/cts/common/Requirement.java b/tests/mediapc/common/src/android/mediapc/cts/common/Requirement.java
index 445c5c6..2160b10 100644
--- a/tests/mediapc/common/src/android/mediapc/cts/common/Requirement.java
+++ b/tests/mediapc/common/src/android/mediapc/cts/common/Requirement.java
@@ -18,15 +18,13 @@
import android.util.Log;
-import androidx.test.platform.app.InstrumentationRegistry;
-
-import com.android.compatibility.common.util.DeviceReportLog;
+import com.android.compatibility.common.util.ReportLog;
import com.android.compatibility.common.util.ResultType;
import com.android.compatibility.common.util.ResultUnit;
+
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableMap;
-import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@@ -113,7 +111,7 @@
/**
* @return whether or not the requirement meets the device's specified performance class
*/
- public boolean writeLogAndCheck(String testName) {
+ public boolean writeLogAndCheck(ReportLog log, String testName) {
if (this.id == RequirementConstants.RTBD) {
// skip upload on any requirement without a specified id
Log.i(this.TAG, testName + "has requirement without set requirement id and test " +
@@ -123,7 +121,6 @@
int perfClass = this.computePerformanceClass();
- DeviceReportLog log = new DeviceReportLog(RequirementConstants.REPORT_LOG_NAME, this.id);
log.addValue(RequirementConstants.TN_FIELD_NAME, testName, ResultType.NEUTRAL,
ResultUnit.NONE);
for (RequiredMeasurement rm: this.mRequiredMeasurements.values()) {
@@ -131,7 +128,6 @@
}
log.addValue(RequirementConstants.PC_FIELD_NAME, perfClass, ResultType.NEUTRAL,
ResultUnit.NONE);
- log.submit(InstrumentationRegistry.getInstrumentation());
return this.checkPerformanceClass(Utils.getPerfClass());
}
diff --git a/tests/mediapc/common/src/android/mediapc/cts/common/RequirementConstants.java b/tests/mediapc/common/src/android/mediapc/cts/common/RequirementConstants.java
index ad0d0d56..6893e62 100644
--- a/tests/mediapc/common/src/android/mediapc/cts/common/RequirementConstants.java
+++ b/tests/mediapc/common/src/android/mediapc/cts/common/RequirementConstants.java
@@ -50,8 +50,11 @@
public static final String R7_5__H_1_2 = "r7_5__h_1_2"; // 7.5/H-1-2
public static final String R7_5__H_1_3 = "r7_5__h_1_3"; // 7.5/H-1-3
public static final String R7_5__H_1_4 = "r7_5__h_1_4"; // 7.5/H-1-4
- public static final String R7_5__H_1_5 = "r7_5__h_1_5"; // 7.5/H-1-5
- public static final String R7_5__H_1_6 = "r7_5__h_1_6"; // 7.5/H-1-6
+
+ // these includes "its" because the proto in google3 was originally implemented incorrectly
+ public static final String R7_5__H_1_5 = "r7_5__h_1_5__its"; // 7.5/H-1-5
+ public static final String R7_5__H_1_6 = "r7_5__h_1_6__its"; // 7.5/H-1-6
+
public static final String R7_5__H_1_8 = "r7_5__h_1_8"; // 7.5/H-1-8
public static final String R7_5__H_1_9 = "r7_5__h_1_9"; // 7.5/H-1-9
public static final String R7_5__H_1_10 = "r7_5__h_1_10"; // 7.5/H-1-10
@@ -77,6 +80,7 @@
public static final String RTBD = "tbd"; // placeholder for requirements without a set id
public static final String CONCURRENT_SESSIONS = "concurrent_sessions";
+ public static final String TEST_RESOLUTION = "resolution";
public static final String CONCURRENT_FPS = "concurrent_fps";
public static final String SUPPORTED_PERFORMANCE_POINTS = "supported_performance_points";
public static final String FRAMES_DROPPED = "frame_drops_per_30sec";
@@ -92,6 +96,7 @@
public static final String SECURE_REQ_SATISFIED = "secure_requirement_satisfied_boolean";
public static final String NUM_CRYPTO_HW_SECURE_ALL_SUPPORT =
"number_crypto_hw_secure_all_support";
+ public static final String FILESYSTEM_IO_RATE = "filesystem_io_rate_mbps";
public static final String PRIMARY_CAMERA_AVAILABLE = "primary_camera_available";
public static final String PRIMARY_CAMERA_RESOLUTION = "primary_camera_resolution";
@@ -126,6 +131,8 @@
"rear_camera_stream_usecase_supported";
public static final String FRONT_CAMERA_STREAM_USECASE_SUPPORTED =
"front_camera_stream_usecase_supported";
+ public static final String API_NATIVE_LATENCY = "native_latency_ms";
+ public static final String API_JAVA_LATENCY = "java_latency_ms";
public enum Result {
NA, MET, UNMET
@@ -137,9 +144,10 @@
public static final BiPredicate<Integer, Integer> INTEGER_GTE = RequirementConstants.gte();
public static final BiPredicate<Integer, Integer> INTEGER_LTE = RequirementConstants.lte();
public static final BiPredicate<Integer, Integer> INTEGER_EQ = RequirementConstants.eq();
+ public static final BiPredicate<Double, Double> DOUBLE_GTE = RequirementConstants.gte();
+ public static final BiPredicate<Double, Double> DOUBLE_LTE = RequirementConstants.lte();
public static final BiPredicate<Double, Double> DOUBLE_EQ = RequirementConstants.eq();
public static final BiPredicate<Boolean, Boolean> BOOLEAN_EQ = RequirementConstants.eq();
- public static final BiPredicate<Double, Double> DOUBLE_GTE = RequirementConstants.gte();
/**
* Creates a >= predicate.
diff --git a/tests/mediapc/common/tests/src/android/mediapc/cts/common/RequirementTest.java b/tests/mediapc/common/tests/src/android/mediapc/cts/common/RequirementTest.java
index daa9d27..1c5035b 100644
--- a/tests/mediapc/common/tests/src/android/mediapc/cts/common/RequirementTest.java
+++ b/tests/mediapc/common/tests/src/android/mediapc/cts/common/RequirementTest.java
@@ -22,6 +22,8 @@
import android.os.Build;
+import com.android.compatibility.common.util.DeviceReportLog;
+
import org.junit.Test;
public class RequirementTest {
@@ -197,9 +199,10 @@
@Test
public void writeLogAndCheck_UnsetMeasurement() {
TestReq testReq = TestReq.create();
+ DeviceReportLog testLog = new DeviceReportLog("test", "test");
assertThrows(
IllegalStateException.class,
- () -> testReq.writeLogAndCheck("writeLogAndCheck_UnsetMeasurement"));
+ () -> testReq.writeLogAndCheck(testLog, "writeLogAndCheck_UnsetMeasurement"));
}
}
diff --git a/tests/mediapc/copy_media.sh b/tests/mediapc/copy_media.sh
index 693691c..374a22c 100644
--- a/tests/mediapc/copy_media.sh
+++ b/tests/mediapc/copy_media.sh
@@ -17,7 +17,7 @@
## script to install media performance class test files manually
adbOptions=" "
-resLabel=CtsMediaPerformanceClassTestCases-1.3
+resLabel=CtsMediaPerformanceClassTestCases-1.4
srcDir="/tmp/$resLabel"
tgtDir="/sdcard/test"
usage="Usage: $0 [-h] [-s serial]"
diff --git a/tests/mediapc/src/android/mediapc/cts/WorkDir.java b/tests/mediapc/src/android/mediapc/cts/WorkDir.java
index 6cf7a9c..0497862 100644
--- a/tests/mediapc/src/android/mediapc/cts/WorkDir.java
+++ b/tests/mediapc/src/android/mediapc/cts/WorkDir.java
@@ -40,7 +40,7 @@
// user has specified the mediaDirString via instrumentation-arg
return mediaDirString + ((mediaDirString.endsWith("/")) ? "" : "/");
} else {
- return (getTopDirString() + "test/CtsMediaPerformanceClassTestCases-1.3/");
+ return (getTopDirString() + "test/CtsMediaPerformanceClassTestCases-1.4/");
}
}
}
diff --git a/tests/providerui/src/android/providerui/cts/MediaStoreUiTest.java b/tests/providerui/src/android/providerui/cts/MediaStoreUiTest.java
index 0e1bcd1..b2292f4 100644
--- a/tests/providerui/src/android/providerui/cts/MediaStoreUiTest.java
+++ b/tests/providerui/src/android/providerui/cts/MediaStoreUiTest.java
@@ -281,6 +281,11 @@
public void testOpenFile_onMediaDocumentsProvider_failsWithoutAccess() throws Exception {
if (!supportsHardware()) return;
+ String rawText = "TEST";
+ // Read and write grants will be provided to the file associated with this pair.
+ // Stages a text file which contains raw text "TEST"
+ Pair<Uri, File> uriFilePairWithGrants = prepareFileAndFetchDetails(rawText);
+
clearDocumentsUi();
final Intent intent = new Intent();
intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
@@ -289,10 +294,6 @@
mActivity.startActivityForResult(intent, REQUEST_CODE);
mDevice.waitForIdle();
- String rawText = "TEST";
- // Read and write grants will be provided to the file associated with this pair.
- // Stages a text file which contains raw text "TEST"
- Pair<Uri, File> uriFilePairWithGrants = prepareFileAndFetchDetails(rawText);
// Read and write grants will not be provided to the file associated with this pair
// Stages a text file which contains raw text "TEST"
Pair<Uri, File> uriFilePairWithoutGrants = prepareFileAndFetchDetails(rawText);
diff --git a/tests/tests/bluetooth/bluetoothTestUtilLib/src/android/bluetooth/cts/BTAdapterUtils.java b/tests/tests/bluetooth/bluetoothTestUtilLib/src/android/bluetooth/cts/BTAdapterUtils.java
index 32d37fc..6807c39 100644
--- a/tests/tests/bluetooth/bluetoothTestUtilLib/src/android/bluetooth/cts/BTAdapterUtils.java
+++ b/tests/tests/bluetooth/bluetoothTestUtilLib/src/android/bluetooth/cts/BTAdapterUtils.java
@@ -280,7 +280,12 @@
try {
adoptPermissionAsShellUid(BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED);
bluetoothAdapter.disable();
- return waitForAdapterStateLocked(BluetoothAdapter.STATE_OFF, bluetoothAdapter);
+ if (waitForAdapterStateLocked(BluetoothAdapter.STATE_OFF, bluetoothAdapter)) {
+ //TODO b/234892968
+ Thread.sleep(2000);
+ return true;
+ }
+ return false;
} catch (InterruptedException e) {
Log.w(TAG, "disableAdapter(): interrupted", e);
} finally {
diff --git a/tests/tests/content/Android.bp b/tests/tests/content/Android.bp
index 7a691f9..d7d1424 100644
--- a/tests/tests/content/Android.bp
+++ b/tests/tests/content/Android.bp
@@ -26,6 +26,7 @@
// Include both the 32 and 64 bit versions
compile_multilib: "both",
jni_libs: [
+ "libcts_jni",
"libnativecursorwindow_jni",
"libnativehelper_compat_libc++",
],
diff --git a/tests/tests/content/src/android/content/pm/cts/ChecksumsTest.java b/tests/tests/content/src/android/content/pm/cts/ChecksumsTest.java
index b519f7b..086c607 100644
--- a/tests/tests/content/src/android/content/pm/cts/ChecksumsTest.java
+++ b/tests/tests/content/src/android/content/pm/cts/ChecksumsTest.java
@@ -71,6 +71,8 @@
import com.android.server.pm.PackageManagerShellCommandDataLoader;
import com.android.server.pm.PackageManagerShellCommandDataLoader.Metadata;
+import com.android.compatibility.common.util.CpuFeatures;
+
import org.junit.After;
import org.junit.Assert;
import org.junit.Assume;
@@ -157,8 +159,6 @@
new Checksum(TYPE_WHOLE_SHA256, hexStringToBytes(TEST_FIXED_APK_SHA256)),
new Checksum(TYPE_WHOLE_MD5, hexStringToBytes(TEST_FIXED_APK_MD5))};
- private static final String PRIMARY_ABI = Build.SUPPORTED_ABIS[0];
-
/** Default is to not use fs-verity since it depends on kernel support. */
private static final int FSVERITY_DISABLED = 0;
@@ -338,19 +338,18 @@
assertNotNull(checksums);
assertEquals(checksums.length, 2);
assertEquals(checksums[0].getType(), TYPE_WHOLE_MERKLE_ROOT_4K_SHA256);
- if ("x86_64".equals(PRIMARY_ABI) || "x86".equals(PRIMARY_ABI)) {
- assertEquals(bytesToHexString(checksums[0].getValue()),
- TEST_FIXED_APK_FSVERITY_SHA256_X86_64);
- assertEquals(bytesToHexString(checksums[1].getValue()),
- "6f7cfa569c4a25d7241e26c1c8ff274badbdefd7854d91b842b1a97a985d5917");
- } else if ("arm64-v8a".equals(PRIMARY_ABI) || "armeabi".equals(PRIMARY_ABI)
- || "armeabi-v7a".equals(PRIMARY_ABI)) {
+ if (CpuFeatures.isArm64Cpu() || CpuFeatures.isArmCpu()) {
assertEquals(bytesToHexString(checksums[0].getValue()),
TEST_FIXED_APK_FSVERITY_SHA256_ARM64);
assertEquals(bytesToHexString(checksums[1].getValue()),
"8c61bc2548521aa0005276af68e42253957e1e24c122f7d8bf10f1832d4014e5");
+ } else if (CpuFeatures.isX86_64Cpu() || CpuFeatures.isX86Cpu()) {
+ assertEquals(bytesToHexString(checksums[0].getValue()),
+ TEST_FIXED_APK_FSVERITY_SHA256_X86_64);
+ assertEquals(bytesToHexString(checksums[1].getValue()),
+ "6f7cfa569c4a25d7241e26c1c8ff274badbdefd7854d91b842b1a97a985d5917");
} else {
- Assert.fail("Unsupported ABI: " + PRIMARY_ABI);
+ Assert.fail("Unsupported CPU ABI");
}
assertEquals(checksums[1].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256);
}
@@ -373,15 +372,14 @@
assertNotNull(checksums);
assertEquals(checksums.length, 1);
assertEquals(checksums[0].getType(), TYPE_WHOLE_MERKLE_ROOT_4K_SHA256);
- if ("x86_64".equals(PRIMARY_ABI) || "x86".equals(PRIMARY_ABI)) {
- assertEquals(bytesToHexString(checksums[0].getValue()),
- TEST_FIXED_APK_FSVERITY_SHA256_X86_64);
- } else if ("arm64-v8a".equals(PRIMARY_ABI) || "armeabi".equals(PRIMARY_ABI)
- || "armeabi-v7a".equals(PRIMARY_ABI)) {
+ if (CpuFeatures.isArm64Cpu() || CpuFeatures.isArmCpu()) {
assertEquals(bytesToHexString(checksums[0].getValue()),
TEST_FIXED_APK_FSVERITY_SHA256_ARM64);
+ } else if (CpuFeatures.isX86_64Cpu() || CpuFeatures.isX86Cpu()) {
+ assertEquals(bytesToHexString(checksums[0].getValue()),
+ TEST_FIXED_APK_FSVERITY_SHA256_X86_64);
} else {
- Assert.fail("Unsupported ABI: " + PRIMARY_ABI);
+ Assert.fail("Unsupported CPU ABI");
}
}
diff --git a/tests/tests/gameservice/TEST_MAPPING b/tests/tests/gameservice/TEST_MAPPING
index 8d6b802..6a5661b 100644
--- a/tests/tests/gameservice/TEST_MAPPING
+++ b/tests/tests/gameservice/TEST_MAPPING
@@ -1,7 +1,12 @@
{
"presubmit": [
{
- "name": "CtsGameServiceTestCases"
+ "name": "CtsGameServiceTestCases",
+ "options": [
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ }
+ ]
}
]
}
\ No newline at end of file
diff --git a/tests/tests/gameservice/src/android/service/games/GameServiceTest.java b/tests/tests/gameservice/src/android/service/games/GameServiceTest.java
index aada0a0..d31f61c 100644
--- a/tests/tests/gameservice/src/android/service/games/GameServiceTest.java
+++ b/tests/tests/gameservice/src/android/service/games/GameServiceTest.java
@@ -60,6 +60,7 @@
import android.view.WindowMetrics;
import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.FlakyTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.compatibility.common.util.PollingCheck;
@@ -88,6 +89,7 @@
/**
* CTS tests for {@link android.service.games.GameService}.
*/
+@FlakyTest(bugId = 263181277)
@RunWith(AndroidJUnit4.class)
public final class GameServiceTest {
static final String TAG = "GameServiceTest";
diff --git a/tests/tests/graphics/src/android/graphics/fonts/FontFileTestUtil.java b/tests/tests/graphics/src/android/graphics/fonts/FontFileTestUtil.java
index 5ee0912..fcaab4bc0 100644
--- a/tests/tests/graphics/src/android/graphics/fonts/FontFileTestUtil.java
+++ b/tests/tests/graphics/src/android/graphics/fonts/FontFileTestUtil.java
@@ -90,50 +90,4 @@
}
return null;
}
-
- public static boolean containsEmojiCompatMetadata(File file) throws IOException {
- try (FileInputStream fis = new FileInputStream(file)) {
- final FileChannel fc = fis.getChannel();
- long size = fc.size();
- ByteBuffer buffer = fc.map(FileChannel.MapMode.READ_ONLY, 0, size)
- .order(ByteOrder.BIG_ENDIAN);
-
- int magicNumber = buffer.getInt(0);
-
- int fontOffset = 0;
- if (magicNumber == TTC_TAG) {
- throw new IOException("Emoji font is not expected to be in a font collection.");
- } else if (magicNumber != SFNT_VERSION_1 && magicNumber != SFNT_VERSION_OTTO) {
- throw new IOException("Unknown magic number: #" + magicNumber);
- }
-
- int numTables = buffer.getShort(fontOffset + 4); // offset to number of table
- int metaTableOffset = 0;
- for (int i = 0; i < numTables; ++i) {
- int tableEntryOffset = fontOffset + 12 + i * 16;
- int tableTag = buffer.getInt(tableEntryOffset);
- if (tableTag == META_TAG) {
- metaTableOffset = buffer.getInt(tableEntryOffset + 8);
- break;
- }
- }
-
- if (metaTableOffset == 0) {
- throw new IOException("name table not found.");
- }
-
- int dataMapsCount = buffer.getInt(metaTableOffset + 12);
-
- for (int i = 0; i < dataMapsCount; ++i) {
- int tag = buffer.getInt(metaTableOffset + 16 + 12 * i);
- int offset = buffer.getInt(metaTableOffset + 16 + 12 * i + 4);
- int dataLength = buffer.getInt(metaTableOffset + 16 + 12 * i + 8);
-
- if (tag == EMJI_TAG && dataLength != 0) {
- return true;
- }
- }
- }
- return false;
- }
}
diff --git a/tests/tests/graphics/src/android/graphics/fonts/SystemEmojiTest.java b/tests/tests/graphics/src/android/graphics/fonts/SystemEmojiTest.java
index f42da83..a4d0ab4 100644
--- a/tests/tests/graphics/src/android/graphics/fonts/SystemEmojiTest.java
+++ b/tests/tests/graphics/src/android/graphics/fonts/SystemEmojiTest.java
@@ -47,8 +47,6 @@
// NotoColorEmoji.ttf should be always available as a fallback font even if another emoji
// font files are installed in the system.
assertThat(emojiFont).isNotNull();
-
- assertThat(FontFileTestUtil.containsEmojiCompatMetadata(emojiFont)).isTrue();
}
public String getFontName(String chars) {
diff --git a/tests/tests/hardware/src/android/hardware/input/cts/tests/VirtualMouseTest.java b/tests/tests/hardware/src/android/hardware/input/cts/tests/VirtualMouseTest.java
index 90a4975..c0ddb91 100644
--- a/tests/tests/hardware/src/android/hardware/input/cts/tests/VirtualMouseTest.java
+++ b/tests/tests/hardware/src/android/hardware/input/cts/tests/VirtualMouseTest.java
@@ -128,10 +128,6 @@
maybeConsumeHoverEnter();
verifyEvents(Arrays.asList(
- createMotionEvent(MotionEvent.ACTION_HOVER_ENTER, secondStopPositionX,
- secondStopPositionY, -relativeChangeX,
- -relativeChangeY, /* vScroll= */ 0f,
- /* hScroll= */ 0f, /* buttonState= */ 0, /* pressure= */ 0.0f),
createMotionEvent(MotionEvent.ACTION_HOVER_MOVE, secondStopPositionX,
secondStopPositionY, -relativeChangeX,
-relativeChangeY, /* vScroll= */ 0f,
diff --git a/tests/tests/media/codec/src/android/media/codec/cts/MediaCodecCapabilitiesTest.java b/tests/tests/media/codec/src/android/media/codec/cts/MediaCodecCapabilitiesTest.java
index 0c33f93..644ecc6 100644
--- a/tests/tests/media/codec/src/android/media/codec/cts/MediaCodecCapabilitiesTest.java
+++ b/tests/tests/media/codec/src/android/media/codec/cts/MediaCodecCapabilitiesTest.java
@@ -750,7 +750,15 @@
int minFrameRate = Math.max(vcaps.getSupportedFrameRatesFor(minWidth, minHeight)
.getLower().intValue(), 1);
format = MediaFormat.createVideoFormat(mime, minWidth, minHeight);
- format.setInteger(MediaFormat.KEY_COLOR_FORMAT, caps.colorFormats[0]);
+ int colorFormat = caps.colorFormats[0];
+ for (int i = 0; i < caps.colorFormats.length; ++i) {
+ colorFormat = caps.colorFormats[i];
+ // Avoid COLOR_FormatSurface as we will be configuring the codec without a surface.
+ if (colorFormat != CodecCapabilities.COLOR_FormatSurface) {
+ break;
+ }
+ }
+ format.setInteger(MediaFormat.KEY_COLOR_FORMAT, colorFormat);
format.setInteger(MediaFormat.KEY_BIT_RATE, minBitrate);
format.setInteger(MediaFormat.KEY_FRAME_RATE, minFrameRate);
format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, IFRAME_INTERVAL);
diff --git a/tests/tests/media/common/src/android/media/cts/MediaTestBase.java b/tests/tests/media/common/src/android/media/cts/MediaTestBase.java
index 9f98508..55c94de 100644
--- a/tests/tests/media/common/src/android/media/cts/MediaTestBase.java
+++ b/tests/tests/media/common/src/android/media/cts/MediaTestBase.java
@@ -81,6 +81,7 @@
@CallSuper
protected void tearDown() {
+ mActivityScenario.close();
mActivity = null;
}
diff --git a/tests/tests/notificationlegacy/notificationlegacy30/src/android/app/notification/legacy30/cts/NotificationTemplateApi30Test.kt b/tests/tests/notificationlegacy/notificationlegacy30/src/android/app/notification/legacy30/cts/NotificationTemplateApi30Test.kt
index 29638bd..e0895ef 100644
--- a/tests/tests/notificationlegacy/notificationlegacy30/src/android/app/notification/legacy30/cts/NotificationTemplateApi30Test.kt
+++ b/tests/tests/notificationlegacy/notificationlegacy30/src/android/app/notification/legacy30/cts/NotificationTemplateApi30Test.kt
@@ -19,11 +19,11 @@
import android.app.Notification
import android.app.cts.NotificationTemplateTestBase
import android.content.pm.PackageManager
-import android.util.Log
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import com.google.common.truth.Truth.assertThat
+import org.junit.Assume
class NotificationTemplateApi30Test : NotificationTemplateTestBase() {
@@ -58,11 +58,8 @@
}
fun testWideIcon_inBigPicture_isSquareForLegacyApps() {
- if (isPlatformAutomotive()) {
- Log.i(TAG, "Skipping: testWideIcon_inBigPicture_isSquareForLegacyApps" +
- " - BigPictureStyle is not supported in automotive.")
- return
- }
+ skipIfPlatformDoesNotSupportNotificationStyles()
+
val picture = createBitmap(40, 30)
val icon = createBitmap(200, 100)
val views = Notification.Builder(mContext, NOTIFICATION_CHANNEL_ID)
@@ -92,11 +89,8 @@
}
fun testPromoteBigPicture_withoutLargeIcon() {
- if (isPlatformAutomotive()) {
- Log.i(TAG, "Skipping: testPromoteBigPicture_withoutLargeIcon" +
- " - BigPictureStyle is not supported in automotive.")
- return
- }
+ skipIfPlatformDoesNotSupportNotificationStyles()
+
val picture = createBitmap(40, 30)
val builder = Notification.Builder(mContext, NOTIFICATION_CHANNEL_ID)
.setSmallIcon(R.drawable.ic_media_play)
@@ -121,11 +115,8 @@
}
fun testPromoteBigPicture_withLargeIcon() {
- if (isPlatformAutomotive()) {
- Log.i(TAG, "Skipping: testPromoteBigPicture_withLargeIcon" +
- " - BigPictureStyle is not supported in automotive.")
- return
- }
+ skipIfPlatformDoesNotSupportNotificationStyles()
+
val picture = createBitmap(40, 30)
val icon = createBitmap(80, 65)
val builder = Notification.Builder(mContext, NOTIFICATION_CHANNEL_ID)
@@ -137,36 +128,24 @@
.showBigPictureWhenCollapsed(true)
)
- // At really high densities the size of rendered icon can dip below the
- // tested size - we allow rendering of smaller icon with the same
- // aspect ratio then.
- val expectedIconWidth = minOf(rightIconSize(), 80)
- val expectedIconHeight = minOf(rightIconSize() * 65 / 80, 65)
-
// the promoted big picture is shown with enlarged aspect ratio
checkIconView(builder.createContentView()) { iconView ->
assertThat(iconView.visibility).isEqualTo(View.VISIBLE)
assertThat(iconView.width.toFloat())
.isWithin(1f)
.of((iconView.height * 4 / 3).toFloat())
- assertThat(iconView.drawable.intrinsicWidth).isEqualTo(40)
- assertThat(iconView.drawable.intrinsicHeight).isEqualTo(30)
}
// because it doesn't target S, the icon is still shown in a square
checkIconView(builder.createBigContentView()) { iconView ->
assertThat(iconView.visibility).isEqualTo(View.VISIBLE)
assertThat(iconView.width).isEqualTo(iconView.height)
- assertThat(iconView.drawable.intrinsicWidth).isEqualTo(expectedIconWidth)
- assertThat(iconView.drawable.intrinsicHeight).isEqualTo(expectedIconHeight)
+ assertThat(iconView.scaleType).isEqualTo(ImageView.ScaleType.CENTER_CROP)
}
}
fun testPromoteBigPicture_withBigLargeIcon() {
- if (isPlatformAutomotive()) {
- Log.i(TAG, "Skipping: testPromoteBigPicture_withBigLargeIcon" +
- " - BigPictureStyle is not supported in automotive.")
- return
- }
+ skipIfPlatformDoesNotSupportNotificationStyles()
+
val picture = createBitmap(40, 30)
val inputWidth = 400
val inputHeight = 300
@@ -180,24 +159,19 @@
.showBigPictureWhenCollapsed(true)
)
- val expectedIconWidth = minOf(rightIconSize(), inputWidth)
- val expectedIconHeight = minOf(rightIconSize() * inputHeight / inputWidth, inputHeight)
-
// the promoted big picture is shown with enlarged aspect ratio
checkIconView(builder.createContentView()) { iconView ->
assertThat(iconView.visibility).isEqualTo(View.VISIBLE)
assertThat(iconView.width.toFloat())
.isWithin(1f)
.of((iconView.height * 4 / 3).toFloat())
- assertThat(iconView.drawable.intrinsicWidth).isEqualTo(40)
- assertThat(iconView.drawable.intrinsicHeight).isEqualTo(30)
+ assertThat(iconView.scaleType).isEqualTo(ImageView.ScaleType.CENTER_CROP)
}
// because it doesn't target S, the icon is still shown in a square
checkIconView(builder.createBigContentView()) { iconView ->
assertThat(iconView.visibility).isEqualTo(View.VISIBLE)
assertThat(iconView.width).isEqualTo(iconView.height)
- assertThat(iconView.drawable.intrinsicWidth).isEqualTo(expectedIconWidth)
- assertThat(iconView.drawable.intrinsicHeight).isEqualTo(expectedIconHeight)
+ assertThat(iconView.scaleType).isEqualTo(ImageView.ScaleType.CENTER_CROP)
}
}
@@ -314,17 +288,19 @@
}
}
- private fun rightIconSize(): Int {
- return mContext.resources.getDimensionPixelSize(
- getAndroidRDimen("notification_right_icon_size"))
- }
-
- private fun isPlatformAutomotive(): Boolean {
- return mContext.packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)
+ /**
+ * Assume that we're running on the platform that supports styled notifications.
+ *
+ * If the current platform does not support notification styles, skip this test without failure.
+ */
+ private fun skipIfPlatformDoesNotSupportNotificationStyles() {
+ Assume.assumeFalse("Current platform does not support notification styles.",
+ mContext.packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE) ||
+ mContext.packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK))
}
companion object {
val TAG = NotificationTemplateApi30Test::class.java.simpleName
const val NOTIFICATION_CHANNEL_ID = "NotificationTemplateApi30Test"
}
-}
\ No newline at end of file
+}
diff --git a/tests/tests/os/src/android/os/cts/AutoRevokeTest.kt b/tests/tests/os/src/android/os/cts/AutoRevokeTest.kt
index 9467e6b..db58721 100644
--- a/tests/tests/os/src/android/os/cts/AutoRevokeTest.kt
+++ b/tests/tests/os/src/android/os/cts/AutoRevokeTest.kt
@@ -26,6 +26,7 @@
import android.content.pm.PackageManager.PERMISSION_DENIED
import android.content.pm.PackageManager.PERMISSION_GRANTED
import android.content.res.Resources
+import android.provider.DeviceConfig
import android.net.Uri
import android.os.Build
import android.platform.test.annotations.AppModeFull
@@ -47,6 +48,7 @@
import com.android.compatibility.common.util.SystemUtil.getEventually
import com.android.compatibility.common.util.SystemUtil.runShellCommandOrThrow
import com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity
+import com.android.compatibility.common.util.ThrowingSupplier
import com.android.compatibility.common.util.UI_ROOT
import com.android.compatibility.common.util.click
import com.android.compatibility.common.util.depthFirstSearch
@@ -259,6 +261,7 @@
@AppModeFull(reason = "Uses separate apps for testing")
@Test
fun testPreMinAutoRevokeVersionUnusedApp_doesntGetPermissionRevoked() {
+ assumeFalse(isHibernationEnabledForPreSApps())
withUnusedThresholdMs(3L) {
withDummyApp(preMinVersionApkPath, preMinVersionAppPackageName) {
withDummyApp {
@@ -287,6 +290,18 @@
}
}
+ private fun isHibernationEnabledForPreSApps(): Boolean {
+ return runWithShellPermissionIdentity(
+ ThrowingSupplier {
+ DeviceConfig.getBoolean(
+ DeviceConfig.NAMESPACE_APP_HIBERNATION,
+ "app_hibernation_targets_pre_s_apps",
+ false
+ )
+ }
+ )
+ }
+
@AppModeFull(reason = "Uses separate apps for testing")
@Test
fun testAutoRevoke_userAllowlisting() {
diff --git a/tests/tests/permission2/res/raw/android_manifest.xml b/tests/tests/permission2/res/raw/android_manifest.xml
index 1c9dc63..c495afa 100644
--- a/tests/tests/permission2/res/raw/android_manifest.xml
+++ b/tests/tests/permission2/res/raw/android_manifest.xml
@@ -6495,6 +6495,10 @@
<p>Not for use by third-party applications.</p> -->
<attribution android:tag="MusicRecognitionManagerService"
android:label="@string/music_recognition_manager_service"/>
+ <!-- @hide Allows an application to receive keycode events.
+ <p>Wear specific. -->
+ <permission android:name="android.permission.RECEIVE_KEYCODE_EVENTS"
+ android:protectionLevel="signature|preinstalled" />
<application android:process="system"
android:persistent="true"
diff --git a/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java b/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java
index 752a794..93d9f29 100644
--- a/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java
+++ b/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java
@@ -74,6 +74,9 @@
private static final String SET_UNRESTRICTED_GESTURE_EXCLUSION
= "android.permission.SET_UNRESTRICTED_GESTURE_EXCLUSION";
+ private static final String RECEIVE_KEYCODE_EVENTS_PERMISSION =
+ "android.permission.RECEIVE_KEYCODE_EVENTS";
+
private static final String LOG_TAG = "PermissionProtectionTest";
private static final String PLATFORM_PACKAGE_NAME = "android";
@@ -167,11 +170,17 @@
for (ExpectedPermissionInfo expectedPermission : expectedPermissions) {
String expectedPermissionName = expectedPermission.name;
if (shouldSkipPermission(expectedPermissionName)) {
- // This permission doesn't need to exist yet, but will exist in
- // a future SPL. It is acceptable to declare the permission
- // even in an earlier SPL, so we remove it here so it doesn't
- // trigger a failure after the loop.
- declaredPermissionsMap.remove(expectedPermissionName);
+ // This permission doesn't need to exist, either because it
+ // will exist in a future SPL or because it is specific to a
+ // particular device type.
+
+ if (shouldAllowPermission(expectedPermissionName)) {
+ // It is acceptable to declare the permission if it will
+ // be in a future SPL, but not if it is for a different
+ // device type. If the permission may be declared, remove
+ // it here so it doesn't trigger a failure after the loop.
+ declaredPermissionsMap.remove(expectedPermissionName);
+ }
continue;
}
@@ -501,6 +510,18 @@
return patchDate;
}
+ private boolean shouldAllowPermission(String permissionName) {
+ boolean isWatch =
+ sContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH);
+
+ switch (permissionName) {
+ case RECEIVE_KEYCODE_EVENTS_PERMISSION:
+ return isWatch;
+ default:
+ return true;
+ }
+ }
+
private boolean shouldSkipPermission(String permissionName) {
switch (permissionName) {
case HIDE_NON_SYSTEM_OVERLAY_WINDOWS_PERMISSION:
@@ -509,6 +530,8 @@
return parseDate(SECURITY_PATCH).before(MANAGE_COMPANION_DEVICES_PATCH_DATE);
case SET_UNRESTRICTED_GESTURE_EXCLUSION:
return true;
+ case RECEIVE_KEYCODE_EVENTS_PERMISSION:
+ return true;
default:
return false;
}
diff --git a/tests/tests/permission3/src/android/permission3/cts/BaseUsePermissionTest.kt b/tests/tests/permission3/src/android/permission3/cts/BaseUsePermissionTest.kt
index dfefabc..f2e6aff 100755
--- a/tests/tests/permission3/src/android/permission3/cts/BaseUsePermissionTest.kt
+++ b/tests/tests/permission3/src/android/permission3/cts/BaseUsePermissionTest.kt
@@ -597,8 +597,8 @@
button.click()
}
- val shouldShowStorageWarning = !isWatch &&
- SdkLevel.isAtLeastT() && targetSdk <= Build.VERSION_CODES.S_V2 &&
+ val shouldShowStorageWarning = SdkLevel.isAtLeastT() &&
+ targetSdk <= Build.VERSION_CODES.S_V2 &&
permission in MEDIA_PERMISSIONS
if (shouldShowStorageWarning) {
click(By.res(ALERT_DIALOG_OK_BUTTON))
diff --git a/tests/tests/settings/src/android/settings/cts/AppLocaleSettingsTest.java b/tests/tests/settings/src/android/settings/cts/AppLocaleSettingsTest.java
index 85f5e5d..5bd31a7 100644
--- a/tests/tests/settings/src/android/settings/cts/AppLocaleSettingsTest.java
+++ b/tests/tests/settings/src/android/settings/cts/AppLocaleSettingsTest.java
@@ -17,6 +17,7 @@
package android.settings.cts;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeFalse;
import android.content.Intent;
import android.content.pm.PackageManager;
@@ -39,6 +40,9 @@
public class AppLocaleSettingsTest {
@Test
public void testAppLocaleSettingsExist() throws RemoteException {
+ assumeFalse(
+ "Skipping test: AppLocaleSettings is not supported in Wear OS",
+ isWatch());
final Intent intent = new Intent(Settings.ACTION_APP_LOCALE_SETTINGS);
intent.setData(Uri.parse("package:com.my.app"));
final ResolveInfo ri = InstrumentationRegistry.getTargetContext()
@@ -46,4 +50,9 @@
intent, PackageManager.MATCH_DEFAULT_ONLY);
assertTrue(ri != null);
}
+
+ private boolean isWatch() {
+ return InstrumentationRegistry.getTargetContext()
+ .getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH);
+ }
}
diff --git a/tests/tests/voiceRecognition/src/android/voicerecognition/cts/RecognitionServiceMicIndicatorTest.java b/tests/tests/voiceRecognition/src/android/voicerecognition/cts/RecognitionServiceMicIndicatorTest.java
index 82ee4d3..f7edd76 100644
--- a/tests/tests/voiceRecognition/src/android/voicerecognition/cts/RecognitionServiceMicIndicatorTest.java
+++ b/tests/tests/voiceRecognition/src/android/voicerecognition/cts/RecognitionServiceMicIndicatorTest.java
@@ -21,6 +21,7 @@
import static com.google.common.truth.Truth.assertWithMessage;
+import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeTrue;
import android.Manifest;
@@ -114,6 +115,10 @@
DeviceConfig.getProperty(DeviceConfig.NAMESPACE_PRIVACY, INDICATORS_FLAG);
Log.v(TAG, "setup(): mOriginalIndicatorsState=" + mOriginalIndicatorsState);
});
+
+ // TODO(http://b/259941077): Remove once privacy indicators are implemented.
+ assumeFalse("Privacy indicators not supported", isWatch());
+
setIndicatorsEnabledState(Boolean.toString(true));
// Wait for any privacy indicator to disappear to avoid the test becoming flaky.
SystemClock.sleep(INDICATOR_DISMISS_TIMEOUT);
@@ -286,4 +291,9 @@
PackageManager pm = mContext.getPackageManager();
return pm.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
}
+
+ private boolean isWatch() {
+ PackageManager pm = mContext.getPackageManager();
+ return pm.hasSystemFeature(PackageManager.FEATURE_WATCH);
+ }
}
diff --git a/tests/tests/webkit/src/android/webkit/cts/PacProcessorTest.java b/tests/tests/webkit/src/android/webkit/cts/PacProcessorTest.java
index ee6f11f..26f699d 100644
--- a/tests/tests/webkit/src/android/webkit/cts/PacProcessorTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/PacProcessorTest.java
@@ -20,11 +20,13 @@
import android.net.ConnectivityManager;
import android.net.Network;
import android.webkit.PacProcessor;
+import com.android.compatibility.common.util.NullWebViewUtils;
import androidx.test.platform.app.InstrumentationRegistry;
import org.junit.After;
import org.junit.Assert;
+import org.junit.Assume;
import org.junit.Before;
import org.junit.Test;
@@ -79,6 +81,7 @@
*/
@Test
public void testCreatePacProcessor() throws Throwable {
+ Assume.assumeTrue("WebView is not available", NullWebViewUtils.isWebViewAvailable());
mProcess.run(TestCreatePacProcessor.class);
}
@@ -97,6 +100,7 @@
*/
@Test
public void testDefaultNetworkIsNull() throws Throwable {
+ Assume.assumeTrue("WebView is not available", NullWebViewUtils.isWebViewAvailable());
mProcess.run(TestDefaultNetworkIsNull.class);
}
@@ -131,6 +135,7 @@
*/
@Test
public void testSetNetwork() throws Throwable {
+ Assume.assumeTrue("WebView is not available", NullWebViewUtils.isWebViewAvailable());
mProcess.run(TestSetNetwork.class);
}
}
diff --git a/tests/tests/widget/res/layout-round/edittext_layout.xml b/tests/tests/widget/res/layout-round/edittext_layout.xml
index 4f7f62b..1213d65 100644
--- a/tests/tests/widget/res/layout-round/edittext_layout.xml
+++ b/tests/tests/widget/res/layout-round/edittext_layout.xml
@@ -56,5 +56,12 @@
android:autoSizeTextType="uniform"
android:textSize="50dp"
android:autoSizeStepGranularity="2dp" />
+
+ <EditText
+ android:id="@+id/edittext_conversion_suggestion"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:inputType="textEnableTextConversionSuggestions"
+ android:text="@string/edit_text" />
</LinearLayout>
</ScrollView>
diff --git a/tests/tests/widget/res/values/themes.xml b/tests/tests/widget/res/values/themes.xml
index bbce31f..938452e 100644
--- a/tests/tests/widget/res/values/themes.xml
+++ b/tests/tests/widget/res/values/themes.xml
@@ -24,4 +24,8 @@
<item name="themeColor">@color/remoteviews_theme_color</item>
<item name="themeString">@string/remoteviews_theme_string</item>
</style>
-</resources>
\ No newline at end of file
+
+ <style name="HorizontalScrollViewCtsActivityTheme" parent="@android:style/Theme.DeviceDefault">
+ <item name="android:windowSwipeToDismiss">false</item>
+ </style>
+</resources>
diff --git a/tests/tests/widget/src/android/widget/cts/HorizontalScrollViewCtsActivity.java b/tests/tests/widget/src/android/widget/cts/HorizontalScrollViewCtsActivity.java
index 96d8279..489aa54 100644
--- a/tests/tests/widget/src/android/widget/cts/HorizontalScrollViewCtsActivity.java
+++ b/tests/tests/widget/src/android/widget/cts/HorizontalScrollViewCtsActivity.java
@@ -24,6 +24,7 @@
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ setTheme(R.style.HorizontalScrollViewCtsActivityTheme);
setContentView(R.layout.horizontal_scrollview);
}
}
diff --git a/tools/cts-tradefed/Android.bp b/tools/cts-tradefed/Android.bp
index 0811941..e50b6b4 100644
--- a/tools/cts-tradefed/Android.bp
+++ b/tools/cts-tradefed/Android.bp
@@ -34,7 +34,7 @@
wrapper: "etc/cts-tradefed",
short_name: "CTS",
full_name: "Compatibility Test Suite",
- version: "13_r3",
+ version: "13_r4",
static_libs: ["cts-tradefed-harness"],
required: ["compatibility-host-util"],
}
diff --git a/tools/cts-tradefed/res/config/cts-on-gsi-on-r.xml b/tools/cts-tradefed/res/config/cts-on-gsi-on-r.xml
index be375f0..2800406c 100644
--- a/tools/cts-tradefed/res/config/cts-on-gsi-on-r.xml
+++ b/tools/cts-tradefed/res/config/cts-on-gsi-on-r.xml
@@ -29,7 +29,13 @@
<!-- Excluded test cases start-->
- <!-- b/240971401 -->
+ <!-- CtsLocationPrivilegedTestCases: b/240971401 -->
<option name="compatibility:exclude-filter" value="CtsLocationPrivilegedTestCases android.location.cts.privileged.GnssLocationValuesTest#testLowPowerModeGnssLocation" />
+ <!-- CtsMediaTranscodingTestCases: b/257522539 -->
+ <option name="compatibility:exclude-filter" value="CtsMediaTranscodingTestCases android.media.mediatranscoding.cts.MediaTranscodingManagerTest#testAvcTranscoding1080PVideo30FramesWithoutAudio" />
+ <!-- CtsSecurityTestCases: b/241000034 -->
+ <option name="compatibility:exclude-filter" value="CtsSecurityTestCases android.security.cts.VerifiedBootTest#testVerifiedBootSupport" />
+ <!-- CtsKeystoreTestCases: b/218751802 -->
+ <option name="compatibility:exclude-filter" value="CtsKeystoreTestCases android.keystore.cts.KeyAttestationTest#testAttestationKmVersionMatchesFeatureVersionStrongBox" />
</configuration>
diff --git a/tools/cts-tradefed/res/config/cts-on-gsi-on-s.xml b/tools/cts-tradefed/res/config/cts-on-gsi-on-s.xml
index 2057484..0b48b68 100644
--- a/tools/cts-tradefed/res/config/cts-on-gsi-on-s.xml
+++ b/tools/cts-tradefed/res/config/cts-on-gsi-on-s.xml
@@ -29,14 +29,13 @@
<!-- Excluded test cases start-->
- <!-- b/257492672 -->
+ <!-- CtsMediaV2TestCases: b/257492672, b/257492847, b/258826057, b/241293905, b/257493109 -->
<option name="compatibility:exclude-filter" value="CtsMediaV2TestCases android.mediav2.cts.CodecDecoderTest#testReconfigure" />
- <!-- b/257553257 -->
+ <!-- CtsOsTestCases: b/257553257 -->
<option name="compatibility:exclude-filter" value="CtsOsTestCases android.os.cts.VibratorTest#testVibrateWaveformWithFrequencyStartsAndFinishesVibration" />
<option name="compatibility:exclude-filter" value="CtsOsTestCases android.os.cts.VibratorTest#testVibratorFrequencyProfileSupportedFrequencyRange" />
<option name="compatibility:exclude-filter" value="CtsOsTestCases android.os.cts.VibratorTest#testVibratorFrequencyProfileMeasurementInterval" />
- <!-- b/257492847 -->
- <option name="compatibility:exclude-filter" value="CtsMediaV2TestCases android.mediav2.cts.CodecDecoderTest#testSimpleDecodeQueueCSD" />
- <option name="compatibility:exclude-filter" value="CtsMediaV2TestCases android.mediav2.cts.CodecDecoderTest#testSimpleDecode" />
+ <!-- CtsKeystoreTestCases: b/258826404 -->
+ <option name="compatibility:exclude-filter" value="CtsKeystoreTestCases android.keystore.cts.NoAttestKeyTest#testEcAttestKeyFail" />
</configuration>