Merge "cts: skip audio routing test for automotive products" into android15-tests-dev
diff --git a/apps/CameraITS/config.yml b/apps/CameraITS/config.yml
index 27c960a..59ee64b 100644
--- a/apps/CameraITS/config.yml
+++ b/apps/CameraITS/config.yml
@@ -55,4 +55,4 @@
lighting_cntl: <controller-type> # can be arduino or "None"
lighting_ch: <controller-channel>
scene: "checkerboard" # "checkerboard" for both SF and scene_flash
-
+ parallel_execution: "True" # "False" for low-performance hosts
diff --git a/apps/CameraITS/tests/feature_combination/test_feature_combination.py b/apps/CameraITS/tests/feature_combination/test_feature_combination.py
index 6152adb..69f547a 100644
--- a/apps/CameraITS/tests/feature_combination/test_feature_combination.py
+++ b/apps/CameraITS/tests/feature_combination/test_feature_combination.py
@@ -277,6 +277,9 @@
future = executor.submit(
preview_processing_utils.verify_preview_stabilization,
recording_obj, gyro_events, _NAME, log_path, facing)
+ # Get result from future before continuing if desired
+ if not self.parallel_execution:
+ future.result()
preview_verification_futures.append(future)
combination_names.append(combination_name)
diff --git a/apps/CameraITS/tests/its_base_test.py b/apps/CameraITS/tests/its_base_test.py
index 1fdb7db..6f09860 100644
--- a/apps/CameraITS/tests/its_base_test.py
+++ b/apps/CameraITS/tests/its_base_test.py
@@ -74,6 +74,9 @@
self.debug_mode = self.user_params['debug_mode'] == 'True'
if self.user_params.get('scene'):
self.scene = self.user_params['scene']
+ self.parallel_execution = (
+ self.user_params.get('parallel_execution', 'True') == 'True'
+ )
camera_id_combo = self.parse_hidden_camera_id()
self.camera_id = camera_id_combo[0]
if len(camera_id_combo) == 2:
diff --git a/apps/CameraITS/tests/scene1_1/test_ev_compensation_advanced.py b/apps/CameraITS/tests/scene1_1/test_ev_compensation_advanced.py
index 463fc0f..ca83031 100644
--- a/apps/CameraITS/tests/scene1_1/test_ev_compensation_advanced.py
+++ b/apps/CameraITS/tests/scene1_1/test_ev_compensation_advanced.py
@@ -31,6 +31,7 @@
_LOCKED = 3
_LUMA_DELTA_ATOL = 0.05
_LUMA_DELTA_ATOL_SAT = 0.10
+_LUMA_DELTA_ATOL_SAT_UW = 0.15 # higher tol to compensate for less chart area
_LUMA_SAT_THRESH = 0.75 # luma value at which ATOL changes from MID to SAT
_NAME = os.path.splitext(os.path.basename(__file__))[0]
_PATCH_H = 0.1 # center 10%
@@ -38,6 +39,7 @@
_PATCH_X = 0.5 - _PATCH_W/2
_PATCH_Y = 0.5 - _PATCH_H/2
_THRESH_CONVERGE_FOR_EV = 8 # AE must converge within this num auto reqs for EV
+_UW_FOV_THRESHOLD = 90 # degrees
def create_request_with_ev(ev):
@@ -136,8 +138,10 @@
i_mid = len(ev_steps) // 2
luma_normal = lumas[i_mid] / ev_shifts[i_mid]
expected_lumas = [min(1.0, luma_normal*shift) for shift in ev_shifts]
+ luma_delta_sat_atol = _LUMA_DELTA_ATOL_SAT_UW if float(
+ cam.calc_camera_fov(props)) > _UW_FOV_THRESHOLD else _LUMA_DELTA_ATOL
luma_delta_atols = [_LUMA_DELTA_ATOL if l < _LUMA_SAT_THRESH
- else _LUMA_DELTA_ATOL_SAT for l in expected_lumas]
+ else luma_delta_sat_atol for l in expected_lumas]
# Create plot
pylab.figure(_NAME)
diff --git a/apps/CameraITS/utils/ui_interaction_utils.py b/apps/CameraITS/utils/ui_interaction_utils.py
index 5f85cfe..517f470 100644
--- a/apps/CameraITS/utils/ui_interaction_utils.py
+++ b/apps/CameraITS/utils/ui_interaction_utils.py
@@ -36,6 +36,7 @@
CAMERA_FILES_PATHS = ('/sdcard/DCIM/Camera',
'/storage/emulated/0/Pictures')
CAPTURE_BUTTON_RESOURCE_ID = 'CaptureButton'
+DEFAULT_CAMERA_CONTENT_DESC_SEPARATOR = ','
DONE_BUTTON_TXT = 'Done'
FLASH_MODE_TO_CLICKS = types.MappingProxyType({
'OFF': 3,
@@ -162,6 +163,27 @@
its_device_utils.run_adb_shell_command(device_id, allow_manage_storage_cmd)
+def _get_current_camera_facing(content_desc, resource_id):
+ """Returns the current camera facing based on UI elements."""
+ # If separator is present, the last element is the current camera facing.
+ if DEFAULT_CAMERA_CONTENT_DESC_SEPARATOR in content_desc:
+ current_facing = content_desc.split(
+ DEFAULT_CAMERA_CONTENT_DESC_SEPARATOR)[-1]
+ if 'rear' in current_facing.lower() or 'back' in current_facing.lower():
+ return 'rear'
+ elif 'front' in current_facing.lower():
+ return 'front'
+
+ # If separator is not present, the element describes the other camera facing.
+ if ('rear' in content_desc.lower() or 'rear' in resource_id.lower()
+ or 'back' in content_desc.lower() or 'back' in resource_id.lower()):
+ return 'front'
+ elif 'front' in content_desc.lower() or 'front' in resource_id.lower():
+ return 'rear'
+ else:
+ raise ValueError('Failed to determine current camera facing.')
+
+
def switch_default_camera(dut, facing, log_path):
"""Interacts with default camera app UI to switch camera.
@@ -179,7 +201,6 @@
default_ui_dump = dut.ui.dump()
logging.debug('Default camera UI dump: %s', default_ui_dump)
root = et.fromstring(default_ui_dump)
- camera_flip_res = False
for node in root.iter('node'):
resource_id = node.get('resource-id')
content_desc = node.get('content-desc')
@@ -189,31 +210,18 @@
logging.debug('Pattern matches')
logging.debug('Resource id: %s', resource_id)
logging.debug('Flip camera content-desc: %s', content_desc)
- camera_flip_res = True
break
- if content_desc and resource_id:
- if facing == 'front' and camera_flip_res:
- if ('rear' in content_desc.lower() or 'rear' in resource_id.lower()
- or 'back' in content_desc.lower() or 'back' in resource_id.lower()
- ):
- logging.debug('Pattern found but camera is already switched.')
- else:
- dut.ui(desc=content_desc).click.wait()
- elif facing == 'rear' and camera_flip_res:
- if 'front' in content_desc.lower() or 'front' in resource_id.lower():
- logging.debug('Pattern found but camera is already switched.')
- else:
- dut.ui(desc=content_desc).click.wait()
- else:
- raise ValueError(f'Unknown facing: {facing}')
+ else:
+ raise AssertionError('Flip camera resource not found.')
+ if facing == _get_current_camera_facing(content_desc, resource_id):
+ logging.debug('Pattern found but camera is already switched.')
+ else:
+ dut.ui(desc=content_desc).click.wait()
dut.take_screenshot(
log_path, prefix=f'switched_to_{facing}_default_camera'
)
- if not camera_flip_res:
- raise AssertionError('Flip camera resource not found.')
-
def pull_img_files(device_id, input_path, output_path):
"""Pulls files from the input_path on the device to output_path.
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index 12d1fad..6c58a42 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="15_r3">
+ android:versionName="15_r4">
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="35"/>
diff --git a/apps/CtsVerifier/jni/audio_loopback/Android.bp b/apps/CtsVerifier/jni/audio_loopback/Android.bp
index f3c0e98..f011816 100644
--- a/apps/CtsVerifier/jni/audio_loopback/Android.bp
+++ b/apps/CtsVerifier/jni/audio_loopback/Android.bp
@@ -7,6 +7,8 @@
srcs: [
"jni-bridge.cpp",
"NativeAudioAnalyzer.cpp",
+ "WaveFileWriter.cpp",
+ "WavFileCapture.cpp",
],
include_dirs: [
"system/core/include/cutils",
diff --git a/apps/CtsVerifier/jni/audio_loopback/NativeAudioAnalyzer.cpp b/apps/CtsVerifier/jni/audio_loopback/NativeAudioAnalyzer.cpp
index e765e64..c84052e 100644
--- a/apps/CtsVerifier/jni/audio_loopback/NativeAudioAnalyzer.cpp
+++ b/apps/CtsVerifier/jni/audio_loopback/NativeAudioAnalyzer.cpp
@@ -16,6 +16,10 @@
#include "NativeAudioAnalyzer.h"
+#include "WavFileCapture.h"
+
+extern WavFileCapture sWavFileCapture;
+
static void convertPcm16ToFloat(const int16_t *source,
float *destination,
int32_t numSamples) {
@@ -168,6 +172,8 @@
mActualOutputChannelCount,
numFrames);
+ sWavFileCapture.captureData(audioData, numFrames);
+
mIsDone = mLoopbackProcessor->isDone();
if (mIsDone) {
callbackResult = AAUDIO_CALLBACK_RESULT_STOP;
diff --git a/apps/CtsVerifier/jni/audio_loopback/WavCaptureOutputStream.h b/apps/CtsVerifier/jni/audio_loopback/WavCaptureOutputStream.h
new file mode 100644
index 0000000..f0e91f9
--- /dev/null
+++ b/apps/CtsVerifier/jni/audio_loopback/WavCaptureOutputStream.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2024 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.
+ */
+
+#ifndef __WAVCAPTUREOUTPUTSTREAM_H__
+#define __WAVCAPTUREOUTPUTSTREAM_H__
+
+#include "WaveFileWriter.h"
+
+#include <vector>
+
+class WavCaptureOutputStream : public WaveFileOutputStream {
+public:
+ WavCaptureOutputStream() {
+ }
+
+ void init() {
+ mData.clear();
+ }
+
+ void write(uint8_t b) override {
+ mData.push_back(b);
+ }
+
+ void write(uint8_t* bytes, size_t numBytes) {
+ while (numBytes-- > 0) {
+ mData.push_back(*bytes++);
+ }
+ }
+
+ int32_t length() {
+ return (int32_t) mData.size();
+ }
+
+ uint8_t *getData() {
+ return mData.data();
+ }
+
+ void abandonData() {
+ mData.clear();
+ }
+private:
+ std::vector<uint8_t> mData;
+};
+
+#endif
diff --git a/apps/CtsVerifier/jni/audio_loopback/WavFileCapture.cpp b/apps/CtsVerifier/jni/audio_loopback/WavFileCapture.cpp
new file mode 100644
index 0000000..548c5db
--- /dev/null
+++ b/apps/CtsVerifier/jni/audio_loopback/WavFileCapture.cpp
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <android/log.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+
+#include "WavFileCapture.h"
+#include "WavCaptureOutputStream.h"
+
+const char * TAG = "WavFileCapture";
+
+WavFileCapture sWavFileCapture;
+
+WavFileCapture::WavFileCapture() : mCaptureActive(false) {
+ mOutputStream = new WavCaptureOutputStream();
+ mWavFileWriter = new WaveFileWriter(mOutputStream);
+}
+
+WavFileCapture::~WavFileCapture() {
+ delete mOutputStream;
+ delete mWavFileWriter;
+}
+
+void WavFileCapture::setCaptureFile(const char* wavFilePath) {
+ mWavCapturePath = wavFilePath;
+}
+
+void WavFileCapture::setWavSpec(int numChannels, int sampleRate) {
+ mNumChannels = numChannels;
+ mSampleRate = sampleRate;
+}
+
+void WavFileCapture::startCapture() {
+ mOutputStream->init();
+ mWavFileWriter->reset();
+ mCaptureActive = true;
+}
+
+int WavFileCapture::completeCapture() {
+ if (!mCaptureActive) {
+ return CAPTURE_NOTDONE;
+ }
+
+ int returnVal;
+ FILE* file = fopen(mWavCapturePath.c_str(), "w");
+ if (file == nullptr) {
+ __android_log_print(ANDROID_LOG_ERROR, TAG,
+ "error opening capture file: %s", mWavCapturePath.c_str());
+ returnVal = CAPTURE_BADOPEN;
+ } else {
+ int numWriteBytes = mOutputStream->length();
+ int numWrittenBytes =
+ fwrite(mOutputStream->getData(), sizeof(uint8_t), numWriteBytes, file);
+ if (numWrittenBytes != numWriteBytes) {
+ __android_log_print(ANDROID_LOG_ERROR, TAG,
+ "error writing capture file: %s", mWavCapturePath.c_str());
+ returnVal = CAPTURE_BADWRITE;
+ } else {
+ returnVal = CAPTURE_SUCCESS;
+ }
+ fclose(file);
+ }
+ mCaptureActive = false;
+
+ return returnVal;
+}
+
+void WavFileCapture::abandonCaptureData() {
+ // TODO: implement when we have a caller for this.
+ mCaptureActive = false;
+}
+
+void WavFileCapture::captureData(void *audioData, int32_t numFrames) {
+ if (mCaptureActive) {
+ mWavFileWriter->write((float*)audioData, 0, numFrames /* * numChannels? */);
+ }
+}
+
+/*
+ * JNI Interface
+ */
+#include <jni.h>
+
+extern "C" {
+
+JNIEXPORT jlong JNICALL
+ Java_com_android_cts_verifier_audio_audiolib_WavFileCapture_getCapture_1n() {
+ return (jlong)&sWavFileCapture;
+}
+
+JNIEXPORT void JNICALL
+ Java_com_android_cts_verifier_audio_audiolib_WavFileCapture_setCaptureFile_1n(
+ JNIEnv *env __unused, jobject obj __unused, jlong wavCaptureObj, jstring wavFilePath) {
+ WavFileCapture* capture = (WavFileCapture*)wavCaptureObj;
+
+ const char *captureFile = env->GetStringUTFChars(wavFilePath, 0);
+ capture->setCaptureFile(captureFile);
+
+ env->ReleaseStringUTFChars(wavFilePath, captureFile);
+}
+
+JNIEXPORT void JNICALL
+ Java_com_android_cts_verifier_audio_audiolib_WavFileCapture_setWavSpec_1n(
+ JNIEnv *env __unused, jobject obj __unused, jlong wavCaptureObj, jint numChannels, jint sampleRate) {
+ WavFileCapture* capture = (WavFileCapture*)wavCaptureObj;
+ capture->setWavSpec(numChannels, sampleRate);
+}
+
+JNIEXPORT void JNICALL
+ Java_com_android_cts_verifier_audio_audiolib_WavFileCapture_startCapture_1n(
+ JNIEnv *env __unused, jobject obj __unused, jlong wavCaptureObj) {
+ WavFileCapture* capture = (WavFileCapture*)wavCaptureObj;
+ capture->startCapture();
+}
+
+JNIEXPORT jint JNICALL
+ Java_com_android_cts_verifier_audio_audiolib_WavFileCapture_completeCapture_1n(
+ JNIEnv *env __unused, jobject obj __unused, jlong wavCaptureObj) {
+ WavFileCapture* capture = (WavFileCapture*)wavCaptureObj;
+ return capture->completeCapture();
+}
+
+JNIEXPORT void JNICALL
+ Java_com_android_cts_verifier_audio_audiolib_WavFileCapture_abandonCapture_n(
+ JNIEnv *env __unused, jobject obj __unused, jlong wavCaptureObj) {
+ WavFileCapture* capture = (WavFileCapture*)wavCaptureObj;
+ capture->abandonCaptureData();
+}
+
+} // extern "C"
diff --git a/apps/CtsVerifier/jni/audio_loopback/WavFileCapture.h b/apps/CtsVerifier/jni/audio_loopback/WavFileCapture.h
new file mode 100644
index 0000000..671a849
--- /dev/null
+++ b/apps/CtsVerifier/jni/audio_loopback/WavFileCapture.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2024 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.
+ */
+
+#ifndef __WAVFILECAPTURE_H__
+#define __WAVFILECAPTURE_H__
+
+#include <string>
+
+class WaveFileWriter;
+class WavCaptureOutputStream;
+
+class WavFileCapture {
+public:
+ WavFileCapture();
+ ~WavFileCapture();
+
+ void setCaptureFile(const char* wavFilePath);
+ void setWavSpec(int numChannels, int sampleRate);
+
+ void startCapture();
+
+ /*
+ * completeCapture() status codes.
+ * Note: These need to be kept in sync with the equivalent constants
+ * in WavFileCapture.java.
+ */
+ static const int CAPTURE_NOTDONE = 1;
+ static const int CAPTURE_SUCCESS = 0;
+ static const int CAPTURE_BADOPEN = -1;
+ static const int CAPTURE_BADWRITE = -2;
+ int completeCapture();
+ void abandonCaptureData();
+
+ void captureData(void *audioData, int32_t numFrames);
+
+private:
+ std::string mWavCapturePath;
+
+ int mNumChannels;
+ int mSampleRate;
+
+ bool mCaptureActive;
+
+ WaveFileWriter* mWavFileWriter;
+ WavCaptureOutputStream* mOutputStream;
+};
+
+#endif // __WAVFILECAPTURE_H__
+
diff --git a/apps/CtsVerifier/jni/audio_loopback/WaveFileWriter.cpp b/apps/CtsVerifier/jni/audio_loopback/WaveFileWriter.cpp
new file mode 100644
index 0000000..4a244d0
--- /dev/null
+++ b/apps/CtsVerifier/jni/audio_loopback/WaveFileWriter.cpp
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "WaveFileWriter.h"
+
+#include <android/log.h>
+
+void WaveFileWriter::write(float value) {
+ if (!headerWritten) {
+ writeHeader();
+ }
+ if (bitsPerSample == 24) {
+ writePCM24(value);
+ } else {
+ writePCM16(value);
+ }
+}
+
+void WaveFileWriter::write(float *buffer, int32_t startSample, int32_t numSamples) {
+ for (int32_t i = 0; i < numSamples; i++) {
+ write(buffer[startSample + i]);
+ }
+}
+
+void WaveFileWriter::writeIntLittle(int32_t n) {
+ writeByte(n);
+ writeByte(n >> 8);
+ writeByte(n >> 16);
+ writeByte(n >> 24);
+}
+
+void WaveFileWriter::writeShortLittle(int16_t n) {
+ writeByte(n);
+ writeByte(n >> 8);
+}
+
+void WaveFileWriter::writeFormatChunk() {
+ int32_t bytesPerSample = (bitsPerSample + 7) / 8;
+
+ writeByte('f');
+ writeByte('m');
+ writeByte('t');
+ writeByte(' ');
+ writeIntLittle(16); // chunk size
+ writeShortLittle(WAVE_FORMAT_PCM);
+ writeShortLittle((int16_t) mSamplesPerFrame);
+ writeIntLittle(mFrameRate);
+ // bytes/second
+ writeIntLittle(mFrameRate * mSamplesPerFrame * bytesPerSample);
+ // block align
+ writeShortLittle((int16_t) (mSamplesPerFrame * bytesPerSample));
+ writeShortLittle((int16_t) bitsPerSample);
+}
+
+void WaveFileWriter::writeDataChunkHeader() {
+ writeByte('d');
+ writeByte('a');
+ writeByte('t');
+ writeByte('a');
+ // Maximum size is not strictly correct but is commonly used
+ // when we do not know the final size.
+ writeIntLittle(INT32_MAX);
+}
+
+void WaveFileWriter::writeHeader() {
+ writeRiffHeader();
+ writeFormatChunk();
+ writeDataChunkHeader();
+ headerWritten = true;
+}
+
+// Write lower 8 bits. Upper bits ignored.
+void WaveFileWriter::writeByte(uint8_t b) {
+ mOutputStream->write(b);
+ bytesWritten += 1;
+}
+
+void WaveFileWriter::writePCM24(float value) {
+ // Offset before casting so that we can avoid using floor().
+ // Also round by adding 0.5 so that very small signals go to zero.
+ float temp = (PCM24_MAX * value) + 0.5 - PCM24_MIN;
+ int32_t sample = ((int) temp) + PCM24_MIN;
+ // clip to 24-bit range
+ if (sample > PCM24_MAX) {
+ sample = PCM24_MAX;
+ } else if (sample < PCM24_MIN) {
+ sample = PCM24_MIN;
+ }
+ // encode as little-endian
+ writeByte(sample); // little end
+ writeByte(sample >> 8); // middle
+ writeByte(sample >> 16); // big end
+}
+
+void WaveFileWriter::writePCM16(float value) {
+ // Offset before casting so that we can avoid using floor().
+ // Also round by adding 0.5 so that very small signals go to zero.
+ float temp = (INT16_MAX * value) + 0.5 - INT16_MIN;
+ int32_t sample = ((int) temp) + INT16_MIN;
+ if (sample > INT16_MAX) {
+ sample = INT16_MAX;
+ } else if (sample < INT16_MIN) {
+ sample = INT16_MIN;
+ }
+ writeByte(sample); // little end
+ writeByte(sample >> 8); // big end
+}
+
+void WaveFileWriter::writeRiffHeader() {
+ writeByte('R');
+ writeByte('I');
+ writeByte('F');
+ writeByte('F');
+ // Maximum size is not strictly correct but is commonly used
+ // when we do not know the final size.
+ writeIntLittle(INT32_MAX);
+ writeByte('W');
+ writeByte('A');
+ writeByte('V');
+ writeByte('E');
+}
diff --git a/apps/CtsVerifier/jni/audio_loopback/WaveFileWriter.h b/apps/CtsVerifier/jni/audio_loopback/WaveFileWriter.h
new file mode 100644
index 0000000..fcb7f93
--- /dev/null
+++ b/apps/CtsVerifier/jni/audio_loopback/WaveFileWriter.h
@@ -0,0 +1,161 @@
+/*
+ * Copyright 2024 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.
+ */
+
+// Based on the WaveFileWriter in Java from the open source JSyn library by Phil Burk
+// https://github.com/philburk/jsyn/blob/master/src/main/java/com/jsyn/util/WaveFileWriter.java
+
+#ifndef UTIL_WAVE_FILE_WRITER
+#define UTIL_WAVE_FILE_WRITER
+
+#include <cassert>
+#include <stdio.h>
+
+class WaveFileOutputStream {
+public:
+ virtual ~WaveFileOutputStream() = default;
+ virtual void write(uint8_t b) = 0;
+};
+
+/**
+ * Write audio data to a WAV file.
+ *
+ * <pre>
+ * <code>
+ * WaveFileWriter writer = new WaveFileWriter(waveFileOutputStream);
+ * writer.setFrameRate(48000);
+ * writer.setBitsPerSample(24);
+ * writer.write(floatArray, 0, numSamples);
+ * writer.close();
+ * </code>
+ * </pre>
+ *
+ */
+class WaveFileWriter {
+public:
+
+ /**
+ * Create an object that will write a WAV file image to the specified stream.
+ *
+ * @param outputStream stream to receive the bytes
+ * @throws FileNotFoundException
+ */
+ WaveFileWriter(WaveFileOutputStream *outputStream) {
+ mOutputStream = outputStream;
+ bitsPerSample = 24;
+ }
+
+ void reset() {
+ bytesWritten = 0;
+ headerWritten = false;
+ }
+
+ /**
+ * @param frameRate default is 44100
+ */
+ void setFrameRate(int32_t frameRate) {
+ mFrameRate = frameRate;
+ }
+
+ int32_t getFrameRate() const {
+ return mFrameRate;
+ }
+
+ /**
+ * For stereo, set this to 2. Default is mono = 1.
+ * Also known as ChannelCount
+ */
+ void setSamplesPerFrame(int32_t samplesPerFrame) {
+ mSamplesPerFrame = samplesPerFrame;
+ }
+
+ int32_t getSamplesPerFrame() const {
+ return mSamplesPerFrame;
+ }
+
+ /** Only 16 or 24 bit samples supported at the moment. Default is 16. */
+ void setBitsPerSample(int32_t bits) {
+ assert((bits == 16) || (bits == 24));
+ bitsPerSample = bits;
+ }
+
+ int32_t getBitsPerSample() const {
+ return bitsPerSample;
+ }
+
+ void close() {
+ }
+
+ /** Write single audio data value to the WAV capture buffer. */
+ void write(float value);
+
+ /**
+ * Write a buffer to the WAV capture buffer.
+ */
+ void write(float *buffer, int32_t startSample, int32_t numSamples);
+
+private:
+ /**
+ * Write a 32 bit integer to the stream in Little Endian format.
+ */
+ void writeIntLittle(int32_t n);
+
+ /**
+ * Write a 16 bit integer to the stream in Little Endian format.
+ */
+ void writeShortLittle(int16_t n);
+
+ /**
+ * Write an 'fmt ' chunk to the WAV file containing the given information.
+ */
+ void writeFormatChunk();
+
+ /**
+ * Write a 'data' chunk header to the WAV file. This should be followed by call to
+ * writeShortLittle() to write the data to the chunk.
+ */
+ void writeDataChunkHeader();
+
+ /**
+ * Write a simple WAV header for PCM data.
+ */
+ void writeHeader();
+
+ // Write lower 8 bits. Upper bits ignored.
+ void writeByte(uint8_t b);
+
+ void writePCM24(float value);
+
+ void writePCM16(float value);
+
+ /**
+ * Write a 'RIFF' file header and a 'WAVE' ID to the WAV file.
+ */
+ void writeRiffHeader();
+
+ static constexpr int WAVE_FORMAT_PCM = 1;
+ WaveFileOutputStream *mOutputStream = nullptr;
+ int32_t mFrameRate = 48000;
+ int32_t mSamplesPerFrame = 1;
+ int32_t bitsPerSample = 16;
+ int32_t bytesWritten = 0;
+ bool headerWritten = false;
+ static constexpr int32_t PCM24_MIN = -(1 << 23);
+ static constexpr int32_t PCM24_MAX = (1 << 23) - 1;
+
+};
+
+#endif /* UTIL_WAVE_FILE_WRITER */
+
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index 5b4bcfb..b5b19cf 100644
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -2863,9 +2863,10 @@
1. Press "Set up" to open Security settings. (If this device has a separate app for work
settings, ignore this button and open that app manually from the launcher.) Create a
lockscreen password and if available, enroll a fingerprint under "Work profile security".\n
- 2. Go through the list of tests.\n
- 3. Mark the overall test pass or fail.\n
- 4. Once the set of tests are completed, remove the lockscreen challenge.
+ 2. Ensure that work profile and device entry password and fingerprint are separate by disabling "One Lock".\n
+ 3. Go through the list of tests.\n
+ 4. Mark the overall test pass or fail.\n
+ 5. Once the set of tests are completed, remove the lockscreen challenge.
</string>
<string name="provisioning_byod_auth_bound_key_set_up">Set up</string>
<string name="provisioning_byod_lockscreen_bound_key">Lockscreen-bound key test</string>
@@ -4976,6 +4977,20 @@
\n
Use the Back button to return to this page.
</string>
+ <string name="device_owner_disallow_user_switch_info" product="automotive">
+ Press \'Create uninitialized user\' to create a user that is not setup.
+ Then press \'Set restriction\' button to set the user restriction.
+ Then press \'Go\' to open \'Users\' settings.
+ In Quick Settings, confirm that user switcher is hidden or disabled.\n
+ \n
+ The following steps apply only if the created user is visible on Users page. Confirm that:\n
+ \n
+ - Pressing on managed user opens user details page.\n
+ - \"Switch to managed user\" is disabled\n
+ - Tapping \"Switch to managed user\" shows a \"Blocked by work policy\" dialog.\n
+ \n
+ Use the Back button to return to this page.
+ </string>
<string name="device_owner_disallow_user_switch_create_user">Create uninitialized user</string>
<string name="device_owner_user_switcher_message">User switcher message</string>
@@ -5799,6 +5814,10 @@
Repeat until a sufficient confidence is achieved. When each route test is completed, the
measured and required latencies will be displayed.
\n\nWhen all test routes have passed, the test as a whole can be passed.
+ \n\nIf a route fails, the captured audio can be copied to a host computer with the "adb pull command"
+ using the \"WAV Capture Folder\" and \"Capture File\" displayed in the Results Panel.
+ \nFor example, on a typical device \"adb pull /storage/emulated/0/AudioLoopbackLatency_0.wav\"
+ will copy the audio from the Speaker/Mic path to the host computer.
</string>
<string name="audio_loopback_instructions">
Please connect a "Loopback Plug" and press "Loopback Plug Ready".
@@ -5842,7 +5861,9 @@
<string name="audio_loopback_basiclatency">Basic Latency:</string>
<string name="audio_loopback_mpclatency">MPC Latency</string>
<string name="audio_loopback_proaudiolatency">"Pro Audio Latency"</string>
-
+ <string name="audio_loopback_wavcapturefolder">WAV Capture Folder:</string>
+ <string name="audio_loopback_wavcapturefile">Capture File:</string>
+ <string name="audio_loopback_nocapture">No Capture</string>
<string name="audio_general_proaudio">Pro Audio</string>
<string name="audio_general_mpc">MCP</string>
<string name="audio_general_basicaudio">Basic Audio</string>
@@ -5933,7 +5954,7 @@
<string name="audio_mixdown_micspeaker">Mic/Speaker</string>
<string name="audio_mixdown_analogheadset">Analog Headset Jack + Loopback</string>
<string name="audio_mixdown_usbdevice">USB Interface + Loopback</string>
- <string name="audio_mixdown_usbheadset">USB Headset Adapter + Looback</string>
+ <string name="audio_mixdown_usbheadset">USB Headset Adapter + Loopback</string>
<!-- Mixdown status strings -->
<string name="audio_mixdown_invalidinput">Invalid Input.</string>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioDataPathsBaseActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioDataPathsBaseActivity.java
index cefe4dc..884a2c7 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioDataPathsBaseActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioDataPathsBaseActivity.java
@@ -26,6 +26,7 @@
import android.media.AudioManager;
import android.os.Build;
import android.os.Bundle;
+import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
@@ -42,12 +43,12 @@
import com.android.cts.verifier.audio.audiolib.AudioDeviceUtils;
import com.android.cts.verifier.audio.audiolib.AudioSystemFlags;
import com.android.cts.verifier.audio.audiolib.DisplayUtils;
+import com.android.cts.verifier.audio.audiolib.WaveFileWriter;
import com.android.cts.verifier.audio.audiolib.WaveScopeView;
import com.android.cts.verifier.libs.ui.HtmlFormatter;
import com.android.cts.verifier.libs.ui.PlainTextFormatter;
import com.android.cts.verifier.libs.ui.TextFormatter;
-// MegaAudio
import org.hyphonate.megaaudio.common.BuilderBase;
import org.hyphonate.megaaudio.common.Globals;
import org.hyphonate.megaaudio.common.StreamBase;
@@ -57,6 +58,8 @@
import org.hyphonate.megaaudio.recorder.AudioSinkProvider;
import org.hyphonate.megaaudio.recorder.sinks.AppCallback;
+import java.io.File;
+import java.io.IOException;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Calendar;
@@ -296,6 +299,8 @@
private String mSectionTitle = null;
private String mDescription = "";
+ private String mSavedFileMessage; // OK if null
+
private static final String PLAYER_FAILED_TO_GET_STRING = "Player failed to get ";
private static final String RECORDER_FAILED_TO_GET_STRING = "Recorder failed to get ";
@@ -441,6 +446,19 @@
this.mModuleIndex = index;
}
+ public void setSavedFileMessage(String s) {
+ mSavedFileMessage = s;
+ }
+
+ /**
+ * A message generated when saving a WAV file.
+ *
+ * @return message or null
+ */
+ public String getSavedFileMessage() {
+ return mSavedFileMessage;
+ }
+
public void setAnalysisType(int type) {
mAnalysisType = type;
}
@@ -966,6 +984,11 @@
}
}
textFormatter.closeItalic();
+
+ String savedFileMessage = getSavedFileMessage();
+ if (savedFileMessage != null) {
+ textFormatter.appendBreak().appendText(savedFileMessage);
+ }
} else {
// results == null
textFormatter.appendBreak()
@@ -1343,6 +1366,11 @@
}
sb.append(testModule.getTestStateString(mApi));
+
+ String savedFileMessage = testModule.getSavedFileMessage();
+ if (savedFileMessage != null) {
+ sb.append("\n").append(savedFileMessage);
+ }
testStep++;
}
mRoutesTx.setText(sb.toString());
@@ -1524,6 +1552,12 @@
if (testModule != null) {
if (testModule.canRun()) {
testModule.setTestResults(mApi, mAnalyzer);
+ if (!testModule.hasPassed(mApi)) {
+ String message = saveWaveFile(mAnalyzer, testModule.getModuleIndex());
+ testModule.setSavedFileMessage(message);
+ } else {
+ testModule.setSavedFileMessage(null); // erase any old messages
+ }
runOnUiThread(new Runnable() {
@Override
public void run() {
@@ -1607,6 +1641,35 @@
}
}
+ private String saveWaveFile(BaseSineAnalyzer mAnalyzer, int index) {
+ // Write to a directory that can be read on production builds using 'adb pull'.
+ // This works because we have WRITE_EXTERNAL_STORAGE permission.
+ File recordingDir = new File(Environment.getExternalStorageDirectory(), "verifierWaves");
+ if (!recordingDir.exists()) {
+ recordingDir.mkdir();
+ }
+ File waveFile = new File(recordingDir,
+ String.format(Locale.US, "datapaths_%03d.wav", index));
+
+ float[] data = mAnalyzer.getRecordedData();
+ int numSamples = data.length;
+ if (numSamples > 0) {
+ try {
+ WaveFileWriter writer = new WaveFileWriter(waveFile);
+ writer.setFrameRate(mAnalyzer.getSampleRate());
+ writer.setBitsPerSample(24);
+ writer.write(data);
+ writer.close();
+ return "Wrote " + numSamples + " samples to " + waveFile.getAbsolutePath();
+ } catch (IOException e) {
+ return "FAILED to save " + waveFile.getAbsolutePath()
+ + ", " + e.getMessage();
+ }
+ } else {
+ return "No recorded data!";
+ }
+ }
+
//
// Process Handling
//
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 d0fb172..44c214f 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioLoopbackLatencyActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioLoopbackLatencyActivity.java
@@ -26,6 +26,7 @@
import android.media.MediaRecorder;
import android.os.Build;
import android.os.Bundle;
+import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
@@ -49,6 +50,7 @@
import com.android.cts.verifier.audio.audiolib.AudioUtils;
import com.android.cts.verifier.audio.audiolib.DisplayUtils;
import com.android.cts.verifier.audio.audiolib.StatUtils;
+import com.android.cts.verifier.audio.audiolib.WavFileCapture;
import com.android.cts.verifier.libs.ui.HtmlFormatter;
import com.android.cts.verifier.libs.ui.TextFormatter;
@@ -58,6 +60,7 @@
import org.json.JSONException;
import org.json.JSONObject;
+import java.io.File;
import java.util.Locale;
/**
@@ -168,6 +171,10 @@
private TestSpec[] mTestSpecs = new TestSpec[NUM_TEST_ROUTES];
private volatile UsbDeviceReport mUsbDeviceReport;
+ // WAV File Stuff
+ File mFilesDir;
+ WavFileCapture mWavFileCapture;
+
class TestSpec {
private static final String TAG = "AudioLoopbackLatencyActivity.TestSpec";
// impossibly low latencies (indicating something in the test went wrong).
@@ -203,6 +210,9 @@
boolean mRouteConnected; // is the route available NOW
boolean mTestRun;
+ String mWavCaptureFileName;
+ int mCaptureCode = mWavFileCapture.CAPTURE_NOTDONE;
+
TestSpec(int routeId, double requiredConfidence) {
mRouteId = routeId;
mRequiredConfidence = requiredConfidence;
@@ -223,6 +233,12 @@
mTestStatusText.setVisibility(View.VISIBLE);
mProgressBar.setVisibility(View.VISIBLE);
+
+ // WAV Capture
+ mWavCaptureFileName = "AudioLoopbackTest_" + mRouteId + ".wav";
+ mWavFileCapture.setCaptureFile(mFilesDir.getPath() + "/" + mWavCaptureFileName);
+ mWavFileCapture.setWavSpec(/*numChannels*/ 1, mSampleRate);
+ mWavFileCapture.startCapture();
}
void recordPhase(int phase, double latencyMS, double confidence,
@@ -259,6 +275,8 @@
mTestStatusText.setVisibility(View.GONE);
mProgressBar.setVisibility(View.GONE);
+
+ mCaptureCode = mWavFileCapture.completeCapture();
}
boolean isMeasurementValid() {
@@ -568,6 +586,10 @@
mConnectListener = new ConnectListener();
+ // WAV Capture
+ mFilesDir = Environment.getExternalStorageDirectory();
+ mWavFileCapture = new WavFileCapture();
+
showRouteStatus();
showTestInstructions();
handleTestCompletion(false);
@@ -1198,6 +1220,25 @@
return pass;
}
+ private void reportCapture(TextFormatter textFormatter, int pathId) {
+ if (mTestSpecs[pathId].mCaptureCode == WavFileCapture.CAPTURE_SUCCESS) {
+ textFormatter.appendBreak()
+ .appendText(getString(R.string.audio_loopback_wavcapturefile) + " "
+ + mTestSpecs[pathId].mWavCaptureFileName);
+ } else {
+ if (mTestSpecs[pathId].mWavCaptureFileName == null) {
+ textFormatter.appendBreak()
+ .appendText(getString(R.string.audio_loopback_nocapture));
+ } else {
+ textFormatter.appendBreak()
+ .openBold()
+ .appendText(getString(R.string.audio_loopback_nocapture)
+ + ": " + mTestSpecs[pathId].mWavCaptureFileName)
+ .closeBold();
+ }
+ }
+ }
+
private void buildResultsPanel(boolean proAudio, int mediaPerformanceClass) {
// We will want to think about non-WebView devices
TextFormatter textFormatter = new HtmlFormatter();
@@ -1262,6 +1303,12 @@
.appendBreak();
}
+ textFormatter.appendBreak()
+ .appendText(getString(R.string.audio_loopback_wavcapturefolder))
+ .appendBreak()
+ .appendText(mFilesDir.getPath())
+ .appendBreak();
+
/*
* Speaker/Mic route
*/
@@ -1296,6 +1343,9 @@
textFormatter.appendText(getString(R.string.ctsv_general_failsuffix));
}
}
+
+ // Capture Info
+ reportCapture(textFormatter, TESTROUTE_DEVICE);
textFormatter.closeParagraph();
/*
@@ -1348,6 +1398,9 @@
}
textFormatter.closeItalic();
}
+
+ // Capture Info
+ reportCapture(textFormatter, TESTROUTE_ANALOG_JACK);
textFormatter.closeParagraph();
/*
@@ -1398,6 +1451,9 @@
}
textFormatter.closeItalic();
}
+
+ // Capture Info
+ reportCapture(textFormatter, TESTROUTE_USB);
textFormatter.closeParagraph();
textFormatter.openParagraph();
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/analyzers/BaseSineAnalyzer.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/analyzers/BaseSineAnalyzer.java
index 0d47f9e..e99482c 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/analyzers/BaseSineAnalyzer.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/analyzers/BaseSineAnalyzer.java
@@ -78,7 +78,7 @@
MagnitudePhase mMagPhase = new MagnitudePhase();
- InfiniteRecording mInfiniteRecording = new InfiniteRecording(64 * 1024);
+ InfiniteRecording mInfiniteRecording = new InfiniteRecording(10 * 48000);
enum RESULT_CODE {
RESULT_OK,
@@ -181,6 +181,14 @@
mCosAccumulator = 0.0;
}
+ /**
+ * Get the audio data recorded during the analysis.
+ * @return recorded data
+ */
+ public float[] getRecordedData() {
+ return mInfiniteRecording.readAll();
+ }
+
class MagnitudePhase {
public double mMagnitude;
public double mPhase;
@@ -262,13 +270,13 @@
}
/**
- * @param frameData contains microphone data with sine signal feedback
- * @param channelCount
+ * @param audioData contains microphone data with sine signal feedback
+ * @param offset in the audioData to the sample
*/
- RESULT_CODE processInputFrame(float[] frameData, int offset) {
+ RESULT_CODE processInputFrame(float[] audioData, int offset) {
RESULT_CODE result = RESULT_CODE.RESULT_OK;
- float sample = frameData[offset];
+ float sample = audioData[offset];
mInfiniteRecording.write(sample);
if (transformSample(sample, mOutputPhase)) {
@@ -317,6 +325,8 @@
mPhaseErrorCount = 0.0;
updatePhaseIncrement();
+
+ mInfiniteRecording.clear();
}
@Override
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/analyzers/InfiniteRecording.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/analyzers/InfiniteRecording.java
index e403184..a75008b 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/analyzers/InfiniteRecording.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/analyzers/InfiniteRecording.java
@@ -53,16 +53,28 @@
// copy (InputIterator first, InputIterator last, OutputIterator result)
// std::copy(&mData[offset], &mData[offset + firstReadSize], buffer);
// arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
- System.arraycopy(mData, offset, mData, offset + firstReadSize, firstReadSize);
+ System.arraycopy(mData, offset, buffer, 0, firstReadSize);
if (firstReadSize < numToRead) {
// Second read needed.
// std::copy(&mData[0], &mData[numToRead - firstReadSize], &buffer[firstReadSize]);
- System.arraycopy(mData, 0, mData, numToRead - firstReadSize, numToRead - firstReadSize);
+ System.arraycopy(mData, 0, buffer, firstReadSize, numToRead - firstReadSize);
}
return numToRead;
}
/**
+ * Get all the available audio data recorded during the analysis.
+ * @return recorded data
+ */
+ public float[] readAll() {
+ int numWritten = getTotalWritten();
+ int numAvailable = getAvailable();
+ float[] data = new float[numAvailable];
+ readFrom(data, numWritten - numAvailable, numAvailable);
+ return data;
+ }
+
+ /**
*
* @param sample
*/
@@ -75,9 +87,25 @@
/**
*
- * @return
+ * @return total number of samples written
*/
public int getTotalWritten() {
return mWritten.get();
}
+
+ /**
+ * Get the maximum number of frames that are available to read.
+ *
+ * @return total number of samples written or maxSamples
+ */
+ public int getAvailable() {
+ return Math.min(mMaxSamples, mWritten.get());
+ }
+
+ /**
+ * Erase the previously recorded data.
+ */
+ public void clear() {
+ mWritten.set(0);
+ }
};
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/audiolib/WavFileCapture.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/audiolib/WavFileCapture.java
new file mode 100644
index 0000000..74de7d5
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/audiolib/WavFileCapture.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.verifier.audio.audiolib;
+
+/**
+ * Implements a facility for capturing (buffering) audio data from a native stream and writing
+ * it out to a WAV format file.
+ */
+public class WavFileCapture {
+ private static final String TAG = "WavFileCapture";
+ private static final boolean LOG = false;
+
+ private long mNativeWavFileCapture;
+
+ private String mWavFilePath;
+
+ public WavFileCapture() {
+ getCapture();
+ }
+
+ /**
+ * @return a pointer to the native WavFileCapture cast to a long
+ */
+ public long getCapture() {
+ return mNativeWavFileCapture = getCapture_n();
+ }
+
+ /**
+ * Specifies the location and filename for any capture files.
+ * @param wavFileName - The full path name of the captured file.
+ */
+ public void setCaptureFile(String wavFileName) {
+ mWavFilePath = wavFileName;
+
+ setCaptureFile_n(mNativeWavFileCapture, mWavFilePath);
+ }
+
+ /**
+ * @return The name of the captured file (if any)
+ */
+ public String getWavFilePath() {
+ return mWavFilePath;
+ }
+
+ /**
+ * Specifies the format of the captured WAV file name.
+ * @param numChannels The number of channels
+ * @param sampleRate The sample rate
+ */
+ public void setWavSpec(int numChannels, int sampleRate) {
+ setWavSpec_n(mNativeWavFileCapture, numChannels, sampleRate);
+ }
+
+ /**
+ * Starts the capture process
+ */
+ public void startCapture() {
+ startCapture_n(mNativeWavFileCapture);
+ }
+
+ /**
+ * completeCapture() status codes.
+ * Note: These need to be kept in sync with the equivalent constants
+ * in WavFileCapture.h.
+ */
+ public static final int CAPTURE_NOTDONE = 1;
+ public static final int CAPTURE_SUCCESS = 0;
+ public static final int CAPTURE_BADOPEN = -1;
+ public static final int CAPTURE_BADWRITE = -2;
+ /**
+ * Finishes the capture process and saves the captured WAV data
+ * @return a return code (from above) indicating the result of the file save.
+ */
+ public int completeCapture() {
+ return completeCapture_n(mNativeWavFileCapture);
+ }
+
+ /**
+ * Abandons the capture process. Discards any captured WAV data.
+ */
+ public void abandonCaptureData() {
+ abandonCaptureData_n(mNativeWavFileCapture);
+ }
+
+ /*
+ * JNI Interface
+ */
+ private native long getCapture_n();
+ private native void setCaptureFile_n(long wavCaptureObj, String wavFilePath);
+ private native void setWavSpec_n(long wavCaptureObj, int numChannels, int sampleRate);
+
+ private native void startCapture_n(long wavCaptureObj);
+ private native int completeCapture_n(long wavCaptureObj);
+ private native void abandonCaptureData_n(long wavCaptureObj);
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/audiolib/WaveFileWriter.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/audiolib/WaveFileWriter.java
new file mode 100644
index 0000000..16a230f1
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/audiolib/WaveFileWriter.java
@@ -0,0 +1,291 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.verifier.audio.audiolib;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.RandomAccessFile;
+
+
+/**
+ * Write audio data to a WAV file.
+ *
+ * <pre>
+ * <code>
+ * WaveFileWriter writer = new WaveFileWriter(file);
+ * writer.setFrameRate(22050);
+ * writer.setBitsPerSample(24);
+ * writer.write(floatArray);
+ * writer.close();
+ * </code>
+ * </pre>
+ *
+ * This was borrowed with Phil Burk's permission from JSyn at:
+ * https://github.com/philburk/jsyn/blob/master/src/main/java/com/jsyn/util/WaveFileWriter.java
+ */
+public class WaveFileWriter {
+
+ private static final short WAVE_FORMAT_PCM = 1;
+ private static final int PCM24_MIN = -(1 << 23);
+ private static final int PCM24_MAX = (1 << 23) - 1;
+
+ private final OutputStream mOutputStream;
+ private long mRiffSizePosition = 0;
+ private long mDataSizePosition = 0;
+ private int mFrameRate = 44100;
+ private int mSamplesPerFrame = 1;
+ private int mBitsPerSample = 16;
+ private int mBytesWritten;
+ private final File mOutputFile;
+ private boolean mHeaderWritten = false;
+
+ /**
+ * Create a writer that will write to the specified file.
+ */
+ public WaveFileWriter(File outputFile) throws FileNotFoundException {
+ mOutputFile = outputFile;
+ FileOutputStream fileOut = new FileOutputStream(outputFile);
+ mOutputStream = new BufferedOutputStream(fileOut);
+ }
+
+ /**
+ * @param frameRate default is 44100
+ */
+ public void setFrameRate(int frameRate) {
+ mFrameRate = frameRate;
+ }
+
+ public int getFrameRate() {
+ return mFrameRate;
+ }
+
+ /**
+ * For stereo, set this to 2. Default is 1.
+ */
+ public void setSamplesPerFrame(int samplesPerFrame) {
+ mSamplesPerFrame = samplesPerFrame;
+ }
+
+ public int getSamplesPerFrame() {
+ return mSamplesPerFrame;
+ }
+
+ /**
+ * Only 16 or 24 bit samples supported at the moment. Default is 16.
+ */
+ public void setBitsPerSample(int bits) {
+ if ((bits != 16) && (bits != 24)) {
+ throw new IllegalArgumentException(
+ "Only 16 or 24 bits per sample allowed. Not " + bits);
+ }
+ mBitsPerSample = bits;
+ }
+
+ public int getBitsPerSample() {
+ return mBitsPerSample;
+ }
+
+ /**
+ * Close the stream and fix the chunk sizes.
+ * @throws IOException if the close fails
+ */
+ public void close() throws IOException {
+ mOutputStream.close();
+ fixSizes();
+ }
+
+ /**
+ * Write entire buffer of audio samples to the WAV file.
+ */
+ public void write(float[] buffer) throws IOException {
+ write(buffer, 0, buffer.length);
+ }
+
+ /**
+ * Write single audio data value to the WAV file.
+ */
+ public void write(float value) throws IOException {
+ if (!mHeaderWritten) {
+ writeHeader();
+ }
+
+ if (mBitsPerSample == 24) {
+ writePCM24(value);
+ } else {
+ writePCM16(value);
+ }
+ }
+
+ private void writePCM24(float value) throws IOException {
+ // Offset before casting so that we can avoid using floor().
+ // Also round by adding 0.5 so that very small signals go to zero.
+ float temp = (PCM24_MAX * value) + 0.5f - PCM24_MIN;
+ int sample = ((int) temp) + PCM24_MIN;
+ // clip to 24-bit range
+ if (sample > PCM24_MAX) {
+ sample = PCM24_MAX;
+ } else if (sample < PCM24_MIN) {
+ sample = PCM24_MIN;
+ }
+ // encode as little-endian
+ writeByte(sample); // little end
+ writeByte(sample >> 8); // middle
+ writeByte(sample >> 16); // big end
+ }
+
+ private void writePCM16(float value) throws IOException {
+ // Offset before casting so that we can avoid using floor().
+ // Also round by adding 0.5 so that very small signals go to zero.
+ float temp = (Short.MAX_VALUE * value) + 0.5f - Short.MIN_VALUE;
+ int sample = ((int) temp) + Short.MIN_VALUE;
+ if (sample > Short.MAX_VALUE) {
+ sample = Short.MAX_VALUE;
+ } else if (sample < Short.MIN_VALUE) {
+ sample = Short.MIN_VALUE;
+ }
+ writeByte(sample); // little end
+ writeByte(sample >> 8); // big end
+ }
+
+ /**
+ * Write audio to the WAV file.
+ */
+ public void write(float[] buffer, int start, int count) throws IOException {
+ for (int i = 0; i < count; i++) {
+ write(buffer[start + i]);
+ }
+ }
+
+ // Write lower 8 bits. Upper bits ignored.
+ private void writeByte(int b) throws IOException {
+ mOutputStream.write(b);
+ mBytesWritten += 1;
+ }
+
+ /**
+ * Write a 32 bit integer to the stream in Little Endian format.
+ */
+ public void writeIntLittle(int n) throws IOException {
+ writeByte(n);
+ writeByte(n >> 8);
+ writeByte(n >> 16);
+ writeByte(n >> 24);
+ }
+
+ /**
+ * Write a 16 bit integer to the stream in Little Endian format.
+ */
+ public void writeShortLittle(short n) throws IOException {
+ writeByte(n);
+ writeByte(n >> 8);
+ }
+
+ /**
+ * Write a simple WAV header for PCM data.
+ */
+ private void writeHeader() throws IOException {
+ writeRiffHeader();
+ writeFormatChunk();
+ writeDataChunkHeader();
+ mOutputStream.flush();
+ mHeaderWritten = true;
+ }
+
+ /**
+ * Write a 'RIFF' file header and a 'WAVE' ID to the WAV file.
+ */
+ private void writeRiffHeader() throws IOException {
+ writeByte('R');
+ writeByte('I');
+ writeByte('F');
+ writeByte('F');
+ mRiffSizePosition = mBytesWritten;
+ writeIntLittle(Integer.MAX_VALUE);
+ writeByte('W');
+ writeByte('A');
+ writeByte('V');
+ writeByte('E');
+ }
+
+ /**
+ * Write an 'fmt ' chunk to the WAV file containing the given information.
+ */
+ public void writeFormatChunk() throws IOException {
+ int bytesPerSample = (mBitsPerSample + 7) / 8;
+
+ writeByte('f');
+ writeByte('m');
+ writeByte('t');
+ writeByte(' ');
+ writeIntLittle(16); // chunk size
+ writeShortLittle(WAVE_FORMAT_PCM);
+ writeShortLittle((short) mSamplesPerFrame);
+ writeIntLittle(mFrameRate);
+ // bytes/second
+ writeIntLittle(mFrameRate * mSamplesPerFrame * bytesPerSample);
+ // block align
+ writeShortLittle((short) (mSamplesPerFrame * bytesPerSample));
+ writeShortLittle((short) mBitsPerSample);
+ }
+
+ /**
+ * Write a 'data' chunk header to the WAV file. This should be followed by call to
+ * writeShortLittle() to write the data to the chunk.
+ */
+ public void writeDataChunkHeader() throws IOException {
+ writeByte('d');
+ writeByte('a');
+ writeByte('t');
+ writeByte('a');
+ mDataSizePosition = mBytesWritten;
+ writeIntLittle(Integer.MAX_VALUE); // size
+ }
+
+ /**
+ * Fix RIFF and data chunk sizes based on final size. Assume data chunk is the last chunk.
+ */
+ private void fixSizes() throws IOException {
+ RandomAccessFile randomFile = new RandomAccessFile(mOutputFile, "rw");
+ try {
+ // adjust RIFF size
+ long end = mBytesWritten;
+ int riffSize = (int) (end - mRiffSizePosition) - 4;
+ randomFile.seek(mRiffSizePosition);
+ writeRandomIntLittle(randomFile, riffSize);
+ // adjust data size
+ int dataSize = (int) (end - mDataSizePosition) - 4;
+ randomFile.seek(mDataSizePosition);
+ writeRandomIntLittle(randomFile, dataSize);
+ } finally {
+ randomFile.close();
+ }
+ }
+
+ private void writeRandomIntLittle(RandomAccessFile randomFile, int n) throws IOException {
+ byte[] buffer = new byte[4];
+ buffer[0] = (byte) n;
+ buffer[1] = (byte) (n >> 8);
+ buffer[2] = (byte) (n >> 16);
+ buffer[3] = (byte) (n >> 24);
+ randomFile.write(buffer);
+ }
+
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java
index 01011b2..4c6ed89 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java
@@ -3050,7 +3050,8 @@
aeTargetFpsMax = 30;
}
return new PreviewRecorder(cameraDeviceId, videoSize, aeTargetFpsMax,
- sensorOrientation, outputFilePath, mCameraHandler, hlg10Enabled, this);
+ sensorOrientation, outputFilePath, mCameraHandler, hlg10Enabled,
+ getEncoderTimestampOffset(), this);
}
private void doStaticPreviewRecording(JSONObject cmdObj) throws JSONException, ItsException {
@@ -3276,8 +3277,10 @@
assert outputFilePath != null;
int aeTargetFpsMax = 30;
+ boolean prevSend3AResults = mSend3AResults;
try (PreviewRecorder pr = new PreviewRecorder(cameraDeviceId, previewSize, aeTargetFpsMax,
- sensorOrientation, outputFilePath, mCameraHandler, /*hlg10Enabled*/false, this)) {
+ sensorOrientation, outputFilePath, mCameraHandler, /*hlg10Enabled*/false,
+ getEncoderTimestampOffset(), this)) {
CaptureRequest.Builder reqBuilder = mCamera.createCaptureRequest(
CameraDevice.TEMPLATE_PREVIEW);
JSONObject captureReqJSON = params.getJSONObject("captureRequest");
@@ -3319,6 +3322,8 @@
} catch (InterruptedException e) {
Log.e(TAG, "doCapturePreviewFrame [error]", e);
throw new ItsException("Interrupted while recording preview", e);
+ } finally {
+ mSend3AResults = prevSend3AResults;
}
}
@@ -5169,4 +5174,15 @@
|| format == ImageFormat.JPEG_R
|| format == ImageFormat.YCBCR_P010);
}
+
+ private long getEncoderTimestampOffset() {
+ int timestampSource = mCameraCharacteristics.get(
+ CameraCharacteristics.SENSOR_INFO_TIMESTAMP_SOURCE);
+ long encoderTimestampOffset = 0;
+ if (timestampSource == CameraMetadata.SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME) {
+ long uptimeNanos = TimeUnit.MILLISECONDS.toNanos(SystemClock.uptimeMillis());
+ encoderTimestampOffset = uptimeNanos - SystemClock.elapsedRealtimeNanos();
+ }
+ return encoderTimestampOffset;
+ }
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/PreviewRecorder.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/PreviewRecorder.java
index 3533683..509fab8 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/PreviewRecorder.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/PreviewRecorder.java
@@ -147,14 +147,17 @@
private final float[] mTexRotMatrix; // length = 4
private final float[] mTransformMatrix = new float[16];
+ // An offset applied to convert from camera timestamp to codec timestamp, due to potentially
+ // different time bases (elapsedRealtime vs uptime).
+ private long mEncoderTimestampOffset;
private List<Long> mFrameTimeStamps = new ArrayList();
/**
* Initializes MediaRecorder/MediaCodec and EGL context. The result of recorded video will
* be stored in {@code outputFile}.
*/
PreviewRecorder(int cameraId, Size previewSize, int maxFps, int sensorOrientation,
- String outputFile, Handler handler, boolean hlg10Enabled, Context context)
- throws ItsException {
+ String outputFile, Handler handler, boolean hlg10Enabled, long encoderTimestampOffset,
+ Context context) throws ItsException {
// Ensure that we can record the given size
int maxSupportedResolution = ItsUtils.RESOLUTION_TO_CAMCORDER_PROFILE
.stream()
@@ -172,6 +175,7 @@
mMaxFps = maxFps;
// rotate the texture as needed by the sensor orientation
mTexRotMatrix = getRotationMatrix(sensorOrientation);
+ mEncoderTimestampOffset = encoderTimestampOffset;
ConditionVariable cv = new ConditionVariable();
cv.close();
@@ -231,18 +235,20 @@
}
try {
// Set EGL presentation time to camera timestamp
+ long timestamp = surfaceTexture.getTimestamp();
EGLExt.eglPresentationTimeANDROID(
- mEGLDisplay, mEGLRecorderSurface, surfaceTexture.getTimestamp());
+ mEGLDisplay, mEGLRecorderSurface,
+ timestamp + mEncoderTimestampOffset);
copyFrameToRecordSurface();
// Capture results are not collected for padded green frames
if (mIsPaintGreen) {
Logt.v(TAG, "Recorded frame# " + mFrameTimeStamps.size()
- + " timestamp = " + surfaceTexture.getTimestamp()
+ + " timestamp = " + timestamp
+ " with color. mIsPaintGreen = " + mIsPaintGreen);
} else {
- mFrameTimeStamps.add(surfaceTexture.getTimestamp());
+ mFrameTimeStamps.add(timestamp);
Logt.v(TAG, "Recorded frame# " + mFrameTimeStamps.size()
- + " timestamp = " + surfaceTexture.getTimestamp());
+ + " timestamp = " + timestamp);
}
} catch (ItsException e) {
Logt.e(TAG, "Failed to copy texture to recorder.", e);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/NotificationListenerVerifierActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/NotificationListenerVerifierActivity.java
index c22124b..42c267b 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/NotificationListenerVerifierActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/NotificationListenerVerifierActivity.java
@@ -1739,11 +1739,13 @@
mId1 = NOTIFICATION_ID + 1;
Notification.MessagingStyle.Message msg1 =
- new Notification.MessagingStyle.Message("text1", 0 /* timestamp */, "sender1");
+ new Notification.MessagingStyle.Message("text 1", 0 /* timestamp */,
+ "sender 1");
msg1.getExtras().putCharSequence(extrasKey1, extrasValue1);
Notification.MessagingStyle.Message msg2 =
- new Notification.MessagingStyle.Message("text2", 1 /* timestamp */, "sender2");
+ new Notification.MessagingStyle.Message("text 2", 1 /* timestamp */,
+ "sender 2");
msg2.getExtras().putCharSequence(extrasKey2, extrasValue2);
Notification.MessagingStyle style = new Notification.MessagingStyle("display_name");
@@ -1753,7 +1755,7 @@
Notification n1 =
new Notification.Builder(mContext, NOTIFICATION_CHANNEL_ID)
.setContentTitle("ClearTest 1")
- .setContentText(mTag1.toString())
+ .setContentText("Content Title")
.setPriority(Notification.PRIORITY_LOW)
.setSmallIcon(mIcon1)
.setWhen(mWhen1)
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/presence/BleRssiPrecisionActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/presence/BleRssiPrecisionActivity.java
index 03dfde9..4408ed2 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/presence/BleRssiPrecisionActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/presence/BleRssiPrecisionActivity.java
@@ -223,7 +223,7 @@
String packetDeviceName = "";
if (DEVICE_NAME.length() > BleAdvertisingPacket.MAX_REFERENCE_DEVICE_NAME_LENGTH) {
packetDeviceName = DEVICE_NAME.substring(0,
- BleAdvertisingPacket.MAX_REFERENCE_DEVICE_NAME_LENGTH - 1);
+ BleAdvertisingPacket.MAX_REFERENCE_DEVICE_NAME_LENGTH);
} else {
packetDeviceName = DEVICE_NAME;
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/presence/ble/BleAdvertisingPacket.java b/apps/CtsVerifier/src/com/android/cts/verifier/presence/ble/BleAdvertisingPacket.java
index 1e505c2..e2a93b3 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/presence/ble/BleAdvertisingPacket.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/presence/ble/BleAdvertisingPacket.java
@@ -67,12 +67,14 @@
Log.e(TAG, "Advertising packet is null or not the right size");
return null;
}
- String referenceDeviceName = new String(
- ByteBuffer.wrap(packet, 0, MAX_REFERENCE_DEVICE_NAME_LENGTH - 1).array(),
- StandardCharsets.UTF_8);
- byte randomDeviceId = ByteBuffer.wrap(packet, MAX_REFERENCE_DEVICE_NAME_LENGTH, 1).get();
- byte rssiMedianFromReferenceDevice = ByteBuffer.wrap(packet,
- MAX_REFERENCE_DEVICE_NAME_LENGTH + 1, 1).get();
+
+ ByteBuffer byteBuffer = ByteBuffer.wrap(packet);
+ byte[] referenceDeviceNameBytes = new byte[MAX_REFERENCE_DEVICE_NAME_LENGTH];
+ byteBuffer.get(referenceDeviceNameBytes);
+ String referenceDeviceName = new String(referenceDeviceNameBytes, StandardCharsets.UTF_8);
+ byte randomDeviceId = byteBuffer.get();
+ byte rssiMedianFromReferenceDevice = byteBuffer.get();
+
return new BleAdvertisingPacket(referenceDeviceName, randomDeviceId,
rssiMedianFromReferenceDevice);
}
diff --git a/common/device-side/bedstead/remotedpc/src/main/java/com/android/bedstead/remotedpc/RemoteDpc.java b/common/device-side/bedstead/remotedpc/src/main/java/com/android/bedstead/remotedpc/RemoteDpc.java
index 99d2acf..909435a 100644
--- a/common/device-side/bedstead/remotedpc/src/main/java/com/android/bedstead/remotedpc/RemoteDpc.java
+++ b/common/device-side/bedstead/remotedpc/src/main/java/com/android/bedstead/remotedpc/RemoteDpc.java
@@ -58,6 +58,8 @@
private boolean mShouldRemoveUserWhenRemoved = false;
+ public static final String TAG = "RemoteDpc";
+
/**
* Get the {@link RemoteDpc} instance for the Device Owner.
*
@@ -354,9 +356,16 @@
dpcTestApp,
TestApis.devicePolicy().setProfileOwner(user, componentName));
- // DISALLOW_INSTALL_UNKNOWN_SOURCES causes verification failures in work profiles
- remoteDpc.devicePolicyManager()
- .clearUserRestriction(remoteDpc.componentName(), DISALLOW_INSTALL_UNKNOWN_SOURCES);
+ try { // workaround for: b/391462951
+ // DISALLOW_INSTALL_UNKNOWN_SOURCES causes verification failures in work profiles
+ remoteDpc.devicePolicyManager().clearUserRestriction(
+ remoteDpc.componentName(),
+ DISALLOW_INSTALL_UNKNOWN_SOURCES
+ );
+ } catch (Exception e) {
+ Log.e(TAG, "unable to clear user restriction: "
+ + DISALLOW_INSTALL_UNKNOWN_SOURCES, e);
+ }
return remoteDpc;
}
diff --git a/hostsidetests/adpf/app/hintsession/Android.bp b/hostsidetests/adpf/app/hintsession/Android.bp
index 53e10da..f120f8a 100644
--- a/hostsidetests/adpf/app/hintsession/Android.bp
+++ b/hostsidetests/adpf/app/hintsession/Android.bp
@@ -20,26 +20,20 @@
name: "libadpfhintsession_test_helper_jni",
min_sdk_version: "34",
srcs: [
- "src/cpp/AndroidOut.cpp",
- "src/cpp/JNIManager.cpp",
- "src/cpp/main.cpp",
- "src/cpp/Renderer.cpp",
- "src/cpp/Shader.cpp",
- "src/cpp/TextureAsset.cpp",
- "src/cpp/Utility.cpp",
- "src/cpp/external/android_native_app_glue.c",
+ "src/cpp/**/*.cpp",
+ "src/cpp/**/*.c",
],
shared_libs: [
"libandroid",
"libjnigraphics",
"libnativehelper",
+ "libnativewindow",
"libEGL",
"libGLESv3",
"liblog",
],
cpp_std: "c++20",
stl: "c++_shared",
- whole_static_libs: ["libnativetesthelper_jni"],
sdk_version: "current",
}
diff --git a/hostsidetests/adpf/app/hintsession/src/android/adpf/hintsession/app/ADPFHintSessionDeviceTest.java b/hostsidetests/adpf/app/hintsession/src/android/adpf/hintsession/app/ADPFHintSessionDeviceTest.java
index 89cfc3c..4c706a6 100644
--- a/hostsidetests/adpf/app/hintsession/src/android/adpf/hintsession/app/ADPFHintSessionDeviceTest.java
+++ b/hostsidetests/adpf/app/hintsession/src/android/adpf/hintsession/app/ADPFHintSessionDeviceTest.java
@@ -28,6 +28,7 @@
import android.device.collectors.util.SendToInstrumentation;
import android.os.Bundle;
+import androidx.test.filters.LargeTest;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
@@ -60,6 +61,7 @@
pm.hasSystemFeature(PackageManager.FEATURE_EMBEDDED));
}
+ @LargeTest
@Test
public void testAdpfHintSession() throws IOException {
assumeMobileDeviceFormFactor();
@@ -77,6 +79,9 @@
final Bundle returnBundle = new Bundle();
Map<String, String> metrics = activity.getMetrics();
if (metrics.containsKey("failure")) {
+ assumeFalse(
+ "Skipping test due to calibration issues",
+ metrics.get("failure").contains("Failed to calibrate"));
fail("Failed with error: " + metrics.get("failure"));
}
metrics.forEach(returnBundle::putString);
diff --git a/hostsidetests/adpf/app/hintsession/src/cpp/EventLoop.cpp b/hostsidetests/adpf/app/hintsession/src/cpp/EventLoop.cpp
new file mode 100644
index 0000000..e34e75a
--- /dev/null
+++ b/hostsidetests/adpf/app/hintsession/src/cpp/EventLoop.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "EventLoop.h"
+
+#include <unistd.h>
+
+#include <mutex>
+
+#include "Utility.h"
+
+void EventLoop::queueWork(std::function<void()>&& job) {
+ {
+ std::scoped_lock lock(mQueueMutex);
+ mEventsQueue->emplace(std::move(job));
+ }
+ mCV.notify_all();
+}
+
+EventLoop::~EventLoop() {
+ mStopping = true;
+ mCV.notify_all();
+ mRunner->join();
+}
+
+void EventLoop::run() {
+ mTidPromise.set_value(gettid());
+ while (!mStopping) {
+ {
+ std::unique_lock lock(mQueueMutex);
+ mCV.wait(lock, [&] { return (!mEventsQueue->empty() || mStopping); });
+ if (mStopping) {
+ return;
+ }
+ if (!mEventsQueue->empty()) {
+ // Swap the front and back queue
+ mEventsQueue.swap(mEventsProcessing);
+ }
+ }
+ // Process all queued events
+ // lock not needed here since mEventsProcessing is held by this thread uniquely
+ while (!mEventsProcessing->empty() && !mStopping) {
+ // Run the item
+ {
+ std::scoped_lock lock{mRunnerMutex};
+ (mEventsProcessing->front())();
+ }
+ mEventsProcessing->pop();
+ }
+ }
+}
+
+int EventLoop::getlooptid() {
+ if (!mTid.has_value()) {
+ mTid = mTidFuture.get();
+ }
+ return *mTid;
+}
\ No newline at end of file
diff --git a/hostsidetests/adpf/app/hintsession/src/cpp/EventLoop.h b/hostsidetests/adpf/app/hintsession/src/cpp/EventLoop.h
new file mode 100644
index 0000000..d6455f4
--- /dev/null
+++ b/hostsidetests/adpf/app/hintsession/src/cpp/EventLoop.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2024 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.
+ */
+
+#pragma once
+
+#include <queue>
+#include <functional>
+#include <future>
+#include <optional>
+#include <thread>
+
+class EventLoop {
+public:
+ void queueWork(std::function<void()>&& job);
+ ~EventLoop();
+ int getlooptid();
+
+private:
+ // Front queue where items are loaded
+ std::unique_ptr<std::queue<std::function<void()>>> mEventsQueue{
+ std::make_unique<std::queue<std::function<void()>>>()};
+ // Back queue where items are processed
+ std::unique_ptr<std::queue<std::function<void()>>> mEventsProcessing{
+ std::make_unique<std::queue<std::function<void()>>>()};
+ std::condition_variable mCV;
+ std::mutex mQueueMutex{};
+ std::mutex mRunnerMutex{};
+ std::promise<int> mTidPromise{};
+ std::future<int> mTidFuture = mTidPromise.get_future();
+ std::optional<int> mTid;
+ bool mStopping = false;
+ std::unique_ptr<std::thread> mRunner = std::make_unique<std::thread>(&EventLoop::run, this);
+ void run();
+};
\ No newline at end of file
diff --git a/hostsidetests/adpf/app/hintsession/src/cpp/Model.h b/hostsidetests/adpf/app/hintsession/src/cpp/Model.h
index 6e20398..28cf627 100644
--- a/hostsidetests/adpf/app/hintsession/src/cpp/Model.h
+++ b/hostsidetests/adpf/app/hintsession/src/cpp/Model.h
@@ -19,6 +19,7 @@
#include <memory>
#include <vector>
+#include "AndroidOut.h"
#include "TextureAsset.h"
union Vector3 {
@@ -58,12 +59,15 @@
class Model {
public:
- inline Model(std::vector<Vertex> vertices, std::vector<Index> indices,
- std::shared_ptr<TextureAsset> spTexture)
+ static std::shared_ptr<TextureAsset> texture;
+ // Default init only useful as a placeholder
+ Model() {}
+
+ inline Model(std::vector<Vertex> vertices, std::vector<Index> indices)
: currentVertices_(vertices),
startVertices_(std::move(vertices)),
indices_(std::move(indices)),
- spTexture_(std::move(spTexture)) {
+ id_(0) {
findCenter();
}
@@ -73,10 +77,21 @@
inline const Index *getIndexData() const { return indices_.data(); }
- inline const TextureAsset &getTexture() const { return *spTexture_; }
+ inline const TextureAsset &getTexture() const { return *texture; }
inline const Vector3 getCenter() { return center_; }
+ inline void dump() const {
+ aout << "Indices: " << std::endl;
+ for (auto &&ver : currentVertices_) {
+ aout << "Vertex: x: " << ver.position.x << " y: " << ver.position.y
+ << " z: " << ver.position.z << std::endl;
+ }
+ aout << std::endl;
+ aout << "Center: x: " << center_.x << " y: " << center_.y << " z: " << center_.z
+ << std::endl;
+ }
+
void move(Vector3 offset) {
for (int i = 0; i < startVertices_.size(); ++i) {
startVertices_[i].position = startVertices_[i].position + offset;
@@ -85,7 +100,7 @@
center_ = center_ + offset;
}
- void setRotation(float angle) {
+ void addRotation(float angle) {
float rad = angle + rotationOffset_;
for (int i = 0; i < startVertices_.size(); ++i) {
Vector3 normalized = startVertices_[i].position - center_;
@@ -94,10 +109,21 @@
out.y = normalized.x * sin(rad) + normalized.y * cos(rad);
currentVertices_[i].position = out + center_;
}
+ rotationOffset_ = rad;
}
void setRotationOffset(float angle) { rotationOffset_ = angle; }
+ static void applyPhysics(float deltaTimeUnit, Model *models, int size, float width,
+ float height) {
+ nBodySimulation(deltaTimeUnit, models, size, width, height);
+ }
+
+ void setMass(float m) { mass_ = m; }
+
+ int getId() const { return id_; }
+ void setId(int id) { id_ = id; }
+
private:
void findCenter() {
Vector3 center{{0, 0, 0}};
@@ -107,10 +133,48 @@
center_ = center / static_cast<float>(startVertices_.size());
}
+ static void nBodySimulation(float deltaTimeUnit, Model *models, int size, float width,
+ float height) {
+ static const float G = 6.67e-10;
+ for (auto i = 0; i < size; i++) {
+ auto &model = models[i];
+ Vector3 acc = {{0, 0, 0}};
+ for (auto j = 0; j < size; j++) {
+ if (i != j) {
+ auto &other = models[j];
+ auto dx = model.center_.x - other.center_.x;
+ auto dy = model.center_.y - other.center_.y;
+ auto dz = model.center_.z - other.center_.z;
+ float distanceSq = dx * dx + dy * dy + dz * dz;
+ Vector3 direction = {{dx, dy, dz}};
+ float distance = std::sqrt(distanceSq);
+ float force = (G * model.mass_ * other.mass_) / std::max(0.01f, distanceSq);
+ acc = acc + (direction / std::max(0.01f, distance)) * (force / model.mass_);
+ }
+ }
+ model.velocity_ = model.velocity_ + acc * deltaTimeUnit;
+ model.move(model.velocity_ * deltaTimeUnit);
+ if (model.center_.x <= -width / 2 || model.center_.x >= width / 2) {
+ model.velocity_.x = model.center_.x <= -width / 2 ? abs(model.velocity_.x)
+ : -abs(model.velocity_.x);
+ auto border = model.center_.x <= -width / 2 ? -width / 2 : width / 2;
+ model.move({{border - model.center_.x, 0, 0}});
+ }
+ if (model.center_.y <= -height / 2 || model.center_.y >= height / 2) {
+ model.velocity_.y = model.center_.y <= -height / 2 ? abs(model.velocity_.y)
+ : -abs(model.velocity_.y);
+ auto border = model.center_.y <= -height / 2 ? -height / 2 : height / 2;
+ model.move({{0, border - model.center_.y, 0}});
+ }
+ }
+ }
+
Vector3 center_;
std::vector<Vertex> currentVertices_;
std::vector<Vertex> startVertices_;
std::vector<Index> indices_;
- std::shared_ptr<TextureAsset> spTexture_;
float rotationOffset_;
+ Vector3 velocity_;
+ float mass_ = 1.0f;
+ int id_;
};
diff --git a/hostsidetests/adpf/app/hintsession/src/cpp/Renderer.cpp b/hostsidetests/adpf/app/hintsession/src/cpp/Renderer.cpp
index af3512f..190c495 100644
--- a/hostsidetests/adpf/app/hintsession/src/cpp/Renderer.cpp
+++ b/hostsidetests/adpf/app/hintsession/src/cpp/Renderer.cpp
@@ -15,7 +15,6 @@
*/
#include "Renderer.h"
-#include <GLES3/gl3.h>
#include <android/imagedecoder.h>
#include <memory>
@@ -24,6 +23,8 @@
#include <vector>
// #include <iostream>
+#include <android/hardware_buffer_jni.h>
+
#include <chrono>
#include "AndroidOut.h"
@@ -104,11 +105,13 @@
static constexpr float kProjectionNearPlane = -1.f;
/*!
- * The far plane distance for the projection matrix. Since this is an orthographic porjection
+ * The far plane distance for the projection matrix. Since this is an orthographic projection
* matrix, it's convenient to have the far plane equidistant from 0 as the near plane.
*/
static constexpr float kProjectionFarPlane = 1.f;
+std::shared_ptr<TextureAsset> Model::texture = nullptr;
+
Renderer::~Renderer() {
if (display_ != EGL_NO_DISPLAY) {
eglMakeCurrent(display_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
@@ -125,7 +128,40 @@
}
}
-jlong Renderer::render() {
+Renderer *getRenderer() {
+ return Renderer::getInstance();
+}
+
+StageState Renderer::updateModels(StageState &lastUpdate) {
+ StageState output{
+ .models = lastUpdate.models,
+ .start = Utility::now(),
+ };
+
+ // Get desired seconds per rotation
+ double spr = duration_cast<std::chrono::nanoseconds>(2s).count();
+
+ // Figure out what angle the models need to be at
+ double offset = (output.start - lastUpdate.start);
+
+ // Calculate the required spin as a fraction of a circle
+ auto spin = offset / spr;
+
+ for (Model &model : output.models) {
+ model.addRotation(M_PI * 2.0 * spin);
+ }
+
+ for (int j = 0; j < physicsIterations_; ++j) {
+ Model::applyPhysics(0.1f, output.models.data(), output.models.size(),
+ static_cast<float>(width_) * kProjectionHalfHeight * 2 / height_,
+ kProjectionHalfHeight * 2);
+ }
+
+ output.end = Utility::now();
+ return output;
+}
+
+void Renderer::render(const StackState &stack) {
// Check to see if the surface has changed size. This is _necessary_ to do every frame when
// using immersive mode as you'll get no other notification that your renderable area has
// changed.
@@ -162,35 +198,34 @@
// clear the color buffer
glClear(GL_COLOR_BUFFER_BIT);
- // Rotate the models
- const std::chrono::steady_clock::duration rpm = 2s;
- static std::chrono::steady_clock::time_point startTime = std::chrono::steady_clock::now();
- std::chrono::steady_clock::time_point renderTime = std::chrono::steady_clock::now();
- // Figure out what angle the models need to be at
- std::chrono::steady_clock::duration offset = (renderTime - startTime) % rpm;
- auto spin = static_cast<double>(offset.count()) / static_cast<double>(rpm.count());
-
// Render all the models. There's no depth testing in this sample so they're accepted in the
// order provided. But the sample EGL setup requests a 24 bit depth buffer so you could
// configure it at the end of initRenderer
- auto start = std::chrono::steady_clock::now();
-
- if (!heads_.empty()) {
- for (auto &model : heads_) {
- model.setRotation(M_PI * 2.0 * spin);
+ for (auto &&stage : stack.stages) {
+ for (const Model &model : stage.models) {
shader_->drawModel(model);
}
}
-
- auto end = std::chrono::steady_clock::now();
-
- // Present the rendered image. This is an implicit glFlush.
- auto swapResult = eglSwapBuffers(display_, surface_);
- assert(swapResult == EGL_TRUE);
- return (end - start).count();
}
-void Renderer::initRenderer() {
+void Renderer::swapBuffers(const StackState &) {
+ auto swapResult = eglSwapBuffers(display_, surface_);
+}
+
+void Renderer::threadedInit() {
+ std::promise<bool> syncOnCompletion;
+
+ drawLoop_.queueWork([this, &syncOnCompletion]() { initRenderer(syncOnCompletion); });
+
+ syncOnCompletion.get_future().get();
+
+ for (int i = 0; i < loops_.size(); ++i) {
+ tids_.push_back(loops_[i].getlooptid());
+ }
+ tids_.push_back(drawLoop_.getlooptid());
+}
+
+void Renderer::initRenderer(std::promise<bool> &syncOnCompletion) {
// Choose your render attributes
constexpr EGLint attribs[] = {EGL_RENDERABLE_TYPE,
EGL_OPENGL_ES3_BIT,
@@ -253,9 +288,8 @@
surface_ = surface;
context_ = context;
- // make width and height invalid so it gets updated the first frame in @a updateRenderArea()
- width_ = -1;
- height_ = -1;
+ width_ = static_cast<uint32_t>(ANativeWindow_getWidth(app_->window));
+ height_ = static_cast<uint32_t>(ANativeWindow_getHeight(app_->window));
PRINT_GL_STRING(GL_VENDOR);
PRINT_GL_STRING(GL_RENDERER);
@@ -277,16 +311,13 @@
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- // get some demo models into memory
- // setNumHeads(1000);
+ createHeads();
+ syncOnCompletion.set_value(true);
}
void Renderer::updateRenderArea() {
- EGLint width;
- eglQuerySurface(display_, surface_, EGL_WIDTH, &width);
-
- EGLint height;
- eglQuerySurface(display_, surface_, EGL_HEIGHT, &height);
+ EGLint width = static_cast<uint32_t>(ANativeWindow_getWidth(app_->window));
+ EGLint height = static_cast<uint32_t>(ANativeWindow_getHeight(app_->window));
if (width != width_ || height != height_) {
width_ = width;
@@ -298,48 +329,59 @@
}
}
-void Renderer::addHead() {
- thread_local auto assetManager = app_->activity->assetManager;
- thread_local auto spAndroidRobotTexture = TextureAsset::loadAsset(assetManager, "android.png");
- thread_local std::vector<Vertex> vertices = {
- Vertex(Vector3{{0.3, 0.3, 0}}, Vector2{{0, 0}}), // 0
- Vertex(Vector3{{-0.3, 0.3, 0}}, Vector2{{1, 0}}), // 1
- Vertex(Vector3{{-0.3, -0.3, 0}}, Vector2{{1, 1}}), // 2
- Vertex(Vector3{{0.3, -0.3, 0}}, Vector2{{0, 1}}) // 3
- };
- thread_local std::vector<Index> indices = {0, 1, 2, 0, 2, 3};
- thread_local Model baseModel{vertices, indices, spAndroidRobotTexture};
- float angle = 2 * M_PI * (static_cast<float>(rand()) / static_cast<float>(RAND_MAX));
- float x = 1.5 * static_cast<float>(rand()) / static_cast<float>(RAND_MAX) - 0.75;
- float y = 3.0 * static_cast<float>(rand()) / static_cast<float>(RAND_MAX) - 1.5;
- Vector3 offset{{x, y, 0}};
- Model toAdd{baseModel};
- toAdd.move(offset);
- toAdd.setRotationOffset(angle);
- heads_.push_back(toAdd);
+std::vector<int64_t> Renderer::findVsyncTargets(int &events, android_poll_source *&pSource,
+ int numFrames) {
+ targets_ = {};
+ drawFramesSync(numFrames, events, pSource, "findVsyncTargets");
+ return targets_;
}
-void Renderer::setNumHeads(int headCount) {
- if (headCount > heads_.size()) {
- int to_add = headCount - heads_.size();
- for (int i = 0; i < to_add; ++i) {
- addHead();
+void Renderer::createHeads() {
+ auto assetManager = app_->activity->assetManager;
+ Model::texture = TextureAsset::loadAsset(assetManager, "android.png");
+ std::vector<Vertex> vertices = {
+ Vertex(Vector3{{-0.3, 0.3, 0}}, Vector2{{0, 0}}), // 0
+ Vertex(Vector3{{0.3, 0.3, 0}}, Vector2{{1, 0}}), // 1
+ Vertex(Vector3{{0.3, -0.3, 0}}, Vector2{{1, 1}}), // 2
+ Vertex(Vector3{{-0.3, -0.3, 0}}, Vector2{{0, 1}}) // 3
+ };
+ std::vector<Index> indices = {0, 1, 2, 0, 2, 3};
+ Model baseModel{vertices, indices};
+ int id = 0;
+ for (auto &&stage : latest_stage_models_) {
+ for (int i = 0; i < stage.models.size(); ++i) {
+ ++id;
+ float angle = 2 * M_PI * (static_cast<float>(rand()) / static_cast<float>(RAND_MAX));
+ float x = 1.5 * static_cast<float>(rand()) / static_cast<float>(RAND_MAX) - 0.75;
+ float y = 3.0 * static_cast<float>(rand()) / static_cast<float>(RAND_MAX) - 1.5;
+ float mass = rand() % 10 + 1;
+ Vector3 offset{{x, y, 0}};
+ Model toAdd{baseModel};
+ toAdd.move(offset);
+ toAdd.setRotationOffset(angle);
+ toAdd.setMass(mass);
+ toAdd.setId(id);
+ stage.models[i] = toAdd;
}
- } else if (headCount < heads_.size()) {
- heads_.erase(heads_.begin() + headCount, heads_.end());
}
}
-bool Renderer::startHintSession(std::vector<int32_t> &tids, int64_t target) {
+void Renderer::setPhysicsIterations(int iterations) {
+ physicsIterations_ = iterations;
+}
+
+bool Renderer::startHintSession(int64_t target) {
if (hintManager_ == nullptr) {
hintManager_ = APerformanceHint_getManager();
}
long preferredRate = APerformanceHint_getPreferredUpdateRateNanos(hintManager_);
results_["preferredRate"] = std::to_string(preferredRate);
if (preferredRate > 0 && hintSession_ == nullptr && hintManager_ != nullptr) {
+ std::vector<int> toSend(tids_);
+ toSend.push_back(gettid());
lastTarget_ = target;
hintSession_ =
- APerformanceHint_createSession(hintManager_, tids.data(), tids.size(), target);
+ APerformanceHint_createSession(hintManager_, toSend.data(), toSend.size(), target);
}
bool supported = preferredRate > 0 && hintSession_ != nullptr;
results_["isHintSessionSupported"] = supported ? "true" : "false";
@@ -398,38 +440,222 @@
return values[values.size() / 2];
}
-FrameStats Renderer::getFrameStats(std::vector<int64_t> &durations, std::vector<int64_t> &intervals,
- std::string &testName) {
+void Renderer::setChoreographer(AChoreographer *choreographer) {
+ choreographer_ = choreographer;
+}
+
+void dumpCallbacksData(VsyncData &data) {
+ aerr << "Frame time: " << data.frameTimeNanos << std::endl;
+ aerr << "Num callbacks: " << data.numVsyncs << std::endl;
+ aerr << "Preferred callback: " << data.preferredVsync << std::endl;
+ for (auto &&callback : data.vsyncs) {
+ aerr << "Callback " << callback.index << " has deadline: " << callback.deadlineNanos
+ << " which is: " << callback.deadlineNanos - data.frameTimeNanos
+ << " away, vsyncId: " << callback.vsyncId << std::endl;
+ }
+ aerr << "Finished dump " << std::endl;
+}
+
+Vsync &getClosestCallbackToTarget(int64_t target, VsyncData &data) {
+ int min_i = 0;
+ int64_t min_diff = std::abs(data.vsyncs[0].deadlineNanos - data.frameTimeNanos - target);
+ for (int i = 1; i < data.vsyncs.size(); ++i) {
+ int64_t diff = std::abs(data.vsyncs[i].deadlineNanos - data.frameTimeNanos - target);
+ if (diff < min_diff) {
+ min_diff = diff;
+ min_i = i;
+ }
+ }
+ return data.vsyncs[min_i];
+}
+
+VsyncData fromFrameCallbackData(const AChoreographerFrameCallbackData *data) {
+ VsyncData out{.frameTimeNanos = AChoreographerFrameCallbackData_getFrameTimeNanos(data),
+ .numVsyncs = AChoreographerFrameCallbackData_getFrameTimelinesLength(data),
+ .preferredVsync =
+ AChoreographerFrameCallbackData_getPreferredFrameTimelineIndex(data),
+ .vsyncs{}};
+ for (size_t i = 0; i < out.numVsyncs; ++i) {
+ out.vsyncs.push_back(
+ {.index = i,
+ .deadlineNanos =
+ AChoreographerFrameCallbackData_getFrameTimelineDeadlineNanos(data, i),
+ .presentationNanos =
+ AChoreographerFrameCallbackData_getFrameTimelineExpectedPresentationTimeNanos(
+ data, i),
+ .vsyncId = AChoreographerFrameCallbackData_getFrameTimelineVsyncId(data, i)});
+ }
+ return out;
+}
+
+void Renderer::rawChoreographerCallback(const AChoreographerFrameCallbackData *data, void *) {
+ static std::mutex choreographerMutex{};
+ assert(appPtr != nullptr);
+ std::scoped_lock lock(choreographerMutex);
+ getRenderer()->choreographerCallback(data);
+}
+
+void Renderer::choreographerCallback(const AChoreographerFrameCallbackData *data) {
+ if (framesRemaining_ > 0) {
+ --framesRemaining_;
+ }
+ VsyncData callbackData = fromFrameCallbackData(data);
+ batchData_.vsyncs.push_back(callbackData);
+ // Allow a passed-in method to check on the callback data
+ if (wakeupMethod_ != std::nullopt) {
+ (*wakeupMethod_)(callbackData);
+ }
+ if (framesRemaining_ == 0 && targets_.size() == 0) {
+ dumpCallbacksData(callbackData);
+ for (int i = 0; i < callbackData.vsyncs.size(); ++i) {
+ targets_.push_back(callbackData.vsyncs[i].deadlineNanos - callbackData.frameTimeNanos);
+ }
+ }
+
+ int64_t start = Utility::now();
+ if (lastStart_.has_value()) {
+ batchData_.intervals.push_back(start - *lastStart_);
+ }
+ lastStart_ = start;
+
+ StackState startState{
+ .intendedVsync = getClosestCallbackToTarget(lastTarget_, callbackData),
+ .stages{},
+ };
+
+ batchData_.selectedVsync.push_back(startState.intendedVsync);
+
+ if (framesRemaining_ > 0) {
+ postCallback();
+ }
+
+ // Copy here so the lambdas can use that copy and not the global one
+ int remain = framesRemaining_;
+
+ stackSchedule<StackState>(
+ [=, startTime = start, this](int level, StackState &state) {
+ // Render against the most recent physics data for this pipeline
+ state.stages[level] = updateModels(latest_stage_models_[level]);
+
+ // Save the output from this physics step for the next frame to use
+ latest_stage_models_[level] = state.stages[level];
+
+ // If we're at the end of the stack, push a draw job to the draw loop
+ if (level == 0) {
+ drawLoop_.queueWork([=, this]() {
+ if (remain == 0) {
+ framesDone_.set_value(true);
+ }
+
+ render(state);
+ // Update final stage time after render finishes
+
+ int64_t duration = Utility::now() - startTime;
+ batchData_.durations.push_back(duration);
+ if (isHintSessionRunning()) {
+ reportActualWorkDuration(duration);
+ }
+
+ swapBuffers(state);
+ });
+ }
+ },
+ std::move(startState));
+}
+
+FrameStats Renderer::drawFramesSync(int frames, int &events, android_poll_source *&pSource,
+ std::string testName) {
+ bool namedTest = testName.size() > 0;
+
+ // Make sure this can only run once at a time because the callback is unique
+ static std::mutex mainThreadLock;
+ framesDone_ = std::promise<bool>();
+ auto frameFuture = framesDone_.get_future();
+
+ std::scoped_lock lock(mainThreadLock);
+ batchData_ = {};
+ framesRemaining_ = frames;
+ postCallback();
+
+ while (true) {
+ int retval = ALooper_pollOnce(30, nullptr, &events, (void **)&pSource);
+ if (retval > 0 && pSource) {
+ pSource->process(app_, pSource);
+ }
+ auto status = frameFuture.wait_for(0s);
+ if (status == std::future_status::ready) {
+ break;
+ }
+ }
+ if (namedTest) {
+ addResult(testName + "_durations", Utility::serializeValues(batchData_.durations));
+ addResult(testName + "_intervals", Utility::serializeValues(batchData_.intervals));
+ }
+
+ return getFrameStats(batchData_, testName);
+}
+
+void Renderer::postCallback() {
+ AChoreographer_postVsyncCallback(choreographer_, rawChoreographerCallback, nullptr);
+}
+
+FrameStats Renderer::getFrameStats(FrameBatchData &batchData, std::string &testName) {
FrameStats stats;
- // Double precision is int-precise up to 2^52 so we should be fine for this range
- double sum = std::accumulate(durations.begin(), durations.end(), 0);
- double mean = static_cast<double>(sum) / static_cast<double>(durations.size());
+ stats.actualTargetDuration = lastTarget_;
+
+ std::vector<int64_t> targets;
+ for (int i = 0; i < batchData.vsyncs.size(); ++i) {
+ VsyncData &vsyncData = batchData.vsyncs[i];
+ Vsync &selectedVsync = batchData.selectedVsync[i];
+ targets.push_back(selectedVsync.deadlineNanos - vsyncData.frameTimeNanos);
+ }
+
+ stats.medianClosestDeadlineToTarget = getMedian(targets);
+
+ double sum = std::accumulate(batchData.durations.begin(), batchData.durations.end(),
+ static_cast<double>(0.0));
+ double mean = sum / static_cast<double>(batchData.durations.size());
int dropCount = 0;
double varianceSum = 0;
- for (int64_t &duration : durations) {
+ for (int64_t &duration : batchData.durations) {
if (isHintSessionRunning() && duration > lastTarget_) {
++dropCount;
}
varianceSum += (duration - mean) * (duration - mean);
}
- if (durations.size() > 0) {
- stats.medianWorkDuration = getMedian(durations);
+ std::vector<int64_t> selectedDeadlineDurations;
+ for (int i = 0; i < batchData.vsyncs.size(); ++i) {
+ selectedDeadlineDurations.push_back(batchData.selectedVsync[i].deadlineNanos -
+ batchData.vsyncs[i].frameTimeNanos);
}
- if (intervals.size() > 0) {
- stats.medianFrameInterval = getMedian(intervals);
+ if (batchData.durations.size() > 0) {
+ stats.medianWorkDuration = getMedian(batchData.durations);
}
- stats.deviation = std::sqrt(varianceSum / static_cast<double>(durations.size() - 1));
+ if (batchData.intervals.size() > 0) {
+ stats.medianFrameInterval = getMedian(batchData.intervals);
+ }
+ stats.deviation = std::sqrt(varianceSum / static_cast<double>(batchData.durations.size() - 1));
if (isHintSessionRunning()) {
stats.exceededCount = dropCount;
stats.exceededFraction =
- static_cast<double>(dropCount) / static_cast<double>(durations.size());
+ static_cast<double>(dropCount) / static_cast<double>(batchData.durations.size());
stats.efficiency = static_cast<double>(sum) /
- static_cast<double>(durations.size() * std::min(lastTarget_, baselineMedian_));
+ static_cast<double>(batchData.durations.size() *
+ std::min(lastTarget_, baselineMedian_));
}
if (testName.size() > 0) {
+ addResult(testName + "_selected_deadline_durations",
+ Utility::serializeValues(selectedDeadlineDurations));
+ addResult(testName + "_sum", std::to_string(sum));
+ addResult(testName + "_num_durations", std::to_string(batchData.durations.size()));
+ addResult(testName + "_mean", std::to_string(mean));
addResult(testName + "_median", std::to_string(stats.medianWorkDuration));
addResult(testName + "_median_interval", std::to_string(stats.medianFrameInterval));
+ addResult(testName + "_median_deadline_duration",
+ std::to_string(stats.medianClosestDeadlineToTarget));
+ addResult(testName + "_intended_deadline_duration",
+ std::to_string(stats.actualTargetDuration));
addResult(testName + "_deviation", std::to_string(stats.deviation));
if (isHintSessionRunning()) {
addResult(testName + "_target", std::to_string(getTargetWorkDuration()));
@@ -442,3 +668,18 @@
return stats;
}
+
+void Renderer::makeInstance(android_app *pApp) {
+ if (sRenderer == nullptr) {
+ sRenderer = std::make_unique<Renderer>(pApp);
+ }
+}
+
+Renderer *Renderer::getInstance() {
+ if (sRenderer == nullptr) {
+ return nullptr;
+ }
+ return sRenderer.get();
+}
+
+std::unique_ptr<Renderer> Renderer::sRenderer = nullptr;
\ No newline at end of file
diff --git a/hostsidetests/adpf/app/hintsession/src/cpp/Renderer.h b/hostsidetests/adpf/app/hintsession/src/cpp/Renderer.h
index cc7fd72..595f84d 100644
--- a/hostsidetests/adpf/app/hintsession/src/cpp/Renderer.h
+++ b/hostsidetests/adpf/app/hintsession/src/cpp/Renderer.h
@@ -16,35 +16,116 @@
#pragma once
#include <EGL/egl.h>
+#include <android/native_activity.h>
+#include <android/native_window.h>
#include <android/performance_hint.h>
+#include <android/surface_control.h>
#include <jni.h>
#include <chrono>
#include <map>
#include <memory>
#include <optional>
+#include <array>
+#include "EventLoop.h"
#include "Model.h"
#include "Shader.h"
#include "external/android_native_app_glue.h"
+const constexpr size_t kStages = 3;
+const constexpr size_t kHeadsPerStage = 4;
+const constexpr size_t kHeads = kStages * kHeadsPerStage;
+
struct android_app;
-struct FrameStats {
- // Median of the durations
- int64_t medianWorkDuration;
- // Median of the intervals
- int64_t medianFrameInterval;
- // Standard deviation of a given run
- double deviation;
- // The total number of frames that exceeded target
- std::optional<int64_t> exceededCount;
- // The percent of frames that exceeded target
- std::optional<double> exceededFraction;
- // Efficiency of a given run is calculated by how close to min(target, baseline) the median is
- std::optional<double> efficiency;
+struct Vsync {
+ size_t index;
+ int64_t deadlineNanos;
+ int64_t presentationNanos;
+ int64_t vsyncId;
};
+struct VsyncData {
+ int64_t frameTimeNanos;
+ size_t numVsyncs;
+ size_t preferredVsync;
+ std::vector<Vsync> vsyncs{};
+};
+
+/*!
+ * The output of running the per-stage lambda
+ */
+struct StageState {
+ int64_t start;
+ int64_t end;
+ std::array<Model, kHeadsPerStage> models{};
+};
+
+/*!
+ * The output state of running the whole stack of the per-stage updates for each stage
+ */
+struct StackState {
+ Vsync intendedVsync;
+ std::array<StageState, kStages> stages{};
+};
+
+Vsync &getClosestCallbackToTarget(int64_t target, VsyncData &data);
+
+struct FrameStats {
+ /*!
+ * Median of the durations
+ */
+ int64_t medianWorkDuration;
+ /*!
+ * Median of the intervals
+ */
+ int64_t medianFrameInterval;
+ /*!
+ * Standard deviation of a given run
+ */
+ double deviation;
+ /*!
+ * The total number of frames that exceeded target
+ */
+ std::optional<int64_t> exceededCount;
+ /*!
+ * The percent of frames that exceeded target
+ */
+ std::optional<double> exceededFraction;
+ /*!
+ * Efficiency of a given run is calculated by how close to min(target, baseline) the median is
+ */
+ std::optional<double> efficiency;
+ /*!
+ * Median of the target duration that was closest to what we wanted
+ */
+ int64_t medianClosestDeadlineToTarget;
+ // Actual target duration, related to session target but not exactly the same
+ // This is based on the intended frame deadline based on results from Choreographer
+ int64_t actualTargetDuration;
+ void dump(std::string testName) const {
+ aerr << "Stats for: " << testName;
+ aerr << "medianWorkDuration: " << medianWorkDuration << std::endl;
+ aerr << "medianFrameInterval: " << medianFrameInterval << std::endl;
+ aerr << "deviation: " << deviation << std::endl;
+ aerr << "exceededCount: " << exceededCount.value_or(-1) << std::endl;
+ aerr << "exceededFraction: " << exceededFraction.value_or(-1) << std::endl;
+ aerr << "efficiency: " << efficiency.value_or(-1) << std::endl;
+ aerr << "medianClosestDeadlineToTarget: " << medianClosestDeadlineToTarget << std::endl;
+ aerr << "actualTargetDuration: " << actualTargetDuration << std::endl;
+ };
+};
+
+struct FrameBatchData {
+ std::vector<int64_t> durations{};
+ std::vector<int64_t> intervals{};
+ std::vector<VsyncData> vsyncs{};
+ std::vector<Vsync> selectedVsync{};
+};
+
+Renderer *getRenderer();
+
class Renderer {
public:
/*!
@@ -58,21 +139,20 @@
width_(0),
height_(0),
shaderNeedsNewProjectionMatrix_(true) {
- initRenderer();
+ threadedInit();
}
virtual ~Renderer();
/*!
- * Renders all the models in the renderer, returns time spent waiting for CPU work
- * to finish.
+ * Draw all models waiting to render in a given StackState.
*/
- jlong render();
+ void render(const StackState &state);
/*!
* Attempts to start hint session and returns whether ADPF is supported on a given device.
*/
- bool startHintSession(std::vector<pid_t> &threads, int64_t target);
+ bool startHintSession(int64_t target);
void closeHintSession();
void reportActualWorkDuration(int64_t duration);
void updateTargetWorkDuration(int64_t target);
@@ -80,11 +160,9 @@
int64_t getTargetWorkDuration();
/*!
- * Sets the number of android "heads" in the scene, these are used to create a synthetic
- * workload that scales with performance, and by adjusting the number of them, the test can
- * adjust the amount of stress to place the system under.
+ * Sets the number of iterations of physics before during each draw to control the CPU overhead.
*/
- void setNumHeads(int headCount);
+ void setPhysicsIterations(int iterations);
/*!
* Adds an entry to the final result map that gets passed up to the Java side of the app, and
@@ -97,12 +175,6 @@
*/
std::map<std::string, std::string> &getResults();
- /*
- * Finds the test settings that best match this device, and returns the
- * duration of the frame's work
- */
- double calibrate(int &events, android_poll_source *pSource);
-
/*!
* Sets the baseline median, used to determine efficiency score
*/
@@ -111,15 +183,42 @@
/*!
* Calculates the above frame stats for a given run
*/
- FrameStats getFrameStats(std::vector<int64_t> &durations, std::vector<int64_t> &intervals,
- std::string &testName);
+ FrameStats getFrameStats(FrameBatchData &batchData, std::string &testName);
+
+ void setChoreographer(AChoreographer *choreographer);
+ FrameStats drawFramesSync(int frames, int &events, android_poll_source *&pSource,
+ std::string testName = "");
+
+ /*!
+ * Run a few frames to figure out what vsync targets SF uses
+ */
+ std::vector<int64_t> findVsyncTargets(int &events, android_poll_source *&pSource,
+ int numFrames);
+
+ static Renderer *getInstance();
+ static void makeInstance(android_app *pApp);
private:
/*!
+ * Creates the set of android heads for load testing
+ */
+ void createHeads();
+
+ /*!
+ * Swap the waiting render buffer after everything is drawn
+ */
+ void swapBuffers(const StackState &state);
+
+ /*!
* Performs necessary OpenGL initialization. Customize this if you want to change your EGL
* context or application-wide settings.
*/
- void initRenderer();
+ void initRenderer(std::promise<bool> &syncOnCompletion);
+
+ /*!
+ * Run initRenderer on the drawing thread to hold the context there
+ */
+ void threadedInit();
/*!
* @brief we have to check every frame to see if the framebuffer has changed in size. If it has,
@@ -128,9 +227,21 @@
void updateRenderArea();
/*!
- * Adds an android "head" to the scene.
+ * Run physics and spin the models in a pipeline
*/
- void addHead();
+ StageState updateModels(StageState &lastUpdate);
+
+ void choreographerCallback(const AChoreographerFrameCallbackData *data);
+
+ /*!
+ * Passed directly choreographer as the callback method
+ */
+ static void rawChoreographerCallback(const AChoreographerFrameCallbackData *data, void *appPtr);
+
+ /*!
+ * Post a new callback to Choreographer for the next frame
+ */
+ void postCallback();
android_app *app_;
EGLDisplay display_;
@@ -140,15 +251,58 @@
EGLint height_;
APerformanceHintSession *hintSession_ = nullptr;
APerformanceHintManager *hintManager_ = nullptr;
+ AChoreographer *choreographer_;
int64_t lastTarget_ = 0;
int64_t baselineMedian_ = 0;
- bool shaderNeedsNewProjectionMatrix_;
+ bool shaderNeedsNewProjectionMatrix_ = true;
+
+ /*!
+ * Schedules a method to run against each level of the pipeline. At each step, the
+ * method will be passed a "Data" object and output an object of the same type, allowing
+ * different levels of the same pipeline to easily share data or work on the same problem.
+ */
+ template <class Data>
+ void recursiveSchedule(std::function<void(int level, Data &data)> fn, int level, Data &&data) {
+ loops_[level].queueWork(
+ [=, this, fn = std::move(fn), dataInner = std::move(data)]() mutable {
+ // Run the method
+ fn(level, dataInner);
+
+ if (level > 0) {
+ this->recursiveSchedule(fn, level - 1, std::move(dataInner));
+ }
+ });
+ }
+
+ template <class Data>
+ void stackSchedule(std::function<void(int level, Data &data)> fn, Data startData) {
+ recursiveSchedule<Data>(fn, loops_.size() - 1, std::move(startData));
+ }
std::unique_ptr<Shader> shader_;
- std::vector<Model> heads_;
+ std::array<StageState, kStages> latest_stage_models_;
+ int headsSize_ = 0;
+ int physicsIterations_ = 1;
- // Hold on to the results object in the renderer, so
- // we can reach the data anywhere in the rendering step.
+ /*!
+ * Holds onto the results object in the renderer, so
+ * we can reach the data anywhere in the rendering step.
+ */
std::map<std::string, std::string> results_;
+
+ std::array<EventLoop, kStages> loops_{};
+ EventLoop drawLoop_{};
+ std::vector<pid_t> tids_{};
+ std::vector<int64_t> targets_{};
+
+ FrameBatchData batchData_{};
+
+ std::optional<std::function<void(VsyncData &data)>> wakeupMethod_ = std::nullopt;
+
+ std::optional<int64_t> lastStart_ = std::nullopt;
+ int framesRemaining_ = 0;
+ std::promise<bool> framesDone_{};
+
+ static std::unique_ptr<Renderer> sRenderer;
};
diff --git a/hostsidetests/adpf/app/hintsession/src/cpp/Utility.h b/hostsidetests/adpf/app/hintsession/src/cpp/Utility.h
index 2dfbfb14..be5a2ab 100644
--- a/hostsidetests/adpf/app/hintsession/src/cpp/Utility.h
+++ b/hostsidetests/adpf/app/hintsession/src/cpp/Utility.h
@@ -16,6 +16,7 @@
#pragma once
#include <cassert>
+#include <chrono>
#include <string>
#include "Renderer.h"
@@ -44,4 +45,24 @@
static float *buildIdentityMatrix(float *outMatrix);
static void setFailure(std::string message, Renderer *renderer = nullptr);
+
+ static int64_t now() {
+ return duration_cast<std::chrono::nanoseconds>(
+ std::chrono::steady_clock::now().time_since_epoch())
+ .count();
+ }
+
+ // Converts lists of numbers into strings, so they can be
+ // passed up to the Java code the results map.
+ template <typename T>
+ static std::string serializeValues(const std::vector<T> &values) {
+ std::stringstream stream;
+ for (auto &&value : values) {
+ stream << value;
+ stream << ",";
+ }
+ std::string out = stream.str();
+ out.pop_back(); // remove the last comma
+ return out;
+ }
};
diff --git a/hostsidetests/adpf/app/hintsession/src/cpp/main.cpp b/hostsidetests/adpf/app/hintsession/src/cpp/main.cpp
index b2b6058..161318f 100644
--- a/hostsidetests/adpf/app/hintsession/src/cpp/main.cpp
+++ b/hostsidetests/adpf/app/hintsession/src/cpp/main.cpp
@@ -14,9 +14,11 @@
* limitations under the License.
*/
+#include <android/native_window.h>
#include <android/performance_hint.h>
#include <assert.h>
#include <jni.h>
+#include <sys/system_properties.h>
#include <algorithm>
#include <chrono>
@@ -38,108 +40,107 @@
using namespace std::chrono_literals;
const constexpr auto kDrawingTimeout = 3s;
-const constexpr int kSamples = 800;
-const constexpr int kCalibrationSamples = 800;
+const constexpr int kSamples = 300;
+const constexpr int kCalibrationSamples = 50;
+bool verboseLogging = true;
-Renderer *getRenderer(android_app *pApp) {
- return (pApp->userData) ? reinterpret_cast<Renderer *>(pApp->userData) : nullptr;
+FrameStats drawFramesWithTarget(int64_t targetDuration, int &events, android_poll_source *&pSource,
+ std::string testName = "") {
+ getRenderer()->updateTargetWorkDuration(targetDuration);
+ return getRenderer()->drawFramesSync(kSamples, events, pSource, testName);
}
-// Converts lists of numbers into strings, so they can be
-// passed up to the Java code the results map.
-template <typename T>
-std::string serializeValues(const std::vector<T> &values) {
- std::stringstream stream;
- for (auto &&value : values) {
- stream << value;
- stream << ",";
+struct CalibrationStep {
+ int physicsSteps;
+ int duration;
+ FrameStats stats;
+};
+
+struct RegressionStats {
+ double m;
+ double c;
+};
+
+RegressionStats calcRegression(std::vector<CalibrationStep> &stepData, bool dropOutlier) {
+ RegressionStats out;
+
+ double xAvg = 0, yAvg = 0;
+ for (auto &&step : stepData) {
+ xAvg += step.physicsSteps;
+ yAvg += step.duration;
}
- std::string out = stream.str();
- out.pop_back(); // remove the last comma
+
+ // Calculate a least-squares regression across the CalibrationSteps
+ double numerator = 0, denominator = 0;
+ for (auto &&step : stepData) {
+ numerator += (step.physicsSteps - xAvg) * (step.duration - yAvg);
+ denominator += (step.physicsSteps - xAvg) * (step.physicsSteps - xAvg);
+ }
+ out.m = numerator / denominator;
+ out.c = yAvg - out.m * xAvg;
+
+ if (dropOutlier) {
+ double maxError = 0;
+ int maxErrorIndex = 0;
+ for (int i = 0; i < stepData.size(); ++i) {
+ double error = stepData[i].duration - (out.m * stepData[i].physicsSteps + out.c);
+ if (error > maxError) {
+ maxError = error;
+ maxErrorIndex = i;
+ }
+ }
+ stepData.erase(stepData.begin() + maxErrorIndex);
+ }
return out;
}
-// Generalizes the loop used to draw frames so that it can be easily started and stopped
-// back to back with different parameters, or after adjustments such as target time adjustments.
-FrameStats drawFrames(int count, android_app *pApp, int &events, android_poll_source *&pSource,
- std::string testName = "") {
- bool namedTest = testName.size() > 0;
- std::vector<int64_t> durations{};
- std::vector<int64_t> intervals{};
+CalibrationStep doCalibrationStep(int iter, int steps, int &events, android_poll_source *&pSource) {
+ CalibrationStep out{.physicsSteps = steps};
+ getRenderer()->setPhysicsIterations(steps);
+ std::string testName = "calibration_" + std::to_string(iter);
+ out.stats = getRenderer()->drawFramesSync(kCalibrationSamples, events, pSource, testName);
+ out.duration = out.stats.medianWorkDuration;
+ return out;
+}
- auto drawStart = std::chrono::steady_clock::now();
- // Iter is -1 so we have a buffer frame before it starts, to eat any delay from time spent
- // between tests
- for (int iter = -1; iter < count && !pApp->destroyRequested;) {
- if (std::chrono::steady_clock::now() - drawStart > kDrawingTimeout) {
- aout << "Stops drawing on " << kDrawingTimeout.count() << "s timeout for test "
- << (namedTest ? testName : "unnamed") << std::endl;
+// Try to create a workload that takes "goal" amount of time
+bool calibrate(int64_t goal, int &events, android_poll_source *&pSource) {
+ int calibrateIter = 0;
+ int bestIter;
+
+ std::vector<CalibrationStep> stepData{};
+
+ double error = 1.0;
+
+ stepData.push_back(doCalibrationStep(calibrateIter++, 5, events, pSource));
+
+ if ((stepData.back().duration + std::chrono::nanoseconds(1ms).count()) > goal) {
+ Utility::setFailure("Baseline load is too expensive", getRenderer());
+ }
+
+ stepData.push_back(doCalibrationStep(calibrateIter++, 500, events, pSource));
+
+ for (; calibrateIter < 20; ++calibrateIter) {
+ // Drop an outlier every few steps because that converges way faster
+ RegressionStats stats = calcRegression(stepData, (calibrateIter % 4 == 0));
+ int nextStep = (goal - stats.c) / stats.m;
+ stepData.push_back(doCalibrationStep(calibrateIter, nextStep, events, pSource));
+
+ error = (abs(static_cast<double>(goal) - static_cast<double>(stepData.back().duration)) /
+ static_cast<double>(goal));
+
+ // If we're ever within 2% of the target, that's good enough
+ aerr << "Error: " << error << std::endl;
+ if (error < 0.02) {
break;
}
- int retval = ALooper_pollOnce(0, nullptr, &events, (void **)&pSource);
- while (retval == ALOOPER_POLL_CALLBACK) {
- retval = ALooper_pollOnce(0, nullptr, &events, (void **)&pSource);
- }
- if (retval >= 0 && pSource) {
- pSource->process(pApp, pSource);
- }
- if (pApp->userData) {
- // Don't add metrics for buffer frames
- if (iter > -1) {
- thread_local auto lastStart = std::chrono::steady_clock::now();
- auto start = std::chrono::steady_clock::now();
-
- // Render a frame
- jlong spinTime = getRenderer(pApp)->render();
- getRenderer(pApp)->reportActualWorkDuration(spinTime);
- durations.push_back(spinTime);
- intervals.push_back((start - lastStart).count());
- lastStart = start;
- }
- ++iter;
- }
}
-
- if (namedTest) {
- getRenderer(pApp)->addResult(testName + "_durations", serializeValues(durations));
- getRenderer(pApp)->addResult(testName + "_intervals", serializeValues(intervals));
- }
-
- return getRenderer(pApp)->getFrameStats(durations, intervals, testName);
-}
-
-FrameStats drawFramesWithTarget(int64_t targetDuration, int &events, android_app *pApp,
- android_poll_source *&pSource, std::string testName = "") {
- getRenderer(pApp)->updateTargetWorkDuration(targetDuration);
- return drawFrames(kSamples, pApp, events, pSource, testName);
-}
-
-// Finds the test settings that best match this device, and returns the
-// duration of the frame's work
-double calibrate(int &events, android_app *pApp, android_poll_source *&pSource) {
- FrameStats calibration[2];
- getRenderer(pApp)->setNumHeads(1);
-
- // Find a number of heads that gives a work duration approximately equal
- // to 1/4 the vsync period. This gives enough time for the frame to finish
- // everything, while still providing enough overhead that differences are easy
- // to notice.
- calibration[0] = drawFrames(kCalibrationSamples, pApp, events, pSource);
- getRenderer(pApp)->setNumHeads(200);
- calibration[1] = drawFrames(kCalibrationSamples, pApp, events, pSource);
-
- double target = calibration[1].medianFrameInterval / 6.0;
- aout << "Goal duration: " << (int)target << std::endl;
- double perHeadDuration =
- (calibration[1].medianWorkDuration - calibration[0].medianWorkDuration) / 200.0;
- aout << "per-head duration: " << (int)perHeadDuration << std::endl;
- int heads = (target - static_cast<double>(calibration[0].medianWorkDuration)) / perHeadDuration;
-
- getRenderer(pApp)->addResult("goal_duration", std::to_string(static_cast<int>(target)));
- getRenderer(pApp)->addResult("heads_count", std::to_string(heads));
-
- getRenderer(pApp)->setNumHeads(std::max(heads, 1));
- return target;
+ getRenderer()->addResult("goal", std::to_string(goal));
+ getRenderer()->addResult("duration", std::to_string(stepData.back().duration));
+ getRenderer()->addResult("heads_count", std::to_string(kHeads));
+ getRenderer()->addResult("interval", std::to_string(stepData.back().stats.medianFrameInterval));
+ getRenderer()->addResult("physics_iterations", std::to_string(stepData.back().physicsSteps));
+ return error < 0.02;
}
// /*!
@@ -150,7 +151,9 @@
void handle_cmd(android_app *pApp, int32_t cmd) {
switch (cmd) {
case APP_CMD_INIT_WINDOW:
- pApp->userData = new Renderer(pApp);
+ Renderer::makeInstance(pApp);
+ pApp->userData = Renderer::getInstance();
+ getRenderer()->setChoreographer(AChoreographer_getInstance());
break;
case APP_CMD_TERM_WINDOW:
// The window is being destroyed. Use this to clean up your userData to avoid leaking
@@ -158,7 +161,7 @@
//
// We have to check if userData is assigned just in case this comes in really quickly
if (pApp->userData) {
- auto *pRenderer = getRenderer(pApp);
+ auto *pRenderer = getRenderer();
Utility::setFailure("App was closed while running!", pRenderer);
}
break;
@@ -167,6 +170,14 @@
}
}
+void setFrameRate(android_app *pApp, float frameRate) {
+ auto t = ANativeWindow_setFrameRate(pApp->window, frameRate,
+ ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT);
+ if (t != 0) {
+ Utility::setFailure("Can't set frame rate to " + std::to_string(frameRate), getRenderer());
+ }
+}
+
void android_main(struct android_app *pApp) {
app_dummy();
@@ -179,62 +190,133 @@
int events;
android_poll_source *pSource = nullptr;
+ // adb shell setprop debug.adpf_cts_verbose_logging true
+ const prop_info *pi_verbose = __system_property_find("debug.adpf_cts_verbose_logging");
+ if (pi_verbose != nullptr) {
+ char value[PROP_VALUE_MAX];
+ __system_property_read(pi_verbose, nullptr, value);
+ if (strcmp(value, "false") == 0) {
+ verboseLogging = false;
+ } else {
+ verboseLogging = true;
+ }
+ }
+
// Ensure renderer is initialized
- drawFrames(1, pApp, events, pSource);
- std::this_thread::sleep_for(10s);
- getRenderer(pApp)->setNumHeads(100);
- // Run an initial load to get the CPU active and stable
- drawFrames(kCalibrationSamples, pApp, events, pSource);
+ while (!pApp->userData) {
+ int retval = ALooper_pollOnce(0, nullptr, &events, (void **)&pSource);
+ while (retval == ALOOPER_POLL_CALLBACK) {
+ retval = ALooper_pollOnce(0, nullptr, &events, (void **)&pSource);
+ }
+ if (retval >= 0 && pSource) {
+ pSource->process(pApp, pSource);
+ }
+ }
- FrameStats initialStats = drawFrames(kSamples, pApp, events, pSource);
+ float frameRate = 60.0f;
+ // adb shell setprop debug.adpf_cts_frame_rate 60.0
+ const prop_info *pi_frame_rate = __system_property_find("debug.adpf_cts_frame_rate");
+ if (pi_frame_rate != nullptr) {
+ char value[PROP_VALUE_MAX];
+ __system_property_read(pi_frame_rate, nullptr, value);
+ char *endptr; // To check for valid conversion
+ float floatValue = strtof(value, &endptr);
+ if (*endptr == '\0') {
+ frameRate = floatValue;
+ }
+ }
+ setFrameRate(pApp, frameRate);
- std::vector<pid_t> tids;
- tids.push_back(gettid());
- bool supported = getRenderer(pApp)->startHintSession(tids, 6 * initialStats.medianWorkDuration);
+ // Make sure everything has long enough to get processed
+ std::this_thread::sleep_for(1s);
+
+ int64_t fpsPeriod = duration_cast<std::chrono::nanoseconds>(1s / frameRate).count();
+
+ bool supported = getRenderer()->startHintSession(fpsPeriod * 2);
if (!supported) {
- JNIManager::sendResultsToJava(getRenderer(pApp)->getResults());
+ JNIManager::sendResultsToJava(getRenderer()->getResults());
return;
}
- // Do an initial load with the session to let CPU settle
- drawFrames(kCalibrationSamples / 2, pApp, events, pSource);
+ getRenderer()->updateTargetWorkDuration(fpsPeriod * 2);
- double calibratedTarget = calibrate(events, pApp, pSource);
+ // Do an initial load with the session to let CPU settle and measure frame deadlines
+ std::vector<int64_t> targets = getRenderer()->findVsyncTargets(events, pSource, kSamples);
+
+ int64_t maxIntendedTarget = fpsPeriod * 1.5;
+ int intendedTargetIndex;
+ for (intendedTargetIndex = 0;
+ intendedTargetIndex < targets.size() && targets[intendedTargetIndex] < maxIntendedTarget;
+ ++intendedTargetIndex);
+ intendedTargetIndex--;
+
+ // The "Heavy Target" is the vsync callback time we expect to get from Choreographer after
+ // running for a while. We use this to decide how expensive to make the workload.
+ const int64_t heavyTarget = targets[intendedTargetIndex];
+
+ // The light target is the third soonest available vsync callback time we get from Choreographer
+ // after running for a while. We use this as a realistic "heavily pipelined" long frame target,
+ // where we would expect the boost to be low.
+ const int64_t lightTarget = targets[intendedTargetIndex + 2];
+
+ aout << "Heavy load: " << heavyTarget << " light load: " << lightTarget << std::endl;
auto testNames = JNIManager::getInstance().getTestNames();
std::set<std::string> testSet{testNames.begin(), testNames.end()};
std::vector<std::function<void()>> tests;
- FrameStats baselineStats = drawFrames(kSamples, pApp, events, pSource, "baseline");
+ // TODO(b/344696346): skip the test if the frame interval is significantly larger than
+ // 16ms? Say the device has limited performance to run this test, or its FPS capped at 30
- double calibrationAccuracy = 1.0 -
- (abs(static_cast<double>(baselineStats.medianWorkDuration) - calibratedTarget) /
- calibratedTarget);
- getRenderer(pApp)->addResult("calibration_accuracy", std::to_string(calibrationAccuracy));
+ // Calibrate a workload that's 30% longer
+ int64_t goal = heavyTarget * 1.3;
+ double benchmarkedError;
+ FrameStats baselineStats;
- const int64_t lightTarget = 6 * baselineStats.medianWorkDuration;
+ bool calibrated = false;
+ for (int i = 0; i < 10 && !calibrated; ++i) {
+ if (!calibrate(goal, events, pSource)) {
+ continue;
+ }
+
+ baselineStats = getRenderer()->drawFramesSync(kSamples, events, pSource, "baseline");
+
+ benchmarkedError = (abs(static_cast<double>(baselineStats.medianWorkDuration - goal)) /
+ static_cast<double>(goal));
+
+ if (benchmarkedError < 0.05) {
+ calibrated = true;
+ getRenderer()->addResult("median_frame_interval",
+ std::to_string(baselineStats.medianFrameInterval));
+ }
+ }
+
+ if (!calibrated) {
+ Utility::setFailure("Failed to calibrate", getRenderer());
+ }
+
+ double calibrationAccuracy = 1.0 - benchmarkedError;
+
+ getRenderer()->addResult("calibration_accuracy", std::to_string(calibrationAccuracy));
// Used to figure out efficiency score on actual runs
- getRenderer(pApp)->setBaselineMedian(baselineStats.medianWorkDuration);
-
- // Set heavy target to be slightly smaller than the baseline to ensure a boost is necessary
- const int64_t heavyTarget = (3 * baselineStats.medianWorkDuration) / 4;
+ getRenderer()->setBaselineMedian(baselineStats.medianWorkDuration);
if (testSet.count("heavy_load") > 0) {
tests.push_back(
- [&]() { drawFramesWithTarget(heavyTarget, events, pApp, pSource, "heavy_load"); });
+ [&]() { drawFramesWithTarget(heavyTarget, events, pSource, "heavy_load"); });
}
if (testSet.count("light_load") > 0) {
tests.push_back(
- [&]() { drawFramesWithTarget(lightTarget, events, pApp, pSource, "light_load"); });
+ [&]() { drawFramesWithTarget(lightTarget, events, pSource, "light_load"); });
}
if (testSet.count("transition_load") > 0) {
tests.push_back([&]() {
- drawFramesWithTarget(lightTarget, events, pApp, pSource, "transition_load_1");
- drawFramesWithTarget(heavyTarget, events, pApp, pSource, "transition_load_2");
- drawFramesWithTarget(lightTarget, events, pApp, pSource, "transition_load_3");
+ drawFramesWithTarget(lightTarget, events, pSource, "transition_load_1");
+ drawFramesWithTarget(heavyTarget, events, pSource, "transition_load_2");
+ drawFramesWithTarget(lightTarget, events, pSource, "transition_load_3");
});
}
@@ -244,5 +326,9 @@
test();
}
- JNIManager::sendResultsToJava(getRenderer(pApp)->getResults());
+ for (auto &&result : getRenderer()->getResults()) {
+ aout << result.first << " : " << result.second << std::endl;
+ }
+
+ JNIManager::sendResultsToJava(getRenderer()->getResults());
}
diff --git a/hostsidetests/adpf/src/android/adpf/cts/ADPFHintSessionHostJUnit4Test.java b/hostsidetests/adpf/src/android/adpf/cts/ADPFHintSessionHostJUnit4Test.java
index c919163..675c938 100644
--- a/hostsidetests/adpf/src/android/adpf/cts/ADPFHintSessionHostJUnit4Test.java
+++ b/hostsidetests/adpf/src/android/adpf/cts/ADPFHintSessionHostJUnit4Test.java
@@ -31,9 +31,12 @@
import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeTrue;
-import com.android.ddmlib.Log;
+import android.platform.test.annotations.LargeTest;
+
import com.android.ddmlib.testrunner.TestResult.TestStatus;
+import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.log.Log;
import com.android.tradefed.result.TestDescription;
import com.android.tradefed.result.TestResult;
import com.android.tradefed.result.TestRunResult;
@@ -81,6 +84,12 @@
return mDevice.executeShellCommand("getprop " + prop).replace("\n", "");
}
+ private void checkSupportedHardware() throws DeviceNotAvailableException {
+ String features = mDevice.executeShellCommand("pm list features");
+ assumeTrue(!features.contains("android.hardware.type.television")
+ && !features.contains("android.hardware.type.watch"));
+ }
+
private void checkMinSdkVersion() throws Exception {
String sdkAsString = getProperty("ro.build.version.sdk");
int sdk = Integer.parseInt(sdkAsString);
@@ -90,11 +99,16 @@
}
private void checkMinVendorApiLevel() throws Exception {
+ boolean apiLevelOverride =
+ getProperty("debug.graphics.hint_session_cts_api_override").contains("True");
String vendorApiLevelStr = getProperty("ro.vendor.api_level");
int apiLevel = Integer.parseInt(vendorApiLevelStr);
- assumeTrue("Test is only enforced on vendor API level >= " + MINIMUM_VENDOR_API_LEVEL
- + " while test device at = " + apiLevel,
- apiLevel >= MINIMUM_VENDOR_API_LEVEL);
+ assumeTrue(
+ "Test is only enforced on vendor API level >= "
+ + MINIMUM_VENDOR_API_LEVEL
+ + " while test device at = "
+ + apiLevel,
+ apiLevelOverride || (apiLevel >= MINIMUM_VENDOR_API_LEVEL));
}
private void checkVirtualDevice() throws Exception {
@@ -133,18 +147,18 @@
private static final String TAG = android.adpf.cts
.ADPFHintSessionHostJUnit4Test.class.getSimpleName();
-
-
/**
- * This tests the ADPF hint session app behavior under various target states,
- * to validate that the load matches what would be expected for a system with
- * those demands. Higher-load tests with lower targets should have smaller durations,
- * because they require more resources to complete the same work in less time.
- * Conversely, lower-load tests with longer targets should have larger durations,
- * since fewer resources are needed to complete their work by the target time.
+ * This tests the ADPF hint session app behavior under various target states, to validate that
+ * the load matches what would be expected for a system with those demands. Higher-load tests
+ * with lower targets should have smaller durations, because they require more resources to
+ * complete the same work in less time. Conversely, lower-load tests with longer targets should
+ * have larger durations, since fewer resources are needed to complete their work by the target
+ * time.
*/
@Test
+ @LargeTest
public void testAdpfHintSession() throws Exception {
+ checkSupportedHardware();
checkMinSdkVersion();
checkMinVendorApiLevel();
checkVirtualDevice();
@@ -153,6 +167,21 @@
mDevice.executeShellCommand("input keyevent KEYCODE_WAKEUP");
mDevice.executeShellCommand("input keyevent KEYCODE_MENU");
mDevice.executeShellCommand("wm dismiss-keyguard");
+
+ int retries = 5;
+ for (int testIter = 1; testIter <= retries; ++testIter) {
+ try {
+ runAdpfTest();
+ break;
+ } catch (Exception e) {
+ if (testIter == retries) {
+ throw e;
+ }
+ }
+ }
+ }
+
+ private void runAdpfTest() throws Exception {
runDeviceTests(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME + "." + ADPF_DEVICE_TEST_CLASS);
final TestDescription testDesc = new TestDescription(
TEST_PACKAGE_NAME + "." + ADPF_DEVICE_TEST_CLASS, "testAdpfHintSession"
@@ -173,17 +202,29 @@
Map<String, String> metrics = result.getMetrics();
HashMap<String, Long> testMedians = new HashMap<>();
+ HashMap<String, Long> testTargets = new HashMap<>();
for (Map.Entry<String, String> entry : metrics.entrySet()) {
String key = entry.getKey();
if (key.endsWith("_durations")) {
String testName = key.substring(0, key.lastIndexOf("_"));
+ if (entry.getValue().length() == 0) {
+ continue;
+ }
long[] numbers = Arrays.stream(entry.getValue().split(","))
.mapToLong(Long::parseLong).toArray();
Long median = getMedian(numbers);
+ Long target = null;
+ String targetString = metrics.get(testName + "_target");
+ if (targetString != null && !targetString.isEmpty()) {
+ target = Long.parseLong(targetString);
+ }
testMedians.put(testName, median);
Log.e(TAG, "Median of " + testName + " is: " + median.toString());
Log.e(TAG, "Target of " + testName + " is: " + metrics.get(testName + "_target"));
+ if (target != null) {
+ testTargets.put(testName, target);
+ }
}
}
@@ -206,9 +247,23 @@
* workload ramps back down.
*/
if (testMedians.containsKey(TRANSITION_LOAD_KEY + "_1")) {
- assertTrue("High-load case was not faster than previous low-load case!",
- isGreater(testMedians.get(TRANSITION_LOAD_KEY + "_1"),
- testMedians.get(TRANSITION_LOAD_KEY + "_2")));
+ // If every median is greater than the heavy-load target
+ // other than the "boosted" second one, this is satisfied
+ if ((testMedians.get(TRANSITION_LOAD_KEY + "_2")
+ < testTargets.get(TRANSITION_LOAD_KEY + "_2"))
+ && (testMedians.get(TRANSITION_LOAD_KEY + "_1")
+ > testTargets.get(TRANSITION_LOAD_KEY + "_2"))
+ && (testMedians.get(TRANSITION_LOAD_KEY + "_3")
+ > testTargets.get(TRANSITION_LOAD_KEY + "_2"))) {
+ return;
+ }
+
+ // Otherwise, check to make sure they are at least trying
+ assertTrue(
+ "High-load case was not faster than previous low-load case!",
+ isGreater(
+ testMedians.get(TRANSITION_LOAD_KEY + "_1"),
+ testMedians.get(TRANSITION_LOAD_KEY + "_2")));
assertTrue("Low-load case was not slower than previous high-load case!",
isLess(testMedians.get(TRANSITION_LOAD_KEY + "_2"),
testMedians.get(TRANSITION_LOAD_KEY + "_3")));
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/PackageVisibilityTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/PackageVisibilityTest.java
index 7e21d9c..e669683 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/PackageVisibilityTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/PackageVisibilityTest.java
@@ -87,7 +87,7 @@
int userId = mUsers[1];
assertTrue(userId > 0);
- getDevice().startUser(userId);
+ getDevice().startUser(userId, /* waitFlag= */ true);
installTestAppForUser(TEST_APK, userId);
installTestAppForUser(TEST_APK, mPrimaryUserId);
@@ -132,24 +132,25 @@
// Uninstall with keep data and reboot
uninstallWithKeepDataForUser(TINY_PKG, userId);
getDevice().rebootUntilOnline();
+ getDevice().waitForDeviceAvailable();
waitForBootCompleted();
- getDevice().startUser(userId);
+ getDevice().startUser(userId, /* waitFlag= */ true);
// It is visible for the installed user, but only if match uninstalled
assertFalse(isAppVisibleForUser(TINY_PKG, userId, MATCH_NORMAL));
assertTrue(isAppVisibleForUser(TINY_PKG, userId, MATCH_UNINSTALLED));
Utils.runDeviceTests(getDevice(), TEST_PKG,
- ".PackageAccessTest", "testPackageAccess_notInOtherUser", userId);
- Utils.runDeviceTests(getDevice(), TEST_PKG,
- ".PackageAccessTest", "testPackageAccess_getPackagesCanSeeTiny", userId);
-
- Utils.runDeviceTests(getDevice(), TEST_PKG,
".PackageAccessTest", "testPackageAccess_notInOtherUserUninstalled",
mPrimaryUserId);
Utils.runDeviceTests(getDevice(), TEST_PKG,
".PackageAccessTest", "testPackageAccess_getPackagesCantSeeTiny", mPrimaryUserId);
+ Utils.runDeviceTests(getDevice(), TEST_PKG,
+ ".PackageAccessTest", "testPackageAccess_notInOtherUser", userId);
+ Utils.runDeviceTests(getDevice(), TEST_PKG,
+ ".PackageAccessTest", "testPackageAccess_getPackagesCanSeeTiny", userId);
+
getDevice().uninstallPackage(TINY_PKG);
getDevice().uninstallPackage(TEST_PKG);
}
diff --git a/hostsidetests/car/src/android/car/cts/PowerPolicyHostTest.java b/hostsidetests/car/src/android/car/cts/PowerPolicyHostTest.java
index c58cd1e..119ae06 100644
--- a/hostsidetests/car/src/android/car/cts/PowerPolicyHostTest.java
+++ b/hostsidetests/car/src/android/car/cts/PowerPolicyHostTest.java
@@ -451,7 +451,8 @@
DEFAULT_STATE_MACHINE_AT_ON_STEP_NAMES[i]);
// power state shouldn't change
testHelper.checkCurrentState(PowerPolicyConstants.CarPowerState.ON);
- testHelper.checkCurrentPolicy(PowerPolicyDef.IdSet.DEFAULT_ALL_ON);
+ // Check for enabled components, since oem can have their own policy defined.
+ testHelper.checkCurrentPowerComponents(PowerPolicyDef.PolicySet.DEFAULT_ALL_ON);
}
}
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/LogHelper.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/LogHelper.java
index 74bcf67..55e8f66 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/LogHelper.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/LogHelper.java
@@ -45,13 +45,14 @@
private static String getLog(ITestDevice device, String tag) throws Exception {
TimeUnit.SECONDS.sleep(WAIT_TIME);
- String logs = device.executeAdbCommand("logcat", "-v", "brief", "-d", tag + ":I", "*:S");
+ String logs = device.executeAdbCommand("logcat", "-v", "brief", "-d", tag + ":I", tag + ":V", "*:S");
// Search for string.
StringBuilder testString = new StringBuilder();
Scanner in = new Scanner(logs);
while (in.hasNextLine()) {
String line = in.nextLine();
- if (line.startsWith("I/" + tag)) {
+ if (line.startsWith("I/" + tag)
+ || line.startsWith("V/" + tag)) {
testString.append(line.split(":")[1].trim());
}
}
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecGeneralProtocolTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecGeneralProtocolTest.java
index 8c42ba04..dc09f5c 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecGeneralProtocolTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecGeneralProtocolTest.java
@@ -96,6 +96,7 @@
// PowerStatusMonitorAction will send GIVE_POWER_STATUS
// AbsoluteVolumeAudioStatusAction will send GIVE_AUDIO_STATUS
// RequestActiveSourceAction will send REQUEST_ACTIVE_SOURCE
+ // launchRoutingControl will send ACTIVE_SOURCE
List<CecOperand> excludeOperands = new ArrayList<>();
excludeOperands.add(CecOperand.GIVE_PHYSICAL_ADDRESS);
excludeOperands.add(CecOperand.GIVE_DEVICE_VENDOR_ID);
@@ -103,6 +104,7 @@
excludeOperands.add(CecOperand.GIVE_POWER_STATUS);
excludeOperands.add(CecOperand.GIVE_AUDIO_STATUS);
excludeOperands.add(CecOperand.REQUEST_ACTIVE_SOURCE);
+ excludeOperands.add(CecOperand.ACTIVE_SOURCE);
hdmiCecClient.sendCecMessage(message, params);
// Default timeout for the incoming command to arrive in response to a request is 2 secs
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecDeviceOsdNameTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecDeviceOsdNameTest.java
index f2e2661..9f4a6cb 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecDeviceOsdNameTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecDeviceOsdNameTest.java
@@ -73,7 +73,7 @@
String deviceName = getDeviceName();
hdmiCecClient.sendCecMessage(LogicalAddress.TV, CecOperand.GIVE_OSD_NAME);
String message = hdmiCecClient.checkExpectedOutput(LogicalAddress.TV, CecOperand.SET_OSD_NAME);
- assertThat(CecMessage.getAsciiString(message)).isEqualTo(deviceName);
+ assertThat(CecMessage.getAsciiString(message).trim()).isEqualTo(deviceName);
}
/**
@@ -94,7 +94,7 @@
CecOperand.GIVE_OSD_NAME,
HdmiCecConstants.ABORT_NOT_IN_CORRECT_MODE);
if (CecMessage.getOperand(message) != CecOperand.FEATURE_ABORT) {
- assertThat(CecMessage.getAsciiString(message)).isEqualTo(deviceName);
+ assertThat(CecMessage.getAsciiString(message).trim()).isEqualTo(deviceName);
}
} finally {
wakeUpDevice();
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecRemoteControlPassThroughTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecRemoteControlPassThroughTest.java
index 4d1341b..1537f35 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecRemoteControlPassThroughTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecRemoteControlPassThroughTest.java
@@ -27,6 +27,7 @@
import android.hdmicec.cts.CecOperand;
import android.hdmicec.cts.HdmiCecConstants;
import android.hdmicec.cts.HdmiControlManagerUtility;
+import android.hdmicec.cts.LogHelper;
import android.hdmicec.cts.LogicalAddress;
import android.hdmicec.cts.RemoteControlPassthrough;
@@ -46,6 +47,9 @@
public final class HdmiCecRemoteControlPassThroughTest extends BaseHdmiCecCtsTest {
private static int DUT_DEVICE_TYPE = HdmiCecConstants.CEC_DEVICE_TYPE_PLAYBACK_DEVICE;
+ private static String DEVICE_DISCOVERY_ACTION_TAG = "DeviceDiscoveryAction";
+ private static String DEVICE_DISCOVERY_ACTION_WRAP_UP_LOG = "Wrap up Device Discovery";
+ private static int DEVICE_DISCOVERY_ACTION_TIMEOUT_SECONDS = 40;
public HdmiCecRemoteControlPassThroughTest() {
super(DUT_DEVICE_TYPE);
@@ -69,9 +73,16 @@
*/
@Test
public void cect_11_2_13_1_UserControlPressAndRelease() throws Exception {
- LogicalAddress dutLogicalAddress = getTargetLogicalAddress(getDevice(), DUT_DEVICE_TYPE);
- RemoteControlPassthrough.checkUserControlPressAndRelease(
- hdmiCecClient, getDevice(), LogicalAddress.TV, dutLogicalAddress);
+ ITestDevice device = getDevice();
+ try {
+ // Wait for DeviceDiscoveryAction to end before starting the test.
+ LogHelper.waitForLog(device, DEVICE_DISCOVERY_ACTION_TAG,
+ DEVICE_DISCOVERY_ACTION_TIMEOUT_SECONDS, DEVICE_DISCOVERY_ACTION_WRAP_UP_LOG);
+ } finally {
+ LogicalAddress dutLogicalAddress = getTargetLogicalAddress(device, DUT_DEVICE_TYPE);
+ RemoteControlPassthrough.checkUserControlPressAndRelease(
+ hdmiCecClient, device, LogicalAddress.TV, dutLogicalAddress);
+ }
}
/**
@@ -81,9 +92,17 @@
*/
@Test
public void cect_11_2_13_2_UserControlPressAndHold() throws Exception {
- LogicalAddress dutLogicalAddress = getTargetLogicalAddress(getDevice(), DUT_DEVICE_TYPE);
- RemoteControlPassthrough.checkUserControlPressAndHold(
- hdmiCecClient, getDevice(), LogicalAddress.TV, dutLogicalAddress);
+ ITestDevice device = getDevice();
+ try {
+ // Wait for DeviceDiscoveryAction to end before starting the test.
+ LogHelper.waitForLog(device, DEVICE_DISCOVERY_ACTION_TAG,
+ DEVICE_DISCOVERY_ACTION_TIMEOUT_SECONDS, DEVICE_DISCOVERY_ACTION_WRAP_UP_LOG);
+ } finally {
+ LogicalAddress dutLogicalAddress = getTargetLogicalAddress(device,
+ DUT_DEVICE_TYPE);
+ RemoteControlPassthrough.checkUserControlPressAndHold(
+ hdmiCecClient, device, LogicalAddress.TV, dutLogicalAddress);
+ }
}
/**
@@ -102,9 +121,17 @@
@Test
public void cect_4_8_4_UserControlPressAndRelease_20() throws Exception {
setCec20();
- LogicalAddress dutLogicalAddress = getTargetLogicalAddress(getDevice(), DUT_DEVICE_TYPE);
- RemoteControlPassthrough.checkUserControlPressAndRelease_20(
- hdmiCecClient, getDevice(), LogicalAddress.TV, dutLogicalAddress);
+ ITestDevice device = getDevice();
+ try {
+ // Wait for DeviceDiscoveryAction to end before starting the test.
+ LogHelper.waitForLog(device, DEVICE_DISCOVERY_ACTION_TAG,
+ DEVICE_DISCOVERY_ACTION_TIMEOUT_SECONDS, DEVICE_DISCOVERY_ACTION_WRAP_UP_LOG);
+ } finally {
+ LogicalAddress dutLogicalAddress = getTargetLogicalAddress(device,
+ DUT_DEVICE_TYPE);
+ RemoteControlPassthrough.checkUserControlPressAndRelease_20(
+ hdmiCecClient, device, LogicalAddress.TV, dutLogicalAddress);
+ }
}
/**
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/tv/HdmiCecAbsoluteVolumeControlFollowerTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/tv/HdmiCecAbsoluteVolumeControlFollowerTest.java
index c958ec5..b69194f 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/tv/HdmiCecAbsoluteVolumeControlFollowerTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/tv/HdmiCecAbsoluteVolumeControlFollowerTest.java
@@ -24,8 +24,10 @@
import android.hdmicec.cts.CecMessage;
import android.hdmicec.cts.CecOperand;
import android.hdmicec.cts.HdmiCecConstants;
+import android.hdmicec.cts.LogHelper;
import android.hdmicec.cts.LogicalAddress;
+import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
import org.junit.Rule;
@@ -38,6 +40,10 @@
*/
@RunWith(DeviceJUnit4ClassRunner.class)
public class HdmiCecAbsoluteVolumeControlFollowerTest extends BaseHdmiCecCtsTest {
+ private static String DEVICE_DISCOVERY_ACTION_TAG = "DeviceDiscoveryAction";
+ private static String DEVICE_DISCOVERY_ACTION_WRAP_UP_LOG = "Wrap up Device Discovery";
+ private static int DEVICE_DISCOVERY_ACTION_TIMEOUT_SECONDS = 40;
+
public HdmiCecAbsoluteVolumeControlFollowerTest() {
super(HdmiCecConstants.CEC_DEVICE_TYPE_TV, "-t", "p", "-t", "a");
}
@@ -56,27 +62,34 @@
*/
@Test
public void testSystemAudioModeOn_respondsFeatureAbort() throws Exception {
- AudioManagerHelper.unmuteDevice(getDevice());
+ ITestDevice device = getDevice();
+ try {
+ // Wait for DeviceDiscoveryAction to end before starting the test.
+ LogHelper.waitForLog(device, DEVICE_DISCOVERY_ACTION_TAG,
+ DEVICE_DISCOVERY_ACTION_TIMEOUT_SECONDS, DEVICE_DISCOVERY_ACTION_WRAP_UP_LOG);
+ } finally {
+ AudioManagerHelper.unmuteDevice(device);
- int initialDeviceVolume = AudioManagerHelper.getDutAudioVolume(getDevice());
+ int initialDeviceVolume = AudioManagerHelper.getDutAudioVolume(device);
- getDevice().executeShellCommand("cmd hdmi_control setsam on");
+ device.executeShellCommand("cmd hdmi_control setsam on");
- hdmiCecClient.sendCecMessage(LogicalAddress.PLAYBACK_1,
- CecOperand.SET_AUDIO_VOLUME_LEVEL,
- CecMessage.formatParams((initialDeviceVolume + 50) % 101));
+ hdmiCecClient.sendCecMessage(LogicalAddress.PLAYBACK_1,
+ CecOperand.SET_AUDIO_VOLUME_LEVEL,
+ CecMessage.formatParams((initialDeviceVolume + 50) % 101));
- // Check that the DUT sent
- // <Feature Abort>[Set Audio Volume Level, Not in correct mode to respond]
- String featureAbort = hdmiCecClient.checkExpectedOutput(
- LogicalAddress.PLAYBACK_1, CecOperand.FEATURE_ABORT);
- assertThat(CecOperand.getOperand(CecMessage.getParams(featureAbort, 0, 2)))
- .isEqualTo(CecOperand.SET_AUDIO_VOLUME_LEVEL);
- assertThat(CecMessage.getParams(featureAbort, 2, 4)).isEqualTo(1);
+ // Check that the DUT sent
+ // <Feature Abort>[Set Audio Volume Level, Not in correct mode to respond]
+ String featureAbort = hdmiCecClient.checkExpectedOutput(
+ LogicalAddress.PLAYBACK_1, CecOperand.FEATURE_ABORT);
+ assertThat(CecOperand.getOperand(CecMessage.getParams(featureAbort, 0, 2)))
+ .isEqualTo(CecOperand.SET_AUDIO_VOLUME_LEVEL);
+ assertThat(CecMessage.getParams(featureAbort, 2, 4)).isEqualTo(1);
- // Check that volume did not change
- assertThat(AudioManagerHelper.getDutAudioVolume(getDevice()))
- .isEqualTo(initialDeviceVolume);
+ // Check that volume did not change
+ assertThat(AudioManagerHelper.getDutAudioVolume(device))
+ .isEqualTo(initialDeviceVolume);
+ }
}
/**
diff --git a/hostsidetests/multidevices/nfc/cts_nfc_hce_multi_device_test.py b/hostsidetests/multidevices/nfc/cts_nfc_hce_multi_device_test.py
index 7b6b92f..85edfdc 100644
--- a/hostsidetests/multidevices/nfc/cts_nfc_hce_multi_device_test.py
+++ b/hostsidetests/multidevices/nfc/cts_nfc_hce_multi_device_test.py
@@ -439,6 +439,8 @@
1. Verifies a successful APDU exchange between the emulator and the
payment service with prefix AIDs.
"""
+ asserts.skip_if(not self.emulator.nfc_emulator.isAidPrefixRegistrationSupported(),
+ "Prefix registration is not supported on device")
self._set_up_emulator(
start_emulator_fun=self.emulator.nfc_emulator.startPrefixPaymentEmulatorActivity,
payment_default_service=_PREFIX_PAYMENT_SERVICE_1,
@@ -471,6 +473,8 @@
1. Verifies a successful APDU exchange between the emulator and the
payment service with prefix AIDs.
"""
+ asserts.skip_if(not self.emulator.nfc_emulator.isAidPrefixRegistrationSupported(),
+ "Prefix registration is not supported on device")
self._set_up_emulator(
start_emulator_fun=self.emulator.nfc_emulator.startPrefixPaymentEmulator2Activity,
payment_default_service=_PREFIX_PAYMENT_SERVICE_1,
@@ -499,6 +503,8 @@
1. Verifies successful APDU sequence exchange.
"""
+ asserts.skip_if(not self.emulator.nfc_emulator.isAidPrefixRegistrationSupported(),
+ "Prefix registration is not supported on device")
self._set_up_emulator(
start_emulator_fun=self.emulator.nfc_emulator.startDualNonPaymentPrefixEmulatorActivity)
@@ -804,6 +810,8 @@
1. Verifies APDU exchange is successful between the reader and the
selected service.
"""
+ asserts.skip_if(not self.emulator.nfc_emulator.isAidPrefixRegistrationSupported(),
+ "Prefix registration is not supported on device")
self._set_up_emulator(
start_emulator_fun=
self.emulator.nfc_emulator.startConflictingNonPaymentPrefixEmulatorActivity,
diff --git a/hostsidetests/statsdatom/src/android/cts/statsdatom/perfetto/PerfettoTests.java b/hostsidetests/statsdatom/src/android/cts/statsdatom/perfetto/PerfettoTests.java
index 4389df2..799b0a1 100644
--- a/hostsidetests/statsdatom/src/android/cts/statsdatom/perfetto/PerfettoTests.java
+++ b/hostsidetests/statsdatom/src/android/cts/statsdatom/perfetto/PerfettoTests.java
@@ -185,6 +185,10 @@
if (DeviceUtils.hasFeature(getDevice(), DeviceUtils.FEATURE_WATCH)) return;
StatsdConfig.Builder config = ConfigUtils.createConfigBuilder("AID_NOBODY");
+
+ // TODO(lalitm): remove this once CTS is no longer being released for 24Q3.
+ config.addAllowedLogSource("AID_SHELL");
+
ConfigUtils.addEventMetric(config, AtomsProto.Atom.PERFETTO_TRIGGER_FIELD_NUMBER);
ConfigUtils.uploadConfig(getDevice(), config);
@@ -193,9 +197,14 @@
List<EventMetricData> data = ReportUtils.getEventMetricDataList(getDevice());
assertThat(data).hasSize(1);
- assertThat(extractPerfettoTriggerEvents(data))
- .containsExactly(
- PerfettoTrigger.Event.PERFETTO_TRACED_TRIGGER);
+
+ List<PerfettoTrigger.Event> triggerEvents = extractPerfettoTriggerEvents(data);
+ assertThat(triggerEvents).hasSize(1);
+
+ // TODO(lalitm): remove this once CTS is no longer being released for 24Q3.
+ assertThat(triggerEvents).containsAnyOf(
+ PerfettoTrigger.Event.PERFETTO_TRACED_TRIGGER,
+ PerfettoTrigger.Event.PERFETTO_TRIGGER_PERFETTO_TRIGGER);
}
private ByteString getPerfettoIncidentConfig() {
diff --git a/hostsidetests/statsdatom/src/android/cts/statsdatom/performancehintmanager/PerformanceHintManagerStatsTests.java b/hostsidetests/statsdatom/src/android/cts/statsdatom/performancehintmanager/PerformanceHintManagerStatsTests.java
index f19a28c..31f6f46 100644
--- a/hostsidetests/statsdatom/src/android/cts/statsdatom/performancehintmanager/PerformanceHintManagerStatsTests.java
+++ b/hostsidetests/statsdatom/src/android/cts/statsdatom/performancehintmanager/PerformanceHintManagerStatsTests.java
@@ -47,6 +47,7 @@
import com.android.os.adpf.AdpfSessionTag;
import com.android.os.adpf.PerformanceHintSessionReported;
import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.result.TestDescription;
import com.android.tradefed.result.TestResult;
import com.android.tradefed.result.TestRunResult;
@@ -88,6 +89,7 @@
@Before
public void setUp() throws Exception {
+ checkSupportedHardware();
assertThat(mCtsBuild).isNotNull();
ConfigUtils.removeConfig(getDevice());
ReportUtils.clearReports(getDevice());
@@ -103,6 +105,12 @@
DeviceUtils.uninstallStatsdTestApp(getDevice());
}
+ private void checkSupportedHardware() throws DeviceNotAvailableException {
+ String features = getDevice().executeShellCommand("pm list features");
+ assumeTrue(!features.contains("android.hardware.type.television")
+ && !features.contains("android.hardware.type.watch"));
+ }
+
@Override
public void setBuild(IBuildInfo buildInfo) {
mCtsBuild = buildInfo;
diff --git a/libs/input/src/com/android/cts/input/InjectInputInProcess.kt b/libs/input/src/com/android/cts/input/InjectInputInProcess.kt
new file mode 100755
index 0000000..26b3d4c
--- /dev/null
+++ b/libs/input/src/com/android/cts/input/InjectInputInProcess.kt
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.input.injectinputinprocess
+
+import android.os.Looper
+import android.view.InputDevice
+import android.view.MotionEvent
+import android.view.View
+import com.android.cts.input.MotionEventBuilder
+import com.android.cts.input.PointerBuilder
+import java.util.concurrent.ExecutionException
+import java.util.concurrent.FutureTask
+import org.junit.Assert.fail
+
+/**
+ * Click on the provided view.
+ * May be invoked on the test thread, or on the UI thread. This is only possible to use when the
+ * test is running in the same process as the Android application.
+ *
+ * @param view the view on which to click.
+ * @param x the x location where to click, relative to the View's top left corner
+ * @param y the y location where to click, relative to the View's top left corner
+ */
+fun clickOnView(view: View, x: Int, y: Int) {
+ val clickTask = FutureTask {
+ clickOnViewOnUiThread(view, x, y)
+ }
+ // If we are already on UI thread, then execute the code directly. Otherwise, post the click
+ // task and wait for it to complete.
+ if (Looper.getMainLooper().isCurrentThread) {
+ clickTask.run()
+ } else {
+ view.post(clickTask)
+ }
+
+ try {
+ clickTask.get() // this will block until FutureTask completes on the main thread
+ } catch (e: InterruptedException) {
+ fail("Interrupted while waiting for the click to be processed: $e" )
+ } catch (e: ExecutionException) {
+ fail("Execution failed while waiting for the click to be processed: $e" )
+ }
+}
+
+/**
+ * Click on the center of the provided view.
+ * May be invoked on the test thread, or on the UI thread. This is only possible to use when the
+ * test is running in the same process as the Android application.
+ *
+ * @param view the view on which to click.
+ */
+fun clickOnViewCenter(view: View) {
+ return clickOnView(view, view.width / 2, view.height / 2)
+}
+
+private fun getViewLocationInWindow(view: View): Pair<Int, Int> {
+ val xy = IntArray(2)
+ view.getLocationInWindow(xy)
+ return Pair(xy[0], xy[1])
+}
+
+private fun clickOnViewOnUiThread(view: View, x: Int, y: Int) {
+ val (viewX, viewY) = getViewLocationInWindow(view)
+ val clickX = viewX + x
+ val clickY = viewY + y
+ val event = MotionEventBuilder(
+ MotionEvent.ACTION_DOWN,
+ InputDevice.SOURCE_TOUCHSCREEN
+ ).pointer(
+ PointerBuilder(0, MotionEvent.TOOL_TYPE_FINGER).x(clickX.toFloat()).y(clickY.toFloat())
+ ).build()
+
+ view.dispatchTouchEvent(event)
+ event.action = MotionEvent.ACTION_UP
+ view.dispatchTouchEvent(event)
+}
diff --git a/libs/input/src/com/android/cts/input/InputDeviceAssociationByDescriptor.kt b/libs/input/src/com/android/cts/input/InputDeviceAssociationByDescriptor.kt
index d14ec4b..eb49f24 100644
--- a/libs/input/src/com/android/cts/input/InputDeviceAssociationByDescriptor.kt
+++ b/libs/input/src/com/android/cts/input/InputDeviceAssociationByDescriptor.kt
@@ -35,7 +35,9 @@
*/
class InputDeviceAssociationByDescriptor private constructor(
private val inputManager: InputManager,
- val inputDeviceDescriptor: String,
+ val inputDeviceDescriptor: String?,
+ val inputDevicePort: String?,
+ val byDescriptor: Boolean,
val associatedDisplay: Display
) : AutoCloseable {
@@ -68,6 +70,38 @@
)
}, PERMISSION_ASSOCIATE_INPUT_DEVICE_TO_DISPLAY)
+ waitForDeviceAssociation(deviceId, display)
+
+ return InputDeviceAssociationByDescriptor(
+ inputManager = inputManager,
+ inputDeviceDescriptor = descriptor,
+ inputDevicePort = null,
+ byDescriptor = true,
+ associatedDisplay = display
+ )
+ }
+
+ fun associateByPort(deviceId: Int, port: String, display: Display):
+ InputDeviceAssociationByDescriptor {
+ runWithShellPermissionIdentity({
+ inputManager.addUniqueIdAssociationByPort(
+ port,
+ display.uniqueId!!
+ )
+ }, PERMISSION_ASSOCIATE_INPUT_DEVICE_TO_DISPLAY)
+
+ waitForDeviceAssociation(deviceId, display)
+
+ return InputDeviceAssociationByDescriptor(
+ inputManager = inputManager,
+ inputDeviceDescriptor = null,
+ inputDevicePort = port,
+ byDescriptor = false,
+ associatedDisplay = display
+ )
+ }
+
+ private fun waitForDeviceAssociation(deviceId: Int, display: Display) {
waitForDeviceUpdatesUntil {
val inputDevice = inputManager.getInputDevice(deviceId)!!
inputDevice.associatedDisplayId == display.displayId
@@ -78,8 +112,6 @@
// new transition.
WindowManagerStateHelper().waitForAppTransitionIdleOnDisplay(display.displayId)
instrumentation.uiAutomation.syncInputTransactions()
-
- return InputDeviceAssociationByDescriptor(inputManager, descriptor, display)
}
private fun waitForDeviceUpdatesUntil(condition: () -> Boolean) {
@@ -115,9 +147,15 @@
override fun close() {
if (!closed) {
- runWithShellPermissionIdentity({
- inputManager.removeUniqueIdAssociationByDescriptor(inputDeviceDescriptor)
- }, PERMISSION_ASSOCIATE_INPUT_DEVICE_TO_DISPLAY)
+ if (byDescriptor) {
+ runWithShellPermissionIdentity({
+ inputManager.removeUniqueIdAssociationByDescriptor(inputDeviceDescriptor!!)
+ }, PERMISSION_ASSOCIATE_INPUT_DEVICE_TO_DISPLAY)
+ } else {
+ runWithShellPermissionIdentity({
+ inputManager.removeUniqueIdAssociationByPort(inputDevicePort!!)
+ }, PERMISSION_ASSOCIATE_INPUT_DEVICE_TO_DISPLAY)
+ }
closed = true
}
}
diff --git a/libs/input/src/com/android/cts/input/InputEventMatchers.kt b/libs/input/src/com/android/cts/input/InputEventMatchers.kt
index 0c1e7ad..160ebec 100644
--- a/libs/input/src/com/android/cts/input/InputEventMatchers.kt
+++ b/libs/input/src/com/android/cts/input/InputEventMatchers.kt
@@ -180,6 +180,27 @@
}
}
+fun withModifierState(modifierState: Int): Matcher<KeyEvent> =
+ object : TypeSafeMatcher<KeyEvent>() {
+ override fun describeTo(description: Description) {
+ description.appendText("With modifier state = $modifierState")
+ }
+
+ override fun matchesSafely(event: KeyEvent): Boolean {
+ return (event.metaState and modifierState) == modifierState
+ }
+}
+
+fun withKeyAction(keyAction: Int): Matcher<KeyEvent> = object : TypeSafeMatcher<KeyEvent>() {
+ override fun describeTo(description: Description) {
+ description.appendText("With key action = $keyAction")
+ }
+
+ override fun matchesSafely(event: KeyEvent): Boolean {
+ return event.action == keyAction
+ }
+}
+
fun withEdgeFlags(edgeFlags: Int): Matcher<MotionEvent> = object : TypeSafeMatcher<MotionEvent>() {
override fun describeTo(description: Description) {
description.appendText("With edge flags = 0x${edgeFlags.toString(16)}")
diff --git a/libs/input/src/com/android/cts/input/VirtualInputDevice.java b/libs/input/src/com/android/cts/input/VirtualInputDevice.java
index 2cfde9e..031dea0 100644
--- a/libs/input/src/com/android/cts/input/VirtualInputDevice.java
+++ b/libs/input/src/com/android/cts/input/VirtualInputDevice.java
@@ -41,6 +41,7 @@
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
+import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -119,11 +120,38 @@
registerInputDevice(registerCommand.toString());
if (display != null) {
- mDisplayAssociation = new InputDeviceAssociationByDescriptor.Associator(
- mInstrumentation).associate(mDeviceId, display);
+ if (isDeviceAssociationsAvailable()) {
+ mDisplayAssociation = new InputDeviceAssociationByDescriptor.Associator(
+ mInstrumentation).associate(mDeviceId, display);
+ } else {
+ if (registerCommand instanceof UinputRegisterCommand) {
+ String port = ((UinputRegisterCommand) registerCommand).getPort();
+ mDisplayAssociation = new InputDeviceAssociationByDescriptor.Associator(
+ mInstrumentation).associateByPort(mDeviceId, port, display);
+ } else {
+ Log.w(TAG, "Association by port requires UinputRegisterCommand");
+ }
+ }
}
}
+ /**
+ * Checks if the {@link InputManager#addUniqueIdAssociationByDescriptor} (test API protected by
+ * FLAG_DEVICE_ASSOCIATIONS flag) is available.
+ *
+ * @return {@code true} if the {@link InputManager#addUniqueIdAssociationByDescriptor} test API
+ * is available
+ */
+ private static boolean isDeviceAssociationsAvailable() {
+ final var methods = InputManager.class.getDeclaredMethods();
+ for (Method m : methods) {
+ if ("addUniqueIdAssociationByDescriptor".equals(m.getName())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
protected byte[] readData() throws IOException {
ArrayList<Integer> data = new ArrayList<Integer>();
try {
diff --git a/tests/PhotoPicker/AndroidTest.xml b/tests/PhotoPicker/AndroidTest.xml
index 2351d1c..195331e 100644
--- a/tests/PhotoPicker/AndroidTest.xml
+++ b/tests/PhotoPicker/AndroidTest.xml
@@ -34,6 +34,7 @@
<option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
<option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
<option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
+ <option name="config-descriptor:metadata" key="parameter" value="secondary_user_on_secondary_display" />
<option name="config-descriptor:metadata" key="parameter" value="run_on_sdk_sandbox" />
<option name="config-descriptor:metadata" key="parameter" value="run_on_work_profile" />
<option name="config-descriptor:metadata" key="component" value="framework" />
diff --git a/tests/PhotoPicker/src/android/photopicker/cts/ActionGetContentOnlyTest.java b/tests/PhotoPicker/src/android/photopicker/cts/ActionGetContentOnlyTest.java
index 619a617..9d68667 100644
--- a/tests/PhotoPicker/src/android/photopicker/cts/ActionGetContentOnlyTest.java
+++ b/tests/PhotoPicker/src/android/photopicker/cts/ActionGetContentOnlyTest.java
@@ -24,11 +24,14 @@
import static android.photopicker.cts.util.PhotoPickerUiUtils.SHORT_TIMEOUT;
import static android.photopicker.cts.util.PhotoPickerUiUtils.clickAndWait;
import static android.photopicker.cts.util.PhotoPickerUiUtils.findAndClickBrowse;
+import static android.photopicker.cts.util.PhotoPickerUiUtils.findObject;
import static android.photopicker.cts.util.ResultsAssertionsUtils.assertReadOnlyAccess;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
+import static org.junit.Assume.assumeFalse;
+
import android.content.ClipData;
import android.content.Intent;
import android.net.Uri;
@@ -37,9 +40,13 @@
import android.provider.MediaStore;
import android.util.Pair;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.BySelector;
import androidx.test.uiautomator.UiObject;
+import androidx.test.uiautomator.UiObject2;
import androidx.test.uiautomator.UiObjectNotFoundException;
import androidx.test.uiautomator.UiSelector;
+import androidx.test.uiautomator.Until;
import org.junit.After;
import org.junit.Before;
@@ -47,6 +54,7 @@
import java.util.ArrayList;
import java.util.List;
+import java.util.regex.Pattern;
/**
* Photo Picker tests for PhotoPicker launched via {@link Intent#ACTION_GET_CONTENT} intent
@@ -88,6 +96,9 @@
@Test
public void testMimeTypeFilter() throws Exception {
+ // TODO(b/374851711): Re-enable these tests once b/374851711 is fixed.
+ assumeFalse("DocumentsUi does not support visible background users",
+ isVisibleBackgroundUser());
final Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.addCategory(Intent.CATEGORY_OPENABLE);
@@ -103,6 +114,9 @@
@Test
public void testExtraMimeTypeFilter() throws Exception {
+ // TODO(b/374851711): Re-enable these tests once b/374851711 is fixed.
+ assumeFalse("DocumentsUi does not support visible background users",
+ isVisibleBackgroundUser());
final Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.addCategory(Intent.CATEGORY_OPENABLE);
@@ -119,6 +133,9 @@
@Test
public void testBrowse_singleSelect() throws Exception {
+ // TODO(b/374851711): Re-enable these tests once b/374851711 is fixed.
+ assumeFalse("DocumentsUi does not support visible background users",
+ isVisibleBackgroundUser());
final int itemCount = 1;
List<Pair<Uri, String>> createdImagesData = createImagesAndGetUriAndPath(itemCount,
mContext.getUserId(), /* isFavorite */ false);
@@ -133,7 +150,11 @@
intent.setType("image/*");
mActivity.startActivityForResult(intent, REQUEST_CODE);
- findAndClickBrowse(sDevice);
+ if (isVisibleBackgroundUser()) {
+ findAndClickBrowse(sDevice, getMainDisplayId());
+ } else {
+ findAndClickBrowse(sDevice);
+ }
findAndClickFilesInDocumentsUi(fileNameList);
@@ -144,6 +165,9 @@
@Test
public void testBrowse_multiSelect() throws Exception {
+ // TODO(b/374851711): Re-enable these tests once b/374851711 is fixed.
+ assumeFalse("DocumentsUi does not support visible background users",
+ isVisibleBackgroundUser());
final int itemCount = 3;
List<Pair<Uri, String>> createdImagesData = createImagesAndGetUriAndPath(itemCount,
mContext.getUserId(), /* isFavorite */ false);
@@ -159,7 +183,11 @@
intent.setType("image/*");
mActivity.startActivityForResult(intent, REQUEST_CODE);
- findAndClickBrowse(sDevice);
+ if (isVisibleBackgroundUser()) {
+ findAndClickBrowse(sDevice, getMainDisplayId());
+ } else {
+ findAndClickBrowse(sDevice);
+ }
findAndClickFilesInDocumentsUi(fileNameList);
@@ -183,6 +211,9 @@
@Test
public void testChooserIntent_nonMediaFilter() throws Exception {
+ // TODO(b/374851711): Re-enable these tests once b/374851711 is fixed.
+ assumeFalse("DocumentsUi does not support visible background users",
+ isVisibleBackgroundUser());
final Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
mActivity.startActivityForResult(Intent.createChooser(intent, TAG), REQUEST_CODE);
@@ -207,8 +238,14 @@
private void assertThatShowsDocumentsUiButtons() {
// Assert that "Recent files" header for DocumentsUi shows
// Add a short timeout wait for DocumentsUi to show
- assertThat(new UiObject(new UiSelector().resourceId(sDocumentsUiPackageName
- + ":id/header_title")).waitForExists(SHORT_TIMEOUT)).isTrue();
+ if (isVisibleBackgroundUser()) {
+ final BySelector selector = By.res(Pattern.compile(
+ sDocumentsUiPackageName + ":id/header_title")).displayId(getMainDisplayId());
+ assertThat(sDevice.wait(Until.hasObject(selector), SHORT_TIMEOUT)).isTrue();
+ } else {
+ assertThat(new UiObject(new UiSelector().resourceId(sDocumentsUiPackageName
+ + ":id/header_title")).waitForExists(SHORT_TIMEOUT)).isTrue();
+ }
}
private UiObject findSaveButton() {
@@ -217,18 +254,42 @@
.childSelector(new UiSelector().resourceId("android:id/button1")));
}
+ private UiObject2 findSaveButton(int displayId) {
+ final BySelector containerSelector = By.res(Pattern.compile(
+ sDocumentsUiPackageName + ":id/container_save")).displayId(displayId);
+ final BySelector buttonSelector = containerSelector.hasChild(By.res("android:id/button1"));
+ return sDevice.findObject(buttonSelector);
+ }
+
private void findAndClickFilesInDocumentsUi(List<String> fileNameList) throws Exception {
- final UiSelector docList = getDirectoryListSelector();
- for (String fileName : fileNameList) {
- findAndClickFileInDocumentsUi(docList, fileName);
+ if (isVisibleBackgroundUser()) {
+ final int displayId = getMainDisplayId();
+ final BySelector docList = getDirectoryListSelector(displayId);
+ for (String fileName : fileNameList) {
+ findAndClickFileInDocumentsUi(docList, fileName, displayId);
+ }
+ } else {
+ final UiSelector docList = getDirectoryListSelector();
+ for (String fileName : fileNameList) {
+ findAndClickFileInDocumentsUi(docList, fileName);
+ }
}
findAndClickSelect();
}
private void findAndClickSelect() throws Exception {
- final UiObject selectButton = new UiObject(new UiSelector().resourceId(
- sDocumentsUiPackageName + ":id/action_menu_select"));
- clickAndWait(sDevice, selectButton);
+ if (isVisibleBackgroundUser()) {
+ final int displayId = getMainDisplayId();
+ final BySelector buttonSelector = By.res(Pattern.compile(
+ sDocumentsUiPackageName + ":id/action_menu_select")).displayId(displayId);
+ final UiObject2 selectButton = findObject(sDevice, buttonSelector);
+ clickAndWait(sDevice, selectButton);
+ } else {
+ final UiObject selectButton = new UiObject(new UiSelector().resourceId(
+ sDocumentsUiPackageName + ":id/action_menu_select"));
+ clickAndWait(sDevice, selectButton);
+ }
+
}
private UiSelector getDirectoryListSelector() throws Exception {
@@ -252,6 +313,25 @@
return docList;
}
+ private BySelector getDirectoryListSelector(int displayId) throws Exception {
+ final BySelector docList = By.res(Pattern.compile(sDocumentsUiPackageName
+ + ":id/dir_list")).displayId(displayId);
+
+ // Wait for the first list item to appear
+ assertWithMessage("First list item")
+ .that(sDevice.wait(Until.hasObject(docList.hasChild(By.depth(1))), SHORT_TIMEOUT))
+ .isTrue();
+
+ // Enforce to set the list mode
+ // Because UiScrollable can't reach the real bottom (when WEB_LINKABLE_FILE item)
+ // in grid mode when screen landscape mode
+ final BySelector subMenuSelector = By.res(Pattern.compile(sDocumentsUiPackageName
+ + ":id/sub_menu_list")).displayId(displayId);
+ final UiObject2 subMenu = findObject(sDevice, subMenuSelector);
+ clickAndWait(sDevice, subMenu);
+ return docList;
+ }
+
private void findAndClickFileInDocumentsUi(UiSelector docList, String fileName)
throws Exception {
@@ -280,4 +360,29 @@
targetObject.longClick();
}
+
+ private void findAndClickFileInDocumentsUi(BySelector docList, String fileName, int displayId)
+ throws Exception {
+ // Repeat swipe gesture to find our item
+ final BySelector targetSelect = By.textContains(fileName).displayId(displayId);
+ UiObject2 targetObject = findObject(sDevice, targetSelect);
+ UiObject2 saveButton = findSaveButton(displayId);
+ int stepLimit = 10;
+ while (stepLimit-- > 0) {
+ boolean targetObjectFullyVisible = (saveButton == null)
+ || targetObject.getVisibleBounds().bottom
+ <= saveButton.getVisibleBounds().top;
+ if (targetObjectFullyVisible) {
+ break;
+ }
+ sDevice.swipe(/* startX= */ sDevice.getDisplayWidth() / 2,
+ /* startY= */ sDevice.getDisplayHeight() / 2,
+ /* endX= */ sDevice.getDisplayWidth() / 2,
+ /* endY= */ 0,
+ /* steps= */ 40);
+ targetObject = findObject(sDevice, targetSelect);
+ saveButton = findSaveButton(displayId);
+ }
+ targetObject.longClick();
+ }
}
diff --git a/tests/PhotoPicker/src/android/photopicker/cts/ActionPickImagesOnlyTest.java b/tests/PhotoPicker/src/android/photopicker/cts/ActionPickImagesOnlyTest.java
index 4e951e5..172bc33 100644
--- a/tests/PhotoPicker/src/android/photopicker/cts/ActionPickImagesOnlyTest.java
+++ b/tests/PhotoPicker/src/android/photopicker/cts/ActionPickImagesOnlyTest.java
@@ -42,8 +42,12 @@
import android.util.Log;
import androidx.test.runner.AndroidJUnit4;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.BySelector;
import androidx.test.uiautomator.UiObject;
+import androidx.test.uiautomator.UiObject2;
import androidx.test.uiautomator.UiSelector;
+import androidx.test.uiautomator.Until;
import org.junit.After;
import org.junit.Test;
@@ -120,24 +124,46 @@
intent.putExtra(MediaStore.EXTRA_PICK_IMAGES_MAX, maxCount);
mActivity.startActivityForResult(intent, REQUEST_CODE);
- final List<UiObject> itemList = findItemList(imageCount);
- final int itemCount = itemList.size();
- assertThat(itemCount).isEqualTo(imageCount);
- // Select maxCount + 1 item
- for (int i = 0; i < itemCount; i++) {
- clickAndWait(sDevice, itemList.get(i));
+ if (isVisibleBackgroundUser()) {
+ final int displayId = getMainDisplayId();
+ final List<UiObject2> itemList = findItemList(sDevice, imageCount, displayId);
+ final int itemCount = itemList.size();
+ assertThat(itemCount).isEqualTo(imageCount);
+ // Select maxCount + 1 item
+ for (int i = 0; i < itemCount; i++) {
+ clickAndWait(sDevice, itemList.get(i));
+ }
+
+ final BySelector snackbarSelector = By.text("Select up to 2 items")
+ .displayId(displayId);
+ assertWithMessage(
+ "Timed out while waiting for snackbar to appear on display " + displayId)
+ .that(sDevice.wait(Until.hasObject(snackbarSelector), SHORT_TIMEOUT)).isTrue();
+
+ assertWithMessage("Timed out waiting for snackbar to disappear on display " + displayId)
+ .that(sDevice.wait(Until.gone(snackbarSelector), SHORT_TIMEOUT)).isTrue();
+
+ clickAndWait(sDevice, findAddButton(sDevice, displayId));
+ } else {
+ final List<UiObject> itemList = findItemList(imageCount);
+ final int itemCount = itemList.size();
+ assertThat(itemCount).isEqualTo(imageCount);
+ // Select maxCount + 1 item
+ for (int i = 0; i < itemCount; i++) {
+ clickAndWait(sDevice, itemList.get(i));
+ }
+
+ UiObject snackbarTextView = sDevice.findObject(new UiSelector().text(
+ "Select up to 2 items"));
+ assertWithMessage("Timed out while waiting for snackbar to appear").that(
+ snackbarTextView.waitForExists(SHORT_TIMEOUT)).isTrue();
+
+ assertWithMessage("Timed out waiting for snackbar to disappear").that(
+ snackbarTextView.waitUntilGone(SHORT_TIMEOUT)).isTrue();
+
+ clickAndWait(sDevice, findAddButton());
}
- UiObject snackbarTextView = sDevice.findObject(new UiSelector().text(
- "Select up to 2 items"));
- assertWithMessage("Timed out while waiting for snackbar to appear").that(
- snackbarTextView.waitForExists(SHORT_TIMEOUT)).isTrue();
-
- assertWithMessage("Timed out waiting for snackbar to disappear").that(
- snackbarTextView.waitUntilGone(SHORT_TIMEOUT)).isTrue();
-
- clickAndWait(sDevice, findAddButton());
-
final ClipData clipData = mActivity.getResult().data.getClipData();
final int count = clipData.getItemCount();
assertThat(count).isEqualTo(maxCount);
@@ -151,11 +177,19 @@
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
mActivity.startActivityForResult(intent, REQUEST_CODE);
- final List<UiObject> itemList = findItemList(imageCount);
- final int itemCount = itemList.size();
- assertThat(itemCount).isEqualTo(imageCount);
- // Select 1 item
- clickAndWait(sDevice, itemList.get(0));
+ if (isVisibleBackgroundUser()) {
+ final List<UiObject2> itemList = findItemList(sDevice, imageCount, getMainDisplayId());
+ final int itemCount = itemList.size();
+ assertThat(itemCount).isEqualTo(imageCount);
+ // Select 1 item
+ clickAndWait(sDevice, itemList.get(0));
+ } else {
+ final List<UiObject> itemList = findItemList(imageCount);
+ final int itemCount = itemList.size();
+ assertThat(itemCount).isEqualTo(imageCount);
+ // Select 1 item
+ clickAndWait(sDevice, itemList.get(0));
+ }
final Uri uri = mActivity.getResult().data.getData();
assertPickerUriFormat(ACTION_PICK_IMAGES, uri, mContext.getUserId());
diff --git a/tests/PhotoPicker/src/android/photopicker/cts/ActionUserSelectImagesForAppTest.java b/tests/PhotoPicker/src/android/photopicker/cts/ActionUserSelectImagesForAppTest.java
index 7d56429..ec22c1a 100644
--- a/tests/PhotoPicker/src/android/photopicker/cts/ActionUserSelectImagesForAppTest.java
+++ b/tests/PhotoPicker/src/android/photopicker/cts/ActionUserSelectImagesForAppTest.java
@@ -175,13 +175,25 @@
photoPickerIntent.putExtra(MediaStore.EXTRA_PICK_IMAGES_MAX,
MediaStore.getPickImagesMaxLimit());
launchActivityForResult(photoPickerIntent);
- final ClipData clipData = fetchPickerMedia(mActivity, sDevice, 1);
- // Verify that selected item is a cloud item
- containsExcept(extractMediaIds(clipData, 1), cloudId, String.valueOf(localId));
+ if (isVisibleBackgroundUser()) {
+ final int displayId = getMainDisplayId();
+ final ClipData clipData = fetchPickerMedia(mActivity, sDevice, 1, displayId);
+ // Verify that selected item is a cloud item
+ containsExcept(extractMediaIds(clipData, 1), cloudId, String.valueOf(localId));
- // 2. Verify we can't see cloud item in Picker choice.
- launchActivityForResult(getUserSelectImagesIntent());
- selectAndAddPickerMedia(sDevice, 1);
+ // 2. Verify we can't see cloud item in Picker choice.
+ launchActivityForResult(getUserSelectImagesIntent());
+ selectAndAddPickerMedia(sDevice, 1, displayId);
+ } else {
+ final ClipData clipData = fetchPickerMedia(mActivity, sDevice, 1);
+ // Verify that selected item is a cloud item
+ containsExcept(extractMediaIds(clipData, 1), cloudId, String.valueOf(localId));
+
+ // 2. Verify we can't see cloud item in Picker choice.
+ launchActivityForResult(getUserSelectImagesIntent());
+ selectAndAddPickerMedia(sDevice, 1);
+ }
+
// Query the media_grants to verify that the grant was on local id.
// Please note that READ_MEDIA_VISUAL_USER_SELECTED is granted by declaring it in
diff --git a/tests/PhotoPicker/src/android/photopicker/cts/CloudPhotoPickerTest.java b/tests/PhotoPicker/src/android/photopicker/cts/CloudPhotoPickerTest.java
index 015d811..684bef6 100644
--- a/tests/PhotoPicker/src/android/photopicker/cts/CloudPhotoPickerTest.java
+++ b/tests/PhotoPicker/src/android/photopicker/cts/CloudPhotoPickerTest.java
@@ -401,6 +401,10 @@
intent.putExtra(MediaStore.EXTRA_PICK_IMAGES_MAX, MediaStore.getPickImagesMaxLimit());
mActivity.startActivityForResult(intent, REQUEST_CODE);
+ if (isVisibleBackgroundUser()) {
+ return PhotoPickerCloudUtils.fetchPickerMedia(mActivity, sDevice, maxCount,
+ getMainDisplayId());
+ }
return PhotoPickerCloudUtils.fetchPickerMedia(mActivity, sDevice, maxCount);
}
diff --git a/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerBaseTest.java b/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerBaseTest.java
index fee9ec2..9f1e499 100644
--- a/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerBaseTest.java
+++ b/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerBaseTest.java
@@ -22,11 +22,14 @@
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
+import android.view.Display;
import androidx.annotation.Nullable;
import androidx.test.InstrumentationRegistry;
import androidx.test.uiautomator.UiDevice;
+import com.android.compatibility.common.util.UserHelper;
+
import org.junit.Assume;
import org.junit.Before;
@@ -40,7 +43,7 @@
private static final String TAG = "PhotoPickerBaseTest";
public static int REQUEST_CODE = 42;
protected static final String INVALID_CLOUD_PROVIDER = "Invalid";
- private static final Instrumentation sInstrumentation =
+ protected static final Instrumentation sInstrumentation =
InstrumentationRegistry.getInstrumentation();
public static final String sTargetPackageName =
sInstrumentation.getTargetContext().getPackageName();
@@ -49,6 +52,9 @@
protected GetResultActivity mActivity;
protected Context mContext;
+ private int mDisplayId = Display.DEFAULT_DISPLAY;
+ private boolean mIsVisibleBackgroundUser = false;
+
// Do not use org.junit.BeforeClass (b/260380362) or
// com.android.bedstead.harrier.annotations.BeforeClass (b/246986339#comment18)
// when using DeviceState. Some subclasses of PhotoPickerBaseTest may use DeviceState so avoid
@@ -76,6 +82,9 @@
sInstrumentation.waitForIdleSync();
mActivity.clearResult();
sDevice.waitForIdle();
+ UserHelper userHelper = new UserHelper(mContext);
+ mDisplayId = userHelper.getMainDisplayId();
+ mIsVisibleBackgroundUser = userHelper.isVisibleBackgroundUser();
}
static boolean isHardwareSupported() {
@@ -94,5 +103,13 @@
protected static String getCurrentCloudProvider() throws IOException {
return PhotoPickerCloudUtils.getCurrentCloudProvider(sDevice);
}
+
+ protected int getMainDisplayId() {
+ return mDisplayId;
+ }
+
+ protected boolean isVisibleBackgroundUser() {
+ return mIsVisibleBackgroundUser;
+ }
}
diff --git a/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerCloudUtils.java b/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerCloudUtils.java
index facd006..e81b957 100644
--- a/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerCloudUtils.java
+++ b/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerCloudUtils.java
@@ -41,6 +41,7 @@
import androidx.test.InstrumentationRegistry;
import androidx.test.uiautomator.UiDevice;
import androidx.test.uiautomator.UiObject;
+import androidx.test.uiautomator.UiObject2;
import com.android.modules.utils.build.SdkLevel;
@@ -103,6 +104,30 @@
uiDevice.waitForIdle();
}
+ /**
+ * Selects and adds media items from the media picker interface.
+ *
+ * @param uiDevice The {@link UiDevice} instance to use for interacting with the UI.
+ * @param maxCount an integer value that specifies the maximum number of
+ * media items to select from the picker
+ * @param displayId The id of the target display.
+ * @throws Exception if there is an error during the selection or addition
+ * of media items
+ */
+ public static void selectAndAddPickerMedia(UiDevice uiDevice, int maxCount,
+ int displayId) throws Exception {
+ final List<UiObject2> itemList = findItemList(uiDevice, maxCount, displayId);
+ for (int i = 0; i < itemList.size(); i++) {
+ final UiObject2 item = itemList.get(i);
+ item.click();
+ uiDevice.waitForIdle();
+ }
+
+ final UiObject2 addButton = findAddButton(uiDevice, displayId);
+ addButton.click();
+ uiDevice.waitForIdle();
+ }
+
public static ClipData fetchPickerMedia(GetResultActivity activity, UiDevice uiDevice,
int maxCount) throws Exception {
selectAndAddPickerMedia(uiDevice, maxCount);
@@ -110,6 +135,23 @@
return activity.getResult().data.getClipData();
}
+ /**
+ * Fetches media items from the media picker interface.
+ *
+ * @param activity the activity to get the result
+ * @param uiDevice The {@link UiDevice} instance to use for interacting with the UI.
+ * @param maxCount an integer value that specifies the maximum number of media items to fetch.
+ * @param displayId The id of the target display.
+ * @throws Exception if there is an error during the selection or retrieval of media items
+ * @return ClipData the ClipData object containing the selected media items
+ */
+ public static ClipData fetchPickerMedia(GetResultActivity activity, UiDevice uiDevice,
+ int maxCount, int displayId) throws Exception {
+ selectAndAddPickerMedia(uiDevice, maxCount, displayId);
+
+ return activity.getResult().data.getClipData();
+ }
+
public static void initCloudProviderWithImage(
Context context, PickerProviderMediaGenerator.MediaGenerator mediaGenerator,
String authority, Pair<String, String>... mediaPairs) throws Exception {
diff --git a/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerTest.java b/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerTest.java
index e0015d4..2c4d2aa 100644
--- a/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerTest.java
+++ b/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerTest.java
@@ -34,6 +34,7 @@
import static android.photopicker.cts.util.PhotoPickerUiUtils.findItemList;
import static android.photopicker.cts.util.PhotoPickerUiUtils.findPreviewAddButton;
import static android.photopicker.cts.util.PhotoPickerUiUtils.findPreviewAddOrSelectButton;
+import static android.photopicker.cts.util.PhotoPickerUiUtils.findObject;
import static android.photopicker.cts.util.ResultsAssertionsUtils.assertContainsMimeType;
import static android.photopicker.cts.util.ResultsAssertionsUtils.assertExtension;
import static android.photopicker.cts.util.ResultsAssertionsUtils.assertMimeType;
@@ -41,6 +42,7 @@
import static android.photopicker.cts.util.ResultsAssertionsUtils.assertPickerUriFormat;
import static android.photopicker.cts.util.ResultsAssertionsUtils.assertRedactedReadOnlyAccess;
import static android.provider.MediaStore.ACTION_PICK_IMAGES;
+import static android.view.KeyEvent.KEYCODE_BACK;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
@@ -54,9 +56,14 @@
import android.photopicker.cts.util.PhotoPickerComponentUtils;
import android.provider.MediaStore;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.BySelector;
+import androidx.test.uiautomator.Direction;
import androidx.test.uiautomator.UiObject;
+import androidx.test.uiautomator.UiObject2;
import androidx.test.uiautomator.UiObjectNotFoundException;
import androidx.test.uiautomator.UiSelector;
+import androidx.test.uiautomator.Until;
import org.junit.After;
import org.junit.Before;
@@ -70,6 +77,7 @@
import java.util.Arrays;
import java.util.List;
import java.util.Map;
+import java.util.regex.Pattern;
/**
* Photo Picker Device only tests for common flows.
@@ -121,8 +129,13 @@
final Intent intent = new Intent(mAction);
launchPhotoPickerForIntent(intent);
- final UiObject item = findItemList(itemCount).get(0);
- clickAndWait(sDevice, item);
+ if (isVisibleBackgroundUser()) {
+ final UiObject2 item = findItemList(sDevice, itemCount, getMainDisplayId()).get(0);
+ clickAndWait(sDevice, item);
+ } else {
+ final UiObject item = findItemList(itemCount).get(0);
+ clickAndWait(sDevice, item);
+ }
final Uri uri = mActivity.getResult().data.getData();
assertPickerUriFormat(mAction, uri, mContext.getUserId());
@@ -139,14 +152,25 @@
final Intent intent = new Intent(mAction);
launchPhotoPickerForIntent(intent);
- UiObject albumsTab = sDevice.findObject(new UiSelector().text(
- "Albums"));
- clickAndWait(sDevice, albumsTab);
- final UiObject album = findItemList(1).get(0);
- clickAndWait(sDevice, album);
+ if (isVisibleBackgroundUser()) {
+ int displayId = getMainDisplayId();
+ UiObject2 albumsTab = findObject(sDevice, By.text("Albums").displayId(displayId));
+ clickAndWait(sDevice, albumsTab);
+ final UiObject2 album = findItemList(sDevice, 1, displayId).get(0);
+ clickAndWait(sDevice, album);
- final UiObject item = findItemList(itemCount).get(0);
- clickAndWait(sDevice, item);
+ final UiObject2 item = findItemList(sDevice, itemCount, displayId).get(0);
+ clickAndWait(sDevice, item);
+ } else {
+ UiObject albumsTab = sDevice.findObject(new UiSelector().text(
+ "Albums"));
+ clickAndWait(sDevice, albumsTab);
+ final UiObject album = findItemList(1).get(0);
+ clickAndWait(sDevice, album);
+
+ final UiObject item = findItemList(itemCount).get(0);
+ clickAndWait(sDevice, item);
+ }
final Uri uri = mActivity.getResult().data.getData();
assertPickerUriFormat(mAction, uri, mContext.getUserId());
@@ -163,23 +187,44 @@
addMultipleSelectionFlag(intent);
launchPhotoPickerForIntent(intent);
- UiObject albumsTab = sDevice.findObject(new UiSelector().text(
- "Albums"));
- clickAndWait(sDevice, albumsTab);
- final UiObject album = findItemList(1).get(0);
- clickAndWait(sDevice, album);
+ if (isVisibleBackgroundUser()) {
+ int displayId = getMainDisplayId();
+ UiObject2 albumsTab = findObject(sDevice, By.text("Albums").displayId(displayId));
+ clickAndWait(sDevice, albumsTab);
+ final UiObject2 album = findItemList(sDevice, 1, displayId).get(0);
+ clickAndWait(sDevice, album);
- final List<UiObject> itemList = findItemList(videoCount);
- final int itemCount = itemList.size();
+ final List<UiObject2> itemList = findItemList(sDevice, videoCount, displayId);
+ final int itemCount = itemList.size();
- assertThat(itemCount).isEqualTo(videoCount);
+ assertThat(itemCount).isEqualTo(videoCount);
- for (int i = 0; i < itemCount; i++) {
- clickAndWait(sDevice, itemList.get(i));
+ for (int i = 0; i < itemCount; i++) {
+ clickAndWait(sDevice, itemList.get(i));
+ }
+
+ UiObject2 viewSelectedButton = findObject(sDevice,
+ getViewSelectedButtonSelector(getMainDisplayId()));
+ clickAndWait(sDevice, viewSelectedButton);
+ } else {
+ UiObject albumsTab = sDevice.findObject(new UiSelector().text(
+ "Albums"));
+ clickAndWait(sDevice, albumsTab);
+ final UiObject album = findItemList(1).get(0);
+ clickAndWait(sDevice, album);
+
+ final List<UiObject> itemList = findItemList(videoCount);
+ final int itemCount = itemList.size();
+
+ assertThat(itemCount).isEqualTo(videoCount);
+
+ for (int i = 0; i < itemCount; i++) {
+ clickAndWait(sDevice, itemList.get(i));
+ }
+
+ clickAndWait(sDevice, findViewSelectedButton());
}
- clickAndWait(sDevice, findViewSelectedButton());
-
// Wait for playback to start. This is needed in some devices where playback
// buffering -> ready state takes around 10s.
final long playbackStartTimeout = 10000;
@@ -194,13 +239,23 @@
final Intent intent = new Intent(mAction);
launchPhotoPickerForIntent(intent);
- final UiObject item = findItemList(itemCount).get(0);
- item.longClick();
- sDevice.waitForIdle();
+ if (isVisibleBackgroundUser()) {
+ final UiObject2 item = findItemList(sDevice, itemCount, getMainDisplayId()).get(0);
+ item.longClick();
+ sDevice.waitForIdle();
- final UiObject addButton = findPreviewAddOrSelectButton();
- assertThat(addButton.waitForExists(1000)).isTrue();
- clickAndWait(sDevice, addButton);
+ final UiObject2 addButton = findPreviewAddOrSelectButton(sDevice, getMainDisplayId());
+ assertThat(addButton).isNotNull();
+ clickAndWait(sDevice, addButton);
+ } else {
+ final UiObject item = findItemList(itemCount).get(0);
+ item.longClick();
+ sDevice.waitForIdle();
+
+ final UiObject addButton = findPreviewAddOrSelectButton();
+ assertThat(addButton.waitForExists(1000)).isTrue();
+ clickAndWait(sDevice, addButton);
+ }
final Uri uri = mActivity.getResult().data.getData();
assertPickerUriFormat(mAction, uri, mContext.getUserId());
@@ -215,14 +270,26 @@
addMultipleSelectionFlag(intent);
launchPhotoPickerForIntent(intent);
- final List<UiObject> itemList = findItemList(imageCount);
- final int itemCount = itemList.size();
- assertThat(itemCount).isEqualTo(imageCount);
- for (int i = 0; i < itemCount; i++) {
- clickAndWait(sDevice, itemList.get(i));
- }
+ final int itemCount;
+ if (isVisibleBackgroundUser()) {
+ final List<UiObject2> itemList = findItemList(sDevice, imageCount, getMainDisplayId());
+ itemCount = itemList.size();
+ assertThat(itemCount).isEqualTo(imageCount);
+ for (int i = 0; i < itemCount; i++) {
+ clickAndWait(sDevice, itemList.get(i));
+ }
- clickAndWait(sDevice, findAddButton());
+ clickAndWait(sDevice, findAddButton(sDevice, getMainDisplayId()));
+ } else {
+ final List<UiObject> itemList = findItemList(imageCount);
+ itemCount = itemList.size();
+ assertThat(itemCount).isEqualTo(imageCount);
+ for (int i = 0; i < itemCount; i++) {
+ clickAndWait(sDevice, itemList.get(i));
+ }
+
+ clickAndWait(sDevice, findAddButton());
+ }
final ClipData clipData = mActivity.getResult().data.getClipData();
final int count = clipData.getItemCount();
@@ -245,31 +312,62 @@
addMultipleSelectionFlag(intent);
launchPhotoPickerForIntent(intent);
- final List<UiObject> itemList = findItemList(videoCount);
- final int itemCount = itemList.size();
- assertThat(itemCount).isEqualTo(videoCount);
+ if (isVisibleBackgroundUser()) {
+ final List<UiObject2> itemList = findItemList(sDevice, videoCount, getMainDisplayId());
+ final int itemCount = itemList.size();
+ assertThat(itemCount).isEqualTo(videoCount);
- // Select one item from Photo grid
- clickAndWait(sDevice, itemList.get(0));
+ // Select one item from Photo grid
+ clickAndWait(sDevice, itemList.get(0));
- // Preview the item
- UiObject item = itemList.get(1);
- item.longClick();
- sDevice.waitForIdle();
+ // Preview the item
+ UiObject2 item = itemList.get(1);
+ item.longClick();
+ sDevice.waitForIdle();
- final UiObject addOrSelectButton = findPreviewAddOrSelectButton();
- assertWithMessage("Timed out waiting for AddOrSelectButton to appear")
- .that(addOrSelectButton.waitForExists(1000)).isTrue();
+ final UiObject2 addOrSelectButton =
+ findPreviewAddOrSelectButton(sDevice, getMainDisplayId());
+ assertWithMessage("Timed out waiting for AddOrSelectButton to appear")
+ .that(addOrSelectButton).isNotNull();
- // Select the item from Preview
- clickAndWait(sDevice, addOrSelectButton);
+ // Select the item from Preview
+ clickAndWait(sDevice, addOrSelectButton);
- sDevice.pressBack();
+ // Instrumentation will ensure that back key event is delivered to the proper display
+ // for visible background users.
+ sInstrumentation.sendKeyDownUpSync(KEYCODE_BACK);
- // Select one more item from Photo grid
- clickAndWait(sDevice, itemList.get(2));
+ // Select one more item from Photo grid
+ clickAndWait(sDevice, findItemList(sDevice, videoCount, getMainDisplayId()).get(2));
- clickAndWait(sDevice, findAddButton());
+ clickAndWait(sDevice, findAddButton(sDevice, getMainDisplayId()));
+ } else {
+ final List<UiObject> itemList = findItemList(videoCount);
+ final int itemCount = itemList.size();
+ assertThat(itemCount).isEqualTo(videoCount);
+
+ // Select one item from Photo grid
+ clickAndWait(sDevice, itemList.get(0));
+
+ // Preview the item
+ UiObject item = itemList.get(1);
+ item.longClick();
+ sDevice.waitForIdle();
+
+ final UiObject addOrSelectButton = findPreviewAddOrSelectButton();
+ assertWithMessage("Timed out waiting for AddOrSelectButton to appear")
+ .that(addOrSelectButton.waitForExists(1000)).isTrue();
+
+ // Select the item from Preview
+ clickAndWait(sDevice, addOrSelectButton);
+
+ sDevice.pressBack();
+
+ // Select one more item from Photo grid
+ clickAndWait(sDevice, itemList.get(2));
+
+ clickAndWait(sDevice, findAddButton());
+ }
// Verify that all 3 items are returned
final ClipData clipData = mActivity.getResult().data.getClipData();
@@ -292,25 +390,49 @@
addMultipleSelectionFlag(intent);
launchPhotoPickerForIntent(intent);
- final List<UiObject> itemList = findItemList(imageCount);
- final int itemCount = itemList.size();
- assertThat(itemCount).isEqualTo(imageCount);
- for (int i = 0; i < itemCount; i++) {
- clickAndWait(sDevice, itemList.get(i));
- }
+ final int itemCount;
+ if (isVisibleBackgroundUser()) {
+ final List<UiObject2> itemList = findItemList(sDevice, imageCount, getMainDisplayId());
+ itemCount = itemList.size();
+ assertThat(itemCount).isEqualTo(imageCount);
+ for (int i = 0; i < itemCount; i++) {
+ clickAndWait(sDevice, itemList.get(i));
+ }
- clickAndWait(sDevice, findViewSelectedButton());
+ UiObject2 viewSelectedButton = findObject(sDevice,
+ getViewSelectedButtonSelector(getMainDisplayId()));
+ clickAndWait(sDevice, viewSelectedButton);
+ } else {
+ final List<UiObject> itemList = findItemList(imageCount);
+ itemCount = itemList.size();
+ assertThat(itemCount).isEqualTo(imageCount);
+ for (int i = 0; i < itemCount; i++) {
+ clickAndWait(sDevice, itemList.get(i));
+ }
+
+ clickAndWait(sDevice, findViewSelectedButton());
+ }
// Swipe left three times
swipeLeftAndWait();
swipeLeftAndWait();
swipeLeftAndWait();
- // Deselect one item
- clickAndWait(sDevice, findPreviewSelectedCheckButton());
+ if (isVisibleBackgroundUser()) {
+ // Deselect one item
+ UiObject2 previewSelectedCheckButton = findObject(sDevice,
+ getPreviewSelectedCheckButtonSelector(getMainDisplayId()));
+ clickAndWait(sDevice, previewSelectedCheckButton);
- // Return selected items
- clickAndWait(sDevice, findPreviewAddButton());
+ // Return selected items
+ clickAndWait(sDevice, findPreviewAddButton(sDevice, getMainDisplayId()));
+ } else {
+ // Deselect one item
+ clickAndWait(sDevice, findPreviewSelectedCheckButton());
+
+ // Return selected items
+ clickAndWait(sDevice, findPreviewAddButton());
+ }
final ClipData clipData = mActivity.getResult().data.getClipData();
final int count = clipData.getItemCount();
@@ -325,6 +447,11 @@
@Test
public void testMultiSelect_previewVideoMuteButtonInitial() throws Exception {
+ if (isVisibleBackgroundUser()) {
+ verifyMultiSelect_previewVideoMuteButtonInitialForVisibleBackgroundUser();
+ return;
+ }
+
launchPreviewMultipleWithVideos(/* videoCount */ 1);
final UiObject playPauseButton = findPlayPauseButton();
@@ -373,8 +500,68 @@
// test the video controls
}
+ private void verifyMultiSelect_previewVideoMuteButtonInitialForVisibleBackgroundUser()
+ throws Exception {
+ launchPreviewMultipleWithVideos(/* videoCount */ 1);
+
+ final BySelector playPauseButton = getPlayPauseButtonSelector(getMainDisplayId());
+ final BySelector muteButton = getMuteButtonSelector(getMainDisplayId());
+
+ // check that player controls are visible
+ assertPlayerControlsVisible(playPauseButton, muteButton);
+
+ // Test 1: Initial state of the mute Button
+ // Check that initial state of mute button is mute, i.e., volume off
+ assertMuteButtonState(muteButton, /* isMuted */ true);
+
+ // Test 2: Click Mute Button
+ // Click to unmute the audio
+ UiObject2 previewMuteButton = findObject(sDevice, muteButton);
+ clickAndWait(sDevice, previewMuteButton);
+
+ waitForBinderCallsToComplete();
+
+ // Check that mute button state is unmute, i.e., it shows `volume up` icon
+ assertMuteButtonState(muteButton, /* isMuted */ false);
+ // Click on the muteButton and check that mute button status is now 'mute'
+ clickAndWait(sDevice, previewMuteButton);
+
+ waitForBinderCallsToComplete();
+
+ assertMuteButtonState(muteButton, /* isMuted */ true);
+ // Click on the muteButton and check that mute button status is now unmute
+ clickAndWait(sDevice, previewMuteButton);
+
+ waitForBinderCallsToComplete();
+
+ assertMuteButtonState(muteButton, /* isMuted */ false);
+
+ // Test 3: Next preview resumes mute state
+ // Go back and launch preview again
+ // Instrumentation will ensure that back key event is delivered to the proper display
+ // for visible background users.
+ sInstrumentation.sendKeyDownUpSync(KEYCODE_BACK);
+ UiObject2 viewSelectedButton = findObject(sDevice,
+ getViewSelectedButtonSelector(getMainDisplayId()));
+ clickAndWait(sDevice, viewSelectedButton);
+
+ waitForBinderCallsToComplete();
+
+ // check that player controls are visible
+ assertPlayerControlsVisible(playPauseButton, muteButton);
+ assertMuteButtonState(muteButton, /* isMuted */ false);
+
+ // We don't test the result of the picker here because the intention of the test is only to
+ // test the video controls
+ }
+
@Test
public void testMultiSelect_previewVideoMuteButtonOnSwipe() throws Exception {
+ if (isVisibleBackgroundUser()) {
+ verifyMultiSelect_previewVideoMuteButtonOnSwipeForVisibleBackgroundUser();
+ return;
+ }
+
launchPreviewMultipleWithVideos(/* videoCount */ 3);
final UiObject playPauseButton = findPlayPauseButton();
@@ -417,6 +604,53 @@
// test the video controls
}
+ private void verifyMultiSelect_previewVideoMuteButtonOnSwipeForVisibleBackgroundUser()
+ throws Exception {
+ launchPreviewMultipleWithVideos(/* videoCount */ 3);
+
+ final BySelector playerView = getPlayerViewSelector(getMainDisplayId());
+ final BySelector playPauseButton = getPlayPauseButtonSelector(getMainDisplayId());
+ final BySelector muteButton = getMuteButtonSelector(getMainDisplayId());
+
+ // check that player controls are visible
+ assertPlayerControlsVisible(playPauseButton, muteButton);
+
+ // Test 1: Swipe resumes mute state, with state of the button is 'volume off' / 'mute'
+ assertMuteButtonState(muteButton, /* isMuted */ true);
+ // Swipe to next page and check that muteButton is in mute state.
+ swipeLeftAndWait();
+
+ waitForBinderCallsToComplete();
+
+ // set-up and wait for player controls to be sticky
+ setUpAndAssertStickyPlayerControls(playerView, playPauseButton, muteButton);
+
+ assertMuteButtonState(muteButton, /* isMuted */ true);
+
+ // Test 2: Swipe resumes mute state, with state of mute button 'volume up' / 'unmute'
+ // Click muteButton again to check the next video resumes the previous video's mute state
+ final UiObject2 previewMuteButton = findObject(sDevice, muteButton);
+ clickAndWait(sDevice, previewMuteButton);
+
+ waitForBinderCallsToComplete();
+
+ assertMuteButtonState(muteButton, /* isMuted */ false);
+ // check that next video resumed previous video's mute state
+ swipeLeftAndWait();
+
+ waitForBinderCallsToComplete();
+
+ // Wait for 1s before checking Play/Pause button's visibility
+ sDevice.wait(Until.hasObject(playPauseButton), 1000);
+
+ // check that player controls are visible
+ assertPlayerControlsVisible(playPauseButton, muteButton);
+ assertMuteButtonState(muteButton, /* isMuted */ false);
+
+ // We don't test the result of the picker here because the intention of the test is only to
+ // test the video controls
+ }
+
@Test
public void testVideoPreviewAudioFocus() throws Exception {
final int[] focusStateForTest = new int[1];
@@ -449,16 +683,30 @@
// video preview starts
assertThat(focusStateForTest[0]).isEqualTo(0);
- final UiObject muteButton = findMuteButton();
- // unmute the audio of video preview
- clickAndWait(sDevice, muteButton);
+ if (isVisibleBackgroundUser()) {
+ final BySelector muteButton = getMuteButtonSelector(getMainDisplayId());
+ final UiObject2 previewMuteButton = findObject(sDevice, muteButton);
+ // unmute the audio of video preview
+ clickAndWait(sDevice, previewMuteButton);
- // Remote video preview involves binder calls
- // Wait for Binder calls to complete and device to be idle
- MediaStore.waitForIdle(mContext.getContentResolver());
- sDevice.waitForIdle();
+ // Remote video preview involves binder calls
+ // Wait for Binder calls to complete and device to be idle
+ MediaStore.waitForIdle(mContext.getContentResolver());
+ sDevice.waitForIdle();
- assertMuteButtonState(muteButton, /* isMuted */ false);
+ assertMuteButtonState(muteButton, /* isMuted */ false);
+ } else {
+ final UiObject muteButton = findMuteButton();
+ // unmute the audio of video preview
+ clickAndWait(sDevice, muteButton);
+
+ // Remote video preview involves binder calls
+ // Wait for Binder calls to complete and device to be idle
+ MediaStore.waitForIdle(mContext.getContentResolver());
+ sDevice.waitForIdle();
+
+ assertMuteButtonState(muteButton, /* isMuted */ false);
+ }
// Verify that test lost the audio focus because PhotoPicker has requested audio focus now.
assertThat(focusStateForTest[0]).isEqualTo(AudioManager.AUDIOFOCUS_LOSS_TRANSIENT);
@@ -482,7 +730,11 @@
.isEqualTo("Play");
// Swipe to next video and verify preview gains audio focus
- findPlayButton().swipeLeft(5);
+ if (isVisibleBackgroundUser()) {
+ findPlayButton(getMainDisplayId(), 1000).swipe(Direction.LEFT, 1.0f);
+ } else {
+ findPlayButton().swipeLeft(5);
+ }
findPauseButton().waitForExists(SHORT_TIMEOUT);
// Video preview is now in unmute mode. Hence, PhotoPicker will request audio focus. Verify
// that test lost the audio focus.
@@ -536,14 +788,26 @@
launchPhotoPickerForIntent(intent);
// find all items
- final List<UiObject> itemList = findItemList(-1);
- final int itemCount = itemList.size();
- assertThat(itemCount).isAtLeast(videoCount);
- for (int i = 0; i < itemCount; i++) {
- clickAndWait(sDevice, itemList.get(i));
- }
+ final int itemCount;
+ if (isVisibleBackgroundUser()) {
+ final List<UiObject2> itemList = findItemList(sDevice, -1, getMainDisplayId());
+ itemCount = itemList.size();
+ assertThat(itemCount).isAtLeast(videoCount);
+ for (int i = 0; i < itemCount; i++) {
+ clickAndWait(sDevice, itemList.get(i));
+ }
- clickAndWait(sDevice, findAddButton());
+ clickAndWait(sDevice, findAddButton(sDevice, getMainDisplayId()));
+ } else {
+ final List<UiObject> itemList = findItemList(-1);
+ itemCount = itemList.size();
+ assertThat(itemCount).isAtLeast(videoCount);
+ for (int i = 0; i < itemCount; i++) {
+ clickAndWait(sDevice, itemList.get(i));
+ }
+
+ clickAndWait(sDevice, findAddButton());
+ }
final ClipData clipData = mActivity.getResult().data.getClipData();
final int count = clipData.getItemCount();
@@ -582,14 +846,26 @@
launchPhotoPickerForIntent(intent);
final int totalCount = mj2VideoCount + imageCount;
- final List<UiObject> itemList = findItemList(totalCount);
- final int itemCount = itemList.size();
- assertThat(itemCount).isAtLeast(totalCount);
- for (int i = 0; i < itemCount; i++) {
- clickAndWait(sDevice, itemList.get(i));
- }
+ final int itemCount;
+ if (isVisibleBackgroundUser()) {
+ final List<UiObject2> itemList = findItemList(sDevice, totalCount, getMainDisplayId());
+ itemCount = itemList.size();
+ assertThat(itemCount).isAtLeast(totalCount);
+ for (int i = 0; i < itemCount; i++) {
+ clickAndWait(sDevice, itemList.get(i));
+ }
- clickAndWait(sDevice, findAddButton());
+ clickAndWait(sDevice, findAddButton(sDevice, getMainDisplayId()));
+ } else {
+ final List<UiObject> itemList = findItemList(totalCount);
+ itemCount = itemList.size();
+ assertThat(itemCount).isAtLeast(totalCount);
+ for (int i = 0; i < itemCount; i++) {
+ clickAndWait(sDevice, itemList.get(i));
+ }
+
+ clickAndWait(sDevice, findAddButton());
+ }
final ClipData clipData = mActivity.getResult().data.getClipData();
assertWithMessage("Expected number of items returned to be: " + itemCount)
@@ -618,15 +894,28 @@
intent.putExtra(Intent.EXTRA_MIME_TYPES, new String[] {mimeType});
launchPhotoPickerForIntent(intent);
- // find all items
- final List<UiObject> itemList = findItemList(-1);
- final int itemCount = itemList.size();
- assertThat(itemCount).isAtLeast(videoCount);
- for (int i = 0; i < itemCount; i++) {
- clickAndWait(sDevice, itemList.get(i));
- }
+ final int itemCount;
+ if (isVisibleBackgroundUser()) {
+ // find all items
+ final List<UiObject2> itemList = findItemList(sDevice, -1, getMainDisplayId());
+ itemCount = itemList.size();
+ assertThat(itemCount).isAtLeast(videoCount);
+ for (int i = 0; i < itemCount; i++) {
+ clickAndWait(sDevice, itemList.get(i));
+ }
- clickAndWait(sDevice, findAddButton());
+ clickAndWait(sDevice, findAddButton(sDevice, getMainDisplayId()));
+ } else {
+ // find all items
+ final List<UiObject> itemList = findItemList(-1);
+ itemCount = itemList.size();
+ assertThat(itemCount).isAtLeast(videoCount);
+ for (int i = 0; i < itemCount; i++) {
+ clickAndWait(sDevice, itemList.get(i));
+ }
+
+ clickAndWait(sDevice, findAddButton());
+ }
final ClipData clipData = mActivity.getResult().data.getClipData();
assertWithMessage("Expected number of items returned to be: " + itemCount)
@@ -663,16 +952,31 @@
launchPhotoPickerForIntent(intent);
// 3. Add all items
- final List<UiObject> itemList = findItemList(expectedItemCount);
- final int itemCount = itemList.size();
- assertWithMessage("Unexpected number of media items found in the picker ui")
- .that(itemCount)
- .isEqualTo(expectedItemCount);
+ final int itemCount;
+ if (isVisibleBackgroundUser()) {
+ final List<UiObject2> itemList =
+ findItemList(sDevice, expectedItemCount, getMainDisplayId());
+ itemCount = itemList.size();
+ assertWithMessage("Unexpected number of media items found in the picker ui")
+ .that(itemCount)
+ .isEqualTo(expectedItemCount);
- for (UiObject item : itemList) {
- clickAndWait(sDevice, item);
+ for (UiObject2 item : itemList) {
+ clickAndWait(sDevice, item);
+ }
+ clickAndWait(sDevice, findAddButton(sDevice, getMainDisplayId()));
+ } else {
+ final List<UiObject> itemList = findItemList(expectedItemCount);
+ itemCount = itemList.size();
+ assertWithMessage("Unexpected number of media items found in the picker ui")
+ .that(itemCount)
+ .isEqualTo(expectedItemCount);
+
+ for (UiObject item : itemList) {
+ clickAndWait(sDevice, item);
+ }
+ clickAndWait(sDevice, findAddButton());
}
- clickAndWait(sDevice, findAddButton());
// 4. Get the activity result data to extract the picker uris
final ClipData clipData = mActivity.getResult().data.getClipData();
@@ -698,6 +1002,17 @@
.isEqualTo(expectedContentDescription);
}
+ private void assertMuteButtonState(BySelector muteButtonSelector, boolean isMuted) {
+ // We use content description to assert the state of the mute button, there is no other way
+ // to test this.
+ final String expectedContentDescription = isMuted ? "Unmute video" : "Mute video";
+ final String assertMessage =
+ "Expected mute button content description to be " + expectedContentDescription;
+ UiObject2 muteButton = findObject(sDevice, muteButtonSelector);
+ assertWithMessage(assertMessage).that(muteButton.getContentDescription())
+ .isEqualTo(expectedContentDescription);
+ }
+
private void launchPreviewMultipleWithVideos(int videoCount) throws Exception {
mUriList.addAll(createVideosAndGetUris(videoCount, mContext.getUserId()));
@@ -706,17 +1021,32 @@
addMultipleSelectionFlag(intent);
launchPhotoPickerForIntent(intent);
- final List<UiObject> itemList = findItemList(videoCount);
- final int itemCount = itemList.size();
+ if (isVisibleBackgroundUser()) {
+ final List<UiObject2> itemList = findItemList(sDevice, videoCount, getMainDisplayId());
+ final int itemCount = itemList.size();
- assertThat(itemCount).isEqualTo(videoCount);
+ assertThat(itemCount).isEqualTo(videoCount);
- for (int i = 0; i < itemCount; i++) {
- clickAndWait(sDevice, itemList.get(i));
+ for (int i = 0; i < itemCount; i++) {
+ clickAndWait(sDevice, itemList.get(i));
+ }
+
+ UiObject2 viewSelectedButton = findObject(sDevice,
+ getViewSelectedButtonSelector(getMainDisplayId()));
+ clickAndWait(sDevice, viewSelectedButton);
+ } else {
+ final List<UiObject> itemList = findItemList(videoCount);
+ final int itemCount = itemList.size();
+
+ assertThat(itemCount).isEqualTo(videoCount);
+
+ for (int i = 0; i < itemCount; i++) {
+ clickAndWait(sDevice, itemList.get(i));
+ }
+
+ clickAndWait(sDevice, findViewSelectedButton());
}
- clickAndWait(sDevice, findViewSelectedButton());
-
// Wait for playback to start. This is needed in some devices where playback
// buffering -> ready state takes around 10s.
final long playbackStartTimeout = 10000;
@@ -742,11 +1072,29 @@
assertPlayerControlsVisible(playPauseButton, muteButton);
}
+ private void setUpAndAssertStickyPlayerControls(BySelector playerViewSelector,
+ BySelector playPauseButtonSelector, BySelector muteButtonSelector) throws Exception {
+ // Wait for 1s for player view to exist
+ sDevice.wait(Until.hasObject(playerViewSelector), 1000);
+ // Wait for 1s or Play/Pause button to hide
+ sDevice.wait(Until.gone(playPauseButtonSelector), 1000);
+ // Click on StyledPlayerView to make the video controls visible
+ UiObject2 playerView = findObject(sDevice, playerViewSelector);
+ clickAndWait(sDevice, playerView);
+ assertPlayerControlsVisible(playPauseButtonSelector, muteButtonSelector);
+ }
+
private void assertPlayerControlsVisible(UiObject playPauseButton, UiObject muteButton) {
assertVisible(playPauseButton, "Expected play/pause button to be visible");
assertVisible(muteButton, "Expected mute button to be visible");
}
+ private void assertPlayerControlsVisible(
+ BySelector playPauseButtonSelector, BySelector muteButtonSelctor) {
+ assertVisible(playPauseButtonSelector, "Expected play/pause button to be visible");
+ assertVisible(muteButtonSelctor, "Expected mute button to be visible");
+ }
+
private void assertPlayerControlsDontAutoHide(UiObject playPauseButton, UiObject muteButton) {
assertWithMessage("Expected play/pause button to not auto hide in 1s")
.that(playPauseButton.waitUntilGone(1100)).isFalse();
@@ -757,40 +1105,79 @@
assertWithMessage(message).that(button.exists()).isTrue();
}
+ private void assertVisible(BySelector selector, String message) {
+ assertWithMessage(message)
+ .that(sDevice.wait(Until.hasObject(selector), SHORT_TIMEOUT)).isTrue();
+ }
+
private static UiObject findViewSelectedButton() {
return new UiObject(new UiSelector().resourceIdMatches(
REGEX_PACKAGE_NAME + ":id/button_view_selected"));
}
+ private static BySelector getViewSelectedButtonSelector(int displayId) {
+ return By.res(Pattern.compile(
+ REGEX_PACKAGE_NAME + ":id/button_view_selected")).displayId(displayId);
+ }
+
private static UiObject findPreviewSelectedCheckButton() {
return new UiObject(new UiSelector().resourceIdMatches(
REGEX_PACKAGE_NAME + ":id/preview_selected_check_button"));
}
+ private static BySelector getPreviewSelectedCheckButtonSelector(int displayId) {
+ return By.res(Pattern.compile(
+ REGEX_PACKAGE_NAME + ":id/preview_selected_check_button")).displayId(displayId);
+ }
private static UiObject findPlayerView() {
return new UiObject(new UiSelector().resourceIdMatches(
REGEX_PACKAGE_NAME + ":id/preview_player_view"));
}
+ private static BySelector getPlayerViewSelector(int displayId) {
+ return By.res(Pattern.compile(
+ REGEX_PACKAGE_NAME + ":id/preview_player_view")).displayId(displayId);
+ }
+
private static UiObject findMuteButton() {
return new UiObject(new UiSelector().resourceIdMatches(
REGEX_PACKAGE_NAME + ":id/preview_mute"));
}
+ private static BySelector getMuteButtonSelector(int displayId) {
+ return By.res(Pattern.compile(
+ REGEX_PACKAGE_NAME + ":id/preview_mute")).displayId(displayId);
+ }
+
private static UiObject findPlayPauseButton() {
return new UiObject(new UiSelector().resourceIdMatches(
REGEX_PACKAGE_NAME + ":id/exo_play_pause"));
}
+ private static BySelector getPlayPauseButtonSelector(int displayId) {
+ return By.res(Pattern.compile(
+ REGEX_PACKAGE_NAME + ":id/exo_play_pause")).displayId(displayId);
+ }
+
private static UiObject findPauseButton() {
return new UiObject(new UiSelector().descriptionContains("Pause"));
}
+ private static UiObject2 findPauseButton(int displayId, long timeout) {
+ return sDevice.wait(Until.findObject(
+ By.displayId(displayId).descContains("Pause")), timeout);
+ }
+
private static UiObject findPlayButton() {
return new UiObject(new UiSelector().descriptionContains("Play"));
}
+ private static UiObject2 findPlayButton(int displayId, long timeout) {
+ return sDevice.wait(Until.findObject(
+ By.displayId(displayId).descContains("Play")), timeout);
+ }
+
private static UiObject findPreviewVideoImageView() {
return new UiObject(new UiSelector().resourceIdMatches(
REGEX_PACKAGE_NAME + ":id/preview_video_image"));
diff --git a/tests/PhotoPicker/src/android/photopicker/cts/RemoteVideoPreviewTest.java b/tests/PhotoPicker/src/android/photopicker/cts/RemoteVideoPreviewTest.java
index be7cad0..b40d5b4 100644
--- a/tests/PhotoPicker/src/android/photopicker/cts/RemoteVideoPreviewTest.java
+++ b/tests/PhotoPicker/src/android/photopicker/cts/RemoteVideoPreviewTest.java
@@ -25,6 +25,7 @@
import static android.photopicker.cts.util.PhotoPickerUiUtils.clickAndWait;
import static android.photopicker.cts.util.PhotoPickerUiUtils.findAddButton;
import static android.photopicker.cts.util.PhotoPickerUiUtils.findItemList;
+import static android.photopicker.cts.util.PhotoPickerUiUtils.findObject;
import static android.photopicker.cts.util.PhotoPickerUiUtils.findPreviewAddButton;
import static android.provider.CloudMediaProvider.CloudMediaSurfaceStateChangedCallback.PLAYBACK_STATE_BUFFERING;
import static android.provider.CloudMediaProvider.CloudMediaSurfaceStateChangedCallback.PLAYBACK_STATE_ERROR_PERMANENT_FAILURE;
@@ -51,8 +52,12 @@
import androidx.annotation.Nullable;
import androidx.test.filters.SdkSuppress;
import androidx.test.runner.AndroidJUnit4;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.BySelector;
import androidx.test.uiautomator.UiObject;
+import androidx.test.uiautomator.UiObject2;
import androidx.test.uiautomator.UiSelector;
+import androidx.test.uiautomator.Until;
import org.junit.After;
import org.junit.AfterClass;
@@ -68,6 +73,8 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Pattern;
/**
* PhotoPicker test coverage for remote video preview APIs.
@@ -334,47 +341,95 @@
CloudProviderPrimary.setPlaybackState(surfaceId, PLAYBACK_STATE_BUFFERING);
// Wait for photo picker to receive the event and invoke media play via binder calls.
MediaStore.waitForIdle(mContext.getContentResolver());
- assertWithMessage("Expected circular progress indicator to be visible when state is "
- + "buffering").that(findPreviewProgressIndicator().waitForExists(SHORT_TIMEOUT))
- .isTrue();
+ if (isVisibleBackgroundUser()) {
+ BySelector indicator = getPreviewProgressIndicatorSelector(getMainDisplayId());
+ assertWithMessage("Expected circular progress indicator to be visible when state is "
+ + "buffering").that(sDevice.wait(Until.hasObject(indicator), SHORT_TIMEOUT))
+ .isTrue();
+ } else {
+ assertWithMessage("Expected circular progress indicator to be visible when state is "
+ + "buffering").that(findPreviewProgressIndicator().waitForExists(SHORT_TIMEOUT))
+ .isTrue();
+ }
}
private void verifySnackbarShowsWhenPermanentError(int surfaceId) throws Exception {
CloudProviderPrimary.setPlaybackState(surfaceId, PLAYBACK_STATE_ERROR_PERMANENT_FAILURE);
// Wait for photo picker to receive the event and invoke media play via binder calls.
MediaStore.waitForIdle(mContext.getContentResolver());
- assertWithMessage("Expected snackbar to be visible when state is permanent error")
- .that(findPreviewErrorSnackbar().waitForExists(SHORT_TIMEOUT)).isTrue();
+ if (isVisibleBackgroundUser()) {
+ BySelector snackbar = getPreviewErrorSnackbarSelector(getMainDisplayId());
+ assertWithMessage("Expected snackbar to be visible when state is permanent error")
+ .that(sDevice.wait(Until.hasObject(snackbar), SHORT_TIMEOUT)).isTrue();
+ } else {
+ assertWithMessage("Expected snackbar to be visible when state is permanent error")
+ .that(findPreviewErrorSnackbar().waitForExists(SHORT_TIMEOUT)).isTrue();
+ }
}
private void verifyAlertDialogShowsWhenRetriableError(int surfaceId) throws Exception {
CloudProviderPrimary.setPlaybackState(surfaceId, PLAYBACK_STATE_ERROR_RETRIABLE_FAILURE);
// Wait for photo picker to receive the event and invoke media play via binder calls.
MediaStore.waitForIdle(mContext.getContentResolver());
+ if (isVisibleBackgroundUser()) {
+ final int displayId = getMainDisplayId();
+ BySelector dialogTitle = getPreviewErrorAlertDialogTitleSelector(displayId);
+ BySelector dialogBody = getPreviewErrorAlertDialogBodySelector(displayId);
+ BySelector retryButton = getPreviewErrorAlertDialogRetryButtonSelector(displayId);
+ BySelector cancelButton = getPreviewErrorAlertDialogCancelButtonSelector(displayId);
+ assertWithMessage("Expected alert dialog with title to be visible when state is "
+ + "retriable error")
+ .that(sDevice.wait(Until.hasObject(dialogTitle), SHORT_TIMEOUT))
+ .isTrue();
+ assertWithMessage("Expected alert dialog with text body to be visible when state is "
+ + "retriable error").that(sDevice.hasObject(dialogBody)).isTrue();
+ assertWithMessage("Expected alert dialog with retry button to be visible when state is "
+ + "retriable error").that(sDevice.hasObject(retryButton)).isTrue();
+ assertWithMessage("Expected alert dialog with cancel button to be visible when state "
+ + "is retriable error").that(sDevice.hasObject(cancelButton)).isTrue();
- assertWithMessage("Expected alert dialog with title to be visible when state is retriable "
- + "error").that(findPreviewErrorAlertDialogTitle().waitForExists(SHORT_TIMEOUT))
- .isTrue();
- assertWithMessage("Expected alert dialog with text body to be visible when state is "
- + "retriable error").that(findPreviewErrorAlertDialogBody().exists()).isTrue();
- assertWithMessage("Expected alert dialog with retry button to be visible when state is "
- + "retriable error").that(findPreviewErrorAlertDialogRetryButton().exists())
- .isTrue();
- assertWithMessage("Expected alert dialog with cancel button to be visible when state is "
- + "retriable error").that(findPreviewErrorAlertDialogCancelButton().exists())
- .isTrue();
+ } else {
+ assertWithMessage("Expected alert dialog with title to be visible when state is "
+ + "retriable error")
+ .that(findPreviewErrorAlertDialogTitle().waitForExists(SHORT_TIMEOUT))
+ .isTrue();
+ assertWithMessage("Expected alert dialog with text body to be visible when state is "
+ + "retriable error").that(findPreviewErrorAlertDialogBody().exists()).isTrue();
+ assertWithMessage("Expected alert dialog with retry button to be visible when state is "
+ + "retriable error").that(findPreviewErrorAlertDialogRetryButton().exists())
+ .isTrue();
+ assertWithMessage("Expected alert dialog with cancel button to be visible when state "
+ + "is retriable error").that(findPreviewErrorAlertDialogCancelButton().exists())
+ .isTrue();
+ }
}
private void verifyAlertDialogRetry(int surfaceId) throws Exception {
CloudProviderPrimary.setPlaybackState(surfaceId, PLAYBACK_STATE_ERROR_RETRIABLE_FAILURE);
// Wait for photo picker to receive the event and invoke media play via binder calls.
MediaStore.waitForIdle(mContext.getContentResolver());
+ if (isVisibleBackgroundUser()) {
+ BySelector retryButtonSelector =
+ getPreviewErrorAlertDialogRetryButtonSelector(getMainDisplayId());
+ assertWithMessage("Expected alert dialog with retry button to be visible when state is "
+ + "retriable error")
+ .that(sDevice.wait(Until.hasObject(retryButtonSelector), SHORT_TIMEOUT))
+ .isTrue();
+ UiObject2 retryButton = findObject(sDevice, retryButtonSelector);
+ clickAndWait(sDevice, retryButton);
+ // It needs to take some time before verifying.
+ try {
+ TimeUnit.MILLISECONDS.sleep(SHORT_TIMEOUT);
+ } catch (InterruptedException expected) {
+ }
+ } else {
+ assertWithMessage("Expected alert dialog with retry button to be visible when state is "
+ + "retriable error")
+ .that(findPreviewErrorAlertDialogRetryButton().waitForExists(SHORT_TIMEOUT))
+ .isTrue();
+ clickAndWait(sDevice, findPreviewErrorAlertDialogRetryButton());
+ }
- assertWithMessage("Expected alert dialog with retry button to be visible when state is "
- + "retriable error")
- .that(findPreviewErrorAlertDialogRetryButton().waitForExists(SHORT_TIMEOUT))
- .isTrue();
- clickAndWait(sDevice, findPreviewErrorAlertDialogRetryButton());
mAssertInOrder.verify(mSurfaceControllerListener).onMediaPlay(eq(surfaceId));
}
@@ -415,18 +470,37 @@
intent.putExtra(MediaStore.EXTRA_PICK_IMAGES_MAX, MediaStore.getPickImagesMaxLimit());
mActivity.startActivityForResult(intent, REQUEST_CODE);
- final List<UiObject> itemList = findItemList(count);
- final int itemCount = itemList.size();
+ if (isVisibleBackgroundUser()) {
+ final int displayId = getMainDisplayId();
+ final List<UiObject2> itemList = findItemList(sDevice, count, displayId);
+ final int itemCount = itemList.size();
+ assertThat(itemCount).isEqualTo(count);
- assertThat(itemCount).isEqualTo(count);
+ for (final UiObject2 item : itemList) {
+ item.click();
+ sDevice.waitForIdle();
+ }
- for (final UiObject item : itemList) {
- item.click();
- sDevice.waitForIdle();
+ final UiObject2 viewSelectedButton = findViewSelectedButton(displayId);
+ viewSelectedButton.click();
+ // It needs to take some time for readying the surface controller.
+ try {
+ TimeUnit.MILLISECONDS.sleep(SHORT_TIMEOUT);
+ } catch (InterruptedException expected) {
+ }
+ } else {
+ final List<UiObject> itemList = findItemList(count);
+ final int itemCount = itemList.size();
+ assertThat(itemCount).isEqualTo(count);
+
+ for (final UiObject item : itemList) {
+ item.click();
+ sDevice.waitForIdle();
+ }
+
+ final UiObject viewSelectedButton = findViewSelectedButton();
+ viewSelectedButton.click();
}
-
- final UiObject viewSelectedButton = findViewSelectedButton();
- viewSelectedButton.click();
sDevice.waitForIdle();
// Wait for CloudMediaProvider binder calls to finish.
@@ -438,6 +512,12 @@
REGEX_PACKAGE_NAME + ":id/button_view_selected"));
}
+ private static UiObject2 findViewSelectedButton(int displayId) {
+ final BySelector button = By.res(Pattern.compile(
+ REGEX_PACKAGE_NAME + ":id/button_view_selected")).displayId(displayId);
+ return findObject(sDevice, button);
+ }
+
private void swipeLeftAndWait() throws Exception {
final int width = sDevice.getDisplayWidth();
final int height = sDevice.getDisplayHeight();
@@ -463,23 +543,48 @@
REGEX_PACKAGE_NAME + ":id/preview_progress_indicator"));
}
+ private static BySelector getPreviewProgressIndicatorSelector(int displayId) {
+ return By.res(Pattern.compile(
+ REGEX_PACKAGE_NAME + ":id/preview_progress_indicator")).displayId(displayId);
+ }
+
private static UiObject findPreviewErrorAlertDialogTitle() {
return new UiObject(new UiSelector().text("Trouble playing video"));
}
+ private static BySelector getPreviewErrorAlertDialogTitleSelector(int displayId) {
+ return By.text("Trouble playing video").displayId(displayId);
+ }
+
private static UiObject findPreviewErrorAlertDialogBody() {
return new UiObject(new UiSelector().text("Check your internet connection and try again"));
}
+ private static BySelector getPreviewErrorAlertDialogBodySelector(int displayId) {
+ return By.text("Check your internet connection and try again").displayId(displayId);
+ }
+
private static UiObject findPreviewErrorAlertDialogRetryButton() {
return new UiObject(new UiSelector().textMatches("R(etry|ETRY)"));
}
+ private static BySelector getPreviewErrorAlertDialogRetryButtonSelector(int displayId) {
+ return By.text(Pattern.compile("R(etry|ETRY)")).displayId(displayId);
+ }
+
private static UiObject findPreviewErrorAlertDialogCancelButton() {
return new UiObject(new UiSelector().textMatches("C(ancel|ANCEL)"));
}
+ private static BySelector getPreviewErrorAlertDialogCancelButtonSelector(int displayId) {
+ return By.text(Pattern.compile("C(ancel|ANCEL)")).displayId(displayId);
+ }
+
private static UiObject findPreviewErrorSnackbar() {
return new UiObject(new UiSelector().text("Can't play video"));
}
+
+ private static BySelector getPreviewErrorSnackbarSelector(int displayId) {
+ return By.text("Can't play video").displayId(displayId);
+ }
}
diff --git a/tests/PhotoPicker/src/android/photopicker/cts/util/PhotoPickerUiUtils.java b/tests/PhotoPicker/src/android/photopicker/cts/util/PhotoPickerUiUtils.java
index 89d2f54..b85739a 100644
--- a/tests/PhotoPicker/src/android/photopicker/cts/util/PhotoPickerUiUtils.java
+++ b/tests/PhotoPicker/src/android/photopicker/cts/util/PhotoPickerUiUtils.java
@@ -16,19 +16,25 @@
package android.photopicker.cts.util;
+import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import android.text.format.DateUtils;
import androidx.annotation.NonNull;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.BySelector;
import androidx.test.uiautomator.UiDevice;
import androidx.test.uiautomator.UiObject;
+import androidx.test.uiautomator.UiObject2;
import androidx.test.uiautomator.UiObjectNotFoundException;
import androidx.test.uiautomator.UiScrollable;
import androidx.test.uiautomator.UiSelector;
+import androidx.test.uiautomator.Until;
import java.util.ArrayList;
import java.util.List;
+import java.util.regex.Pattern;
/**
* Photo Picker Utility methods for finding UI elements.
@@ -42,7 +48,8 @@
"com(.google)?.android.providers.media(.module)?";
/**
- * Get the list of items from the photo grid list.
+ * Gets the list of items from the photo grid list.
+ *
* @param itemCount if the itemCount is -1, return all matching items. Otherwise, return the
* item list that its size is not greater than the itemCount.
* @throws Exception
@@ -75,21 +82,117 @@
return itemList;
}
+ /**
+ * Gets the list of items from the photo grid list.
+ *
+ * @param uiDevice The {@link UiDevice} instance to use for interacting with the UI.
+ * @param itemCount if the itemCount is -1, return all matching items. Otherwise, return the
+ * item list that its size is not greater than the itemCount.
+ * @param displayId The id of the target display.
+ * @return a list of {@link UiObject2} representing the found items
+ * @throws Exception if an error occurs while waiting for the first item to appear or
+ * retrieving the items
+ */
+ public static List<UiObject2> findItemList(UiDevice uiDevice, int itemCount, int displayId)
+ throws Exception {
+ final List<UiObject2> itemList = new ArrayList<>();
+ final BySelector gridList = By.res(Pattern.compile(
+ REGEX_PACKAGE_NAME + ":id/picker_tab_recyclerview")).displayId(displayId);
+
+ // Wait for the first item to appear
+ assertWithMessage("Timed out while waiting for first item to appear")
+ .that(uiDevice.wait(Until.hasObject(gridList.hasChild(By.depth(1))), TIMEOUT))
+ .isTrue();
+
+ final BySelector itemSelector = By.res(Pattern.compile(
+ REGEX_PACKAGE_NAME + ":id/icon_thumbnail")).displayId(displayId);
+
+ List<UiObject2> items = uiDevice.findObjects(itemSelector);
+ final int childCount = items.size();
+ final int count = itemCount == -1 ? childCount : itemCount;
+
+ for (int i = 0; i < childCount; i++) {
+ final UiObject2 item = items.get(i);
+ itemList.add(item);
+ if (itemList.size() == count) {
+ break;
+ }
+ }
+ return itemList;
+ }
+
public static UiObject findPreviewAddButton() {
return new UiObject(new UiSelector().resourceIdMatches(
REGEX_PACKAGE_NAME + ":id/preview_add_button"));
}
+ /**
+ * Retrieves the UI object representing the preview add button.
+ *
+ * This method first verifies that the preview add button exists
+ * on the target display.If present, it returns a {@link UiObject2} that can be used to
+ * interact with the preview add button.
+ *
+ * @param uiDevice The {@link UiDevice} instance to use for interacting with the UI.
+ * @param displayId The id of the target display.
+ * @return the {@link UiObject2} representing the found preview add button.
+ */
+ public static UiObject2 findPreviewAddButton(UiDevice uiDevice, int displayId) {
+ final BySelector selector = By.displayId(displayId)
+ .res(Pattern.compile(REGEX_PACKAGE_NAME + ":id/preview_add_button"));
+ UiObject2 button = uiDevice.wait(Until.findObject(selector), SHORT_TIMEOUT);
+ assertThat(button).isNotNull();
+ return button;
+ }
+
public static UiObject findPreviewAddOrSelectButton() {
return new UiObject(new UiSelector().resourceIdMatches(
REGEX_PACKAGE_NAME + ":id/preview_add_or_select_button"));
}
+ /**
+ * Retrieves the UI object representing the preview add or select button.
+ *
+ * <p>This method first verifies that the preview add or select button exists
+ * on the target display.If present, it returns a {@link UiObject2} that can be used to
+ * interact with the preview add or select button.<p>
+ *
+ * @param uiDevice The {@link UiDevice} instance to use for interacting with the UI.
+ * @param displayId The id of the target display.
+ * @return the {@link UiObject2} representing the found preview add or select button.
+ */
+ public static UiObject2 findPreviewAddOrSelectButton(UiDevice uiDevice, int displayId) {
+ final BySelector selector = By.displayId(displayId)
+ .res(Pattern.compile(REGEX_PACKAGE_NAME + ":id/preview_add_or_select_button"));
+ UiObject2 button = uiDevice.wait(Until.findObject(selector), SHORT_TIMEOUT);
+ assertThat(button).isNotNull();
+ return button;
+ }
+
public static UiObject findAddButton() {
return new UiObject(new UiSelector().resourceIdMatches(
REGEX_PACKAGE_NAME + ":id/button_add"));
}
+ /**
+ * Retrieves the UI object representing the 'add' button.
+ *
+ * <p>This method first verifies that the 'add' button exists on the target display.
+ * If present, it returns a {@link UiObject2} that can be used to interact with
+ * the 'add' button.<p>
+ *
+ * @param uiDevice The {@link UiDevice} instance to use for interacting with the UI.
+ * @param displayId The id of the target display.
+ * @return the {@link UiObject2} representing the found add button.
+ */
+ public static UiObject2 findAddButton(UiDevice uiDevice, int displayId) {
+ final BySelector selector = By.res(Pattern.compile(
+ REGEX_PACKAGE_NAME + ":id/button_add")).displayId(displayId);
+ UiObject2 button = uiDevice.wait(Until.findObject(selector), SHORT_TIMEOUT);
+ assertThat(button).isNotNull();
+ return button;
+ }
+
public static UiObject findProfileButton() {
return new UiObject(new UiSelector().resourceIdMatches(
REGEX_PACKAGE_NAME + ":id/profile_button"));
@@ -103,6 +206,27 @@
clickAndWait(uiDevice, browseButton);
}
+ /**
+ * Click the UI object representing the "Browse" button.
+ *
+ * <p>This method first finds and clicks that the overflow menu on the target display.
+ * And it verifies that the "Browse" button exists on the target display. If present,
+ * it clicks {@link UiObject2} that can be used to interact with the "Browse" button.</p>
+ *
+ * @param uiDevice The {@link UiDevice} instance to use for interacting with the UI.
+ * @param displayId The id of the target display.
+ * @throws Exception if an error occurs during the click action or while waiting for the UI
+ */
+ public static void findAndClickBrowse(UiDevice uiDevice, int displayId) throws Exception {
+ final UiObject2 overflowMenu = getOverflowMenuObject(uiDevice, displayId);
+ clickAndWait(uiDevice, overflowMenu);
+
+ UiObject2 browseButton = uiDevice.wait(Until.findObject(
+ By.textContains("Browse").displayId(displayId)), SHORT_TIMEOUT);
+ assertThat(browseButton).isNotNull();
+ clickAndWait(uiDevice, browseButton);
+ }
+
public static UiObject findSettingsOverflowMenuItem(UiDevice uiDevice) throws Exception {
final UiObject overflowMenu = getOverflowMenuObject(uiDevice);
clickAndWait(uiDevice, overflowMenu);
@@ -115,6 +239,24 @@
return new UiObject(new UiSelector().description("More options"));
}
+ /**
+ * Retrieves the UI object representing the overflow menu.
+ *
+ * <p>This method first verifies that the overflow menu exists on the screen. If present,
+ * it returns a {@link UiObject} that can be used to interact with the overflow menu.</p>
+ *
+ * @param uiDevice The {@link UiDevice} instance to use for interacting with the UI.
+ * @param displayId The id of the target display.
+ * @return The {@link UiObject2} representing the overflow menu.
+ */
+ public static UiObject2 getOverflowMenuObject(UiDevice uiDevice, int displayId) {
+ // Wait for overflow menu to appear.
+ verifyOverflowMenuExists(uiDevice, displayId);
+ final BySelector selector = By.desc("More options").displayId(displayId);
+ UiObject2 menu = findObject(uiDevice, selector);
+ return menu;
+ }
+
public static boolean isPhotoPickerVisible() {
return new UiObject(new UiSelector().resourceIdMatches(
PhotoPickerUiUtils.REGEX_PACKAGE_NAME + ":id/bottom_sheet")).waitForExists(TIMEOUT);
@@ -169,6 +311,12 @@
.isTrue();
}
+ private static void verifyOverflowMenuExists(UiDevice uiDevice, int displayId) {
+ BySelector options = By.desc("More options").displayId(displayId);
+ assertWithMessage("Timed out waiting for overflow menu to appear")
+ .that(uiDevice.wait(Until.hasObject(options), TIMEOUT)).isTrue();
+ }
+
public static void verifySettingsActivityIsVisible() {
// id/settings_activity_root is the root layout in activity_photo_picker_settings.xml
assertWithMessage("Timed out waiting for settings activity to appear")
@@ -184,6 +332,19 @@
}
/**
+ * Click the given UI object(UiObject2)
+ *
+ * @param uiDevice The {@link UiDevice} instance to use for interacting with the UI.
+ * @param uiObject2 The {@link UiObject2} The UI object to click
+ * @throws Exception if an error occurs during the click action or while waiting for the UI
+ * to become idle
+ */
+ public static void clickAndWait(UiDevice uiDevice, UiObject2 uiObject2) throws Exception {
+ uiObject2.click();
+ uiDevice.waitForIdle();
+ }
+
+ /**
* Verifies whether the selected tab is the one with the provided title
*/
public static boolean isSelectedTabTitle(
@@ -200,4 +361,112 @@
public static UiObject findObject(@NonNull String resourceId, UiDevice device) {
return device.findObject(new UiSelector().resourceIdMatches(resourceId));
}
+
+ /**
+ * Retrieves a UI object based on the specified resource ID and display ID.
+ *
+ * @param resourceId a non-null string representing the resource ID of the UI object.
+ * @param device The {@link UiDevice} instance to use for interacting with the UI.
+ * @param displayId an integer representing the display ID where the UI object is located.
+ * @return The {@link UiObject2} representing the resource ID and display ID.
+ */
+ public static UiObject2 findObject(@NonNull String resourceId, UiDevice device, int displayId) {
+ final BySelector selector = By.res(Pattern.compile(resourceId)).displayId(displayId);
+ return findObject(device, selector);
+ }
+
+ /**
+ * Retrieves a UI object based on the specified selector
+ *
+ * @param device The {@link UiDevice} instance to use for interacting with the UI.
+ * @param selector the BySelector used to identify the UI object to find
+ * @return the {@link UiObject2} representing the found UI object
+ */
+ public static UiObject2 findObject(@NonNull UiDevice device, @NonNull BySelector selector) {
+ UiObject2 object = device.wait(Until.findObject(selector), SHORT_TIMEOUT);
+ assertThat(object).isNotNull();
+ return object;
+ }
+
+ /**
+ * Asserts that a UI object with the specified resource ID exists within the given timeout.
+ *
+ * @param resourceId The resource ID of the UI object to find.
+ * @param device The {@link UiDevice} instance to use for searching the UI.
+ */
+ public static void assertUiObjectExistsWithId(@NonNull String resourceId, UiDevice device) {
+ assertWithMessage("Couldn't find Ui object with resource Id " + resourceId)
+ .that(findObject(resourceId, device).waitForExists(TIMEOUT)).isTrue();
+ }
+
+ /**
+ * Finds a UI object with the specified resource ID and performs a click action on it.
+ *
+ * @param resourceId The resource ID of the UI object to find and click.
+ * @param device The {@link UiDevice} instance to use for searching the UI.
+ * @throws Exception if an error occurs during the process of finding or clicking the object.
+ */
+ public static void findAndClickUiObjectWithId(@NonNull String resourceId, UiDevice device)
+ throws Exception {
+ clickAndWait(device, findObject(resourceId, device));
+ }
+
+ /**
+ * Finds a UI object with the specified resource ID and performs a click action on it.
+ *
+ * @param resourceId The resource ID of the UI object to find and click.
+ * @param device The {@link UiDevice} instance to use for searching the UI.
+ * @param displayId The id of the target display.
+ * @throws Exception if an error occurs during the process of finding or clicking the object.
+ */
+ public static void findAndClickUiObjectWithId(@NonNull String resourceId, UiDevice device,
+ int displayId) throws Exception {
+ clickAndWait(device, findObject(resourceId, device, displayId));
+ }
+
+ /**
+ * Finds a UI element using UI Automator (UiObject) that matches the provided text.
+ *
+ * @param text The text to match. This can be a regular expression.
+ * @param device The {@link UiDevice} instance to use for searching.
+ */
+ public static UiObject getUiObjectMatchingText(@NonNull String text, UiDevice device) {
+ return device.findObject(new UiSelector().textMatches(text));
+ }
+
+ /**
+ * Gets a UI element using UI Automator (BySelector) that matches the provided text.
+ *
+ * @param text The text to match. This can be a regular expression.
+ * @param displayId The id of the target display.
+ * @return the BySelector for given text and displayId
+ */
+ public static BySelector getUiObjectMatchingTextSelector(@NonNull String text, int displayId) {
+ return By.text(text).displayId(displayId);
+ }
+
+ /**
+ * Finds a UI element using UI Automator (UiObject2) that matches the provided
+ * content description.
+ *
+ * @param text The content description to match.
+ * @param device The {@link UiDevice} instance to use for searching.
+ */
+ public static UiObject2 getUiObjectMatchingDescription(@NonNull String text, UiDevice device) {
+ return device.findObject(By.desc(text));
+ }
+
+ /**
+ * Finds a UI element using UI Automator (UiObject2) that matches the provided
+ * content description.
+ *
+ * @param text The content description to match.
+ * @param device The {@link UiDevice} instance to use for searching.
+ * @param displayId The id of the target display.
+ * @return the {@link UiObject2} for given text and displayId
+ */
+ public static UiObject2 getUiObjectMatchingDescription(@NonNull String text, UiDevice device,
+ int displayId) {
+ return device.findObject(By.desc(text).displayId(displayId));
+ }
}
diff --git a/tests/accessibility/AndroidTest.xml b/tests/accessibility/AndroidTest.xml
index 0ec90a0..a7ffb7c 100644
--- a/tests/accessibility/AndroidTest.xml
+++ b/tests/accessibility/AndroidTest.xml
@@ -22,12 +22,19 @@
<option name="config-descriptor:metadata" key="parameter" value="no_foldable_states" />
<option name="config-descriptor:metadata" key="parameter" value="run_on_sdk_sandbox" />
<target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
- <option name="run-command" value="cmd accessibility set-bind-instant-service-allowed true" />
- <option name="teardown-command" value="cmd accessibility set-bind-instant-service-allowed false" />
- <!-- Enable hidden APIs to allow tests to use reflection, for security tests which
- check reflection abuse. This must be set before installing the test app. -->
+ <option name="run-command"
+ value="cmd accessibility set-bind-instant-service-allowed true" />
+ <option name="teardown-command"
+ value="cmd accessibility set-bind-instant-service-allowed false" />
+ <!-- Enable hidden APIs to allow tests to use reflection, for security tests
+ which check reflection abuse. This must be set before installing the test app. -->
<option name="run-command" value="settings put global hidden_api_policy 1" />
<option name="teardown-command" value="settings delete global hidden_api_policy" />
+ <!-- Dismiss all system dialogs for all users before launch test -->
+ <option name="run-command"
+ value="am broadcast -a android.intent.action.CLOSE_SYSTEM_DIALOGS --user -1" />
+ <!-- Collapse notifications -->
+ <option name="run-command" value="cmd statusbar collapse" />
</target_preparer>
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
diff --git a/tests/accessibility/src/android/view/accessibility/cts/CaptioningManagerTest.java b/tests/accessibility/src/android/view/accessibility/cts/CaptioningManagerTest.java
index 89bc47c..9193985 100644
--- a/tests/accessibility/src/android/view/accessibility/cts/CaptioningManagerTest.java
+++ b/tests/accessibility/src/android/view/accessibility/cts/CaptioningManagerTest.java
@@ -32,6 +32,7 @@
import android.Manifest;
import android.accessibility.cts.common.AccessibilityDumpOnFailureRule;
+import android.accessibilityservice.cts.utils.ActivityLaunchUtils;
import android.app.UiAutomation;
import android.content.res.Resources;
import android.os.ParcelFileDescriptor;
@@ -41,6 +42,7 @@
import androidx.test.runner.AndroidJUnit4;
+import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -76,6 +78,17 @@
mUiAutomation = getInstrumentation().getUiAutomation();
}
+ @After
+ public void cleanUp() {
+ // Turn off all captioning related settings
+ putSecureSetting("odi_captions_enabled", "0");
+ putSecureSetting("odi_captions_volume_ui_enabled", "0");
+ putSecureSetting("accessibility_captioning_enabled", "0");
+
+ // Remove all system dialogs and go back home
+ ActivityLaunchUtils.homeScreenOrBust(getInstrumentation().getContext(), mUiAutomation);
+ }
+
/**
* Tests whether a client can observe changes in caption properties.
*/
diff --git a/tests/accessibilityservice/AndroidTest.xml b/tests/accessibilityservice/AndroidTest.xml
index 78f144e..458b678 100644
--- a/tests/accessibilityservice/AndroidTest.xml
+++ b/tests/accessibilityservice/AndroidTest.xml
@@ -28,6 +28,11 @@
check reflection abuse. This must be set before installing the test app. -->
<option name="run-command" value="settings put global hidden_api_policy 1" />
<option name="teardown-command" value="settings delete global hidden_api_policy" />
+ <!-- Dismiss all system dialogs for all users before launch test -->
+ <option name="run-command"
+ value="am broadcast -a android.intent.action.CLOSE_SYSTEM_DIALOGS --user -1" />
+ <!-- Collapse notifications -->
+ <option name="run-command" value="cmd statusbar collapse" />
</target_preparer>
<target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
<option name="cleanup" value="true" />
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/activities/NotTouchableWindowTestActivity.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/activities/NotTouchableWindowTestActivity.java
index 039b948..3eb95f0 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/activities/NotTouchableWindowTestActivity.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/activities/NotTouchableWindowTestActivity.java
@@ -22,6 +22,8 @@
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.os.Bundle;
+import android.view.Display;
+import android.view.DisplayCutout;
import android.view.Gravity;
import android.view.View;
import android.view.WindowManager;
@@ -40,7 +42,7 @@
throw new IllegalStateException("Window already exists");
}
rootView = new View(context);
- params = createDefaultWindowParams();
+ params = createDefaultWindowParams(NotTouchableWindowTestActivity.this.getDisplay());
context.getSystemService(WindowManager.class).addView(rootView, params);
break;
@@ -49,7 +51,7 @@
throw new IllegalStateException("Window already exists");
}
rootView = new Button(context);
- params = createDefaultWindowParams();
+ params = createDefaultWindowParams(NotTouchableWindowTestActivity.this.getDisplay());
params.privateFlags |= PRIVATE_FLAG_TRUSTED_OVERLAY;
context.getSystemService(WindowManager.class).addView(rootView, params);
break;
@@ -98,14 +100,22 @@
this.unregisterReceiver(mBroadcastReceiver);
}
- private static WindowManager.LayoutParams createDefaultWindowParams() {
+ private static WindowManager.LayoutParams createDefaultWindowParams(Display display) {
WindowManager.LayoutParams params = new WindowManager.LayoutParams();
+
+ DisplayCutout cutout = display != null? display.getCutout(): null;
+ if (cutout != null) {
+ params.layoutInDisplayCutoutMode =
+ WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+ }
+
params.width = WindowManager.LayoutParams.MATCH_PARENT;
params.height = WindowManager.LayoutParams.MATCH_PARENT;
params.flags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
+
params.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
params.setFitInsetsTypes(0);
params.gravity = Gravity.TOP;
@@ -113,4 +123,4 @@
return params;
}
-}
\ No newline at end of file
+}
diff --git a/tests/app/AppExitTest/src/android/app/cts/ActivityManagerAppExitInfoTest.java b/tests/app/AppExitTest/src/android/app/cts/ActivityManagerAppExitInfoTest.java
index e61e612..7e1b9053 100644
--- a/tests/app/AppExitTest/src/android/app/cts/ActivityManagerAppExitInfoTest.java
+++ b/tests/app/AppExitTest/src/android/app/cts/ActivityManagerAppExitInfoTest.java
@@ -558,6 +558,9 @@
// Start a process and do nothing
startService(ACTION_FINISH, STUB_SERVICE_NAME, false, false);
+ // Give a few seconds to let stub process enter into cache state.
+ sleep(WAITFOR_SETTLE_DOWN);
+
final ArrayList<IBinder> memConsumers = new ArrayList<>();
List<ApplicationExitInfo> list = new ArrayList<>();
final MemoryConsumerService.TestFuncInterface testFunc =
diff --git a/tests/app/WallpaperTest/res/drawable/icon_blue.jpg b/tests/app/WallpaperTest/res/drawable-nodpi/icon_blue.jpg
similarity index 100%
rename from tests/app/WallpaperTest/res/drawable/icon_blue.jpg
rename to tests/app/WallpaperTest/res/drawable-nodpi/icon_blue.jpg
Binary files differ
diff --git a/tests/app/WallpaperTest/res/drawable/icon_green.jpg b/tests/app/WallpaperTest/res/drawable-nodpi/icon_green.jpg
similarity index 100%
rename from tests/app/WallpaperTest/res/drawable/icon_green.jpg
rename to tests/app/WallpaperTest/res/drawable-nodpi/icon_green.jpg
Binary files differ
diff --git a/tests/app/WallpaperTest/res/drawable/icon_red.jpg b/tests/app/WallpaperTest/res/drawable-nodpi/icon_red.jpg
similarity index 100%
rename from tests/app/WallpaperTest/res/drawable/icon_red.jpg
rename to tests/app/WallpaperTest/res/drawable-nodpi/icon_red.jpg
Binary files differ
diff --git a/tests/app/WallpaperTest/res/drawable/robot.png b/tests/app/WallpaperTest/res/drawable-nodpi/robot.png
similarity index 100%
rename from tests/app/WallpaperTest/res/drawable/robot.png
rename to tests/app/WallpaperTest/res/drawable-nodpi/robot.png
Binary files differ
diff --git a/tests/app/WallpaperTest/testsdk33/src/android/app/cts/wallpapers/WallpaperManagerSdk33Test.java b/tests/app/WallpaperTest/testsdk33/src/android/app/cts/wallpapers/WallpaperManagerSdk33Test.java
index e0ed494..dcfa6dc 100644
--- a/tests/app/WallpaperTest/testsdk33/src/android/app/cts/wallpapers/WallpaperManagerSdk33Test.java
+++ b/tests/app/WallpaperTest/testsdk33/src/android/app/cts/wallpapers/WallpaperManagerSdk33Test.java
@@ -91,7 +91,7 @@
if (sTvTarget) return;
sWallpaperManager = WallpaperManager.getInstance(context);
- sWallpaperManager.clear(FLAG_SYSTEM | FLAG_LOCK);
+ sWallpaperManager.clearWallpaper();
// ignore for targets that have a live default wallpaper
runWithShellPermissionIdentity(
@@ -117,7 +117,7 @@
@AfterClass
public static void tearDownClass() throws IOException {
if (sRedBitmap != null && !sRedBitmap.isRecycled()) sRedBitmap.recycle();
- if (sWallpaperManager != null) sWallpaperManager.clear(FLAG_SYSTEM | FLAG_LOCK);
+ if (sWallpaperManager != null) sWallpaperManager.clearWallpaper();
sWallpaperManager = null;
}
@@ -179,7 +179,7 @@
public void getWallpaperFile_lock_noPermission_returnsDefault() throws IOException {
sWallpaperManager.setBitmap(sRedBitmap, null, true, FLAG_LOCK);
ParcelFileDescriptor parcelFileDescriptor = sWallpaperManager.getWallpaperFile(FLAG_LOCK);
- sWallpaperManager.clear(FLAG_SYSTEM | FLAG_LOCK);
+ sWallpaperManager.clearWallpaper();
try {
if (parcelFileDescriptor != null) {
Bitmap bitmap = BitmapFactory.decodeFileDescriptor(
diff --git a/tests/app/app/AndroidManifest.xml b/tests/app/app/AndroidManifest.xml
index ea9bde8..cea775a 100644
--- a/tests/app/app/AndroidManifest.xml
+++ b/tests/app/app/AndroidManifest.xml
@@ -444,6 +444,7 @@
android:documentLaunchMode="intoExisting"/>
<activity android:name="android.app.stubs.DisplayTestActivity"
+ android:resizeableActivity="false"
android:configChanges="smallestScreenSize|orientation|screenSize|screenLayout"/>
<activity android:name="android.app.stubs.ToolbarActivity"
diff --git a/tests/app/shared/AndroidManifest.xml b/tests/app/shared/AndroidManifest.xml
index 2eea680..00cdc83 100644
--- a/tests/app/shared/AndroidManifest.xml
+++ b/tests/app/shared/AndroidManifest.xml
@@ -31,5 +31,44 @@
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
</service>
+
+ <!-- The following components are needed for the test to hold the SMS role -->
+ <activity android:name="android.app.stubs.shared.SmsActivity"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.SENDTO" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <data android:scheme="smsto" />
+ </intent-filter>
+ </activity>
+
+ <!-- The following components are needed for the test app to hold the SMS role -->
+
+ <service android:name="android.app.stubs.shared.SmsService"
+ android:permission="android.permission.SEND_RESPOND_VIA_MESSAGE"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.RESPOND_VIA_MESSAGE" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <data android:scheme="smsto" />
+ </intent-filter>
+ </service>
+
+ <receiver android:name="android.app.stubs.shared.SmsReceiver"
+ android:permission="android.permission.BROADCAST_SMS"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.provider.Telephony.SMS_DELIVER" />
+ </intent-filter>
+ </receiver>
+
+ <receiver android:name="android.app.stubs.shared.SmsReceiver2"
+ android:permission="android.permission.BROADCAST_WAP_PUSH"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.provider.Telephony.WAP_PUSH_DELIVER" />
+ <data android:mimeType="application/vnd.wap.mms-message" />
+ </intent-filter>
+ </receiver>
</application>
</manifest>
diff --git a/tests/app/shared/src/android/app/stubs/shared/SmsRoleComponents.kt b/tests/app/shared/src/android/app/stubs/shared/SmsRoleComponents.kt
new file mode 100644
index 0000000..58799ca
--- /dev/null
+++ b/tests/app/shared/src/android/app/stubs/shared/SmsRoleComponents.kt
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2024 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.app.stubs.shared
+
+import android.app.Activity
+import android.app.Service
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.os.IBinder
+
+// Stub services, receivers, and activities that let the test app hold the SMS role
+
+class SmsReceiver : BroadcastReceiver() {
+ override fun onReceive(context: Context?, intent: Intent?) { /* stub */ }
+}
+
+class SmsReceiver2 : BroadcastReceiver() {
+ override fun onReceive(context: Context?, intent: Intent?) { /* stub */ }
+}
+
+class SmsService : Service() {
+ override fun onBind(intent: Intent?): IBinder? { return null }
+}
+
+class SmsActivity : Activity()
diff --git a/tests/app/src/android/app/cts/AppTaskTests.java b/tests/app/src/android/app/cts/AppTaskTests.java
index 9c6792c..15a0a35 100644
--- a/tests/app/src/android/app/cts/AppTaskTests.java
+++ b/tests/app/src/android/app/cts/AppTaskTests.java
@@ -179,7 +179,7 @@
waitAndAssertCondition(() -> targetResumed.value,
"Expected activity brought to front and resumed");
}
- assertTrue(appTask.getTaskInfo().isVisible());
+ waitAndAssertCondition(() -> appTask.getTaskInfo().isVisible(), "Waiting for task visible");
assertEquals(appTask.getTaskInfo().topActivity, firstActivity.getComponentName());
waitAndAssertCondition(() -> firstActivity.isTopResumed,
"First activity is top resumed");
diff --git a/tests/appsearch/AndroidManifest.xml b/tests/appsearch/AndroidManifest.xml
index 3a71c58..4daa0b2 100644
--- a/tests/appsearch/AndroidManifest.xml
+++ b/tests/appsearch/AndroidManifest.xml
@@ -32,20 +32,6 @@
<application android:label="CtsAppSearchTestCases">
<uses-library android:name="android.test.runner"/>
-
- <activity android:name="android.app.appsearch.testutil.functions.ActivityCreationSynchronizer"
- android:exported="true"/>
- <service android:name="android.app.appsearch.testutil.functions.TestAppFunctionService"
- android:exported="true"
- android:permission="android.permission.BIND_APP_FUNCTION_SERVICE"
- android:process=":appfunctions">
- <intent-filter>
- <action android:name="android.app.appsearch.functions.AppFunctionService"/>
- </intent-filter>
- </service>
- <receiver
- android:name="android.app.appsearch.testutil.functions.TestAppFunctionServiceLifecycleReceiver"
- android:exported="false"/>
</application>
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
android:targetPackage="com.android.cts.appsearch"
diff --git a/tests/appsearch/src/com/android/cts/appsearch/functions/AppFunctionManagerCtsTest.java b/tests/appsearch/src/com/android/cts/appsearch/functions/AppFunctionManagerCtsTest.java
deleted file mode 100644
index d6c0496..0000000
--- a/tests/appsearch/src/com/android/cts/appsearch/functions/AppFunctionManagerCtsTest.java
+++ /dev/null
@@ -1,406 +0,0 @@
-/*
- * Copyright (C) 2024 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.app.appsearch.cts.functions;
-
-import static android.app.appsearch.AppSearchResult.RESULT_INTERNAL_ERROR;
-import static android.app.appsearch.AppSearchResult.RESULT_INVALID_ARGUMENT;
-import static android.app.appsearch.AppSearchResult.RESULT_NOT_FOUND;
-import static android.app.appsearch.AppSearchResult.RESULT_SECURITY_ERROR;
-import static android.app.appsearch.AppSearchResult.RESULT_TIMED_OUT;
-import static android.app.appsearch.AppSearchResult.RESULT_UNKNOWN_ERROR;
-import static android.app.appsearch.functions.ExecuteAppFunctionResponse.PROPERTY_RESULT;
-import static android.app.appsearch.testutil.functions.TestAppFunctionServiceLifecycleReceiver.waitForServiceOnCreate;
-import static android.app.appsearch.testutil.functions.TestAppFunctionServiceLifecycleReceiver.waitForServiceOnDestroy;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.app.appsearch.AppSearchManager;
-import android.app.appsearch.AppSearchResult;
-import android.app.appsearch.GenericDocument;
-import android.app.appsearch.functions.AppFunctionManager;
-import android.app.appsearch.functions.ExecuteAppFunctionRequest;
-import android.app.appsearch.functions.ExecuteAppFunctionResponse;
-import android.app.appsearch.testutil.PackageUtil;
-import android.app.appsearch.testutil.functions.ActivityCreationSynchronizer;
-import android.app.appsearch.testutil.functions.TestAppFunctionServiceLifecycleReceiver;
-import android.content.Context;
-import android.platform.test.annotations.RequiresFlagsEnabled;
-import android.platform.test.flag.junit.CheckFlagsRule;
-import android.platform.test.flag.junit.DeviceFlagsValueProvider;
-
-import androidx.test.core.app.ApplicationProvider;
-
-import com.android.appsearch.flags.Flags;
-import com.android.bedstead.harrier.BedsteadJUnit4;
-import com.android.bedstead.harrier.DeviceState;
-import com.android.bedstead.enterprise.annotations.EnsureHasWorkProfile;
-import com.android.bedstead.harrier.annotations.Postsubmit;
-import com.android.bedstead.harrier.annotations.RequireRunOnWorkProfile;
-import com.android.bedstead.enterprise.annotations.EnsureHasDeviceOwner;
-import com.android.bedstead.enterprise.annotations.EnsureHasNoDeviceOwner;
-import com.android.compatibility.common.util.ApiTest;
-import com.android.compatibility.common.util.DeviceConfigStateChangerRule;
-
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.TimeUnit;
-
-/**
- * CTS for {@link AppFunctionManager}.
- *
- * Implementation notes:
- * We are using Bedstead to create the multi-user environment. To speed up test execution,
- * Bedstead does not clean up the environment unless the test explicitly asks it to.
- * For example, if there is a test setting up a device owner with @EnsureHasDeviceOwner, the
- * latter tests will run with a device owner. To tell Bedstead to remove the device owner,
- * we annotate the test functions with @EnsureHasNoDeviceOwner.
- */
-@RequiresFlagsEnabled(Flags.FLAG_ENABLE_APP_FUNCTIONS)
-@RunWith(BedsteadJUnit4.class)
-public class AppFunctionManagerCtsTest {
- @ClassRule
- @Rule
- public static final DeviceState sDeviceState = new DeviceState();
-
- @Rule
- public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
-
- private static final String TARGET_PACKAGE = "com.android.cts.appsearch";
- private static final String PKG_B = "com.android.cts.appsearch.helper.b";
- private static final long SHORT_TIMEOUT_SECOND = 1;
- private static final long LONG_TIMEOUT_SECOND = 5;
-
- private final Context mContext = ApplicationProvider.getApplicationContext();
- private AppFunctionManager mAppFunctionManager;
-
- /** This rule establishes a shorter timeout for testing timeout scenarios. */
- @Rule
- public final DeviceConfigStateChangerRule mSetTimeoutRule =
- new DeviceConfigStateChangerRule(
- mContext, "appsearch", "app_function_call_timeout_millis", "1000");
-
- @Before
- public void setup() {
- ActivityCreationSynchronizer.reset();
- TestAppFunctionServiceLifecycleReceiver.reset();
- AppSearchManager appSearchManager = mContext.getSystemService(AppSearchManager.class);
- mAppFunctionManager = appSearchManager.getAppFunctionManager();
- }
-
- @ApiTest(apis = {"android.app.appsearch.functions.AppFunctionManager#executeAppFunction"})
- @Test
- public void executeAppFunction_failed_noSuchMethod() throws Exception {
- ExecuteAppFunctionRequest request =
- new ExecuteAppFunctionRequest.Builder(TARGET_PACKAGE, "invalid").build();
-
- AppSearchResult<ExecuteAppFunctionResponse> response = executeAppFunctionAndWait(request);
-
- assertThat(response.isSuccess()).isFalse();
- assertThat(response.getResultCode()).isEqualTo(RESULT_NOT_FOUND);
- assertServiceDestroyed();
- }
-
- @ApiTest(apis = {"android.app.appsearch.functions.AppFunctionManager#executeAppFunction"})
- @Test
- @EnsureHasNoDeviceOwner
- public void executeAppFunction_onlyInvokeCallbackOnce() throws Exception {
- GenericDocument parameters = new GenericDocument.Builder("", "", "")
- .setPropertyLong("a", 1)
- .setPropertyLong("b", 2)
- .build();
- ExecuteAppFunctionRequest request =
- new ExecuteAppFunctionRequest.Builder(TARGET_PACKAGE, "add_invokeCallbackTwice")
- .setParameters(parameters)
- .build();
- LinkedBlockingQueue<AppSearchResult<ExecuteAppFunctionResponse>> blockingQueue =
- new LinkedBlockingQueue<>();
-
- mAppFunctionManager.executeAppFunction(
- request, mContext.getMainExecutor(), blockingQueue::add);
-
- AppSearchResult<ExecuteAppFunctionResponse> response =
- blockingQueue.poll(LONG_TIMEOUT_SECOND, TimeUnit.SECONDS);
- assertThat(response.isSuccess()).isTrue();
- assertThat(response.getResultValue().getResult().getPropertyLong(PROPERTY_RESULT))
- .isEqualTo(3);
-
- // Each callback can only be invoked once.
- assertThat(blockingQueue.poll(SHORT_TIMEOUT_SECOND, TimeUnit.SECONDS)).isNull();
- assertServiceDestroyed();
- }
-
- @ApiTest(apis = {"android.app.appsearch.functions.AppFunctionManager#executeAppFunction"})
- @Test
- @EnsureHasNoDeviceOwner
- public void executeAppFunction_success() throws Exception {
- GenericDocument parameters = new GenericDocument.Builder("", "", "")
- .setPropertyLong("a", 1)
- .setPropertyLong("b", 2)
- .build();
-
- ExecuteAppFunctionRequest request =
- new ExecuteAppFunctionRequest.Builder(TARGET_PACKAGE, "add")
- .setParameters(parameters)
- .build();
-
- AppSearchResult<ExecuteAppFunctionResponse> response = executeAppFunctionAndWait(request);
-
- assertThat(response.isSuccess()).isTrue();
- assertThat(response.getResultValue().getResult().getPropertyLong(PROPERTY_RESULT))
- .isEqualTo(3);
- assertServiceDestroyed();
- }
-
- @ApiTest(apis = {"android.app.appsearch.functions.AppFunctionManager#executeAppFunction"})
- @Test
- @EnsureHasNoDeviceOwner
- public void executeAppFunction_otherNonExistingOtherPackage() throws Exception {
- ExecuteAppFunctionRequest request =
- new ExecuteAppFunctionRequest.Builder("other.package", "someMethod").build();
-
- AppSearchResult<ExecuteAppFunctionResponse> response = executeAppFunctionAndWait(request);
-
- assertThat(response.isSuccess()).isFalse();
- // Apps without the permission can only invoke functions from themselves.
- assertThat(response.getResultCode()).isEqualTo(AppSearchResult.RESULT_SECURITY_ERROR);
- assertThat(response.getErrorMessage()).endsWith(
- "is not allowed to call executeAppFunction");
- assertServiceWasNotCreated();
- }
-
- @ApiTest(apis = {"android.app.appsearch.functions.AppFunctionManager#executeAppFunction"})
- @Test
- @EnsureHasNoDeviceOwner
- public void executeAppFunction_otherExistingTargetPackage() throws Exception {
- ExecuteAppFunctionRequest request =
- new ExecuteAppFunctionRequest.Builder(PKG_B, "someMethod").build();
-
- AppSearchResult<ExecuteAppFunctionResponse> response = executeAppFunctionAndWait(request);
-
- assertThat(response.isSuccess()).isFalse();
- assertThat(response.getResultCode()).isEqualTo(AppSearchResult.RESULT_SECURITY_ERROR);
- // The error message from this and executeAppFunction_otherNonExistingOther must be kept
- // in sync. This verifies that a caller cannot tell whether a package is installed or not by
- // comparing the error messages.
- assertThat(response.getErrorMessage()).endsWith(
- "is not allowed to call executeAppFunction");
- assertServiceWasNotCreated();
- }
-
- @ApiTest(apis = {"android.app.appsearch.functions.AppFunctionManager#executeAppFunction"})
- @Test
- @EnsureHasNoDeviceOwner
- public void executeAppFunction_startActivity() throws Exception {
- ExecuteAppFunctionRequest request =
- new ExecuteAppFunctionRequest.Builder(TARGET_PACKAGE, "startActivity").build();
-
- AppSearchResult<ExecuteAppFunctionResponse> response = executeAppFunctionAndWait(request);
-
- assertThat(response.isSuccess()).isTrue();
- assertThat(ActivityCreationSynchronizer.waitForActivityCreated(5, TimeUnit.SECONDS))
- .isTrue();
- assertServiceDestroyed();
- }
-
- @ApiTest(apis = {"android.app.appsearch.functions.AppFunctionManager#executeAppFunction"})
- @Test
- @EnsureHasNoDeviceOwner
- public void executeAppFunction_throwsException() throws Exception {
- ExecuteAppFunctionRequest request =
- new ExecuteAppFunctionRequest.Builder(TARGET_PACKAGE, "throwException").build();
-
- AppSearchResult<ExecuteAppFunctionResponse> response = executeAppFunctionAndWait(request);
-
- assertThat(response.isSuccess()).isFalse();
- assertThat(response.getResultCode()).isEqualTo(RESULT_UNKNOWN_ERROR);
- assertServiceDestroyed();
- }
-
- @ApiTest(apis = {"android.app.appsearch.functions.AppFunctionManager#executeAppFunction"})
- @Test
- @EnsureHasNoDeviceOwner
- public void executeAppFunction_onRemoteProcessKilled() throws Exception {
- ExecuteAppFunctionRequest request =
- new ExecuteAppFunctionRequest.Builder(TARGET_PACKAGE, "kill").build();
-
- AppSearchResult<ExecuteAppFunctionResponse> response = executeAppFunctionAndWait(request);
-
- assertThat(response.isSuccess()).isFalse();
- assertThat(response.getResultCode()).isEqualTo(RESULT_INTERNAL_ERROR);
- // The process that the service was just crashed. Validate the service is not created again.
- TestAppFunctionServiceLifecycleReceiver.reset();
- assertServiceWasNotCreated();
- }
-
- @ApiTest(apis = {"android.app.appsearch.functions.AppFunctionManager#executeAppFunction"})
- @Test
- @EnsureHasNoDeviceOwner
- public void executeAppFunction_timedOut() throws Exception {
- ExecuteAppFunctionRequest request =
- new ExecuteAppFunctionRequest.Builder(TARGET_PACKAGE, "notInvokeCallback").build();
-
- AppSearchResult<ExecuteAppFunctionResponse> response = executeAppFunctionAndWait(request);
-
- assertThat(response.isSuccess()).isFalse();
- assertThat(response.getResultCode()).isEqualTo(RESULT_TIMED_OUT);
- assertServiceDestroyed();
- }
-
- @ApiTest(apis = {"android.app.appsearch.functions.AppFunctionManager#executeAppFunction"})
- @Test
- @EnsureHasNoDeviceOwner
- public void executeAppFunction_success_async() throws Exception {
- GenericDocument parameters = new GenericDocument.Builder<>("", "", "")
- .setPropertyLong("a", 1)
- .setPropertyLong("b", 2)
- .build();
- ExecuteAppFunctionRequest request =
- new ExecuteAppFunctionRequest.Builder(TARGET_PACKAGE, "addAsync")
- .setParameters(parameters)
- .build();
-
- AppSearchResult<ExecuteAppFunctionResponse> response = executeAppFunctionAndWait(request);
-
- assertThat(response.isSuccess()).isTrue();
- assertThat(response.getResultValue().getResult().getPropertyLong(PROPERTY_RESULT))
- .isEqualTo(3);
- assertServiceDestroyed();
- }
-
- @ApiTest(apis = {"android.app.appsearch.functions.AppFunctionManager#executeAppFunction"})
- @Test
- @EnsureHasNoDeviceOwner
- public void executeAppFunction_emptyPackage() throws Exception {
- ExecuteAppFunctionRequest request =
- new ExecuteAppFunctionRequest.Builder("", "noOp")
- .build();
-
- AppSearchResult<ExecuteAppFunctionResponse> response = executeAppFunctionAndWait(request);
-
- assertThat(response.isSuccess()).isFalse();
- assertThat(response.getResultCode()).isEqualTo(RESULT_INVALID_ARGUMENT);
- assertServiceWasNotCreated();
- }
-
- @ApiTest(apis = {"android.app.appsearch.functions.AppFunctionManager#executeAppFunction"})
- @Test
- @RequireRunOnWorkProfile
- @EnsureHasNoDeviceOwner
- @Postsubmit(reason = "new test")
- public void executeAppFunction_runInManagedProfile_fail() throws Exception {
- ExecuteAppFunctionRequest request =
- new ExecuteAppFunctionRequest.Builder(TARGET_PACKAGE, "noOp")
- .build();
-
- AppSearchResult<ExecuteAppFunctionResponse> response = executeAppFunctionAndWait(request);
-
- assertThat(response.isSuccess()).isFalse();
- assertThat(response.getResultCode()).isEqualTo(RESULT_SECURITY_ERROR);
- assertServiceWasNotCreated();
- }
-
- @ApiTest(apis = {"android.app.appsearch.functions.AppFunctionManager#executeAppFunction"})
- @Test
- @EnsureHasWorkProfile
- @EnsureHasNoDeviceOwner
- public void executeAppFunction_hasManagedProfileRunInPersonalProfile_success()
- throws Exception {
- ExecuteAppFunctionRequest request =
- new ExecuteAppFunctionRequest.Builder(TARGET_PACKAGE, "noOp")
- .build();
-
- AppSearchResult<ExecuteAppFunctionResponse> response = executeAppFunctionAndWait(request);
-
- assertThat(response.isSuccess()).isTrue();
- assertServiceDestroyed();
- }
-
-
- @ApiTest(apis = {"android.app.appsearch.functions.AppFunctionManager#executeAppFunction"})
- @Test
- @EnsureHasDeviceOwner
- public void executeAppFunction_deviceOwner_fail() throws Exception {
- ExecuteAppFunctionRequest request =
- new ExecuteAppFunctionRequest.Builder(TARGET_PACKAGE, "noOp")
- .build();
-
- AppSearchResult<ExecuteAppFunctionResponse> response =
- executeAppFunctionAndWait(request);
-
- assertThat(response.isSuccess()).isFalse();
- assertThat(response.getResultCode()).isEqualTo(RESULT_SECURITY_ERROR);
- assertServiceWasNotCreated();
- }
-
- @ApiTest(apis = {"android.app.appsearch.functions.AppFunctionManager#executeAppFunction"})
- @Test
- @EnsureHasNoDeviceOwner
- public void executeAppFunction_correctSha256Certificate() throws Exception {
- ExecuteAppFunctionRequest request =
- new ExecuteAppFunctionRequest.Builder(TARGET_PACKAGE, "noOp")
- .setSha256Certificate(PackageUtil.getSelfPackageSha256Cert(mContext))
- .build();
-
- AppSearchResult<ExecuteAppFunctionResponse> response = executeAppFunctionAndWait(request);
-
- assertThat(response.isSuccess()).isTrue();
- assertServiceDestroyed();
- }
-
- @ApiTest(apis = {"android.app.appsearch.functions.AppFunctionManager#executeAppFunction"})
- @Test
- @EnsureHasNoDeviceOwner
- public void executeAppFunction_wrongSha256Certificate() throws Exception {
- ExecuteAppFunctionRequest request =
- new ExecuteAppFunctionRequest.Builder(TARGET_PACKAGE, "noOp")
- .setSha256Certificate(new byte[]{100})
- .build();
-
- AppSearchResult<ExecuteAppFunctionResponse> response = executeAppFunctionAndWait(request);
-
- assertThat(response.isSuccess()).isFalse();
- assertThat(response.getResultCode()).isEqualTo(RESULT_NOT_FOUND);
- assertServiceWasNotCreated();
- }
-
- private AppSearchResult<ExecuteAppFunctionResponse> executeAppFunctionAndWait(
- ExecuteAppFunctionRequest request) throws InterruptedException {
- LinkedBlockingQueue<AppSearchResult<ExecuteAppFunctionResponse>> blockingQueue =
- new LinkedBlockingQueue<>();
- mAppFunctionManager.executeAppFunction(
- request, mContext.getMainExecutor(), blockingQueue::add);
- return blockingQueue.poll(LONG_TIMEOUT_SECOND, TimeUnit.SECONDS);
- }
-
- /**
- * Verifies that the service is unbound by asserting the service was destroyed.
- */
- private void assertServiceDestroyed() throws InterruptedException {
- assertThat(waitForServiceOnDestroy(LONG_TIMEOUT_SECOND, TimeUnit.SECONDS)).isTrue();
- }
-
- /**
- * Verifies that the service has never been created.
- */
- private void assertServiceWasNotCreated() throws InterruptedException {
- assertThat(waitForServiceOnCreate(SHORT_TIMEOUT_SECOND, TimeUnit.SECONDS)).isFalse();
- }
-}
diff --git a/tests/appsearch/src/com/android/cts/appsearch/functions/ExecuteAppFunctionRequestCtsTest.java b/tests/appsearch/src/com/android/cts/appsearch/functions/ExecuteAppFunctionRequestCtsTest.java
deleted file mode 100644
index 2e421b7..0000000
--- a/tests/appsearch/src/com/android/cts/appsearch/functions/ExecuteAppFunctionRequestCtsTest.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2024 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.app.appsearch.cts.functions;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.app.appsearch.GenericDocument;
-import android.app.appsearch.functions.ExecuteAppFunctionRequest;
-import android.os.Bundle;
-import android.os.Parcel;
-import android.platform.test.annotations.RequiresFlagsEnabled;
-import android.platform.test.flag.junit.CheckFlagsRule;
-import android.platform.test.flag.junit.DeviceFlagsValueProvider;
-
-import com.android.appsearch.flags.Flags;
-import com.android.compatibility.common.util.ApiTest;
-
-import org.junit.Rule;
-import org.junit.Test;
-
-@RequiresFlagsEnabled(Flags.FLAG_ENABLE_APP_FUNCTIONS)
-public class ExecuteAppFunctionRequestCtsTest {
- @Rule
- public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
-
- @ApiTest(apis = {
- "android.app.appsearch.functions.ExecuteAppFunctionRequest.Builder#Builder",
- "android.app.appsearch.functions.ExecuteAppFunctionRequest.Builder#setParameter",
- "android.app.appsearch.functions.ExecuteAppFunctionRequest.Builder#setExtras",
- "android.app.appsearch.functions.ExecuteAppFunctionRequest"
- + ".Builder#setSha256Certificate",
- "android.app.appsearch.functions.ExecuteAppFunctionRequest.Builder#build",
- "android.app.appsearch.functions.ExecuteAppFunctionRequest#writeToParcel",
- "android.app.appsearch.functions.ExecuteAppFunctionRequest#CREATOR",
- "android.app.appsearch.functions.ExecuteAppFunctionRequest#getTargetPackageName",
- "android.app.appsearch.functions.ExecuteAppFunctionRequest#getParameters",
- "android.app.appsearch.functions.ExecuteAppFunctionRequest#getExtras",
- "android.app.appsearch.functions.ExecuteAppFunctionRequest#getSha256Certificate",
- })
- @Test
- public void build() {
- Bundle extras = new Bundle();
- extras.putString("extra", "value");
- GenericDocument parameters = new GenericDocument.Builder<>("", "", "")
- .setPropertyLong("a", 42)
- .build();
- ExecuteAppFunctionRequest request = new ExecuteAppFunctionRequest.Builder("pkg", "method")
- .setParameters(parameters)
- .setSha256Certificate(new byte[] {100})
- .setExtras(extras)
- .build();
-
- ExecuteAppFunctionRequest restored = parcelizeAndDeparcelize(request);
-
- assertThat(restored.getTargetPackageName()).isEqualTo("pkg");
- assertThat(restored.getParameters()).isEqualTo(parameters);
- assertThat(restored.getSha256Certificate()).isEqualTo(new byte[] {100});
- assertThat(restored.getExtras().size()).isEqualTo(1);
- assertThat(restored.getExtras().getString("extra")).isEqualTo("value");
- }
-
-
- private static ExecuteAppFunctionRequest parcelizeAndDeparcelize(
- ExecuteAppFunctionRequest original) {
- Parcel parcel = Parcel.obtain();
- try {
- original.writeToParcel(parcel, 0);
- parcel.setDataPosition(0);
- return ExecuteAppFunctionRequest.CREATOR.createFromParcel(parcel);
- } finally {
- parcel.recycle();
- }
- }
-}
diff --git a/tests/appsearch/src/com/android/cts/appsearch/functions/ExecuteAppFunctionResponseCtsTest.java b/tests/appsearch/src/com/android/cts/appsearch/functions/ExecuteAppFunctionResponseCtsTest.java
deleted file mode 100644
index a95d517..0000000
--- a/tests/appsearch/src/com/android/cts/appsearch/functions/ExecuteAppFunctionResponseCtsTest.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2024 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.app.appsearch.cts.functions;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.app.appsearch.GenericDocument;
-import android.app.appsearch.functions.ExecuteAppFunctionResponse;
-import android.os.Bundle;
-import android.os.Parcel;
-import android.platform.test.annotations.RequiresFlagsEnabled;
-import android.platform.test.flag.junit.CheckFlagsRule;
-import android.platform.test.flag.junit.DeviceFlagsValueProvider;
-
-import com.android.appsearch.flags.Flags;
-import com.android.compatibility.common.util.ApiTest;
-
-import org.junit.Rule;
-import org.junit.Test;
-
-@RequiresFlagsEnabled(Flags.FLAG_ENABLE_APP_FUNCTIONS)
-public class ExecuteAppFunctionResponseCtsTest {
- @Rule
- public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
-
- @ApiTest(apis = {
- "android.app.appsearch.functions.ExecuteAppFunctionResponse.Builder#Builder",
- "android.app.appsearch.functions.ExecuteAppFunctionResponse.Builder#setExtras",
- "android.app.appsearch.functions.ExecuteAppFunctionResponse.Builder#build",
- "android.app.appsearch.functions.ExecuteAppFunctionResponse#writeToParcel",
- "android.app.appsearch.functions.ExecuteAppFunctionResponse#CREATOR",
- "android.app.appsearch.functions.ExecuteAppFunctionResponse#getResult",
- "android.app.appsearch.functions.ExecuteAppFunctionResponse#getExtras",
- })
- @Test
- public void build() {
- Bundle extras = new Bundle();
- extras.putString("extra", "value");
- GenericDocument functionResult = new GenericDocument.Builder<>("", "", "")
- .setPropertyLong(ExecuteAppFunctionResponse.PROPERTY_RESULT, 42)
- .build();
- ExecuteAppFunctionResponse response =
- new ExecuteAppFunctionResponse.Builder()
- .setResult(functionResult)
- .setExtras(extras)
- .build();
-
- ExecuteAppFunctionResponse restored =
- parcelizeAndDeparcelize(response);
-
- assertThat(restored.getResult()).isEqualTo(functionResult);
- assertThat(restored.getExtras().size()).isEqualTo(1);
- assertThat(restored.getExtras().getString("extra")).isEqualTo("value");
- }
-
- private static ExecuteAppFunctionResponse parcelizeAndDeparcelize(
- ExecuteAppFunctionResponse original) {
- Parcel parcel = Parcel.obtain();
- try {
- original.writeToParcel(parcel, 0);
- parcel.setDataPosition(0);
- return ExecuteAppFunctionResponse.CREATOR.createFromParcel(parcel);
- } finally {
- parcel.recycle();
- }
- }
-}
diff --git a/tests/appsearch/testutils/src/android/app/appsearch/testutil/functions/ActivityCreationSynchronizer.java b/tests/appsearch/testutils/src/android/app/appsearch/testutil/functions/ActivityCreationSynchronizer.java
deleted file mode 100644
index 9ddf94e..0000000
--- a/tests/appsearch/testutils/src/android/app/appsearch/testutil/functions/ActivityCreationSynchronizer.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2024 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.app.appsearch.testutil.functions;
-
-import android.app.Activity;
-import android.os.Bundle;
-
-import androidx.annotation.Nullable;
-
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-/** An activity class that enables waiting for its own creation. */
-public class ActivityCreationSynchronizer extends Activity {
-
- private static volatile CountDownLatch sLatch = new CountDownLatch(1);
-
- /**
- * Called within the Activity's onCreate() lifecycle method.
- * Signals that the Activity has been fully created.
- */
- @Override
- protected void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- sLatch.countDown();
- finish();
- }
-
- /**
- * Resets the latch and enables another wait cycle. Should never call this with
- * {@link #waitForActivityCreated} in parallel.
- */
- public static void reset() {
- sLatch = new CountDownLatch(1);
- }
-
- /**
- * Blocks the current thread until the Activity is created or the specified timeout elapses.
- * Should never call this with {@link #reset()} in parallel.
- *
- * @param timeout The duration to wait for Activity creation.
- * @param unit The unit of time for the timeout value.
- * @return True if the Activity was created within the timeout, false otherwise.
- * @throws InterruptedException If the current thread is interrupted while waiting.
- */
- public static boolean waitForActivityCreated(long timeout, TimeUnit unit)
- throws InterruptedException {
- return sLatch.await(timeout, unit);
- }
-}
diff --git a/tests/appsearch/testutils/src/android/app/appsearch/testutil/functions/TestAppFunctionService.java b/tests/appsearch/testutils/src/android/app/appsearch/testutil/functions/TestAppFunctionService.java
deleted file mode 100644
index 1ed2b1e..0000000
--- a/tests/appsearch/testutils/src/android/app/appsearch/testutil/functions/TestAppFunctionService.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2024 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.app.appsearch.testutil.functions;
-
-import static android.app.appsearch.AppSearchResult.RESULT_NOT_FOUND;
-import static android.app.appsearch.AppSearchResult.newFailedResult;
-import static android.app.appsearch.AppSearchResult.newSuccessfulResult;
-import static android.app.appsearch.functions.ExecuteAppFunctionResponse.PROPERTY_RESULT;
-
-import android.app.appsearch.AppSearchResult;
-import android.app.appsearch.GenericDocument;
-import android.app.appsearch.functions.AppFunctionService;
-import android.app.appsearch.functions.ExecuteAppFunctionRequest;
-import android.app.appsearch.functions.ExecuteAppFunctionResponse;
-import android.content.Intent;
-
-import androidx.annotation.NonNull;
-
-import java.util.concurrent.Executor;
-import java.util.concurrent.Executors;
-import java.util.function.Consumer;
-
-/**
- * An implementation of {@link android.app.appsearch.functions.AppFunctionService} that provides
- * some simple functions for testing purposes.
- */
-public class TestAppFunctionService extends AppFunctionService {
- private final Executor mExecutor = Executors.newSingleThreadExecutor();
-
- @Override
- public void onCreate() {
- super.onCreate();
- TestAppFunctionServiceLifecycleReceiver.notifyOnCreateInvoked(this);
- }
-
- @Override
- public void onExecuteFunction(
- @NonNull ExecuteAppFunctionRequest request,
- @NonNull Consumer<AppSearchResult<ExecuteAppFunctionResponse>> callback) {
- switch (request.getFunctionIdentifier()) {
- case "add": {
- ExecuteAppFunctionResponse result = add(request);
- callback.accept(newSuccessfulResult(result));
- break;
- }
- case "add_invokeCallbackTwice": {
- ExecuteAppFunctionResponse result = add(request);
- callback.accept(newSuccessfulResult(result));
- callback.accept(newSuccessfulResult(result));
- break;
- }
- case "startActivity": {
- ExecuteAppFunctionResponse result = startActivity(request);
- callback.accept(newSuccessfulResult(result));
- break;
- }
- case "throwException": {
- throw new RuntimeException();
- }
- case "kill": {
- System.exit(0);
- break;
- }
- case "notInvokeCallback": {
- break;
- }
- case "addAsync": {
- mExecutor.execute(() -> {
- ExecuteAppFunctionResponse result = add(request);
- callback.accept(newSuccessfulResult(result));
- });
- break;
- }
- case "noOp": {
- callback.accept(
- newSuccessfulResult(new ExecuteAppFunctionResponse.Builder().build()));
- break;
- }
- default:
- callback.accept(newFailedResult(RESULT_NOT_FOUND, "no such method"));
- }
- }
-
- private ExecuteAppFunctionResponse add(ExecuteAppFunctionRequest request) {
- long a = request.getParameters().getPropertyLong("a");
- long b = request.getParameters().getPropertyLong("b");
- GenericDocument result = new GenericDocument.Builder<>("", "", "")
- .setPropertyLong(PROPERTY_RESULT, a + b)
- .build();
- return new ExecuteAppFunctionResponse.Builder().setResult(result).build();
- }
-
- private ExecuteAppFunctionResponse startActivity(ExecuteAppFunctionRequest request) {
- Intent intent = new Intent(this, ActivityCreationSynchronizer.class);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- startActivity(intent);
-
- return new ExecuteAppFunctionResponse.Builder().build();
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
- TestAppFunctionServiceLifecycleReceiver.notifyOnDestroyInvoked(this);
- }
-}
diff --git a/tests/appsearch/testutils/src/android/app/appsearch/testutil/functions/TestAppFunctionServiceLifecycleReceiver.java b/tests/appsearch/testutils/src/android/app/appsearch/testutil/functions/TestAppFunctionServiceLifecycleReceiver.java
deleted file mode 100644
index 994eb9b..0000000
--- a/tests/appsearch/testutils/src/android/app/appsearch/testutil/functions/TestAppFunctionServiceLifecycleReceiver.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2024 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.app.appsearch.testutil.functions;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Provides utilities to listen to lifecycle events of the {@link TestAppFunctionService}.
- */
-public class TestAppFunctionServiceLifecycleReceiver extends BroadcastReceiver {
- private static final String ACTION_SERVICE_ON_CREATE = "oncreate";
- private static final String ACTION_SERVICE_ON_DESTROY = "ondestroy";
-
- private static volatile CountDownLatch sOnCreateLatch = new CountDownLatch(1);
- private static volatile CountDownLatch sOnDestroyedLatch = new CountDownLatch(1);
-
- @Override
- public void onReceive(Context context, Intent intent) {
- if (ACTION_SERVICE_ON_CREATE.equals(intent.getAction())) {
- sOnCreateLatch.countDown();
- } else if (ACTION_SERVICE_ON_DESTROY.equals(intent.getAction())) {
- sOnDestroyedLatch.countDown();
- }
- }
-
- /**
- * Resets the latch and enables another wait cycle. Should never call this method with any
- * other methods in parallel.
- */
- public static void reset() {
- sOnCreateLatch = new CountDownLatch(1);
- sOnDestroyedLatch = new CountDownLatch(1);
- }
-
- /**
- * Blocks the current thread until {@link TestAppFunctionService#onDestroy()} is invoked, or the
- * specified timeout elapses.
- *
- * @param timeout The duration to wait for.
- * @param unit The unit of time for the timeout value.
- * @return True if the onDestroy was invoked within the timeout, false otherwise.
- * @throws InterruptedException If the current thread is interrupted while waiting.
- */
- public static boolean waitForServiceOnDestroy(long timeout, TimeUnit unit)
- throws InterruptedException {
- return sOnDestroyedLatch.await(timeout, unit);
- }
-
- /**
- * Blocks the current thread until {@link TestAppFunctionService#onCreate()} is invoked, or the
- * specified timeout elapses.
- *
- * @param timeout The duration to wait for.
- * @param unit The unit of time for the timeout value.
- * @return True if the onCreate was invoked within the timeout, false otherwise.
- * @throws InterruptedException If the current thread is interrupted while waiting.
- */
- public static boolean waitForServiceOnCreate(long timeout, TimeUnit unit)
- throws InterruptedException {
- return sOnCreateLatch.await(timeout, unit);
- }
-
- /** Notifies that {@link TestAppFunctionService} is created. */
- public static void notifyOnCreateInvoked(Context context) {
- notifyEvent(context, ACTION_SERVICE_ON_CREATE);
- }
-
- /** Notifies that {@link TestAppFunctionService} is destroyed. */
- public static void notifyOnDestroyInvoked(Context context) {
- notifyEvent(context, ACTION_SERVICE_ON_DESTROY);
- }
-
- private static void notifyEvent(Context context, String action) {
- Intent intent = new Intent(context, TestAppFunctionServiceLifecycleReceiver.class);
- intent.setAction(action);
- intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
- context.sendBroadcast(intent);
- }
-}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/commontests/AutoFillServiceTestCase.java b/tests/autofillservice/src/android/autofillservice/cts/commontests/AutoFillServiceTestCase.java
index 2850734..fc14d6b 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/commontests/AutoFillServiceTestCase.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/commontests/AutoFillServiceTestCase.java
@@ -68,7 +68,6 @@
import com.android.compatibility.common.util.SafeCleanerRule;
import com.android.compatibility.common.util.SettingsStateKeeperRule;
import com.android.compatibility.common.util.TestNameUtils;
-import com.android.compatibility.common.util.UserHelper;
import com.android.cts.mockime.ImeSettings;
import com.android.cts.mockime.MockImeSessionRule;
@@ -417,21 +416,14 @@
.around(new RequiredFeatureRule(PackageManager.FEATURE_INPUT_METHODS));
public BaseTestCase() {
- this(sDefaultUiBot);
+ mPackageName = mContext.getPackageName();
+ mUiBot = sDefaultUiBot;
}
private BaseTestCase(@NonNull UiBot uiBot) {
mPackageName = mContext.getPackageName();
mUiBot = uiBot;
mUiBot.reset();
- // Context#getDisplayId() always returns the default display ID, even if it is called
- // from an app running as a visible background user (b/356478691).
- // To work around it, let's set the correct display ID manually.
- final UserHelper userHelper = new UserHelper(mContext);
- final int myDisplayId = userHelper.getMainDisplayId();
- if (mContext.getDisplayId() != myDisplayId) {
- mContext.updateDisplay(myDisplayId);
- }
}
protected int getSmartSuggestionMode() {
diff --git a/tests/autofillservice/src/android/autofillservice/cts/commontests/CustomDescriptionWithLinkTestCase.java b/tests/autofillservice/src/android/autofillservice/cts/commontests/CustomDescriptionWithLinkTestCase.java
index c2c9168..23d2dc7 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/commontests/CustomDescriptionWithLinkTestCase.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/commontests/CustomDescriptionWithLinkTestCase.java
@@ -25,6 +25,7 @@
import android.autofillservice.cts.R;
import android.autofillservice.cts.activities.AbstractAutoFillActivity;
import android.autofillservice.cts.testcore.Helper;
+import android.autofillservice.cts.testcore.Timeouts;
import android.autofillservice.cts.testcore.UiBot;
import android.content.Intent;
import android.service.autofill.CustomDescription;
@@ -98,6 +99,7 @@
!Helper.isDeviceInState(mContext, Helper.DeviceStateEnum.REAR_DISPLAY));
mUiBot.assumeMinimumResolution(500);
+ mUiBot.assumeMinimumResolutionInDp(480);
mUiBot.setScreenOrientation(UiBot.PORTRAIT);
try {
saveUiRestoredAfterTappingLinkTest(
@@ -328,13 +330,12 @@
return saveUi;
}
- protected final UiObject2 getLink(final UiObject2 container) {
- final UiObject2 link = container.findObject(By.res(mPackageName, ID_LINK));
- assertThat(link).isNotNull();
+ protected final UiObject2 getLink(final UiObject2 container) throws Exception{
+ final UiObject2 link = mUiBot.waitForObject(container, ID_LINK, Timeouts.UI_TIMEOUT);
return link;
}
- protected final void tapSaveUiLink(UiObject2 saveUi) {
+ protected final void tapSaveUiLink(UiObject2 saveUi) throws Exception{
getLink(saveUi).click();
}
}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/dropdown/LoginActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/dropdown/LoginActivityTest.java
index ba1cfde..9b0d31f 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/dropdown/LoginActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/dropdown/LoginActivityTest.java
@@ -2695,7 +2695,7 @@
mActivity.assertAutoFilled();
// Change focus to prepare for next step - must do it before session is gone
- requestFocusOnPassword();
+ mActivity.onPassword(View::requestFocus);
// Rinse and repeat...
mActivity.tapClear();
diff --git a/tests/autofillservice/src/android/autofillservice/cts/saveui/SimpleSaveActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/saveui/SimpleSaveActivityTest.java
index ec07c87..ec8a768 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/saveui/SimpleSaveActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/saveui/SimpleSaveActivityTest.java
@@ -290,6 +290,7 @@
assumeTrue("Device state is not REAR_DISPLAY",
!Helper.isDeviceInState(mContext, Helper.DeviceStateEnum.REAR_DISPLAY));
mUiBot.assumeMinimumResolution(500);
+ mUiBot.assumeMinimumResolutionInDp(480);
mUiBot.setScreenOrientation(UiBot.PORTRAIT);
try {
saveTest(true);
diff --git a/tests/autofillservice/src/android/autofillservice/cts/testcore/UiBot.java b/tests/autofillservice/src/android/autofillservice/cts/testcore/UiBot.java
index a40569e..2f87c62 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/testcore/UiBot.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/testcore/UiBot.java
@@ -32,8 +32,6 @@
import static android.service.autofill.SaveInfo.SAVE_DATA_TYPE_PASSWORD;
import static android.service.autofill.SaveInfo.SAVE_DATA_TYPE_PAYMENT_CARD;
import static android.service.autofill.SaveInfo.SAVE_DATA_TYPE_USERNAME;
-import static android.view.KeyEvent.KEYCODE_BACK;
-import static android.view.KeyEvent.KEYCODE_HOME;
import static com.android.compatibility.common.util.ShellUtils.runShellCommand;
@@ -57,6 +55,7 @@
import android.text.Spanned;
import android.text.style.URLSpan;
import android.util.Log;
+import android.view.Display;
import android.view.InputDevice;
import android.view.MotionEvent;
import android.view.Surface;
@@ -83,13 +82,11 @@
import androidx.test.uiautomator.Until;
import com.android.compatibility.common.util.RetryableException;
-import com.android.compatibility.common.util.SystemUtil;
import com.android.compatibility.common.util.Timeout;
import com.android.compatibility.common.util.UserHelper;
import java.io.File;
import java.io.FileInputStream;
-import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -150,6 +147,18 @@
private static final String RESOURCE_ID_FILL_DIALOG_BUTTON_NO = "autofill_dialog_no";
private static final String RESOURCE_ID_FILL_DIALOG_BUTTON_YES = "autofill_dialog_yes";
+ static final BySelector DATASET_PICKER_SELECTOR = By.res("android", RESOURCE_ID_DATASET_PICKER);
+ private static final BySelector SAVE_UI_SELECTOR = By.res("android", RESOURCE_ID_SAVE_SNACKBAR);
+ private static final BySelector DATASET_HEADER_SELECTOR =
+ By.res("android", RESOURCE_ID_DATASET_HEADER);
+ private static final BySelector FILL_DIALOG_SELECTOR =
+ By.res("android", RESOURCE_ID_FILL_DIALOG_PICKER);
+ private static final BySelector FILL_DIALOG_HEADER_SELECTOR =
+ By.res("android", RESOURCE_ID_FILL_DIALOG_HEADER);
+ private static final BySelector FILL_DIALOG_DATASET_SELECTOR =
+ By.res("android", RESOURCE_ID_FILL_DIALOG_DATASET);
+
+
// TODO: figure out a more reliable solution that does not depend on SystemUI resources.
private static final String SPLIT_WINDOW_DIVIDER_ID =
"com.android.systemui:id/docked_divider_background";
@@ -177,15 +186,6 @@
private final String mPackageName;
private final UiAutomation mAutoman;
private final Timeout mDefaultTimeout;
- private final int mMyDisplayId;
- private final BySelector mDatasetPickerSelector;
- private final BySelector mSaveUiSelector;
- private final BySelector mDatasetHeaderSelector;
- private final BySelector mFillDialogSelector;
- private final BySelector mFillDialogHeaderSelector;
- // TODO:update this for android.autofillservice.cts.dialog.LoginActivityTest
- // #testShowFillDialog_switchToUnsupportedField_fallbackDropdown
- private final BySelector mDialogDatasetSelector;
private boolean mOkToCallAssertNoDatasets;
@@ -201,19 +201,6 @@
mUserHelper = new UserHelper(mContext);
mPackageName = mContext.getPackageName();
mAutoman = instrumentation.getUiAutomation();
- mMyDisplayId = mUserHelper.getMainDisplayId();
-
- mDatasetPickerSelector =
- By.res("android", RESOURCE_ID_DATASET_PICKER).displayId(mMyDisplayId);
- mSaveUiSelector = By.res("android", RESOURCE_ID_SAVE_SNACKBAR).displayId(mMyDisplayId);
- mDatasetHeaderSelector =
- By.res("android", RESOURCE_ID_DATASET_HEADER).displayId(mMyDisplayId);
- mFillDialogSelector =
- By.res("android", RESOURCE_ID_FILL_DIALOG_PICKER).displayId(mMyDisplayId);
- mFillDialogHeaderSelector =
- By.res("android", RESOURCE_ID_FILL_DIALOG_HEADER).displayId(mMyDisplayId);
- mDialogDatasetSelector =
- By.res("android", RESOURCE_ID_FILL_DIALOG_DATASET).displayId(mMyDisplayId);
}
public void waitForIdle() {
@@ -249,6 +236,21 @@
}
/**
+ * Assumes the device has a minimum height and width of {@code minSizeDp}, throwing a
+ * {@code AssumptionViolatedException} if it doesn't (so the test is skipped by the JUnit
+ * Runner).
+ */
+ public void assumeMinimumResolutionInDp(int minSizeDp) {
+ final int widthInDp = mDevice.getDisplaySizeDp().x;
+ final int heightInDp = mDevice.getDisplaySizeDp().y;
+ final int min = Math.min(widthInDp, heightInDp);
+ assumeTrue("Screen size is too small (" + widthInDp + "x" + heightInDp + ")",
+ min >= minSizeDp);
+ Log.d(TAG, "assumeMinimumResolutionInDp(" + minSizeDp + ") passed: screen size is "
+ + widthInDp + "x" + heightInDp);
+ }
+
+ /**
* Sets the screen resolution in a way that the IME doesn't interfere with the Autofill UI
* when the device is rotated to landscape.
*
@@ -299,7 +301,7 @@
throw new IllegalStateException(
"Cannot call assertNoDatasets() without calling assertDatasets first");
}
- mDevice.wait(Until.gone(mDatasetPickerSelector), UI_DATASET_PICKER_TIMEOUT.ms());
+ mDevice.wait(Until.gone(DATASET_PICKER_SELECTOR), UI_DATASET_PICKER_TIMEOUT.ms());
mOkToCallAssertNoDatasets = false;
}
@@ -310,7 +312,7 @@
* cases where the dataset picker was not previous shown.
*/
public void assertNoDatasetsEver() throws Exception {
- assertNeverShown("dataset picker", mDatasetPickerSelector,
+ assertNeverShown("dataset picker", DATASET_PICKER_SELECTOR,
DATASET_PICKER_NOT_SHOWN_NAPTIME_MS);
}
@@ -354,7 +356,7 @@
final List<String> expectedChild = new ArrayList<>();
if (header != null) {
if (Helper.isAutofillWindowFullScreen(mContext)) {
- final UiObject2 headerView = waitForObject(mDatasetHeaderSelector,
+ final UiObject2 headerView = waitForObject(DATASET_HEADER_SELECTOR,
UI_DATASET_PICKER_TIMEOUT);
assertWithMessage("fullscreen wrong dataset header")
.that(getChildrenAsText(headerView))
@@ -414,7 +416,7 @@
* Selects a dataset that should be visible in the floating UI.
*/
public void selectDataset(UiObject2 picker, String name) {
- final UiObject2 dataset = picker.findObject(By.text(name).displayId(mMyDisplayId));
+ final UiObject2 dataset = picker.findObject(By.text(name));
if (dataset == null) {
throw new AssertionError("no dataset " + name + " in " + getChildrenAsText(picker));
}
@@ -462,7 +464,7 @@
public void selectByText(String name) throws Exception {
Log.v(TAG, "selectByText(): " + name);
- final UiObject2 object = waitForObject(By.text(name).displayId(mMyDisplayId));
+ final UiObject2 object = waitForObject(By.text(name));
object.click();
}
@@ -477,7 +479,7 @@
}
public UiObject2 assertShownByText(String text, Timeout timeout) throws Exception {
- final UiObject2 object = waitForObject(By.text(text).displayId(mMyDisplayId), timeout);
+ final UiObject2 object = waitForObject(By.text(text), timeout);
assertWithMessage("No node with text '%s'", text).that(object).isNotNull();
return object;
}
@@ -487,7 +489,7 @@
*/
@NonNull
public UiObject2 findRightAwayByText(@NonNull String text) throws Exception {
- final UiObject2 object = mDevice.findObject(By.text(text).displayId(mMyDisplayId));
+ final UiObject2 object = mDevice.findObject(By.text(text));
assertWithMessage("no UIObject for text '%s'", text).that(object).isNotNull();
return object;
}
@@ -499,11 +501,31 @@
* <p>Typically called after another assertion that waits for a condition to be shown.
*/
public void assertNotShowingForSure(String text) throws Exception {
- final UiObject2 object = mDevice.findObject(By.text(text).displayId(mMyDisplayId));
+ final UiObject2 object = mDevice.findObject(By.text(text));
assertWithMessage("Found node with text '%s'", text).that(object).isNull();
}
/**
+ * Asserts a node with the given content description is shown.
+ *
+ */
+ public UiObject2 assertShownByContentDescription(String contentDescription) throws Exception {
+ final UiObject2 object = waitForObject(By.desc(contentDescription));
+ assertWithMessage("No node with content description '%s'", contentDescription).that(object)
+ .isNotNull();
+ return object;
+ }
+
+ /**
+ * Checks if a View with a certain text exists.
+ */
+ public boolean hasViewWithText(String name) {
+ Log.v(TAG, "hasViewWithText(): " + name);
+
+ return mDevice.findObject(By.text(name)) != null;
+ }
+
+ /**
* Selects a view by id.
*/
public UiObject2 selectByRelativeId(String id) throws Exception {
@@ -512,7 +534,7 @@
public UiObject2 selectByRelativeId(String packageName, String id) throws Exception {
Log.v(TAG, "selectByRelativeId(): " + packageName + ":/" + id);
- UiObject2 object = waitForObject(By.res(packageName, id).displayId(mMyDisplayId));
+ UiObject2 object = waitForObject(By.res(packageName, id));
object.click();
return object;
}
@@ -521,7 +543,7 @@
* Asserts the id is shown on the screen.
*/
public UiObject2 assertShownById(String id) throws Exception {
- final UiObject2 object = waitForObject(By.res(id).displayId(mMyDisplayId));
+ final UiObject2 object = waitForObject(By.res(id));
assertThat(object).isNotNull();
return object;
}
@@ -534,8 +556,7 @@
}
public UiObject2 assertShownByRelativeId(String id, Timeout timeout) throws Exception {
- final UiObject2 obj =
- waitForObject(By.res(mPackageName, id).displayId(mMyDisplayId), timeout);
+ final UiObject2 obj = waitForObject(By.res(mPackageName, id), timeout);
assertThat(obj).isNotNull();
return obj;
}
@@ -566,8 +587,7 @@
*/
public void assertGoneByRelativeId(@Nullable UiObject2 parent, @NonNull String id,
@NonNull Timeout timeout) {
- final SearchCondition<Boolean> condition =
- Until.gone(By.res(mPackageName, id).displayId(mMyDisplayId));
+ final SearchCondition<Boolean> condition = Until.gone(By.res(mPackageName, id));
final boolean gone = parent != null
? parent.wait(condition, timeout.ms())
: mDevice.wait(condition, timeout.ms());
@@ -585,8 +605,7 @@
public void assertNeverShownByRelativeId(@NonNull String description, int resId, long timeout)
throws Exception {
- final BySelector selector =
- By.res(Helper.MY_PACKAGE, getIdName(resId)).displayId(mMyDisplayId);
+ final BySelector selector = By.res(Helper.MY_PACKAGE, getIdName(resId));
assertNeverShown(description, selector, timeout);
}
@@ -608,21 +627,21 @@
* Gets the text set on a view.
*/
public String getTextByRelativeId(String id) throws Exception {
- return waitForObject(By.res(mPackageName, id).displayId(mMyDisplayId)).getText();
+ return waitForObject(By.res(mPackageName, id)).getText();
}
/**
* Focus in the view with the given resource id.
*/
public void focusByRelativeId(String id) throws Exception {
- waitForObject(By.res(mPackageName, id).displayId(mMyDisplayId)).click();
+ waitForObject(By.res(mPackageName, id)).click();
}
/**
* Sets a new text on a view.
*/
public void setTextByRelativeId(String id, String newText) throws Exception {
- waitForObject(By.res(mPackageName, id).displayId(mMyDisplayId)).setText(newText);
+ waitForObject(By.res(mPackageName, id)).setText(newText);
}
/**
@@ -635,7 +654,7 @@
* resetting to empty at once.
*/
public void clearTextByRelativeId(String id) throws Exception {
- final UiObject2 object = waitForObject(By.res(mPackageName, id).displayId(mMyDisplayId));
+ final UiObject2 object = waitForObject(By.res(mPackageName, id));
String oldText = object.getText();
if (!oldText.isEmpty()) {
object.setText(String.valueOf(oldText.charAt(0)));
@@ -679,13 +698,7 @@
*/
public void pressBack() {
Log.d(TAG, "pressBack()");
- try {
- SystemUtil.runShellCommand(
- InstrumentationRegistry.getInstrumentation().getUiAutomation(),
- String.format("input -d %d keyevent %d", mMyDisplayId, KEYCODE_BACK));
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
+ mDevice.pressBack();
}
/**
@@ -693,20 +706,14 @@
*/
public void pressHome() {
Log.d(TAG, "pressHome()");
- try {
- SystemUtil.runShellCommand(
- InstrumentationRegistry.getInstrumentation().getUiAutomation(),
- String.format("input -d %d keyevent %d", mMyDisplayId, KEYCODE_HOME));
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
+ mDevice.pressHome();
}
/**
* Asserts the save snackbar is not showing.
*/
public void assertSaveNotShowing(int type) throws Exception {
- assertNeverShown("save UI for type " + saveTypeToString(type), mSaveUiSelector,
+ assertNeverShown("save UI for type " + saveTypeToString(type), SAVE_UI_SELECTOR,
SAVE_NOT_SHOWN_NAPTIME_MS);
}
@@ -715,12 +722,12 @@
*/
public void assertSaveNotShowing(int type, @Nullable String when) throws Exception {
String suffix = when == null ? "" : " when " + when;
- assertNeverShown("save UI for type " + saveTypeToString(type) + suffix, mSaveUiSelector,
+ assertNeverShown("save UI for type " + saveTypeToString(type) + suffix, SAVE_UI_SELECTOR,
SAVE_NOT_SHOWN_NAPTIME_MS);
}
public void assertSaveNotShowing() throws Exception {
- assertNeverShown("save UI", mSaveUiSelector, SAVE_NOT_SHOWN_NAPTIME_MS);
+ assertNeverShown("save UI", SAVE_UI_SELECTOR, SAVE_NOT_SHOWN_NAPTIME_MS);
}
private String getSaveTypeString(int type) {
@@ -819,15 +826,15 @@
int positiveButtonStyle, String description, Timeout timeout, String serviceLabel,
int... types) throws Exception {
- final UiObject2 snackbar = waitForObject(mSaveUiSelector, timeout);
+ final UiObject2 snackbar = waitForObject(SAVE_UI_SELECTOR, timeout);
- final UiObject2 titleView = waitForObject(snackbar,
- By.res("android", RESOURCE_ID_SAVE_TITLE).displayId(mMyDisplayId), timeout);
+ final UiObject2 titleView =
+ waitForObject(snackbar, By.res("android", RESOURCE_ID_SAVE_TITLE), timeout);
assertWithMessage("save title (%s) is not shown", RESOURCE_ID_SAVE_TITLE).that(titleView)
.isNotNull();
- final UiObject2 iconView = waitForObject(snackbar,
- By.res("android", RESOURCE_ID_SAVE_ICON).displayId(mMyDisplayId), timeout);
+ final UiObject2 iconView =
+ waitForObject(snackbar, By.res("android", RESOURCE_ID_SAVE_ICON), timeout);
assertWithMessage("save icon (%s) is not shown", RESOURCE_ID_SAVE_ICON).that(iconView)
.isNotNull();
@@ -867,8 +874,7 @@
}
if (description != null) {
- final UiObject2 saveSubTitle =
- snackbar.findObject(By.text(description).displayId(mMyDisplayId));
+ final UiObject2 saveSubTitle = snackbar.findObject(By.text(description));
assertWithMessage("save subtitle(%s)", description).that(saveSubTitle).isNotNull();
}
@@ -883,7 +889,7 @@
}
final String expectedPositiveButtonText = getString(positiveButtonStringId).toUpperCase();
final UiObject2 positiveButton = waitForObject(snackbar,
- By.res("android", RESOURCE_ID_SAVE_BUTTON_YES).displayId(mMyDisplayId), timeout);
+ By.res("android", RESOURCE_ID_SAVE_BUTTON_YES), timeout);
assertWithMessage("wrong text on positive button")
.that(positiveButton.getText().toUpperCase()).isEqualTo(expectedPositiveButtonText);
@@ -897,7 +903,7 @@
}
final String expectedNegativeButtonText = getString(negativeButtonStringId).toUpperCase();
final UiObject2 negativeButton = waitForObject(snackbar,
- By.res("android", RESOURCE_ID_SAVE_BUTTON_NO).displayId(mMyDisplayId), timeout);
+ By.res("android", RESOURCE_ID_SAVE_BUTTON_NO), timeout);
assertWithMessage("wrong text on negative button")
.that(negativeButton.getText().toUpperCase()).isEqualTo(expectedNegativeButtonText);
@@ -968,8 +974,7 @@
public void saveForAutofill(UiObject2 saveSnackBar, boolean yesDoIt) {
final String id = yesDoIt ? "autofill_save_yes" : "autofill_save_no";
- final UiObject2 button =
- saveSnackBar.findObject(By.res("android", id).displayId(mMyDisplayId));
+ final UiObject2 button = saveSnackBar.findObject(By.res("android", id));
assertWithMessage("save button (%s)", id).that(button).isNotNull();
button.click();
}
@@ -985,12 +990,12 @@
* @param id resource id of the field.
*/
public UiObject2 getAutofillMenuOption(String id) throws Exception {
- final UiObject2 field = waitForObject(By.res(mPackageName, id).displayId(mMyDisplayId));
+ final UiObject2 field = waitForObject(By.res(mPackageName, id));
// TODO: figure out why obj.longClick() doesn't always work
field.click(LONG_PRESS_MS);
- List<UiObject2> menuItems = waitForObjects(By.res("android",
- RESOURCE_ID_CONTEXT_MENUITEM).displayId(mMyDisplayId), mDefaultTimeout);
+ List<UiObject2> menuItems = waitForObjects(
+ By.res("android", RESOURCE_ID_CONTEXT_MENUITEM), mDefaultTimeout);
final String expectedText = getAutofillContextualMenuTitle();
final StringBuffer menuNames = new StringBuffer();
@@ -1008,8 +1013,7 @@
menuNames.append(";");
// First menu does not have AUTOFILL, check overflow
- final BySelector overflowSelector =
- By.res("android", RESOURCE_ID_OVERFLOW).displayId(mMyDisplayId);
+ final BySelector overflowSelector = By.res("android", RESOURCE_ID_OVERFLOW);
// Click overflow menu button.
final UiObject2 overflowMenu = waitForObject(overflowSelector, mDefaultTimeout);
@@ -1018,8 +1022,8 @@
// Wait for overflow menu to show.
mDevice.wait(Until.gone(overflowSelector), 1000);
- menuItems = waitForObjects(By.res("android", RESOURCE_ID_CONTEXT_MENUITEM)
- .displayId(mMyDisplayId), mDefaultTimeout);
+ menuItems = waitForObjects(
+ By.res("android", RESOURCE_ID_CONTEXT_MENUITEM), mDefaultTimeout);
for (UiObject2 menuItem : menuItems) {
final String menuName = menuItem.getText();
if (menuName.equalsIgnoreCase(expectedText)) {
@@ -1106,6 +1110,22 @@
}
/**
+ * Waits and returns an object that is a child of a parent {@link UiObject2} base on string
+ * resource id.
+ *
+ * @param parent where to find the object (or {@code null} to use device's root).
+ * @param resourceId resource id of the child.
+ * @param timeout specifies the timeout for retries
+ * @return the object that is found
+ * @throws Exception if the object is not found after the timeout
+ */
+ public UiObject2 waitForObject(
+ @Nullable UiObject2 parent, @NonNull String resourceId, @NonNull Timeout timeout)
+ throws Exception {
+ return waitForObject(parent, By.res(mPackageName, resourceId), timeout);
+ }
+
+ /**
* Waits for and returns an object.
*
* @param selector {@link BySelector} that identifies the object.
@@ -1116,13 +1136,11 @@
return waitForObject(/* parent= */ null, selector, timeout);
}
- /**
- * Waits for and returns a child from a parent {@link UiObject2}.
- */
+ /** Waits for and returns a child from a parent {@link UiObject2}. */
public UiObject2 assertChildText(UiObject2 parent, String resourceId, String expectedText)
throws Exception {
- final UiObject2 child = waitForObject(parent,
- By.res(mPackageName, resourceId).displayId(mMyDisplayId), Timeouts.UI_TIMEOUT);
+ final UiObject2 child = waitForObject(parent, By.res(mPackageName, resourceId),
+ Timeouts.UI_TIMEOUT);
assertWithMessage("wrong text for view '%s'", resourceId).that(child.getText())
.isEqualTo(expectedText);
return child;
@@ -1185,7 +1203,7 @@
final String expectedTitle = getString(RESOURCE_STRING_DATASET_PICKER_ACCESSIBILITY_TITLE);
while (retryCount < MAX_UIOBJECT_RETRY_COUNT) {
try {
- picker = waitForObject(mDatasetPickerSelector, timeout);
+ picker = waitForObject(DATASET_PICKER_SELECTOR, timeout);
assertAccessibilityTitle(picker, expectedTitle);
break;
} catch (StaleObjectException e) {
@@ -1231,7 +1249,7 @@
InstrumentationRegistry.getInstrumentation()
.getContext()
.getSystemService(DisplayManager.class)
- .getDisplay(mMyDisplayId)
+ .getDisplay(Display.DEFAULT_DISPLAY)
.getRotation();
return orientation == currentRotation;
}
@@ -1251,7 +1269,7 @@
// always use UiBot#setScreenOrientation() to change the screen rotation, which blocks until
// new rotation is reflected on the device.
final int currentRotation = InstrumentationRegistry.getInstrumentation().getContext()
- .getSystemService(DisplayManager.class).getDisplay(mMyDisplayId)
+ .getSystemService(DisplayManager.class).getDisplay(Display.DEFAULT_DISPLAY)
.getRotation();
mAutoman.setRotation(orientation);
@@ -1364,8 +1382,7 @@
*/
public void assertChild(@NonNull UiObject2 parent, @NonNull String childId,
@Nullable Visitor<UiObject2> assertion) {
- final UiObject2 child =
- parent.findObject(By.res(mPackageName, childId).displayId(mMyDisplayId));
+ final UiObject2 child = parent.findObject(By.res(mPackageName, childId));
try {
if (assertion != null) {
assertWithMessage("Didn't find child with id '%s'", childId).that(child)
@@ -1436,7 +1453,7 @@
// "No thanks" button shown
final UiObject2 rejectButton = picker.findObject(
- By.res("android", RESOURCE_ID_FILL_DIALOG_BUTTON_NO).displayId(mMyDisplayId));
+ By.res("android", RESOURCE_ID_FILL_DIALOG_BUTTON_NO));
assertWithMessage("No reject button in fill dialog")
.that(rejectButton).isNotNull();
assertWithMessage("wrong text on reject button")
@@ -1452,7 +1469,7 @@
// "Continue" button shown
final UiObject2 acceptButton = picker.findObject(
- By.res("android", RESOURCE_ID_FILL_DIALOG_BUTTON_YES).displayId(mMyDisplayId));
+ By.res("android", RESOURCE_ID_FILL_DIALOG_BUTTON_YES));
assertWithMessage("No accept button in fill dialog")
.that(acceptButton).isNotNull();
assertWithMessage("wrong text on accept button")
@@ -1468,7 +1485,7 @@
// "Continue" button not shown
final UiObject2 acceptButton = picker.findObject(
- By.res("android", RESOURCE_ID_FILL_DIALOG_BUTTON_YES).displayId(mMyDisplayId));
+ By.res("android", RESOURCE_ID_FILL_DIALOG_BUTTON_YES));
assertWithMessage("wrong accept button in fill dialog")
.that(acceptButton).isNull();
}
@@ -1510,7 +1527,7 @@
*/
public void touchOutsideSaveDialog() throws Exception {
Log.v(TAG, "touchOutsideSaveDialog()");
- final UiObject2 picker = waitForObject(mSaveUiSelector, SAVE_TIMEOUT);
+ final UiObject2 picker = waitForObject(SAVE_UI_SELECTOR, SAVE_TIMEOUT);
Log.v(TAG, "got picker: " + picker);
final Rect bounds = picker.getVisibleBounds();
assertThat(injectClick(new Point(bounds.left, bounds.top / 2))).isTrue();
@@ -1522,28 +1539,28 @@
public void clickFillDialogDismiss() throws Exception {
Log.v(TAG, "dismissedFillDialog()");
final UiObject2 picker = findFillDialogPicker();
- final UiObject2 noButton = picker.findObject(By.res("android",
- RESOURCE_ID_FILL_DIALOG_BUTTON_NO).displayId(mMyDisplayId));
+ final UiObject2 noButton =
+ picker.findObject(By.res("android", RESOURCE_ID_FILL_DIALOG_BUTTON_NO));
noButton.click();
}
private UiObject2 findFillDialogPicker() throws Exception {
- return waitForObject(mFillDialogSelector, UI_DATASET_PICKER_TIMEOUT);
+ return waitForObject(FILL_DIALOG_SELECTOR, UI_DATASET_PICKER_TIMEOUT);
}
public UiObject2 findFillDialogDatasetPicker() throws Exception {
- return waitForObject(mDialogDatasetSelector, UI_DATASET_PICKER_TIMEOUT);
+ return waitForObject(FILL_DIALOG_DATASET_SELECTOR, UI_DATASET_PICKER_TIMEOUT);
}
public UiObject2 findFillDialogHeaderPicker() throws Exception {
- return waitForObject(mFillDialogHeaderSelector, UI_DATASET_PICKER_TIMEOUT);
+ return waitForObject(FILL_DIALOG_HEADER_SELECTOR, UI_DATASET_PICKER_TIMEOUT);
}
/**
* Asserts the fill dialog is not shown.
*/
public void assertNoFillDialog() throws Exception {
- assertNeverShown("Fill dialog", mFillDialogSelector, DATASET_PICKER_NOT_SHOWN_NAPTIME_MS);
+ assertNeverShown("Fill dialog", FILL_DIALOG_SELECTOR, DATASET_PICKER_NOT_SHOWN_NAPTIME_MS);
}
/**
diff --git a/tests/devicepolicy/src/android/devicepolicy/cts/BluetoothTest.java b/tests/devicepolicy/src/android/devicepolicy/cts/BluetoothTest.java
index f135db0..6304781 100644
--- a/tests/devicepolicy/src/android/devicepolicy/cts/BluetoothTest.java
+++ b/tests/devicepolicy/src/android/devicepolicy/cts/BluetoothTest.java
@@ -449,7 +449,7 @@
Poll.forValue("Opp Launcher Component Enabled",
() -> TestApis.packages().activity(OPP_LAUNCHER_COMPONENT)
- .isEnabled(TestApis.users().system()))
+ .isEnabled(TestApis.users().current()))
.toBeEqualTo(false)
.errorOnFail()
.await();
diff --git a/tests/devicepolicy/src/android/devicepolicy/cts/PreferentialNetworkServiceTest.java b/tests/devicepolicy/src/android/devicepolicy/cts/PreferentialNetworkServiceTest.java
index dd5a956..57261a2 100644
--- a/tests/devicepolicy/src/android/devicepolicy/cts/PreferentialNetworkServiceTest.java
+++ b/tests/devicepolicy/src/android/devicepolicy/cts/PreferentialNetworkServiceTest.java
@@ -17,11 +17,13 @@
package android.devicepolicy.cts;
import static android.Manifest.permission.ACCESS_NETWORK_STATE;
+import static android.Manifest.permission.MANAGE_TEST_NETWORKS;
import static android.Manifest.permission.NETWORK_SETTINGS;
import static android.net.NetworkCapabilities.NET_CAPABILITY_ENTERPRISE;
import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED;
+import static android.net.NetworkCapabilities.TRANSPORT_TEST;
import static com.google.common.truth.Truth.assertThat;
@@ -84,6 +86,7 @@
sContext.getSystemService(ConnectivityManager.class);
private final HandlerThread mHandlerThread = new HandlerThread(TAG + " handler thread");
private final NetworkCapabilities mEnterpriseNcFilter = new NetworkCapabilities.Builder()
+ .addTransportType(TRANSPORT_TEST)
.addCapability(NET_CAPABILITY_INTERNET)
.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
.addCapability(NET_CAPABILITY_ENTERPRISE)
@@ -140,7 +143,7 @@
* Enable PreferentialNetworkService, verify the provider that provides enterprise slice can
* see the enterprise slice requests.
*/
- @EnsureHasPermission({ACCESS_NETWORK_STATE, NETWORK_SETTINGS})
+ @EnsureHasPermission({ACCESS_NETWORK_STATE, NETWORK_SETTINGS, MANAGE_TEST_NETWORKS})
@PolicyAppliesTest(policy = PreferentialNetworkService.class)
public void setPreferentialNetworkServiceEnabled_enableService_issueRequest() {
// Expect a regular default network.
@@ -177,7 +180,7 @@
* Disable PreferentialNetworkService, verify the provider that provides enterprise slice cannot
* see the enterprise slice requests.
*/
- @EnsureHasPermission({ACCESS_NETWORK_STATE, NETWORK_SETTINGS})
+ @EnsureHasPermission({ACCESS_NETWORK_STATE, NETWORK_SETTINGS, MANAGE_TEST_NETWORKS})
@PolicyAppliesTest(policy = PreferentialNetworkService.class)
public void setPreferentialNetworkServiceEnabled_disableService_noIssueRequest() {
// Expect a regular default network.
diff --git a/tests/devicepolicy/src/android/devicepolicy/cts/WipeDataTest.java b/tests/devicepolicy/src/android/devicepolicy/cts/WipeDataTest.java
index 0689e52..50f9405 100644
--- a/tests/devicepolicy/src/android/devicepolicy/cts/WipeDataTest.java
+++ b/tests/devicepolicy/src/android/devicepolicy/cts/WipeDataTest.java
@@ -24,25 +24,26 @@
import static com.google.common.truth.Truth.assertWithMessage;
import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.fail;
import android.app.admin.DevicePolicyManager;
+import com.android.bedstead.enterprise.annotations.EnsureHasDeviceOwner;
+import com.android.bedstead.enterprise.annotations.EnsureHasProfileOwner;
+import com.android.bedstead.enterprise.annotations.EnsureHasWorkProfile;
import com.android.bedstead.harrier.BedsteadJUnit4;
import com.android.bedstead.harrier.DeviceState;
import com.android.bedstead.harrier.annotations.EnsureHasAdditionalUser;
import com.android.bedstead.harrier.annotations.EnsureHasNoAdditionalUser;
-import com.android.bedstead.enterprise.annotations.EnsureHasWorkProfile;
import com.android.bedstead.harrier.annotations.Postsubmit;
import com.android.bedstead.harrier.annotations.RequireHeadlessSystemUserMode;
import com.android.bedstead.harrier.annotations.RequireRunOnAdditionalUser;
import com.android.bedstead.harrier.annotations.RequireRunOnInitialUser;
import com.android.bedstead.harrier.annotations.RequireRunOnSystemUser;
-import com.android.bedstead.enterprise.annotations.EnsureHasDeviceOwner;
-import com.android.bedstead.enterprise.annotations.EnsureHasProfileOwner;
-import com.android.bedstead.permissions.annotations.EnsureDoesNotHavePermission;
import com.android.bedstead.nene.TestApis;
import com.android.bedstead.nene.users.UserReference;
import com.android.bedstead.nene.utils.Poll;
+import com.android.bedstead.permissions.annotations.EnsureDoesNotHavePermission;
import com.android.compatibility.common.util.ApiTest;
import org.junit.ClassRule;
@@ -115,10 +116,16 @@
@EnsureHasAdditionalUser
@RequireRunOnSystemUser(switchedToUser = ANY)
@ApiTest(apis = "android.app.admin.DevicePolicyManager#wipeData")
- public void wipeData_systemUser_throwsSecurityException() {
- assertThrows("System user should not be removed",
- SecurityException.class,
- () -> sDeviceState.dpc().devicePolicyManager().wipeData(/* flags= */ 0));
+ public void wipeData_systemUser_throwsException() {
+ try {
+ sDeviceState.dpc().devicePolicyManager().wipeData(/* flags= */ 0);
+ } catch (RuntimeException e) {
+ assertWithMessage("Should throw either SE or ISE when attempting to wipe system user")
+ .that(e instanceof SecurityException || e instanceof IllegalStateException)
+ .isTrue();
+ return;
+ }
+ fail("Should have thrown an exception");
}
@Postsubmit(reason = "new test")
diff --git a/tests/framework/base/windowmanager/intent_tests/clearCases/clear-task_with_new-task.json b/tests/framework/base/windowmanager/intent_tests/clearCases/clear-task_with_new-task.json
index 18bcd6f81..d580895 100644
--- a/tests/framework/base/windowmanager/intent_tests/clearCases/clear-task_with_new-task.json
+++ b/tests/framework/base/windowmanager/intent_tests/clearCases/clear-task_with_new-task.json
@@ -17,28 +17,34 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/clearCases/clear-task_without_new-task.json b/tests/framework/base/windowmanager/intent_tests/clearCases/clear-task_without_new-task.json
index cd89b22..58ec8e4 100644
--- a/tests/framework/base/windowmanager/intent_tests/clearCases/clear-task_without_new-task.json
+++ b/tests/framework/base/windowmanager/intent_tests/clearCases/clear-task_without_new-task.json
@@ -17,32 +17,38 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/clearCases/test-1.json b/tests/framework/base/windowmanager/intent_tests/clearCases/test-1.json
index 8e477ed..9aa54da 100644
--- a/tests/framework/base/windowmanager/intent_tests/clearCases/test-1.json
+++ b/tests/framework/base/windowmanager/intent_tests/clearCases/test-1.json
@@ -17,28 +17,34 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/clearCases/test-2.json b/tests/framework/base/windowmanager/intent_tests/clearCases/test-2.json
index 15f0db4..a370039 100644
--- a/tests/framework/base/windowmanager/intent_tests/clearCases/test-2.json
+++ b/tests/framework/base/windowmanager/intent_tests/clearCases/test-2.json
@@ -23,36 +23,42 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/clearCases/test-3.json b/tests/framework/base/windowmanager/intent_tests/clearCases/test-3.json
index 304dce9..bca7402 100644
--- a/tests/framework/base/windowmanager/intent_tests/clearCases/test-3.json
+++ b/tests/framework/base/windowmanager/intent_tests/clearCases/test-3.json
@@ -23,36 +23,42 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/clearCases/test-4.json b/tests/framework/base/windowmanager/intent_tests/clearCases/test-4.json
index e73fc19..6240ce1 100644
--- a/tests/framework/base/windowmanager/intent_tests/clearCases/test-4.json
+++ b/tests/framework/base/windowmanager/intent_tests/clearCases/test-4.json
@@ -23,36 +23,42 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/clearCases/test-5.json b/tests/framework/base/windowmanager/intent_tests/clearCases/test-5.json
index 67fba8ac2..6ef0f8a 100644
--- a/tests/framework/base/windowmanager/intent_tests/clearCases/test-5.json
+++ b/tests/framework/base/windowmanager/intent_tests/clearCases/test-5.json
@@ -23,36 +23,42 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/clearCases/test-6.json b/tests/framework/base/windowmanager/intent_tests/clearCases/test-6.json
index 1a1471e..7a2cdf8 100644
--- a/tests/framework/base/windowmanager/intent_tests/clearCases/test-6.json
+++ b/tests/framework/base/windowmanager/intent_tests/clearCases/test-6.json
@@ -29,40 +29,46 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "STOPPED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/clearCases/test-no-history-1.json b/tests/framework/base/windowmanager/intent_tests/clearCases/test-no-history-1.json
index 5e90c3f..1365cf1 100644
--- a/tests/framework/base/windowmanager/intent_tests/clearCases/test-no-history-1.json
+++ b/tests/framework/base/windowmanager/intent_tests/clearCases/test-no-history-1.json
@@ -17,28 +17,34 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTopActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTopActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/clearCases/test-no-history-2.json b/tests/framework/base/windowmanager/intent_tests/clearCases/test-no-history-2.json
index 0e6e758..a4405e1 100644
--- a/tests/framework/base/windowmanager/intent_tests/clearCases/test-no-history-2.json
+++ b/tests/framework/base/windowmanager/intent_tests/clearCases/test-no-history-2.json
@@ -23,36 +23,42 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTopActivity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTopActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/forResult/test-1.json b/tests/framework/base/windowmanager/intent_tests/forResult/test-1.json
index b26456b..14d307f 100644
--- a/tests/framework/base/windowmanager/intent_tests/forResult/test-1.json
+++ b/tests/framework/base/windowmanager/intent_tests/forResult/test-1.json
@@ -17,28 +17,34 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/forResult/test-10.json b/tests/framework/base/windowmanager/intent_tests/forResult/test-10.json
index a971364..afff5ac 100644
--- a/tests/framework/base/windowmanager/intent_tests/forResult/test-10.json
+++ b/tests/framework/base/windowmanager/intent_tests/forResult/test-10.json
@@ -17,33 +17,38 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "STOPPED"
- }
- ]
- }
- ]
-
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/forResult/test-11.json b/tests/framework/base/windowmanager/intent_tests/forResult/test-11.json
index eeb7b4f..9d32b94 100644
--- a/tests/framework/base/windowmanager/intent_tests/forResult/test-11.json
+++ b/tests/framework/base/windowmanager/intent_tests/forResult/test-11.json
@@ -23,49 +23,100 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
- "state": "RESUMED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
- "state": "STOPPED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
-
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+ "state": "STOPPED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+ "state": "STOPPED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/forResult/test-12.json b/tests/framework/base/windowmanager/intent_tests/forResult/test-12.json
index 84402cb..b2b4202 100644
--- a/tests/framework/base/windowmanager/intent_tests/forResult/test-12.json
+++ b/tests/framework/base/windowmanager/intent_tests/forResult/test-12.json
@@ -23,40 +23,67 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity",
- "state": "RESUMED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/forResult/test-13.json b/tests/framework/base/windowmanager/intent_tests/forResult/test-13.json
index eaf733f..079e147 100644
--- a/tests/framework/base/windowmanager/intent_tests/forResult/test-13.json
+++ b/tests/framework/base/windowmanager/intent_tests/forResult/test-13.json
@@ -23,32 +23,38 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/forResult/test-14.json b/tests/framework/base/windowmanager/intent_tests/forResult/test-14.json
index f9fa7ea..1a6f413 100644
--- a/tests/framework/base/windowmanager/intent_tests/forResult/test-14.json
+++ b/tests/framework/base/windowmanager/intent_tests/forResult/test-14.json
@@ -23,32 +23,38 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/forResult/test-15.json b/tests/framework/base/windowmanager/intent_tests/forResult/test-15.json
index 1f7fec6..e161d50 100644
--- a/tests/framework/base/windowmanager/intent_tests/forResult/test-15.json
+++ b/tests/framework/base/windowmanager/intent_tests/forResult/test-15.json
@@ -29,52 +29,108 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity",
- "state": "RESUMED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
- "state": "STOPPED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+ "state": "STOPPED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/forResult/test-16.json b/tests/framework/base/windowmanager/intent_tests/forResult/test-16.json
index 813d82c..93891f7 100644
--- a/tests/framework/base/windowmanager/intent_tests/forResult/test-16.json
+++ b/tests/framework/base/windowmanager/intent_tests/forResult/test-16.json
@@ -29,52 +29,108 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity",
- "state": "RESUMED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
- "state": "STOPPED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity",
- "state": "STOPPED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+ "state": "STOPPED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity",
+ "state": "STOPPED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity",
+ "state": "STOPPED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/forResult/test-2.json b/tests/framework/base/windowmanager/intent_tests/forResult/test-2.json
index 685b00f..22e4b311 100644
--- a/tests/framework/base/windowmanager/intent_tests/forResult/test-2.json
+++ b/tests/framework/base/windowmanager/intent_tests/forResult/test-2.json
@@ -17,28 +17,34 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/forResult/test-3.json b/tests/framework/base/windowmanager/intent_tests/forResult/test-3.json
index 7c2d5e9..6de47fe 100644
--- a/tests/framework/base/windowmanager/intent_tests/forResult/test-3.json
+++ b/tests/framework/base/windowmanager/intent_tests/forResult/test-3.json
@@ -17,28 +17,34 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTopActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTopActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTopActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTopActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/forResult/test-4.json b/tests/framework/base/windowmanager/intent_tests/forResult/test-4.json
index 23d175d..905a3a8 100644
--- a/tests/framework/base/windowmanager/intent_tests/forResult/test-4.json
+++ b/tests/framework/base/windowmanager/intent_tests/forResult/test-4.json
@@ -17,28 +17,34 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTopActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTopActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTopActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTopActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/forResult/test-5.json b/tests/framework/base/windowmanager/intent_tests/forResult/test-5.json
index 8e477ed..9aa54da 100644
--- a/tests/framework/base/windowmanager/intent_tests/forResult/test-5.json
+++ b/tests/framework/base/windowmanager/intent_tests/forResult/test-5.json
@@ -17,28 +17,34 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/forResult/test-6.json b/tests/framework/base/windowmanager/intent_tests/forResult/test-6.json
index dc2f620..5aada31 100644
--- a/tests/framework/base/windowmanager/intent_tests/forResult/test-6.json
+++ b/tests/framework/base/windowmanager/intent_tests/forResult/test-6.json
@@ -17,28 +17,34 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/forResult/test-7.json b/tests/framework/base/windowmanager/intent_tests/forResult/test-7.json
index 95c2d0b..bfc97bd 100644
--- a/tests/framework/base/windowmanager/intent_tests/forResult/test-7.json
+++ b/tests/framework/base/windowmanager/intent_tests/forResult/test-7.json
@@ -17,36 +17,63 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/forResult/test-8.json b/tests/framework/base/windowmanager/intent_tests/forResult/test-8.json
index 032558a..f35f7e2 100644
--- a/tests/framework/base/windowmanager/intent_tests/forResult/test-8.json
+++ b/tests/framework/base/windowmanager/intent_tests/forResult/test-8.json
@@ -23,36 +23,42 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/forResult/test-9.json b/tests/framework/base/windowmanager/intent_tests/forResult/test-9.json
index 588a98d..43d7efd 100644
--- a/tests/framework/base/windowmanager/intent_tests/forResult/test-9.json
+++ b/tests/framework/base/windowmanager/intent_tests/forResult/test-9.json
@@ -23,36 +23,42 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-1.json b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-1.json
index c0c9af0..a3b4b26 100644
--- a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-1.json
+++ b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-1.json
@@ -17,36 +17,63 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
- "state": "RESUMED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-10.json b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-10.json
index 1f9c91c..7995d0e 100644
--- a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-10.json
+++ b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-10.json
@@ -17,36 +17,63 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-11.json b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-11.json
index 64cc2c9..bd4d98f 100644
--- a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-11.json
+++ b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-11.json
@@ -17,28 +17,34 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-12.json b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-12.json
index ca2bb0f..ce3009e 100644
--- a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-12.json
+++ b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-12.json
@@ -17,28 +17,34 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-13.json b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-13.json
index e840860..01010b9 100644
--- a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-13.json
+++ b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-13.json
@@ -18,32 +18,38 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$DocumentLaunchNeverActivity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$DocumentLaunchNeverActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-14.json b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-14.json
index 76e16fa..62bbd52 100644
--- a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-14.json
+++ b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-14.json
@@ -24,46 +24,92 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
- "state": "RESUMED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$DocumentLaunchNeverActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
-
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$DocumentLaunchNeverActivity",
- "state": "RESUMED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
-
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$DocumentLaunchNeverActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$DocumentLaunchNeverActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$DocumentLaunchNeverActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$DocumentLaunchNeverActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-15.json b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-15.json
index a024da2..d575e6b 100644
--- a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-15.json
+++ b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-15.json
@@ -26,46 +26,92 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$DocumentLaunchIntoActivity",
- "state": "RESUMED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
-
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$DocumentLaunchIntoActivity",
- "state": "RESUMED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
-
- }
-}
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$DocumentLaunchIntoActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$DocumentLaunchIntoActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$DocumentLaunchIntoActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$DocumentLaunchIntoActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-16.json b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-16.json
index e68d8c6..486b709 100644
--- a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-16.json
+++ b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-16.json
@@ -26,52 +26,108 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$DocumentLaunchAlwaysActivity",
- "state": "RESUMED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$DocumentLaunchAlwaysActivity",
- "state": "RESUMED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$DocumentLaunchAlwaysActivity",
- "state": "STOPPED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
-}
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$DocumentLaunchAlwaysActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$DocumentLaunchAlwaysActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$DocumentLaunchAlwaysActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$DocumentLaunchAlwaysActivity",
+ "state": "STOPPED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$DocumentLaunchAlwaysActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$DocumentLaunchAlwaysActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-17.json b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-17.json
index 50d6dc8..cb481b0 100644
--- a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-17.json
+++ b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-17.json
@@ -26,52 +26,108 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$DocumentLaunchIntoActivity",
- "state": "RESUMED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$DocumentLaunchIntoActivity",
- "state": "RESUMED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$DocumentLaunchIntoActivity",
- "state": "STOPPED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
-}
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$DocumentLaunchIntoActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$DocumentLaunchIntoActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$DocumentLaunchIntoActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$DocumentLaunchIntoActivity",
+ "state": "STOPPED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$DocumentLaunchIntoActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$DocumentLaunchIntoActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-2.json b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-2.json
index cb74d21..18ee215 100644
--- a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-2.json
+++ b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-2.json
@@ -17,36 +17,63 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
- "state": "RESUMED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-3.json b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-3.json
index fe88fad..9ff5506 100644
--- a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-3.json
+++ b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-3.json
@@ -17,32 +17,38 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-4.json b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-4.json
index 810f44d..15fab52 100644
--- a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-4.json
+++ b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-4.json
@@ -17,36 +17,63 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "RESUMED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-5.json b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-5.json
index 8316f2d..2be5c62 100644
--- a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-5.json
+++ b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-5.json
@@ -17,28 +17,34 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-6.json b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-6.json
index 2957f18..9ef8170 100644
--- a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-6.json
+++ b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-6.json
@@ -17,36 +17,63 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTopActivity",
- "state": "RESUMED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTopActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTopActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-7.json b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-7.json
index dab125d..ec89755 100644
--- a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-7.json
+++ b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-7.json
@@ -29,52 +29,108 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "RESUMED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "RESUMED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-8.json b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-8.json
index 67f9f6f..4086cbb 100644
--- a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-8.json
+++ b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-8.json
@@ -35,52 +35,108 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-9.json b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-9.json
index cd1973a..ef7e7ae 100644
--- a/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-9.json
+++ b/tests/framework/base/windowmanager/intent_tests/newDocumentCases/test-9.json
@@ -35,60 +35,124 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity2",
- "state": "RESUMED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "STOPPED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity2",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity2",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newTask/request_new_task_different_affinity-new_task.json b/tests/framework/base/windowmanager/intent_tests/newTask/request_new_task_different_affinity-new_task.json
index 99b4046..d741279 100644
--- a/tests/framework/base/windowmanager/intent_tests/newTask/request_new_task_different_affinity-new_task.json
+++ b/tests/framework/base/windowmanager/intent_tests/newTask/request_new_task_different_affinity-new_task.json
@@ -17,36 +17,63 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newTask/request_new_task_same_affinity-same_task.json b/tests/framework/base/windowmanager/intent_tests/newTask/request_new_task_same_affinity-same_task.json
index 3635017..14e8ea54 100644
--- a/tests/framework/base/windowmanager/intent_tests/newTask/request_new_task_same_affinity-same_task.json
+++ b/tests/framework/base/windowmanager/intent_tests/newTask/request_new_task_same_affinity-same_task.json
@@ -17,32 +17,38 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity2",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity2",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newTask/request_same_task_different_affinity-same_task.json b/tests/framework/base/windowmanager/intent_tests/newTask/request_same_task_different_affinity-same_task.json
index 52470c0..6cc45c0 100644
--- a/tests/framework/base/windowmanager/intent_tests/newTask/request_same_task_different_affinity-same_task.json
+++ b/tests/framework/base/windowmanager/intent_tests/newTask/request_same_task_different_affinity-same_task.json
@@ -17,32 +17,38 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newTask/single-task.json b/tests/framework/base/windowmanager/intent_tests/newTask/single-task.json
index 9c5a63f..d3d1f3b 100644
--- a/tests/framework/base/windowmanager/intent_tests/newTask/single-task.json
+++ b/tests/framework/base/windowmanager/intent_tests/newTask/single-task.json
@@ -17,36 +17,63 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity2",
- "state": "RESUMED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
-}
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity2",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity2",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newTask/test-1.json b/tests/framework/base/windowmanager/intent_tests/newTask/test-1.json
index c0c9af0..a3b4b26 100644
--- a/tests/framework/base/windowmanager/intent_tests/newTask/test-1.json
+++ b/tests/framework/base/windowmanager/intent_tests/newTask/test-1.json
@@ -17,36 +17,63 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
- "state": "RESUMED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newTask/test-10.json b/tests/framework/base/windowmanager/intent_tests/newTask/test-10.json
index 06e5363..afbafef 100644
--- a/tests/framework/base/windowmanager/intent_tests/newTask/test-10.json
+++ b/tests/framework/base/windowmanager/intent_tests/newTask/test-10.json
@@ -17,36 +17,63 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newTask/test-11.json b/tests/framework/base/windowmanager/intent_tests/newTask/test-11.json
index 6e93afb..76de611 100644
--- a/tests/framework/base/windowmanager/intent_tests/newTask/test-11.json
+++ b/tests/framework/base/windowmanager/intent_tests/newTask/test-11.json
@@ -17,28 +17,34 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newTask/test-12.json b/tests/framework/base/windowmanager/intent_tests/newTask/test-12.json
index 769a9b8..c378baf 100644
--- a/tests/framework/base/windowmanager/intent_tests/newTask/test-12.json
+++ b/tests/framework/base/windowmanager/intent_tests/newTask/test-12.json
@@ -17,28 +17,34 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newTask/test-13.json b/tests/framework/base/windowmanager/intent_tests/newTask/test-13.json
index 4f4f738..fa864f8 100644
--- a/tests/framework/base/windowmanager/intent_tests/newTask/test-13.json
+++ b/tests/framework/base/windowmanager/intent_tests/newTask/test-13.json
@@ -17,36 +17,63 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newTask/test-14.json b/tests/framework/base/windowmanager/intent_tests/newTask/test-14.json
index 4f3c581..992c18b 100644
--- a/tests/framework/base/windowmanager/intent_tests/newTask/test-14.json
+++ b/tests/framework/base/windowmanager/intent_tests/newTask/test-14.json
@@ -17,32 +17,38 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTaskActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newTask/test-15.json b/tests/framework/base/windowmanager/intent_tests/newTask/test-15.json
index b0f1b08..d6a9b74 100644
--- a/tests/framework/base/windowmanager/intent_tests/newTask/test-15.json
+++ b/tests/framework/base/windowmanager/intent_tests/newTask/test-15.json
@@ -17,32 +17,38 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newTask/test-16.json b/tests/framework/base/windowmanager/intent_tests/newTask/test-16.json
index d579057..18c65c0 100644
--- a/tests/framework/base/windowmanager/intent_tests/newTask/test-16.json
+++ b/tests/framework/base/windowmanager/intent_tests/newTask/test-16.json
@@ -23,44 +23,92 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
- "state": "RESUMED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newTask/test-2.json b/tests/framework/base/windowmanager/intent_tests/newTask/test-2.json
index 8441735..26633eb 100644
--- a/tests/framework/base/windowmanager/intent_tests/newTask/test-2.json
+++ b/tests/framework/base/windowmanager/intent_tests/newTask/test-2.json
@@ -17,36 +17,63 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
- "state": "RESUMED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstanceActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newTask/test-3.json b/tests/framework/base/windowmanager/intent_tests/newTask/test-3.json
index fe88fad..9ff5506 100644
--- a/tests/framework/base/windowmanager/intent_tests/newTask/test-3.json
+++ b/tests/framework/base/windowmanager/intent_tests/newTask/test-3.json
@@ -17,32 +17,38 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newTask/test-4.json b/tests/framework/base/windowmanager/intent_tests/newTask/test-4.json
index 6168dac..4c3e535 100644
--- a/tests/framework/base/windowmanager/intent_tests/newTask/test-4.json
+++ b/tests/framework/base/windowmanager/intent_tests/newTask/test-4.json
@@ -17,36 +17,63 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "RESUMED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newTask/test-5.json b/tests/framework/base/windowmanager/intent_tests/newTask/test-5.json
index 1769784..bc00f15 100644
--- a/tests/framework/base/windowmanager/intent_tests/newTask/test-5.json
+++ b/tests/framework/base/windowmanager/intent_tests/newTask/test-5.json
@@ -17,28 +17,34 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newTask/test-6.json b/tests/framework/base/windowmanager/intent_tests/newTask/test-6.json
index 94104ee..f6fefd8 100644
--- a/tests/framework/base/windowmanager/intent_tests/newTask/test-6.json
+++ b/tests/framework/base/windowmanager/intent_tests/newTask/test-6.json
@@ -17,32 +17,38 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTopActivity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTopActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newTask/test-7.json b/tests/framework/base/windowmanager/intent_tests/newTask/test-7.json
index 7209c12..ed47c78 100644
--- a/tests/framework/base/windowmanager/intent_tests/newTask/test-7.json
+++ b/tests/framework/base/windowmanager/intent_tests/newTask/test-7.json
@@ -29,52 +29,108 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "RESUMED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "RESUMED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newTask/test-8.json b/tests/framework/base/windowmanager/intent_tests/newTask/test-8.json
index 91f8229..7205552 100644
--- a/tests/framework/base/windowmanager/intent_tests/newTask/test-8.json
+++ b/tests/framework/base/windowmanager/intent_tests/newTask/test-8.json
@@ -35,52 +35,108 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newTask/test-9.json b/tests/framework/base/windowmanager/intent_tests/newTask/test-9.json
index a257933..8c3853b 100644
--- a/tests/framework/base/windowmanager/intent_tests/newTask/test-9.json
+++ b/tests/framework/base/windowmanager/intent_tests/newTask/test-9.json
@@ -35,56 +35,116 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity2",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "STOPPED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity2",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity2",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/newTask/test-multiple-task.json b/tests/framework/base/windowmanager/intent_tests/newTask/test-multiple-task.json
index 99b3c18..4c9701e 100644
--- a/tests/framework/base/windowmanager/intent_tests/newTask/test-multiple-task.json
+++ b/tests/framework/base/windowmanager/intent_tests/newTask/test-multiple-task.json
@@ -17,33 +17,38 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTopActivity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
-
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleTopActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/keep_affinity-request_new_task_with_same_affinity-same_task.json b/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/keep_affinity-request_new_task_with_same_affinity-same_task.json
index 924e7e2..4585963 100644
--- a/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/keep_affinity-request_new_task_with_same_affinity-same_task.json
+++ b/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/keep_affinity-request_new_task_with_same_affinity-same_task.json
@@ -23,40 +23,46 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1RelinquishTaskIdentityActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity2",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "STOPPED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1RelinquishTaskIdentityActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1RelinquishTaskIdentityActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity2",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1RelinquishTaskIdentityActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_change_affinity-request_new_task_with_changed_affinity-new_task.json b/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_change_affinity-request_new_task_with_changed_affinity-new_task.json
index 3b8ecb2..f81c02e 100644
--- a/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_change_affinity-request_new_task_with_changed_affinity-new_task.json
+++ b/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_change_affinity-request_new_task_with_changed_affinity-new_task.json
@@ -24,44 +24,75 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RelinquishTaskIdentityActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity2",
- "state": "RESUMED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "STOPPED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RelinquishTaskIdentityActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RelinquishTaskIdentityActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity2",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RelinquishTaskIdentityActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity2",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RelinquishTaskIdentityActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_change_affinity-request_new_task_with_old_affinity-same_task.json b/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_change_affinity-request_new_task_with_old_affinity-same_task.json
index f8ec310b..57f87cb 100644
--- a/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_change_affinity-request_new_task_with_old_affinity-same_task.json
+++ b/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_change_affinity-request_new_task_with_old_affinity-same_task.json
@@ -24,40 +24,46 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RelinquishTaskIdentityActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "STOPPED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RelinquishTaskIdentityActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RelinquishTaskIdentityActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RelinquishTaskIdentityActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_change_affinity-request_same_task_with_changed_affinity-same_task.json b/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_change_affinity-request_same_task_with_changed_affinity-same_task.json
index fe0c8b1..59fa11c 100644
--- a/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_change_affinity-request_same_task_with_changed_affinity-same_task.json
+++ b/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_change_affinity-request_same_task_with_changed_affinity-same_task.json
@@ -24,40 +24,46 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RelinquishTaskIdentityActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity2",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "STOPPED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RelinquishTaskIdentityActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RelinquishTaskIdentityActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity2",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RelinquishTaskIdentityActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_change_affinity-request_same_task_with_old_affinity-same_task.json b/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_change_affinity-request_same_task_with_old_affinity-same_task.json
index 0d6d344..c792b2a 100644
--- a/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_change_affinity-request_same_task_with_old_affinity-same_task.json
+++ b/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_change_affinity-request_same_task_with_old_affinity-same_task.json
@@ -24,40 +24,46 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RelinquishTaskIdentityActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "STOPPED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RelinquishTaskIdentityActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RelinquishTaskIdentityActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RelinquishTaskIdentityActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_new_task_with_different_affinity-new_task.json b/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_new_task_with_different_affinity-new_task.json
index e1905d9..c6fdb53 100644
--- a/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_new_task_with_different_affinity-new_task.json
+++ b/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_new_task_with_different_affinity-new_task.json
@@ -17,36 +17,63 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1RelinquishTaskIdentityActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1RelinquishTaskIdentityActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1RelinquishTaskIdentityActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1RelinquishTaskIdentityActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1RelinquishTaskIdentityActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_new_task_with_same_affinity-same_task.json b/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_new_task_with_same_affinity-same_task.json
index 78ac855..223564a 100644
--- a/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_new_task_with_same_affinity-same_task.json
+++ b/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_new_task_with_same_affinity-same_task.json
@@ -17,32 +17,38 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1RelinquishTaskIdentityActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1RelinquishTaskIdentityActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1RelinquishTaskIdentityActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1RelinquishTaskIdentityActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_same_task_with_different_affinity-same_task.json b/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_same_task_with_different_affinity-same_task.json
index ed2dfe2..8632049 100644
--- a/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_same_task_with_different_affinity-same_task.json
+++ b/tests/framework/base/windowmanager/intent_tests/relinquishTaskIdentity/request_same_task_with_different_affinity-same_task.json
@@ -17,32 +17,38 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1RelinquishTaskIdentityActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1RelinquishTaskIdentityActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1RelinquishTaskIdentityActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1RelinquishTaskIdentityActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/reorderToFront/reorder-to-front.json b/tests/framework/base/windowmanager/intent_tests/reorderToFront/reorder-to-front.json
index 5e3de96..a2e001d 100644
--- a/tests/framework/base/windowmanager/intent_tests/reorderToFront/reorder-to-front.json
+++ b/tests/framework/base/windowmanager/intent_tests/reorderToFront/reorder-to-front.json
@@ -35,52 +35,58 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity2Activity",
- "state": "STOPPED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "STOPPED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity2Activity",
- "state": "STOPPED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity2Activity",
+ "state": "STOPPED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity2Activity",
+ "state": "STOPPED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/reorderToFront/reorder-to-front_with_new-task_on_different_affinity.json b/tests/framework/base/windowmanager/intent_tests/reorderToFront/reorder-to-front_with_new-task_on_different_affinity.json
index c783577..375a4fd 100644
--- a/tests/framework/base/windowmanager/intent_tests/reorderToFront/reorder-to-front_with_new-task_on_different_affinity.json
+++ b/tests/framework/base/windowmanager/intent_tests/reorderToFront/reorder-to-front_with_new-task_on_different_affinity.json
@@ -30,52 +30,87 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity2Activity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "STOPPED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "RESUMED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity2Activity",
- "state": "STOPPED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "STOPPED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity2Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity2Activity",
+ "state": "STOPPED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity2Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/reset-task.json b/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/reset-task.json
index d306d86..afca4a8 100644
--- a/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/reset-task.json
+++ b/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/reset-task.json
@@ -17,32 +17,38 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$NoHistoryActivity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$NoHistoryActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/reset-task_reparent_affinity_in.json b/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/reset-task_reparent_affinity_in.json
index 691d002..1039d17 100644
--- a/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/reset-task_reparent_affinity_in.json
+++ b/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/reset-task_reparent_affinity_in.json
@@ -23,44 +23,75 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity2",
- "state": "INITIALIZING"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity2",
+ "state": "INITIALIZING"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity2",
+ "state": "INITIALIZING"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/reset-task_reparent_affinity_in_and_out.json b/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/reset-task_reparent_affinity_in_and_out.json
index a709c0d..45873f3 100644
--- a/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/reset-task_reparent_affinity_in_and_out.json
+++ b/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/reset-task_reparent_affinity_in_and_out.json
@@ -35,64 +35,132 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity2",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity2Activity",
- "state": "STOPPED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity2",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "STOPPED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity2Activity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity2",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity2Activity",
+ "state": "STOPPED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity2",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity2Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity2",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity2Activity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity2",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity2Activity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/reset-task_with_new-task.json b/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/reset-task_with_new-task.json
index 21ea454..97414ec 100644
--- a/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/reset-task_with_new-task.json
+++ b/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/reset-task_with_new-task.json
@@ -17,28 +17,34 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/reset-task_with_new-task_new_document.json b/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/reset-task_with_new-task_new_document.json
index a5d5e5e..3b022a4 100644
--- a/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/reset-task_with_new-task_new_document.json
+++ b/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/reset-task_with_new-task_new_document.json
@@ -17,36 +17,63 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$NoHistoryActivity",
- "state": "RESUMED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$NoHistoryActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$NoHistoryActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/test-1.json b/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/test-1.json
index 418ea7f..2dbf7e3 100644
--- a/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/test-1.json
+++ b/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/test-1.json
@@ -23,40 +23,46 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/test-2.json b/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/test-2.json
index 333cfbc..5c610f3 100644
--- a/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/test-2.json
+++ b/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/test-2.json
@@ -23,36 +23,42 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/test-3.json b/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/test-3.json
index ac7cbbe..02159de 100644
--- a/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/test-3.json
+++ b/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/test-3.json
@@ -29,56 +29,116 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "RESUMED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "STOPPED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "STOPPED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/test-4.json b/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/test-4.json
index 27f84bb..7374cb8 100644
--- a/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/test-4.json
+++ b/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/test-4.json
@@ -29,48 +29,54 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity2",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "STOPPED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity2",
- "state": "STOPPED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity2",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity2",
+ "state": "STOPPED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/test-5.json b/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/test-5.json
index bd7d2e6..8028527 100644
--- a/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/test-5.json
+++ b/tests/framework/base/windowmanager/intent_tests/resetTaskIfNeeded/test-5.json
@@ -29,48 +29,79 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1SingleTopActivity",
- "state": "STOPPED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1SingleTopActivity",
- "state": "RESUMED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1SingleTopActivity",
+ "state": "STOPPED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1SingleTopActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$TaskAffinity1SingleTopActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/singleInstancePerTask/test-1.json b/tests/framework/base/windowmanager/intent_tests/singleInstancePerTask/test-1.json
index 92481c9..dcfb188 100644
--- a/tests/framework/base/windowmanager/intent_tests/singleInstancePerTask/test-1.json
+++ b/tests/framework/base/windowmanager/intent_tests/singleInstancePerTask/test-1.json
@@ -18,36 +18,63 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskActivity",
- "state": "RESUMED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/singleInstancePerTask/test-10.json b/tests/framework/base/windowmanager/intent_tests/singleInstancePerTask/test-10.json
index 4d3da8d..b245978 100644
--- a/tests/framework/base/windowmanager/intent_tests/singleInstancePerTask/test-10.json
+++ b/tests/framework/base/windowmanager/intent_tests/singleInstancePerTask/test-10.json
@@ -18,28 +18,34 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskDocumentNeverActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskDocumentNeverActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskDocumentNeverActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskDocumentNeverActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/singleInstancePerTask/test-11.json b/tests/framework/base/windowmanager/intent_tests/singleInstancePerTask/test-11.json
index fe99a1b..b555e90 100644
--- a/tests/framework/base/windowmanager/intent_tests/singleInstancePerTask/test-11.json
+++ b/tests/framework/base/windowmanager/intent_tests/singleInstancePerTask/test-11.json
@@ -18,28 +18,34 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskDocumentNeverActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskDocumentNeverActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskDocumentNeverActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskDocumentNeverActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/singleInstancePerTask/test-12.json b/tests/framework/base/windowmanager/intent_tests/singleInstancePerTask/test-12.json
index 46616b3..be73c29 100644
--- a/tests/framework/base/windowmanager/intent_tests/singleInstancePerTask/test-12.json
+++ b/tests/framework/base/windowmanager/intent_tests/singleInstancePerTask/test-12.json
@@ -18,36 +18,63 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskDocumentNeverActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskDocumentNeverActivity",
- "state": "RESUMED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskDocumentNeverActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskDocumentNeverActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskDocumentNeverActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskDocumentNeverActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskDocumentNeverActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskDocumentNeverActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/singleInstancePerTask/test-2.json b/tests/framework/base/windowmanager/intent_tests/singleInstancePerTask/test-2.json
index bc6ae8f..acc2643 100644
--- a/tests/framework/base/windowmanager/intent_tests/singleInstancePerTask/test-2.json
+++ b/tests/framework/base/windowmanager/intent_tests/singleInstancePerTask/test-2.json
@@ -18,36 +18,63 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskActivity",
- "state": "RESUMED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/singleInstancePerTask/test-3.json b/tests/framework/base/windowmanager/intent_tests/singleInstancePerTask/test-3.json
index ddcc3a0..1f76224 100644
--- a/tests/framework/base/windowmanager/intent_tests/singleInstancePerTask/test-3.json
+++ b/tests/framework/base/windowmanager/intent_tests/singleInstancePerTask/test-3.json
@@ -24,44 +24,79 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskActivity",
- "state": "RESUMED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskActivity",
- "state": "STOPPED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskActivity",
+ "state": "STOPPED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/singleInstancePerTask/test-4.json b/tests/framework/base/windowmanager/intent_tests/singleInstancePerTask/test-4.json
index 9f273ff..75ce229 100644
--- a/tests/framework/base/windowmanager/intent_tests/singleInstancePerTask/test-4.json
+++ b/tests/framework/base/windowmanager/intent_tests/singleInstancePerTask/test-4.json
@@ -30,36 +30,63 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskActivity",
- "state": "RESUMED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/singleInstancePerTask/test-5.json b/tests/framework/base/windowmanager/intent_tests/singleInstancePerTask/test-5.json
index 766af41..c955074 100644
--- a/tests/framework/base/windowmanager/intent_tests/singleInstancePerTask/test-5.json
+++ b/tests/framework/base/windowmanager/intent_tests/singleInstancePerTask/test-5.json
@@ -30,44 +30,79 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskActivity",
- "state": "RESUMED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "STOPPED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/singleInstancePerTask/test-6.json b/tests/framework/base/windowmanager/intent_tests/singleInstancePerTask/test-6.json
index 93d6671..143f293 100644
--- a/tests/framework/base/windowmanager/intent_tests/singleInstancePerTask/test-6.json
+++ b/tests/framework/base/windowmanager/intent_tests/singleInstancePerTask/test-6.json
@@ -18,32 +18,38 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
- "state": "RESUMED"
- },
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/singleInstancePerTask/test-7.json b/tests/framework/base/windowmanager/intent_tests/singleInstancePerTask/test-7.json
index 324c39f..ea3a556 100644
--- a/tests/framework/base/windowmanager/intent_tests/singleInstancePerTask/test-7.json
+++ b/tests/framework/base/windowmanager/intent_tests/singleInstancePerTask/test-7.json
@@ -20,28 +20,34 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/singleInstancePerTask/test-8.json b/tests/framework/base/windowmanager/intent_tests/singleInstancePerTask/test-8.json
index 65718a2..2f80088 100644
--- a/tests/framework/base/windowmanager/intent_tests/singleInstancePerTask/test-8.json
+++ b/tests/framework/base/windowmanager/intent_tests/singleInstancePerTask/test-8.json
@@ -20,28 +20,34 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/intent_tests/singleInstancePerTask/test-9.json b/tests/framework/base/windowmanager/intent_tests/singleInstancePerTask/test-9.json
index fc49d3a..272b0d3 100644
--- a/tests/framework/base/windowmanager/intent_tests/singleInstancePerTask/test-9.json
+++ b/tests/framework/base/windowmanager/intent_tests/singleInstancePerTask/test-9.json
@@ -20,36 +20,63 @@
}
]
},
- "initialState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskActivity",
- "state": "RESUMED"
- }
- ]
- }
- ]
- },
- "endState": {
- "tasks": [
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskActivity",
- "state": "RESUMED"
- }
- ]
- },
- {
- "activities": [
- {
- "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskActivity",
- "state": "STOPPED"
- }
- ]
- }
- ]
- }
+ "initialStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ }
+ ],
+ "endStates": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_UNDEFINED"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.wm.cts/android.server.wm.intent.Activities$SingleInstancePerTaskActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "launchedWindowingMode": "WINDOWING_MODE_FREEFORM"
+ }
+ ]
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/embedding/ActivityEmbeddingPolicyTests.java b/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/embedding/ActivityEmbeddingPolicyTests.java
index 73fd17d..5450f34 100644
--- a/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/embedding/ActivityEmbeddingPolicyTests.java
+++ b/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/embedding/ActivityEmbeddingPolicyTests.java
@@ -28,7 +28,6 @@
import static android.server.wm.jetpack.utils.WindowManagerJetpackTestBase.EXTRA_EMBED_ACTIVITY;
import static android.server.wm.jetpack.utils.WindowManagerJetpackTestBase.startActivityFromActivity;
import static android.server.wm.jetpack.utils.WindowManagerJetpackTestBase.startActivityOnDisplaySingleTop;
-import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Surface.ROTATION_0;
import static android.view.Surface.ROTATION_90;
@@ -53,7 +52,6 @@
import android.server.wm.jetpack.utils.TestActivityKnownEmbeddingCerts;
import android.server.wm.jetpack.utils.TestActivityLauncher;
import android.server.wm.jetpack.utils.TestConfigChangeHandlingActivity;
-import android.view.Display;
import android.view.WindowManager;
import androidx.annotation.NonNull;
@@ -171,21 +169,21 @@
try {
// Start an activity that will attempt to embed TestActivityKnownEmbeddingCerts
- startActivityOnDisplaySingleTop(mContext, DEFAULT_DISPLAY, SIGNED_EMBEDDING_ACTIVITY,
+ startActivityOnDisplaySingleTop(mContext, getMainDisplayId(), SIGNED_EMBEDDING_ACTIVITY,
Bundle.EMPTY);
mWmState.waitForActivityState(SIGNED_EMBEDDING_ACTIVITY,
WindowManagerState.STATE_RESUMED);
- mWmState.waitForAppTransitionIdleOnDisplay(DEFAULT_DISPLAY);
+ mWmState.waitForAppTransitionIdleOnDisplay(getMainDisplayId());
Bundle embedExtra = new Bundle();
embedExtra.putBoolean(EXTRA_EMBED_ACTIVITY, true);
- startActivityOnDisplaySingleTop(mContext, DEFAULT_DISPLAY, SIGNED_EMBEDDING_ACTIVITY,
+ startActivityOnDisplaySingleTop(mContext, getMainDisplayId(), SIGNED_EMBEDDING_ACTIVITY,
embedExtra);
// Verify that the embedded activity drops input during animation
final ComponentName embeddedActivityComponent = new ComponentName(mContext,
TestActivityKnownEmbeddingCerts.class);
- mWmState.waitForAppTransitionRunningOnDisplay(DEFAULT_DISPLAY);
+ mWmState.waitForAppTransitionRunningOnDisplay(getMainDisplayId());
waitForOrFailWithRapidRetry(
"Embedded activity must drop all input for the duration of animation",
() -> {
@@ -195,7 +193,7 @@
});
// Verify that the embedded activity drops input if obscured after animation
- mWmState.waitForAppTransitionIdleOnDisplay(DEFAULT_DISPLAY);
+ mWmState.waitForAppTransitionIdleOnDisplay(getMainDisplayId());
assertEquals(
"Embedded activity must not drop input if obscured in trusted embedding",
0 /* DropInputMode.NONE */,
@@ -235,7 +233,7 @@
assumeTrue(getDisplayConfiguration().orientation == ORIENTATION_LANDSCAPE);
// Launch a fixed-portrait activity
- startActivityOnDisplay(Display.DEFAULT_DISPLAY, PORTRAIT_ACTIVITY);
+ startActivityOnDisplay(getMainDisplayId(), PORTRAIT_ACTIVITY);
// The display should be remained in landscape.
assertEquals("The display should be remained in landscape", ORIENTATION_LANDSCAPE,
@@ -244,7 +242,7 @@
private Configuration getDisplayConfiguration() {
mWmState.computeState();
- WindowManagerState.DisplayContent display = mWmState.getDisplay(DEFAULT_DISPLAY);
+ WindowManagerState.DisplayContent display = mWmState.getDisplay(getMainDisplayId());
return display.getFullConfiguration();
}
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 0aa9b93..bfd5b16 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
@@ -395,10 +395,9 @@
boolean shouldWaitForResume) {
final WindowManagerStateHelper wmState = new WindowManagerStateHelper();
final ComponentName activityName = activity.getComponentName();
+ wmState.waitForValidState(activityName);
if (shouldWaitForResume) {
wmState.waitAndAssertActivityState(activityName, STATE_RESUMED);
- } else {
- wmState.waitForValidState(activityName);
}
return wmState.getTaskByActivity(activityName).getBounds();
}
diff --git a/tests/framework/base/windowmanager/res/values/dimens.xml b/tests/framework/base/windowmanager/res/values/dimens.xml
index 44953ec1..bd11a84 100644
--- a/tests/framework/base/windowmanager/res/values/dimens.xml
+++ b/tests/framework/base/windowmanager/res/values/dimens.xml
@@ -18,4 +18,7 @@
<resources>
<dimen name="test_background_blur_radius">80px</dimen>
<dimen name="test_blur_behind_radius">40px</dimen>
+
+ <!-- TODO(b/389045836): remove this when rounded corners are reported correctly. -->
+ <dimen name="taskbar_corner_radius">16dp</dimen>
</resources>
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/activity/ActivityVisibilityTests.java b/tests/framework/base/windowmanager/src/android/server/wm/activity/ActivityVisibilityTests.java
index 4096288..110773e 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/activity/ActivityVisibilityTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/activity/ActivityVisibilityTests.java
@@ -468,11 +468,20 @@
launchTaskDisplayAreaFeatureId, DEFAULT_DISPLAY);
mWmState.waitForActivityState(BROADCAST_RECEIVER_ACTIVITY, STATE_RESUMED);
mWmState.waitForActivityState(MOVE_TASK_TO_BACK_ACTIVITY,STATE_STOPPED);
- final int topActivityTaskWindowingMode =
- mWmState.getTaskByActivity(BROADCAST_RECEIVER_ACTIVITY).getWindowingMode();
+ mWmState.computeState();
+ final Task topTask =
+ mWmState.getTaskByActivity(BROADCAST_RECEIVER_ACTIVITY);
+ final boolean topTaskCanAffectBottomTaskVisibility =
+ topTask.getWindowingMode() == WINDOWING_MODE_FULLSCREEN
+ ||
+ // Top task in multi window mode can still affect bottom's task visibility
+ // if it fillsParent
+ (topTask.getWindowingMode() == WINDOWING_MODE_MULTI_WINDOW
+ && topTask.isFullscreen());
+
final boolean topActivityOccludes =
- topActivityTaskWindowingMode == WINDOWING_MODE_FULLSCREEN &&
- !mWmState.isActivityTranslucent(BROADCAST_RECEIVER_ACTIVITY);
+ topTaskCanAffectBottomTaskVisibility
+ && !mWmState.isActivityTranslucent(BROADCAST_RECEIVER_ACTIVITY);
if (!topActivityOccludes) {
mWmState.assertVisibility(MOVE_TASK_TO_BACK_ACTIVITY, true);
} else {
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/activity/lifecycle/ActivityLifecycleTests.java b/tests/framework/base/windowmanager/src/android/server/wm/activity/lifecycle/ActivityLifecycleTests.java
index 72a3af7..4c4a46b 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/activity/lifecycle/ActivityLifecycleTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/activity/lifecycle/ActivityLifecycleTests.java
@@ -76,6 +76,7 @@
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeFalse;
import android.app.Activity;
import android.app.ActivityOptions;
@@ -188,6 +189,13 @@
.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK)
.setOptions(activityOptions)
.launch();
+
+ // Different form factors may force tasks to be non-overlapping multi-window mode
+ // (e.g. in freeform windowing mode) instead of fullscreen, which could
+ // result in translucentActivity remaining in RESUMED state.
+ // TODO(b/388831963): Add a test case to cover non-overlapping multi-window mode.
+ assumeFalse(isNonOverlappingMultiWindowMode(firstActivity));
+
waitAndAssertActivityStates(state(translucentActivity, ON_STOP));
final ComponentName firstActivityName = getComponentName(FirstActivity.class);
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/activity/lifecycle/ActivityTests.java b/tests/framework/base/windowmanager/src/android/server/wm/activity/lifecycle/ActivityTests.java
index 5168eae..8787ab1 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/activity/lifecycle/ActivityTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/activity/lifecycle/ActivityTests.java
@@ -252,14 +252,27 @@
final Activity differentAffinityActivity = new Launcher(DifferentAffinityActivity.class)
.setOptions(activityOptions)
.launch();
- waitAndAssertActivityStates(state(differentAffinityActivity, ON_RESUME),
- state(firstActivity, ON_STOP));
+
+ // Different form factors may force tasks to be non-overlapping multi-window mode
+ // (e.g. in freeform windowing mode) instead of fullscreen, which could
+ // have multiple activities in RESUMED state.
+ final boolean isInNonOverlappingMultiWindowMode =
+ isNonOverlappingMultiWindowMode(differentAffinityActivity);
+ if (isInNonOverlappingMultiWindowMode) {
+ waitAndAssertActivityStates(state(differentAffinityActivity, ON_RESUME),
+ state(firstActivity, ON_RESUME));
+ } else {
+ waitAndAssertActivityStates(state(differentAffinityActivity, ON_RESUME),
+ state(firstActivity, ON_STOP));
+ }
getTransitionLog().clear();
differentAffinityActivity.finishAffinity();
waitAndAssertActivityStates(state(DifferentAffinityActivity.class, ON_DESTROY));
- assertSequence(FirstActivity.class, getTransitionLog(),
- Arrays.asList(ON_RESTART, ON_START, ON_RESUME), "finishAffinity");
+ if (!isInNonOverlappingMultiWindowMode) {
+ assertSequence(FirstActivity.class, getTransitionLog(),
+ Arrays.asList(ON_RESTART, ON_START, ON_RESUME), "finishAffinity");
+ }
}
/**
@@ -278,12 +291,25 @@
.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK)
.setOptions(activityOptions)
.launch();
- waitAndAssertActivityStates(state(secondActivity, ON_RESUME),
- state(firstActivity, ON_STOP));
+
+ // Different form factors may force tasks to be non-overlapping multi-window mode
+ // (e.g. in freeform windowing mode) instead of fullscreen, which could
+ // have multiple activities in RESUMED state.
+ final boolean isInNonOverlappingMultiWindowMode =
+ isNonOverlappingMultiWindowMode(secondActivity);
+ if (isInNonOverlappingMultiWindowMode) {
+ waitAndAssertActivityStates(state(secondActivity, ON_RESUME),
+ state(firstActivity, ON_RESUME));
+ } else {
+ waitAndAssertActivityStates(state(secondActivity, ON_RESUME),
+ state(firstActivity, ON_STOP));
+ }
getTransitionLog().clear();
secondActivity.finishAffinity();
- waitAndAssertActivityStates(state(SecondActivity.class, ON_DESTROY),
- state(firstActivity, ON_RESUME));
+ waitAndAssertActivityStates(state(SecondActivity.class, ON_DESTROY));
+ if (!isInNonOverlappingMultiWindowMode) {
+ waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
+ }
}
}
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/animations/ActivityTransitionTests.java b/tests/framework/base/windowmanager/src/android/server/wm/animations/ActivityTransitionTests.java
index b989d98..02d9f830 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/animations/ActivityTransitionTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/animations/ActivityTransitionTests.java
@@ -806,17 +806,17 @@
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- getWindow().getAttributes().layoutInDisplayCutoutMode =
- LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
- // Ensure the activity is edge-to-edge
- // In tests we rely on the activity's content filling the entire window
- getWindow().setDecorFitsSystemWindows(false);
-
View view = new View(this);
view.setLayoutParams(new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
view.setOnApplyWindowInsetsListener((v, insets) -> mInsets = insets);
view.setBackgroundColor(Color.CYAN);
setContentView(view);
+
+ getWindow().getAttributes().layoutInDisplayCutoutMode =
+ LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+ // Ensure the activity is edge-to-edge
+ // In tests we rely on the activity's content filling the entire window
+ getWindow().setDecorFitsSystemWindows(false);
}
private Rect getActivityTestableRegion() {
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/animations/BlurTests.java b/tests/framework/base/windowmanager/src/android/server/wm/animations/BlurTests.java
index 0be275e..5620355 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/animations/BlurTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/animations/BlurTests.java
@@ -44,6 +44,7 @@
import android.server.wm.WindowManagerTestBase;
import android.server.wm.cts.R;
import android.server.wm.settings.SettingsSession;
+import android.util.TypedValue;
import android.view.RoundedCorner;
import android.view.View;
import android.view.WindowInsets;
@@ -480,9 +481,13 @@
return mInsetsToBeIgnored;
}
- private static int getCornerRadius(WindowInsets insets, int position) {
+ private int getCornerRadius(WindowInsets insets, int position) {
final RoundedCorner corner = insets.getRoundedCorner(position);
- return corner != null ? corner.getRadius() : 0;
+
+ // TODO (b/389045836): Make sure that Taskbar's "soft" rounded corners are reported
+ // in insets.getRoundedCorner so that this adjustment won't be necessary any more.
+ return Math.max((corner != null ? corner.getRadius() : 0),
+ getResources().getDimensionPixelSize(R.dimen.taskbar_corner_radius));
}
}
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/animations/KeepScreenOnTests.java b/tests/framework/base/windowmanager/src/android/server/wm/animations/KeepScreenOnTests.java
index 374cd76..9621f75 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/animations/KeepScreenOnTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/animations/KeepScreenOnTests.java
@@ -27,6 +27,7 @@
import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeTrue;
+import android.app.DreamManager;
import android.content.ContentResolver;
import android.content.Intent;
import android.content.pm.PackageManager;
@@ -40,6 +41,7 @@
import com.android.compatibility.common.util.ApiTest;
import com.android.compatibility.common.util.BlockingBroadcastReceiver;
+import com.android.compatibility.common.util.SystemUtil;
import org.junit.After;
import org.junit.Before;
@@ -52,6 +54,8 @@
private PowerManager mPowerManager;
private ContentResolver mContentResolver;
private boolean mIsTv;
+ private DreamManager mDreamManager;
+ private Boolean mDefaultScreensaverEnabled;
@Before
public void setUp() throws Exception {
@@ -66,11 +70,25 @@
mPowerManager = mContext.getSystemService(PowerManager.class);
assumeFalse("Automotive main display is always on - skipping test",
mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE));
+ mDreamManager = mContext.getSystemService(DreamManager.class);
+ if (mDreamManager != null && mDreamManager.areDreamsSupported()) {
+ SystemUtil.runWithShellPermissionIdentity(() -> {
+ mDefaultScreensaverEnabled = mDreamManager.isScreensaverEnabled();
+ if (mDefaultScreensaverEnabled) {
+ mDreamManager.setScreensaverEnabled(false);
+ }
+ });
+ }
}
@After
public void tearDown() {
setScreenOffTimeoutMs(mInitialDisplayTimeout);
+ if (Boolean.TRUE.equals(mDefaultScreensaverEnabled)) {
+ SystemUtil.runWithShellPermissionIdentity(() -> {
+ mDreamManager.setScreensaverEnabled(true);
+ });
+ }
Settings.Global.putInt(mContentResolver, STAY_ON_WHILE_PLUGGED_IN,
mInitialStayOnWhilePluggedInSetting);
UiDeviceUtils.wakeUpAndUnlock(mContext);
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/animations/SplashscreenTests.java b/tests/framework/base/windowmanager/src/android/server/wm/animations/SplashscreenTests.java
index 0c861fe..665dd98 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/animations/SplashscreenTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/animations/SplashscreenTests.java
@@ -208,15 +208,12 @@
// Activity may not be launched yet even if app transition is in idle state.
mWmState.waitForActivityState(name, STATE_RESUMED);
mWmState.waitForAppTransitionIdleOnDisplay(DEFAULT_DISPLAY);
-
- final Bitmap image = takeScreenshot();
- final WindowMetrics windowMetrics = mWm.getMaximumWindowMetrics();
- final Rect stableBounds = new Rect(windowMetrics.getBounds());
- stableBounds.inset(windowMetrics.getWindowInsets().getInsetsIgnoringVisibility(
- systemBars() & ~captionBar()));
+ final WindowManagerState.Task task = mWmState.getRootTaskByActivity(name);
+ final Rect taskBounds = task.getBounds();
+ final Bitmap[] image = new Bitmap[1];
+ runWithShellPermission(() -> image[0] = mWm.snapshotTaskForRecents(task.getTaskId()));
WindowManagerState.WindowState startingWindow = mWmState.findFirstWindowWithType(
WindowManager.LayoutParams.TYPE_APPLICATION_STARTING);
-
Rect startingWindowBounds = startingWindow.getBounds();
final Rect appBounds;
if (startingWindowBounds != null) {
@@ -224,24 +221,22 @@
} else {
appBounds = new Rect(startingWindow.getFrame());
}
-
insetGivenFrame(startingWindow,
- insetsSource -> (insetsSource.is(WindowInsets.Type.captionBar())), appBounds);
-
+ insetsSource -> (insetsSource.is(WindowInsets.Type.captionBar())), appBounds);
assertFalse("Couldn't find splash screen bounds. Impossible to assert the colors",
appBounds.isEmpty());
-
- // Use ratios to flexibly accommodate circular or not quite rectangular displays
- // Note: Color.BLACK is the pixel color outside of the display region
-
+ // Scale up because task snapshot may be captured with different scale ratio.
+ final Bitmap scaleImage = Bitmap.createScaledBitmap(image[0],
+ taskBounds.width(), taskBounds.height(), false /* filter */);
+ // Offset appBounds to align the image coordinate.
+ appBounds.offset(-taskBounds.left, -taskBounds.top);
int px = WindowManagerState.dpToPx(CENTER_ICON_SIZE,
mContext.getResources().getConfiguration().densityDpi);
Rect ignoreRect = new Rect(0, 0, px, px);
ignoreRect.offsetTo(appBounds.centerX() - ignoreRect.width() / 2,
appBounds.centerY() - ignoreRect.height() / 2);
-
- appBounds.intersect(stableBounds);
- assertColors(image, appBounds, primaryColor, 0.99f, secondaryColor, 0.02f, ignoreRect);
+ assertColors(scaleImage, appBounds, primaryColor, 0.99f, secondaryColor,
+ 0.02f, ignoreRect);
}
// For real devices, gamma correction might be applied on hardware driver, so the colors may
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/display/AppConfigurationTests.java b/tests/framework/base/windowmanager/src/android/server/wm/display/AppConfigurationTests.java
index 25e8957..2e35ed2 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/display/AppConfigurationTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/display/AppConfigurationTests.java
@@ -725,10 +725,10 @@
TestActivitySession<ConfigChangeHandlingActivity> activitySession
= createManagedTestActivitySession();
- int baseDisplayId = Display.DEFAULT_DISPLAY;
+ int baseDisplayId = getMainDisplayId();
activitySession.launchTestActivityOnDisplaySync(
ConfigChangeHandlingActivity.class,
- Display.DEFAULT_DISPLAY,
+ baseDisplayId,
WINDOWING_MODE_FULLSCREEN);
final ConfigChangeHandlingActivity activity = activitySession.getActivity();
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/display/DisplayHashManagerTest.java b/tests/framework/base/windowmanager/src/android/server/wm/display/DisplayHashManagerTest.java
index bd5a072..5a7587f 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/display/DisplayHashManagerTest.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/display/DisplayHashManagerTest.java
@@ -35,6 +35,7 @@
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
+import static org.junit.Assume.assumeFalse;
import android.app.Activity;
import android.app.Instrumentation;
@@ -49,6 +50,7 @@
import android.os.PowerManager;
import android.os.SystemClock;
import android.platform.test.annotations.Presubmit;
+import android.server.wm.ActivityManagerTestBase;
import android.server.wm.WindowManagerState;
import android.server.wm.WindowManagerStateHelper;
import android.service.displayhash.DisplayHashParams;
@@ -85,7 +87,7 @@
import java.util.concurrent.TimeUnit;
@Presubmit
-public class DisplayHashManagerTest {
+public class DisplayHashManagerTest extends ActivityManagerTestBase {
private static final int WAIT_TIME_S = 5;
private static final int TIMEOUT_MS = 1000;
private static final int SLEEP_TIMEOUT_MS = 200;
@@ -176,7 +178,14 @@
assertEquals(mTestViewSize.x, verifiedDisplayHash.getBoundsInWindow().width());
assertEquals(mTestViewSize.y, verifiedDisplayHash.getBoundsInWindow().height());
- assertArrayEquals(expectedImageHash, verifiedDisplayHash.getImageHash());
+ assertNotNull(verifiedDisplayHash.getImageHash());
+ // TODO(b/349391086): For form factors that launch activities in non-overlapping
+ // multi-window mode mode, the image hash may not be what is expected as other parts of the
+ // display may be included in the image screenshot used. Skip this check in that case. This
+ // should be replaced with a check of the image hash that can also account for the display.
+ if (!isNonOverlappingMultiWindowMode(mActivity)) {
+ assertArrayEquals(expectedImageHash, verifiedDisplayHash.getImageHash());
+ }
}
@Test
@@ -264,6 +273,11 @@
@Test
public void testGenerateDisplayHash_WindowOffscreen() throws InterruptedException {
+ // TODO(b/349391086): For form factors that launch activities in non-overlapping
+ // multi-window mode, a valid display hash may be produced since windows may not be
+ // completely "offscreen". Skip this test case for now and consider adding a branch that
+ // that has a better heuristic for if windows can be "offscreen" before proceeding.
+ assumeFalse(isNonOverlappingMultiWindowMode(mActivity));
final WindowManager wm = mActivity.getWindowManager();
final WindowManager.LayoutParams windowParams = new WindowManager.LayoutParams();
@@ -446,20 +460,13 @@
assertEquals(mTestViewSize.x, verifiedDisplayHash.getBoundsInWindow().width());
assertEquals(mTestViewSize.y, verifiedDisplayHash.getBoundsInWindow().height());
- assertArrayEquals(expectedImageHash, verifiedDisplayHash.getImageHash());
- }
-
- private void waitForActivityResumed(int timeoutMs, ComponentName componentName) {
- long endTime = System.currentTimeMillis() + timeoutMs;
- while (endTime > System.currentTimeMillis()) {
- mWmState.computeState();
- if (mWmState.hasActivityState(componentName, STATE_RESUMED)) {
- SystemClock.sleep(SLEEP_TIMEOUT_MS);
- mWmState.computeState();
- break;
- }
- SystemClock.sleep(SLEEP_TIMEOUT_MS);
- mWmState.computeState();
+ assertNotNull(verifiedDisplayHash.getImageHash());
+ // TODO(b/349391086): For form factors that launch activities in non-overlapping
+ // multi-window mode mode, the image hash may not be what is expected as other parts of the
+ // display may be included in the image screenshot used. Skip this check in that case. This
+ // should be replaced with a check of the image hash that can also account for the display.
+ if (!isNonOverlappingMultiWindowMode(mActivity)) {
+ assertArrayEquals(expectedImageHash, verifiedDisplayHash.getImageHash());
}
}
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/display/PresentationTest.java b/tests/framework/base/windowmanager/src/android/server/wm/display/PresentationTest.java
index ba375a0..08b7070 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/display/PresentationTest.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/display/PresentationTest.java
@@ -140,7 +140,7 @@
mContext.startActivity(intent);
waitAndAssertTopResumedActivity(
Components.PRESENTATION_ACTIVITY,
- Display.DEFAULT_DISPLAY,
+ getMainDisplayId(),
"Launched activity must be on top");
}
}
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/input/WindowInputTests.java b/tests/framework/base/windowmanager/src/android/server/wm/input/WindowInputTests.java
index b1c24de..4ddec09 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/input/WindowInputTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/input/WindowInputTests.java
@@ -71,6 +71,7 @@
import com.android.compatibility.common.util.CtsTouchUtils;
import com.android.compatibility.common.util.SystemUtil;
+import com.android.compatibility.common.util.UserHelper;
import org.junit.Before;
import org.junit.Test;
@@ -116,12 +117,17 @@
private int mClickCount = 0;
private static final long EVENT_FLAGS_WAIT_TIME = 10L * HW_TIMEOUT_MULTIPLIER;
+ private final UserHelper mUserHelper = new UserHelper(getInstrumentation().getContext());
@Before
public void setUp() throws InterruptedException {
pressWakeupButton();
pressUnlockButton();
launchHomeActivityNoWait();
+ final WindowManagerStateHelper wmState = new WindowManagerStateHelper();
+ // Wait for app transition idle on display to avoid having Home and further activities
+ // launch in the same transition
+ wmState.waitForAppTransitionIdleOnDisplay(mUserHelper.getMainDisplayId());
mInstrumentation = getInstrumentation();
mCtsTouchUtils = new CtsTouchUtils(mInstrumentation.getTargetContext());
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/insets/WindowInsetsAnimationTests.java b/tests/framework/base/windowmanager/src/android/server/wm/insets/WindowInsetsAnimationTests.java
index 9b29935..29e8889 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/insets/WindowInsetsAnimationTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/insets/WindowInsetsAnimationTests.java
@@ -68,11 +68,11 @@
@Before
public void setup() throws Exception {
super.setUp();
+ assumeFalse(isCar() && remoteInsetsControllerControlsSystemBars());
mActivity =
startActivity(TestActivity.class, DEFAULT_DISPLAY, true, WINDOWING_MODE_FULLSCREEN);
mRootView = mActivity.getWindow().getDecorView();
assumeTrue(hasWindowInsets(mRootView, systemBars()));
- assumeFalse(isCar() && remoteInsetsControllerControlsSystemBars());
}
@Test
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/intent/LaunchRunner.java b/tests/framework/base/windowmanager/src/android/server/wm/intent/LaunchRunner.java
index 205c8b8..11c5827 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/intent/LaunchRunner.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/intent/LaunchRunner.java
@@ -48,6 +48,7 @@
import com.google.common.collect.Lists;
+import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
@@ -117,8 +118,13 @@
FEATURE_UNDEFINED, launchDisplayId);
// Launch all tasks in the same task display area. CTS tests using multiple tasks assume
// they will be started in the same task display area.
+ ComponentName firstActivityName = firstActivity.getComponentName();
int firstActivityDisplayAreaFeatureId = mTestBase.getWmState()
- .getTaskDisplayAreaFeatureId(firstActivity.getComponentName());
+ .getTaskDisplayAreaFeatureId(firstActivityName);
+ int launchedWindowingMode =
+ mTestBase.getWmState().getTaskByActivity(firstActivityName).getWindowingMode();
+ Persistence.ReadableWindowingMode readableLaunchedWindowingMode =
+ Persistence.ReadableWindowingMode.covert(launchedWindowingMode);
activityLog.add(firstActivity);
// launch the rest from the initial intents
@@ -132,9 +138,12 @@
}
// assert that the state after setup is the same this time as the recorded state.
- StateDump setupStateDump = waitDumpAndTrimForVerification(getLast(activityLog),
- testCase.getInitialState());
- assertInitialStateEqual(testCase.getInitialState(), setupStateDump);
+ StateDump expectedInitialStateDump =
+ testCase.getInitialStateWithLaunchedWindowingModeOrDefault(
+ readableLaunchedWindowingMode.getName());
+ StateDump setupStateDump =
+ waitDumpAndTrimForVerification(getLast(activityLog), expectedInitialStateDump);
+ assertInitialStateEqual(expectedInitialStateDump, setupStateDump);
// apply all the intents in the act stage
for (int i = 0; i < act.size(); i++) {
@@ -148,9 +157,12 @@
}
// assert that the endStates are the same.
- StateDump endStateDump = waitDumpAndTrimForVerification(getLast(activityLog),
- testCase.getEndState());
- assertEndStatesEqual(testCase.getEndState(), endStateDump);
+ StateDump expectedEndStateDump =
+ testCase.getEndStateWithLaunchedWindowingModeOrDefault(
+ readableLaunchedWindowingMode.getName());
+ StateDump endStateDump =
+ waitDumpAndTrimForVerification(getLast(activityLog), expectedEndStateDump);
+ assertEndStatesEqual(expectedEndStateDump, endStateDump);
}
/**
@@ -184,7 +196,10 @@
Persistence.Setup setup = new Persistence.Setup(setupIntents, actIntents);
- return new Persistence.TestCase(setup, launchRecord.initialDump, launchRecord.endDump,
+ return new Persistence.TestCase(
+ setup,
+ Collections.singletonList(launchRecord.initialDump),
+ Collections.singletonList(launchRecord.endDump),
name);
}
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/intent/Persistence.java b/tests/framework/base/windowmanager/src/android/server/wm/intent/Persistence.java
index 47e1ac4..9b3a52c 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/intent/Persistence.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/intent/Persistence.java
@@ -16,6 +16,12 @@
package android.server.wm.intent;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+
import static java.util.stream.Collectors.toList;
import android.content.ComponentName;
@@ -52,8 +58,8 @@
*/
public static class TestCase {
private static final String SETUP_KEY = "setup";
- private static final String INITIAL_STATE_KEY = "initialState";
- private static final String END_STATE_KEY = "endState";
+ private static final String INITIAL_STATES_KEY = "initialStates";
+ private static final String END_STATES_KEY = "endStates";
/**
* Contains the {@link android.content.Intent}-s that will be launched in this test case.
@@ -61,14 +67,16 @@
private final Setup mSetup;
/**
- * The state of the system after the {@link Setup#mInitialIntents} have been launched.
+ * The possible states of the system after the {@link Setup#mInitialIntents} have been
+ * launched. These are organized by launched windowing mode.
*/
- private final StateDump mInitialState;
+ private final List<StateDump> mInitialStates;
/**
- * The state of the system after the {@link Setup#mAct} have been launched
+ * The possible states of the system after the {@link Setup#mAct} have been launched. These
+ * are organized by launched windowing mode.
*/
- private final StateDump mEndState;
+ private final List<StateDump> mEndStates;
/**
* The name of the testCase, usually the file name it is stored in.
@@ -76,42 +84,98 @@
*/
private final String mName;
- public TestCase(Setup setup, StateDump initialState,
- StateDump endState, String name) {
+ public TestCase(Setup setup, List<StateDump> initialStates,
+ List<StateDump> endStates, String name) {
mSetup = setup;
- mInitialState = initialState;
- mEndState = endState;
+ mInitialStates = initialStates;
+ mEndStates = endStates;
mName = name;
}
public JSONObject toJson() throws JSONException {
return new JSONObject()
.put(SETUP_KEY, mSetup.toJson())
- .put(INITIAL_STATE_KEY, mInitialState.toJson())
- .put(END_STATE_KEY, mEndState.toJson());
+ .put(INITIAL_STATES_KEY, stateDumpsToJson(mInitialStates))
+ .put(END_STATES_KEY, stateDumpsToJson(mEndStates));
}
public static TestCase fromJson(JSONObject object,
Map<String, IntentFlag> table, String name) throws JSONException {
return new TestCase(Setup.fromJson(object.getJSONObject(SETUP_KEY), table),
- StateDump.fromJson(object.getJSONObject(INITIAL_STATE_KEY)),
- StateDump.fromJson(object.getJSONObject(END_STATE_KEY)), name);
+ stateDumpsFromJson(object.getJSONArray(INITIAL_STATES_KEY)),
+ stateDumpsFromJson(object.getJSONArray(END_STATES_KEY)), name);
+ }
+
+ public static JSONArray stateDumpsToJson(List<StateDump> stateDumps)
+ throws JSONException {
+ JSONArray stateDumpArray = new JSONArray();
+ for (StateDump stateDump : stateDumps) {
+ stateDumpArray.put(stateDump.toJson());
+ }
+ return stateDumpArray;
+ }
+
+ public static List<StateDump> stateDumpsFromJson(
+ JSONArray stateDumpsArray) throws JSONException {
+ List<StateDump> stateDumps = new ArrayList<>();
+ for (int i = 0; i < stateDumpsArray.length(); i++) {
+ JSONObject object = (JSONObject) stateDumpsArray.get(i);
+ StateDump stateDump = StateDump.fromJson(object);
+ stateDumps.add(stateDump);
+ }
+ return stateDumps;
}
public Setup getSetup() {
return mSetup;
}
- public StateDump getInitialState() {
- return mInitialState;
+ /**
+ * Returns the initial state with the matching launched windowing mode. If no matching
+ * launched windowing mode is found, use the default initial state.
+ */
+ public StateDump getInitialStateWithLaunchedWindowingModeOrDefault(
+ String launchedWindowingMode) {
+ StateDump defaultInitialState = null;
+ for (StateDump initialState : mInitialStates) {
+ if (Objects.equals(initialState.mLaunchedWindowingMode, launchedWindowingMode)) {
+ return initialState;
+ } else if (Objects.equals(initialState.mLaunchedWindowingMode,
+ StateDump.DEFAULT_LAUNCHED_WINDOWING_MODE)) {
+ defaultInitialState = initialState;
+ }
+ }
+ if (defaultInitialState == null) {
+ throw new RuntimeException(
+ "No initial state with default launched windowing mode found");
+ }
+ return defaultInitialState;
}
public String getName() {
return mName;
}
- public StateDump getEndState() {
- return mEndState;
+ /**
+ * Returns the end state with the matching launched windowing mode. If no matching
+ * launched windowing mode is found, use the default end state.
+ */
+ public StateDump getEndStateWithLaunchedWindowingModeOrDefault(
+ String launchedWindowingMode) {
+ StateDump defaultEndState = null;
+ for (StateDump endState : mEndStates) {
+ if (Objects.equals(endState.mLaunchedWindowingMode, launchedWindowingMode)) {
+ return endState;
+ } else if (Objects.equals(endState.mLaunchedWindowingMode,
+ StateDump.DEFAULT_LAUNCHED_WINDOWING_MODE)) {
+ defaultEndState = endState;
+ }
+ }
+ if (defaultEndState == null) {
+ throw new RuntimeException(
+ "No end state with default launched windowing mode found");
+ }
+ return defaultEndState;
}
}
@@ -159,7 +223,6 @@
return new Setup(initialState, act);
}
-
public static JSONArray intentsToJson(List<GenerationIntent> intents)
throws JSONException {
@@ -445,25 +508,87 @@
return new IntentFlag(flag, name);
}
+ /**
+ * A windowing mode class that also stores the name of the windowing mode.
+ * It is used to be able to put the modes in human readable form in the JSON file.
+ */
+ public static class ReadableWindowingMode {
+ /**
+ * The underlying mode, should be a value from WindowConfiguration.WINDOWING_MODE_*.
+ */
+ public final int windowingMode;
+
+ /**
+ * The name of the windowing mode.
+ */
+ public final String name;
+
+ public ReadableWindowingMode(int windowingMode, String name) {
+ this.windowingMode = windowingMode;
+ this.name = name;
+ }
+
+ public int getWindowingMode() {
+ return windowingMode;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String toString() {
+ return name;
+ }
+
+ static ReadableWindowingMode covert(int windowingMode) {
+ return switch (windowingMode) {
+ case WINDOWING_MODE_FULLSCREEN -> new ReadableWindowingMode(windowingMode,
+ "WINDOWING_MODE_FULLSCREEN");
+ case WINDOWING_MODE_PINNED -> new ReadableWindowingMode(windowingMode,
+ "WINDOWING_MODE_PINNED");
+ case WINDOWING_MODE_FREEFORM -> new ReadableWindowingMode(windowingMode,
+ "WINDOWING_MODE_FREEFORM");
+ case WINDOWING_MODE_MULTI_WINDOW -> new ReadableWindowingMode(windowingMode,
+ "WINDOWING_MODE_MULTI_WINDOW");
+ default -> new ReadableWindowingMode(windowingMode,
+ StateDump.DEFAULT_LAUNCHED_WINDOWING_MODE);
+ };
+ }
+ }
+
public static class StateDump {
private static final String TASKS_KEY = "tasks";
+ private static final String LAUNCHED_WINDOWING_MODE_KEY = "launchedWindowingMode";
+ private static final String DEFAULT_LAUNCHED_WINDOWING_MODE = "WINDOWING_MODE_UNDEFINED";
/**
* The Tasks in this stack ordered from most recent to least recent.
*/
private final List<TaskState> mTasks;
+ /**
+ * The windowing mode of which tasks in this stack are launched in.
+ */
+ private final String mLaunchedWindowingMode;
+
public static StateDump fromTasks(List<WindowManagerState.Task> activityTasks,
List<WindowManagerState.Task> baseStacks) {
List<TaskState> tasks = new ArrayList<>();
+ int launchedWindowingMode = WINDOWING_MODE_UNDEFINED;
for (WindowManagerState.Task task : trimTasks(activityTasks, baseStacks)) {
tasks.add(new TaskState(task));
+ if (launchedWindowingMode != task.getWindowingMode()) {
+ launchedWindowingMode = task.getWindowingMode();
+ }
}
- return new StateDump(tasks);
+ Persistence.ReadableWindowingMode readableLaunchedWindowingMode =
+ Persistence.ReadableWindowingMode.covert(launchedWindowingMode);
+ return new StateDump(tasks, readableLaunchedWindowingMode.getName());
}
- private StateDump(List<TaskState> tasks) {
+ private StateDump(List<TaskState> tasks, String launchedWindowingMode) {
mTasks = tasks;
+ mLaunchedWindowingMode = launchedWindowingMode;
}
JSONObject toJson() throws JSONException {
@@ -472,7 +597,9 @@
tasks.put(task.toJson());
}
- return new JSONObject().put(TASKS_KEY, tasks);
+ return new JSONObject()
+ .put(TASKS_KEY, tasks)
+ .put(LAUNCHED_WINDOWING_MODE_KEY, mLaunchedWindowingMode);
}
static StateDump fromJson(JSONObject object) throws JSONException {
@@ -483,7 +610,7 @@
tasks.add(TaskState.fromJson((JSONObject) jsonTasks.get(i)));
}
- return new StateDump(tasks);
+ return new StateDump(tasks, object.getString(LAUNCHED_WINDOWING_MODE_KEY));
}
/**
@@ -496,7 +623,7 @@
List<WindowManagerState.Task> trimFrom) {
for (WindowManagerState.Task task : trimFrom) {
- toTrim.removeIf(t -> t.getRootTaskId() == task.getRootTaskId());
+ toTrim.removeIf(t -> t.getTaskId() == task.getTaskId());
}
return toTrim;
@@ -507,12 +634,19 @@
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
StateDump stateDump = (StateDump) o;
- return Objects.equals(mTasks, stateDump.mTasks);
+ final boolean defaultLaunchedWindowingModeUsed =
+ Objects.equals(mLaunchedWindowingMode, DEFAULT_LAUNCHED_WINDOWING_MODE)
+ || Objects.equals(stateDump.mLaunchedWindowingMode,
+ DEFAULT_LAUNCHED_WINDOWING_MODE);
+ final boolean launchedWindowingModeEqualOrDefault =
+ Objects.equals(mLaunchedWindowingMode, stateDump.mLaunchedWindowingMode)
+ || defaultLaunchedWindowingModeUsed;
+ return Objects.equals(mTasks, stateDump.mTasks) && launchedWindowingModeEqualOrDefault;
}
@Override
public int hashCode() {
- return Objects.hash(mTasks);
+ return Objects.hash(mTasks, mLaunchedWindowingMode);
}
}
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/window/WindowMetricsActivityTests.java b/tests/framework/base/windowmanager/src/android/server/wm/window/WindowMetricsActivityTests.java
index 9cc7649..2767542 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/window/WindowMetricsActivityTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/window/WindowMetricsActivityTests.java
@@ -76,7 +76,9 @@
activity.getOnCreateCurrentMetrics(),
activity.getOnCreateMaximumMetrics(),
listener.getLayoutBounds(),
- listener.getLayoutInsets());
+ listener.getLayoutInsets(),
+ activity.isInMultiWindowMode()
+ );
}
@Test
diff --git a/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerStateHelper.java b/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerStateHelper.java
index 2522334..ddd9d27 100644
--- a/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerStateHelper.java
+++ b/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerStateHelper.java
@@ -485,8 +485,15 @@
computeState();
return getFocusedApp();
}).setResultValidator(focusedAppName -> {
- return focusedAppName != null && appPackageName.equals(
- ComponentName.unflattenFromString(focusedAppName).getPackageName());
+ if (focusedAppName == null) {
+ return false;
+ }
+ ComponentName unflattenedName = ComponentName.unflattenFromString(focusedAppName);
+ if (unflattenedName == null) {
+ logAlways("unflattenedName is null; focusedAppName=" + focusedAppName);
+ return false;
+ }
+ return appPackageName.equals(unflattenedName.getPackageName());
}).setOnFailure(focusedAppName -> {
fail("Timed out waiting for focus on app "
+ appPackageName + ", last was " + focusedAppName);
diff --git a/tests/input/AndroidTest.xml b/tests/input/AndroidTest.xml
index 4628086..dfb93cf 100644
--- a/tests/input/AndroidTest.xml
+++ b/tests/input/AndroidTest.xml
@@ -57,7 +57,7 @@
<option name="pull-pattern-keys"
value="android.device.collectors.ScreenshotOnFailureCollector.*\.png" />
<!-- Pull files created by tests, like the output of screenshot tests -->
- <option name="directory-keys" value="/storage/emulated/0/CtsInputTestCases" />
+ <option name="directory-keys" value="/sdcard/Download/CtsInputTestCases" />
<option name="collect-on-run-ended-only" value="false" />
</metrics_collector>
</configuration>
diff --git a/tests/input/src/android/input/cts/ModifierKeyRemappingTest.kt b/tests/input/src/android/input/cts/ModifierKeyRemappingTest.kt
index b70bbb8..31fba80 100644
--- a/tests/input/src/android/input/cts/ModifierKeyRemappingTest.kt
+++ b/tests/input/src/android/input/cts/ModifierKeyRemappingTest.kt
@@ -17,6 +17,7 @@
package android.input.cts
import android.Manifest
+import android.cts.input.EventVerifier
import android.hardware.input.InputManager
import android.provider.Settings
import android.view.KeyEvent
@@ -28,8 +29,11 @@
import com.android.compatibility.common.util.SystemUtil
import com.android.compatibility.common.util.ThrowingSupplier
import com.android.cts.input.UinputKeyboard
-import org.junit.Assert.assertEquals
-import org.junit.Assert.assertNotNull
+import com.android.cts.input.inputeventmatchers.withKeyAction
+import com.android.cts.input.inputeventmatchers.withKeyCode
+import com.android.cts.input.inputeventmatchers.withModifierState
+import org.hamcrest.Matchers.allOf
+import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
@@ -44,17 +48,8 @@
class ModifierKeyRemappingTest {
companion object {
- val REMAPPABLE_MODIFIER_KEYCODES = intArrayOf(
- KeyEvent.KEYCODE_CTRL_LEFT, KeyEvent.KEYCODE_CTRL_RIGHT, KeyEvent.KEYCODE_META_LEFT,
- KeyEvent.KEYCODE_META_RIGHT, KeyEvent.KEYCODE_ALT_LEFT, KeyEvent.KEYCODE_ALT_RIGHT,
- KeyEvent.KEYCODE_SHIFT_LEFT, KeyEvent.KEYCODE_SHIFT_RIGHT, KeyEvent.KEYCODE_CAPS_LOCK
- )
-
// Linux keycode defined in the "linux/input-event-codes.h" header.
val KEY_LEFTALT = 56
-
- // Wait time for existing remapping to happen after device added
- val MODIFIER_REMAPPING_WAIT_TIME_MILLIS = 500L
}
private val instrumentation = InstrumentationRegistry.getInstrumentation()
@@ -63,163 +58,128 @@
val rule = ActivityScenarioRule<CaptureEventActivity>(CaptureEventActivity::class.java)
private lateinit var activity: CaptureEventActivity
+ private lateinit var verifier: EventVerifier
private lateinit var inputManager: InputManager
+ private lateinit var existingRemappings: Map<Int, Int>
@Before
fun setUp() {
rule.getScenario().onActivity {
inputManager = it.getSystemService(InputManager::class.java)
activity = it
+ verifier = EventVerifier(activity::getInputEvent)
}
PollingCheck.waitFor { activity.hasWindowFocus() }
- // Clear any existing remappings
+ // Save existing remappings
+ existingRemappings = getModifierKeyRemapping()
clearAllModifierKeyRemappings()
- // Wait for handler to execute and clear all remappings
- PollingCheck.waitFor { getModifierKeyRemapping().isEmpty() }
}
- private fun assertReceivedEventsCorrectlyMapped(numEvents: Int, expectedKeyCode: Int) {
- for (i in 1..numEvents) {
- val lastInputEvent: KeyEvent = activity.getInputEvent() as KeyEvent
- assertNotNull("Event number $i is null!", lastInputEvent)
- assertEquals(
- "Key code should be " + KeyEvent.keyCodeToString(expectedKeyCode),
- expectedKeyCode,
- lastInputEvent.keyCode
- )
- }
- activity.assertNoEvents()
- }
-
- /**
- * Test modifier key remapping APIs
- */
- @Test
- fun testModifierKeyRemapping() {
- ModifierRemappingFlag(true).use {
- val keyboardDevice = UinputKeyboard(instrumentation)
-
- // Wait for device to be added
- PollingCheck.waitFor { inputManager.getInputDevice(keyboardDevice.deviceId) != null }
- val inputDevice = inputManager.getInputDevice(keyboardDevice.deviceId)
-
- val numKeys = REMAPPABLE_MODIFIER_KEYCODES.size
-
- // Remap modifier keys in cyclic manner
- for (i in 0 until numKeys) {
- remapModifierKey(
- REMAPPABLE_MODIFIER_KEYCODES[i],
- REMAPPABLE_MODIFIER_KEYCODES[(i + 1) % numKeys]
- )
- }
-
- // Wait for handler to execute and add remappings
- PollingCheck.waitFor { getModifierKeyRemapping().size == numKeys }
- val remapping: Map<Int, Int> = getModifierKeyRemapping()
- for (i in 0 until numKeys) {
- val fromKeyCode = REMAPPABLE_MODIFIER_KEYCODES[i]
- val toKeyCode = REMAPPABLE_MODIFIER_KEYCODES[(i + 1) % numKeys]
- val actualToKeyCode = remapping[fromKeyCode]!!
- assertEquals(
- "Modifier key remapping should map " + KeyEvent.keyCodeToString(fromKeyCode) +
- " to " + KeyEvent.keyCodeToString(toKeyCode) + " but was " +
- KeyEvent.keyCodeToString(actualToKeyCode),
- toKeyCode,
- actualToKeyCode
- )
- assertEquals(
- "Key location" + KeyEvent.keyCodeToString(fromKeyCode) + " should map to " +
- KeyEvent.keyCodeToString(toKeyCode) + " after remapping.",
- toKeyCode,
- inputDevice?.getKeyCodeForKeyLocation(fromKeyCode)
- )
- }
-
+ @After
+ fun tearDown() {
+ if (this::existingRemappings.isInitialized) {
clearAllModifierKeyRemappings()
-
- // Wait for handler to execute and clear all remappings
- PollingCheck.waitFor { getModifierKeyRemapping().isEmpty() }
-
- for (i in 0 until numKeys) {
- val keyCode = REMAPPABLE_MODIFIER_KEYCODES[i]
- assertEquals(
- "Key location" + KeyEvent.keyCodeToString(keyCode) + " should map to " +
- KeyEvent.keyCodeToString(keyCode) + " after remapping.",
- keyCode,
- inputDevice?.getKeyCodeForKeyLocation(keyCode)
- )
+ existingRemappings.forEach { entry ->
+ remapModifierKey(entry.key, entry.value)
}
-
- // Remove the device
- keyboardDevice.close()
}
}
@Test
- fun testHardwareKeyEventsWithRemapping_AfterKeyboardAdded() {
+ fun testHardwareKeyEventsWithRemapping_afterKeyboardAdded() {
ModifierRemappingFlag(true).use {
- val keyboardDevice = UinputKeyboard(instrumentation)
+ UinputKeyboard(instrumentation).use { keyboardDevice ->
+ val inputDevice = inputManager.getInputDevice(keyboardDevice.deviceId)
- // Wait for device to be added
- PollingCheck.waitFor { inputManager.getInputDevice(keyboardDevice.deviceId) != null }
+ // Add remapping after device is already added
+ remapModifierKey(KeyEvent.KEYCODE_ALT_LEFT, KeyEvent.KEYCODE_SHIFT_LEFT)
+ PollingCheck.waitFor {
+ KeyEvent.KEYCODE_SHIFT_LEFT ==
+ inputDevice?.getKeyCodeForKeyLocation(KeyEvent.KEYCODE_ALT_LEFT)
+ }
- remapModifierKey(KeyEvent.KEYCODE_ALT_LEFT, KeyEvent.KEYCODE_SHIFT_LEFT)
- // Wait for handler to execute and add remappings
- PollingCheck.waitFor { getModifierKeyRemapping().size == 1 }
- activity.assertNoEvents()
+ injectKeyDown(keyboardDevice, KEY_LEFTALT)
+ verifier.assertReceivedKey(
+ allOf(
+ withKeyCode(KeyEvent.KEYCODE_SHIFT_LEFT),
+ withKeyAction(KeyEvent.ACTION_DOWN),
+ withModifierState(KeyEvent.META_SHIFT_LEFT_ON or KeyEvent.META_SHIFT_ON)
+ )
+ )
- injectKeyDown(keyboardDevice, KEY_LEFTALT)
- injectKeyUp(keyboardDevice, KEY_LEFTALT)
+ injectKeyUp(keyboardDevice, KEY_LEFTALT)
+ verifier.assertReceivedKey(withKeyCode(KeyEvent.KEYCODE_SHIFT_LEFT))
- assertReceivedEventsCorrectlyMapped(2, KeyEvent.KEYCODE_SHIFT_LEFT)
+ clearAllModifierKeyRemappings()
+ PollingCheck.waitFor {
+ KeyEvent.KEYCODE_ALT_LEFT ==
+ inputDevice?.getKeyCodeForKeyLocation(KeyEvent.KEYCODE_ALT_LEFT)
+ }
- clearAllModifierKeyRemappings()
- // Wait for handler to execute and clear all remappings
- PollingCheck.waitFor { getModifierKeyRemapping().isEmpty() }
+ injectKeyDown(keyboardDevice, KEY_LEFTALT)
+ verifier.assertReceivedKey(
+ allOf(
+ withKeyCode(KeyEvent.KEYCODE_ALT_LEFT),
+ withKeyAction(KeyEvent.ACTION_DOWN),
+ withModifierState(KeyEvent.META_ALT_LEFT_ON or KeyEvent.META_ALT_ON)
+ )
+ )
- injectKeyDown(keyboardDevice, KEY_LEFTALT)
- injectKeyUp(keyboardDevice, KEY_LEFTALT)
+ injectKeyUp(keyboardDevice, KEY_LEFTALT)
+ verifier.assertReceivedKey(withKeyCode(KeyEvent.KEYCODE_ALT_LEFT))
- assertReceivedEventsCorrectlyMapped(2, KeyEvent.KEYCODE_ALT_LEFT)
-
- // Remove the device
- keyboardDevice.close()
+ activity.assertNoEvents()
+ }
}
}
@Test
- fun testHardwareKeyEventsWithRemapping_BeforeKeyboardAdded() {
+ fun testHardwareKeyEventsWithRemapping_beforeKeyboardAdded() {
ModifierRemappingFlag(true).use {
+ // Add remapping before device is added
remapModifierKey(KeyEvent.KEYCODE_ALT_LEFT, KeyEvent.KEYCODE_SHIFT_LEFT)
- // Wait for handler to execute and add remappings
PollingCheck.waitFor { getModifierKeyRemapping().size == 1 }
- val keyboardDevice = UinputKeyboard(instrumentation)
+ UinputKeyboard(instrumentation).use { keyboardDevice ->
+ val inputDevice = inputManager.getInputDevice(keyboardDevice.deviceId)
+ PollingCheck.waitFor {
+ KeyEvent.KEYCODE_SHIFT_LEFT ==
+ inputDevice?.getKeyCodeForKeyLocation(KeyEvent.KEYCODE_ALT_LEFT)
+ }
- // Wait for device to be added
- PollingCheck.waitFor { inputManager.getInputDevice(keyboardDevice.deviceId) != null }
- activity.assertNoEvents()
+ injectKeyDown(keyboardDevice, KEY_LEFTALT)
+ verifier.assertReceivedKey(
+ allOf(
+ withKeyCode(KeyEvent.KEYCODE_SHIFT_LEFT),
+ withKeyAction(KeyEvent.ACTION_DOWN),
+ withModifierState(KeyEvent.META_SHIFT_LEFT_ON or KeyEvent.META_SHIFT_ON)
+ )
+ )
- // TODO(b/344517984): Refactor so that we don't need to wait for remapping to occur
- Thread.sleep(MODIFIER_REMAPPING_WAIT_TIME_MILLIS)
+ injectKeyUp(keyboardDevice, KEY_LEFTALT)
+ verifier.assertReceivedKey(withKeyCode(KeyEvent.KEYCODE_SHIFT_LEFT))
- injectKeyDown(keyboardDevice, KEY_LEFTALT)
- injectKeyUp(keyboardDevice, KEY_LEFTALT)
+ clearAllModifierKeyRemappings()
+ PollingCheck.waitFor {
+ KeyEvent.KEYCODE_ALT_LEFT ==
+ inputDevice?.getKeyCodeForKeyLocation(KeyEvent.KEYCODE_ALT_LEFT)
+ }
- assertReceivedEventsCorrectlyMapped(2, KeyEvent.KEYCODE_SHIFT_LEFT)
+ injectKeyDown(keyboardDevice, KEY_LEFTALT)
+ verifier.assertReceivedKey(
+ allOf(
+ withKeyCode(KeyEvent.KEYCODE_ALT_LEFT),
+ withKeyAction(KeyEvent.ACTION_DOWN),
+ withModifierState(KeyEvent.META_ALT_LEFT_ON or KeyEvent.META_ALT_ON)
+ )
+ )
- clearAllModifierKeyRemappings()
- // Wait for handler to execute and clear all remappings
- PollingCheck.waitFor { getModifierKeyRemapping().isEmpty() }
+ injectKeyUp(keyboardDevice, KEY_LEFTALT)
+ verifier.assertReceivedKey(withKeyCode(KeyEvent.KEYCODE_ALT_LEFT))
- injectKeyDown(keyboardDevice, KEY_LEFTALT)
- injectKeyUp(keyboardDevice, KEY_LEFTALT)
-
- assertReceivedEventsCorrectlyMapped(2, KeyEvent.KEYCODE_ALT_LEFT)
-
- // Remove the device
- keyboardDevice.close()
+ activity.assertNoEvents()
+ }
}
}
@@ -244,6 +204,7 @@
{ inputManager.clearAllModifierKeyRemappings() },
Manifest.permission.REMAP_MODIFIER_KEYS
)
+ PollingCheck.waitFor { getModifierKeyRemapping().isEmpty() }
}
private fun getModifierKeyRemapping(): Map<Int, Int> {
diff --git a/tests/input/src/android/input/cts/PointerIconTest.kt b/tests/input/src/android/input/cts/PointerIconTest.kt
index 4dcaec0..7003983 100644
--- a/tests/input/src/android/input/cts/PointerIconTest.kt
+++ b/tests/input/src/android/input/cts/PointerIconTest.kt
@@ -28,7 +28,6 @@
import android.hardware.input.VirtualMouse
import android.hardware.input.VirtualMouseConfig
import android.hardware.input.VirtualMouseRelativeEvent
-import android.os.Environment
import android.os.SystemProperties
import android.view.Display
import android.view.MotionEvent
@@ -228,9 +227,7 @@
const val SCREENSHOT_DIFF_PERCENT = 0.01 // 1% total difference threshold
const val MAX_PIXELS_DIFFERENT = 5
const val ASSETS_PATH = "tests/input/assets"
- val TEST_OUTPUT_PATH = Environment.getExternalStorageDirectory().absolutePath +
- "/CtsInputTestCases/" +
- PointerIconTest::class.java.simpleName
+ val TEST_OUTPUT_PATH = "/sdcard/Download/CtsInputTestCases/" + PointerIconTest::class.java.simpleName
val HW_TIMEOUT_MULTIPLIER = SystemProperties.getInt("ro.hw_timeout_multiplier", 1);
@JvmStatic
diff --git a/tests/inputmethod/Android.bp b/tests/inputmethod/Android.bp
index 06d1099..ce0af47 100644
--- a/tests/inputmethod/Android.bp
+++ b/tests/inputmethod/Android.bp
@@ -46,6 +46,7 @@
"cts_window-extensions",
"statsdprotonano",
"android.view.inputmethod.flags-aconfig-java",
+ "com.android.input.flags-aconfig-java",
"com.android.text.flags-aconfig-java",
"flag-junit",
"ravenwood-junit",
diff --git a/tests/inputmethod/src/android/view/inputmethod/cts/InputMethodManagerMultiDisplayTest.java b/tests/inputmethod/src/android/view/inputmethod/cts/InputMethodManagerMultiDisplayTest.java
index 14a9f1a..39e23f9 100644
--- a/tests/inputmethod/src/android/view/inputmethod/cts/InputMethodManagerMultiDisplayTest.java
+++ b/tests/inputmethod/src/android/view/inputmethod/cts/InputMethodManagerMultiDisplayTest.java
@@ -33,6 +33,7 @@
import android.platform.test.annotations.AppModeFull;
import android.server.wm.MultiDisplayTestBase;
import android.server.wm.WindowManagerState;
+import android.util.Log;
import android.view.Display;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
@@ -43,6 +44,9 @@
import androidx.test.filters.MediumTest;
import androidx.test.uiautomator.By;
import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.UiObjectNotFoundException;
+import androidx.test.uiautomator.UiScrollable;
+import androidx.test.uiautomator.UiSelector;
import androidx.test.uiautomator.Until;
import org.junit.After;
@@ -55,7 +59,8 @@
@MediumTest
@RunWith(AndroidJUnit4.class)
@AppModeFull(reason = "Instant apps cannot query the installed IMEs")
-public class InputMethodManagerMultiDisplayTest extends MultiDisplayTestBase {
+public final class InputMethodManagerMultiDisplayTest extends MultiDisplayTestBase {
+ private static final String TAG = "InputMethodManagerMultiDisplayTest";
private static final String MOCK_IME_ID =
"com.android.cts.mockimewithsubtypes/.MockImeWithSubtypes";
private static final String MOCK_IME_SUBTYPE_LABEL = "CTS Subtype 1 Test String";
@@ -89,6 +94,14 @@
uiDevice.setOrientationNatural();
mImManager.showInputMethodAndSubtypeEnabler(MOCK_IME_ID);
+ UiScrollable scroller = new UiScrollable(new UiSelector().scrollable(true));
+ try {
+ // Swipe far away from the edges to avoid triggering navigation gestures
+ scroller.setSwipeDeadZonePercentage(0.25);
+ scroller.scrollTextIntoView(MOCK_IME_SUBTYPE_LABEL);
+ } catch (UiObjectNotFoundException e) {
+ Log.e(TAG, "Exception when scroll to this view object", e);
+ }
// Check if new activity was started with subtype settings
assertThat(uiDevice.wait(Until.hasObject(By.text(MOCK_IME_SUBTYPE_LABEL)),
TIMEOUT)).isTrue();
diff --git a/tests/inputmethod/src/android/view/inputmethod/cts/InputMethodStartInputLifecycleTest.java b/tests/inputmethod/src/android/view/inputmethod/cts/InputMethodStartInputLifecycleTest.java
index 0e8c457..a508d24 100644
--- a/tests/inputmethod/src/android/view/inputmethod/cts/InputMethodStartInputLifecycleTest.java
+++ b/tests/inputmethod/src/android/view/inputmethod/cts/InputMethodStartInputLifecycleTest.java
@@ -38,6 +38,8 @@
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
+import static com.android.cts.input.injectinputinprocess.InjectInputInProcessKt.clickOnViewCenter;
+
import android.app.Instrumentation;
import android.content.Context;
import android.content.pm.PackageManager;
@@ -183,8 +185,7 @@
TestUtils.unlockScreen();
TestUtils.waitOnMainUntil(() -> screenStateCallbackRef.get() == SCREEN_STATE_ON
&& editText.getWindowVisibility() == VISIBLE, TIMEOUT);
- mCtsTouchUtils.emulateTapOnViewCenter(instrumentation, null, editText);
-
+ clickOnViewCenter(editText);
expectEvent(stream, editorMatcher("onStartInput", marker), TIMEOUT);
if (imeSession.isFinishInputNoFallbackConnectionEnabled()) {
// Expected only onStartInput and the EditText is active for input method.
diff --git a/tests/inputmethod/src/android/view/inputmethod/cts/StylusHandwritingTest.java b/tests/inputmethod/src/android/view/inputmethod/cts/StylusHandwritingTest.java
index c049bfb..02dde63 100644
--- a/tests/inputmethod/src/android/view/inputmethod/cts/StylusHandwritingTest.java
+++ b/tests/inputmethod/src/android/view/inputmethod/cts/StylusHandwritingTest.java
@@ -32,6 +32,7 @@
import static com.android.cts.mockime.ImeEventStreamTestUtils.expectEvent;
import static com.android.cts.mockime.ImeEventStreamTestUtils.notExpectEvent;
import static com.android.cts.mockime.ImeEventStreamTestUtils.withDescription;
+import static com.android.input.flags.Flags.FLAG_DEVICE_ASSOCIATIONS;
import static com.android.text.flags.Flags.FLAG_HANDWRITING_END_OF_LINE_TAP;
import static com.android.text.flags.Flags.FLAG_HANDWRITING_UNSUPPORTED_MESSAGE;
@@ -1117,6 +1118,7 @@
* until stylus ACTION_UP.
*/
@Test
+ @RequiresFlagsEnabled(FLAG_DEVICE_ASSOCIATIONS)
public void testHandwriting_fingerTouchIsIgnored() throws Exception {
int displayId = 0;
String initialUserRotation = null;
@@ -1294,6 +1296,7 @@
*/
@Test
@FlakyTest
+ @RequiresFlagsEnabled(FLAG_DEVICE_ASSOCIATIONS)
public void testOnViewClicked_withStylusTap() throws Exception {
UinputTouchDevice stylus = null;
int displayId = 0;
@@ -1347,10 +1350,14 @@
} else {
expectEvent(stream, onStartInputMatcher(toolType, unfocusedMarker), TIMEOUT);
}
- expectEvent(
- stream,
- onUpdateEditorToolTypeMatcher(toolType),
- TIMEOUT);
+ if (!Flags.refactorInsetsController()) {
+ // With the flag enabled, we won't call showSoftInput when the
+ // requestedVisibleTypes are not changed.
+ expectEvent(
+ stream,
+ onUpdateEditorToolTypeMatcher(toolType),
+ TIMEOUT);
+ }
} finally {
if (stylus != null) {
stylus.close();
@@ -1367,6 +1374,7 @@
*/
@Test
@FlakyTest
+ @RequiresFlagsEnabled(FLAG_DEVICE_ASSOCIATIONS)
public void testOnViewClicked_withFingerTap() throws Exception {
UinputTouchDevice touch = null;
int displayId = 0;
@@ -1431,6 +1439,7 @@
*/
@Test
@FlakyTest
+ @RequiresFlagsEnabled(FLAG_DEVICE_ASSOCIATIONS)
public void testOnViewClicked_withStylusHandwriting() throws Exception {
int displayId;
String initialUserRotation = null;
@@ -1927,6 +1936,7 @@
* editor ToolType should match stylus.
*/
@Test
+ @RequiresFlagsEnabled(FLAG_DEVICE_ASSOCIATIONS)
public void testHandwriting_editorToolTypeOnNewWindow() throws Exception {
assumeTrue(Flags.useHandwritingListenerForTooltype());
Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
diff --git a/tests/location/location_gnss/src/android/location/cts/gnss/GnssLocationValuesTest.java b/tests/location/location_gnss/src/android/location/cts/gnss/GnssLocationValuesTest.java
index 362b7a9..599fb2b 100644
--- a/tests/location/location_gnss/src/android/location/cts/gnss/GnssLocationValuesTest.java
+++ b/tests/location/location_gnss/src/android/location/cts/gnss/GnssLocationValuesTest.java
@@ -89,7 +89,7 @@
softAssert.assertAll();
}
- public static void checkLocationAccuracyFields(SoftAssert softAssert,
+ public void checkLocationAccuracyFields(SoftAssert softAssert,
Location location, boolean extendedLocationAccuracyExpected) {
softAssert.assertTrue("All locations generated by the LocationManager "
+ "should have a horizontal accuracy.", location.hasAccuracy());
@@ -117,7 +117,12 @@
softAssert.assertOrWarnTrue(/* strict= */ YEAR_2017_CAPABILITY_ENFORCED,
"All GNSS locations generated by the LocationManager "
+ "must have a speed accuracy.", location.hasSpeedAccuracy());
- if (location.hasSpeedAccuracy()) {
+ boolean isAutomotiveDevice = TestMeasurementUtil.isAutomotiveDevice(getContext());
+ // Automotive devices can with confidence (i.e. location.speedAccuracyMetersPerSecond() == 0)
+ // determine that the device is in stand-still (i.e. location.getSpeed() == 0).
+ // Thus, for automotive: test for location.speedAccuracyMetersPerSecond() > 0 only if
+ // location.getSpeed() > 0.
+ if (location.hasSpeedAccuracy() && (!isAutomotiveDevice || location.getSpeed() > 0)) {
softAssert.assertOrWarnTrue(/* strict= */ true,
"Speed Accuracy should be greater than 0.",
location.getSpeedAccuracyMetersPerSecond() > 0);
diff --git a/tests/mediaprovider/src/android/provider/cts/media/MediaStore_Video_ThumbnailsTest.java b/tests/mediaprovider/src/android/provider/cts/media/MediaStore_Video_ThumbnailsTest.java
index 94eb360..a8bb067 100644
--- a/tests/mediaprovider/src/android/provider/cts/media/MediaStore_Video_ThumbnailsTest.java
+++ b/tests/mediaprovider/src/android/provider/cts/media/MediaStore_Video_ThumbnailsTest.java
@@ -51,6 +51,7 @@
import com.android.compatibility.common.util.MediaUtils;
+import org.junit.Assume;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -213,6 +214,10 @@
@Test
public void testInsertUpdateDelete() throws Exception {
+ Assume.assumeTrue(
+ MediaUtils.hasCodecForResourceAndDomain(mContext, R.raw.testvideo, "video/")
+ && MediaUtils.hasCodecForResourceAndDomain(mContext, R.raw.testvideo2, "video/"));
+
final Uri finalUri = MediaProviderTestUtils.stageMedia(R.raw.testvideo,
mExternalVideo, "video/mp4");
diff --git a/tests/security/src/android/keystore/cts/AuthorizationList.java b/tests/security/src/android/keystore/cts/AuthorizationList.java
index 5c8ab25..15c83ec 100644
--- a/tests/security/src/android/keystore/cts/AuthorizationList.java
+++ b/tests/security/src/android/keystore/cts/AuthorizationList.java
@@ -22,6 +22,11 @@
import static com.google.common.collect.Collections2.transform;
import android.os.Build;
+import static android.security.keymaster.KeymasterDefs.KM_PURPOSE_AGREE_KEY;
+import static android.security.keymaster.KeymasterDefs.KM_PURPOSE_ENCRYPT;
+import static android.security.keymaster.KeymasterDefs.KM_PURPOSE_DECRYPT;
+import static android.security.keymaster.KeymasterDefs.KM_PURPOSE_SIGN;
+import static android.security.keymaster.KeymasterDefs.KM_PURPOSE_VERIFY;
import android.security.keystore.KeyProperties;
import android.util.Log;
@@ -81,12 +86,6 @@
public static final int KM_ORIGIN_IMPORTED = 2;
public static final int KM_ORIGIN_UNKNOWN = 3;
- // Operation Purposes.
- public static final int KM_PURPOSE_ENCRYPT = 0;
- public static final int KM_PURPOSE_DECRYPT = 1;
- public static final int KM_PURPOSE_SIGN = 2;
- public static final int KM_PURPOSE_VERIFY = 3;
-
// User authenticators.
public static final int HW_AUTH_PASSWORD = 1 << 0;
public static final int HW_AUTH_FINGERPRINT = 1 << 1;
@@ -172,6 +171,7 @@
.put(KM_PURPOSE_ENCRYPT, "ENCRYPT")
.put(KM_PURPOSE_SIGN, "SIGN")
.put(KM_PURPOSE_VERIFY, "VERIFY")
+ .put(KM_PURPOSE_AGREE_KEY, "AGREE_KEY")
.build();
private Integer securityLevel;
diff --git a/tests/surfacecontrol/src/android/view/surfacecontrol/cts/ASurfaceControlTest.java b/tests/surfacecontrol/src/android/view/surfacecontrol/cts/ASurfaceControlTest.java
index e760611..0e30ecf 100644
--- a/tests/surfacecontrol/src/android/view/surfacecontrol/cts/ASurfaceControlTest.java
+++ b/tests/surfacecontrol/src/android/view/surfacecontrol/cts/ASurfaceControlTest.java
@@ -68,6 +68,7 @@
import android.graphics.Rect;
import android.hardware.DataSpace;
import android.os.SystemClock;
+import android.os.SystemProperties;
import android.os.Trace;
import android.platform.test.annotations.RequiresDevice;
import android.util.Log;
@@ -1245,9 +1246,11 @@
assertTrue(onCompleteCallback.mCallbackTime > 0);
assertTrue(onCompleteCallback.mLatchTime > 0);
- assertTrue("transaction was presented too early. presentTime="
- + onCompleteCallback.mPresentTime,
- onCompleteCallback.mPresentTime >= mDesiredPresentTime);
+ if(SystemProperties.getBoolean("service.sf.present_timestamp", true)) {
+ assertTrue("transaction was presented too early. presentTime="
+ + onCompleteCallback.mPresentTime,
+ onCompleteCallback.mPresentTime >= mDesiredPresentTime);
+ }
}
@Test
@@ -1289,9 +1292,11 @@
assertTrue(onCompleteCallback.mCallbackTime > 0);
assertTrue(onCompleteCallback.mLatchTime > 0);
- assertTrue("transaction was presented too early. presentTime="
- + onCompleteCallback.mPresentTime,
- onCompleteCallback.mPresentTime >= mDesiredPresentTime);
+ if(SystemProperties.getBoolean("service.sf.present_timestamp", true)) {
+ assertTrue("transaction was presented too early. presentTime="
+ + onCompleteCallback.mPresentTime,
+ onCompleteCallback.mPresentTime >= mDesiredPresentTime);
+ }
}
@Test
@@ -1334,9 +1339,11 @@
assertTrue(onCompleteCallback.mCallbackTime > 0);
assertTrue(onCompleteCallback.mLatchTime > 0);
- assertTrue("transaction was presented too early. presentTime="
- + onCompleteCallback.mPresentTime,
- onCompleteCallback.mPresentTime >= mDesiredPresentTime);
+ if(SystemProperties.getBoolean("service.sf.present_timestamp", true)) {
+ assertTrue("transaction was presented too early. presentTime="
+ + onCompleteCallback.mPresentTime,
+ onCompleteCallback.mPresentTime >= mDesiredPresentTime);
+ }
}
@Test
diff --git a/tests/surfacecontrol/src/android/view/surfacecontrol/cts/AttachedSurfaceControlTest.java b/tests/surfacecontrol/src/android/view/surfacecontrol/cts/AttachedSurfaceControlTest.java
index 99fb649..26c29be 100644
--- a/tests/surfacecontrol/src/android/view/surfacecontrol/cts/AttachedSurfaceControlTest.java
+++ b/tests/surfacecontrol/src/android/view/surfacecontrol/cts/AttachedSurfaceControlTest.java
@@ -59,7 +59,6 @@
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.rule.ActivityTestRule;
-import com.android.compatibility.common.util.SystemUtil;
import com.android.window.flags.Flags;
import org.junit.After;
@@ -77,8 +76,6 @@
@SmallTest
public class AttachedSurfaceControlTest {
private static final String TAG = "AttachedSurfaceControlTest";
- private static final String FIXED_TO_USER_ROTATION_COMMAND =
- "cmd window fixed-to-user-rotation";
private IgnoreOrientationRequestSession mOrientationSession;
private WindowManagerStateHelper mWmState;
@@ -146,8 +143,8 @@
InstrumentationRegistry.getInstrumentation().getContext().getPackageManager();
boolean supportsRotation = pm.hasSystemFeature(PackageManager.FEATURE_SCREEN_PORTRAIT)
&& pm.hasSystemFeature(PackageManager.FEATURE_SCREEN_LANDSCAPE);
- final boolean isFixedToUserRotation =
- "enabled".equals(SystemUtil.runShellCommand(FIXED_TO_USER_ROTATION_COMMAND).trim());
+ mWmState.computeState();
+ final boolean isFixedToUserRotation = mWmState.isFixedToUserRotation();
Assume.assumeTrue(supportsRotation && !isFixedToUserRotation);
}
diff --git a/tests/surfacecontrol/src/android/view/surfacecontrol/cts/ChoreographerNativeTest.java b/tests/surfacecontrol/src/android/view/surfacecontrol/cts/ChoreographerNativeTest.java
index d18a131..21cb7ce 100644
--- a/tests/surfacecontrol/src/android/view/surfacecontrol/cts/ChoreographerNativeTest.java
+++ b/tests/surfacecontrol/src/android/view/surfacecontrol/cts/ChoreographerNativeTest.java
@@ -120,6 +120,7 @@
mSupportedPeriods = Arrays.stream(mDefaultDisplay.getSupportedModes())
.mapToLong(mode -> (long) (Duration.ofSeconds(1).toNanos() / mode.getRefreshRate()))
+ .distinct()
.toArray();
mChoreographerPtr = nativeGetChoreographer();
diff --git a/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java b/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java
index 74f5f24..a542e64 100644
--- a/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java
+++ b/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java
@@ -19,6 +19,7 @@
import static android.Manifest.permission.POST_NOTIFICATIONS;
import static android.Manifest.permission.REVOKE_POST_NOTIFICATIONS_WITHOUT_KILL;
import static android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_FREQUENT;
@@ -710,7 +711,18 @@
startTime, endTime);
stats = events.get(mTargetPackage);
- assertEquals(startingCount + 2, stats.getAppLaunchCount());
+ final ComponentName activityThree = new ComponentName(mTargetPackage,
+ Activities.ActivityThree.class.getName());
+ mWMStateHelper.waitAndAssertActivityState(activityThree, WindowManagerState.STATE_RESUMED);
+
+ // If the app is launching in freeform instead of the requested FULLSCREEN, then the
+ // target package was never stopped.
+ if (mWMStateHelper.getTaskByActivity(activityThree).getWindowingMode()
+ == WINDOWING_MODE_FREEFORM) {
+ assertEquals(startingCount + 1, stats.getAppLaunchCount());
+ } else {
+ assertEquals(startingCount + 2, stats.getAppLaunchCount());
+ }
}
@AppModeFull(reason = "No usage events access in instant apps")
diff --git a/tests/tests/appenumeration/src/android/appenumeration/cts/MediaSessionEnumerationTests.java b/tests/tests/appenumeration/src/android/appenumeration/cts/MediaSessionEnumerationTests.java
index 14b4def..cfacad4 100644
--- a/tests/tests/appenumeration/src/android/appenumeration/cts/MediaSessionEnumerationTests.java
+++ b/tests/tests/appenumeration/src/android/appenumeration/cts/MediaSessionEnumerationTests.java
@@ -26,6 +26,7 @@
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
+import static org.junit.Assume.assumeFalse;
import android.content.Intent;
import android.content.pm.PackageManager;
@@ -33,6 +34,8 @@
import androidx.test.ext.junit.runners.AndroidJUnit4;
+import com.android.compatibility.common.util.UserHelper;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -41,8 +44,14 @@
@RunWith(AndroidJUnit4.class)
public class MediaSessionEnumerationTests extends AppEnumerationTestsBase {
+ private UserHelper mUserHelper = new UserHelper();
+
@Before
public void onBefore() {
+ // Skip tests for visible background users.
+ // TODO(b/380297485): Enable the tests back when notification listener fully supports
+ // visible background users.
+ assumeFalse(mUserHelper.isVisibleBackgroundUser());
setAllowGetActiveSession(TARGET_NO_API, true);
}
diff --git a/tests/tests/assist/common/src/android/assist/common/Utils.java b/tests/tests/assist/common/src/android/assist/common/Utils.java
index 5cee36d..fe8354e 100755
--- a/tests/tests/assist/common/src/android/assist/common/Utils.java
+++ b/tests/tests/assist/common/src/android/assist/common/Utils.java
@@ -39,10 +39,7 @@
public static final String BROADCAST_INTENT_START_ASSIST = ACTION_PREFIX + "START_ASSIST";
public static final String ASSIST_RECEIVER_REGISTERED = ACTION_PREFIX + "ASSIST_READY";
public static final String ACTION_END_OF_TEST = ACTION_PREFIX + "END_OF_TEST";
-
- public static final String ACTION_INVALIDATE = "invalidate_action";
- public static final String GET_CONTENT_VIEW_HEIGHT = ACTION_PREFIX + "GET_CONTENT_VIEW_HEIGHT";
- public static final String BROADCAST_CONTENT_VIEW_HEIGHT = ACTION_PREFIX + "VIEW_HEIGHT";
+ public static final String BROADCAST_CONTENT_VIEW = ACTION_PREFIX + "CONTENT_VIEW";
public static final String SCROLL_TEXTVIEW_ACTION = ACTION_PREFIX + "TEXTVIEW_SCROLL";
public static final String SCROLL_SCROLLVIEW_ACTION = ACTION_PREFIX + "SCROLLVIEW_SCROLL";
public static final String TEST_ERROR = "Error In Test:";
@@ -64,6 +61,7 @@
/** Lifecycle Test intent constants */
public static final String LIFECYCLE_PREFIX = ACTION_PREFIX + "lifecycle_";
+
public static final String LIFECYCLE_HASRESUMED = LIFECYCLE_PREFIX + "hasResumed";
public static final String LIFECYCLE_HASFOCUS = LIFECYCLE_PREFIX + "hasFocus";
public static final String LIFECYCLE_LOSTFOCUS = LIFECYCLE_PREFIX + "lostFocus";
@@ -73,28 +71,26 @@
/** Focus Change Test intent constants */
public static final String GAINED_FOCUS = ACTION_PREFIX + "focus_changed";
+
public static final String LOST_FOCUS = ACTION_PREFIX + "lost_focus";
public static final String APP_3P_HASRESUMED = ACTION_PREFIX + "app_3p_hasResumed";
public static final String APP_3P_HASDRAWED = ACTION_PREFIX + "app_3p_hasDrawed";
public static final String TEST_ACTIVITY_DESTROY = ACTION_PREFIX + "test_activity_destroy";
- public static final String TEST_ACTIVITY_WEBVIEW_LOADED = ACTION_PREFIX + "test_activity_webview_hasResumed";
+ public static final String TEST_ACTIVITY_WEBVIEW_LOADED =
+ ACTION_PREFIX + "test_activity_webview_hasResumed";
// Notice: timeout belows have to be long because some devices / form factors (like car) are
// slower.
/** Timeout for getting back assist context */
public static final int TIMEOUT_MS = 6 * 1_000;
+
/** Timeout for an activity to resume */
public static final int ACTIVITY_ONRESUME_TIMEOUT_MS = 12 * 1_000;
public static final String EXTRA_REGISTER_RECEIVER = "register_receiver";
- /** Extras for passing the Assistant's ContentView's dimensions*/
- public static final String EXTRA_CONTENT_VIEW_HEIGHT = "extra_content_view_height";
- public static final String EXTRA_CONTENT_VIEW_WIDTH = "extra_content_view_width";
- public static final String EXTRA_DISPLAY_POINT = "extra_display_point";
-
/*
* Extras used to pass RemoteCallback objects responsible for IPC between test, app, and
* service.
@@ -103,10 +99,12 @@
public static final String EXTRA_REMOTE_CALLBACK_ACTION = "extra_remote_callback_action";
public static final String EXTRA_REMOTE_CALLBACK_RECEIVING = "extra_remote_callback_receiving";
- public static final String EXTRA_REMOTE_CALLBACK_RECEIVING_ACTION = "extra_remote_callback_receiving_action";
+ public static final String EXTRA_REMOTE_CALLBACK_RECEIVING_ACTION =
+ "extra_remote_callback_receiving_action";
/** Test name suffixes */
public static final String ASSIST_STRUCTURE = "ASSIST_STRUCTURE";
+
public static final String DISABLE_CONTEXT = "DISABLE_CONTEXT";
public static final String FLAG_SECURE = "FLAG_SECURE";
public static final String LIFECYCLE = "LIFECYCLE";
@@ -121,43 +119,49 @@
/** Session intent constants */
public static final String HIDE_SESSION = "android.intent.action.hide_session";
- public static final String HIDE_SESSION_COMPLETE = "android.intent.action.hide_session_complete";
+
+ public static final String HIDE_SESSION_COMPLETE =
+ "android.intent.action.hide_session_complete";
/** Lifecycle activity intent constants */
/** Session intent constants */
- public static final String HIDE_LIFECYCLE_ACTIVITY
- = "android.intent.action.hide_lifecycle_activity";
+ public static final String HIDE_LIFECYCLE_ACTIVITY =
+ "android.intent.action.hide_lifecycle_activity";
/** Stub html view to load into WebView */
public static final String WEBVIEW_HTML_URL = "http://dev.null/thou/should?not=pass";
+
public static final String WEBVIEW_HTML_DOMAIN = "dev.null";
public static final LocaleList WEBVIEW_LOCALE_LIST = new LocaleList(Locale.ROOT, Locale.US);
public static final String WEBVIEW_HTML_GREETING = "Hello WebView!";
- public static final String WEBVIEW_HTML = "<html><body><div><p>" + WEBVIEW_HTML_GREETING
- + "</p></div></body></html>";
+ public static final String WEBVIEW_HTML =
+ "<html><body><div><p>" + WEBVIEW_HTML_GREETING + "</p></div></body></html>";
/** Extra data to add to assist data and assist content */
private static Bundle EXTRA_ASSIST_BUNDLE;
+
private static String STRUCTURED_JSON;
private static String MY_UID_EXTRA = "my_uid";
public static final String getStructuredJSON() throws Exception {
if (STRUCTURED_JSON == null) {
- STRUCTURED_JSON = new JSONObject()
- .put("@type", "MusicRecording")
- .put("@id", "https://example/music/recording")
- .put("url", "android-app://com.example/https/music/album")
- .put("name", "Album Title")
- .put("hello", "hi there")
- .put("knownNull", null)
- .put("unicode value", "\ud800\udc35")
- .put("empty string", "")
- .put("LongString",
- "lkasdjfalsdkfjalsdjfalskj9i9234jl1w23j4o123j412l3j421l3kj412l3kj1l3k4j32")
- .put("\ud800\udc35", "any-value")
- .put("key with spaces", "any-value")
- .toString();
+ STRUCTURED_JSON =
+ new JSONObject()
+ .put("@type", "MusicRecording")
+ .put("@id", "https://example/music/recording")
+ .put("url", "android-app://com.example/https/music/album")
+ .put("name", "Album Title")
+ .put("hello", "hi there")
+ .put("knownNull", null)
+ .put("unicode value", "\ud800\udc35")
+ .put("empty string", "")
+ .put(
+ "LongString",
+ "lkasdjfalsdkfjalsdjfalskj9i9234jl1w23j4o123j412l3j421l3kj412l3kj1l3k4j32")
+ .put("\ud800\udc35", "any-value")
+ .put("key with spaces", "any-value")
+ .toString();
}
return STRUCTURED_JSON;
}
@@ -172,7 +176,6 @@
public static void addExtraAssistDataToBundle(Bundle data) {
addExtraAssistDataToBundle(data, /* addMyUid= */ true);
-
}
private static void addExtraAssistDataToBundle(Bundle data, boolean addMyUid) {
@@ -185,9 +188,7 @@
}
}
- /**
- * The test app associated with each test.
- */
+ /** The test app associated with each test. */
public static final ComponentName getTestAppComponent(String testCaseType) {
switch (testCaseType) {
case ASSIST_STRUCTURE:
@@ -218,21 +219,17 @@
return new ComponentName(
"android.assist.testapp", "android.assist.testapp.FocusChangeActivity");
default:
- return new ComponentName("","");
+ return new ComponentName("", "");
}
}
- /**
- * Sets the proper action used to launch an activity in the testapp package.
- */
+ /** Sets the proper action used to launch an activity in the testapp package. */
public static void setTestAppAction(Intent intent, String testCaseName) {
intent.putExtra(Utils.TESTCASE_TYPE, testCaseName);
intent.setAction("android.intent.action.TEST_APP_" + testCaseName);
}
- /**
- * Returns the amount of time to wait for assist data.
- */
+ /** Returns the amount of time to wait for assist data. */
public static final int getAssistDataTimeout(String testCaseType) {
switch (testCaseType) {
case SCREENSHOT:
@@ -263,7 +260,7 @@
public static final void addErrorResult(final Bundle testinfo, final String msg) {
testinfo.getStringArrayList(testinfo.getString(Utils.TESTCASE_TYPE))
- .add(TEST_ERROR + " " + msg);
+ .add(TEST_ERROR + " " + msg);
}
public static int getExpectedUid(Bundle extras) {
diff --git a/tests/tests/assist/service/src/android/assist/service/MainInteractionSession.java b/tests/tests/assist/service/src/android/assist/service/MainInteractionSession.java
index e81df71..21fdd7f 100644
--- a/tests/tests/assist/service/src/android/assist/service/MainInteractionSession.java
+++ b/tests/tests/assist/service/src/android/assist/service/MainInteractionSession.java
@@ -16,9 +16,6 @@
package android.assist.service;
-import static android.view.WindowInsets.Type.displayCutout;
-import static android.view.WindowInsets.Type.statusBars;
-
import android.app.assist.AssistContent;
import android.app.assist.AssistStructure;
import android.assist.common.Utils;
@@ -35,14 +32,9 @@
import android.os.RemoteCallback;
import android.service.voice.VoiceInteractionSession;
import android.util.Log;
-import android.view.Display;
-import android.view.DisplayCutout;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewTreeObserver;
-import android.view.WindowInsets;
-import android.view.WindowManager;
-import android.view.WindowMetrics;
public class MainInteractionSession extends VoiceInteractionSession {
static final String TAG = "MainInteractionSession";
@@ -54,8 +46,6 @@
private boolean hasReceivedScreenshot = false;
private boolean mScreenshotNeeded = true;
private int mCurColor;
- private int mDisplayHeight;
- private int mDisplayWidth;
private Rect mDisplayAreaBounds;
private BroadcastReceiver mReceiver;
private String mTestName;
@@ -71,22 +61,26 @@
@Override
public void onCreate() {
super.onCreate();
- mReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (action.equals(Utils.HIDE_SESSION)) {
- hide();
- }
+ mReceiver =
+ new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (action.equals(Utils.HIDE_SESSION)) {
+ hide();
+ }
- Bundle bundle = new Bundle();
- bundle.putString(Utils.EXTRA_REMOTE_CALLBACK_ACTION, Utils.HIDE_SESSION_COMPLETE);
- mRemoteCallback.sendResult(bundle);
- }
- };
+ Bundle bundle = new Bundle();
+ bundle.putString(
+ Utils.EXTRA_REMOTE_CALLBACK_ACTION, Utils.HIDE_SESSION_COMPLETE);
+ mRemoteCallback.sendResult(bundle);
+ }
+ };
IntentFilter filter = new IntentFilter();
filter.addAction(Utils.HIDE_SESSION);
- mContext.registerReceiver(mReceiver, filter,
+ mContext.registerReceiver(
+ mReceiver,
+ filter,
Context.RECEIVER_VISIBLE_TO_INSTANT_APPS | Context.RECEIVER_EXPORTED);
}
@@ -124,63 +118,25 @@
mScreenshotNeeded = (showFlags & SHOW_WITH_SCREENSHOT) != 0;
mTestName = args.getString(Utils.TESTCASE_TYPE, "");
mCurColor = args.getInt(Utils.SCREENSHOT_COLOR_KEY);
- mDisplayHeight = args.getInt(Utils.DISPLAY_HEIGHT_KEY);
- mDisplayWidth = args.getInt(Utils.DISPLAY_WIDTH_KEY);
mDisplayAreaBounds = args.getParcelable(Utils.DISPLAY_AREA_BOUNDS_KEY);
mRemoteCallback = args.getParcelable(Utils.EXTRA_REMOTE_CALLBACK);
super.onShow(args, showFlags);
if (mContentView == null) return; // Happens when ui is not enabled.
- mContentView.getViewTreeObserver().addOnPreDrawListener(
- new ViewTreeObserver.OnPreDrawListener() {
- @Override
- public boolean onPreDraw() {
- mContentView.getViewTreeObserver().removeOnPreDrawListener(this);
- Display d = mContentView.getDisplay();
- Point displayPoint = new Point();
- // The voice interaction window layer is higher than keyguard, status bar,
- // nav bar now. So we should take both status bar, nav bar into consideration.
- // The voice interaction hide the nav bar, so the height only need to consider
- // status bar. The status bar may contain display cutout but the display cutout
- // is device specific, we need to check it.
- WindowManager wm = mContext.getSystemService(WindowManager.class);
- WindowMetrics windowMetrics = wm.getCurrentWindowMetrics();
- Rect bound = windowMetrics.getBounds();
- WindowInsets windowInsets = windowMetrics.getWindowInsets();
- android.graphics.Insets statusBarInsets =
- windowInsets.getInsets(statusBars());
- android.graphics.Insets displayCutoutInsets =
- windowInsets.getInsets(displayCutout());
- android.graphics.Insets min =
- android.graphics.Insets.min(statusBarInsets, displayCutoutInsets);
- boolean statusBarContainsCutout = !android.graphics.Insets.NONE.equals(min);
- Log.d(TAG, "statusBarContainsCutout=" + statusBarContainsCutout);
- displayPoint.y = statusBarContainsCutout
- ? bound.height() - min.top - min.bottom :
- bound.height() - displayCutoutInsets.top - displayCutoutInsets.bottom;
- displayPoint.x = statusBarContainsCutout ?
- bound.width() - min.left - min.right :
- bound.width() - displayCutoutInsets.left - displayCutoutInsets.right;
- DisplayCutout dc = d.getCutout();
- if (dc != null) {
- // Means the device has a cutout area
- android.graphics.Insets wi = d.getCutout().getWaterfallInsets();
-
- if (wi != android.graphics.Insets.NONE) {
- // Waterfall cutout. Considers only the display
- // useful area discarding the cutout.
- displayPoint.x -= (wi.left + wi.right);
- }
- }
- Bundle bundle = new Bundle();
- bundle.putString(Utils.EXTRA_REMOTE_CALLBACK_ACTION,
- Utils.BROADCAST_CONTENT_VIEW_HEIGHT);
- bundle.putInt(Utils.EXTRA_CONTENT_VIEW_HEIGHT, mContentView.getHeight());
- bundle.putInt(Utils.EXTRA_CONTENT_VIEW_WIDTH, mContentView.getWidth());
- bundle.putParcelable(Utils.EXTRA_DISPLAY_POINT, displayPoint);
- mRemoteCallback.sendResult(bundle);
- return true;
- }
- });
+ mContentView
+ .getViewTreeObserver()
+ .addOnPreDrawListener(
+ new ViewTreeObserver.OnPreDrawListener() {
+ @Override
+ public boolean onPreDraw() {
+ mContentView.getViewTreeObserver().removeOnPreDrawListener(this);
+ Bundle bundle = new Bundle();
+ bundle.putString(
+ Utils.EXTRA_REMOTE_CALLBACK_ACTION,
+ Utils.BROADCAST_CONTENT_VIEW);
+ mRemoteCallback.sendResult(bundle);
+ return true;
+ }
+ });
}
@Override
@@ -191,12 +147,16 @@
AssistContent content = state.getAssistContent();
ComponentName activity = structure == null ? null : structure.getActivityComponent();
Log.i(TAG, "onHandleAssist()");
- Log.i(TAG, String.format("Bundle: %s, Activity: %s, Structure: %s, Content: %s",
- data, activity, structure, content));
+ Log.i(
+ TAG,
+ String.format(
+ "Bundle: %s, Activity: %s, Structure: %s, Content: %s",
+ data, activity, structure, content));
// The structure becomes null under following conditions
// May be null if assist data has been disabled by the user or device policy;
- // Will be an empty stub if the application has disabled assist by marking its window as secure.
+ // Will be an empty stub if the application has disabled assist by marking its window as
+ // secure.
// The CTS testcase will fail under the condition(automotive usecases) where
// there are multiple displays and some of the displays are marked with FLAG_SECURE
@@ -205,7 +165,8 @@
return;
}
- if (activity != null && Utils.isAutomotive(mContext)
+ if (activity != null
+ && Utils.isAutomotive(mContext)
&& !activity.getPackageName().startsWith("android.assist")) {
// TODO: automotive has multiple activities / displays, so the test might fail if it
// receives one of them (like the cluster activity) instead of what's expecting. This is
@@ -249,8 +210,7 @@
if (mTestName.equals(Utils.SCREENSHOT)) {
boolean screenshotMatches = compareScreenshot(screenshot, mCurColor);
Log.i(TAG, "this is a screenshot test. Matches? " + screenshotMatches);
- mAssistData.putBoolean(
- Utils.COMPARE_SCREENSHOT_KEY, screenshotMatches);
+ mAssistData.putBoolean(Utils.COMPARE_SCREENSHOT_KEY, screenshotMatches);
}
} else {
mAssistData.putBoolean(Utils.ASSIST_SCREENSHOT_KEY, false);
@@ -264,13 +224,14 @@
// factors.
// The current approach does not handle overridden screen sizes, and there's no clear way
// to handle that and multiple display areas at the same time.
-// Point size = new Point(mDisplayWidth, mDisplayHeight);
+ // Point size = new Point(mDisplayWidth, mDisplayHeight);
-// if (screenshot.getWidth() != size.x || screenshot.getHeight() != size.y) {
-// Log.i(TAG, "width or height didn't match: " + size + " vs " + screenshot.getWidth()
-// + "," + screenshot.getHeight());
-// return false;
-// }
+ // if (screenshot.getWidth() != size.x || screenshot.getHeight() != size.y) {
+ // Log.i(TAG, "width or height didn't match: " + size + " vs " +
+ // screenshot.getWidth()
+ // + "," + screenshot.getHeight());
+ // return false;
+ // }
Point size = new Point(screenshot.getWidth(), screenshot.getHeight());
int[] pixels = new int[size.x * size.y];
screenshot.getPixels(pixels, 0, size.x, 0, 0, size.x, size.y);
@@ -278,8 +239,13 @@
// screenshot bitmap contains the screenshot for the entire physical display. A single
// physical display could have multiple display area with different applications.
// Let's grab the region of the display area from the original screenshot.
- Bitmap displayAreaScreenshot = Bitmap.createBitmap(screenshot, mDisplayAreaBounds.left,
- mDisplayAreaBounds.top, mDisplayAreaBounds.width(), mDisplayAreaBounds.height());
+ Bitmap displayAreaScreenshot =
+ Bitmap.createBitmap(
+ screenshot,
+ mDisplayAreaBounds.left,
+ mDisplayAreaBounds.top,
+ mDisplayAreaBounds.width(),
+ mDisplayAreaBounds.height());
int expectedColor = 0;
for (int pixel : pixels) {
// Check for roughly the same because there are rounding errors converting from the
@@ -304,7 +270,8 @@
Log.i(TAG, "waiting for screenshot before broadcasting results");
} else {
Bundle bundle = new Bundle();
- bundle.putString(Utils.EXTRA_REMOTE_CALLBACK_ACTION, Utils.BROADCAST_ASSIST_DATA_INTENT);
+ bundle.putString(
+ Utils.EXTRA_REMOTE_CALLBACK_ACTION, Utils.BROADCAST_ASSIST_DATA_INTENT);
bundle.putBundle(Utils.ON_SHOW_ARGS_KEY, mOnShowArgs);
bundle.putAll(mAssistData);
mRemoteCallback.sendResult(bundle);
@@ -320,7 +287,7 @@
if (f == null) {
Log.wtf(TAG, "layout inflater was null");
}
- mContentView = f.inflate(R.layout.assist_layer,null);
+ mContentView = f.inflate(R.layout.assist_layer, null);
Log.i(TAG, "onCreateContentView");
return mContentView;
}
diff --git a/tests/tests/assist/src/android/assist/cts/AssistantContentViewTest.java b/tests/tests/assist/src/android/assist/cts/AssistantContentViewTest.java
index cd1c8bc..23f9f7d 100644
--- a/tests/tests/assist/src/android/assist/cts/AssistantContentViewTest.java
+++ b/tests/tests/assist/src/android/assist/cts/AssistantContentViewTest.java
@@ -16,13 +16,10 @@
package android.assist.cts;
-import static com.google.common.truth.Truth.assertThat;
-
import static org.junit.Assert.fail;
import android.assist.common.AutoResetLatch;
import android.assist.common.Utils;
-import android.graphics.Point;
import android.os.Bundle;
import android.util.Log;
@@ -34,7 +31,6 @@
public class AssistantContentViewTest extends AssistTestBase {
private static final String TAG = "ContentViewTest";
private AutoResetLatch mContentViewLatch = new AutoResetLatch(1);
- private Bundle mBundle;
@Override
protected void customSetup() throws Exception {
@@ -42,11 +38,6 @@
startTestActivity(Utils.VERIFY_CONTENT_VIEW);
}
- @Override
- protected void customTearDown() throws Exception {
- mBundle = null;
- }
-
private void waitForContentView() throws Exception {
Log.i(TAG, "waiting for the Assistant's Content View before continuing");
if (!mContentViewLatch.await(Utils.TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
@@ -55,31 +46,25 @@
}
@Test
- public void testAssistantContentViewDimens() throws Exception {
+ public void testAssistantContentView() throws Exception {
if (mActivityManager.isLowRamDevice()) {
- Log.d(TAG, "Not running assist tests on low-RAM device.");
- return;
+ Log.d(TAG, "Not running assist tests on low-RAM device.");
+ return;
}
startTest(Utils.VERIFY_CONTENT_VIEW);
waitForAssistantToBeReady();
startSession();
waitForContentView();
- int height = mBundle.getInt(Utils.EXTRA_CONTENT_VIEW_HEIGHT, 0);
- int width = mBundle.getInt(Utils.EXTRA_CONTENT_VIEW_WIDTH, 0);
- Point displayPoint = mBundle.getParcelable(Utils.EXTRA_DISPLAY_POINT);
- assertThat(height).isEqualTo(displayPoint.y);
- assertThat(width).isEqualTo(displayPoint.x);
}
private class AssistantReceiver extends ActionLatchReceiver {
AssistantReceiver() {
- super(Utils.BROADCAST_CONTENT_VIEW_HEIGHT, mContentViewLatch);
+ super(Utils.BROADCAST_CONTENT_VIEW, mContentViewLatch);
}
@Override
protected void onAction(Bundle bundle, String action) {
- mBundle = bundle;
super.onAction(bundle, action);
}
}
diff --git a/tests/tests/car/src/android/car/cts/CarAudioManagerTest.java b/tests/tests/car/src/android/car/cts/CarAudioManagerTest.java
index 7c5b340..b45f413 100644
--- a/tests/tests/car/src/android/car/cts/CarAudioManagerTest.java
+++ b/tests/tests/car/src/android/car/cts/CarAudioManagerTest.java
@@ -19,6 +19,7 @@
import static android.car.Car.PERMISSION_CAR_CONTROL_AUDIO_VOLUME;
import static android.car.media.CarAudioManager.AUDIO_FEATURE_AUDIO_MIRRORING;
import static android.car.media.CarAudioManager.AUDIO_FEATURE_DYNAMIC_ROUTING;
+import static android.car.media.CarAudioManager.AUDIO_FEATURE_OEM_AUDIO_SERVICE;
import static android.car.media.CarAudioManager.AUDIO_FEATURE_VOLUME_GROUP_EVENTS;
import static android.car.media.CarAudioManager.AUDIO_FEATURE_VOLUME_GROUP_MUTING;
import static android.car.media.CarAudioManager.AUDIO_MIRROR_CAN_ENABLE;
@@ -253,6 +254,7 @@
@ApiTest(apis = {
"android.car.media.CarAudioManager#registerCarVolumeCallback"})
public void registerCarVolumeCallback_onGroupVolumeChanged() throws Exception {
+ assumeOemServiceIsDisabled();
assumeDynamicRoutingIsEnabled();
mCallback = new CarAudioManagerTestUtils.SyncCarVolumeCallback();
@@ -1895,6 +1897,11 @@
mCarAudioManager.isAudioFeatureEnabled(AUDIO_FEATURE_DYNAMIC_ROUTING));
}
+ private void assumeOemServiceIsDisabled() {
+ assumeFalse("Requires OEM service disabled",
+ mCarAudioManager.isAudioFeatureEnabled(AUDIO_FEATURE_OEM_AUDIO_SERVICE));
+ }
+
private void assumeVolumeGroupMutingIsEnabled() {
assumeTrue("Requires volume group muting",
mCarAudioManager.isAudioFeatureEnabled(AUDIO_FEATURE_VOLUME_GROUP_MUTING));
diff --git a/tests/tests/car_builtin/src/android/car/cts/builtin/app/TaskInfoHelperTest.java b/tests/tests/car_builtin/src/android/car/cts/builtin/app/TaskInfoHelperTest.java
index 5eb6bb7..d579173 100644
--- a/tests/tests/car_builtin/src/android/car/cts/builtin/app/TaskInfoHelperTest.java
+++ b/tests/tests/car_builtin/src/android/car/cts/builtin/app/TaskInfoHelperTest.java
@@ -31,10 +31,14 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.graphics.Point;
import android.graphics.Rect;
import android.server.wm.ActivityManagerTestBase;
import android.util.Log;
import android.view.View;
+import android.view.WindowManager;
+import android.view.DisplayCutout;
+import android.view.Display;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
@@ -136,8 +140,16 @@
@Test
public void testGetBounds() throws Exception {
TaskInfo taskInfo = getTaskInfo(mTestActivity.getTaskId());
-
Rect bounds = TaskInfoHelper.getBounds(taskInfo);
+ Display display = mTestActivity.getDisplay();
+ DisplayCutout cutout = display.getCutout();
+
+ if (cutout != null) {
+ Rect safeBounds = new Rect(bounds);
+ safeBounds.inset(cutout.getSafeInsetLeft(), cutout.getSafeInsetTop(),
+ cutout.getSafeInsetRight(), cutout.getSafeInsetBottom());
+ bounds = safeBounds;
+ }
View testActivityDecorView = mTestActivity.getWindow().getDecorView();
assertThat(bounds).isNotNull();
diff --git a/tests/tests/car_permission_tests/src/android/car/cts/permissiontest/media/CarAudioManagerPermissionTest.java b/tests/tests/car_permission_tests/src/android/car/cts/permissiontest/media/CarAudioManagerPermissionTest.java
index 0e44d37..8f24ff9 100644
--- a/tests/tests/car_permission_tests/src/android/car/cts/permissiontest/media/CarAudioManagerPermissionTest.java
+++ b/tests/tests/car_permission_tests/src/android/car/cts/permissiontest/media/CarAudioManagerPermissionTest.java
@@ -20,11 +20,15 @@
import static android.car.Car.PERMISSION_CAR_CONTROL_AUDIO_SETTINGS;
import static android.car.Car.PERMISSION_CAR_CONTROL_AUDIO_VOLUME;
import static android.car.media.CarAudioManager.AUDIO_FEATURE_DYNAMIC_ROUTING;
+import static android.car.media.CarAudioManager.AUDIO_FEATURE_OEM_AUDIO_SERVICE;
import static android.car.media.CarAudioManager.PRIMARY_AUDIO_ZONE;
import static android.media.AudioAttributes.USAGE_MEDIA;
+
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
+
import static org.junit.Assert.assertThrows;
+import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeTrue;
import android.app.UiAutomation;
@@ -307,6 +311,7 @@
@ApiTest(apis = {
"android.car.media.CarAudioManager#unregisterCarVolumeCallback(CarVolumeCallback)"})
public void unregisterCarVolumeCallback_withoutPermission_receivesCallback() {
+ assumeOemServiceIsDisabled();
assumeDynamicRoutingIsEnabled();
mCallback = new CarAudioManagerTestUtils.SyncCarVolumeCallback();
runWithCarControlAudioVolumePermission(
@@ -339,6 +344,11 @@
mCarAudioManager.isAudioFeatureEnabled(AUDIO_FEATURE_DYNAMIC_ROUTING));
}
+ private void assumeOemServiceIsDisabled() {
+ assumeFalse("Requires OEM service disabled",
+ mCarAudioManager.isAudioFeatureEnabled(AUDIO_FEATURE_OEM_AUDIO_SERVICE));
+ }
+
private void injectVolumeDownKeyEvent() {
injectKeyEvent(KeyEvent.KEYCODE_VOLUME_DOWN);
}
diff --git a/tests/tests/content/src/android/content/pm/cts/LauncherAppsForHiddenProfilesTest.java b/tests/tests/content/src/android/content/pm/cts/LauncherAppsForHiddenProfilesTest.java
index 757c8fa..24b18cca 100644
--- a/tests/tests/content/src/android/content/pm/cts/LauncherAppsForHiddenProfilesTest.java
+++ b/tests/tests/content/src/android/content/pm/cts/LauncherAppsForHiddenProfilesTest.java
@@ -237,7 +237,7 @@
new TestLauncherCallback(targetUser.userHandle(), mTestApp.packageName());
mLauncherApps.registerCallback(callback, new Handler(Looper.getMainLooper()));
triggerCallbacks(targetUser);
- long timeoutSec = 10;
+ long timeoutSec = 15;
try {
assertThat(callback.mPackageAdded.await(timeoutSec, TimeUnit.SECONDS))
.isEqualTo(received);
diff --git a/tests/tests/content/src/android/content/pm/cts/PackageInstallerArchiveTest.java b/tests/tests/content/src/android/content/pm/cts/PackageInstallerArchiveTest.java
index 4e2036c..eabcd32 100644
--- a/tests/tests/content/src/android/content/pm/cts/PackageInstallerArchiveTest.java
+++ b/tests/tests/content/src/android/content/pm/cts/PackageInstallerArchiveTest.java
@@ -902,7 +902,7 @@
mContext.startActivity(createTestActivityIntent(),
options.toBundle());
mUiDevice.wait(Until.hasObject(By.clazz(PACKAGE_NAME, ACTIVITY_NAME)),
- TimeUnit.SECONDS.toMillis(5));
+ TimeUnit.SECONDS.toMillis(10));
}
private Intent createTestActivityIntent() {
diff --git a/tests/tests/display/src/android/display/cts/DisplayTest.java b/tests/tests/display/src/android/display/cts/DisplayTest.java
index 48824c8..2d835e2 100644
--- a/tests/tests/display/src/android/display/cts/DisplayTest.java
+++ b/tests/tests/display/src/android/display/cts/DisplayTest.java
@@ -669,10 +669,16 @@
assertEquals(SECONDARY_DISPLAY_HEIGHT, outMetrics.heightPixels);
// The scale is in [0.1, 3], and density is the scale factor.
- assertTrue(SCALE_DENSITY_LOWER_BOUND <= outMetrics.density
- && outMetrics.density <= SCALE_DENSITY_UPPER_BOUND);
- assertTrue(SCALE_DENSITY_LOWER_BOUND <= outMetrics.scaledDensity
- && outMetrics.scaledDensity <= SCALE_DENSITY_UPPER_BOUND);
+ assertTrue("Density is out of bounds: " + outMetrics.density +
+ " (Expected: [" + SCALE_DENSITY_LOWER_BOUND + ", "
+ + SCALE_DENSITY_UPPER_BOUND + "])",
+ SCALE_DENSITY_LOWER_BOUND <= outMetrics.density
+ && outMetrics.density <= SCALE_DENSITY_UPPER_BOUND);
+ assertTrue("ScaledDensity is out of bounds: " + outMetrics.scaledDensity +
+ " (Expected: [" + SCALE_DENSITY_LOWER_BOUND + ", "
+ + SCALE_DENSITY_UPPER_BOUND + "])",
+ SCALE_DENSITY_LOWER_BOUND <= outMetrics.scaledDensity
+ && outMetrics.scaledDensity <= SCALE_DENSITY_UPPER_BOUND);
assertEquals(SECONDARY_DISPLAY_DPI, outMetrics.densityDpi);
assertEquals((float)SECONDARY_DISPLAY_DPI, outMetrics.xdpi, 0.0001f);
diff --git a/tests/tests/hibernation/src/android/hibernation/cts/AppHibernationIntegrationTest.kt b/tests/tests/hibernation/src/android/hibernation/cts/AppHibernationIntegrationTest.kt
index 4daa2a7e..5a09988 100644
--- a/tests/tests/hibernation/src/android/hibernation/cts/AppHibernationIntegrationTest.kt
+++ b/tests/tests/hibernation/src/android/hibernation/cts/AppHibernationIntegrationTest.kt
@@ -98,6 +98,7 @@
const val HIBERNATION_ENABLED_KEY = "app_hibernation_enabled"
const val CMD_KILL = "am kill %s"
+ const val MAX_SWIPES = 10
@JvmStatic
@BeforeClass
@@ -381,6 +382,7 @@
assertTrue("No scrollable exists on screen", scrollableExists)
}
while (!toggleFound && scrollableExists) {
+ scrollableObject.scrollToEnd(MAX_SWIPES)
toggleFound = scrollableObject.scrollTextIntoView(title) ||
UiAutomatorUtils2.waitFindObjectOrNull(By.text(title)) != null
scrollableObject = UiScrollable(UiSelector().scrollable(true).instance(++i))
diff --git a/tests/tests/hibernation/src/android/hibernation/cts/AppHibernationUtils.kt b/tests/tests/hibernation/src/android/hibernation/cts/AppHibernationUtils.kt
index 5a7c936..8033e36 100644
--- a/tests/tests/hibernation/src/android/hibernation/cts/AppHibernationUtils.kt
+++ b/tests/tests/hibernation/src/android/hibernation/cts/AppHibernationUtils.kt
@@ -444,3 +444,12 @@
}
}
}
+
+fun scrollToLabel(label: String) {
+ val uiDevice = UiAutomatorUtils2.getUiDevice()
+
+ if (!uiDevice.hasObject(By.text(label))) {
+ var scrollableObject = UiScrollable(UiSelector().scrollable(true))
+ scrollableObject.scrollTextIntoView(label)
+ }
+}
diff --git a/tests/tests/hibernation/src/android/hibernation/cts/AutoRevokeTest.kt b/tests/tests/hibernation/src/android/hibernation/cts/AutoRevokeTest.kt
index 6e0d86d..0397658 100644
--- a/tests/tests/hibernation/src/android/hibernation/cts/AutoRevokeTest.kt
+++ b/tests/tests/hibernation/src/android/hibernation/cts/AutoRevokeTest.kt
@@ -691,6 +691,7 @@
.addFlags(FLAG_ACTIVITY_CLEAR_TASK))
waitForIdle()
+ scrollToLabel("Permissions")
click("Permissions")
}
diff --git a/tests/tests/keystore/src/android/keystore/cts/CipherTest.java b/tests/tests/keystore/src/android/keystore/cts/CipherTest.java
index 9f622c4..d41657d 100644
--- a/tests/tests/keystore/src/android/keystore/cts/CipherTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/CipherTest.java
@@ -1975,22 +1975,23 @@
}
private ImportedKey importDefaultKatKey(
- String transformation, int purposes, boolean ivProvidedWhenEncrypting)
- throws Exception {
+ String transformation, @KeyProperties.PurposeEnum int purposes,
+ boolean ivProvidedWhenEncrypting) throws Exception {
KeyProtection importParams = TestUtils.getMinimalWorkingImportParametersForCipheringWith(
transformation, purposes, ivProvidedWhenEncrypting);
return importDefaultKatKey(transformation, importParams);
}
private Collection<ImportedKey> importKatKeys(
- String transformation, int purposes, boolean ivProvidedWhenEncrypting)
- throws Exception {
+ String transformation, @KeyProperties.PurposeEnum int purposes,
+ boolean ivProvidedWhenEncrypting) throws Exception {
return importKatKeys(transformation, purposes, ivProvidedWhenEncrypting, false, false);
}
private Collection<ImportedKey> importKatKeys(
- String transformation, int purposes, boolean ivProvidedWhenEncrypting,
- boolean isUnlockedDeviceRequired, boolean isUserAuthRequired) throws Exception {
+ String transformation, @KeyProperties.PurposeEnum int purposes,
+ boolean ivProvidedWhenEncrypting, boolean isUnlockedDeviceRequired,
+ boolean isUserAuthRequired) throws Exception {
KeyProtection importParams = TestUtils.getMinimalWorkingImportParametersForCipheringWith(
transformation, purposes, ivProvidedWhenEncrypting, isUnlockedDeviceRequired,
isUserAuthRequired);
diff --git a/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java b/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java
index 48fc2d7..3386068 100644
--- a/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java
@@ -26,12 +26,12 @@
import static android.keystore.cts.AuthorizationList.KM_DIGEST_SHA_2_512;
import static android.keystore.cts.AuthorizationList.KM_ORIGIN_GENERATED;
import static android.keystore.cts.AuthorizationList.KM_ORIGIN_UNKNOWN;
-import static android.keystore.cts.AuthorizationList.KM_PURPOSE_DECRYPT;
-import static android.keystore.cts.AuthorizationList.KM_PURPOSE_ENCRYPT;
-import static android.keystore.cts.AuthorizationList.KM_PURPOSE_SIGN;
-import static android.keystore.cts.AuthorizationList.KM_PURPOSE_VERIFY;
import static android.keystore.cts.RootOfTrust.KM_VERIFIED_BOOT_VERIFIED;
import static android.security.keymaster.KeymasterDefs.KM_PURPOSE_AGREE_KEY;
+import static android.security.keymaster.KeymasterDefs.KM_PURPOSE_ENCRYPT;
+import static android.security.keymaster.KeymasterDefs.KM_PURPOSE_DECRYPT;
+import static android.security.keymaster.KeymasterDefs.KM_PURPOSE_SIGN;
+import static android.security.keymaster.KeymasterDefs.KM_PURPOSE_VERIFY;
import static android.security.keystore.KeyProperties.DIGEST_SHA256;
import static android.security.keystore.KeyProperties.ENCRYPTION_PADDING_NONE;
import static android.security.keystore.KeyProperties.ENCRYPTION_PADDING_RSA_OAEP;
@@ -209,8 +209,8 @@
if (getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_PC))
return;
- final int[] purposes = {
- KM_PURPOSE_SIGN, KM_PURPOSE_VERIFY, KM_PURPOSE_SIGN | KM_PURPOSE_VERIFY
+ final @KeyProperties.PurposeEnum int[] purposes = {
+ PURPOSE_SIGN, PURPOSE_VERIFY, PURPOSE_SIGN | PURPOSE_VERIFY
};
final boolean[] devicePropertiesAttestationValues = {true, false};
final boolean[] includeValidityDatesValues = {true, false};
@@ -331,8 +331,14 @@
boolean[] devicePropertiesAttestationValues = {true, false};
for (boolean devicePropertiesAttestation : devicePropertiesAttestationValues) {
try {
- testEcAttestation(new byte[129], true /* includeValidityDates */, "secp256r1", 256,
- KM_PURPOSE_SIGN, devicePropertiesAttestation, isStrongBox);
+ testEcAttestation(
+ new byte[129],
+ true /* includeValidityDates */,
+ "secp256r1",
+ 256,
+ PURPOSE_SIGN,
+ devicePropertiesAttestation,
+ isStrongBox);
fail("Attestation challenges larger than 128 bytes should be rejected");
} catch (ProviderException e) {
KeyStoreException cause = (KeyStoreException) e.getCause();
@@ -657,7 +663,7 @@
if (getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_PC))
return;
- final int[] purposes = {
+ final @KeyProperties.PurposeEnum int[] purposes = {
PURPOSE_SIGN | PURPOSE_VERIFY,
PURPOSE_ENCRYPT | PURPOSE_DECRYPT,
};
@@ -726,7 +732,7 @@
for (boolean devicePropertiesAttestation : devicePropertiesAttestationValues) {
for (int keySize : keySizes) {
for (byte[] challenge : challenges) {
- for (int purpose : purposes) {
+ for (@KeyProperties.PurposeEnum int purpose : purposes) {
if (isEncryptionPurpose(purpose)) {
testRsaAttestations(keySize, challenge, purpose, encryptionPaddingModes,
devicePropertiesAttestation, isStrongBox);
@@ -945,9 +951,9 @@
}
}
- private void testRsaAttestations(int keySize, byte[] challenge, int purpose,
- String[][] paddingModes, boolean devicePropertiesAttestation,
- boolean isStrongBox) throws Exception {
+ private void testRsaAttestations(int keySize, byte[] challenge,
+ @KeyProperties.PurposeEnum int purpose, String[][] paddingModes,
+ boolean devicePropertiesAttestation, boolean isStrongBox) throws Exception {
for (String[] paddings : paddingModes) {
try {
testRsaAttestation(challenge, true /* includeValidityDates */, keySize, purpose,
@@ -1056,7 +1062,7 @@
@SuppressWarnings("deprecation")
private void testCurve25519Attestations(String curve, byte[] challenge,
- int purpose, boolean devicePropertiesAttestation)
+ @KeyProperties.PurposeEnum int purpose, boolean devicePropertiesAttestation)
throws Exception {
Log.i(TAG, curve + " curve key attestation with: "
+ " / challenge " + Arrays.toString(challenge)
@@ -1107,8 +1113,8 @@
@SuppressWarnings("deprecation")
private void testRsaAttestation(byte[] challenge, boolean includeValidityDates, int keySize,
- int purposes, String[] paddingModes, boolean devicePropertiesAttestation,
- boolean isStrongBox) throws Exception {
+ @KeyProperties.PurposeEnum int purposes, String[] paddingModes,
+ boolean devicePropertiesAttestation, boolean isStrongBox) throws Exception {
Log.i(TAG, "RSA key attestation with: challenge " + Arrays.toString(challenge) +
" / includeValidityDates " + includeValidityDates + " / keySize " + keySize +
" / purposes " + purposes + " / paddingModes " + Arrays.toString(paddingModes) +
@@ -1136,7 +1142,7 @@
// Because we sometimes set "no padding", allow non-randomized encryption.
builder.setRandomizedEncryptionRequired(false);
}
- if (isSignaturePurpose(purposes)) {
+ if (isSignaturePurpose(purposes) || isVerifyPurpose(purposes)) {
builder.setSignaturePaddings(paddingModes);
}
@@ -1163,10 +1169,22 @@
}
}
- private void checkKeyUsage(X509Certificate attestationCert, int purposes) {
+ private void checkKeyUsage(X509Certificate attestationCert,
+ @KeyProperties.PurposeEnum int purposes) {
boolean[] expectedKeyUsage = new boolean[KEY_USAGE_BITSTRING_LENGTH];
+ boolean[] certKeyUsage = attestationCert.getKeyUsage();
+
+ if (isVerifyPurpose(purposes)) {
+ // Some implementations may set the signature key usage
+ // bit when PURPOSE_VERIFY is used, but some do not. Allow
+ // for either possibility by updating the expected value of
+ // the bit to match what's actually present.
+ expectedKeyUsage[KEY_USAGE_DIGITAL_SIGNATURE_BIT_OFFSET] =
+ certKeyUsage[KEY_USAGE_DIGITAL_SIGNATURE_BIT_OFFSET];
+ }
if (isSignaturePurpose(purposes)) {
+ // A PURPOSE_SIGN key should definitely have the bit set.
expectedKeyUsage[KEY_USAGE_DIGITAL_SIGNATURE_BIT_OFFSET] = true;
}
if (isEncryptionPurpose(purposes)) {
@@ -1177,13 +1195,13 @@
expectedKeyUsage[KEY_USAGE_KEY_AGREE_BIT_OFFSET] = true;
}
assertThat("Attested certificate has unexpected key usage.",
- attestationCert.getKeyUsage(), is(expectedKeyUsage));
+ certKeyUsage, is(expectedKeyUsage));
}
@SuppressWarnings("deprecation")
private void testEcAttestation(byte[] challenge, boolean includeValidityDates, String ecCurve,
- int keySize, int purposes, boolean devicePropertiesAttestation,
- boolean isStrongBox) throws Exception {
+ int keySize, @KeyProperties.PurposeEnum int purposes,
+ boolean devicePropertiesAttestation, boolean isStrongBox) throws Exception {
Log.i(TAG, "EC key attestation with: challenge " + Arrays.toString(challenge) +
" / includeValidityDates " + includeValidityDates + " / ecCurve " + ecCurve +
" / keySize " + keySize + " / purposes " + purposes +
@@ -1305,7 +1323,8 @@
assertNull(attestation.getSoftwareEnforced().getSerialNumber());
}
- private void checkKeyIndependentAttestationInfo(byte[] challenge, int purposes,
+ private void checkKeyIndependentAttestationInfo(byte[] challenge,
+ @KeyProperties.PurposeEnum int purposes,
Date startTime, boolean includesValidityDates,
boolean devicePropertiesAttestation, Attestation attestation)
throws NoSuchAlgorithmException, NameNotFoundException {
@@ -1318,10 +1337,10 @@
devicePropertiesAttestation, attestation);
}
- private void checkKeyIndependentAttestationInfo(byte[] challenge, int purposes,
- Set digests, Date startTime, boolean includesValidityDates,
- boolean devicePropertiesAttestation, Attestation attestation)
- throws NoSuchAlgorithmException, NameNotFoundException {
+ private void checkKeyIndependentAttestationInfo(byte[] challenge,
+ @KeyProperties.PurposeEnum int purposes, Set digests, Date startTime,
+ boolean includesValidityDates, boolean devicePropertiesAttestation,
+ Attestation attestation) throws NoSuchAlgorithmException, NameNotFoundException {
checkUnexpectedOids(attestation);
checkAttestationSecurityLevelDependentParams(attestation);
assertNotNull("Attestation challenge must not be null.",
@@ -1539,7 +1558,8 @@
}
}
- private Set<Integer> checkPurposes(Attestation attestation, int purposes) {
+ private Set<Integer> checkPurposes(Attestation attestation,
+ @KeyProperties.PurposeEnum int purposes) {
Set<Integer> expectedPurposes = buildPurposeSet(purposes);
if (attestation.getKeymasterSecurityLevel() == KM_SECURITY_LEVEL_SOFTWARE
|| attestation.getKeymasterVersion() == 0) {
@@ -1855,19 +1875,23 @@
assertNull(nonKeyDetailsList.getPaddingModes());
}
- private boolean isEncryptionPurpose(int purposes) {
+ private boolean isEncryptionPurpose(@KeyProperties.PurposeEnum int purposes) {
return (purposes & PURPOSE_DECRYPT) != 0 || (purposes & PURPOSE_ENCRYPT) != 0;
}
- private boolean isSignaturePurpose(int purposes) {
- return (purposes & PURPOSE_SIGN) != 0 || (purposes & PURPOSE_VERIFY) != 0;
+ private boolean isSignaturePurpose(@KeyProperties.PurposeEnum int purposes) {
+ return (purposes & PURPOSE_SIGN) != 0;
}
- private boolean isAgreeKeyPurpose(int purposes) {
+ private boolean isVerifyPurpose(@KeyProperties.PurposeEnum int purposes) {
+ return (purposes & PURPOSE_VERIFY) != 0;
+ }
+
+ private boolean isAgreeKeyPurpose(@KeyProperties.PurposeEnum int purposes) {
return (purposes & PURPOSE_AGREE_KEY) != 0;
}
- private ImmutableSet<Integer> buildPurposeSet(int purposes) {
+ private ImmutableSet<Integer> buildPurposeSet(@KeyProperties.PurposeEnum int purposes) {
ImmutableSet.Builder<Integer> builder = ImmutableSet.builder();
if ((purposes & PURPOSE_SIGN) != 0)
builder.add(KM_PURPOSE_SIGN);
diff --git a/tests/tests/keystore/src/android/keystore/cts/KeyFactoryTest.java b/tests/tests/keystore/src/android/keystore/cts/KeyFactoryTest.java
index 0a5bfba..8495b5b 100644
--- a/tests/tests/keystore/src/android/keystore/cts/KeyFactoryTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/KeyFactoryTest.java
@@ -130,7 +130,8 @@
KeyProperties.DIGEST_SHA224,
KeyProperties.DIGEST_SHA384,
KeyProperties.DIGEST_SHA512};
- int purposes = KeyProperties.PURPOSE_DECRYPT | KeyProperties.PURPOSE_SIGN;
+ @KeyProperties.PurposeEnum int purposes =
+ KeyProperties.PURPOSE_DECRYPT | KeyProperties.PURPOSE_SIGN;
KeyPairGenerator keyGenerator =
KeyPairGenerator.getInstance(algorithm, EXPECTED_PROVIDER_NAME);
keyGenerator.initialize(new KeyGenParameterSpec.Builder("test1", purposes)
diff --git a/tests/tests/keystore/src/android/keystore/cts/KeyGeneratorTest.java b/tests/tests/keystore/src/android/keystore/cts/KeyGeneratorTest.java
index 794f4da..b4ed59a 100644
--- a/tests/tests/keystore/src/android/keystore/cts/KeyGeneratorTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/KeyGeneratorTest.java
@@ -731,7 +731,7 @@
new String[] {KeyProperties.ENCRYPTION_PADDING_PKCS7,
KeyProperties.ENCRYPTION_PADDING_NONE};
String[] digests;
- int purposes;
+ @KeyProperties.PurposeEnum int purposes;
if (TestUtils.isHmacAlgorithm(algorithm)) {
// HMAC key can only be authorized for one digest, the one implied by the key's
// JCA algorithm name.
@@ -753,7 +753,6 @@
.build());
SecretKey key = keyGenerator.generateKey();
assertEquals(algorithm, key.getAlgorithm());
-
KeyInfo keyInfo = TestUtils.getKeyInfo(key);
assertEquals(purposes, keyInfo.getPurposes());
TestUtils.assertContentsInAnyOrder(
@@ -923,7 +922,8 @@
return getWorkingSpec(0);
}
- private static KeyGenParameterSpec.Builder getWorkingSpec(int purposes) {
+ private static KeyGenParameterSpec.Builder getWorkingSpec(
+ @KeyProperties.PurposeEnum int purposes) {
return new KeyGenParameterSpec.Builder("test1", purposes);
}
diff --git a/tests/tests/keystore/src/android/keystore/cts/KeyPairGeneratorTest.java b/tests/tests/keystore/src/android/keystore/cts/KeyPairGeneratorTest.java
index fe3890f..7dcff38 100644
--- a/tests/tests/keystore/src/android/keystore/cts/KeyPairGeneratorTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/KeyPairGeneratorTest.java
@@ -376,7 +376,8 @@
KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1};
String[] digests =
new String[] {KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA1};
- int purposes = KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_ENCRYPT;
+ @KeyProperties.PurposeEnum int purposes =
+ KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_ENCRYPT;
KeyPairGenerator generator = getGenerator(algorithm);
generator.initialize(getWorkingSpec(purposes)
.setBlockModes(blockModes)
@@ -2152,7 +2153,7 @@
return getWorkingSpec(0);
}
- private KeyGenParameterSpec.Builder getWorkingSpec(int purposes) {
+ private KeyGenParameterSpec.Builder getWorkingSpec(@KeyProperties.PurposeEnum int purposes) {
return new KeyGenParameterSpec.Builder(TEST_ALIAS_1, purposes);
}
diff --git a/tests/tests/keystore/src/android/keystore/cts/SecretKeyFactoryTest.java b/tests/tests/keystore/src/android/keystore/cts/SecretKeyFactoryTest.java
index f9d97b1..70d9040 100644
--- a/tests/tests/keystore/src/android/keystore/cts/SecretKeyFactoryTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/SecretKeyFactoryTest.java
@@ -109,7 +109,7 @@
new String[] {KeyProperties.ENCRYPTION_PADDING_PKCS7,
KeyProperties.ENCRYPTION_PADDING_NONE};
String[] digests;
- int purposes;
+ @KeyProperties.PurposeEnum int purposes;
if (TestUtils.isHmacAlgorithm(algorithm)) {
String digest = TestUtils.getHmacAlgorithmDigest(algorithm);
digests = new String[] {digest};
diff --git a/tests/tests/keystore/src/android/keystore/cts/util/TestUtils.java b/tests/tests/keystore/src/android/keystore/cts/util/TestUtils.java
index 9359048..8957572 100644
--- a/tests/tests/keystore/src/android/keystore/cts/util/TestUtils.java
+++ b/tests/tests/keystore/src/android/keystore/cts/util/TestUtils.java
@@ -700,7 +700,8 @@
private static KeyProtection.Builder buildUponInternal(
KeyProtection spec, Integer newPurposes) {
- int purposes = (newPurposes == null) ? spec.getPurposes() : newPurposes;
+ @KeyProperties.PurposeEnum int purposes =
+ (newPurposes == null) ? spec.getPurposes() : newPurposes;
KeyProtection.Builder result = new KeyProtection.Builder(purposes);
result.setBlockModes(spec.getBlockModes());
if (spec.isDigestsSpecified()) {
@@ -739,7 +740,8 @@
private static KeyGenParameterSpec.Builder buildUponInternal(
KeyGenParameterSpec spec, Integer newPurposes) {
- int purposes = (newPurposes == null) ? spec.getPurposes() : newPurposes;
+ @KeyProperties.PurposeEnum int purposes =
+ (newPurposes == null) ? spec.getPurposes() : newPurposes;
KeyGenParameterSpec.Builder result =
new KeyGenParameterSpec.Builder(spec.getKeystoreAlias(), purposes);
if (spec.getKeySize() >= 0) {
@@ -1150,19 +1152,21 @@
}
public static KeyProtection getMinimalWorkingImportParametersForCipheringWith(
- String transformation, int purposes) {
+ String transformation, @KeyProperties.PurposeEnum int purposes) {
return getMinimalWorkingImportParametersForCipheringWith(transformation, purposes, false);
}
public static KeyProtection getMinimalWorkingImportParametersForCipheringWith(
- String transformation, int purposes, boolean ivProvidedWhenEncrypting) {
+ String transformation, @KeyProperties.PurposeEnum int purposes,
+ boolean ivProvidedWhenEncrypting) {
return getMinimalWorkingImportParametersForCipheringWith(transformation, purposes,
ivProvidedWhenEncrypting, false, false);
}
public static KeyProtection getMinimalWorkingImportParametersForCipheringWith(
- String transformation, int purposes, boolean ivProvidedWhenEncrypting,
- boolean isUnlockedDeviceRequired, boolean isUserAuthRequired) {
+ String transformation, @KeyProperties.PurposeEnum int purposes,
+ boolean ivProvidedWhenEncrypting, boolean isUnlockedDeviceRequired,
+ boolean isUserAuthRequired) {
String keyAlgorithm = TestUtils.getCipherKeyAlgorithm(transformation);
if (KeyProperties.KEY_ALGORITHM_AES.equalsIgnoreCase(keyAlgorithm)
|| KeyProperties.KEY_ALGORITHM_3DES.equalsIgnoreCase(keyAlgorithm)) {
diff --git a/tests/tests/match_flags/src/android/matchflags/cts/MatchFlagTests.java b/tests/tests/match_flags/src/android/matchflags/cts/MatchFlagTests.java
index aa9aa29..65c50a0 100644
--- a/tests/tests/match_flags/src/android/matchflags/cts/MatchFlagTests.java
+++ b/tests/tests/match_flags/src/android/matchflags/cts/MatchFlagTests.java
@@ -123,6 +123,7 @@
@Test
public void startNoBrowserRequireDefaultUnapproved() throws Exception {
assumeFalse("Skipping test for watch", FeatureUtil.isWatch());
+ assumeFalse("Skipping test for car", FeatureUtil.isAutomotive());
setDomainUserSelectionApproval(false);
startNoBrowserRequireDefaultInternal(false);
}
diff --git a/tests/tests/media/audio/Android.bp b/tests/tests/media/audio/Android.bp
index 28f7952..84f4a80 100644
--- a/tests/tests/media/audio/Android.bp
+++ b/tests/tests/media/audio/Android.bp
@@ -106,6 +106,7 @@
libs: [
"android.test.base",
"android.test.runner",
+ "android.car-test-stubs",
],
// Tag this module as a cts test artifact
test_suites: [
diff --git a/tests/tests/media/audio/src/android/media/audio/cts/AudioFocusTest.java b/tests/tests/media/audio/src/android/media/audio/cts/AudioFocusTest.java
index 931211a..6a871cf 100644
--- a/tests/tests/media/audio/src/android/media/audio/cts/AudioFocusTest.java
+++ b/tests/tests/media/audio/src/android/media/audio/cts/AudioFocusTest.java
@@ -30,6 +30,7 @@
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeTrue;
import android.Manifest;
@@ -37,6 +38,8 @@
import android.annotation.RawRes;
import android.app.Instrumentation;
import android.app.NotificationManager;
+import android.car.Car;
+import android.car.media.CarAudioManager;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.AssetFileDescriptor;
@@ -299,18 +302,27 @@
@Test
public void testAudioFocusRequestGainLoss() throws Exception {
+ // TODO(b/380497573): replace the skip directive with a verification that the focus
+ // policy is installed.
+ assumeOemServiceIsNotEnabled();
final AudioAttributes[] attributes = { ATTR_DRIVE_DIR, ATTR_MEDIA };
doTestTwoPlayersGainLoss(AudioManager.AUDIOFOCUS_GAIN, attributes, false /*no handler*/);
}
@Test
public void testAudioFocusRequestGainLossHandler() throws Exception {
+ // TODO(b/380497573): replace the skip directive with a verification that the focus
+ // policy is installed.
+ assumeOemServiceIsNotEnabled();
final AudioAttributes[] attributes = { ATTR_DRIVE_DIR, ATTR_MEDIA };
doTestTwoPlayersGainLoss(AudioManager.AUDIOFOCUS_GAIN, attributes, true /*with handler*/);
}
@Test
public void testAudioFocusRequestGainLossTransient() throws Exception {
+ // TODO(b/380497573): replace the skip directive with a verification that the focus
+ // policy is installed.
+ assumeOemServiceIsNotEnabled();
final AudioAttributes[] attributes = { ATTR_DRIVE_DIR, ATTR_MEDIA };
doTestTwoPlayersGainLoss(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT, attributes,
false /*no handler*/);
@@ -318,6 +330,9 @@
@Test
public void testAudioFocusRequestGainLossTransientHandler() throws Exception {
+ // TODO(b/380497573): replace the skip directive with a verification that the focus
+ // policy is installed.
+ assumeOemServiceIsNotEnabled();
final AudioAttributes[] attributes = { ATTR_DRIVE_DIR, ATTR_MEDIA };
doTestTwoPlayersGainLoss(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT, attributes,
true /*with handler*/);
@@ -352,6 +367,9 @@
@Test
public void testAudioFocusRequestA11y() throws Exception {
+ // TODO(b/380497573): replace the skip directive with a verification that the focus
+ // policy is installed.
+ assumeOemServiceIsNotEnabled();
final AudioAttributes[] attributes = {ATTR_DRIVE_DIR, ATTR_A11Y};
doTestTwoPlayersGainLoss(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE,
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE, attributes,
@@ -1268,6 +1286,27 @@
return mp;
}
+ private void assumeOemServiceIsNotEnabled() {
+ boolean oemAudioServiceEnabled = false;
+ if (isCar()) {
+ final Car car = Car.createCar(mContext);
+ try {
+ final CarAudioManager carAudioManager = car.getCarManager(CarAudioManager.class);
+ oemAudioServiceEnabled = carAudioManager.isAudioFeatureEnabled(
+ CarAudioManager.AUDIO_FEATURE_OEM_AUDIO_SERVICE);
+ } finally {
+ if (car != null) {
+ car.disconnect();
+ }
+ }
+ }
+ assumeFalse("OEM audio service is enabled", oemAudioServiceEnabled);
+ }
+
+ protected boolean isCar() {
+ return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
+ }
+
private static class FocusChangeListener implements OnAudioFocusChangeListener {
private final Object mLock = new Object();
private final Semaphore mChangeEventSignal = new Semaphore(0);
diff --git a/tests/tests/media/audio/src/android/media/audio/cts/VolumeShaperTest.java b/tests/tests/media/audio/src/android/media/audio/cts/VolumeShaperTest.java
index e510795..9d98f0f5 100644
--- a/tests/tests/media/audio/src/android/media/audio/cts/VolumeShaperTest.java
+++ b/tests/tests/media/audio/src/android/media/audio/cts/VolumeShaperTest.java
@@ -228,7 +228,7 @@
private MediaPlayer createMediaPlayer(boolean offloaded) {
// MP3 resource should be greater than 1m to introduce offloading
- final int RESOURCE_ID = R.raw.test1m1s;
+ final int RESOURCE_ID = R.raw.testmp3_2;
final MediaPlayer mediaPlayer = MediaPlayer.create(getContext(),
RESOURCE_ID,
diff --git a/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/MediaActivityTest.java b/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/MediaActivityTest.java
index 769d1ed5..9f4f390 100644
--- a/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/MediaActivityTest.java
+++ b/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/MediaActivityTest.java
@@ -39,10 +39,12 @@
import android.view.KeyEvent;
import androidx.test.core.app.ActivityScenario;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;
import androidx.test.platform.app.InstrumentationRegistry;
+import com.android.bedstead.harrier.BedsteadJUnit4;
+import com.android.bedstead.harrier.UserType;
+import com.android.bedstead.harrier.annotations.UserTest;
import com.android.compatibility.common.util.FrameworkSpecificTest;
import com.android.compatibility.common.util.NonMainlineTest;
import com.android.compatibility.common.util.SystemUtil;
@@ -60,13 +62,11 @@
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
-/**
- * Test {@link MediaSessionTestActivity} which has called {@link Activity#setMediaController}.
- */
+/** Test {@link MediaSessionTestActivity} which has called {@link Activity#setMediaController}. */
@FrameworkSpecificTest
@NonMainlineTest
@LargeTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(BedsteadJUnit4.class)
public class MediaActivityTest {
private static final String TAG = "MediaActivityTest";
private static final int WAIT_TIME_MS = 5000;
@@ -183,10 +183,9 @@
}
}
- /**
- * Tests whether volume key changes volume with the session's stream.
- */
+ /** Tests whether volume key changes volume with the session's stream. */
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testVolumeKey_whileSessionAlive() throws Exception {
assumeTrue(/* message= */ "Test skipped on automotive target",
!isAutomotive());
@@ -215,10 +214,11 @@
}
/**
- * Tests whether volume key changes a stream volume even after the session is released,
- * without being ignored.
+ * Tests whether volume key changes a stream volume even after the session is released, without
+ * being ignored.
*/
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testVolumeKey_afterSessionReleased() throws Exception {
assumeTrue(/* message= */ "Test skipped on automotive target",
!isAutomotive());
@@ -248,6 +248,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testMediaKey_whileSessionAlive() throws Exception {
int testKeyEvent = KeyEvent.KEYCODE_MEDIA_PLAY;
@@ -270,6 +271,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testMediaKey_whileSessionReleased() throws Exception {
int testKeyEvent = KeyEvent.KEYCODE_MEDIA_PLAY;
diff --git a/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/MediaBrowserServiceTest.java b/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/MediaBrowserServiceTest.java
index f61ba15..24e9d39 100644
--- a/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/MediaBrowserServiceTest.java
+++ b/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/MediaBrowserServiceTest.java
@@ -52,9 +52,11 @@
import android.service.media.MediaBrowserService.BrowserRoot;
import androidx.test.core.app.ApplicationProvider;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;
+import com.android.bedstead.harrier.BedsteadJUnit4;
+import com.android.bedstead.harrier.UserType;
+import com.android.bedstead.harrier.annotations.UserTest;
import com.android.compatibility.common.util.FrameworkSpecificTest;
import com.android.compatibility.common.util.NonMainlineTest;
import com.android.media.flags.Flags;
@@ -71,12 +73,10 @@
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
-/**
- * Test {@link android.service.media.MediaBrowserService}.
- */
+/** Test {@link android.service.media.MediaBrowserService}. */
@FrameworkSpecificTest
@NonMainlineTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(BedsteadJUnit4.class)
@AppModeNonSdkSandbox(reason = "SDK sandbox does not need MediaBrowser.")
public class MediaBrowserServiceTest {
@@ -178,12 +178,14 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testGetSessionToken() {
assertThat(mMediaBrowserService.getSessionToken())
.isEqualTo(StubMediaBrowserService.sSession.getSessionToken());
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testNotifyChildrenChanged() throws Exception {
getInstrumentation().runOnMainSync(()-> {
mMediaBrowser.subscribe(StubMediaBrowserService.MEDIA_ID_ROOT, mSubscriptionCallback);
@@ -196,6 +198,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testNotifyChildrenChangedWithNullOptionsThrowsIAE() {
assertThrows(IllegalArgumentException.class,
() -> mMediaBrowserService.notifyChildrenChanged(
@@ -203,6 +206,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testNotifyChildrenChangedWithPagination() {
final int pageSize = 5;
final int page = 2;
@@ -242,6 +246,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testDelayedNotifyChildrenChanged() throws Exception {
getInstrumentation().runOnMainSync(()-> {
mMediaBrowser.subscribe(StubMediaBrowserService.MEDIA_ID_CHILDREN_DELAYED,
@@ -262,6 +267,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testDelayedItem() throws Exception {
getInstrumentation().runOnMainSync(()-> {
mMediaBrowser.getItem(StubMediaBrowserService.MEDIA_ID_CHILDREN_DELAYED,
@@ -274,6 +280,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testGetBrowserInfo() throws Exception {
// StubMediaBrowserService stores the browser info in its onGetRoot().
assertThat(compareRemoteUserInfo(mBrowserInfo, StubMediaBrowserService.sBrowserInfo))
@@ -297,6 +304,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testBrowserRoot() {
final String id = "test-id";
final String key = "test-key";
@@ -314,6 +322,7 @@
* {@link MediaBrowser} on the remote process due to binder buffer overflow.
*/
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testSeriesOfNotifyChildrenChanged() throws Exception {
String parentMediaId = "testSeriesOfNotifyChildrenChanged";
int numberOfCalls = 100;
@@ -347,6 +356,7 @@
@RequiresFlagsEnabled(Flags.FLAG_ENABLE_NULL_SESSION_IN_MEDIA_BROWSER_SERVICE)
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testSetNullSessionToken() {
MediaBrowserCallbackImpl browserCallback = new MediaBrowserCallbackImpl();
ComponentName componentName = new ComponentName(mContext, SimpleMediaBrowserService.class);
diff --git a/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/MediaBrowserTest.java b/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/MediaBrowserTest.java
index 48c11eb..89586e0 100644
--- a/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/MediaBrowserTest.java
+++ b/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/MediaBrowserTest.java
@@ -27,9 +27,11 @@
import android.os.Bundle;
import android.platform.test.annotations.AppModeNonSdkSandbox;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;
+import com.android.bedstead.harrier.BedsteadJUnit4;
+import com.android.bedstead.harrier.UserType;
+import com.android.bedstead.harrier.annotations.UserTest;
import com.android.compatibility.common.util.FrameworkSpecificTest;
import com.android.compatibility.common.util.NonMainlineTest;
import com.android.compatibility.common.util.PollingCheck;
@@ -46,12 +48,10 @@
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
-/**
- * Test {@link android.media.browse.MediaBrowser}.
- */
+/** Test {@link android.media.browse.MediaBrowser}. */
@FrameworkSpecificTest
@NonMainlineTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(BedsteadJUnit4.class)
@AppModeNonSdkSandbox(reason = "SDK sandbox does not need MediaBrowser.")
public class MediaBrowserTest {
// The maximum time to wait for an operation.
@@ -135,6 +135,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testThrowingISEWhileNotConnected() throws Throwable {
resetCallbacks();
createMediaBrowser(TEST_BROWSER_SERVICE);
@@ -156,6 +157,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testConnectTwice() throws Throwable {
resetCallbacks();
createMediaBrowser(TEST_BROWSER_SERVICE);
@@ -167,6 +169,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testConnectionFailed() throws Throwable {
resetCallbacks();
createMediaBrowser(TEST_INVALID_BROWSER_SERVICE);
@@ -184,6 +187,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testReconnection() throws Throwable {
createMediaBrowser(TEST_BROWSER_SERVICE);
@@ -235,6 +239,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testConnectionCallbackNotCalledAfterDisconnect() throws Throwable {
createMediaBrowser(TEST_BROWSER_SERVICE);
runOnMainThread(() -> {
@@ -257,6 +262,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testSubscribe() throws Throwable {
resetCallbacks();
createMediaBrowser(TEST_BROWSER_SERVICE);
@@ -298,6 +304,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testSubscribeWithIllegalArguments() throws Throwable {
createMediaBrowser(TEST_BROWSER_SERVICE);
@@ -326,6 +333,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testSubscribeWithOptions() throws Throwable {
createMediaBrowser(TEST_BROWSER_SERVICE);
connectMediaBrowserService();
@@ -385,6 +393,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testSubscribeInvalidItem() throws Throwable {
resetCallbacks();
createMediaBrowser(TEST_BROWSER_SERVICE);
@@ -403,6 +412,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testSubscribeInvalidItemWithOptions() throws Throwable {
resetCallbacks();
createMediaBrowser(TEST_BROWSER_SERVICE);
@@ -432,6 +442,7 @@
@Ignore // TODO(b/291800179): Diagnose flakiness and re-enable.
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testSubscriptionCallbackNotCalledAfterDisconnect() throws Throwable {
createMediaBrowser(TEST_BROWSER_SERVICE);
connectMediaBrowserService();
@@ -453,6 +464,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testUnsubscribeWithIllegalArguments() throws Throwable {
createMediaBrowser(TEST_BROWSER_SERVICE);
runOnMainThread(() -> {
@@ -474,6 +486,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testUnsubscribeForMultipleSubscriptions() throws Throwable {
createMediaBrowser(TEST_BROWSER_SERVICE);
connectMediaBrowserService();
@@ -522,6 +535,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testUnsubscribeWithSubscriptionCallbackForMultipleSubscriptions() throws Throwable {
createMediaBrowser(TEST_BROWSER_SERVICE);
connectMediaBrowserService();
@@ -588,6 +602,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testGetItem() throws Throwable {
resetCallbacks();
createMediaBrowser(TEST_BROWSER_SERVICE);
@@ -607,6 +622,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testGetItemThrowsIAE() throws Throwable {
resetCallbacks();
createMediaBrowser(TEST_BROWSER_SERVICE);
@@ -630,6 +646,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testGetItemWhileNotConnected() throws Throwable {
resetCallbacks();
createMediaBrowser(TEST_BROWSER_SERVICE);
@@ -650,6 +667,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testGetItemFailure() throws Throwable {
resetCallbacks();
createMediaBrowser(TEST_BROWSER_SERVICE);
@@ -668,6 +686,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testItemCallbackNotCalledAfterDisconnect() throws Throwable {
createMediaBrowser(TEST_BROWSER_SERVICE);
connectMediaBrowserService();
diff --git a/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/MediaCommunicationManagerTest.java b/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/MediaCommunicationManagerTest.java
index 5b92800..aa73193 100644
--- a/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/MediaCommunicationManagerTest.java
+++ b/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/MediaCommunicationManagerTest.java
@@ -22,6 +22,7 @@
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
+import android.Manifest;
import android.content.Context;
import android.media.MediaCommunicationManager;
import android.media.MediaSession2;
@@ -31,7 +32,10 @@
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SdkSuppress;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
+
+import com.android.bedstead.harrier.BedsteadJUnit4;
+import com.android.bedstead.harrier.UserType;
+import com.android.bedstead.harrier.annotations.UserTest;
import org.junit.After;
import org.junit.Before;
@@ -47,10 +51,8 @@
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
-/**
- * Tests {@link android.media.MediaCommunicationManager}.
- */
-@RunWith(AndroidJUnit4.class)
+/** Tests {@link android.media.MediaCommunicationManager}. */
+@RunWith(BedsteadJUnit4.class)
@SmallTest
@SdkSuppress(minSdkVersion = 31, codeName = "S")
public class MediaCommunicationManagerTest {
@@ -73,12 +75,14 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testGetVersion() {
assertNotNull("Missing MediaCommunicationManager", mManager);
assertTrue(mManager.getVersion() > 0);
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testGetSession2Tokens() throws Exception {
// registerSessionCallback requires permission MEDIA_CONTENT_CONTROL
InstrumentationRegistry.getInstrumentation()
@@ -107,8 +111,12 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void registerSessionCallback_noMediaContentControlPermission_throwsSecurityException()
throws Exception {
+ InstrumentationRegistry.getInstrumentation()
+ .getUiAutomation()
+ .adoptShellPermissionIdentity(Manifest.permission.MANAGE_EXTERNAL_STORAGE);
Executor executor = Executors.newSingleThreadExecutor();
assertNotNull("Missing MediaCommunicationManager", mManager);
@@ -120,12 +128,12 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER}) // SystemApi. Requires full user. Don't run for work profile.
public void testManagerSessionCallback() throws Exception {
// registerSessionCallback requires permission MEDIA_CONTENT_CONTROL
InstrumentationRegistry.getInstrumentation()
.getUiAutomation()
.adoptShellPermissionIdentity(MEDIA_CONTENT_CONTROL);
-
Executor executor = Executors.newSingleThreadExecutor();
assertNotNull("Missing MediaCommunicationManager", mManager);
diff --git a/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/MediaController2Test.java b/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/MediaController2Test.java
index 8a21b1c..8e2171b 100644
--- a/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/MediaController2Test.java
+++ b/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/MediaController2Test.java
@@ -34,14 +34,20 @@
import android.os.HandlerThread;
import android.os.Process;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import androidx.test.platform.app.InstrumentationRegistry;
+import com.android.bedstead.harrier.BedsteadJUnit4;
+import com.android.bedstead.harrier.DeviceState;
+import com.android.bedstead.harrier.UserType;
+import com.android.bedstead.harrier.annotations.AfterClass;
+import com.android.bedstead.harrier.annotations.BeforeClass;
+import com.android.bedstead.harrier.annotations.UserTest;
+
import org.junit.After;
-import org.junit.AfterClass;
import org.junit.Before;
-import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -52,12 +58,13 @@
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
-/**
- * Tests {@link android.media.MediaController2}.
- */
-@RunWith(AndroidJUnit4.class)
+/** Tests {@link android.media.MediaController2}. */
+@RunWith(BedsteadJUnit4.class)
@SmallTest
public class MediaController2Test {
+
+ @ClassRule @Rule public static final DeviceState sDeviceState = new DeviceState();
+
private static final long WAIT_TIME_MS = 100L;
static final Object sTestLock = new Object();
@@ -145,6 +152,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testBuilder_withIllegalArguments() {
final Session2Token token = new Session2Token(
mContext, new ComponentName(mContext, this.getClass()));
@@ -179,6 +187,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testBuilder_setConnectionHints_withFrameworkParcelable() throws Exception {
final List<MediaSession2.ControllerInfo> controllerInfoList = new ArrayList<>();
final CountDownLatch latch = new CountDownLatch(1);
@@ -218,6 +227,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testBuilder_setConnectionHints_withCustomParcelable() {
final Session2Token token = new Session2Token(
mContext, new ComponentName(mContext, this.getClass()));
@@ -236,6 +246,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testCreatingControllerWithoutCallback() throws Exception {
try (MediaController2 controller =
new MediaController2.Builder(mContext, mSession.getToken()).build()) {
@@ -247,6 +258,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testGetConnectedToken() {
Controller2Callback controllerCallback = new Controller2Callback();
try (MediaController2 controller =
@@ -269,6 +281,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testCallback_onConnected_onDisconnected() {
Controller2Callback controllerCallback = new Controller2Callback();
try (MediaController2 controller =
@@ -285,6 +298,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testCallback_onSessionCommand() {
Controller2Callback controllerCallback = new Controller2Callback();
try (MediaController2 controller =
@@ -321,6 +335,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testCallback_onCommandResult() {
Controller2Callback controllerCallback = new Controller2Callback();
try (MediaController2 controller =
@@ -355,6 +370,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testCancelSessionCommand() {
Controller2Callback controllerCallback = new Controller2Callback();
try (MediaController2 controller =
diff --git a/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/MediaControllerTest.java b/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/MediaControllerTest.java
index 215bf3a..6b492f94 100644
--- a/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/MediaControllerTest.java
+++ b/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/MediaControllerTest.java
@@ -42,9 +42,11 @@
import android.os.ResultReceiver;
import android.view.KeyEvent;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;
+import com.android.bedstead.harrier.BedsteadJUnit4;
+import com.android.bedstead.harrier.UserType;
+import com.android.bedstead.harrier.annotations.UserTest;
import com.android.compatibility.common.util.FrameworkSpecificTest;
import com.android.compatibility.common.util.NonMainlineTest;
@@ -53,12 +55,10 @@
import org.junit.Test;
import org.junit.runner.RunWith;
-/**
- * Test {@link android.media.session.MediaController}.
- */
+/** Test {@link android.media.session.MediaController}. */
@FrameworkSpecificTest
@NonMainlineTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(BedsteadJUnit4.class)
public class MediaControllerTest {
// The maximum time to wait for an operation.
private static final long TIME_OUT_MS = 3000L;
@@ -98,12 +98,14 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testGetPackageName() {
assertThat(mController.getPackageName())
.isEqualTo(getContext().getPackageName());
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testGetPlaybackState() {
final int testState = STATE_PLAYING;
final long testPosition = 100000L;
@@ -145,6 +147,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testGetRatingType() {
assertWithMessage("Default rating type of a session must be Rating.RATING_NONE")
.that(mController.getRatingType())
@@ -156,11 +159,13 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testGetSessionToken() {
assertThat(mController.getSessionToken()).isEqualTo(mSession.getSessionToken());
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testGetSessionInfo() {
Bundle sessionInfo = mController.getSessionInfo();
assertThat(sessionInfo).isNotNull();
@@ -171,6 +176,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testGetSessionInfoReturnsAnEmptyBundleWhenNotSet() {
MediaSession session = new MediaSession(getContext(), "test_tag", /*sessionInfo=*/ null);
try {
@@ -181,11 +187,13 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testGetTag() {
assertThat(mController.getTag()).isEqualTo(SESSION_TAG);
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testSendCommand() throws Exception {
synchronized (mWaitLock) {
mCallback.reset();
@@ -203,6 +211,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testSendCommandWithIllegalArgumentsThrowsIAE() {
Bundle args = new Bundle();
ResultReceiver resultReceiver = new ResultReceiver(mHandler);
@@ -215,6 +224,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testSetPlaybackSpeed() throws Exception {
synchronized (mWaitLock) {
mCallback.reset();
@@ -230,12 +240,14 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testAdjustVolumeWithIllegalDirection() {
// Call the method with illegal direction. System should not reboot.
mController.adjustVolume(37, 0);
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testVolumeControl() throws Exception {
VolumeProvider vp = new VolumeProvider(VolumeProvider.VOLUME_CONTROL_ABSOLUTE, 11, 5) {
@Override
@@ -281,6 +293,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testTransportControlsAndMediaSessionCallback() throws Exception {
MediaController.TransportControls controls = mController.getTransportControls();
final MediaSession.Callback callback = (MediaSession.Callback) mCallback;
@@ -478,6 +491,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testRegisterCallbackWithNullThrowsIAE() {
assertThrows(IllegalArgumentException.class,
() -> mController.registerCallback(/*handler=*/ null));
@@ -487,6 +501,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testRegisteringSameCallbackWithDifferentHandlerHasNoEffect() {
MediaController.Callback callback = new MediaController.Callback() {};
mController.registerCallback(callback, mHandler);
@@ -510,12 +525,14 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testUnregisterCallbackWithNull() {
assertThrows(IllegalArgumentException.class,
() -> mController.unregisterCallback(/*handler=*/ null));
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testUnregisterCallbackShouldRemoveCallback() {
MediaController.Callback callback = new MediaController.Callback() {};
mController.registerCallback(callback, mHandler);
@@ -527,18 +544,21 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testDispatchMediaButtonEventWithNullKeyEvent() {
assertThrows(IllegalArgumentException.class,
() -> mController.dispatchMediaButtonEvent(/*keyEvent=*/ null));
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testDispatchMediaButtonEventWithNonMediaKeyEventReturnsFalse() {
KeyEvent keyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_CAPS_LOCK);
assertThat(mController.dispatchMediaButtonEvent(keyEvent)).isFalse();
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testPlaybackInfoCreatorNewArray() {
final int arrayLength = 5;
MediaController.PlaybackInfo[] playbackInfoArrayInitializedWithNulls =
@@ -551,6 +571,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testTransportControlsPlayAndPrepareFromMediaIdWithIllegalArgumentsThrowsIAE() {
MediaController.TransportControls transportControls = mController.getTransportControls();
@@ -571,6 +592,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testTransportControlsPlayAndPrepareFromUriWithIllegalArgumentsThrowsIAE() {
MediaController.TransportControls transportControls = mController.getTransportControls();
@@ -588,6 +610,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testTransportControlsPlayAndPrepareFromSearchWithNullDoesNotCrash()
throws Exception {
MediaController.TransportControls transportControls = mController.getTransportControls();
@@ -605,6 +628,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testSendCustomActionWithIllegalArgumentsThrowsIAE() {
MediaController.TransportControls transportControls = mController.getTransportControls();
diff --git a/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/MediaItemTest.java b/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/MediaItemTest.java
index 2882998..1ef9451 100644
--- a/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/MediaItemTest.java
+++ b/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/MediaItemTest.java
@@ -21,20 +21,19 @@
import android.media.browse.MediaBrowser.MediaItem;
import android.os.Parcel;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-
+import com.android.bedstead.harrier.BedsteadJUnit4;
+import com.android.bedstead.harrier.UserType;
+import com.android.bedstead.harrier.annotations.UserTest;
import com.android.compatibility.common.util.FrameworkSpecificTest;
import com.android.compatibility.common.util.NonMainlineTest;
import org.junit.Test;
import org.junit.runner.RunWith;
-/**
- * Test {@link android.media.browse.MediaBrowser.MediaItem}.
- */
+/** Test {@link android.media.browse.MediaBrowser.MediaItem}. */
@FrameworkSpecificTest
@NonMainlineTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(BedsteadJUnit4.class)
public class MediaItemTest {
private static final String DESCRIPTION = "test_description";
private static final String MEDIA_ID = "test_media_id";
@@ -73,6 +72,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testPlayableMediaItem() {
MediaDescription description = new MediaDescription.Builder()
.setDescription(DESCRIPTION).setMediaId(MEDIA_ID)
diff --git a/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/MediaMetadataTest.java b/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/MediaMetadataTest.java
index 7da0288..ebfe655 100644
--- a/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/MediaMetadataTest.java
+++ b/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/MediaMetadataTest.java
@@ -29,6 +29,8 @@
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
+import com.android.bedstead.harrier.UserType;
+import com.android.bedstead.harrier.annotations.UserTest;
import com.android.compatibility.common.util.FrameworkSpecificTest;
import com.android.compatibility.common.util.NonMainlineTest;
@@ -47,6 +49,7 @@
public class MediaMetadataTest {
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void builder_defaultConstructor_hasNoData() {
MediaMetadata metadata = new MediaMetadata.Builder().build();
@@ -55,6 +58,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void builder_putText() {
String testTitle = "test_title";
MediaMetadata metadata = new MediaMetadata.Builder()
@@ -67,6 +71,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void builder_putString() {
String testTitle = "test_title";
MediaMetadata metadata = new MediaMetadata.Builder()
@@ -79,6 +84,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void builder_putLong() {
long testYear = 2021;
MediaMetadata metadata = new MediaMetadata.Builder()
@@ -91,6 +97,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void builder_putRating() {
Rating testHeartRating = Rating.newHeartRating(/*hasHeart=*/ true);
MediaMetadata metadata = new MediaMetadata.Builder()
@@ -103,6 +110,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void builder_putText_throwsIAE_withNonTextKey() {
MediaMetadata.Builder builder = new MediaMetadata.Builder();
@@ -111,6 +119,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void builder_putString_throwsIAE_withNonTextKey() {
MediaMetadata.Builder builder = new MediaMetadata.Builder();
@@ -119,6 +128,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void builder_putLong_throwsIAE_withNonLongKey() {
MediaMetadata.Builder builder = new MediaMetadata.Builder();
@@ -127,6 +137,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void builder_putRating_throwsIAE_withNonRatingKey() {
Rating testHeartRating = Rating.newHeartRating(/*hasHeart=*/ true);
MediaMetadata.Builder builder = new MediaMetadata.Builder();
@@ -136,6 +147,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void builder_putBitmap_throwsIAE_withNonBitmapKey() {
Bitmap testBitmap = Bitmap.createBitmap(/*width=*/ 16, /*height=*/16,
Bitmap.Config.ARGB_8888);
@@ -146,6 +158,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void builder_copyConstructor() {
long testYear = 2021;
MediaMetadata originalMetadata = new MediaMetadata.Builder()
@@ -157,6 +170,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void equalsAndHashCode() {
String testTitle = "test_title";
long testYear = 2021;
@@ -174,6 +188,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void equalsAndHashCode_ignoreRatingAndBitmap() {
Rating testHeartRating = Rating.newHeartRating(/*hasHeart=*/ true);
Bitmap testBitmap = Bitmap.createBitmap(/*width=*/ 16, /*height=*/16,
@@ -189,6 +204,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void sizeAndKeySet() {
Rating testHeartRating = Rating.newHeartRating(/*hasHeart=*/ true);
Bitmap testBitmap = Bitmap.createBitmap(/*width=*/ 16, /*height=*/16,
@@ -205,6 +221,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void describeContents() {
long testYear = 2021;
MediaMetadata metadata = new MediaMetadata.Builder()
@@ -215,6 +232,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void writeToParcel() {
String testTitle = "test_title";
long testYear = 2021;
@@ -233,6 +251,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void getDescription() {
String testMediaId = "media_id";
String testTitle = "test_title";
@@ -261,12 +280,14 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void getBitmapDimensionLimit_returnsIntegerMaxWhenNotSet() {
MediaMetadata metadata = new MediaMetadata.Builder().build();
assertThat(metadata.getBitmapDimensionLimit()).isEqualTo(Integer.MAX_VALUE);
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void builder_setBitmapDimensionLimit_bitmapsAreScaledDown() {
// A large bitmap (64MB).
final int originalWidth = 4096;
@@ -289,6 +310,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void builder_setBitmapDimensionLimit_bitmapsAreNotScaledDown() {
// A small bitmap.
final int originalWidth = 16;
@@ -312,6 +334,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void builder_setMaxBitmapDimensionLimit_unsetLimit() {
final int testBitmapDimensionLimit = 256;
MediaMetadata metadata = new MediaMetadata.Builder()
diff --git a/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/MediaSession2ServiceTest.java b/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/MediaSession2ServiceTest.java
index c079f5aa..107869f 100644
--- a/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/MediaSession2ServiceTest.java
+++ b/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/MediaSession2ServiceTest.java
@@ -34,14 +34,20 @@
import android.os.Process;
import android.platform.test.annotations.AppModeNonSdkSandbox;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import androidx.test.platform.app.InstrumentationRegistry;
+import com.android.bedstead.harrier.BedsteadJUnit4;
+import com.android.bedstead.harrier.DeviceState;
+import com.android.bedstead.harrier.UserType;
+import com.android.bedstead.harrier.annotations.AfterClass;
+import com.android.bedstead.harrier.annotations.BeforeClass;
+import com.android.bedstead.harrier.annotations.UserTest;
+
import org.junit.After;
-import org.junit.AfterClass;
import org.junit.Before;
-import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -50,13 +56,14 @@
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
-/**
- * Tests {@link MediaSession2Service}.
- */
-@RunWith(AndroidJUnit4.class)
+/** Tests {@link MediaSession2Service}. */
+@RunWith(BedsteadJUnit4.class)
@SmallTest
@AppModeNonSdkSandbox(reason = "MediaSession2Service use is restricted to the sandbox.")
public class MediaSession2ServiceTest {
+
+ @ClassRule @Rule public static final DeviceState sDeviceState = new DeviceState();
+
private static final long TIMEOUT_MS = 3000L;
private static final long WAIT_TIME_FOR_NO_RESPONSE_MS = 500L;
@@ -108,10 +115,11 @@
}
/**
- * Tests whether {@link MediaSession2Service#onGetSession(ControllerInfo)}
- * is called when controller tries to connect, with the proper arguments.
+ * Tests whether {@link MediaSession2Service#onGetSession(ControllerInfo)} is called when
+ * controller tries to connect, with the proper arguments.
*/
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testOnGetSessionIsCalled() throws InterruptedException {
final List<ControllerInfo> controllerInfoList = new ArrayList<>();
final CountDownLatch latch = new CountDownLatch(1);
@@ -141,12 +149,13 @@
}
/**
- * Tests whether the controller is connected to the session which is returned from
- * {@link MediaSession2Service#onGetSession(ControllerInfo)}.
- * Also checks whether the connection hints are properly passed to
- * {@link MediaSession2.SessionCallback#onConnect(MediaSession2, ControllerInfo)}.
+ * Tests whether the controller is connected to the session which is returned from {@link
+ * MediaSession2Service#onGetSession(ControllerInfo)}. Also checks whether the connection hints
+ * are properly passed to {@link MediaSession2.SessionCallback#onConnect(MediaSession2,
+ * ControllerInfo)}.
*/
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testOnGetSession_returnsSession() throws InterruptedException {
final List<ControllerInfo> controllerInfoList = new ArrayList<>();
final CountDownLatch latch = new CountDownLatch(1);
@@ -198,10 +207,11 @@
}
/**
- * Tests whether {@link MediaSession2Service#onGetSession(ControllerInfo)}
- * can return different sessions for different controllers.
+ * Tests whether {@link MediaSession2Service#onGetSession(ControllerInfo)} can return different
+ * sessions for different controllers.
*/
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testOnGetSession_returnsDifferentSessions() throws InterruptedException {
final List<Session2Token> tokens = new ArrayList<>();
StubMediaSession2Service.setTestInjector(new StubMediaSession2Service.TestInjector() {
@@ -227,10 +237,11 @@
}
/**
- * Tests whether {@link MediaSession2Service#onGetSession(ControllerInfo)}
- * can reject incoming connection by returning null.
+ * Tests whether {@link MediaSession2Service#onGetSession(ControllerInfo)} can reject incoming
+ * connection by returning null.
*/
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testOnGetSession_rejectsConnection() throws InterruptedException {
StubMediaSession2Service.setTestInjector(new StubMediaSession2Service.TestInjector() {
@Override
@@ -254,6 +265,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testAllControllersDisconnected_oneSession() throws InterruptedException {
final CountDownLatch latch = new CountDownLatch(1);
final MediaSession2 testSession =
@@ -282,6 +294,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testAllControllersDisconnected_multipleSessions() throws InterruptedException {
final CountDownLatch latch = new CountDownLatch(1);
StubMediaSession2Service.setTestInjector(new StubMediaSession2Service.TestInjector() {
@@ -309,6 +322,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testGetSessions() throws InterruptedException {
MediaController2 controller = createConnectedController(mToken);
MediaSession2Service service = StubMediaSession2Service.getInstance();
@@ -328,6 +342,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testAddSessions_removedWhenClose() throws InterruptedException {
MediaController2 controller = createConnectedController(mToken);
MediaSession2Service service = StubMediaSession2Service.getInstance();
@@ -347,6 +362,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testOnUpdateNotification() throws InterruptedException {
MediaController2 controller = createConnectedController(mToken);
MediaSession2Service service = StubMediaSession2Service.getInstance();
@@ -382,6 +398,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testOnBind() throws Exception {
MediaController2 controller1 = createConnectedController(mToken);
MediaSession2Service service = StubMediaSession2Service.getInstance();
@@ -394,6 +411,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testMediaNotification() {
final int testId = 1001;
final String testChannelId = "channelId";
diff --git a/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/MediaSession2Test.java b/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/MediaSession2Test.java
index e9c4fea..379e26d 100644
--- a/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/MediaSession2Test.java
+++ b/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/MediaSession2Test.java
@@ -22,6 +22,7 @@
import static org.junit.Assert.assertThrows;
+import android.Manifest;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
@@ -40,13 +41,20 @@
import android.os.Parcelable;
import android.os.Process;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
-import androidx.test.platform.app.InstrumentationRegistry;
-import org.junit.AfterClass;
+import com.android.bedstead.harrier.BedsteadJUnit4;
+import com.android.bedstead.harrier.DeviceState;
+import com.android.bedstead.harrier.UserType;
+import com.android.bedstead.harrier.annotations.AfterClass;
+import com.android.bedstead.harrier.annotations.BeforeClass;
+import com.android.bedstead.harrier.annotations.UserTest;
+
+import org.junit.After;
import org.junit.Before;
-import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -56,12 +64,13 @@
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
-/**
- * Tests {@link android.media.MediaSession2}.
- */
-@RunWith(AndroidJUnit4.class)
+/** Tests {@link android.media.MediaSession2}. */
+@RunWith(BedsteadJUnit4.class)
@SmallTest
public class MediaSession2Test {
+
+ @ClassRule @Rule public static final DeviceState sDeviceState = new DeviceState();
+
private static final long WAIT_TIME_MS = 300L;
private static final String TEST_KEY = "test_key";
@@ -115,7 +124,14 @@
mContext = InstrumentationRegistry.getInstrumentation().getContext();
}
+ @After
+ public void tearDown() throws Exception {
+ InstrumentationRegistry
+ .getInstrumentation().getUiAutomation().dropShellPermissionIdentity();
+ }
+
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testBuilder_setIllegalArguments() {
assertThrows("null context shouldn't be allowed",
IllegalArgumentException.class,
@@ -129,6 +145,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testBuilder_setSessionActivity() {
Intent intent = new Intent(Intent.ACTION_MAIN);
PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0 /* requestCode */,
@@ -142,6 +159,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testBuilder_createSessionWithoutId() {
try (MediaSession2 session = new MediaSession2.Builder(mContext).build()) {
assertThat(session.getId()).isEqualTo("");
@@ -149,6 +167,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testBuilder_createSessionWithDupId() {
final String dupSessionId = "TEST_SESSION_DUP_ID";
MediaSession2.Builder builder = new MediaSession2.Builder(mContext).setId(dupSessionId);
@@ -160,6 +179,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testBuilder_setExtras_withFrameworkParcelable() {
final String testKey = "test_key";
final Session2Token frameworkParcelable = new Session2Token(mContext,
@@ -179,6 +199,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testBuilder_setExtras_withCustomParcelable() {
final String testKey = "test_key";
final CustomParcelable customParcelable = new CustomParcelable(1);
@@ -194,6 +215,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testSession2Token() {
final Bundle extras = new Bundle();
try (MediaSession2 session = new MediaSession2.Builder(mContext)
@@ -210,6 +232,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testSession2Token_extrasNotSet() {
try (MediaSession2 session = new MediaSession2.Builder(mContext)
.build()) {
@@ -219,6 +242,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testGetConnectedControllers_newController() throws Exception {
Session2Callback sessionCallback = new Session2Callback();
try (MediaSession2 session = new MediaSession2.Builder(mContext)
@@ -245,6 +269,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testGetConnectedControllers_closedController() throws Exception {
Session2Callback sessionCallback = new Session2Callback();
try (MediaSession2 session = new MediaSession2.Builder(mContext)
@@ -265,6 +290,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testSession2Token_writeToParcel() {
final Bundle extras = new Bundle();
extras.putString(TEST_KEY, TEST_VALUE);
@@ -292,6 +318,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testBroadcastSessionCommand() throws Exception {
Session2Callback sessionCallback = new Session2Callback();
@@ -354,6 +381,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testCallback_onConnect_onDisconnect() throws Exception {
Session2Callback sessionCallback = new Session2Callback();
try (MediaSession2 session = new MediaSession2.Builder(mContext)
@@ -393,6 +421,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testCallback_onPostConnect_connected() throws Exception {
Session2Callback sessionCallback = new Session2Callback();
try (MediaSession2 session = new MediaSession2.Builder(mContext)
@@ -410,7 +439,11 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testCallback_onPostConnect_rejected() throws Exception {
+ InstrumentationRegistry.getInstrumentation()
+ .getUiAutomation()
+ .adoptShellPermissionIdentity(Manifest.permission.MANAGE_EXTERNAL_STORAGE);
Session2Callback sessionCallback = new Session2Callback() {
@Override
public Session2CommandGroup onConnect(MediaSession2 session,
@@ -433,6 +466,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testCallback_onSessionCommand() {
Session2Callback sessionCallback = new Session2Callback();
@@ -478,6 +512,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testCallback_onCommandResult() {
Session2Callback sessionCallback = new Session2Callback();
@@ -533,6 +568,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testSetPlaybackActive() {
final boolean testInitialPlaybackActive = true;
final boolean testPlaybackActive = false;
@@ -569,6 +605,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testCancelSessionCommand() {
Session2Callback sessionCallback = new Session2Callback();
try (MediaSession2 session = new MediaSession2.Builder(mContext)
diff --git a/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/MediaSessionManagerTest.java b/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/MediaSessionManagerTest.java
index 3a3fd7a..ed48cf3 100644
--- a/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/MediaSessionManagerTest.java
+++ b/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/MediaSessionManagerTest.java
@@ -46,10 +46,11 @@
import android.text.TextUtils;
import android.view.KeyEvent;
-import androidx.test.annotation.UiThreadTest;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;
+import com.android.bedstead.harrier.BedsteadJUnit4;
+import com.android.bedstead.harrier.UserType;
+import com.android.bedstead.harrier.annotations.UserTest;
import com.android.compatibility.common.util.ApiLevelUtil;
import com.android.compatibility.common.util.FrameworkSpecificTest;
import com.android.compatibility.common.util.NonMainlineTest;
@@ -72,7 +73,7 @@
import java.util.concurrent.TimeUnit;
@AppModeFull(reason = "TODO: evaluate and port to instant")
-@RunWith(AndroidJUnit4.class)
+@RunWith(BedsteadJUnit4.class)
public class MediaSessionManagerTest {
private static final String TAG = "MediaSessionManagerTest";
private static final int TIMEOUT_MS = 3000;
@@ -109,6 +110,7 @@
@Test
@FrameworkSpecificTest
@NonMainlineTest
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testGetActiveSessions() throws Exception {
assertThrows("Expected security exception for unauthorized call to getActiveSessions",
SecurityException.class,
@@ -119,6 +121,7 @@
@Test
@FrameworkSpecificTest
@NonMainlineTest
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testGetMediaKeyEventSession_throwsSecurityException() {
assertThrows("Expected security exception for call to getMediaKeyEventSession",
SecurityException.class,
@@ -128,6 +131,7 @@
@Test
@FrameworkSpecificTest
@NonMainlineTest
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testGetMediaKeyEventSessionPackageName_throwsSecurityException() {
assertThrows("Expected security exception for call to getMediaKeyEventSessionPackageName",
SecurityException.class,
@@ -137,6 +141,7 @@
@Test
@FrameworkSpecificTest
@NonMainlineTest
+ @UserTest({UserType.INITIAL_USER}) // Requires a full user. Don't run for work profile.
public void testOnMediaKeyEventSessionChangedListener() throws Exception {
getInstrumentation().getUiAutomation().adoptShellPermissionIdentity(
Manifest.permission.MEDIA_CONTENT_CONTROL,
@@ -168,6 +173,7 @@
@Test
@FrameworkSpecificTest
@NonMainlineTest
+ @UserTest({UserType.INITIAL_USER}) // Requires a full user. Don't run for work profile.
public void testOnMediaKeyEventSessionChangedListener_whenSessionIsReleased() throws Exception {
getInstrumentation().getUiAutomation().adoptShellPermissionIdentity(
Manifest.permission.MEDIA_CONTENT_CONTROL,
@@ -196,6 +202,7 @@
@Test
@FrameworkSpecificTest
@NonMainlineTest
+ @UserTest({UserType.INITIAL_USER}) // Requires a full user. Don't run for work profile.
public void testOnMediaKeyEventSessionChangedListener_noSession_passesEmptyPackageAndNullToken()
throws InterruptedException {
getInstrumentation().getUiAutomation().adoptShellPermissionIdentity(
@@ -231,6 +238,7 @@
@Test
@FrameworkSpecificTest
@NonMainlineTest
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testOnMediaKeyEventSessionChangedListener_noPermission_throwsSecurityException() {
MediaKeyEventSessionListener keyEventSessionListener = new MediaKeyEventSessionListener();
assertThrows(
@@ -245,6 +253,7 @@
@Test
@FrameworkSpecificTest
@NonMainlineTest
+ @UserTest({UserType.INITIAL_USER}) // Requires a full user. Don't run for work profile.
public void testOnMediaKeyEventDispatchedListener() throws Exception {
getInstrumentation().getUiAutomation().adoptShellPermissionIdentity(
Manifest.permission.MEDIA_CONTENT_CONTROL,
@@ -286,22 +295,6 @@
.await(WAIT_MS, TimeUnit.MILLISECONDS)).isFalse();
}
- @Test
- @UiThreadTest
- @FrameworkSpecificTest
- @NonMainlineTest
- public void testAddOnActiveSessionsListener() throws Exception {
- assertThrows("Expected NPE for call to addOnActiveSessionsChangedListener",
- NullPointerException.class,
- () -> mSessionManager.addOnActiveSessionsChangedListener(null, null));
-
- MediaSessionManager.OnActiveSessionsChangedListener listener = controllers -> {};
-
- assertThrows("Expected security exception for call to addOnActiveSessionsChangedListener",
- SecurityException.class,
- () -> mSessionManager.addOnActiveSessionsChangedListener(listener, null));
- }
-
private void assertKeyEventEquals(KeyEvent lhs, int keyCode, int action, int repeatCount) {
assertThat(lhs.getKeyCode() == keyCode
&& lhs.getAction() == action
@@ -318,6 +311,7 @@
@Test
@FrameworkSpecificTest
@NonMainlineTest
+ @UserTest({UserType.INITIAL_USER}) // Requires a full user. Don't run for work profile.
public void testSetOnVolumeKeyLongPressListener() throws Exception {
Context context = getInstrumentation().getTargetContext();
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK)
@@ -360,6 +354,7 @@
@Test
@FrameworkSpecificTest
@NonMainlineTest
+ @UserTest({UserType.INITIAL_USER}) // Requires a full user. Don't run for work profile.
public void testSetOnMediaKeyListener() throws Exception {
Handler handler = createHandlerWithScheduledLooperQuit();
MediaSession session = new MediaSession(getInstrumentation().getTargetContext(), TAG);
@@ -423,6 +418,7 @@
@Test
@FrameworkSpecificTest
@NonMainlineTest
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testRemoteUserInfo() throws Exception {
final Context context = getInstrumentation().getTargetContext();
Handler handler = createHandlerWithScheduledLooperQuit();
@@ -471,6 +467,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testGetSession2Tokens() throws Exception {
final Context context = getInstrumentation().getTargetContext();
Handler handler = createHandlerWithScheduledLooperQuit();
@@ -496,6 +493,7 @@
@Ignore // TODO(b/291800179): Diagnose flakiness and re-enable.
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testGetSession2TokensWithTwoSessions() throws Exception {
final Context context = getInstrumentation().getTargetContext();
Handler handler = createHandlerWithScheduledLooperQuit();
@@ -545,6 +543,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testAddAndRemoveSession2TokensListener() throws Exception {
final Context context = getInstrumentation().getTargetContext();
Handler handler = createHandlerWithScheduledLooperQuit();
@@ -575,6 +574,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testSession2TokensNotChangedBySession1() throws Exception {
final Context context = getInstrumentation().getTargetContext();
Handler handler = createHandlerWithScheduledLooperQuit();
@@ -596,6 +596,7 @@
@Test
@FrameworkSpecificTest
@NonMainlineTest
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testCustomClassConfigValuesAreValid() throws Exception {
Context context = getInstrumentation().getTargetContext();
String customMediaKeyDispatcher = context.getString(
@@ -618,6 +619,7 @@
@Test
@FrameworkSpecificTest
@NonMainlineTest
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testIsTrustedForMediaControl_withEnabledNotificationListener() throws Exception {
List<String> packageNames = getEnabledNotificationListenerPackages();
for (String packageName : packageNames) {
@@ -632,6 +634,7 @@
@Test
@FrameworkSpecificTest
@NonMainlineTest
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testIsTrustedForMediaControl_withInvalidUid() throws Exception {
List<String> packageNames = getEnabledNotificationListenerPackages();
for (String packageName : packageNames) {
diff --git a/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/MediaSessionTest.java b/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/MediaSessionTest.java
index d15521a..5701693 100644
--- a/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/MediaSessionTest.java
+++ b/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/MediaSessionTest.java
@@ -61,9 +61,11 @@
import android.text.TextUtils;
import android.view.KeyEvent;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;
+import com.android.bedstead.harrier.BedsteadJUnit4;
+import com.android.bedstead.harrier.UserType;
+import com.android.bedstead.harrier.annotations.UserTest;
import com.android.compatibility.common.util.FrameworkSpecificTest;
import com.android.compatibility.common.util.NonMainlineTest;
@@ -84,7 +86,7 @@
@FrameworkSpecificTest
@NonMainlineTest
@AppModeFull(reason = "TODO: evaluate and port to instant")
-@RunWith(AndroidJUnit4.class)
+@RunWith(BedsteadJUnit4.class)
public class MediaSessionTest {
// The maximum time to wait for an operation that is expected to succeed.
private static final long TIME_OUT_MS = 3000L;
@@ -174,6 +176,7 @@
* initialized correctly.
*/
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testCreateSession() throws Exception {
assertThat(mSession.getSessionToken()).isNotNull();
assertWithMessage("New session should not be active").that(mSession.isActive()).isFalse();
@@ -185,6 +188,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
// Needed for assertThat(sessionToken.equals(mSession)).isFalse().
@SuppressWarnings("EqualsIncompatibleType")
public void testSessionTokenEquals() {
@@ -210,6 +214,7 @@
* Tests MediaSession.Token created in the constructor of MediaSession.
*/
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testSessionToken() throws Exception {
MediaSession.Token sessionToken = mSession.getSessionToken();
@@ -238,6 +243,7 @@
* controller.
*/
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testConfigureSession() throws Exception {
MediaController controller = mSession.getController();
controller.registerCallback(mCallback, mHandler);
@@ -379,6 +385,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void setMediaSession_withInaccessibleUri_uriCleared() throws Exception {
createCloneProfile();
Assume.assumeTrue(mCloneProfileId.isPresent());
@@ -412,6 +419,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void setMediaSession_withUri_uriExists() throws Exception {
String testMediaUri = "content://media/external/images/media/";
MediaController controller = mSession.getController();
@@ -444,6 +452,7 @@
*/
@Ignore // TODO(b/291800179): Diagnose flakiness and re-enable.
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testSetMediaButtonReceiver_broadcastReceiver() throws Exception {
Intent intent = new Intent(mContext.getApplicationContext(),
MediaButtonBroadcastReceiver.class);
@@ -495,6 +504,7 @@
* Test whether media button receiver can be a explicit service.
*/
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testSetMediaButtonReceiver_service() throws Exception {
Intent intent = new Intent(mContext.getApplicationContext(),
MediaButtonReceiverService.class);
@@ -547,6 +557,7 @@
* {@link MediaSession#setMediaButtonReceiver(PendingIntent)} with implicit intent.
*/
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testSetMediaButtonReceiver_implicitIntent() throws Exception {
// Note: No such broadcast receiver exists.
Intent intent = new Intent("android.media.bettertogether.cts.ACTION_MEDIA_TEST");
@@ -570,6 +581,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testSetMediaButtonReceiver_withNull_doesNotThrow() {
try {
mSession.setMediaButtonReceiver(null);
@@ -584,6 +596,7 @@
*/
@Ignore // TODO(b/291800179): Diagnose flakiness and re-enable.
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testSetMediaButtonBroadcastReceiver_broadcastReceiver() throws Exception {
// Play a sound so this session can get the priority.
Utils.assertMediaPlaybackStarted(getContext());
@@ -631,6 +644,7 @@
* Test public APIs of {@link VolumeProvider}.
*/
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testVolumeProvider() {
VolumeProvider vp = new VolumeProvider(VolumeProvider.VOLUME_CONTROL_RELATIVE,
TEST_MAX_VOLUME, TEST_CURRENT_VOLUME, TEST_VOLUME_CONTROL_ID) {};
@@ -644,6 +658,7 @@
* Test {@link MediaSession#setPlaybackToLocal} and {@link MediaSession#setPlaybackToRemote}.
*/
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testPlaybackToLocalAndRemote() throws Exception {
MediaController controller = mSession.getController();
controller.registerCallback(mCallback, mHandler);
@@ -711,6 +726,7 @@
* Test {@link MediaSession.Callback#onMediaButtonEvent}.
*/
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testCallbackOnMediaButtonEvent() throws Exception {
MediaSessionCallback sessionCallback = new MediaSessionCallback();
mSession.setCallback(sessionCallback, new Handler(Looper.getMainLooper()));
@@ -825,6 +841,7 @@
* once {@code setCallback(null)} is done.
*/
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testSetCallbackWithNull() throws Exception {
MediaSessionCallback sessionCallback = new MediaSessionCallback();
mSession.setCallback(sessionCallback, mHandler);
@@ -861,6 +878,7 @@
* See: b/36669550
*/
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testReleaseNoCrashWithMultipleSessions() throws Exception {
// Start a media playback for this app to receive media key events.
Utils.assertMediaPlaybackStarted(getContext());
@@ -898,6 +916,7 @@
* Tests {@link MediaSession.QueueItem}.
*/
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testQueueItem() {
MediaDescription.Builder descriptionBuilder = new MediaDescription.Builder()
.setMediaId("media-id")
@@ -935,6 +954,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testQueueItemEquals() {
MediaDescription.Builder descriptionBuilder = new MediaDescription.Builder()
.setMediaId("media-id")
@@ -962,6 +982,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testSessionInfoWithFrameworkParcelable() {
final String testKey = "test_key";
final AudioAttributes frameworkParcelable = new AudioAttributes.Builder().build();
@@ -986,6 +1007,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testSessionInfoWithCustomParcelable() {
final String testKey = "test_key";
final MediaSession2Test.CustomParcelable customParcelable =
@@ -1013,6 +1035,7 @@
* See MediaSessionService#SESSION_CREATION_LIMIT_PER_UID
*/
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testSessionCreationLimit() {
List<MediaSession> sessions = new ArrayList<>();
try {
@@ -1034,6 +1057,7 @@
* does not decrement current session count multiple times.
*/
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testSessionCreationLimitWithMediaSessionRelease() {
List<MediaSession> sessions = new ArrayList<>();
MediaSession sessionToReleaseMultipleTimes = null;
@@ -1063,6 +1087,7 @@
* Check that calling {@link MediaSession2#close()} does not decrement current session count.
*/
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testSessionCreationLimitWithMediaSession2Release() {
List<MediaSession> sessions = new ArrayList<>();
try {
@@ -1089,6 +1114,7 @@
* on the remote process due to binder buffer overflow.
*/
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testSeriesOfSetQueue() throws Exception {
int numberOfCalls = 100;
int queueSize = 1_000;
@@ -1114,6 +1140,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testSetQueueWithLargeNumberOfItems() throws Exception {
int queueSize = 500_000;
List<QueueItem> queue = new ArrayList<>();
@@ -1136,6 +1163,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testSetQueueWithEmptyQueue() throws Exception {
try (RemoteService.Invoker invoker = new RemoteService.Invoker(mContext,
MediaSessionTestService.class, TEST_SET_QUEUE)) {
diff --git a/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/Session2CommandGroupTest.java b/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/Session2CommandGroupTest.java
index ed7a570..611fd30 100644
--- a/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/Session2CommandGroupTest.java
+++ b/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/Session2CommandGroupTest.java
@@ -22,18 +22,19 @@
import android.media.Session2CommandGroup;
import android.os.Parcel;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
+import com.android.bedstead.harrier.BedsteadJUnit4;
+import com.android.bedstead.harrier.UserType;
+import com.android.bedstead.harrier.annotations.UserTest;
+
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.Set;
-/**
- * Tests {@link android.media.Session2CommandGroup}.
- */
-@RunWith(AndroidJUnit4.class)
+/** Tests {@link android.media.Session2CommandGroup}. */
+@RunWith(BedsteadJUnit4.class)
@SmallTest
public class Session2CommandGroupTest {
private static final int TEST_COMMAND_CODE_1 = 10000;
@@ -41,6 +42,7 @@
private static final int TEST_COMMAND_CODE_3 = 10002;
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testHasCommand() {
Session2Command testCommand = new Session2Command(TEST_COMMAND_CODE_1);
Session2CommandGroup.Builder builder = new Session2CommandGroup.Builder()
@@ -52,6 +54,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testGetCommands() {
Session2Command command1 = new Session2Command(TEST_COMMAND_CODE_1);
Session2Command command2 = new Session2Command(TEST_COMMAND_CODE_2);
@@ -65,6 +68,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testDescribeContents() {
final int expected = 0;
Session2Command command = new Session2Command(TEST_COMMAND_CODE_1);
@@ -75,6 +79,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testWriteToParcel() {
Session2CommandGroup.Builder builder = new Session2CommandGroup.Builder()
.addCommand(new Session2Command(TEST_COMMAND_CODE_1))
@@ -90,6 +95,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testBuilder() {
Session2CommandGroup.Builder builder = new Session2CommandGroup.Builder()
.addCommand(new Session2Command(TEST_COMMAND_CODE_1));
@@ -100,6 +106,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testAddAndRemoveCommand() {
Session2Command testCommand1 = new Session2Command(TEST_COMMAND_CODE_1);
Session2Command testCommand2 = new Session2Command(TEST_COMMAND_CODE_2);
diff --git a/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/Session2CommandTest.java b/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/Session2CommandTest.java
index acbb261..0953ce3 100644
--- a/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/Session2CommandTest.java
+++ b/tests/tests/media/bettertogether/src/android/media/bettertogether/cts/Session2CommandTest.java
@@ -24,17 +24,18 @@
import android.os.Bundle;
import android.os.Parcel;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
+import com.android.bedstead.harrier.BedsteadJUnit4;
+import com.android.bedstead.harrier.UserType;
+import com.android.bedstead.harrier.annotations.UserTest;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-/**
- * Tests {@link android.media.Session2Command}.
- */
-@RunWith(AndroidJUnit4.class)
+/** Tests {@link android.media.Session2Command}. */
+@RunWith(BedsteadJUnit4.class)
@SmallTest
public class Session2CommandTest {
private static final int TEST_COMMAND_CODE = 10000;
@@ -50,18 +51,21 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testConstructorWithCommandCodeCustom() {
assertThrows(IllegalArgumentException.class,
() -> new Session2Command(Session2Command.COMMAND_CODE_CUSTOM));
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testConstructorWithNullAction() {
assertThrows(IllegalArgumentException.class,
() -> new Session2Command(null, null));
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testGetCommandCode() {
Session2Command commandWithCode = new Session2Command(TEST_COMMAND_CODE);
assertThat(commandWithCode.getCommandCode()).isEqualTo(TEST_COMMAND_CODE);
@@ -73,6 +77,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testGetCustomAction() {
Session2Command commandWithCode = new Session2Command(TEST_COMMAND_CODE);
assertThat(commandWithCode.getCustomAction()).isNull();
@@ -83,6 +88,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testGetCustomExtras() {
Session2Command commandWithCode = new Session2Command(TEST_COMMAND_CODE);
assertThat(commandWithCode.getCustomExtras()).isNull();
@@ -93,6 +99,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testDescribeContents() {
final int expected = 0;
Session2Command command = new Session2Command(TEST_COMMAND_CODE);
@@ -100,6 +107,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testWriteToParcel() {
Session2Command command = new Session2Command(TEST_CUSTOM_ACTION, null);
Parcel dest = Parcel.obtain();
@@ -111,6 +119,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testEquals() {
Session2Command commandWithCode1 = new Session2Command(TEST_COMMAND_CODE);
Session2Command commandWithCode2 = new Session2Command(TEST_COMMAND_CODE);
@@ -124,6 +133,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testHashCode() {
Session2Command commandWithCode1 = new Session2Command(TEST_COMMAND_CODE);
Session2Command commandWithCode2 = new Session2Command(TEST_COMMAND_CODE);
@@ -131,6 +141,7 @@
}
@Test
+ @UserTest({UserType.INITIAL_USER, UserType.WORK_PROFILE})
public void testGetResultCodeAndData() {
Session2Command.Result result = new Session2Command.Result(TEST_RESULT_CODE,
mTestResultData);
diff --git a/tests/tests/media/common/src/android/media/cts/MediaCodecCryptoAsyncHelper.java b/tests/tests/media/common/src/android/media/cts/MediaCodecCryptoAsyncHelper.java
index c6d1479..47f9e88 100644
--- a/tests/tests/media/common/src/android/media/cts/MediaCodecCryptoAsyncHelper.java
+++ b/tests/tests/media/common/src/android/media/cts/MediaCodecCryptoAsyncHelper.java
@@ -147,6 +147,19 @@
private final boolean mContentEncrypted;
}
+ private static OutputSurface getOutputSurface(
+ int width, int height, boolean useHighBitDepth, boolean secure) {
+ OutputSurface outputSurface = null;
+ try {
+ outputSurface = new OutputSurface(width, height, useHighBitDepth, secure);
+ } catch (RuntimeException e) {
+ // Relaxing EGL errors as these tests are not meant
+ // to test EGL.
+ Assume.assumeTrue("Surface creation failed when using EGL", false);
+ }
+ return outputSurface;
+ }
+
private static class SurfaceOutputSlotListener
implements MediaCodecAsyncHelper.OutputSlotListener {
@@ -192,7 +205,7 @@
slotQueue = new LinkedBlockingQueue<>();
boolean isSecureDecodeASuccess = false;
try {
- outputSurface = new OutputSurface(1, 1, false, secure);
+ outputSurface = getOutputSurface(1, 1, false, secure);
MediaFormat mediaFormat = mediaExtractor.getTrackFormat(
mediaExtractor.getSampleTrackIndex());
String mime = mediaFormat.getString(MediaFormat.KEY_MIME);
@@ -310,7 +323,7 @@
final LinkedBlockingQueue<MediaCodecAsyncHelper.SlotEvent>
slotQueue = new LinkedBlockingQueue<>();
try {
- outputSurface = new OutputSurface(1, 1, false, secure);
+ outputSurface = getOutputSurface(1, 1, false, secure);
MediaFormat mediaFormat = mediaExtractor.getTrackFormat(
mediaExtractor.getSampleTrackIndex());
String mime = mediaFormat.getString(MediaFormat.KEY_MIME);
@@ -438,7 +451,7 @@
final LinkedBlockingQueue<MediaCodec.CryptoInfo>
cryptoInfoQueue = new LinkedBlockingQueue<>();
try {
- outputSurface = new OutputSurface(1, 1, false, secure);
+ outputSurface = getOutputSurface(1, 1, false, secure);
MediaFormat mediaFormat = mediaExtractor.getTrackFormat(
mediaExtractor.getSampleTrackIndex());
String mime = mediaFormat.getString(MediaFormat.KEY_MIME);
diff --git a/tests/tests/media/decoder/src/android/media/decoder/cts/DecodeOnlyTest.java b/tests/tests/media/decoder/src/android/media/decoder/cts/DecodeOnlyTest.java
index ce9a0eb..097fce3 100644
--- a/tests/tests/media/decoder/src/android/media/decoder/cts/DecodeOnlyTest.java
+++ b/tests/tests/media/decoder/src/android/media/decoder/cts/DecodeOnlyTest.java
@@ -797,7 +797,7 @@
while (audioData.remaining() > 0 && !mDone.get()) {
int written = mAudioTrack.write(audioData, audioData.remaining(),
AudioTrack.WRITE_BLOCKING, presentationTimeUs * 1000);
- if (written >= 0) {
+ if (written == 0) {
// When audio track is not in playing state, the write operation does not
// block in WRITE_BLOCKING mode. And when audio track is full, the audio
// data can not be fully written. Must sleep here to wait for free spaces.
@@ -805,7 +805,7 @@
Thread.sleep(50);
} catch (InterruptedException ignored) {
}
- } else {
+ } else if (written < 0) {
Assert.fail("AudioTrack write failure.");
}
}
diff --git a/tests/tests/media/decoder/src/android/media/decoder/cts/DecoderTest.java b/tests/tests/media/decoder/src/android/media/decoder/cts/DecoderTest.java
index e7c5347..e6d33e8 100644
--- a/tests/tests/media/decoder/src/android/media/decoder/cts/DecoderTest.java
+++ b/tests/tests/media/decoder/src/android/media/decoder/cts/DecoderTest.java
@@ -3443,6 +3443,10 @@
@ApiTest(apis={"android.media.MediaCodecInfo.CodecCapabilities#FEATURE_TunneledPlayback"})
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.S)
public void testTunneledVideoFlushHevc() throws Exception {
+ // New requirements and tests were added in Android 12, but upgrading devices are not
+ // required to adhere to them.
+ Assume.assumeTrue("Vendor API level is not Android 12 or later.",
+ IS_VENDOR_AT_LEAST_S);
testTunneledVideoFlush(MediaFormat.MIMETYPE_VIDEO_HEVC,
"video_1280x720_mkv_h265_500kbps_25fps_aac_stereo_128kbps_44100hz.mkv");
}
@@ -3454,6 +3458,10 @@
@ApiTest(apis={"android.media.MediaCodecInfo.CodecCapabilities#FEATURE_TunneledPlayback"})
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.S)
public void testTunneledVideoFlushAvc() throws Exception {
+ // New requirements and tests were added in Android 12, but upgrading devices are not
+ // required to adhere to them.
+ Assume.assumeTrue("Vendor API level is not Android 12 or later.",
+ IS_VENDOR_AT_LEAST_S);
testTunneledVideoFlush(MediaFormat.MIMETYPE_VIDEO_AVC,
"video_480x360_mp4_h264_1000kbps_25fps_aac_stereo_128kbps_44100hz.mp4");
}
@@ -3465,6 +3473,10 @@
@ApiTest(apis={"android.media.MediaCodecInfo.CodecCapabilities#FEATURE_TunneledPlayback"})
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.S)
public void testTunneledVideoFlushVp9() throws Exception {
+ // New requirements and tests were added in Android 12, but upgrading devices are not
+ // required to adhere to them.
+ Assume.assumeTrue("Vendor API level is not Android 12 or later.",
+ IS_VENDOR_AT_LEAST_S);
testTunneledVideoFlush(MediaFormat.MIMETYPE_VIDEO_VP9,
"bbb_s1_640x360_webm_vp9_0p21_1600kbps_30fps_vorbis_stereo_128kbps_48000hz.webm");
}
@@ -3749,6 +3761,10 @@
@ApiTest(apis={"android.media.MediaCodecInfo.CodecCapabilities#FEATURE_TunneledPlayback"})
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.S)
public void testTunneledAudioProgressWithPtsGapsHevc() throws Exception {
+ // New requirements and tests were added in Android 12, but upgrading devices are not
+ // required to adhere to them.
+ Assume.assumeTrue("Vendor API level is not Android 12 or later.",
+ IS_VENDOR_AT_LEAST_S);
testTunneledAudioProgressWithPtsGaps(MediaFormat.MIMETYPE_VIDEO_HEVC,
"video_1280x720_mkv_h265_500kbps_25fps_aac_stereo_128kbps_44100hz.mkv");
}
@@ -3760,6 +3776,10 @@
@ApiTest(apis={"android.media.MediaCodecInfo.CodecCapabilities#FEATURE_TunneledPlayback"})
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.S)
public void testTunneledAudioProgressWithPtsGapsAvc() throws Exception {
+ // New requirements and tests were added in Android 12, but upgrading devices are not
+ // required to adhere to them.
+ Assume.assumeTrue("Vendor API level is not Android 12 or later.",
+ IS_VENDOR_AT_LEAST_S);
testTunneledAudioProgressWithPtsGaps(MediaFormat.MIMETYPE_VIDEO_AVC,
"video_480x360_mp4_h264_1000kbps_25fps_aac_stereo_128kbps_44100hz.mp4");
}
@@ -3771,6 +3791,10 @@
@ApiTest(apis={"android.media.MediaCodecInfo.CodecCapabilities#FEATURE_TunneledPlayback"})
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.S)
public void testTunneledAudioProgressWithPtsGapsVp9() throws Exception {
+ // New requirements and tests were added in Android 12, but upgrading devices are not
+ // required to adhere to them.
+ Assume.assumeTrue("Vendor API level is not Android 12 or later.",
+ IS_VENDOR_AT_LEAST_S);
testTunneledAudioProgressWithPtsGaps(MediaFormat.MIMETYPE_VIDEO_VP9,
"bbb_s1_640x360_webm_vp9_0p21_1600kbps_30fps_vorbis_stereo_128kbps_48000hz.webm");
}
@@ -3877,6 +3901,10 @@
@ApiTest(apis={"android.media.MediaCodecInfo.CodecCapabilities#FEATURE_TunneledPlayback"})
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.S)
public void testTunneledAudioProgressWithUnderrunHevc() throws Exception {
+ // New requirements and tests were added in Android 12, but upgrading devices are not
+ // required to adhere to them.
+ Assume.assumeTrue("Vendor API level is not Android 12 or later.",
+ IS_VENDOR_AT_LEAST_S);
testTunneledAudioProgressWithUnderrun(MediaFormat.MIMETYPE_VIDEO_HEVC,
"video_1280x720_mkv_h265_500kbps_25fps_aac_stereo_128kbps_44100hz.mkv");
}
@@ -3888,6 +3916,10 @@
@ApiTest(apis={"android.media.MediaCodecInfo.CodecCapabilities#FEATURE_TunneledPlayback"})
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.S)
public void testTunneledAudioProgressWithUnderrunAvc() throws Exception {
+ // New requirements and tests were added in Android 12, but upgrading devices are not
+ // required to adhere to them.
+ Assume.assumeTrue("Vendor API level is not Android 12 or later.",
+ IS_VENDOR_AT_LEAST_S);
testTunneledAudioProgressWithUnderrun(MediaFormat.MIMETYPE_VIDEO_AVC,
"video_480x360_mp4_h264_1000kbps_25fps_aac_stereo_128kbps_44100hz.mp4");
}
@@ -3899,6 +3931,10 @@
@ApiTest(apis={"android.media.MediaCodecInfo.CodecCapabilities#FEATURE_TunneledPlayback"})
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.S)
public void testTunneledAudioProgressWithUnderrunVp9() throws Exception {
+ // New requirements and tests were added in Android 12, but upgrading devices are not
+ // required to adhere to them.
+ Assume.assumeTrue("Vendor API level is not Android 12 or later.",
+ IS_VENDOR_AT_LEAST_S);
testTunneledAudioProgressWithUnderrun(MediaFormat.MIMETYPE_VIDEO_VP9,
"bbb_s1_640x360_webm_vp9_0p21_1600kbps_30fps_vorbis_stereo_128kbps_48000hz.webm");
}
@@ -4067,7 +4103,8 @@
@ApiTest(apis={"android.media.MediaCodecInfo.CodecCapabilities#FEATURE_TunneledPlayback"})
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.S)
public void testTunneledAccurateVideoFlushHevc() throws Exception {
- // Requires vendor changes to support this.
+ // New requirements and tests were added in Android 12, but upgrading devices are not
+ // required to adhere to them.
Assume.assumeTrue("Vendor API level is not Android 12 or later.",
IS_VENDOR_AT_LEAST_S);
testTunneledAccurateVideoFlush(MediaFormat.MIMETYPE_VIDEO_HEVC,
@@ -4081,7 +4118,8 @@
@ApiTest(apis={"android.media.MediaCodecInfo.CodecCapabilities#FEATURE_TunneledPlayback"})
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.S)
public void testTunneledAccurateVideoFlushAvc() throws Exception {
- // Requires vendor changes to support this.
+ // New requirements and tests were added in Android 12, but upgrading devices are not
+ // required to adhere to them.
Assume.assumeTrue("Vendor API level is not Android 12 or later.",
IS_VENDOR_AT_LEAST_S);
testTunneledAccurateVideoFlush(MediaFormat.MIMETYPE_VIDEO_AVC,
@@ -4095,7 +4133,8 @@
@ApiTest(apis={"android.media.MediaCodecInfo.CodecCapabilities#FEATURE_TunneledPlayback"})
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.S)
public void testTunneledAccurateVideoFlushVp9() throws Exception {
- // Requires vendor changes to support this.
+ // New requirements and tests were added in Android 12, but upgrading devices are not
+ // required to adhere to them.
Assume.assumeTrue("Vendor API level is not Android 12 or later.",
IS_VENDOR_AT_LEAST_S);
testTunneledAccurateVideoFlush(MediaFormat.MIMETYPE_VIDEO_VP9,
@@ -4162,6 +4201,10 @@
@ApiTest(apis={"android.media.MediaCodecInfo.CodecCapabilities#FEATURE_TunneledPlayback"})
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.S)
public void testTunneledAudioProgressWithPauseHevc() throws Exception {
+ // New requirements and tests were added in Android 12, but upgrading devices are not
+ // required to adhere to them.
+ Assume.assumeTrue("Vendor API level is not Android 12 or later.",
+ IS_VENDOR_AT_LEAST_S);
testTunneledAudioProgressWithPause(MediaFormat.MIMETYPE_VIDEO_HEVC,
"video_1280x720_mkv_h265_500kbps_25fps_aac_stereo_128kbps_44100hz.mkv");
}
@@ -4173,6 +4216,10 @@
@ApiTest(apis={"android.media.MediaCodecInfo.CodecCapabilities#FEATURE_TunneledPlayback"})
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.S)
public void testTunneledAudioProgressWithPauseAvc() throws Exception {
+ // New requirements and tests were added in Android 12, but upgrading devices are not
+ // required to adhere to them.
+ Assume.assumeTrue("Vendor API level is not Android 12 or later.",
+ IS_VENDOR_AT_LEAST_S);
testTunneledAudioProgressWithPause(MediaFormat.MIMETYPE_VIDEO_AVC,
"video_480x360_mp4_h264_1000kbps_25fps_aac_stereo_128kbps_44100hz.mp4");
}
@@ -4184,6 +4231,10 @@
@ApiTest(apis={"android.media.MediaCodecInfo.CodecCapabilities#FEATURE_TunneledPlayback"})
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.S)
public void testTunneledAudioProgressWithPauseVp9() throws Exception {
+ // New requirements and tests were added in Android 12, but upgrading devices are not
+ // required to adhere to them.
+ Assume.assumeTrue("Vendor API level is not Android 12 or later.",
+ IS_VENDOR_AT_LEAST_S);
testTunneledAudioProgressWithPause(MediaFormat.MIMETYPE_VIDEO_VP9,
"bbb_s1_640x360_webm_vp9_0p21_1600kbps_30fps_vorbis_stereo_128kbps_48000hz.webm");
}
@@ -4357,6 +4408,10 @@
@ApiTest(apis={"android.media.MediaCodecInfo.CodecCapabilities#FEATURE_TunneledPlayback"})
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.S)
public void testTunneledAudioUnderrunHevc() throws Exception {
+ // New requirements and tests were added in Android 12, but upgrading devices are not
+ // required to adhere to them.
+ Assume.assumeTrue("Vendor API level is not Android 12 or later.",
+ IS_VENDOR_AT_LEAST_S);
tunneledAudioUnderrun(MediaFormat.MIMETYPE_VIDEO_HEVC,
"video_1280x720_mkv_h265_500kbps_25fps_aac_stereo_128kbps_44100hz.mkv");
}
@@ -4368,6 +4423,10 @@
@ApiTest(apis={"android.media.MediaCodecInfo.CodecCapabilities#FEATURE_TunneledPlayback"})
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.S)
public void testTunneledAudioUnderrunAvc() throws Exception {
+ // New requirements and tests were added in Android 12, but upgrading devices are not
+ // required to adhere to them.
+ Assume.assumeTrue("Vendor API level is not Android 12 or later.",
+ IS_VENDOR_AT_LEAST_S);
tunneledAudioUnderrun(MediaFormat.MIMETYPE_VIDEO_AVC,
"video_480x360_mp4_h264_1000kbps_25fps_aac_stereo_128kbps_44100hz.mp4");
}
@@ -4379,6 +4438,10 @@
@ApiTest(apis={"android.media.MediaCodecInfo.CodecCapabilities#FEATURE_TunneledPlayback"})
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.S)
public void testTunneledAudioUnderrunVp9() throws Exception {
+ // New requirements and tests were added in Android 12, but upgrading devices are not
+ // required to adhere to them.
+ Assume.assumeTrue("Vendor API level is not Android 12 or later.",
+ IS_VENDOR_AT_LEAST_S);
tunneledAudioUnderrun(MediaFormat.MIMETYPE_VIDEO_VP9,
"bbb_s1_640x360_webm_vp9_0p21_1600kbps_30fps_vorbis_stereo_128kbps_48000hz.webm");
}
diff --git a/tests/tests/media/misc/src/android/media/misc/cts/MediaCodecListTest.java b/tests/tests/media/misc/src/android/media/misc/cts/MediaCodecListTest.java
index af0544c..934b57d 100644
--- a/tests/tests/media/misc/src/android/media/misc/cts/MediaCodecListTest.java
+++ b/tests/tests/media/misc/src/android/media/misc/cts/MediaCodecListTest.java
@@ -434,7 +434,10 @@
list.add(new VideoCodec(MediaFormat.MIMETYPE_VIDEO_HEVC, false)); // hevc decoder
}
list.add(new VideoCodec(MediaFormat.MIMETYPE_VIDEO_MPEG4, false)); // m4v decoder
- list.add(new VideoCodec(MediaFormat.MIMETYPE_VIDEO_H263, false)); // h263 decoder
+ // According to CDD, H263 decoding is not mandatory for automotive.
+ if (!isAutomotive()) {
+ list.add(new VideoCodec(MediaFormat.MIMETYPE_VIDEO_H263, false)); // h263 decoder
+ }
if (hasCamera()) {
list.add(new VideoCodec(MediaFormat.MIMETYPE_VIDEO_H263, true)); // h263 encoder
}
diff --git a/tests/tests/media/misc/src/android/media/misc/cts/ResourceManagerStubActivity.java b/tests/tests/media/misc/src/android/media/misc/cts/ResourceManagerStubActivity.java
index 7dd6922..339ce48 100644
--- a/tests/tests/media/misc/src/android/media/misc/cts/ResourceManagerStubActivity.java
+++ b/tests/tests/media/misc/src/android/media/misc/cts/ResourceManagerStubActivity.java
@@ -169,6 +169,12 @@
Intent intent2 = new Intent(context, ResourceManagerTestActivity2.class);
intent2.putExtra("test-type", mType2);
intent2.putExtra("high-resolution", highResolutionForActivity2);
+ if (!highResolutionForActivity2) {
+ // If the codec is to configure at lower resolution,
+ // we should be able to create MAX_INSTANCES even on low ram devices.
+ // This will override the value from getMaxCodecInstances().
+ intent2.putExtra("max-codec-instances", MAX_INSTANCES);
+ }
startActivityForResult(intent2, mRequestCodes[1]);
waitForActivitiesToComplete();
diff --git a/tests/tests/media/misc/src/android/media/misc/cts/ResourceManagerTestActivity2.java b/tests/tests/media/misc/src/android/media/misc/cts/ResourceManagerTestActivity2.java
index a731389..2eea514 100644
--- a/tests/tests/media/misc/src/android/media/misc/cts/ResourceManagerTestActivity2.java
+++ b/tests/tests/media/misc/src/android/media/misc/cts/ResourceManagerTestActivity2.java
@@ -17,6 +17,7 @@
package android.media.misc.cts;
import android.content.Context;
+import android.os.Bundle;
import android.util.Log;
public class ResourceManagerTestActivity2 extends ResourceManagerTestActivityBase {
@@ -32,6 +33,13 @@
// and eventually reclaim a codec from the background activity.
Context context = getApplicationContext();
int maxCodecInstances = ResourceManagerStubActivity.getMaxCodecInstances(context);
+
+ // Check whether the test is overriding the max-codec-instances.
+ Bundle extras = getIntent().getExtras();
+ if (extras != null) {
+ maxCodecInstances = extras.getInt("max-codec-instances", maxCodecInstances);
+ }
+
int codecCount = allocateCodecs(maxCodecInstances);
int result = RESULT_OK;
// See if we have failed to create at least one codec.
diff --git a/tests/tests/mimemap/Android.bp b/tests/tests/mimemap/Android.bp
index 8dc3409..e18d7fc 100644
--- a/tests/tests/mimemap/Android.bp
+++ b/tests/tests/mimemap/Android.bp
@@ -29,6 +29,7 @@
static_libs: [
"ctstestrunner-axt",
"mimemap-testing",
+ "mimemap-testing-alt",
],
test_suites: [
"cts",
diff --git a/tests/tests/mimemap/src/android/content/type/cts/MimeMapTest.java b/tests/tests/mimemap/src/android/content/type/cts/MimeMapTest.java
index 935f13b..3815cf5 100644
--- a/tests/tests/mimemap/src/android/content/type/cts/MimeMapTest.java
+++ b/tests/tests/mimemap/src/android/content/type/cts/MimeMapTest.java
@@ -16,7 +16,14 @@
package android.content.type.cts;
-import android.content.type.cts.StockAndroidMimeMapFactory;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import libcore.content.type.MimeMap;
import org.junit.Before;
import org.junit.Test;
@@ -43,6 +50,9 @@
/** Stock Android's default MimeMap. */
private MimeMap stockAndroidMimeMap;
+ /** Stock Android's default MimeMap. */
+ private MimeMap stockAndroidAltMimeMap;
+
/** The platform's actual default MimeMap. */
private MimeMap mimeMap;
@@ -53,6 +63,9 @@
// The resources are placed into the testres/ path by the "mimemap-testing-res.jar" genrule.
stockAndroidMimeMap = StockAndroidMimeMapFactory.create(
s -> MimeMapTest.class.getResourceAsStream("/testres/" + s));
+ stockAndroidAltMimeMap =
+ StockAndroidAltMimeMapFactory.create(
+ s -> MimeMapTest.class.getResourceAsStream("/testres-alt/" + s));
}
@Test
@@ -247,27 +260,39 @@
}
@Test public void containsAllStockAndroidMappings_mimeToExt() {
+ assertTrue(
+ mimeToExtAsExpected(stockAndroidMimeMap, mimeMap)
+ || mimeToExtAsExpected(stockAndroidAltMimeMap, mimeMap));
+ }
+
+ private static boolean mimeToExtAsExpected(MimeMap stockMimeMap, MimeMap actualMimeMap) {
// The minimum expected mimeType -> extension mappings that should be present.
TreeMap<String, String> expected = new TreeMap<>();
// The extensions that these mimeTypes are actually mapped to.
TreeMap<String, String> actual = new TreeMap<>();
- for (String mimeType : stockAndroidMimeMap.mimeTypes()) {
- expected.put(mimeType, stockAndroidMimeMap.guessExtensionFromMimeType(mimeType));
- actual.put(mimeType, mimeMap.guessExtensionFromMimeType(mimeType));
+ for (String mimeType : stockMimeMap.mimeTypes()) {
+ expected.put(mimeType, stockMimeMap.guessExtensionFromMimeType(mimeType));
+ actual.put(mimeType, actualMimeMap.guessExtensionFromMimeType(mimeType));
}
- assertEquals(expected, actual);
+ return expected.equals(actual);
}
@Test public void containsAllExpectedMappings_extToMime() {
+ assertTrue(
+ extToMimeAsExpected(stockAndroidMimeMap, mimeMap)
+ || extToMimeAsExpected(stockAndroidAltMimeMap, mimeMap));
+ }
+
+ private static boolean extToMimeAsExpected(MimeMap stockMimeMap, MimeMap actualMimeMap) {
// The minimum expected extension -> mimeType mappings that should be present.
TreeMap<String, String> expected = new TreeMap<>();
// The mimeTypes that these extensions are actually mapped to.
TreeMap<String, String> actual = new TreeMap<>();
- for (String extension : stockAndroidMimeMap.extensions()) {
- expected.put(extension, stockAndroidMimeMap.guessMimeTypeFromExtension(extension));
- actual.put(extension, mimeMap.guessMimeTypeFromExtension(extension));
+ for (String extension : stockMimeMap.extensions()) {
+ expected.put(extension, stockMimeMap.guessMimeTypeFromExtension(extension));
+ actual.put(extension, actualMimeMap.guessMimeTypeFromExtension(extension));
}
- assertEquals(expected, actual);
+ return expected.equals(actual);
}
/**
diff --git a/tests/tests/notification/src/android/app/notification/current/cts/SensitiveNotificationRedactionTest.kt b/tests/tests/notification/src/android/app/notification/current/cts/SensitiveNotificationRedactionTest.kt
index 4d996be..e4ad314 100644
--- a/tests/tests/notification/src/android/app/notification/current/cts/SensitiveNotificationRedactionTest.kt
+++ b/tests/tests/notification/src/android/app/notification/current/cts/SensitiveNotificationRedactionTest.kt
@@ -31,6 +31,7 @@
import android.app.NotificationManager
import android.app.PendingIntent
import android.app.Person
+import android.app.role.RoleManager
import android.app.stubs.R
import android.app.stubs.shared.NotificationHelper.SEARCH_TYPE
import android.companion.CompanionDeviceManager
@@ -46,6 +47,7 @@
import android.platform.test.annotations.RequiresFlagsDisabled
import android.platform.test.annotations.RequiresFlagsEnabled
import android.platform.test.flag.junit.DeviceFlagsValueProvider
+import android.provider.Telephony
import android.service.notification.Adjustment
import android.service.notification.Adjustment.KEY_IMPORTANCE
import android.service.notification.Adjustment.KEY_RANKING_SCORE
@@ -54,14 +56,18 @@
import android.service.notification.StatusBarNotification
import androidx.test.runner.AndroidJUnit4
import com.android.compatibility.common.util.CddTest
+import com.android.compatibility.common.util.SystemUtil.callWithShellPermissionIdentity
import com.android.compatibility.common.util.SystemUtil.runShellCommand
import com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity
import com.android.compatibility.common.util.UserHelper
import com.google.common.truth.Truth.assertWithMessage
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.Executors
import org.junit.Assert
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Assume.assumeFalse
+import org.junit.Assume.assumeNotNull
import org.junit.Before
import org.junit.Rule
import org.junit.Test
@@ -454,49 +460,68 @@
mPreviousEnabledAssistant != null
)
mNotificationHelper.disableAssistant(STUB_PACKAGE_NAME)
+ val existingSmsApp = callWithShellPermissionIdentity {
+ Telephony.Sms.getDefaultSmsPackage(mContext)
+ }
+ assumeNotNull(existingSmsApp)
+ setSmsApp(mContext.packageName)
mNotificationHelper.enableOtherPkgAssistantIfNeeded(mPreviousEnabledAssistant)
// We just re-enabled the NAS. send one notification in order to start its process
sendNotification(text = "staring NAS process", title = "", subtext = "", tag = "start")
waitForNotification(tag = "start")
val shouldRedact = mutableListOf(
- "123G5",
- "123456F8",
- "123Ä·4",
- "123Ŀ4",
+ "your code is 123G5",
+ "your code is 123456F8",
+ "your code is 123Ä·4",
+ "your code is 123Ŀ4",
"1-1-01 is the date of your code T3425",
"your code 54-234-3 was sent on 1-1-01",
- "34-58-30",
- "12-1-3089",
- "G-3d523",
- "G-FD-745",
+ "your code is 34-58-30",
+ "your code is 12-1-3089",
+ "your code is G-3d523",
+ "your code is G-FD-745",
"your code is:G-345821",
"your code is (G-345821",
"your code is \nG-345821",
"you code is G-345821.",
- "you code is (G-345821)",
- "c'est g4zy75",
- "2109",
- "3035",
- "1899")
+ "you code is (G-345821)")
var notifNum = 0
val notRedactedFailures = StringBuilder("")
- for (otp in shouldRedact) {
- val tag = "$groupKey #$notifNum"
- sendNotification(text = otp, title = "", subtext = "", tag = tag)
- val sbn = waitForNotification(tag = tag)
- val text = sbn.notification.extras.getCharSequence(EXTRA_TEXT)!!.toString()
- if (text.contains(otp)) {
- notRedactedFailures.append("otp \"$otp\" is in notification text \"$text\"\n")
+ try {
+ // Newly enabled NAS can sometimes take a short while to start properly responding
+ for (i in 0..20) {
+ val basicOtp = "your one time code is 3434"
+ val tag = groupKey
+ sendNotification(text = basicOtp, title = "", subtext = "", tag = tag)
+ val sbn = waitForNotification(tag = tag)
+ val text = sbn.notification.extras.getCharSequence(EXTRA_TEXT)!!.toString()
+ if (!text.contains(basicOtp)) {
+ // Detector is up and running
+ break
+ }
+ Thread.sleep(100)
}
- notifNum += 1
- }
- if (notRedactedFailures.toString() != "") {
- Assert.fail(
- "The following codes were not redacted, but should have been:" +
- "\n$notRedactedFailures"
- )
+ for (otp in shouldRedact) {
+ val tag = "$groupKey #$notifNum"
+ sendNotification(text = otp, title = "", subtext = "", tag = tag)
+ val sbn = waitForNotification(tag = tag)
+ val text = sbn.notification.extras.getCharSequence(EXTRA_TEXT)!!.toString()
+ if (text.contains(otp)) {
+ notRedactedFailures.append("otp \"$otp\" is in notification text \"$text\"\n")
+ }
+ notifNum += 1
+ }
+
+ if (notRedactedFailures.toString() != "") {
+ Assert.fail(
+ "The following codes were not redacted, but should have been:" +
+ "\n$notRedactedFailures"
+ )
+ }
+ } finally {
+ setSmsApp(existingSmsApp)
}
}
@@ -511,6 +536,11 @@
mPreviousEnabledAssistant != null
)
mNotificationHelper.disableAssistant(STUB_PACKAGE_NAME)
+ val existingSmsApp = callWithShellPermissionIdentity {
+ Telephony.Sms.getDefaultSmsPackage(mContext)
+ }
+ assumeNotNull(existingSmsApp)
+ setSmsApp(mContext.packageName)
mNotificationHelper.enableOtherPkgAssistantIfNeeded(mPreviousEnabledAssistant)
// We just re-enabled the NAS. send one notification in order to start its process
sendNotification(text = "staring NAS process", title = "", subtext = "", tag = "start")
@@ -518,44 +548,77 @@
val shouldNotRedact =
mutableListOf(
- "123G",
- "123",
- "12 345",
- "123T56789",
- "TEFHXES",
- "01-01-2001",
- "1-1-2001",
- "1-1-01",
- "6--7893",
- "------",
+ "your code is 123G.",
+ "your code is 123",
+ "your code is 12 345",
+ "your code is 123T56789",
+ "your code is TEFHXES",
+ "your code is 01-01-2001",
+ "your code is 1-1-2001",
+ "your code is 1-1-01",
+ "your code is 6--7893",
+ "your code is ------",
"your code isG-345821",
"your code is G-345821for real",
- "GVRXY 2",
- "2009",
- "1945",
+ "your code is GVRXY 2",
)
var notifNum = 0
val redactedFailures = StringBuilder("")
- for (notOtp in shouldNotRedact) {
- val tag = "$groupKey #$notifNum"
- sendNotification(text = notOtp, title = "", subtext = "", tag = tag)
- val sbn = waitForNotification(tag = tag)
- val text = sbn.notification.extras.getCharSequence(EXTRA_TEXT)!!.toString()
- if (!text.contains(notOtp)) {
- redactedFailures.append(
- "non-otp message \"$notOtp\" is not in notification text " +
- "\"$text\"\n"
+ try {
+ // Newly enabled NAS can sometimes take a short while to start properly responding
+ for (i in 0..20) {
+ val basicOtp = "your one time code is 3434"
+ val tag = groupKey
+ sendNotification(text = basicOtp, title = "", subtext = "", tag = tag)
+ val sbn = waitForNotification(tag = tag)
+ val text = sbn.notification.extras.getCharSequence(EXTRA_TEXT)!!.toString()
+ if (!text.contains(basicOtp)) {
+ // Detector is up and running
+ break
+ }
+ Thread.sleep(100)
+ }
+
+ for (notOtp in shouldNotRedact) {
+ val tag = "$groupKey #$notifNum"
+ sendNotification(text = notOtp, title = "", subtext = "", tag = tag)
+ val sbn = waitForNotification(tag = tag)
+ val text = sbn.notification.extras.getCharSequence(EXTRA_TEXT)!!.toString()
+ if (!text.contains(notOtp)) {
+ redactedFailures.append(
+ "non-otp message \"$notOtp\" is not in notification text " +
+ "\"$text\"\n"
+ )
+ }
+ notifNum += 1
+ }
+
+ if (redactedFailures.toString() != "") {
+ Assert.fail(
+ "The following codes were redacted, but should not have been:" +
+ "\n$redactedFailures"
)
}
- notifNum += 1
+ } finally {
+ setSmsApp(existingSmsApp)
}
+ }
- if (redactedFailures.toString() != "") {
- Assert.fail(
- "The following codes were redacted, but should not have been:" +
- "\n$redactedFailures"
- )
+ private fun setSmsApp(packageName: String) {
+ val latch = CountDownLatch(1)
+ runWithShellPermissionIdentity {
+ mRoleManager.addRoleHolderAsUser(
+ RoleManager.ROLE_SMS,
+ packageName,
+ 0,
+ Process.myUserHandle(),
+ Executors.newSingleThreadExecutor()
+ ) { success ->
+ assertTrue("Failed to set sms role holder", success)
+ latch.countDown()
+ }
}
+ latch.await()
}
private fun assertNotificationNotRedacted() {
diff --git a/tests/tests/os/src/android/os/cts/LowPowerStandbyTest.java b/tests/tests/os/src/android/os/cts/LowPowerStandbyTest.java
index 7eb8290..970dd53 100644
--- a/tests/tests/os/src/android/os/cts/LowPowerStandbyTest.java
+++ b/tests/tests/os/src/android/os/cts/LowPowerStandbyTest.java
@@ -58,9 +58,9 @@
import com.android.bedstead.harrier.BedsteadJUnit4;
import com.android.bedstead.harrier.DeviceState;
-import com.android.bedstead.permissions.annotations.EnsureHasPermission;
import com.android.bedstead.nene.TestApis;
import com.android.bedstead.permissions.PermissionContext;
+import com.android.bedstead.permissions.annotations.EnsureHasPermission;
import com.android.compatibility.common.util.ApiTest;
import com.android.compatibility.common.util.BlockingBroadcastReceiver;
import com.android.compatibility.common.util.CallbackAsserter;
@@ -141,6 +141,7 @@
@Test
@ApiTest(apis = "android.os.PowerManager#setLowPowerStandbyEnabled")
+ @AppModeFull(reason = "Instant app CTS tests hold shell permissions which include DEVICE_POWER")
public void testSetLowPowerStandbyEnabled_withoutPermission_throwsSecurityException() {
try {
mPowerManager.setLowPowerStandbyEnabled(false);
diff --git a/tests/tests/packageinstaller/packagescheme/Android.bp b/tests/tests/packageinstaller/packagescheme/Android.bp
index 13633b2..7d0beee 100644
--- a/tests/tests/packageinstaller/packagescheme/Android.bp
+++ b/tests/tests/packageinstaller/packagescheme/Android.bp
@@ -32,13 +32,14 @@
"kotlin-test",
"truth",
"androidx.test.uiautomator_uiautomator",
+ "compatibility-device-util-axt",
],
platform_apis: true,
test_suites: [
"cts",
"general-tests",
],
- java_resources: [
+ data: [
":CtsEmptyTestApp",
],
test_config: "AndroidTestNoVisibility.xml",
@@ -59,13 +60,14 @@
"kotlin-test",
"truth",
"androidx.test.uiautomator_uiautomator",
+ "compatibility-device-util-axt",
],
platform_apis: true,
test_suites: [
"cts",
"general-tests",
],
- java_resources: [
+ data: [
":CtsEmptyTestApp",
],
test_config: "AndroidTestVisibility.xml",
diff --git a/tests/tests/packageinstaller/packagescheme/AndroidTestNoVisibility.xml b/tests/tests/packageinstaller/packagescheme/AndroidTestNoVisibility.xml
index 935002d..e9925c7 100644
--- a/tests/tests/packageinstaller/packagescheme/AndroidTestNoVisibility.xml
+++ b/tests/tests/packageinstaller/packagescheme/AndroidTestNoVisibility.xml
@@ -44,6 +44,10 @@
<!-- dismiss all system dialogs before launch test -->
<option name="run-command" value="am broadcast -a android.intent.action.CLOSE_SYSTEM_DIALOGS" />
</target_preparer>
+ <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
+ <option name="cleanup" value="true" />
+ <option name="push" value="CtsEmptyTestApp.apk->/data/local/tmp/cts/packagescheme/CtsEmptyTestApp.apk" />
+ </target_preparer>
<test class="com.android.tradefed.testtype.AndroidJUnitTest">
<option name="package" value="android.packageinstaller.packagescheme.cts.withoutvisibility" />
diff --git a/tests/tests/packageinstaller/packagescheme/AndroidTestVisibility.xml b/tests/tests/packageinstaller/packagescheme/AndroidTestVisibility.xml
index 4ff7e0c..efaab01 100644
--- a/tests/tests/packageinstaller/packagescheme/AndroidTestVisibility.xml
+++ b/tests/tests/packageinstaller/packagescheme/AndroidTestVisibility.xml
@@ -44,6 +44,10 @@
<!-- dismiss all system dialogs before launch test -->
<option name="run-command" value="am broadcast -a android.intent.action.CLOSE_SYSTEM_DIALOGS" />
</target_preparer>
+ <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
+ <option name="cleanup" value="true" />
+ <option name="push" value="CtsEmptyTestApp.apk->/data/local/tmp/cts/packagescheme/CtsEmptyTestApp.apk" />
+ </target_preparer>
<test class="com.android.tradefed.testtype.AndroidJUnitTest">
<option name="package" value="android.packageinstaller.packagescheme.cts.withvisibility" />
diff --git a/tests/tests/packageinstaller/packagescheme/src/android/packageinstaller/packagescheme/cts/PackageSchemeTestBase.kt b/tests/tests/packageinstaller/packagescheme/src/android/packageinstaller/packagescheme/cts/PackageSchemeTestBase.kt
index c1f41f0..a505b0b 100644
--- a/tests/tests/packageinstaller/packagescheme/src/android/packageinstaller/packagescheme/cts/PackageSchemeTestBase.kt
+++ b/tests/tests/packageinstaller/packagescheme/src/android/packageinstaller/packagescheme/cts/PackageSchemeTestBase.kt
@@ -16,14 +16,9 @@
package android.packageinstaller.packagescheme.cts
-import android.Manifest
import android.app.Activity
-import android.app.PendingIntent
-import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
-import android.content.IntentFilter
-import android.content.pm.PackageInstaller
import android.net.Uri
import android.os.Bundle
import android.util.Log
@@ -37,22 +32,18 @@
import androidx.test.uiautomator.UiScrollable
import androidx.test.uiautomator.UiSelector
import androidx.test.uiautomator.Until
+import com.android.compatibility.common.util.SystemUtil
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertWithMessage
-import java.io.InputStream
-import java.util.concurrent.ArrayBlockingQueue
import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
-import java.util.function.Supplier
import java.util.regex.Pattern
import org.junit.After
import org.junit.Before
open class PackageSchemeTestBase {
- val LOG_TAG = PackageSchemeTestBase::class.java.simpleName
+ val BASE_PATH = "/data/local/tmp/cts/packagescheme/"
val TARGET_APP_PKG_NAME = "android.packageinstaller.emptytestapp.cts"
- val TARGET_APP_APK = "CtsEmptyTestApp.apk"
- val RECEIVER_ACTION = "android.packageinstaller.emptytestapp.cts.action"
+ val TARGET_APP_APK = BASE_PATH + "CtsEmptyTestApp.apk"
val POSITIVE_BTN_ID = "button1"
val NEGATIVE_BTN_ID = "button2"
val SYSTEM_PACKAGE_NAME = "android"
@@ -64,7 +55,6 @@
val mUiDevice = UiDevice.getInstance(mInstrumentation)
var mButton: UiObject2? = null
val mContext: Context = mInstrumentation.context
- val mInstaller: PackageInstaller = mContext.packageManager.packageInstaller
class TestActivity : Activity() {
val mLatch: CountDownLatch = CountDownLatch(1)
@@ -84,66 +74,22 @@
}
}
- private val receiver = object : BroadcastReceiver() {
- private val results = ArrayBlockingQueue<Intent>(1)
-
- override fun onReceive(context: Context, intent: Intent) {
- // Added as a safety net. Have observed instances where the Queue isn't empty which
- // causes the test suite to crash.
- if (results.size != 0) {
- clear()
- }
- results.add(intent)
- }
-
- fun makeIntentSender(sessionId: Int) = PendingIntent.getBroadcast(
- mContext,
- sessionId,
- Intent(RECEIVER_ACTION)
- .setPackage(mContext.packageName)
- .addFlags(Intent.FLAG_RECEIVER_FOREGROUND),
- PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE_UNAUDITED
- ).intentSender
-
- fun getResult(unit: TimeUnit, timeout: Long) = results.poll(timeout, unit)
-
- fun clear() = results.clear()
- }
-
- @Before
- fun setup() {
- receiver.clear()
- mContext.registerReceiver(
- receiver,
- IntentFilter(RECEIVER_ACTION),
- Context.RECEIVER_EXPORTED
- )
- }
-
@Before
@After
fun uninstall() {
- mInstrumentation.uiAutomation.executeShellCommand("pm uninstall $TARGET_APP_PKG_NAME")
- }
-
- @After
- fun tearDown() {
- mContext.unregisterReceiver(receiver)
- mInstrumentation.uiAutomation.dropShellPermissionIdentity()
+ SystemUtil.runShellCommand("pm uninstall $TARGET_APP_PKG_NAME")
}
fun runTest(packageName: String, packageHasVisibility: Boolean, needTargetApp: Boolean) {
if (packageHasVisibility) {
- mInstrumentation.uiAutomation.executeShellCommand(
- "appops set $packageName android:query_all_packages allow"
- )
- mInstrumentation.uiAutomation.executeShellCommand(
+ SystemUtil.runShellCommand("appops set $packageName android:query_all_packages allow")
+ SystemUtil.runShellCommand(
"appops set $packageName android:request_install_packages allow"
)
}
if (needTargetApp) {
- installTargetApp(resourceSupplier(TARGET_APP_APK))
+ installTargetApp()
}
val intent = Intent(ApplicationProvider.getApplicationContext(), TestActivity::class.java)
@@ -185,47 +131,10 @@
mScenario!!.close()
}
- private fun installTargetApp(apkStreamSupplier: Supplier<InputStream>) {
- setupPermissions()
- val params = PackageInstaller.SessionParams(
- PackageInstaller.SessionParams.MODE_FULL_INSTALL
- )
- params.setRequireUserAction(PackageInstaller.SessionParams.USER_ACTION_NOT_REQUIRED)
- val sessionId: Int = mInstaller.createSession(params)
- val session: PackageInstaller.Session = mInstaller.openSession(sessionId)
-
- session.openWrite("apk", 0, -1).use { os ->
- apkStreamSupplier.get().copyTo(os)
- }
-
- session.commit(receiver.makeIntentSender(sessionId))
- session.close()
-
- val result = receiver.getResult(TimeUnit.SECONDS, 30)
- val installStatus = result.getIntExtra(PackageInstaller.EXTRA_STATUS, Int.MIN_VALUE)
- if (installStatus != PackageInstaller.STATUS_SUCCESS) {
- val id = result.getIntExtra(PackageInstaller.EXTRA_SESSION_ID, Int.MIN_VALUE)
- try {
- mInstaller.abandonSession(id)
- } catch (e: SecurityException) {
- Log.w(LOG_TAG, "Could not abandon session: ${e.message}")
- }
- }
- assertThat(installStatus).isEqualTo(PackageInstaller.STATUS_SUCCESS)
- }
-
- private fun resourceSupplier(resourceName: String): Supplier<InputStream> {
- return Supplier<InputStream> {
- val resourceAsStream = javaClass.classLoader.getResourceAsStream(resourceName)
- ?: throw RuntimeException("Resource $resourceName could not be found.")
- resourceAsStream
- }
- }
-
- private fun setupPermissions() {
- mInstrumentation.uiAutomation.adoptShellPermissionIdentity(
- Manifest.permission.INSTALL_PACKAGES
- )
+ private fun installTargetApp() {
+ assertThat(
+ SystemUtil.runShellCommand("pm install $TARGET_APP_APK").trim()
+ ).isEqualTo("Success")
}
private fun getAppInstallIntent(): Intent {
diff --git a/tests/tests/preference/AndroidTest.xml b/tests/tests/preference/AndroidTest.xml
index 5ced35f..adb8239 100644
--- a/tests/tests/preference/AndroidTest.xml
+++ b/tests/tests/preference/AndroidTest.xml
@@ -37,4 +37,9 @@
<option name="collect-on-run-ended-only" value="true" />
<option name="clean-up" value="false" />
</metrics_collector>
+ <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+ <!-- TODO(b/285554134): Remove once underlying issue is fixed-->
+ <option name="run-command" value="wm set-ignore-orientation-request false" />
+ <option name="run-command" value="wm set-letterbox-style --isEducationEnabled false" />
+ </target_preparer>
</configuration>
diff --git a/tests/tests/security/AndroidTest.xml b/tests/tests/security/AndroidTest.xml
index 27c2bd3..71a8286 100644
--- a/tests/tests/security/AndroidTest.xml
+++ b/tests/tests/security/AndroidTest.xml
@@ -20,6 +20,7 @@
<!-- CtsDeviceInfo target API is 23; instant app requires target API >= 26. -->
<option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
<option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
+ <option name="config-descriptor:metadata" key="parameter" value="secondary_user_on_secondary_display" />
<option name="config-descriptor:metadata" key="parameter" value="run_on_sdk_sandbox" />
<target_preparer class="com.android.tradefed.targetprep.DeviceSetup">
@@ -37,8 +38,9 @@
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.CrashReporter" />
<target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+ <option name="test-user-token" value="%TEST_USER%"/>
<option name="run-command"
- value="appops set android.security.cts REQUEST_INSTALL_PACKAGES allow" />
+ value="appops set --user %TEST_USER% android.security.cts REQUEST_INSTALL_PACKAGES allow" />
<option name="teardown-command"
value="appops reset android.security.cts" />
</target_preparer>
diff --git a/tests/tests/security/src/android/security/cts/BasePermissionUiTest.kt b/tests/tests/security/src/android/security/cts/BasePermissionUiTest.kt
index 201df17..a1555f2 100644
--- a/tests/tests/security/src/android/security/cts/BasePermissionUiTest.kt
+++ b/tests/tests/security/src/android/security/cts/BasePermissionUiTest.kt
@@ -37,6 +37,7 @@
import androidx.test.rule.ActivityTestRule
import com.android.compatibility.common.util.SystemUtil
import com.android.compatibility.common.util.UiAutomatorUtils
+import com.android.compatibility.common.util.UserHelper
import com.android.modules.utils.build.SdkLevel
import com.android.sts.common.util.StsExtraBusinessLogicTestCase
import org.junit.After
@@ -53,11 +54,15 @@
protected val packageManager = mContext.packageManager
protected val uiAutomation: UiAutomation = mInstrumentation.uiAutomation
protected val uiDevice: UiDevice = UiDevice.getInstance(mInstrumentation)
+ protected val uiDevice2: androidx.test.uiautomator.UiDevice =
+ androidx.test.uiautomator.UiDevice.getInstance(mInstrumentation)
protected val isAutomotive = packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)
protected val isTv = packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK)
protected val isWatch = packageManager.hasSystemFeature(PackageManager.FEATURE_WATCH)
+ protected val userHelper = UserHelper(mInstrumentation.context)
+
companion object {
const val SPLIT_PERMISSION_APK_PATH =
"/data/local/tmp/cts/security/SplitBluetoothPermissionTestApp.apk"
@@ -290,7 +295,17 @@
protected fun clickPermissionRequestDenyButton() {
if (isAutomotive || isWatch || isTv) {
- click(By.text(getPermissionControllerString(DENY_BUTTON_TEXT)))
+ if (isAutomotive && userHelper.isVisibleBackgroundUser()) {
+ // Visible background users are background users that have access to UI on assigned
+ // displays on devices that have config_multiuserVisibleBackgroundUsers enabled.
+ // The main use case is the passenger in Automotive's multi display configuration.
+ // TODO(b/382327037): Avoid specifying the display ID for each UiSelector.
+ uiDevice2.findObject(androidx.test.uiautomator.By.text(
+ getPermissionControllerString(DENY_BUTTON_TEXT))
+ .displayId(userHelper.mainDisplayId))!!.click()
+ } else {
+ click(By.text(getPermissionControllerString(DENY_BUTTON_TEXT)))
+ }
} else {
click(By.res(DENY_BUTTON))
}
@@ -298,7 +313,14 @@
protected fun clickPermissionRequestAllowButton(timeoutMillis: Long = 20000) {
if (isAutomotive) {
- click(By.text(getPermissionControllerString(ALLOW_BUTTON_TEXT)), timeoutMillis)
+ if (userHelper.isVisibleBackgroundUser()) {
+ // TODO(b/382327037): Avoid specifying the display ID for each UiSelector.
+ uiDevice2.findObject(androidx.test.uiautomator.By.text(
+ getPermissionControllerString(ALLOW_BUTTON_TEXT))
+ .displayId(userHelper.mainDisplayId))!!.click()
+ } else {
+ click(By.text(getPermissionControllerString(ALLOW_BUTTON_TEXT)), timeoutMillis)
+ }
} else {
click(By.res(ALLOW_BUTTON), timeoutMillis)
}
diff --git a/tests/tests/security/src/android/security/cts/CertificateData.java b/tests/tests/security/src/android/security/cts/CertificateData.java
index e0d276c..f7acdb1 100644
--- a/tests/tests/security/src/android/security/cts/CertificateData.java
+++ b/tests/tests/security/src/android/security/cts/CertificateData.java
@@ -24,153 +24,157 @@
* to generate this file.
*/
class CertificateData {
- static final String[] CERTIFICATE_DATA = {
- "99:9A:64:C3:7F:F4:7D:9F:AB:95:F1:47:69:89:14:60:EE:C4:C3:C5",
- "D1:CB:CA:5D:B2:D5:2A:7F:69:3B:67:4D:E5:F0:5A:1D:0C:95:7D:F0",
- "57:73:A5:61:5D:80:B2:E6:AC:38:82:FC:68:07:31:AC:9F:B5:92:5A",
- "6B:A0:B0:98:E1:71:EF:5A:AD:FE:48:15:80:77:10:F4:BD:6F:0B:28",
- "92:5A:8F:8D:2C:6D:04:E0:66:5F:59:6A:FF:22:D8:63:E8:25:6F:3F",
- "18:52:3B:0D:06:37:E4:D6:3A:DF:23:E4:98:FB:5B:16:FB:86:74:48",
- "B4:90:82:DD:45:0C:BE:8B:5B:B1:66:D3:E2:A4:08:26:CD:ED:42:CF",
- "53:A2:B0:4B:CA:6B:D6:45:E6:39:8A:8E:C4:0D:D2:BF:77:C3:A2:90",
- "58:E8:AB:B0:36:15:33:FB:80:F7:9B:1B:6D:29:D3:FF:8D:5F:00:F0",
- "55:A6:72:3E:CB:F2:EC:CD:C3:23:74:70:19:9D:2A:BE:11:E3:81:D1",
- "D6:9B:56:11:48:F0:1C:77:C5:45:78:C1:09:26:DF:5B:85:69:76:AD",
- "D0:67:C1:13:51:01:0C:AA:D0:C7:6A:65:37:31:16:26:4F:53:71:A2",
- "09:3C:61:F3:8B:8B:DC:7D:55:DF:75:38:02:05:00:E1:25:F5:C8:36",
- "27:96:BA:E6:3F:18:01:E2:77:26:1B:A0:D7:77:70:02:8F:20:EE:E4",
- "AD:7E:1C:28:B0:64:EF:8F:60:03:40:20:14:C3:D0:E3:37:0E:B5:8A",
- "17:F3:DE:5E:9F:0F:19:E9:8E:F6:1F:32:26:6E:20:C4:07:AE:30:EE",
- "1F:24:C6:30:CD:A4:18:EF:20:69:FF:AD:4F:DD:5F:46:3A:1B:69:AA",
- "EC:2C:83:40:72:AF:26:95:10:FF:0E:F2:03:EE:31:70:F6:78:9D:CA",
- "9E:BC:75:10:42:B3:02:F3:81:F4:F7:30:62:D4:8F:C3:A7:51:B2:DD",
- "DA:FA:F7:FA:66:84:EC:06:8F:14:50:BD:C7:C2:81:A5:BC:A9:64:57",
- "2D:0D:52:14:FF:9E:AD:99:24:01:74:20:47:6E:6C:85:27:27:F5:43",
- "28:F9:78:16:19:7A:FF:18:25:18:AA:44:FE:C1:A0:CE:5C:B6:4C:8A",
- "31:43:64:9B:EC:CE:27:EC:ED:3A:3F:0B:8F:0D:E4:E8:91:DD:EE:CA",
- "B7:AB:33:08:D1:EA:44:77:BA:14:80:12:5A:6F:BD:A9:36:49:0C:BB",
- "3C:3F:EF:57:0F:FE:65:93:86:9E:A0:FE:B0:F6:ED:8E:D1:13:C7:E5",
- "2B:8F:1B:57:33:0D:BB:A2:D0:7A:6C:51:F7:0E:E9:0D:DA:B9:AD:8E",
- "A8:98:5D:3A:65:E5:E5:C4:B2:D7:D6:6D:40:C6:DD:2F:B1:9C:54:36",
- "D4:DE:20:D0:5E:66:FC:53:FE:1A:50:88:2C:78:DB:28:52:CA:E4:74",
- "EC:8A:39:6C:40:F0:2E:BC:42:75:D4:9F:AB:1C:1A:5B:67:BE:D2:9A",
- "D8:C5:38:8A:B7:30:1B:1B:6E:D4:7A:E6:45:25:3A:6F:9F:1A:27:61",
- "E0:11:84:5E:34:DE:BE:88:81:B9:9C:F6:16:26:D1:96:1F:C3:B9:31",
- "93:05:7A:88:15:C6:4F:CE:88:2F:FA:91:16:52:28:78:BC:53:64:17",
- "50:30:06:09:1D:97:D4:F5:AE:39:F7:CB:E7:92:7D:7D:65:2D:34:31",
- "F3:3E:78:3C:AC:DF:F4:A2:CC:AC:67:55:69:56:D7:E5:16:3C:E1:ED",
- "8C:F4:27:FD:79:0C:3A:D1:66:06:8D:E8:1E:57:EF:BB:93:22:72:D4",
- "2F:78:3D:25:52:18:A7:4A:65:39:71:B5:2C:A2:9C:45:15:6F:E9:19",
- "BA:29:41:60:77:98:3F:F4:F3:EF:F2:31:05:3B:2E:EA:6D:4D:45:FD",
- "BC:B0:C1:9D:E9:98:92:70:19:38:57:E9:8D:A7:B4:5D:6E:EE:01:48",
- "9B:AA:E5:9F:56:EE:21:CB:43:5A:BE:25:93:DF:A7:F0:40:D1:1D:CB",
- "1B:8E:EA:57:96:29:1A:C9:39:EA:B8:0A:81:1A:73:73:C0:93:79:67",
- "6A:92:E4:A8:EE:1B:EC:96:45:37:E3:29:57:49:CD:96:E3:E5:D2:60",
- "74:3A:F0:52:9B:D0:32:A0:F4:4A:83:CD:D4:BA:A9:7B:7C:2E:C4:9A",
- "07:86:C0:D8:DD:8E:C0:80:98:06:98:D0:58:7A:EF:DE:A6:CC:A2:5D",
- "66:31:BF:9E:F7:4F:9E:B6:C9:D5:A6:0C:BA:6A:BE:D1:F7:BD:EF:7B",
- "77:D3:03:67:B5:E0:0C:15:F6:0C:38:61:DF:7C:E1:3B:92:46:4D:47",
- "F3:73:B3:87:06:5A:28:84:8A:F2:F3:4A:CE:19:2B:DD:C7:8E:9C:AC",
- "62:FF:D9:9E:C0:65:0D:03:CE:75:93:D2:ED:3F:2D:32:C9:E3:E5:4A",
- "F9:E1:6D:DC:01:89:CF:D5:82:45:63:3E:C5:37:7D:C2:EB:93:6F:2B",
- "06:08:3F:59:3F:15:A1:04:A0:69:A4:6B:A9:03:D0:06:B7:97:09:91",
- "CA:BD:2A:79:A1:07:6A:31:F2:1D:25:36:35:CB:03:9D:43:29:A5:E8",
- "43:13:BB:96:F1:D5:86:9B:C1:4E:6A:92:F6:CF:F6:34:69:87:82:37",
- "05:63:B8:63:0D:62:D7:5A:BB:C8:AB:1E:4B:DF:B5:A8:99:B2:4D:43",
- "ED:E5:71:80:2B:C8:92:B9:5B:83:3C:D2:32:68:3F:09:CD:A0:1E:46",
- "C3:03:C8:22:74:92:E5:61:A2:9C:5F:79:91:2B:1E:44:13:91:30:3A",
- "D1:EB:23:A4:6D:17:D6:8F:D9:25:64:C2:F1:F1:60:17:64:D8:E3:49",
- "B8:01:86:D1:EB:9C:86:A5:41:04:CF:30:54:F3:4C:52:B7:E5:58:C6",
- "4C:DD:51:A3:D1:F5:20:32:14:B0:C6:C5:32:23:03:91:C7:46:42:6D",
- "0D:44:DD:8C:3C:8C:1A:1A:58:75:64:81:E9:0F:2E:2A:FF:B3:D2:6E",
- "CA:3A:FB:CF:12:40:36:4B:44:B2:16:20:88:80:48:39:19:93:7C:F7",
- "F4:27:86:EB:6E:B8:6D:88:31:67:02:FB:BA:66:A4:53:00:AA:7A:A6",
- "5F:B7:EE:06:33:E2:59:DB:AD:0C:4C:9A:E6:D3:8F:1A:61:C7:DC:25",
- "49:0A:75:74:DE:87:0A:47:FE:58:EE:F6:C7:6B:EB:C6:0B:12:40:99",
- "89:D4:83:03:4F:9E:9A:48:80:5F:72:37:D4:A9:A6:EF:CB:7C:1F:D1",
- "B5:1C:06:7C:EE:2B:0C:3D:F8:55:AB:2D:92:F4:FE:39:D4:E7:0F:0E",
- "29:36:21:02:8B:20:ED:02:F5:66:C5:32:D1:D6:ED:90:9F:45:00:2F",
- "B6:AF:43:C2:9B:81:53:7D:F6:EF:6B:C3:1F:1F:60:15:0C:EE:48:66",
- "BD:B1:B9:3C:D5:97:8D:45:C6:26:14:55:F8:DB:95:C7:5A:D1:53:AF",
- "FA:B7:EE:36:97:26:62:FB:2D:B0:2A:F6:BF:03:FD:E8:7C:4B:2F:9B",
- "C3:19:7C:39:24:E6:54:AF:1B:C4:AB:20:95:7A:E2:C3:0E:13:02:6A",
- "9F:74:4E:9F:2B:4D:BA:EC:0F:31:2C:50:B6:56:3B:8E:2D:93:C3:11",
- "6D:0A:5F:F7:B4:23:06:B4:85:B3:B7:97:64:FC:AC:75:F5:33:F2:93",
- "A1:4B:48:D9:43:EE:0A:0E:40:90:4F:3C:E0:A4:C0:91:93:51:5D:3F",
- "E2:B8:29:4B:55:84:AB:6B:58:C2:90:46:6C:AC:3F:B8:39:8F:84:83",
- "1F:49:14:F7:D8:74:95:1D:DD:AE:02:C0:BE:FD:3A:2D:82:75:51:85",
- "5B:6E:68:D0:CC:15:B6:A0:5F:1E:C1:5F:AE:02:FC:6B:2F:5D:6F:74",
- "9F:F1:71:8D:92:D5:9A:F3:7D:74:97:B4:BC:6F:84:68:0B:BA:B6:66",
- "B5:61:EB:EA:A4:DE:E4:25:4B:69:1A:98:A5:57:47:C2:34:C7:D9:71",
- "73:A5:E6:4A:3B:FF:83:16:FF:0E:DC:CC:61:8A:90:6E:4E:AE:4D:74",
- "07:E0:32:E0:20:B7:2C:3F:19:2F:06:28:A2:59:3A:19:A7:0F:06:9E",
- "80:94:64:0E:B5:A7:A1:CA:11:9C:1F:DD:D5:9F:81:02:63:A7:FB:D1",
- "63:CF:B6:C1:27:2B:56:E4:88:8E:1C:23:9A:B6:2E:81:47:24:C3:C7",
- "84:1A:69:FB:F5:CD:1A:25:34:13:3D:E3:F8:FC:B8:99:D0:C9:14:B7",
- "E7:F3:A3:C8:CF:6F:C3:04:2E:6D:0E:67:32:C5:9E:68:95:0D:5E:D2",
- "67:65:0D:F1:7E:8E:7E:5B:82:40:A4:F4:56:4B:CF:E2:3D:69:C6:F0",
- "DD:FB:16:CD:49:31:C9:73:A2:03:7D:3F:C8:3A:4D:7D:77:5D:05:E4",
- "61:DB:8C:21:59:69:03:90:D8:7C:9C:12:86:54:CF:9D:3D:F4:DD:07",
- "E2:52:FA:95:3F:ED:DB:24:60:BD:6E:28:F3:9C:CC:CF:5E:B3:3F:DE",
- "26:F9:93:B4:ED:3D:28:27:B0:B9:4B:A7:E9:15:1D:A3:8D:92:E5:32",
- "3B:C4:9F:48:F8:F3:73:A0:9C:1E:BD:F8:5B:B1:C3:65:C7:D8:11:B3",
- "0F:36:38:5B:81:1A:25:C3:9B:31:4E:83:CA:E9:34:66:70:CC:74:B4",
- "9C:BB:48:53:F6:A4:F6:D3:52:A4:E8:32:52:55:60:13:F5:AD:AF:65",
- "B1:BC:96:8B:D4:F4:9D:62:2A:A8:9A:81:F2:15:01:52:A4:1D:82:9C",
- "1F:5B:98:F0:E3:B5:F7:74:3C:ED:E6:B0:36:7D:32:CD:F4:09:41:67",
- "20:D8:06:40:DF:9B:25:F5:12:25:3A:11:EA:F7:59:8A:EB:14:B5:47",
- "30:43:FA:4F:F2:57:DC:A0:C3:80:EE:2E:58:EA:78:B2:3F:E6:BB:C1",
- "CF:9E:87:6D:D3:EB:FC:42:26:97:A3:B5:A3:7A:A0:76:A9:06:23:48",
- "2B:B1:F5:3E:55:0C:1D:C5:F1:D4:E6:B7:6A:46:4B:55:06:02:AC:21",
- "02:2D:05:82:FA:88:CE:14:0C:06:79:DE:7F:14:10:E9:45:D7:A5:6D",
- "EC:50:35:07:B2:15:C4:95:62:19:E2:A8:9A:5B:42:99:2C:4C:2C:20",
- "47:BE:AB:C9:22:EA:E8:0E:78:78:34:62:A7:9F:45:C2:54:FD:E6:8B",
- "58:A2:D0:EC:20:52:81:5B:C1:F3:F8:64:02:24:4E:C2:8E:02:4B:02",
- "3A:44:73:5A:E5:81:90:1F:24:86:61:46:1E:3B:9C:C4:5F:F5:3A:1B",
- "B3:1E:B1:B7:40:E3:6C:84:02:DA:DC:37:D4:4D:F5:D4:67:49:52:F9",
- "A7:88:49:DC:5D:7C:75:8C:8C:DE:39:98:56:B3:AA:D0:B2:A5:71:35",
- "F5:17:A2:4F:9A:48:C6:C9:F8:A2:00:26:9F:DC:0F:48:2C:AB:30:89",
- "9A:44:49:76:32:DB:DE:FA:D0:BC:FB:5A:7B:17:BD:9E:56:09:24:94",
- "B8:0E:26:A9:BF:D2:B2:3B:C0:EF:46:C9:BA:C7:BB:F6:1D:0D:41:41",
- "DF:3C:24:F9:BF:D6:66:76:1B:26:80:73:FE:06:D1:CC:8D:4F:82:A4",
- "D3:DD:48:3E:2B:BF:4C:05:E8:AF:10:F5:FA:76:26:CF:D3:DC:30:92",
- "9F:5F:D9:1A:54:6D:F5:0C:71:F0:EE:7A:BD:17:49:98:84:73:E2:39",
- "B8:23:6B:00:2F:1D:16:86:53:01:55:6C:11:A4:37:CA:EB:FF:C3:BB",
- "87:82:C6:C3:04:35:3B:CF:D2:96:92:D2:59:3E:7D:44:D9:34:FF:11",
- "59:0D:2D:7D:88:4F:40:2E:61:7E:A5:62:32:17:65:CF:17:D8:94:E9",
- "0B:BE:C2:27:22:49:CB:39:AA:DB:35:5C:53:E3:8C:AE:78:FF:B6:FE",
- "DF:71:7E:AA:4A:D9:4E:C9:55:84:99:60:2D:48:DE:5F:BC:F0:3A:25",
- "8F:6B:F2:A9:27:4A:DA:14:A0:C4:F4:8E:61:27:F9:C0:1E:78:5D:D1",
- "F6:10:84:07:D6:F8:BB:67:98:0C:C2:E2:44:C2:EB:AE:1C:EF:63:BE",
- "AF:E5:D2:44:A8:D1:19:42:30:FF:47:9F:E2:F8:97:BB:CD:7A:8C:B4",
- "5F:3B:8C:F2:F8:10:B3:7D:78:B4:CE:EC:19:19:C3:73:34:B9:C7:74",
- "96:C9:1B:0B:95:B4:10:98:42:FA:D0:D8:22:79:FE:60:FA:B9:16:83",
- "A0:50:EE:0F:28:71:F4:27:B2:12:6D:6F:50:96:25:BA:CC:86:42:AF",
- "A3:A1:B0:6F:24:61:23:4A:E3:36:A5:C2:37:FC:A6:FF:DD:F0:D7:3A",
- "D8:A6:33:2C:E0:03:6F:B1:85:F6:63:4F:7D:6A:06:65:26:32:28:27",
- "E7:2E:F1:DF:FC:B2:09:28:CF:5D:D4:D5:67:37:B1:51:CB:86:4F:01",
- "01:0C:06:95:A6:98:19:14:FF:BF:5F:C6:B0:B6:95:EA:29:E9:12:A6",
- "0F:F9:40:76:18:D3:D7:6A:4B:98:F0:A8:35:9E:0C:FD:27:AC:CC:ED",
- "AD:98:F9:F3:E4:7D:75:3B:65:D4:82:B3:A4:52:17:BB:6E:F5:E4:38",
- "CF:E9:70:84:0F:E0:73:0F:9D:F6:0C:7F:2C:4B:EE:20:46:34:9C:BB",
- "48:12:BD:92:3C:A8:C4:39:06:E7:30:6D:27:96:E6:A4:CF:22:2E:7D",
- "F9:B5:B6:32:45:5F:9C:BE:EC:57:5F:80:DC:E9:6E:2C:C7:B2:78:B7",
- "39:B4:6C:D5:FE:80:06:EB:E2:2F:4A:BB:08:33:A0:AF:DB:B9:DD:84",
- "EA:B0:E2:52:1B:89:93:4C:11:68:F2:D8:9A:AC:22:4C:A3:8A:57:AE",
- "89:DF:74:FE:5C:F4:0F:4A:80:F9:E3:37:7D:54:DA:91:E1:01:31:8E",
- "7E:04:DE:89:6A:3E:66:6D:00:E6:87:D3:3F:FA:D9:3B:E8:3D:34:9E",
- "2F:8F:36:4F:E1:58:97:44:21:59:87:A5:2A:9A:D0:69:95:26:7F:B5",
- "F6:9C:DB:B0:FC:F6:02:13:B6:52:32:A6:A3:91:3F:16:70:DA:C3:E1",
- "E5:8C:1C:C4:91:3B:38:63:4B:E9:10:6E:E3:AD:8E:6B:9D:D9:81:4A",
- "B9:99:CD:D1:73:50:8A:C4:47:05:08:9C:8C:88:FB:BE:A0:2B:40:CD",
- "14:88:4E:86:26:37:B0:26:AF:59:62:5C:40:77:EC:35:29:BA:96:01",
- "8A:C7:AD:8F:73:AC:4E:C1:B5:75:4D:A5:40:F4:FC:CF:7C:B5:8E:8C",
- "C8:83:44:C0:18:AE:9F:CC:F1:87:B7:8F:22:D1:C5:D7:45:84:BA:E5",
- "5A:8C:EF:45:D7:A6:98:59:76:7A:8C:8B:44:96:B5:78:CF:47:4B:1A",
- "8D:A7:F9:65:EC:5E:FC:37:91:0F:1C:6E:59:FD:C1:CC:6A:6E:DE:16",
- "B1:2E:13:63:45:86:A4:6F:1A:B2:60:68:37:58:2D:C4:AC:FD:94:97",
- "D5:EC:8D:7B:4C:BA:79:F4:E7:E8:CB:9D:6B:AE:77:83:10:03:21:6A",
- };
+ static final String[] CERTIFICATE_DATA = {
+ "99:9A:64:C3:7F:F4:7D:9F:AB:95:F1:47:69:89:14:60:EE:C4:C3:C5",
+ "D1:CB:CA:5D:B2:D5:2A:7F:69:3B:67:4D:E5:F0:5A:1D:0C:95:7D:F0",
+ "A8:31:11:74:A6:14:15:0D:CA:77:DD:0E:E4:0C:5D:58:FC:A0:72:A5",
+ "57:73:A5:61:5D:80:B2:E6:AC:38:82:FC:68:07:31:AC:9F:B5:92:5A",
+ "6B:A0:B0:98:E1:71:EF:5A:AD:FE:48:15:80:77:10:F4:BD:6F:0B:28",
+ "92:5A:8F:8D:2C:6D:04:E0:66:5F:59:6A:FF:22:D8:63:E8:25:6F:3F",
+ "18:52:3B:0D:06:37:E4:D6:3A:DF:23:E4:98:FB:5B:16:FB:86:74:48",
+ "B4:90:82:DD:45:0C:BE:8B:5B:B1:66:D3:E2:A4:08:26:CD:ED:42:CF",
+ "53:A2:B0:4B:CA:6B:D6:45:E6:39:8A:8E:C4:0D:D2:BF:77:C3:A2:90",
+ "58:E8:AB:B0:36:15:33:FB:80:F7:9B:1B:6D:29:D3:FF:8D:5F:00:F0",
+ "55:A6:72:3E:CB:F2:EC:CD:C3:23:74:70:19:9D:2A:BE:11:E3:81:D1",
+ "D6:9B:56:11:48:F0:1C:77:C5:45:78:C1:09:26:DF:5B:85:69:76:AD",
+ "D0:67:C1:13:51:01:0C:AA:D0:C7:6A:65:37:31:16:26:4F:53:71:A2",
+ "09:3C:61:F3:8B:8B:DC:7D:55:DF:75:38:02:05:00:E1:25:F5:C8:36",
+ "27:96:BA:E6:3F:18:01:E2:77:26:1B:A0:D7:77:70:02:8F:20:EE:E4",
+ "AD:7E:1C:28:B0:64:EF:8F:60:03:40:20:14:C3:D0:E3:37:0E:B5:8A",
+ "17:F3:DE:5E:9F:0F:19:E9:8E:F6:1F:32:26:6E:20:C4:07:AE:30:EE",
+ "1F:24:C6:30:CD:A4:18:EF:20:69:FF:AD:4F:DD:5F:46:3A:1B:69:AA",
+ "EC:2C:83:40:72:AF:26:95:10:FF:0E:F2:03:EE:31:70:F6:78:9D:CA",
+ "9E:BC:75:10:42:B3:02:F3:81:F4:F7:30:62:D4:8F:C3:A7:51:B2:DD",
+ "DA:FA:F7:FA:66:84:EC:06:8F:14:50:BD:C7:C2:81:A5:BC:A9:64:57",
+ "2D:0D:52:14:FF:9E:AD:99:24:01:74:20:47:6E:6C:85:27:27:F5:43",
+ "28:F9:78:16:19:7A:FF:18:25:18:AA:44:FE:C1:A0:CE:5C:B6:4C:8A",
+ "31:43:64:9B:EC:CE:27:EC:ED:3A:3F:0B:8F:0D:E4:E8:91:DD:EE:CA",
+ "B7:AB:33:08:D1:EA:44:77:BA:14:80:12:5A:6F:BD:A9:36:49:0C:BB",
+ "3C:3F:EF:57:0F:FE:65:93:86:9E:A0:FE:B0:F6:ED:8E:D1:13:C7:E5",
+ "2B:8F:1B:57:33:0D:BB:A2:D0:7A:6C:51:F7:0E:E9:0D:DA:B9:AD:8E",
+ "A8:98:5D:3A:65:E5:E5:C4:B2:D7:D6:6D:40:C6:DD:2F:B1:9C:54:36",
+ "D4:DE:20:D0:5E:66:FC:53:FE:1A:50:88:2C:78:DB:28:52:CA:E4:74",
+ "EC:8A:39:6C:40:F0:2E:BC:42:75:D4:9F:AB:1C:1A:5B:67:BE:D2:9A",
+ "D8:C5:38:8A:B7:30:1B:1B:6E:D4:7A:E6:45:25:3A:6F:9F:1A:27:61",
+ "E0:11:84:5E:34:DE:BE:88:81:B9:9C:F6:16:26:D1:96:1F:C3:B9:31",
+ "93:05:7A:88:15:C6:4F:CE:88:2F:FA:91:16:52:28:78:BC:53:64:17",
+ "50:30:06:09:1D:97:D4:F5:AE:39:F7:CB:E7:92:7D:7D:65:2D:34:31",
+ "F3:3E:78:3C:AC:DF:F4:A2:CC:AC:67:55:69:56:D7:E5:16:3C:E1:ED",
+ "8C:F4:27:FD:79:0C:3A:D1:66:06:8D:E8:1E:57:EF:BB:93:22:72:D4",
+ "F6:B1:1C:1A:83:38:E9:7B:DB:B3:A8:C8:33:24:E0:2D:9C:7F:26:66",
+ "2F:78:3D:25:52:18:A7:4A:65:39:71:B5:2C:A2:9C:45:15:6F:E9:19",
+ "BA:29:41:60:77:98:3F:F4:F3:EF:F2:31:05:3B:2E:EA:6D:4D:45:FD",
+ "BC:B0:C1:9D:E9:98:92:70:19:38:57:E9:8D:A7:B4:5D:6E:EE:01:48",
+ "9B:AA:E5:9F:56:EE:21:CB:43:5A:BE:25:93:DF:A7:F0:40:D1:1D:CB",
+ "1B:8E:EA:57:96:29:1A:C9:39:EA:B8:0A:81:1A:73:73:C0:93:79:67",
+ "6A:92:E4:A8:EE:1B:EC:96:45:37:E3:29:57:49:CD:96:E3:E5:D2:60",
+ "74:3A:F0:52:9B:D0:32:A0:F4:4A:83:CD:D4:BA:A9:7B:7C:2E:C4:9A",
+ "07:86:C0:D8:DD:8E:C0:80:98:06:98:D0:58:7A:EF:DE:A6:CC:A2:5D",
+ "66:31:BF:9E:F7:4F:9E:B6:C9:D5:A6:0C:BA:6A:BE:D1:F7:BD:EF:7B",
+ "77:D3:03:67:B5:E0:0C:15:F6:0C:38:61:DF:7C:E1:3B:92:46:4D:47",
+ "7A:22:1E:3D:DE:1B:06:AC:9E:C8:47:70:16:8E:3C:E5:F7:6B:06:F4",
+ "F3:73:B3:87:06:5A:28:84:8A:F2:F3:4A:CE:19:2B:DD:C7:8E:9C:AC",
+ "62:FF:D9:9E:C0:65:0D:03:CE:75:93:D2:ED:3F:2D:32:C9:E3:E5:4A",
+ "F9:E1:6D:DC:01:89:CF:D5:82:45:63:3E:C5:37:7D:C2:EB:93:6F:2B",
+ "06:08:3F:59:3F:15:A1:04:A0:69:A4:6B:A9:03:D0:06:B7:97:09:91",
+ "CA:BD:2A:79:A1:07:6A:31:F2:1D:25:36:35:CB:03:9D:43:29:A5:E8",
+ "43:13:BB:96:F1:D5:86:9B:C1:4E:6A:92:F6:CF:F6:34:69:87:82:37",
+ "05:63:B8:63:0D:62:D7:5A:BB:C8:AB:1E:4B:DF:B5:A8:99:B2:4D:43",
+ "ED:E5:71:80:2B:C8:92:B9:5B:83:3C:D2:32:68:3F:09:CD:A0:1E:46",
+ "C0:F8:96:C5:A9:3B:01:06:21:07:DA:18:42:48:BC:E9:9D:88:D5:EC",
+ "D1:EB:23:A4:6D:17:D6:8F:D9:25:64:C2:F1:F1:60:17:64:D8:E3:49",
+ "B8:01:86:D1:EB:9C:86:A5:41:04:CF:30:54:F3:4C:52:B7:E5:58:C6",
+ "4C:DD:51:A3:D1:F5:20:32:14:B0:C6:C5:32:23:03:91:C7:46:42:6D",
+ "0D:44:DD:8C:3C:8C:1A:1A:58:75:64:81:E9:0F:2E:2A:FF:B3:D2:6E",
+ "CA:3A:FB:CF:12:40:36:4B:44:B2:16:20:88:80:48:39:19:93:7C:F7",
+ "F4:27:86:EB:6E:B8:6D:88:31:67:02:FB:BA:66:A4:53:00:AA:7A:A6",
+ "5F:B7:EE:06:33:E2:59:DB:AD:0C:4C:9A:E6:D3:8F:1A:61:C7:DC:25",
+ "49:0A:75:74:DE:87:0A:47:FE:58:EE:F6:C7:6B:EB:C6:0B:12:40:99",
+ "89:D4:83:03:4F:9E:9A:48:80:5F:72:37:D4:A9:A6:EF:CB:7C:1F:D1",
+ "B5:1C:06:7C:EE:2B:0C:3D:F8:55:AB:2D:92:F4:FE:39:D4:E7:0F:0E",
+ "29:36:21:02:8B:20:ED:02:F5:66:C5:32:D1:D6:ED:90:9F:45:00:2F",
+ "B6:AF:43:C2:9B:81:53:7D:F6:EF:6B:C3:1F:1F:60:15:0C:EE:48:66",
+ "DD:50:C0:F7:79:B3:64:2E:74:A2:B8:9D:9F:D3:40:DD:BB:F0:F2:4F",
+ "BD:B1:B9:3C:D5:97:8D:45:C6:26:14:55:F8:DB:95:C7:5A:D1:53:AF",
+ "FA:B7:EE:36:97:26:62:FB:2D:B0:2A:F6:BF:03:FD:E8:7C:4B:2F:9B",
+ "C3:19:7C:39:24:E6:54:AF:1B:C4:AB:20:95:7A:E2:C3:0E:13:02:6A",
+ "9F:74:4E:9F:2B:4D:BA:EC:0F:31:2C:50:B6:56:3B:8E:2D:93:C3:11",
+ "6D:0A:5F:F7:B4:23:06:B4:85:B3:B7:97:64:FC:AC:75:F5:33:F2:93",
+ "A1:4B:48:D9:43:EE:0A:0E:40:90:4F:3C:E0:A4:C0:91:93:51:5D:3F",
+ "CB:BA:83:C8:C1:5A:5D:F1:F9:73:6F:CA:D7:EF:28:13:06:4A:07:7D",
+ "E2:B8:29:4B:55:84:AB:6B:58:C2:90:46:6C:AC:3F:B8:39:8F:84:83",
+ "1F:49:14:F7:D8:74:95:1D:DD:AE:02:C0:BE:FD:3A:2D:82:75:51:85",
+ "5B:6E:68:D0:CC:15:B6:A0:5F:1E:C1:5F:AE:02:FC:6B:2F:5D:6F:74",
+ "9F:F1:71:8D:92:D5:9A:F3:7D:74:97:B4:BC:6F:84:68:0B:BA:B6:66",
+ "B5:61:EB:EA:A4:DE:E4:25:4B:69:1A:98:A5:57:47:C2:34:C7:D9:71",
+ "73:A5:E6:4A:3B:FF:83:16:FF:0E:DC:CC:61:8A:90:6E:4E:AE:4D:74",
+ "07:E0:32:E0:20:B7:2C:3F:19:2F:06:28:A2:59:3A:19:A7:0F:06:9E",
+ "80:94:64:0E:B5:A7:A1:CA:11:9C:1F:DD:D5:9F:81:02:63:A7:FB:D1",
+ "63:CF:B6:C1:27:2B:56:E4:88:8E:1C:23:9A:B6:2E:81:47:24:C3:C7",
+ "84:1A:69:FB:F5:CD:1A:25:34:13:3D:E3:F8:FC:B8:99:D0:C9:14:B7",
+ "E7:F3:A3:C8:CF:6F:C3:04:2E:6D:0E:67:32:C5:9E:68:95:0D:5E:D2",
+ "67:65:0D:F1:7E:8E:7E:5B:82:40:A4:F4:56:4B:CF:E2:3D:69:C6:F0",
+ "DD:FB:16:CD:49:31:C9:73:A2:03:7D:3F:C8:3A:4D:7D:77:5D:05:E4",
+ "61:DB:8C:21:59:69:03:90:D8:7C:9C:12:86:54:CF:9D:3D:F4:DD:07",
+ "E2:52:FA:95:3F:ED:DB:24:60:BD:6E:28:F3:9C:CC:CF:5E:B3:3F:DE",
+ "26:F9:93:B4:ED:3D:28:27:B0:B9:4B:A7:E9:15:1D:A3:8D:92:E5:32",
+ "0F:36:38:5B:81:1A:25:C3:9B:31:4E:83:CA:E9:34:66:70:CC:74:B4",
+ "9C:BB:48:53:F6:A4:F6:D3:52:A4:E8:32:52:55:60:13:F5:AD:AF:65",
+ "B1:BC:96:8B:D4:F4:9D:62:2A:A8:9A:81:F2:15:01:52:A4:1D:82:9C",
+ "1F:5B:98:F0:E3:B5:F7:74:3C:ED:E6:B0:36:7D:32:CD:F4:09:41:67",
+ "20:D8:06:40:DF:9B:25:F5:12:25:3A:11:EA:F7:59:8A:EB:14:B5:47",
+ "30:43:FA:4F:F2:57:DC:A0:C3:80:EE:2E:58:EA:78:B2:3F:E6:BB:C1",
+ "CF:9E:87:6D:D3:EB:FC:42:26:97:A3:B5:A3:7A:A0:76:A9:06:23:48",
+ "2B:B1:F5:3E:55:0C:1D:C5:F1:D4:E6:B7:6A:46:4B:55:06:02:AC:21",
+ "02:2D:05:82:FA:88:CE:14:0C:06:79:DE:7F:14:10:E9:45:D7:A5:6D",
+ "EC:50:35:07:B2:15:C4:95:62:19:E2:A8:9A:5B:42:99:2C:4C:2C:20",
+ "47:BE:AB:C9:22:EA:E8:0E:78:78:34:62:A7:9F:45:C2:54:FD:E6:8B",
+ "58:A2:D0:EC:20:52:81:5B:C1:F3:F8:64:02:24:4E:C2:8E:02:4B:02",
+ "3A:44:73:5A:E5:81:90:1F:24:86:61:46:1E:3B:9C:C4:5F:F5:3A:1B",
+ "B3:1E:B1:B7:40:E3:6C:84:02:DA:DC:37:D4:4D:F5:D4:67:49:52:F9",
+ "A7:88:49:DC:5D:7C:75:8C:8C:DE:39:98:56:B3:AA:D0:B2:A5:71:35",
+ "F5:17:A2:4F:9A:48:C6:C9:F8:A2:00:26:9F:DC:0F:48:2C:AB:30:89",
+ "9A:44:49:76:32:DB:DE:FA:D0:BC:FB:5A:7B:17:BD:9E:56:09:24:94",
+ "B8:0E:26:A9:BF:D2:B2:3B:C0:EF:46:C9:BA:C7:BB:F6:1D:0D:41:41",
+ "DF:3C:24:F9:BF:D6:66:76:1B:26:80:73:FE:06:D1:CC:8D:4F:82:A4",
+ "D3:DD:48:3E:2B:BF:4C:05:E8:AF:10:F5:FA:76:26:CF:D3:DC:30:92",
+ "9F:5F:D9:1A:54:6D:F5:0C:71:F0:EE:7A:BD:17:49:98:84:73:E2:39",
+ "B8:23:6B:00:2F:1D:16:86:53:01:55:6C:11:A4:37:CA:EB:FF:C3:BB",
+ "87:82:C6:C3:04:35:3B:CF:D2:96:92:D2:59:3E:7D:44:D9:34:FF:11",
+ "59:0D:2D:7D:88:4F:40:2E:61:7E:A5:62:32:17:65:CF:17:D8:94:E9",
+ "0B:BE:C2:27:22:49:CB:39:AA:DB:35:5C:53:E3:8C:AE:78:FF:B6:FE",
+ "DF:71:7E:AA:4A:D9:4E:C9:55:84:99:60:2D:48:DE:5F:BC:F0:3A:25",
+ "8F:6B:F2:A9:27:4A:DA:14:A0:C4:F4:8E:61:27:F9:C0:1E:78:5D:D1",
+ "F6:10:84:07:D6:F8:BB:67:98:0C:C2:E2:44:C2:EB:AE:1C:EF:63:BE",
+ "AF:E5:D2:44:A8:D1:19:42:30:FF:47:9F:E2:F8:97:BB:CD:7A:8C:B4",
+ "5F:3B:8C:F2:F8:10:B3:7D:78:B4:CE:EC:19:19:C3:73:34:B9:C7:74",
+ "96:C9:1B:0B:95:B4:10:98:42:FA:D0:D8:22:79:FE:60:FA:B9:16:83",
+ "A0:50:EE:0F:28:71:F4:27:B2:12:6D:6F:50:96:25:BA:CC:86:42:AF",
+ "A3:A1:B0:6F:24:61:23:4A:E3:36:A5:C2:37:FC:A6:FF:DD:F0:D7:3A",
+ "D8:A6:33:2C:E0:03:6F:B1:85:F6:63:4F:7D:6A:06:65:26:32:28:27",
+ "E7:2E:F1:DF:FC:B2:09:28:CF:5D:D4:D5:67:37:B1:51:CB:86:4F:01",
+ "01:0C:06:95:A6:98:19:14:FF:BF:5F:C6:B0:B6:95:EA:29:E9:12:A6",
+ "0F:F9:40:76:18:D3:D7:6A:4B:98:F0:A8:35:9E:0C:FD:27:AC:CC:ED",
+ "AD:98:F9:F3:E4:7D:75:3B:65:D4:82:B3:A4:52:17:BB:6E:F5:E4:38",
+ "CF:E9:70:84:0F:E0:73:0F:9D:F6:0C:7F:2C:4B:EE:20:46:34:9C:BB",
+ "48:12:BD:92:3C:A8:C4:39:06:E7:30:6D:27:96:E6:A4:CF:22:2E:7D",
+ "F9:B5:B6:32:45:5F:9C:BE:EC:57:5F:80:DC:E9:6E:2C:C7:B2:78:B7",
+ "39:B4:6C:D5:FE:80:06:EB:E2:2F:4A:BB:08:33:A0:AF:DB:B9:DD:84",
+ "EA:B0:E2:52:1B:89:93:4C:11:68:F2:D8:9A:AC:22:4C:A3:8A:57:AE",
+ "89:DF:74:FE:5C:F4:0F:4A:80:F9:E3:37:7D:54:DA:91:E1:01:31:8E",
+ "7E:04:DE:89:6A:3E:66:6D:00:E6:87:D3:3F:FA:D9:3B:E8:3D:34:9E",
+ "2F:8F:36:4F:E1:58:97:44:21:59:87:A5:2A:9A:D0:69:95:26:7F:B5",
+ "54:D3:AC:B3:BD:57:56:F6:85:9D:CE:E5:C3:21:E2:D4:AD:83:D0:93",
+ "F6:9C:DB:B0:FC:F6:02:13:B6:52:32:A6:A3:91:3F:16:70:DA:C3:E1",
+ "E5:8C:1C:C4:91:3B:38:63:4B:E9:10:6E:E3:AD:8E:6B:9D:D9:81:4A",
+ "B9:99:CD:D1:73:50:8A:C4:47:05:08:9C:8C:88:FB:BE:A0:2B:40:CD",
+ "8A:C7:AD:8F:73:AC:4E:C1:B5:75:4D:A5:40:F4:FC:CF:7C:B5:8E:8C",
+ "C8:83:44:C0:18:AE:9F:CC:F1:87:B7:8F:22:D1:C5:D7:45:84:BA:E5",
+ "5A:8C:EF:45:D7:A6:98:59:76:7A:8C:8B:44:96:B5:78:CF:47:4B:1A",
+ "8D:A7:F9:65:EC:5E:FC:37:91:0F:1C:6E:59:FD:C1:CC:6A:6E:DE:16",
+ "B1:2E:13:63:45:86:A4:6F:1A:B2:60:68:37:58:2D:C4:AC:FD:94:97",
+ "D5:EC:8D:7B:4C:BA:79:F4:E7:E8:CB:9D:6B:AE:77:83:10:03:21:6A",
+ };
static final String[] WFA_CERTIFICATE_DATA = {
"BB:49:24:83:18:47:95:2B:DB:1A:12:B0:38:EC:51:54:AD:CB:DE:43",
diff --git a/tests/tests/security/src/android/security/cts/FlagSlipperyTest.kt b/tests/tests/security/src/android/security/cts/FlagSlipperyTest.kt
index 0046d6d..16b5128 100644
--- a/tests/tests/security/src/android/security/cts/FlagSlipperyTest.kt
+++ b/tests/tests/security/src/android/security/cts/FlagSlipperyTest.kt
@@ -16,11 +16,13 @@
package android.security.cts
+import android.app.Activity
import android.app.ActivityOptions
import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN
import android.graphics.Rect
import android.os.SystemClock
import android.platform.test.annotations.AsbSecurityTest
+import android.view.Display
import android.view.Gravity
import android.view.InputDevice
import android.view.MotionEvent
@@ -80,6 +82,14 @@
override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {}
}
+private fun <T : Activity> getDisplay(scenario: ActivityScenario<T>): Display {
+ var display: Display? = null
+ scenario.onActivity {
+ display = it.display
+ }
+ return display!!
+}
+
@MediumTest
@RunWith(AndroidJUnit4::class)
/**
@@ -139,8 +149,8 @@
@Before
fun setup() {
scenario = rule.getScenario()
- windowManager = getInstrumentation().getTargetContext().getSystemService<WindowManager>(
- WindowManager::class.java)!!
+ val display = getDisplay(scenario)
+ val displayContext = getInstrumentation().getTargetContext().createDisplayContext(display)
setDimensionsToQuarterScreen()
waitForWindowFocusOnBottomActivity()
diff --git a/tests/tests/security/src/android/security/cts/MotionEventTest.java b/tests/tests/security/src/android/security/cts/MotionEventTest.java
index 670d232..d8f25b5 100644
--- a/tests/tests/security/src/android/security/cts/MotionEventTest.java
+++ b/tests/tests/security/src/android/security/cts/MotionEventTest.java
@@ -39,6 +39,7 @@
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.rule.ActivityTestRule;
+import com.android.compatibility.common.util.UserHelper;
import com.android.compatibility.common.util.WidgetTestUtils;
import com.android.compatibility.common.util.WindowUtil;
@@ -61,6 +62,7 @@
private static final String TAG = "MotionEventTest";
private Activity mActivity;
private Instrumentation mInstrumentation;
+ private UserHelper mUserHelper;
@Rule
public ActivityTestRule<MotionEventTestActivity> mActivityRule =
@@ -71,6 +73,7 @@
mInstrumentation = InstrumentationRegistry.getInstrumentation();
mActivity = mActivityRule.getActivity();
WindowUtil.waitForFocus(mActivity);
+ mUserHelper = new UserHelper();
}
/**
@@ -197,6 +200,7 @@
final UiAutomation automation = mInstrumentation.getUiAutomation();
final long eventTime = SystemClock.uptimeMillis();
MotionEvent event = MotionEvent.obtain(downTime, eventTime, action, x, y, 0);
+ event.setDisplayId(mUserHelper.getMainDisplayId());
event.setSource(InputDevice.SOURCE_TOUCHSCREEN);
automation.injectInputEvent(event, true);
event.recycle();
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/ApnCarrierIdTest.java b/tests/tests/telephony/current/src/android/telephony/cts/ApnCarrierIdTest.java
index 2aa604a..cf94779 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/ApnCarrierIdTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/ApnCarrierIdTest.java
@@ -28,6 +28,7 @@
import android.content.ContentValues;
import android.content.Context;
import android.content.pm.PackageManager;
+import android.database.Cursor;
import android.net.Uri;
import android.platform.test.annotations.AppModeNonSdkSandbox;
import android.platform.test.flag.junit.CheckFlagsRule;
@@ -53,9 +54,12 @@
import org.junit.Test;
import org.junit.runner.RunWith;
-import java.util.List;
+import java.util.Arrays;
+import java.util.ArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
+import java.util.List;
+import java.util.Map;
/**
* Ensures that APNs that use carrier ID instead of legacy identifiers such as MCCMNC, MVNO type and
@@ -98,7 +102,7 @@
// The wait time is padded to account for varying modem performance. Note that this is a
// timeout, not an enforced wait time, so in most cases, a callback will be received prior to
// the wait time elapsing.
- private static final long WAIT_TIME_MILLIS = 10000L;
+ private static final long WAIT_TIME_MILLIS = 15000L;
private Context mContext;
private ContentResolver mContentResolver;
@@ -109,10 +113,10 @@
private PreciseDataConnectionState mPreciseDataConnectionState;
/**
- * The original APN that belongs to the existing data connection. Required to re-insert it
+ * The original APNs that belongs to the existing data connection. Required to re-insert it
* during teardown.
*/
- private ApnSetting mExistingApn;
+ private List<ApnSetting> mExistingApns;
/** Selection args for the carrier ID APN. Required to delete the test APN during teardown. */
private String[] mInsertedApnSelectionArgs;
@@ -175,32 +179,36 @@
APN_SELECTION_STRING_WITH_CARRIER_ID,
mInsertedApnSelectionArgs);
}
- if (mExistingApn != null) {
+ if (mExistingApns != null) {
PreciseDataConnectionStateListener pdcsCallback =
new PreciseDataConnectionStateListener(
mTelephonyManager,
/* desiredDataState= */ TelephonyManager.DATA_CONNECTED);
- // We want to restore the original APN. Before attempting to re-insert it, we should
+ // We want to restore the original APNs. Before attempting to re-insert it, we should
// first try updating it in case it's still present with an `EDITED_STATUS` of
// `USER_DELETED`. If the update does not succeed because the APN doesn't exist, we can
- // opt to insert it instead.
- ContentValues edited = new ContentValues();
- // We'll just reset the `EDITED` status of the APN.
- edited.put(Carriers.EDITED_STATUS, mExistingApn.getEditedStatus());
- int updatedRows =
- mContentResolver.update(
- CARRIER_TABLE_URI,
- edited,
- APN_SELECTION_STRING_WITH_NUMERIC,
- generateSelectionArgs(mExistingApn, mExistingApn.getOperatorNumeric()));
- // If no row was updated, re-insert the APN instead.
- if (updatedRows == 0) {
- mContentResolver.insert(CARRIER_TABLE_URI, mExistingApn.toContentValues());
- }
- try {
+ // opt to insert it instead. Note that we use stricter selection arguments for update
+ // to ensure we don't accidentally update a different APN.
+ for (ApnSetting existingApn : mExistingApns) {
+ String selectionString = generateSelectionStringForUpdate(existingApn);
+ ContentValues edited = new ContentValues();
+ // We'll just reset the `EDITED` status of the APN.
+ edited.put(Carriers.EDITED_STATUS, existingApn.getEditedStatus());
+ int updatedRows =
+ mContentResolver.update(
+ CARRIER_TABLE_URI,
+ edited,
+ selectionString,
+ /*selectionArgs=*/ null);
+ // If no row was updated, re-insert the APN instead.
+ if (updatedRows == 0) {
+ mContentResolver.insert(CARRIER_TABLE_URI, existingApn.toContentValues());
+ }
+ try {
pdcsCallback.awaitDataStateChanged(WAIT_TIME_MILLIS);
- } catch (InterruptedException e) {
+ } catch (InterruptedException e) {
// do nothing - we just want to ensure the teardown is complete.
+ }
}
}
@@ -214,7 +222,7 @@
* as MCCMNC/numeric can establish a data connection.
*/
@Test
- @AppModeNonSdkSandbox(reason = "SDK sanboxes do not have access to telephony provider")
+ @AppModeNonSdkSandbox(reason = "SDK sandboxes do not have access to telephony provider")
public void validateDataConnectionWithCarrierIdApn() throws Exception {
ApnSetting currentApn = mPreciseDataConnectionState.getApnSetting();
validateAndSetupInitialState(currentApn);
@@ -261,14 +269,36 @@
new PreciseDataConnectionStateListener(
mTelephonyManager,
/* desiredDataState= */ TelephonyManager.DATA_DISCONNECTED);
+ String[] selectionArgs = generateSelectionArgs(currentApn, currentApn.getOperatorNumeric());
+ Cursor cursor = mContentResolver.query(
+ CARRIER_TABLE_URI,
+ /*projection=*/ null,
+ APN_SELECTION_STRING_WITH_NUMERIC,
+ selectionArgs,
+ /*sortOrder=*/ null);
+ // Store the APNs so we can re-insert them once the test is complete.
+ // Note that multiple APNs can match the selection args, so we'll end up
+ // deleting them too.
+ int count = 0;
+ mExistingApns = new ArrayList<>();
+ if (cursor != null && cursor.moveToFirst()) {
+ do {
+ ApnSetting apn = ApnSetting.makeApnSetting(cursor);
+ mExistingApns.add(apn);
+ count++;
+ } while (cursor.moveToNext());
+ }
+
int deletedRowCount =
mContentResolver.delete(
CARRIER_TABLE_URI,
APN_SELECTION_STRING_WITH_NUMERIC,
- generateSelectionArgs(currentApn, currentApn.getOperatorNumeric()));
- assertThat(deletedRowCount).isEqualTo(1);
- // Store the APN so we can re-insert it once the test is complete.
- mExistingApn = currentApn;
+ selectionArgs);
+ // Ensure we deleted all APNs that match the identifying fields. There might be
+ // multiple APNs with the same identifying fields (but with MVNO match data
+ // and MVNO type).
+ assertThat(deletedRowCount).isEqualTo(count);
+
if (!pdcsCallback.awaitDataStateChanged(WAIT_TIME_MILLIS)) {
fail("Timed out waiting for data disconnected");
}
@@ -279,7 +309,7 @@
}
private boolean apnAlreadyUsesCarrierId(ApnSetting apnSetting) {
- return apnSetting.getCarrierId() != TelephonyManager.UNKNOWN_CARRIER_ID
+ return apnSetting.getCarrierId() != TelephonyManager.UNKNOWN_CARRIER_ID
&& TextUtils.isEmpty(apnSetting.getOperatorNumeric());
}
@@ -309,6 +339,28 @@
return String.join("=? AND ", columns) + "=?";
}
+ private static String generateSelectionStringForUpdate(ApnSetting apnSetting) {
+ ContentValues apnContentValues = apnSetting.toContentValues();
+ String selectionString = "true";
+ for (Map.Entry<String, Object> entry : apnContentValues.valueSet()) {
+ // Skip the TYPE column and empty values. This is because ApnSetting rebuilds
+ // the TYPE list based on a bitmask which won't necessarily match the
+ // ordering of the string in the APN database.
+ if (entry.getKey().equals(Carriers.TYPE)
+ || entry.getValue().toString().isEmpty()) {
+ continue;
+ }
+ String value = entry.getValue().toString();
+ // If the value is a boolean, we should not wrap it in quotes because
+ // SQLite will process the value as TEXT rather than convert it into an INT.
+ if (!entry.getValue().getClass().equals(Boolean.class)) {
+ value = "\"" + value + "\"";
+ }
+ selectionString += " AND " + entry.getKey() + "=" + value;
+ }
+ return selectionString;
+ }
+
/**
* Generates selection arguments for an APN.
*
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/SmsUsageMonitorShortCodeTest.java b/tests/tests/telephony/current/src/android/telephony/cts/SmsUsageMonitorShortCodeTest.java
index 26e43cd..a37a8b4 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/SmsUsageMonitorShortCodeTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/SmsUsageMonitorShortCodeTest.java
@@ -72,6 +72,7 @@
new ShortCodeTest("ae", "625315", SMS_CATEGORY_NOT_SHORT_CODE),
new ShortCodeTest("ae", "6211", SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
new ShortCodeTest("ae", "6253", SMS_CATEGORY_FREE_SHORT_CODE),
+ new ShortCodeTest("ae", "6568", SMS_CATEGORY_FREE_SHORT_CODE),
new ShortCodeTest("am", "112", expectedReturnCode("112")),
new ShortCodeTest("am", "101", SMS_CATEGORY_FREE_SHORT_CODE),
@@ -144,6 +145,8 @@
new ShortCodeTest("br", "265262", SMS_CATEGORY_NOT_SHORT_CODE),
new ShortCodeTest("br", "2654", SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
new ShortCodeTest("br", "2652", SMS_CATEGORY_FREE_SHORT_CODE),
+ new ShortCodeTest("br", "26808", SMS_CATEGORY_FREE_SHORT_CODE),
+ new ShortCodeTest("br", "26807", SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
new ShortCodeTest("bw", "166416", SMS_CATEGORY_NOT_SHORT_CODE),
new ShortCodeTest("bw", "16649", SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
@@ -164,6 +167,7 @@
new ShortCodeTest("ca", "2000000", SMS_CATEGORY_NOT_SHORT_CODE),
new ShortCodeTest("ca", "60999", SMS_CATEGORY_PREMIUM_SHORT_CODE),
new ShortCodeTest("ca", "88188", SMS_CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("ca", "24470", SMS_CATEGORY_FREE_SHORT_CODE),
new ShortCodeTest("ch", "112", SMS_CATEGORY_NOT_SHORT_CODE),
new ShortCodeTest("ch", "123", SMS_CATEGORY_NOT_SHORT_CODE),
@@ -249,6 +253,10 @@
new ShortCodeTest("ee", "9034567", SMS_CATEGORY_PREMIUM_SHORT_CODE),
new ShortCodeTest("ee", "34567890", SMS_CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("eg", "10020", SMS_CATEGORY_FREE_SHORT_CODE),
+ new ShortCodeTest("eg", "10021", SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("eg", "100211", SMS_CATEGORY_NOT_SHORT_CODE),
+
new ShortCodeTest("es", "112", SMS_CATEGORY_NOT_SHORT_CODE),
new ShortCodeTest("es", "116117", SMS_CATEGORY_FREE_SHORT_CODE),
new ShortCodeTest("es", "25165", SMS_CATEGORY_PREMIUM_SHORT_CODE),
@@ -302,6 +310,7 @@
new ShortCodeTest("gh", "3775", SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
new ShortCodeTest("gh", "3777", SMS_CATEGORY_FREE_SHORT_CODE),
new ShortCodeTest("gh", "2333", SMS_CATEGORY_FREE_SHORT_CODE),
+ new ShortCodeTest("gh", "6061", SMS_CATEGORY_FREE_SHORT_CODE),
new ShortCodeTest("gr", "112", SMS_CATEGORY_NOT_SHORT_CODE),
new ShortCodeTest("gr", "116117", SMS_CATEGORY_FREE_SHORT_CODE),
@@ -412,6 +421,7 @@
new ShortCodeTest("id", "992626", SMS_CATEGORY_NOT_SHORT_CODE),
new ShortCodeTest("id", "99268", SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
new ShortCodeTest("id", "99265", SMS_CATEGORY_FREE_SHORT_CODE),
+ new ShortCodeTest("id", "77413", SMS_CATEGORY_FREE_SHORT_CODE),
new ShortCodeTest("lt", "112", expectedReturnCode("112")),
new ShortCodeTest("lt", "116117", SMS_CATEGORY_FREE_SHORT_CODE),
@@ -459,10 +469,12 @@
new ShortCodeTest("mx", "3030302", SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
new ShortCodeTest("mx", "3030303", SMS_CATEGORY_FREE_SHORT_CODE),
new ShortCodeTest("mx", "81811", SMS_CATEGORY_FREE_SHORT_CODE),
+ new ShortCodeTest("mx", "81818", SMS_CATEGORY_FREE_SHORT_CODE),
new ShortCodeTest("mw", "427611", SMS_CATEGORY_NOT_SHORT_CODE),
new ShortCodeTest("mw", "4279", SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
new ShortCodeTest("mw", "4276", SMS_CATEGORY_FREE_SHORT_CODE),
+ new ShortCodeTest("mw", "4305", SMS_CATEGORY_FREE_SHORT_CODE),
new ShortCodeTest("my", "112", SMS_CATEGORY_NOT_SHORT_CODE),
new ShortCodeTest("my", "1234", SMS_CATEGORY_NOT_SHORT_CODE),
@@ -622,6 +634,7 @@
new ShortCodeTest("tz", "15239", SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
new ShortCodeTest("tz", "15234", SMS_CATEGORY_FREE_SHORT_CODE),
new ShortCodeTest("tz", "15324", SMS_CATEGORY_FREE_SHORT_CODE),
+ new ShortCodeTest("tz", "15610", SMS_CATEGORY_FREE_SHORT_CODE),
new ShortCodeTest("ua", "112", SMS_CATEGORY_NOT_SHORT_CODE),
new ShortCodeTest("ua", "5432", SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
@@ -633,6 +646,7 @@
new ShortCodeTest("ug", "800999", SMS_CATEGORY_NOT_SHORT_CODE),
new ShortCodeTest("ug", "8099", SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
new ShortCodeTest("ug", "8000", SMS_CATEGORY_FREE_SHORT_CODE),
+ new ShortCodeTest("ug", "8009", SMS_CATEGORY_FREE_SHORT_CODE),
new ShortCodeTest("us", "911", SMS_CATEGORY_NOT_SHORT_CODE),
new ShortCodeTest("us", "+18005551234", SMS_CATEGORY_NOT_SHORT_CODE),
@@ -647,6 +661,7 @@
new ShortCodeTest("us", "9683999", SMS_CATEGORY_NOT_SHORT_CODE),
new ShortCodeTest("us", "968319", SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
new ShortCodeTest("us", "96831", SMS_CATEGORY_FREE_SHORT_CODE),
+ new ShortCodeTest("us", "10907", SMS_CATEGORY_FREE_SHORT_CODE),
new ShortCodeTest("uy", "55003", SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
new ShortCodeTest("uy", "55002", SMS_CATEGORY_FREE_SHORT_CODE),
diff --git a/tests/tests/telephony/current/src/android/telephony/euicc/cts/EuiccManagerTest.java b/tests/tests/telephony/current/src/android/telephony/euicc/cts/EuiccManagerTest.java
index f82f98d..b6f0650 100644
--- a/tests/tests/telephony/current/src/android/telephony/euicc/cts/EuiccManagerTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/euicc/cts/EuiccManagerTest.java
@@ -719,6 +719,8 @@
assertThrows(SecurityException.class, () -> getContext().startActivity(testActionIntent));
}
+ // Skip tests using the TestEuiccUiComponent on 25Q1 due to flag failures
+ @Ignore
@Test
public void testEuiccProvisionAction() {
// Only test it when EuiccManager is enabled.
@@ -751,6 +753,8 @@
assertEquals(ACTION_PROVISION_EMBEDDED_SUBSCRIPTION, mCallbackReceiver.getResultData());
}
+ // Skip tests using the TestEuiccUiComponent on 25Q1 due to flag failures
+ @Ignore
@Test
public void testEuiccManageAction() {
// Only test it when EuiccManager is enabled.
@@ -783,6 +787,8 @@
assertEquals(ACTION_MANAGE_EMBEDDED_SUBSCRIPTIONS, mCallbackReceiver.getResultData());
}
+ // Skip tests using the TestEuiccUiComponent on 25Q1 due to flag failures
+ @Ignore
@Test
public void testEuiccTransferAction() {
// Only test it when EuiccManager is enabled.
@@ -815,6 +821,8 @@
assertEquals(ACTION_TRANSFER_EMBEDDED_SUBSCRIPTIONS, mCallbackReceiver.getResultData());
}
+ // Skip tests using the TestEuiccUiComponent on 25Q1 due to flag failures
+ @Ignore
@Test
public void testEuiccConvertAction() {
// Only test it when EuiccManager is enabled.
diff --git a/tests/tests/time/Android.bp b/tests/tests/time/Android.bp
index 6125a62..48fe5b7 100644
--- a/tests/tests/time/Android.bp
+++ b/tests/tests/time/Android.bp
@@ -27,6 +27,7 @@
"general-tests",
],
static_libs: [
+ "android.systemserver.flags-aconfig-java",
"androidx.test.rules",
"compatibility-device-util-axt",
"ctstestrunner-axt",
diff --git a/tests/tests/time/shell_utils/common/android/app/time/cts/shell/NetworkTimeUpdateServiceShellHelper.java b/tests/tests/time/shell_utils/common/android/app/time/cts/shell/NetworkTimeUpdateServiceShellHelper.java
index 80bed2b..d38e8ad 100644
--- a/tests/tests/time/shell_utils/common/android/app/time/cts/shell/NetworkTimeUpdateServiceShellHelper.java
+++ b/tests/tests/time/shell_utils/common/android/app/time/cts/shell/NetworkTimeUpdateServiceShellHelper.java
@@ -35,6 +35,10 @@
private static final String SHELL_CMD_PREFIX = "cmd " + SERVICE_NAME + " ";
+ private static final String SERVICE_PROPERTY = "config.disable_networktime";
+
+ private static final String SHELL_CMD_GET_PROPERTY = "getprop " + SERVICE_PROPERTY;
+
private final DeviceShellCommandExecutor mShellCommandExecutor;
public NetworkTimeUpdateServiceShellHelper(DeviceShellCommandExecutor shellCommandExecutor) {
@@ -67,6 +71,12 @@
}
}
+ /** Returns {@code true} if the network_time_update_service service is disabled. */
+ public boolean isNetworkTimeUpdateServiceDisabled() throws Exception {
+ String resultString = mShellCommandExecutor.executeToTrimmedString(SHELL_CMD_GET_PROPERTY);
+ return (resultString != null) && (resultString.equals("true"));
+ }
+
/**
* Sets time server configuration for use during tests.
* See {@link #resetServerConfigForTests()}.
diff --git a/tests/tests/time/src/android/app/time/cts/NetworkTimeUpdateServiceSntpTest.java b/tests/tests/time/src/android/app/time/cts/NetworkTimeUpdateServiceSntpTest.java
index fb5c781..9b21ef4 100644
--- a/tests/tests/time/src/android/app/time/cts/NetworkTimeUpdateServiceSntpTest.java
+++ b/tests/tests/time/src/android/app/time/cts/NetworkTimeUpdateServiceSntpTest.java
@@ -100,6 +100,8 @@
skipOnFormFactorsWithoutService(mNetworkTimeUpdateServiceShellHelper);
+ skipIfNetworkTimeUpdateServiceIsDisabled(mNetworkTimeUpdateServiceShellHelper);
+
mSetupInstant = Instant.now();
mSetupElapsedRealtimeMillis = SystemClock.elapsedRealtime();
mTimeDetectorShellHelper = new TimeDetectorShellHelper(mShellCommandExecutor);
@@ -259,7 +261,7 @@
// SystemClock.currentNetworkTimeClock() method currently requires
// network_time_update_service (or NtpNetworkTimeHelper in the location service) to be
// running in order to work. See also b/271256787 for context.
- if (isWatch()) {
+ if (isWatch() && !android.server.Flags.allowNetworkTimeUpdateService()) {
// network_time_update_service is not expected to exist on Wear due to
// form-factor-specific changes. If this fails, more changes could be required besides
// just removing this logic, so failing the test forces a discussion rather than moving
@@ -273,6 +275,23 @@
}
}
+ private static void skipIfNetworkTimeUpdateServiceIsDisabled(
+ NetworkTimeUpdateServiceShellHelper networkTimeUpdateServiceShellHelper)
+ throws Exception {
+ // Skip test if NetworkTimeUpdateService is disabled for this OEM. OEMs
+ // may use a separate time update framework, making
+ // SystemClock.currentNetworkTimeClock() unnecessary.
+ if (networkTimeUpdateServiceShellHelper.isNetworkTimeUpdateServiceDisabled()) {
+ // network_time_update_service is not expected to exist
+ // if config.disable_networktime is true
+ assertFalse(networkTimeUpdateServiceShellHelper.isNetworkTimeUpdateServicePresent());
+ // Stop the test execution, but in a way that isn't considered a failure.
+ throw new AssumptionViolatedException(
+ "Skipping test on devices where network_time_update_service is disabled by"
+ + " OEM");
+ }
+ }
+
private static boolean isWatch() {
return ApplicationProvider.getApplicationContext().getPackageManager()
.hasSystemFeature(PackageManager.FEATURE_WATCH);
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ForceDarkTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ForceDarkTests.java
index 010d1d9..09130a3 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ForceDarkTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ForceDarkTests.java
@@ -16,6 +16,8 @@
package android.uirendering.cts.testclasses;
+import static org.junit.Assume.assumeFalse;
+
import android.Manifest;
import android.app.UiModeManager;
import android.content.Context;
@@ -35,9 +37,11 @@
import androidx.test.runner.AndroidJUnit4;
import com.android.compatibility.common.util.SystemUtil;
+import com.android.compatibility.common.util.UserHelper;
import org.junit.AfterClass;
import org.junit.Assert;
+import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -46,9 +50,15 @@
@RunWith(AndroidJUnit4.class)
public class ForceDarkTests extends ActivityTestBase {
static int sPreviousUiMode = UiModeManager.MODE_NIGHT_NO;
+ private static final boolean VISIBLE_BACKGROUND_USER =
+ new UserHelper().isVisibleBackgroundUser();
@BeforeClass
public static void enableForceDark() {
+ // Visible background users are not allowed to call setNightMode.
+ if (VISIBLE_BACKGROUND_USER) {
+ return;
+ }
// Temporarily override the ui mode
UiModeManager uiManager = (UiModeManager)
InstrumentationRegistry.getContext().getSystemService(Context.UI_MODE_SERVICE);
@@ -62,6 +72,10 @@
@AfterClass
public static void restoreForceDarkSetting() {
+ // Visible background users are not allowed to call setNightMode.
+ if (VISIBLE_BACKGROUND_USER) {
+ return;
+ }
UiModeManager uiManager = (UiModeManager)
InstrumentationRegistry.getContext().getSystemService(Context.UI_MODE_SERVICE);
if (sPreviousUiMode != UiModeManager.MODE_NIGHT_YES) {
@@ -70,6 +84,14 @@
}
}
+ @Before
+ public void setUp() {
+ // Skip all tests in this class for a visible background user.
+ assumeFalse(
+ "Visible background users are not allowed to set night mode.",
+ VISIBLE_BACKGROUND_USER);
+ }
+
@Override
protected boolean useForceDark() {
return true;
diff --git a/tests/tests/util/src/android/util/cts/ArrayMapTest.java b/tests/tests/util/src/android/util/cts/ArrayMapTest.java
index bb0c8b5..9a5566b 100644
--- a/tests/tests/util/src/android/util/cts/ArrayMapTest.java
+++ b/tests/tests/util/src/android/util/cts/ArrayMapTest.java
@@ -483,7 +483,8 @@
/**
* Test creating a malformed array map with duplicated keys and that we will catch this
* when unparcelling.
- */
+ *
+ * TODO: remove use of private APIs, see b/384599385
@Test
public void testDuplicateKeys() throws NoSuchMethodException,
InvocationTargetException, IllegalAccessException, NoSuchFieldException {
@@ -517,6 +518,7 @@
dump(map1, map2);
fail(msg);
}
+ */
private static void checkEntrySetToArray(ArrayMap<?, ?> testMap) {
try {
diff --git a/tests/tests/vcn/src/android/net/vcn/cts/VcnGatewayConnectionConfigTest.java b/tests/tests/vcn/src/android/net/vcn/cts/VcnGatewayConnectionConfigTest.java
index 12b9adb..618c3de 100644
--- a/tests/tests/vcn/src/android/net/vcn/cts/VcnGatewayConnectionConfigTest.java
+++ b/tests/tests/vcn/src/android/net/vcn/cts/VcnGatewayConnectionConfigTest.java
@@ -171,12 +171,6 @@
@Test
public void testBuilderSetMinUdpPort4500NatTimeout_invalidValues() {
try {
- buildVcnGatewayConnectionConfigBase().setMinUdpPort4500NatTimeoutSeconds(-1);
- fail("Expected exception due to invalid timeout range");
- } catch (IllegalArgumentException e) {
- }
-
- try {
buildVcnGatewayConnectionConfigBase().setMinUdpPort4500NatTimeoutSeconds(119);
fail("Expected exception due to invalid timeout range");
} catch (IllegalArgumentException e) {
diff --git a/tests/tests/vcn/src/android/net/vcn/cts/VcnManagerTest.java b/tests/tests/vcn/src/android/net/vcn/cts/VcnManagerTest.java
index 81630ff..da6ae98 100644
--- a/tests/tests/vcn/src/android/net/vcn/cts/VcnManagerTest.java
+++ b/tests/tests/vcn/src/android/net/vcn/cts/VcnManagerTest.java
@@ -110,7 +110,7 @@
public class VcnManagerTest extends VcnTestBase {
private static final String TAG = VcnManagerTest.class.getSimpleName();
- private static final int TIMEOUT_MS = 500;
+ private static final int CALLBACK_TIMEOUT_MS = 5000;
private static final long SAFEMODE_TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(35);
private static final int ACTIVE_SUB_ID_TIMEOUT_SECONDS = 60;
@@ -263,7 +263,7 @@
}
public void awaitOnPolicyChanged() throws Exception {
- mFutureOnPolicyChanged.get(TIMEOUT_MS, TimeUnit.MILLISECONDS);
+ mFutureOnPolicyChanged.get(CALLBACK_TIMEOUT_MS, TimeUnit.MILLISECONDS);
}
}
@@ -523,14 +523,16 @@
}
public int awaitOnStatusChanged() throws Exception {
- final Integer status = mOnStatusChangedHistory.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS);
+ final Integer status =
+ mOnStatusChangedHistory.poll(CALLBACK_TIMEOUT_MS, TimeUnit.MILLISECONDS);
// Null means timeout
return status == null ? VCN_STATUS_CODE_AWAIT_TIMEOUT : status;
}
public GatewayConnectionError awaitOnGatewayConnectionError() throws Exception {
- return mOnGatewayConnectionErrorHistory.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS);
+ return mOnGatewayConnectionErrorHistory.poll(
+ CALLBACK_TIMEOUT_MS, TimeUnit.MILLISECONDS);
}
}
diff --git a/tests/tests/view/AndroidManifest.xml b/tests/tests/view/AndroidManifest.xml
index a6568f4..f7255c5 100644
--- a/tests/tests/view/AndroidManifest.xml
+++ b/tests/tests/view/AndroidManifest.xml
@@ -203,6 +203,7 @@
<activity android:name="android.view.cts.PixelCopyViewProducerActivity"
android:label="PixelCopyViewProducerActivity"
android:screenOrientation="portrait"
+ android:resizeableActivity="false"
android:rotationAnimation="jumpcut"
android:theme="@android:style/Theme.DeviceDefault.NoActionBar"
android:configChanges="orientation|screenSize|screenLayout|smallestScreenSize"
@@ -211,6 +212,7 @@
<activity android:name="android.view.cts.PixelCopyWideGamutViewProducerActivity"
android:label="PixelCopyWideGamutViewProducerActivity"
android:screenOrientation="portrait"
+ android:resizeableActivity="false"
android:rotationAnimation="jumpcut"
android:theme="@android:style/Theme.DeviceDefault.NoActionBar"
android:configChanges="orientation|screenSize|screenLayout|smallestScreenSize"
@@ -221,6 +223,7 @@
android:label="PixelCopyViewProducerDialogActivity"
android:screenOrientation="portrait"
android:rotationAnimation="jumpcut"
+ android:resizeableActivity="false"
android:theme="@android:style/Theme.Material.Dialog.NoActionBar"
android:configChanges="orientation|screenSize|screenLayout|smallestScreenSize"
android:exported="true"/>
diff --git a/tests/tests/view/src/android/view/cts/ViewTest.java b/tests/tests/view/src/android/view/cts/ViewTest.java
index 5517ac5..01165ca 100644
--- a/tests/tests/view/src/android/view/cts/ViewTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewTest.java
@@ -4047,13 +4047,24 @@
final WindowMetrics metrics = windowManager.getMaximumWindowMetrics();
final Insets insets =
metrics.getWindowInsets().getInsets(
- WindowInsets.Type.navigationBars() | WindowInsets.Type.displayCutout());
+ WindowInsets.Type.systemBars() | WindowInsets.Type.displayCutout());
final int expectedWidth = metrics.getBounds().width() - insets.left - insets.right;
final int expectedHeight = metrics.getBounds().height() - insets.top - insets.bottom;
+
+ // A bug of getWindowVisibleDisplayFrame has been fixed since 25Q1 (Android 15). We still
+ // need to accept the legacy logic of computing WindowVisibleDisplayFrame until Android 16.
+ final Insets compatInsets =
+ metrics.getWindowInsets().getInsets(
+ WindowInsets.Type.navigationBars() | WindowInsets.Type.displayCutout());
+ final int compatExpectedWidth =
+ metrics.getBounds().width() - compatInsets.left - compatInsets.right;
+ final int compatExpectedHeight =
+ metrics.getBounds().height() - compatInsets.top - compatInsets.bottom;
+
assertEquals(0, outRect.left);
assertEquals(0, outRect.top);
- assertEquals(expectedWidth, outRect.right);
- assertEquals(expectedHeight, outRect.bottom);
+ assertTrue(expectedWidth == outRect.right || compatExpectedWidth == outRect.right);
+ assertTrue(expectedHeight == outRect.bottom || compatExpectedHeight == outRect.bottom);
// mAttachInfo is not null
outRect = new Rect();
diff --git a/tests/tests/virtualdevice/camera/src/android/virtualdevice/cts/camera/VirtualCameraNdkTest.java b/tests/tests/virtualdevice/camera/src/android/virtualdevice/cts/camera/VirtualCameraNdkTest.java
index 934a7d7..6aceba0 100644
--- a/tests/tests/virtualdevice/camera/src/android/virtualdevice/cts/camera/VirtualCameraNdkTest.java
+++ b/tests/tests/virtualdevice/camera/src/android/virtualdevice/cts/camera/VirtualCameraNdkTest.java
@@ -20,6 +20,7 @@
import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_CAMERA;
import static android.companion.virtual.camera.VirtualCameraConfig.SENSOR_ORIENTATION_0;
import static android.hardware.camera2.CameraMetadata.LENS_FACING_FRONT;
+import static android.virtualdevice.cts.camera.VirtualCameraUtils.BACK_CAMERA_ID;
import static android.virtualdevice.cts.camera.VirtualCameraUtils.FRONT_CAMERA_ID;
import static android.virtualdevice.cts.camera.VirtualCameraUtils.createVirtualCameraConfig;
import static android.virtualdevice.cts.common.VirtualDeviceRule.TRUSTED_VIRTUAL_DISPLAY_CONFIG;
@@ -27,6 +28,7 @@
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeTrue;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.after;
import static org.mockito.Mockito.clearInvocations;
@@ -101,9 +103,17 @@
private VirtualDisplay mVirtualDisplay;
@Before
- public void setUp() {
+ public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
+ // Check whether the default camera id's contain the front and back cameras.
+ // This is a workaround for a device-awareness bug in Camera NDK.
+ // TODO(b/391957505): Remove the following assumptions once the bug is fixed.
+ List<String> defaultCameraIds = Arrays.asList(mContext.getSystemService(
+ CameraManager.class).getCameraIdListNoLazy());
+ assumeTrue(defaultCameraIds.contains(FRONT_CAMERA_ID));
+ assumeTrue(defaultCameraIds.contains(BACK_CAMERA_ID));
+
mVirtualDevice = mRule.createManagedVirtualDevice(
new VirtualDeviceParams.Builder()
.setDevicePolicy(POLICY_TYPE_CAMERA, DEVICE_POLICY_CUSTOM)
diff --git a/tests/tests/widget/res/layout/listview_layout.xml b/tests/tests/widget/res/layout/listview_layout.xml
index 4bfb788..1a950d4 100644
--- a/tests/tests/widget/res/layout/listview_layout.xml
+++ b/tests/tests/widget/res/layout/listview_layout.xml
@@ -65,6 +65,7 @@
<ListView
android:id="@+id/listview_stretch"
+ android:visibility="gone"
android:layout_width="90px"
android:layout_height="90px"
android:layout_gravity="center"/>
diff --git a/tests/tests/widget/src/android/widget/cts/ListViewTest.java b/tests/tests/widget/src/android/widget/cts/ListViewTest.java
index efe13e4..6d93372 100644
--- a/tests/tests/widget/src/android/widget/cts/ListViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ListViewTest.java
@@ -1598,18 +1598,17 @@
}
private void showOnlyStretch() throws Throwable {
- mActivityRule.runOnUiThread(() -> {
- ViewGroup parent = (ViewGroup) mListViewStretch.getParent();
- for (int i = 0; i < parent.getChildCount(); i++) {
- View child = parent.getChildAt(i);
- if (child != mListViewStretch) {
- child.setVisibility(View.GONE);
- }
- }
- mListViewStretch.setAdapter(mAdapterColors);
- mListViewStretch.setDivider(null);
- mListViewStretch.setDividerHeight(0);
- });
+ mActivityRule.runOnUiThread(
+ () -> {
+ ViewGroup parent = (ViewGroup) mListViewStretch.getParent();
+ for (int i = 0; i < parent.getChildCount(); i++) {
+ View child = parent.getChildAt(i);
+ child.setVisibility((child == mListViewStretch) ? View.VISIBLE : View.GONE);
+ }
+ mListViewStretch.setAdapter(mAdapterColors);
+ mListViewStretch.setDivider(null);
+ mListViewStretch.setDividerHeight(0);
+ });
// Give it an opportunity to finish layout.
CountDownLatch latch = new CountDownLatch(1);
mActivityRule.runOnUiThread(() -> {
diff --git a/tools/cts-tradefed/Android.bp b/tools/cts-tradefed/Android.bp
index ff5c93f..c438973 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: "15_r3",
+ version: "15_r4",
static_libs: ["cts-tradefed-harness"],
required: ["compatibility-host-util"],
}
diff --git a/tools/cts-tradefed/res/config/cts-known-failures.xml b/tools/cts-tradefed/res/config/cts-known-failures.xml
old mode 100755
new mode 100644
index e8c8b1a..62fdf14
--- a/tools/cts-tradefed/res/config/cts-known-failures.xml
+++ b/tools/cts-tradefed/res/config/cts-known-failures.xml
@@ -357,6 +357,8 @@
<!-- b/330018295 -->
<option name="compatibility:exclude-filter" value="CtsAssistTestCases android.assist.cts.AssistantContentViewTest#testAssistantContentViewDimens" />
<option name="compatibility:exclude-filter" value="CtsAssistTestCases[instant] android.assist.cts.AssistantContentViewTest#testAssistantContentViewDimens" />
+ <!-- b/380538323 -->
+ <option name="compatibility:exclude-filter" value="CtsAssistTestCases[foldable:5:OPENED] android.assist.cts.AssistantContentViewTest#testAssistantContentViewDimens" />
<!-- b/341195751 -->
<option name="compatibility:exclude-filter" value="CtsSimpleCpuTestCases android.simplecpu.cts.SimpleCpuTest#testMatrixMultiplication032" />
@@ -428,4 +430,56 @@
<!-- b/378989105 -->
<option name="compatibility:exclude-filter" value="CtsSliceTestCases" />
+
+ <!-- b/381409777-->
+ <option name="compatibility:exclude-filter" value="CtsHealthConnectHostTestCases android.healthconnect.cts.dailyjob.DailyDeleteAccessLogTest#testAccessLogsAreDeleted" />
+ <!-- b/383123499 -->
+ <option name="compatibility:exclude-filter" value="CtsBluetoothTestCases android.bluetooth.cts.BluetoothQualityReportTest#readWriteBqrParcelV6Flag" />
+ <option name="compatibility:exclude-filter" value="CtsBluetoothTestCases android.bluetooth.cts.BluetoothQualityReportTest#readWriteBqrVsA2dpChoppyParcel" />
+ <option name="compatibility:exclude-filter" value="CtsBluetoothTestCases android.bluetooth.cts.BluetoothQualityReportTest#bqrRfStats" />
+ <option name="compatibility:exclude-filter" value="CtsBluetoothTestCases android.bluetooth.cts.BluetoothQualityReportTest#bqrMonitor" />
+ <option name="compatibility:exclude-filter" value="CtsBluetoothTestCases android.bluetooth.cts.BluetoothQualityReportTest#readWriteBqrConnectFailParcel" />
+ <option name="compatibility:exclude-filter" value="CtsBluetoothTestCases android.bluetooth.cts.BluetoothQualityReportTest#bqrConnectFail" />
+ <option name="compatibility:exclude-filter" value="CtsBluetoothTestCases android.bluetooth.cts.BluetoothQualityReportTest#readWriteBqrVsA2dpChoppyParcel" />
+ <option name="compatibility:exclude-filter" value="CtsBluetoothTestCases android.bluetooth.cts.BluetoothQualityReportTest#readWriteBqrCommonParcel" />
+ <option name="compatibility:exclude-filter" value="CtsBluetoothTestCases android.bluetooth.cts.BluetoothQualityReportTest#readWriteBqrVsScoChoppyParcel" />
+ <option name="compatibility:exclude-filter" value="CtsBluetoothTestCases android.bluetooth.cts.BluetoothQualityReportTest#defaultNameAddress" />
+ <option name="compatibility:exclude-filter" value="CtsBluetoothTestCases android.bluetooth.cts.BluetoothQualityReportTest#bqrApproachLsto" />
+ <option name="compatibility:exclude-filter" value="CtsBluetoothTestCases android.bluetooth.cts.BluetoothQualityReportTest#readWriteBqrParcel" />
+ <option name="compatibility:exclude-filter" value="CtsBluetoothTestCases android.bluetooth.cts.BluetoothQualityReportTest#bqrScoChoppy" />
+ <option name="compatibility:exclude-filter" value="CtsBluetoothTestCases android.bluetooth.cts.BluetoothQualityReportTest#bqrEnergyMonitor" />
+ <option name="compatibility:exclude-filter" value="CtsBluetoothTestCases android.bluetooth.cts.BluetoothQualityReportTest#invalidRawData" />
+ <option name="compatibility:exclude-filter" value="CtsBluetoothTestCases android.bluetooth.cts.BluetoothQualityReportTest#bqrA2dpChoppy" />
+ <option name="compatibility:exclude-filter" value="CtsBluetoothTestCases android.bluetooth.cts.BluetoothQualityReportTest#rawDataNull" />
+ <option name="compatibility:exclude-filter" value="CtsBluetoothTestCases android.bluetooth.cts.BluetoothQualityReportTest#readWriteBqrVsApproachLstoParcel" />
+ <option name="compatibility:exclude-filter" value="CtsBluetoothTestCases android.bluetooth.cts.BluetoothQualityReportTest#invalidQualityReportId" />
+ <option name="compatibility:exclude-filter" value="CtsBluetoothTestCases android.bluetooth.cts.BluetoothAdapterTest#bluetoothQualityReportReadyCallbacks" />
+
+ <!-- b/379233406 -->
+ <option name="compatibility:exclude-filter" value="CtsPhotoPickerTest[run-on-clone-profile]" />
+ <option name="compatibility:exclude-filter" value="CtsPhotoPickerTest[run-on-private-profile]" />
+
+ <!-- b/379236422 -->
+ <option name="compatibility:exclude-filter" value="CtsMediaBetterTogetherTestCases[run-on-clone-profile]" />
+ <option name="compatibility:exclude-filter" value="CtsMediaBetterTogetherTestCases[run-on-private-profile]" />
+ <option name="compatibility:exclude-filter" value="CtsMediaBetterTogetherTestCases[run-on-secondary-user]" />
+ <option name="compatibility:exclude-filter" value="CtsMediaBetterTogetherTestCases[run-on-work-profile]" />
+
+ <!-- b/379239507 -->
+ <option name="compatibility:exclude-filter" value="MctsMediaBetterTogetherTestCases[run-on-clone-profile]" />
+ <option name="compatibility:exclude-filter" value="MctsMediaBetterTogetherTestCases[run-on-private-profile]" />
+ <option name="compatibility:exclude-filter" value="MctsMediaBetterTogetherTestCases[run-on-secondary-user]" />
+ <option name="compatibility:exclude-filter" value="MctsMediaBetterTogetherTestCases[run-on-work-profile]" />
+
+ <!-- b/379234304 -->
+ <option name="compatibility:exclude-filter" value="CtsOsTestCases[run-on-clone-profile]" />
+ <option name="compatibility:exclude-filter" value="CtsOsTestCases[run-on-private-profile]" />
+ <option name="compatibility:exclude-filter" value="CtsOsTestCases[run-on-secondary-user]" />
+ <option name="compatibility:exclude-filter" value="CtsOsTestCases[run-on-work-profile]" />
+
+ <!-- b/395784217 -->
+ <option name="compatibility:exclude-filter" value="CtsAdServicesDebuggableDeviceTestCases com.android.adservices.debuggablects.AdSelectionReportingTest#testReportImpression_withMismatchedBuyerAdTech_sellerStillCalled" />
+
+ <!-- b/395783356 -->
+ <option name="compatibility:exclude-filter" value="CtsAdServicesPermissionsAppOptOutEndToEndTests com.android.adservices.tests.permissions.PermissionsAppOptOutTest#testNoEnrollment_reportImpression" />
</configuration>
diff --git a/tools/cts-tradefed/res/config/incremental-deqp.xml b/tools/cts-tradefed/res/config/incremental-deqp.xml
new file mode 100644
index 0000000..40c8f07
--- /dev/null
+++ b/tools/cts-tradefed/res/config/incremental-deqp.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2024 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<configuration description="Runs a subset of CTS tests when the dEQP stack is not changed">
+
+ <include name="cts" />
+
+ <option name="plan" value="incremental-deqp" />
+
+ <!-- dEQP tests to be included in this plan-->
+ <option name="compatibility:module-arg" value="CtsDeqpTestCases:enable-incremental-deqp:true" />
+
+</configuration>