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>